5) { ob_clean(); http_response_code(403); header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => '권한이 없습니다.']); exit; } // JSON 데이터 받기 $input = file_get_contents('php://input'); $data = json_decode($input, true); if (!$data) { ob_clean(); header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => '잘못된 데이터입니다.']); exit; } // 데이터베이스 연결 require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php"); $pdo = db_connect(); // 트랜잭션 상태 추적 변수 $transactionStarted = false; try { // 디버깅을 위한 로그 error_log("Received data: " . print_r($data, true)); $pdo->beginTransaction(); $transactionStarted = true; error_log("트랜잭션 시작됨"); // work_num 처리 로직 $parentnum = null; if (!empty($data['work_num']) && is_numeric($data['work_num'])) { // work_num이 있는 경우 해당 번호가 존재하는지 확인 $checkSql = "SELECT num FROM work WHERE num = ?"; $checkStmt = $pdo->prepare($checkSql); $checkStmt->execute([$data['work_num']]); if ($checkStmt->rowCount() > 0) { $parentnum = $data['work_num']; } else { throw new Exception('존재하지 않는 작업 번호입니다: ' . $data['work_num']); } } else { // work_num이 없으면 work 테이블 없이 handover만 저장 (parentnum을 NULL로) // 또는 work 테이블에 최소한의 레코드 생성 시도 try { // work 테이블에 기본 레코드 생성 시도 $workSql = "INSERT INTO work () VALUES ()"; $workStmt = $pdo->prepare($workSql); $workStmt->execute(); $parentnum = $pdo->lastInsertId(); error_log("빈 work 레코드 생성됨: " . $parentnum); } catch (PDOException $workError) { error_log("work 테이블 생성 실패: " . $workError->getMessage()); // work 레코드 생성에 실패하면 parentnum을 NULL로 설정 $parentnum = null; error_log("parentnum을 NULL로 설정"); } } error_log("parentnum 설정됨: " . $parentnum); if (empty($data['handover_num'])) { // 새 데이터 삽입 $sql = "INSERT INTO work_handover ( parentnum, workplacename, firstord, secondord, completion_date, contract_amount, contract_items, execution_status, secondary_piping, painting_caulking, equipment_cost, special_notes, meeting_attendees, contract_manager_signature, contract_manager_date, construction_pm_signature, construction_pm_date, department_head_signature, department_head_date, ceo_signature, ceo_date, priceIncludesVat, regist_day, regist_user, is_deleted ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?, 'N' )"; $stmt = $pdo->prepare($sql); $stmt->execute([ $parentnum, $data['workplacename'], $data['firstord'], $data['secondord'], $data['completion_date'], $data['contract_amount'], $data['contract_items'], $data['execution_status'], $data['secondary_piping'], $data['painting_caulking'], $data['equipment_cost'], $data['special_notes'], $data['meeting_attendees'], $data['contract_manager_signature'], $data['contract_manager_date'], $data['construction_pm_signature'], $data['construction_pm_date'], $data['department_head_signature'], $data['department_head_date'], $data['ceo_signature'], $data['ceo_date'], $data['priceIncludesVat'], $data['regist_user'] ]); $handover_num = $pdo->lastInsertId(); error_log("새 handover 레코드 생성됨: " . $handover_num); } else { // 기존 데이터 업데이트 $sql = "UPDATE work_handover SET workplacename = ?, firstord = ?, secondord = ?, completion_date = ?, contract_amount = ?, contract_items = ?, execution_status = ?, secondary_piping = ?, painting_caulking = ?, equipment_cost = ?, special_notes = ?, meeting_attendees = ?, contract_manager_signature = ?, contract_manager_date = ?, construction_pm_signature = ?, construction_pm_date = ?, department_head_signature = ?, department_head_date = ?, ceo_signature = ?, ceo_date = ?, priceIncludesVat = ?, update_day = NOW(), update_user = ? WHERE num = ? AND is_deleted = 'N'"; $stmt = $pdo->prepare($sql); $stmt->execute([ $data['workplacename'], $data['firstord'], $data['secondord'], $data['completion_date'], $data['contract_amount'], $data['contract_items'], $data['execution_status'], $data['secondary_piping'], $data['painting_caulking'], $data['equipment_cost'], $data['special_notes'], $data['meeting_attendees'], $data['contract_manager_signature'], $data['contract_manager_date'], $data['construction_pm_signature'], $data['construction_pm_date'], $data['department_head_signature'], $data['department_head_date'], $data['ceo_signature'], $data['ceo_date'], $data['priceIncludesVat'], $data['regist_user'], $data['handover_num'] ]); $handover_num = $data['handover_num']; } $pdo->commit(); ob_clean(); header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'message' => '저장되었습니다.', 'handover_num' => $handover_num, 'work_num' => $parentnum ]); } catch (Exception $e) { if (isset($pdo) && $transactionStarted) { try { $pdo->rollBack(); error_log("트랜잭션 롤백됨"); } catch (PDOException $rollbackError) { error_log("롤백 오류: " . $rollbackError->getMessage()); } } error_log("Handover save error: " . $e->getMessage()); error_log("Stack trace: " . $e->getTraceAsString()); // 더 자세한 에러 메시지 제공 $errorMessage = $e->getMessage(); if (strpos($errorMessage, 'foreign key constraint') !== false) { $errorMessage = 'work_num(' . ($data['work_num'] ?? 'null') . ')에 해당하는 작업이 존재하지 않습니다.'; } ob_clean(); header('Content-Type: application/json'); echo json_encode([ 'success' => false, 'message' => $errorMessage, 'debug_info' => [ 'work_num' => $data['work_num'] ?? 'null', 'handover_num' => $data['handover_num'] ?? 'null', 'transaction_started' => $transactionStarted ] ]); } catch (Error $e) { // PHP Fatal Error 처리 if (isset($pdo) && $transactionStarted) { try { $pdo->rollBack(); error_log("Fatal Error 후 트랜잭션 롤백됨"); } catch (PDOException $rollbackError) { error_log("Fatal Error 롤백 오류: " . $rollbackError->getMessage()); } } error_log("Handover Fatal Error: " . $e->getMessage()); error_log("Stack trace: " . $e->getTraceAsString()); ob_clean(); header('Content-Type: application/json'); echo json_encode([ 'success' => false, 'message' => 'PHP Fatal Error: ' . $e->getMessage() ]); } ?>