feat: Refactor work process and item inspection logic
- Updated SQL queries in `popProductionController` to separate work order process and result handling, ensuring batch_id is now managed in the work_order_process_result table. - Enhanced `workInstructionController` to include id generation for work items and details, preventing NULL values during insertion. - Implemented case-insensitive search functionality across various services, improving data retrieval accuracy. - Added sorting functionality in the item inspection page, allowing users to sort by different columns with visual indicators for sort direction. This refactor aims to improve data integrity and user experience across the production and inspection workflows.
This commit is contained in:
@@ -173,18 +173,21 @@ async function generateWorkProcessesForInstruction(
|
||||
total_checklists: number;
|
||||
} | null> {
|
||||
// 중복 호출 방지: 이미 생성된 공정이 있는지 확인 (batch_id 기준 분리)
|
||||
// ※ TASK:ERP-011 스키마 분리 반영 — batch_id는 실적 테이블(work_order_process_result)로 이동
|
||||
if (batchId) {
|
||||
// 다중 품목: 같은 wo_id + 같은 batch_id에 대해 이미 공정이 있으면 skip
|
||||
// 기준정보(work_order_process) ⟷ 실적(work_order_process_result) JOIN으로 확인
|
||||
const existCheck = await client.query(
|
||||
`SELECT COUNT(*) as cnt FROM work_order_process
|
||||
WHERE wo_id = $1 AND company_code = $2 AND batch_id = $3`,
|
||||
`SELECT COUNT(*) as cnt FROM work_order_process p
|
||||
JOIN work_order_process_result r ON r.wop_id = p.id
|
||||
WHERE p.wo_id = $1 AND p.company_code = $2 AND r.batch_id = $3`,
|
||||
[workInstructionId, companyCode, batchId],
|
||||
);
|
||||
if (parseInt(existCheck.rows[0].cnt, 10) > 0) {
|
||||
return null; // 이미 존재
|
||||
}
|
||||
} else {
|
||||
// 기존 동작: batch_id 없으면 wo_id 전체로 체크
|
||||
// 기존 동작: batch_id 없으면 wo_id 전체로 체크 (기준정보 테이블만 조회)
|
||||
const existCheck = await client.query(
|
||||
`SELECT COUNT(*) as cnt FROM work_order_process
|
||||
WHERE wo_id = $1 AND company_code = $2`,
|
||||
@@ -221,13 +224,14 @@ async function generateWorkProcessesForInstruction(
|
||||
let totalChecklists = 0;
|
||||
|
||||
for (const rd of routingDetails.rows) {
|
||||
// 2. work_order_process INSERT (batch_id 포함)
|
||||
// 2-A. work_order_process INSERT — 기준정보(TASK:ERP-011 분리 후)
|
||||
// status/batch_id는 실적 테이블로 이동했으므로 여기에서는 제외
|
||||
const wopResult = await client.query(
|
||||
`INSERT INTO work_order_process (
|
||||
id, company_code, wo_id, seq_no, process_code, process_name,
|
||||
is_required, is_fixed_order, standard_time, plan_qty,
|
||||
status, routing_detail_id, batch_id, writer
|
||||
) VALUES (gen_random_uuid()::text, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
||||
routing_detail_id, writer
|
||||
) VALUES (gen_random_uuid()::text, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
RETURNING id`,
|
||||
[
|
||||
companyCode,
|
||||
@@ -239,16 +243,26 @@ async function generateWorkProcessesForInstruction(
|
||||
rd.is_fixed_order,
|
||||
rd.standard_time,
|
||||
planQty || null,
|
||||
parseInt(rd.seq_no, 10) === 1 || rd.is_fixed_order === "Y"
|
||||
? "acceptable"
|
||||
: "waiting",
|
||||
rd.id,
|
||||
batchId || null,
|
||||
userId,
|
||||
],
|
||||
);
|
||||
const wopId = wopResult.rows[0].id;
|
||||
|
||||
// 2-B. work_order_process_result INSERT — 최초 실적 레코드 (seq=1)
|
||||
// 동일 client로 실행 → 트랜잭션 보호 유지
|
||||
// id는 wopId와 동일하게 부여 (초기 이관 정책 및 copyChecklistToSplit 호환 목적)
|
||||
const initialStatus =
|
||||
parseInt(rd.seq_no, 10) === 1 || rd.is_fixed_order === "Y"
|
||||
? "acceptable"
|
||||
: "waiting";
|
||||
await client.query(
|
||||
`INSERT INTO work_order_process_result (
|
||||
id, wop_id, seq, company_code, status, batch_id, writer
|
||||
) VALUES ($1, $2, 1, $3, $4, $5, $6)`,
|
||||
[wopId, wopId, companyCode, initialStatus, batchId || null, userId],
|
||||
);
|
||||
|
||||
// 3. process_work_result INSERT (공통 함수로 체크리스트 복사)
|
||||
const checklistCount = await copyChecklistToSplit(
|
||||
client,
|
||||
|
||||
Reference in New Issue
Block a user