first commit 2
This commit is contained in:
@@ -0,0 +1,441 @@
|
||||
<?php
|
||||
if (!defined('_GNUBOARD_'))
|
||||
exit;
|
||||
|
||||
// ❗ [핵심] NotificationSender 클래스 포함
|
||||
if (file_exists(__DIR__ . '/notification_sender.php')) {
|
||||
require_once(__DIR__ . '/notification_sender.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문 설정값을 가져옵니다.
|
||||
*/
|
||||
function get_order_config($key, $default = '')
|
||||
{
|
||||
$result = sql_fetch("SELECT config_value FROM order_config WHERE config_key = '" . sql_real_escape_string($key) . "'");
|
||||
return $result ? $result['config_value'] : $default;
|
||||
}
|
||||
|
||||
function write_debug_log($message)
|
||||
{
|
||||
$log_dir = G5_PATH . '/log';
|
||||
|
||||
// 1. 디렉토리 존재 여부 확인 및 생성
|
||||
if (!is_dir($log_dir)) {
|
||||
if (!@mkdir($log_dir, 0755, true) && !is_dir($log_dir)) {
|
||||
error_log("--- NotificationSender ERROR: 디버그 로그 디렉토리 생성 실패. '{$log_dir}' 경로를 확인하거나 수동으로 생성 후 웹서버 쓰기 권한을 부여해주세요.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 디렉토리 쓰기 권한 확인
|
||||
if (!is_writable($log_dir)) {
|
||||
error_log("--- NotificationSender ERROR: 디버그 로그 쓰기 오류. '{$log_dir}' 디렉토리에 쓰기 권한이 없습니다. 웹서버의 폴더 권한을 확인해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 로그 파일에 내용 기록
|
||||
$log_file = $log_dir . '/notification_debug.log';
|
||||
$log_message = date("[Y-m-d H:i:s]") . " " . $message . "\n";
|
||||
|
||||
if (file_put_contents($log_file, $log_message, FILE_APPEND | LOCK_EX) === false) {
|
||||
error_log("--- NotificationSender ERROR: 디버그 로그 파일 쓰기 실패. '{$log_file}' 파일에 내용을 쓸 수 없습니다.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ❗ [핵심 수정] 1. 견적 상태 변경 시 알림 발송
|
||||
* @param int $wr_id 상태가 변경된 게시물 ID (원본 또는 답변글)
|
||||
* @param string $new_status 새로 변경된 상태
|
||||
*/
|
||||
function notify_by_status($wr_id, $new_status)
|
||||
{
|
||||
global $config;
|
||||
$post = sql_fetch("SELECT * FROM {$GLOBALS['g5']['write_prefix']}order WHERE wr_id = '{$wr_id}'");
|
||||
if (!$post) return false;
|
||||
write_debug_log("[notify_by_status] 원본 견적(estimate) 시작 : {$wr_id}");
|
||||
// 원본글 정보 조회
|
||||
$origin_post = sql_fetch("SELECT * FROM {$GLOBALS['g5']['write_prefix']}order WHERE wr_num = '{$post['wr_num']}' AND wr_reply = ''");
|
||||
if (!$origin_post) return false;
|
||||
$customer = get_member($origin_post['mb_id']);
|
||||
if (!$customer) return false;
|
||||
|
||||
// 템플릿에 사용할 공통 변수 (영문 키로 표준화)
|
||||
$common_vars = [
|
||||
'customer_name' => $customer['mb_name'],
|
||||
'request_title' => $origin_post['wr_subject'],
|
||||
'request_date' => date('Y-m-d', strtotime($origin_post['wr_datetime'])),
|
||||
'write_url' => get_pretty_url('order', $origin_post['wr_id']),
|
||||
'site_name' => $config['cf_title'] ?? '우리집창호', // 사이트 이름 추가
|
||||
];
|
||||
|
||||
if (!class_exists('NotificationSender')) return false;
|
||||
$sender = new NotificationSender();
|
||||
|
||||
// ❗ [추가] 결제 및 진행상태 관련 알림을 위한 공통 변수 처리
|
||||
$payment_statuses = ['계약금입금완료', '중도금입금예정', '중도금입금완료', '시공완료'];
|
||||
$payment_vars = [];
|
||||
$agent_member = null;
|
||||
$bid_dealer_id = null;
|
||||
|
||||
if (in_array($new_status, $payment_statuses)) {
|
||||
// ❗ [핵심 수정] estimate_bidding을 사용하지 않고, 채택된 답변글에서 직접 정보를 가져옵니다.
|
||||
// 1. 원본글의 estimate 정보를 가져옵니다. (시공일, 중도금일 등)
|
||||
$origin_estimate = sql_fetch("SELECT * FROM estimate WHERE wr_id = '{$origin_post['wr_id']}'");
|
||||
if (!$origin_estimate) {
|
||||
write_debug_log("[notify_by_status] 원본 견적(estimate) 정보를 찾을 수 없습니다. wr_id: {$origin_post['wr_id']}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 채택된 답변글(대리점 제안) 정보를 찾습니다.
|
||||
$selected_reply_sql = "
|
||||
SELECT
|
||||
w.mb_id as dealer_id,
|
||||
e.commission_fee as total_amount
|
||||
FROM
|
||||
{$GLOBALS['g5']['write_prefix']}order w
|
||||
JOIN
|
||||
estimate e ON w.wr_id = e.wr_id
|
||||
WHERE
|
||||
w.wr_num = '{$origin_post['wr_num']}'
|
||||
AND w.wr_reply != ''
|
||||
AND e.status = '견적채택'
|
||||
LIMIT 1
|
||||
";
|
||||
$selected_bid_info = sql_fetch($selected_reply_sql);
|
||||
|
||||
if ($selected_bid_info) {
|
||||
$bid_dealer_id = $selected_bid_info['dealer_id'];
|
||||
$agent_member = get_member($bid_dealer_id);
|
||||
$total_amount = (int) $selected_bid_info['total_amount']; // 답변글의 estimate.commission_fee를 총액으로 사용
|
||||
|
||||
$deposit_rate = (float) get_order_config('contract_deposit_rate', 10);
|
||||
$interim_rate = (float) get_order_config('middle_payment_rate', 40);
|
||||
$deposit_amount = (int) ($total_amount * $deposit_rate / 100);
|
||||
$interim_amount = (int) ($total_amount * $interim_rate / 100);
|
||||
|
||||
$payment_vars = array_merge($common_vars, [
|
||||
'deposit_amount' => number_format($deposit_amount) . '원',
|
||||
'interim_amount' => number_format($interim_amount) . '원',
|
||||
'agent_name' => $agent_member['mb_name'] ?? '담당 대리점',
|
||||
'construction_date' => $origin_estimate['temp_6'] ?? '미정',
|
||||
'interim_payment_date' => $origin_estimate['temp_7'] ?? '미정',
|
||||
'account_info' => get_order_config('payment_account_info', '계좌 정보 미설정'),
|
||||
]);
|
||||
}
|
||||
|
||||
if (empty($payment_vars)) { // 필수 정보가 없으면 발송 중단
|
||||
write_debug_log("[notify_by_status] 결제 정보 부족으로 '{$new_status}' 알림 발송을 건너뜁니다. wr_id: {$wr_id}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($new_status) {
|
||||
case '작성완료':
|
||||
// 1. 고객에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'customer_request_complete',
|
||||
'sms_template_key' => 'customer_request_complete',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
|
||||
// 2. 모든 대리점에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'bulk',
|
||||
'member_levels' => [9,10],
|
||||
'email_template_key' => 'agent_new_request',
|
||||
'sms_template_key' => 'agent_new_request',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '견적채택':
|
||||
$agent_member = get_member($post['mb_id']);
|
||||
write_debug_log("[notify_by_status] agent_member=> ".$agent_member['mb_id'].', name'.$agent_member['mb_name'].', id '.$post['mb_id'].', w_id '.$wr_id);
|
||||
if (!$agent_member) break;
|
||||
|
||||
// 🔥 [핵심 수정] 채택된 답변글(wr_id)의 estimate 레코드에서 최종 금액을 가져옵니다.
|
||||
$agent_estimate = sql_fetch("SELECT id, commission_fee FROM estimate WHERE wr_id = '{$post['wr_id']}'");
|
||||
$final_amount = $agent_estimate ? (int)$agent_estimate['commission_fee'] : 0;
|
||||
|
||||
// [수정] 입찰 정보를 바탕으로 변수를 설정합니다.
|
||||
$bid_vars = array_merge($common_vars, [
|
||||
'agent_name' => $agent_member['mb_name'],
|
||||
'dealer_name' => $agent_member['mb_name'], // 템플릿 호환용
|
||||
'deposit_amount' => number_format($final_amount) . '원', // 최종 금액을 입금 안내
|
||||
'bid_amount' => number_format($final_amount), // 템플릿 호환용
|
||||
'account_info' => get_order_config('payment_account_info', '계좌 정보 미설정'),
|
||||
'estimate_id' => $agent_estimate ? $agent_estimate['id'] : 'N/A',
|
||||
'selected_date' => date('Y-m-d H:i'),
|
||||
'estimate_url' => get_pretty_url('order', $origin_post['wr_id']),
|
||||
]);
|
||||
// 1. 채택된 대리점에게 알림 (축하 메시지)
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $agent_member['mb_id'],
|
||||
'email_template_key' => 'bid_selected_email',
|
||||
'sms_template_key' => 'bid_selected_sms',
|
||||
'vars' => $bid_vars,
|
||||
]);
|
||||
|
||||
// 2. 고객에게 알림 (선택 완료 및 입금 안내)
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'customer_quote_selected',
|
||||
'sms_template_key' => 'customer_quote_selected',
|
||||
'vars' => $bid_vars,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '계약금입금완료':
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'payment_deposit_complete_customer',
|
||||
'sms_template_key' => 'payment_deposit_complete_customer',
|
||||
'vars' => $payment_vars,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '중도금입금예정':
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'payment_interim_due_customer',
|
||||
'sms_template_key' => 'payment_interim_due_customer',
|
||||
'vars' => $payment_vars,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '중도금입금완료':
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'payment_interim_complete_customer',
|
||||
'sms_template_key' => 'payment_interim_complete_customer',
|
||||
'vars' => $payment_vars,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '시공완료':
|
||||
// 고객에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'construction_complete_customer',
|
||||
'sms_template_key' => 'construction_complete_customer',
|
||||
'vars' => $payment_vars,
|
||||
]);
|
||||
|
||||
// 대리점에게 알림
|
||||
if ($bid_dealer_id) {
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $bid_dealer_id,
|
||||
'email_template_key' => 'construction_complete_agent',
|
||||
'sms_template_key' => 'construction_complete_agent',
|
||||
'vars' => $payment_vars,
|
||||
]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ❗ [신규] 2. 입금 관련 알림 발송 (관리자, 고객)
|
||||
* @param int $wr_id 원본 게시물 ID
|
||||
* @param string $payment_status 입금 상태 (예: '계약금입금완료')
|
||||
* @param array $payment_info 추가 결제 정보 (금액 등)
|
||||
*/
|
||||
function notify_for_payment($wr_id, $payment_status, $payment_info = [])
|
||||
{
|
||||
$origin_post = sql_fetch("SELECT * FROM {$GLOBALS['g5']['write_prefix']}order WHERE wr_id = '{$wr_id}'");
|
||||
if (!$origin_post) return false;
|
||||
$customer = get_member($origin_post['mb_id']);
|
||||
if (!$customer) return false;
|
||||
|
||||
$common_vars = array_merge([
|
||||
'customer_name' => $customer['mb_name'],
|
||||
'estimate_subject' => $origin_post['wr_subject'],
|
||||
], $payment_info);
|
||||
|
||||
if (!class_exists('NotificationSender')) return false;
|
||||
$sender = new NotificationSender();
|
||||
|
||||
// 1. 고객에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $customer['mb_id'],
|
||||
'email_template_key' => 'payment_status_update_customer', // 예시 템플릿 키
|
||||
'sms_template_key' => 'payment_status_update_customer',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
|
||||
// 2. 관리자에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'bulk',
|
||||
'member_levels' => [10], // 관리자 레벨
|
||||
'email_template_key' => 'payment_status_update_admin', // 예시 템플릿 키
|
||||
'sms_template_key' => 'payment_status_update_admin',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ❗ [신규] 3. 전문가 방문 예약 관련 알림 발송 (고객, 전문가, 관리자)
|
||||
* @param int $reservation_id 예약 ID
|
||||
* @param string $visit_status 방문 상태 (예: '신규예약', '예약확정', '예약취소')
|
||||
*/
|
||||
function notify_for_expert_visit($reservation_id, $visit_status)
|
||||
{
|
||||
// 예약 정보 조회
|
||||
$reservation = sql_fetch("SELECT * FROM expert_visit_reservations WHERE id = '{$reservation_id}'");
|
||||
if (!$reservation) return false;
|
||||
|
||||
// 💡 [수정] 고객 정보 조회 (회원/비회원 구분)
|
||||
$customer = get_member($reservation['customer_id']);
|
||||
$is_guest = empty($customer['mb_id']);
|
||||
|
||||
// 비회원일 경우 예약 정보에서 직접 가져옴
|
||||
$customer_name = $is_guest ? $reservation['customer_name'] : $customer['mb_name'];
|
||||
$customer_hp = $is_guest ? $reservation['customer_phone'] : $customer['mb_hp'];
|
||||
$customer_email = $is_guest ? $reservation['customer_email'] : $customer['mb_email'];
|
||||
|
||||
$expert = get_member($reservation['expert_id']);
|
||||
|
||||
$common_vars = [
|
||||
'customer_name' => $customer_name,
|
||||
'visit_date' => $reservation['visit_date'],
|
||||
'visit_time' => $reservation['visit_time'],
|
||||
'expert_name' => $expert['mb_name'] ?? '미지정',
|
||||
];
|
||||
|
||||
if (!class_exists('NotificationSender')) return false;
|
||||
$sender = new NotificationSender();
|
||||
|
||||
switch ($visit_status) {
|
||||
case '신규예약':
|
||||
// 1. 고객에게 신청 완료 알림
|
||||
$send_params = [
|
||||
'email_template_key' => 'expert_visit_request_new',
|
||||
'sms_template_key' => 'expert_visit_request_new',
|
||||
'vars' => array_merge($common_vars, [
|
||||
'reservation_id' => $reservation_id,
|
||||
'expert_visit_fee' => number_format($reservation['payment_amount']) . '원',
|
||||
'account_info' => get_order_config('expert_visit_account_info', '계좌 정보 미설정'),
|
||||
]),
|
||||
];
|
||||
|
||||
if ($is_guest) {
|
||||
// 비회원: 직접 수신자 정보 지정
|
||||
$send_params['target_type'] = 'direct';
|
||||
$send_params['receivers'] = [
|
||||
[
|
||||
'mb_name' => $customer_name,
|
||||
'mb_hp' => $customer_hp,
|
||||
'mb_email' => $customer_email,
|
||||
'mb_sms' => 1, // SMS 수신 동의 가정
|
||||
'mb_mailling' => 1 // 메일 수신 동의 가정
|
||||
]
|
||||
];
|
||||
} else {
|
||||
// 회원: member_id 사용
|
||||
$send_params['target_type'] = 'single';
|
||||
$send_params['member_id'] = $customer['mb_id'];
|
||||
}
|
||||
$sender->send($send_params);
|
||||
|
||||
// 2. 관리자에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'bulk',
|
||||
'member_levels' => [10],
|
||||
'email_template_key' => 'admin_new_visit_request',
|
||||
'sms_template_key' => 'admin_new_visit_request',
|
||||
'vars' => array_merge($common_vars, [
|
||||
'customer_phone' => $customer_hp,
|
||||
'request_memo' => $reservation['request_memo'],
|
||||
]),
|
||||
]);
|
||||
break;
|
||||
|
||||
case '예약확정':
|
||||
// 1. 고객에게 예약 확정 알림
|
||||
$send_params = [
|
||||
'email_template_key' => 'expert_visit_confirmed',
|
||||
'sms_template_key' => 'expert_visit_confirmed',
|
||||
'vars' => $common_vars,
|
||||
];
|
||||
|
||||
if ($is_guest) {
|
||||
$send_params['target_type'] = 'direct';
|
||||
$send_params['receivers'] = [
|
||||
[
|
||||
'mb_name' => $customer_name,
|
||||
'mb_hp' => $customer_hp,
|
||||
'mb_email' => $customer_email,
|
||||
'mb_sms' => 1,
|
||||
'mb_mailling' => 1
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$send_params['target_type'] = 'single';
|
||||
$send_params['member_id'] = $customer['mb_id'];
|
||||
}
|
||||
$sender->send($send_params);
|
||||
|
||||
// 2. 배정된 전문가에게 알림
|
||||
if ($expert) {
|
||||
$sender->send([
|
||||
'target_type' => 'single',
|
||||
'member_id' => $expert['mb_id'],
|
||||
'email_template_key' => 'expert_new_assignment',
|
||||
'sms_template_key' => 'expert_new_assignment',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
}
|
||||
break;
|
||||
|
||||
case '예약취소':
|
||||
// 1. 고객에게 예약 취소 알림
|
||||
$send_params = [
|
||||
'email_template_key' => 'expert_visit_cancelled',
|
||||
'sms_template_key' => 'expert_visit_cancelled',
|
||||
'vars' => $common_vars,
|
||||
];
|
||||
|
||||
if ($is_guest) {
|
||||
$send_params['target_type'] = 'direct';
|
||||
$send_params['receivers'] = [
|
||||
[
|
||||
'mb_name' => $customer_name,
|
||||
'mb_hp' => $customer_hp,
|
||||
'mb_email' => $customer_email,
|
||||
'mb_sms' => 1,
|
||||
'mb_mailling' => 1
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$send_params['target_type'] = 'single';
|
||||
$send_params['member_id'] = $customer['mb_id'];
|
||||
}
|
||||
$sender->send($send_params);
|
||||
|
||||
// 2. 관리자에게 알림
|
||||
$sender->send([
|
||||
'target_type' => 'bulk',
|
||||
'member_levels' => [10],
|
||||
'email_template_key' => 'admin_visit_cancelled',
|
||||
'sms_template_key' => 'admin_visit_cancelled',
|
||||
'vars' => $common_vars,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user