From b8c9d94a73efa0b03f1d58ea0da125ec275e60fd Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Mon, 6 Apr 2026 13:47:51 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9E=AC=EC=9E=91=EC=97=85=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=EC=A7=80=EC=A0=95=20=EA=B3=B5=EC=A0=95?= =?UTF-8?q?=EC=97=90=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - target_process_code가 있으면 해당 공정의 마스터를 찾아서 재작업 카드 생성 - 없으면 기존처럼 같은 공정에 생성 - 지정 공정의 seq_no, process_code, routing_detail_id 사용 --- .../controllers/popProductionController.ts | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/backend-node/src/controllers/popProductionController.ts b/backend-node/src/controllers/popProductionController.ts index 7dac3ad2..f896cf4c 100644 --- a/backend-node/src/controllers/popProductionController.ts +++ b/backend-node/src/controllers/popProductionController.ts @@ -998,14 +998,44 @@ export const saveResult = async ( // 재작업 카드 자동 생성 (disposition = 'rework' 항목이 있을 때) if (currentSeq.rowCount > 0 && defect_detail && Array.isArray(defect_detail)) { let totalReworkQty = 0; + let targetProcessCode: string | null = null; for (const item of defect_detail) { if (item.disposition === "rework") { totalReworkQty += parseInt(item.qty, 10) || 0; + if (item.target_process_code) targetProcessCode = item.target_process_code; } } if (totalReworkQty > 0) { const proc = currentSeq.rows[0]; const masterId = proc.parent_process_id || work_order_process_id; + + // 재작업 대상 공정 결정 + let reworkSeqNo = proc.seq_no; + let reworkProcessCode = proc.process_code; + let reworkProcessName = proc.process_name; + let reworkRoutingDetailId = proc.routing_detail_id; + let reworkMasterId = masterId; + + // target_process_code가 지정되면 해당 공정 정보를 조회 + if (targetProcessCode) { + const targetProc = await pool.query( + `SELECT id, seq_no, process_code, process_name, routing_detail_id + FROM work_order_process + WHERE wo_id = $1 AND process_code = $2 AND company_code = $3 + AND parent_process_id IS NULL + LIMIT 1`, + [proc.wo_id, targetProcessCode, companyCode] + ); + if (targetProc.rowCount > 0) { + const tp = targetProc.rows[0]; + reworkSeqNo = tp.seq_no; + reworkProcessCode = tp.process_code; + reworkProcessName = tp.process_name; + reworkRoutingDetailId = tp.routing_detail_id; + reworkMasterId = tp.id; // 지정 공정의 마스터 ID + } + } + const reworkInsert = await pool.query( `INSERT INTO work_order_process ( id, wo_id, seq_no, process_code, process_name, is_required, is_fixed_order, @@ -1020,23 +1050,25 @@ export const saveResult = async ( $12, $13, $14 ) RETURNING id`, [ - proc.wo_id, proc.seq_no, proc.process_code, proc.process_name, + proc.wo_id, reworkSeqNo, reworkProcessCode, reworkProcessName, proc.is_required, proc.is_fixed_order, proc.standard_time, - proc.equipment_code, proc.routing_detail_id, + proc.equipment_code, reworkRoutingDetailId, String(totalReworkQty), work_order_process_id, - masterId, companyCode, userId, + reworkMasterId, companyCode, userId, ] ); // 재작업 카드에 체크리스트 복사 const reworkId = reworkInsert.rows[0]?.id; if (reworkId) { const reworkChecklistCount = await copyChecklistToSplit( - pool, masterId, reworkId, proc.routing_detail_id, companyCode, userId + pool, reworkMasterId, reworkId, reworkRoutingDetailId, companyCode, userId ); logger.info("[pop/production] 재작업 카드 자동 생성", { reworkId, sourceId: work_order_process_id, reworkQty: totalReworkQty, + targetProcess: targetProcessCode || "(같은 공정)", + reworkSeqNo, checklistCount: reworkChecklistCount, }); }