(int)($_POST['wr_id'] ?? 0), 'customer_name' => trim($_POST['customer_name'] ?? ''), 'customer_phone' => trim($_POST['customer_phone'] ?? ''), 'customer_email' => trim($_POST['customer_email'] ?? ''), 'visit_date' => trim($_POST['visit_date'] ?? ''), // 폼의 name="visit_date"와 일치 'visit_time' => trim($_POST['visit_time'] ?? ''), // 폼의 name="visit_time"와 일치 'expert_id' => trim($_POST['expert_id'] ?? ''), // [추가] 전문가 ID 'temp_2' => trim($_POST['visit_type'] ?? ''), // [추가] 방문 유형 (temp_2에 저장) 'request_memo' => trim($_POST['request_memo'] ?? ''), // 폼의 name="request_memo"와 일치 'payment_amount' => (int)($_POST['payment_amount'] ?? 0), 'status' => 'payment_pending', 'created_by' => $member['mb_id'] ?? 'guest' ]; // 필수 항목 유효성 검사 if (empty($reservation_data['customer_name']) || empty($reservation_data['customer_phone']) || empty($reservation_data['visit_date']) || empty($reservation_data['visit_time'])) { throw new Exception('필수 예약 정보(이름, 연락처, 날짜, 시간)가 누락되었습니다.'); } // 예약 가능 여부 재확인 (서버 측 검증) // 1. 해당 날짜/요일에 운영하는 스케줄이 있는지 확인 $dow = date('N', strtotime($reservation_data['visit_date'])); $expert_condition = $reservation_data['expert_id'] ? "(expert_id = '{$reservation_data['expert_id']}' OR expert_id IS NULL)" : "expert_id IS NULL"; $sql_schedule = "SELECT * FROM expert_visit_schedules WHERE (specific_date = '{$reservation_data['visit_date']}' OR (specific_date IS NULL AND day_of_week = '{$dow}')) AND {$expert_condition} AND is_available = 1 ORDER BY specific_date DESC, expert_id DESC LIMIT 1"; $schedule = sql_fetch($sql_schedule); if (!$schedule) { throw new Exception('선택하신 날짜는 예약이 불가능합니다.'); } // 2. 해당 시간대가 운영 시간 내인지 확인 $visit_time_ts = strtotime($reservation_data['visit_date'] . ' ' . $reservation_data['visit_time']); $start_time_ts = strtotime($reservation_data['visit_date'] . ' ' . $schedule['start_time']); $end_time_ts = strtotime($reservation_data['visit_date'] . ' ' . $schedule['end_time']); if ($visit_time_ts < $start_time_ts || $visit_time_ts >= $end_time_ts) { throw new Exception('선택하신 시간은 운영 시간이 아닙니다.'); } // 3. 해당 시간대에 예약 정원이 찼는지 확인 $sql_reserved = "SELECT COUNT(*) as cnt FROM expert_visit_reservations WHERE visit_date = '{$reservation_data['visit_date']}' AND visit_time = '{$reservation_data['visit_time']}' AND status != 'cancelled'"; if ($reservation_data['expert_id']) { $sql_reserved .= " AND expert_id = '{$reservation_data['expert_id']}'"; } $reserved = sql_fetch($sql_reserved); if ($reserved['cnt'] >= $schedule['max_persons']) { throw new Exception('선택하신 시간은 이미 예약이 마감되었습니다.'); } // 예약 생성 $columns = implode(", ", array_keys($reservation_data)); $values = "'" . implode("', '", array_map('sql_real_escape_string', $reservation_data)) . "'"; $sql = "INSERT INTO expert_visit_reservations ($columns, created_at, updated_at) VALUES ($values, NOW(), NOW())"; if (sql_query($sql)) { $reservation_id = sql_insert_id(); // 신규 예약 알림 발송 if (function_exists('notify_for_expert_visit')) { notify_for_expert_visit($reservation_id, '신규예약'); } echo json_encode(['success' => true, 'message' => '전문가 방문 예약 신청이 완료되었습니다.']); } else { throw new Exception('데이터베이스 저장 중 오류가 발생했습니다.'); } } catch (Exception $e) { // 500 오류 방지를 위해 예외 발생 시에도 JSON 응답 반환 http_response_code(200); echo json_encode(['success' => false, 'message' => $e->getMessage()]); } ?>