ERP-node/backend-node/src/controllers/popProductionController.ts

1862 lines
64 KiB
TypeScript
Raw Normal View History

import { Response } from "express";
import { getPool } from "../database/db";
import logger from "../utils/logger";
import { AuthenticatedRequest } from "../middleware/authMiddleware";
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
// 불량 상세 항목 타입
interface DefectDetailItem {
defect_code: string;
defect_name: string;
qty: string;
disposition: string;
}
/**
*
* / .
*
* 전략: routingDetailId가 릿,
*/
async function copyChecklistToSplit(
client: { query: (text: string, values?: any[]) => Promise<any> },
masterProcessId: string,
newProcessId: string,
routingDetailId: string | null,
companyCode: string,
userId: string
): Promise<number> {
// A. routing_detail_id가 있으면 원본 템플릿(process_work_item + detail)에서 복사
if (routingDetailId) {
const result = await client.query(
`INSERT INTO process_work_result (
company_code, work_order_process_id,
source_work_item_id, source_detail_id,
work_phase, item_title, item_sort_order,
detail_content, detail_type, detail_sort_order, is_required,
inspection_code, inspection_method, unit, lower_limit, upper_limit,
input_type, lookup_target, display_fields, duration_minutes,
status, writer
)
SELECT
pwi.company_code, $1,
pwi.id, pwd.id,
pwi.work_phase, pwi.title, pwi.sort_order::text,
pwd.content, pwd.detail_type, pwd.sort_order::text, pwd.is_required,
pwd.inspection_code, pwd.inspection_method, pwd.unit, pwd.lower_limit, pwd.upper_limit,
pwd.input_type, pwd.lookup_target, pwd.display_fields, pwd.duration_minutes::text,
'pending', $2
FROM process_work_item pwi
JOIN process_work_item_detail pwd ON pwd.work_item_id = pwi.id
AND pwd.company_code = pwi.company_code
WHERE pwi.routing_detail_id = $3
AND pwi.company_code = $4
ORDER BY pwi.sort_order, pwd.sort_order`,
[newProcessId, userId, routingDetailId, companyCode]
);
return result.rowCount ?? 0;
}
// B. routing_detail_id가 없으면 마스터 행의 process_work_result에서 구조만 복사 (타이머/결과값 초기화)
const result = await client.query(
`INSERT INTO process_work_result (
company_code, work_order_process_id,
source_work_item_id, source_detail_id,
work_phase, item_title, item_sort_order,
detail_content, detail_type, detail_sort_order, is_required,
inspection_code, inspection_method, unit, lower_limit, upper_limit,
input_type, lookup_target, display_fields, duration_minutes,
status, writer
)
SELECT
company_code, $1,
source_work_item_id, source_detail_id,
work_phase, item_title, item_sort_order,
detail_content, detail_type, detail_sort_order, is_required,
inspection_code, inspection_method, unit, lower_limit, upper_limit,
input_type, lookup_target, display_fields, duration_minutes,
'pending', $2
FROM process_work_result
WHERE work_order_process_id = $3
AND company_code = $4
ORDER BY item_sort_order, detail_sort_order`,
[newProcessId, userId, masterProcessId, companyCode]
);
return result.rowCount ?? 0;
}
/**
* D-BE1: 작업지시
* PC에서 . 1 work_order_process + process_work_result .
*/
export const createWorkProcesses = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
const client = await pool.connect();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_instruction_id, item_code, routing_version_id, plan_qty } =
req.body;
if (!work_instruction_id || !routing_version_id) {
return res.status(400).json({
success: false,
message:
"work_instruction_id와 routing_version_id는 필수입니다.",
});
}
logger.info("[pop/production] create-work-processes 요청", {
companyCode,
userId,
work_instruction_id,
item_code,
routing_version_id,
plan_qty,
});
await client.query("BEGIN");
// 중복 호출 방지: 이미 생성된 공정이 있는지 확인
const existCheck = await client.query(
`SELECT COUNT(*) as cnt FROM work_order_process
WHERE wo_id = $1 AND company_code = $2`,
[work_instruction_id, companyCode]
);
if (parseInt(existCheck.rows[0].cnt, 10) > 0) {
await client.query("ROLLBACK");
return res.status(409).json({
success: false,
message: "이미 공정이 생성된 작업지시입니다.",
});
}
// 1. item_routing_detail + process_mng JOIN (공정 목록 + 공정명)
const routingDetails = await client.query(
`SELECT rd.id, rd.seq_no, rd.process_code,
COALESCE(pm.process_name, rd.process_code) as process_name,
rd.is_required, rd.is_fixed_order, rd.standard_time
FROM item_routing_detail rd
LEFT JOIN process_mng pm ON pm.process_code = rd.process_code
AND pm.company_code = rd.company_code
WHERE rd.routing_version_id = $1 AND rd.company_code = $2
ORDER BY CAST(rd.seq_no AS int) NULLS LAST`,
[routing_version_id, companyCode]
);
if (routingDetails.rows.length === 0) {
await client.query("ROLLBACK");
return res.status(404).json({
success: false,
message: "라우팅 버전에 등록된 공정이 없습니다.",
});
}
const processes: Array<{
id: string;
seq_no: string;
process_name: string;
checklist_count: number;
}> = [];
let totalChecklists = 0;
for (const rd of routingDetails.rows) {
// 2. work_order_process INSERT
const wopResult = await client.query(
`INSERT INTO work_order_process (
company_code, wo_id, seq_no, process_code, process_name,
is_required, is_fixed_order, standard_time, plan_qty,
status, routing_detail_id, writer
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
RETURNING id`,
[
companyCode,
work_instruction_id,
rd.seq_no,
rd.process_code,
rd.process_name,
rd.is_required,
rd.is_fixed_order,
rd.standard_time,
plan_qty || null,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
parseInt(rd.seq_no, 10) === 1 ? "acceptable" : "waiting",
rd.id,
userId,
]
);
const wopId = wopResult.rows[0].id;
// 3. process_work_result INSERT (공통 함수로 체크리스트 복사)
const checklistCount = await copyChecklistToSplit(
client, wopId, wopId, rd.id, companyCode, userId
);
totalChecklists += checklistCount;
processes.push({
id: wopId,
seq_no: rd.seq_no,
process_name: rd.process_name,
checklist_count: checklistCount,
});
logger.info("[pop/production] 공정 생성 완료", {
wopId,
processName: rd.process_name,
checklistCount,
});
}
await client.query("COMMIT");
logger.info("[pop/production] create-work-processes 완료", {
companyCode,
work_instruction_id,
total_processes: processes.length,
total_checklists: totalChecklists,
});
return res.json({
success: true,
data: {
processes,
total_processes: processes.length,
total_checklists: totalChecklists,
},
});
} catch (error: any) {
await client.query("ROLLBACK");
logger.error("[pop/production] create-work-processes 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "공정 생성 중 오류가 발생했습니다.",
});
} finally {
client.release();
}
};
/**
* D-BE2: 타이머 API (//)
*/
export const controlTimer = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_order_process_id, action } = req.body;
if (!work_order_process_id || !action) {
return res.status(400).json({
success: false,
message: "work_order_process_id와 action은 필수입니다.",
});
}
feat: BLOCK DETAIL Phase 4 + 안정화 - 그룹별 타이머, 터치 최적화 UI, DB 저장 버그 수정 pop-work-detail 컴포넌트에 그룹별 타이머 시스템과 터치 최적화 UI를 추가하고, 체크리스트 결과가 DB에 저장되지 않던 버그를 수정하여 안정화를 완료한다. [그룹별 타이머] - group-timer API 신규: start/pause/resume/complete 액션 (popProductionController) - process_work_result에 group_started_at/paused_at/total_paused_time/completed_at 활용 - GroupTimerHeader UI: 순수 작업시간 + 경과시간 이중 표시 - 첫 그룹 "시작" 시 work_order_process.started_at 자동 기록 (공정 시작 자동 감지) - 공정 완료 시 actual_work_time을 그룹 타이머 합산으로 백엔드 자동 계산 [터치 최적화 UI] - 12개 영역 전면 스케일업: 버튼 h-11~h-12, 입력 h-11, 체크박스 h-6 w-6 - 사이드바 w-[180px], InfoBar text-sm, 최소 터치 영역 40~44px 확보 - 산업 현장 태블릿 터치 사용 최적화 [DB 저장 버그 수정] - saveResultValue/handleQuantityRegister: execute-action task 형식 수정 (fixedValue + lookupMode:"manual" + manualItemField/manualPkColumn:"id") - 원인: 백엔드가 __cart_row_key를 찾는데 프론트에서 id만 전송하여 lookup 실패 [디자이너 설정 확장] - displayMode: list/step 전환 설정 추가 - PopWorkDetailConfig: 표시 모드 Select 드롭다운 - types.ts: PopWorkDetailConfig 인터페이스 displayMode 추가 - PopCardListV2Component: parentRow.__processFlow__ 전달 보강
2026-03-17 09:32:59 +09:00
if (!["start", "pause", "resume", "complete"].includes(action)) {
return res.status(400).json({
success: false,
feat: BLOCK DETAIL Phase 4 + 안정화 - 그룹별 타이머, 터치 최적화 UI, DB 저장 버그 수정 pop-work-detail 컴포넌트에 그룹별 타이머 시스템과 터치 최적화 UI를 추가하고, 체크리스트 결과가 DB에 저장되지 않던 버그를 수정하여 안정화를 완료한다. [그룹별 타이머] - group-timer API 신규: start/pause/resume/complete 액션 (popProductionController) - process_work_result에 group_started_at/paused_at/total_paused_time/completed_at 활용 - GroupTimerHeader UI: 순수 작업시간 + 경과시간 이중 표시 - 첫 그룹 "시작" 시 work_order_process.started_at 자동 기록 (공정 시작 자동 감지) - 공정 완료 시 actual_work_time을 그룹 타이머 합산으로 백엔드 자동 계산 [터치 최적화 UI] - 12개 영역 전면 스케일업: 버튼 h-11~h-12, 입력 h-11, 체크박스 h-6 w-6 - 사이드바 w-[180px], InfoBar text-sm, 최소 터치 영역 40~44px 확보 - 산업 현장 태블릿 터치 사용 최적화 [DB 저장 버그 수정] - saveResultValue/handleQuantityRegister: execute-action task 형식 수정 (fixedValue + lookupMode:"manual" + manualItemField/manualPkColumn:"id") - 원인: 백엔드가 __cart_row_key를 찾는데 프론트에서 id만 전송하여 lookup 실패 [디자이너 설정 확장] - displayMode: list/step 전환 설정 추가 - PopWorkDetailConfig: 표시 모드 Select 드롭다운 - types.ts: PopWorkDetailConfig 인터페이스 displayMode 추가 - PopCardListV2Component: parentRow.__processFlow__ 전달 보강
2026-03-17 09:32:59 +09:00
message:
"action은 start, pause, resume, complete 중 하나여야 합니다.",
});
}
logger.info("[pop/production] timer 요청", {
companyCode,
userId,
work_order_process_id,
action,
});
let result;
switch (action) {
case "start":
// 최초 1회만 설정, 이미 있으면 무시
result = await pool.query(
`UPDATE work_order_process
SET started_at = CASE WHEN started_at IS NULL THEN NOW()::text ELSE started_at END,
status = CASE WHEN status = 'waiting' THEN 'in_progress' ELSE status END,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
RETURNING id, started_at, status`,
[work_order_process_id, companyCode]
);
break;
case "pause":
result = await pool.query(
`UPDATE work_order_process
SET paused_at = NOW()::text,
updated_date = NOW()
WHERE id = $1 AND company_code = $2 AND paused_at IS NULL
RETURNING id, paused_at`,
[work_order_process_id, companyCode]
);
break;
case "resume":
// 일시정지 시간 누적 후 paused_at 초기화
result = await pool.query(
`UPDATE work_order_process
SET total_paused_time = (
COALESCE(total_paused_time::int, 0)
+ EXTRACT(EPOCH FROM NOW() - paused_at::timestamp)::int
)::text,
paused_at = NULL,
updated_date = NOW()
WHERE id = $1 AND company_code = $2 AND paused_at IS NOT NULL
RETURNING id, total_paused_time`,
[work_order_process_id, companyCode]
);
break;
feat: BLOCK DETAIL Phase 4 + 안정화 - 그룹별 타이머, 터치 최적화 UI, DB 저장 버그 수정 pop-work-detail 컴포넌트에 그룹별 타이머 시스템과 터치 최적화 UI를 추가하고, 체크리스트 결과가 DB에 저장되지 않던 버그를 수정하여 안정화를 완료한다. [그룹별 타이머] - group-timer API 신규: start/pause/resume/complete 액션 (popProductionController) - process_work_result에 group_started_at/paused_at/total_paused_time/completed_at 활용 - GroupTimerHeader UI: 순수 작업시간 + 경과시간 이중 표시 - 첫 그룹 "시작" 시 work_order_process.started_at 자동 기록 (공정 시작 자동 감지) - 공정 완료 시 actual_work_time을 그룹 타이머 합산으로 백엔드 자동 계산 [터치 최적화 UI] - 12개 영역 전면 스케일업: 버튼 h-11~h-12, 입력 h-11, 체크박스 h-6 w-6 - 사이드바 w-[180px], InfoBar text-sm, 최소 터치 영역 40~44px 확보 - 산업 현장 태블릿 터치 사용 최적화 [DB 저장 버그 수정] - saveResultValue/handleQuantityRegister: execute-action task 형식 수정 (fixedValue + lookupMode:"manual" + manualItemField/manualPkColumn:"id") - 원인: 백엔드가 __cart_row_key를 찾는데 프론트에서 id만 전송하여 lookup 실패 [디자이너 설정 확장] - displayMode: list/step 전환 설정 추가 - PopWorkDetailConfig: 표시 모드 Select 드롭다운 - types.ts: PopWorkDetailConfig 인터페이스 displayMode 추가 - PopCardListV2Component: parentRow.__processFlow__ 전달 보강
2026-03-17 09:32:59 +09:00
case "complete": {
const { good_qty, defect_qty } = req.body;
const groupSumResult = await pool.query(
`SELECT COALESCE(SUM(
CASE WHEN group_started_at IS NOT NULL AND group_completed_at IS NOT NULL THEN
EXTRACT(EPOCH FROM group_completed_at::timestamp - group_started_at::timestamp)::int
- COALESCE(group_total_paused_time::int, 0)
ELSE 0 END
), 0)::text AS total_work_seconds
FROM process_work_result
WHERE work_order_process_id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
const calculatedWorkTime = groupSumResult.rows[0]?.total_work_seconds || "0";
result = await pool.query(
`UPDATE work_order_process
SET status = 'completed',
completed_at = NOW()::text,
completed_by = $3,
actual_work_time = $4,
good_qty = COALESCE($5, good_qty),
defect_qty = COALESCE($6, defect_qty),
paused_at = NULL,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
AND status != 'completed'
RETURNING id, status, completed_at, completed_by, actual_work_time, good_qty, defect_qty`,
[
work_order_process_id,
companyCode,
userId,
calculatedWorkTime,
good_qty || null,
defect_qty || null,
]
);
break;
}
}
if (!result || result.rowCount === 0) {
return res.status(404).json({
success: false,
message: "대상 공정을 찾을 수 없거나 현재 상태에서 수행할 수 없습니다.",
});
}
logger.info("[pop/production] timer 완료", {
action,
work_order_process_id,
result: result.rows[0],
});
return res.json({
success: true,
data: result.rows[0],
});
} catch (error: any) {
logger.error("[pop/production] timer 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "타이머 처리 중 오류가 발생했습니다.",
});
}
};
feat: BLOCK DETAIL Phase 4 + 안정화 - 그룹별 타이머, 터치 최적화 UI, DB 저장 버그 수정 pop-work-detail 컴포넌트에 그룹별 타이머 시스템과 터치 최적화 UI를 추가하고, 체크리스트 결과가 DB에 저장되지 않던 버그를 수정하여 안정화를 완료한다. [그룹별 타이머] - group-timer API 신규: start/pause/resume/complete 액션 (popProductionController) - process_work_result에 group_started_at/paused_at/total_paused_time/completed_at 활용 - GroupTimerHeader UI: 순수 작업시간 + 경과시간 이중 표시 - 첫 그룹 "시작" 시 work_order_process.started_at 자동 기록 (공정 시작 자동 감지) - 공정 완료 시 actual_work_time을 그룹 타이머 합산으로 백엔드 자동 계산 [터치 최적화 UI] - 12개 영역 전면 스케일업: 버튼 h-11~h-12, 입력 h-11, 체크박스 h-6 w-6 - 사이드바 w-[180px], InfoBar text-sm, 최소 터치 영역 40~44px 확보 - 산업 현장 태블릿 터치 사용 최적화 [DB 저장 버그 수정] - saveResultValue/handleQuantityRegister: execute-action task 형식 수정 (fixedValue + lookupMode:"manual" + manualItemField/manualPkColumn:"id") - 원인: 백엔드가 __cart_row_key를 찾는데 프론트에서 id만 전송하여 lookup 실패 [디자이너 설정 확장] - displayMode: list/step 전환 설정 추가 - PopWorkDetailConfig: 표시 모드 Select 드롭다운 - types.ts: PopWorkDetailConfig 인터페이스 displayMode 추가 - PopCardListV2Component: parentRow.__processFlow__ 전달 보강
2026-03-17 09:32:59 +09:00
/**
* ()
* ///
*/
export const controlGroupTimer = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const { work_order_process_id, source_work_item_id, action } = req.body;
if (!work_order_process_id || !source_work_item_id || !action) {
return res.status(400).json({
success: false,
message:
"work_order_process_id, source_work_item_id, action은 필수입니다.",
});
}
if (!["start", "pause", "resume", "complete"].includes(action)) {
return res.status(400).json({
success: false,
message:
"action은 start, pause, resume, complete 중 하나여야 합니다.",
});
}
logger.info("[pop/production] group-timer 요청", {
companyCode,
work_order_process_id,
source_work_item_id,
action,
});
const whereClause = `work_order_process_id = $1 AND source_work_item_id = $2 AND company_code = $3`;
const baseParams = [work_order_process_id, source_work_item_id, companyCode];
let result;
switch (action) {
case "start":
result = await pool.query(
`UPDATE process_work_result
SET group_started_at = CASE WHEN group_started_at IS NULL THEN NOW()::text ELSE group_started_at END,
updated_date = NOW()
WHERE ${whereClause}
RETURNING id, group_started_at`,
baseParams
);
await pool.query(
`UPDATE work_order_process
SET started_at = NOW()::text, updated_date = NOW()
WHERE id = $1 AND company_code = $2 AND started_at IS NULL`,
[work_order_process_id, companyCode]
);
break;
case "pause":
result = await pool.query(
`UPDATE process_work_result
SET group_paused_at = NOW()::text,
updated_date = NOW()
WHERE ${whereClause} AND group_paused_at IS NULL
RETURNING id, group_paused_at`,
baseParams
);
break;
case "resume":
result = await pool.query(
`UPDATE process_work_result
SET group_total_paused_time = (
COALESCE(group_total_paused_time::int, 0)
+ EXTRACT(EPOCH FROM NOW() - group_paused_at::timestamp)::int
)::text,
group_paused_at = NULL,
updated_date = NOW()
WHERE ${whereClause} AND group_paused_at IS NOT NULL
RETURNING id, group_total_paused_time`,
baseParams
);
break;
case "complete": {
result = await pool.query(
`UPDATE process_work_result
SET group_completed_at = NOW()::text,
group_total_paused_time = CASE
WHEN group_paused_at IS NOT NULL THEN (
COALESCE(group_total_paused_time::int, 0)
+ EXTRACT(EPOCH FROM NOW() - group_paused_at::timestamp)::int
)::text
ELSE group_total_paused_time
END,
group_paused_at = NULL,
updated_date = NOW()
WHERE ${whereClause}
RETURNING id, group_started_at, group_completed_at, group_total_paused_time`,
baseParams
);
break;
}
}
if (!result || result.rowCount === 0) {
return res.status(404).json({
success: false,
message: "대상 그룹을 찾을 수 없거나 현재 상태에서 수행할 수 없습니다.",
});
}
logger.info("[pop/production] group-timer 완료", {
action,
source_work_item_id,
affectedRows: result.rowCount,
});
return res.json({
success: true,
data: result.rows[0],
affectedRows: result.rowCount,
});
} catch (error: any) {
logger.error("[pop/production] group-timer 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "그룹 타이머 처리 중 오류가 발생했습니다.",
});
}
};
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
/**
* (defect_standard_mng)
*/
export const getDefectTypes = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
let query: string;
let params: unknown[];
if (companyCode === "*") {
query = `
SELECT id, defect_code, defect_name, defect_type, severity, company_code
FROM defect_standard_mng
WHERE is_active = 'Y'
ORDER BY defect_code`;
params = [];
} else {
query = `
SELECT id, defect_code, defect_name, defect_type, severity, company_code
FROM defect_standard_mng
WHERE is_active = 'Y' AND company_code = $1
ORDER BY defect_code`;
params = [companyCode];
}
const result = await pool.query(query, params);
logger.info("[pop/production] defect-types 조회", {
companyCode,
count: result.rowCount,
});
return res.json({
success: true,
data: result.rows,
});
} catch (error: any) {
logger.error("[pop/production] defect-types 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "불량 유형 조회 중 오류가 발생했습니다.",
});
}
};
/**
* ( )
* .
* result_status는 'draft' ( )
*/
export const saveResult = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const {
work_order_process_id,
production_qty,
good_qty,
defect_qty,
defect_detail,
result_note,
} = req.body;
if (!work_order_process_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id는 필수입니다.",
});
}
if (!production_qty || parseInt(production_qty, 10) <= 0) {
return res.status(400).json({
success: false,
message: "생산수량을 입력해주세요.",
});
}
const statusCheck = await pool.query(
`SELECT wop.status, wop.result_status, wop.total_production_qty, wop.good_qty,
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
wop.defect_qty, wop.concession_qty, wop.defect_detail,
wop.input_qty, wop.parent_process_id, wop.wo_id, wop.seq_no
FROM work_order_process wop
WHERE wop.id = $1 AND wop.company_code = $2`,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
[work_order_process_id, companyCode]
);
if (statusCheck.rowCount === 0) {
return res.status(404).json({
success: false,
message: "공정을 찾을 수 없습니다.",
});
}
const prev = statusCheck.rows[0];
// 마스터 행에 직접 실적 등록 방지 (분할 행이 존재하는 경우)
if (!prev.parent_process_id) {
const splitCheck = await pool.query(
`SELECT COUNT(*) as cnt FROM work_order_process
WHERE parent_process_id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
if (parseInt(splitCheck.rows[0].cnt, 10) > 0) {
return res.status(400).json({
success: false,
message: "원본 공정에는 직접 실적을 등록할 수 없습니다. 분할된 접수 카드에서 등록해주세요.",
});
}
}
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (prev.result_status === "confirmed") {
return res.status(403).json({
success: false,
message: "이미 확정된 실적입니다. 추가 등록이 불가능합니다.",
});
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 초과 생산 경고 (차단하지 않음 - 현장 유연성)
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const prevTotal = parseInt(prev.total_production_qty, 10) || 0;
const acceptedQty = parseInt(prev.input_qty, 10) || 0;
const requestedQty = parseInt(production_qty, 10) || 0;
if (acceptedQty > 0 && (prevTotal + requestedQty) > acceptedQty) {
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
logger.warn("[pop/production] 초과 생산 감지", {
work_order_process_id,
prevTotal, requestedQty, acceptedQty,
overAmount: (prevTotal + requestedQty) - acceptedQty,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 서버 측 양품/불량/특채 계산 (클라이언트 good_qty는 참고만)
const addProduction = parseInt(production_qty, 10) || 0;
let addDefect = 0;
let addConcession = 0;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
let defectDetailStr: string | null = null;
if (defect_detail && Array.isArray(defect_detail)) {
const validated = defect_detail.map((item: DefectDetailItem) => ({
defect_code: item.defect_code || "",
defect_name: item.defect_name || "",
qty: item.qty || "0",
disposition: item.disposition || "scrap",
}));
defectDetailStr = JSON.stringify(validated);
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
for (const item of validated) {
const itemQty = parseInt(item.qty, 10) || 0;
addDefect += itemQty;
if (item.disposition === "accept") {
addConcession += itemQty;
}
}
} else {
addDefect = parseInt(defect_qty, 10) || 0;
}
const addGood = addProduction - addDefect;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const newTotal = (parseInt(prev.total_production_qty, 10) || 0) + addProduction;
const newGood = (parseInt(prev.good_qty, 10) || 0) + addGood;
const newDefect = (parseInt(prev.defect_qty, 10) || 0) + addDefect;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
const newConcession = (parseInt(prev.concession_qty, 10) || 0) + addConcession;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
// 기존 defect_detail에 이번 차수 상세를 병합
let mergedDefectDetail: string | null = null;
if (defectDetailStr) {
let existingEntries: DefectDetailItem[] = [];
try {
existingEntries = prev.defect_detail ? JSON.parse(prev.defect_detail) : [];
} catch { /* 파싱 실패 시 빈 배열 */ }
const newEntries: DefectDetailItem[] = JSON.parse(defectDetailStr);
const merged = [...existingEntries];
for (const ne of newEntries) {
const existing = merged.find(
(e) => e.defect_code === ne.defect_code && e.disposition === ne.disposition
);
if (existing) {
existing.qty = String(
(parseInt(existing.qty, 10) || 0) + (parseInt(ne.qty, 10) || 0)
);
} else {
merged.push(ne);
}
}
mergedDefectDetail = JSON.stringify(merged);
}
const result = await pool.query(
`UPDATE work_order_process
SET total_production_qty = $3,
good_qty = $4,
defect_qty = $5,
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
concession_qty = $9,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
defect_detail = COALESCE($6, defect_detail),
result_note = COALESCE($7, result_note),
result_status = 'draft',
status = CASE WHEN status IN ('acceptable', 'waiting') THEN 'in_progress' ELSE status END,
writer = $8,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
RETURNING id, total_production_qty, good_qty, defect_qty, concession_qty, defect_detail, result_note, result_status, status`,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
[
work_order_process_id,
companyCode,
String(newTotal),
String(newGood),
String(newDefect),
mergedDefectDetail,
result_note || null,
userId,
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
String(newConcession),
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
]
);
if (result.rowCount === 0) {
return res.status(404).json({
success: false,
message: "공정을 찾을 수 없거나 권한이 없습니다.",
});
}
// 현재 분할 행의 공정 정보 조회
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const currentSeq = await pool.query(
`SELECT wop.seq_no, wop.wo_id, wop.input_qty as current_input_qty,
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
wop.parent_process_id, wop.process_code, wop.process_name,
wop.is_required, wop.is_fixed_order, wop.standard_time,
wop.equipment_code, wop.routing_detail_id,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
wi.qty as instruction_qty
FROM work_order_process wop
JOIN work_instruction wi ON wop.wo_id = wi.id AND wop.company_code = wi.company_code
WHERE wop.id = $1 AND wop.company_code = $2`,
[work_order_process_id, companyCode]
);
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 재작업 카드 자동 생성 (disposition = 'rework' 항목이 있을 때)
if (currentSeq.rowCount > 0 && defect_detail && Array.isArray(defect_detail)) {
let totalReworkQty = 0;
for (const item of defect_detail) {
if (item.disposition === "rework") {
totalReworkQty += parseInt(item.qty, 10) || 0;
}
}
if (totalReworkQty > 0) {
const proc = currentSeq.rows[0];
const masterId = proc.parent_process_id || work_order_process_id;
const reworkInsert = await pool.query(
`INSERT INTO work_order_process (
wo_id, seq_no, process_code, process_name, is_required, is_fixed_order,
standard_time, equipment_code, routing_detail_id,
status, input_qty, good_qty, defect_qty, concession_qty, total_production_qty,
result_status, is_rework, rework_source_id,
parent_process_id, company_code, writer
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9,
'acceptable', $10, '0', '0', '0', '0',
'draft', 'Y', $11,
$12, $13, $14
) RETURNING id`,
[
proc.wo_id, proc.seq_no, proc.process_code, proc.process_name,
proc.is_required, proc.is_fixed_order, proc.standard_time,
proc.equipment_code, proc.routing_detail_id,
String(totalReworkQty), work_order_process_id,
masterId, companyCode, userId,
]
);
// 재작업 카드에 체크리스트 복사
const reworkId = reworkInsert.rows[0]?.id;
if (reworkId) {
const reworkChecklistCount = await copyChecklistToSplit(
pool, masterId, reworkId, proc.routing_detail_id, companyCode, userId
);
logger.info("[pop/production] 재작업 카드 자동 생성", {
reworkId,
sourceId: work_order_process_id,
reworkQty: totalReworkQty,
checklistCount: reworkChecklistCount,
});
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
}
}
// 다음 공정 활성화: 양품 발생 시 다음 seq_no의 원본(마스터) 행을 acceptable로
// waiting -> acceptable (최초 활성화)
// in_progress -> acceptable (앞공정 추가양품으로 접수가능량 복원)
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (addGood > 0 && currentSeq.rowCount > 0) {
const { seq_no, wo_id } = currentSeq.rows[0];
const nextSeq = String(parseInt(seq_no, 10) + 1);
const nextUpdate = await pool.query(
`UPDATE work_order_process
SET status = CASE WHEN status IN ('waiting', 'in_progress') THEN 'acceptable' ELSE status END,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
updated_date = NOW()
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NULL
AND status != 'completed'
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
RETURNING id, process_name, status`,
[wo_id, nextSeq, companyCode]
);
if (nextUpdate.rowCount > 0) {
logger.info("[pop/production] 다음 공정 상태 전환", {
nextProcess: nextUpdate.rows[0],
});
}
}
// 개별 분할 행 자동완료: 이 분할 행의 접수분 전량 생산 시 completed
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (currentSeq.rowCount > 0) {
const { seq_no, wo_id, current_input_qty, instruction_qty } = currentSeq.rows[0];
const myInputQty = parseInt(current_input_qty, 10) || 0;
if (newTotal >= myInputQty && myInputQty > 0) {
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
await pool.query(
`UPDATE work_order_process
SET status = 'completed',
result_status = 'confirmed',
completed_at = NOW()::text,
completed_by = $3,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
AND status != 'completed'`,
[work_order_process_id, companyCode, userId]
);
logger.info("[pop/production] 분할 행 자동 완료", {
work_order_process_id, newTotal, myInputQty,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
// 같은 공정의 모든 분할 행이 completed인지 체크 -> 원본도 completed로
const seqNum = parseInt(seq_no, 10);
const instrQty = parseInt(instruction_qty, 10) || 0;
// 앞공정 양품 합산 (접수가능 잔여 계산용)
let prevGoodQty = instrQty;
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3`,
[wo_id, prevSeq, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
}
}
// 같은 seq_no의 모든 분할 행 접수량 합산 + 미완료 행 카운트
const siblingCheck = await pool.query(
`SELECT
COALESCE(SUM(input_qty::int), 0) as total_input,
COUNT(*) FILTER (WHERE status != 'completed') as incomplete_count
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NOT NULL`,
[wo_id, seq_no, companyCode]
);
const totalInput = parseInt(siblingCheck.rows[0].total_input, 10) || 0;
const incompleteCount = parseInt(siblingCheck.rows[0].incomplete_count, 10) || 0;
const remainingAcceptable = prevGoodQty - totalInput;
// 모든 분할 행 완료 + 잔여 접수가능 0 -> 원본(마스터)도 completed
if (incompleteCount === 0 && remainingAcceptable <= 0) {
const masterId = currentSeq.rows[0].parent_process_id;
if (masterId) {
await pool.query(
`UPDATE work_order_process
SET status = 'completed',
result_status = 'confirmed',
completed_at = NOW()::text,
completed_by = $3,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
AND status != 'completed'`,
[masterId, companyCode, userId]
);
logger.info("[pop/production] 원본(마스터) 공정 자동 완료", {
masterId, totalInput, prevGoodQty,
});
}
}
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 작업지시 전체 완료 판정
const { wo_id: woIdForWi } = currentSeq.rows[0];
await checkAndCompleteWorkInstruction(pool, woIdForWi, companyCode, userId);
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
logger.info("[pop/production] save-result 완료 (누적)", {
companyCode,
work_order_process_id,
added: { production_qty: addProduction, good_qty: addGood, defect_qty: addDefect },
accumulated: { total: newTotal, good: newGood, defect: newDefect },
});
// 자동 완료 후 최신 데이터 반환 (status가 변경되었을 수 있음)
const latestData = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`SELECT id, total_production_qty, good_qty, defect_qty, concession_qty, defect_detail, result_note, result_status, status, input_qty
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
FROM work_order_process WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
return res.json({
success: true,
data: latestData.rows[0] || result.rows[0],
});
} catch (error: any) {
logger.error("[pop/production] save-result 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "실적 저장 중 오류가 발생했습니다.",
});
}
};
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
/**
* (work_instruction)
* completed이면
*/
const checkAndCompleteWorkInstruction = async (
pool: any,
woId: string,
companyCode: string,
userId: string
) => {
const maxSeqResult = await pool.query(
`SELECT MAX(seq_no::int) as max_seq
FROM work_order_process
WHERE wo_id = $1 AND company_code = $2`,
[woId, companyCode]
);
if (maxSeqResult.rowCount === 0 || !maxSeqResult.rows[0].max_seq) return;
const maxSeq = String(maxSeqResult.rows[0].max_seq);
const incompleteCheck = await pool.query(
`SELECT COUNT(*) as cnt
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND status != 'completed'`,
[woId, maxSeq, companyCode]
);
if (parseInt(incompleteCheck.rows[0].cnt, 10) > 0) return;
const totalGoodResult = await pool.query(
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3`,
[woId, maxSeq, companyCode]
);
const completedQty = totalGoodResult.rows[0].total_good;
const updateResult = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`UPDATE work_instruction
SET status = 'completed',
progress_status = 'completed',
completed_qty = $3,
writer = $4,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
AND status != 'completed'
RETURNING id, item_id`,
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
[woId, companyCode, String(completedQty), userId]
);
logger.info("[pop/production] 작업지시 전체 완료", {
woId, completedQty, companyCode,
});
// 생산완료→재고 입고: 마지막 공정의 target_warehouse_id가 설정된 경우 inventory_stock UPSERT
if (updateResult.rowCount > 0 && completedQty > 0) {
try {
const itemId = updateResult.rows[0].item_id;
// item_info에서 item_number 조회
const itemResult = await pool.query(
`SELECT item_number FROM item_info WHERE id = $1 AND company_code = $2`,
[itemId, companyCode]
);
if (itemResult.rowCount === 0) {
logger.warn("[pop/production] 재고입고 건너뜀: item_info 없음", { itemId, companyCode });
return;
}
const itemCode = itemResult.rows[0].item_number;
// 마지막 공정의 창고 설정 조회 (마스터 행에서)
const warehouseResult = await pool.query(
`SELECT target_warehouse_id, target_location_code
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NULL
LIMIT 1`,
[woId, maxSeq, companyCode]
);
if (warehouseResult.rowCount === 0 || !warehouseResult.rows[0].target_warehouse_id) {
logger.info("[pop/production] 재고입고 건너뜀: 목표창고 미설정", { woId });
return;
}
const warehouseCode = warehouseResult.rows[0].target_warehouse_id;
const locationCode = warehouseResult.rows[0].target_location_code || warehouseCode;
// inventory_stock UPSERT
await pool.query(
`INSERT INTO inventory_stock (id, company_code, item_code, warehouse_code, location_code, current_qty, last_in_date, created_date, updated_date, writer)
VALUES (gen_random_uuid()::text, $1, $2, $3, $4, $5, NOW(), NOW(), NOW(), $6)
ON CONFLICT (company_code, item_code, warehouse_code, location_code)
DO UPDATE SET current_qty = (COALESCE(inventory_stock.current_qty::numeric, 0) + $5::numeric)::text,
last_in_date = NOW(),
updated_date = NOW(),
writer = $6`,
[companyCode, itemCode, warehouseCode, locationCode, String(completedQty), userId]
);
logger.info("[pop/production] 생산완료→재고 입고 완료", {
woId, itemCode, warehouseCode, locationCode, qty: completedQty, companyCode,
});
} catch (inventoryError: any) {
// 재고 입고 실패해도 공정 완료는 유지 (재고는 보조 기능)
logger.error("[pop/production] 재고입고 오류 (공정 완료는 유지):", inventoryError);
}
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
};
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
/**
* .
* . save-result에서 .
*/
export const confirmResult = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_order_process_id } = req.body;
if (!work_order_process_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id는 필수입니다.",
});
}
const statusCheck = await pool.query(
`SELECT status, result_status, total_production_qty FROM work_order_process
WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
if (statusCheck.rowCount === 0) {
return res.status(404).json({
success: false,
message: "공정을 찾을 수 없습니다.",
});
}
const currentProcess = statusCheck.rows[0];
if (!currentProcess.total_production_qty ||
parseInt(currentProcess.total_production_qty, 10) <= 0) {
return res.status(400).json({
success: false,
message: "등록된 실적이 없습니다. 실적을 먼저 등록해주세요.",
});
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 수동 확정: 무조건 completed 처리 (수동 완료 용도)
const result = await pool.query(
`UPDATE work_order_process
SET result_status = 'confirmed',
status = 'completed',
completed_at = NOW()::text,
completed_by = $3,
writer = $3,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
RETURNING id, status, result_status, total_production_qty, good_qty, defect_qty`,
[work_order_process_id, companyCode, userId]
);
if (result.rowCount === 0) {
return res.status(404).json({
success: false,
message: "공정을 찾을 수 없습니다.",
});
}
// 공정 정보 조회 (다음 공정 활성화 + 마스터 캐스케이드용)
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const seqCheck = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`SELECT wop.seq_no, wop.wo_id, wop.parent_process_id,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
wi.qty as instruction_qty
FROM work_order_process wop
JOIN work_instruction wi ON wop.wo_id = wi.id AND wop.company_code = wi.company_code
WHERE wop.id = $1 AND wop.company_code = $2`,
[work_order_process_id, companyCode]
);
if (seqCheck.rowCount > 0) {
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
const { seq_no, wo_id, parent_process_id, instruction_qty } = seqCheck.rows[0];
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const seqNum = parseInt(seq_no, 10);
const instrQty = parseInt(instruction_qty, 10) || 0;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 다음 공정 활성화 (양품이 있으면)
const goodQty = parseInt(result.rows[0].good_qty, 10) || 0;
if (goodQty > 0) {
const nextSeq = String(seqNum + 1);
await pool.query(
`UPDATE work_order_process
SET status = CASE WHEN status IN ('waiting', 'in_progress') THEN 'acceptable' ELSE status END,
updated_date = NOW()
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NULL
AND status != 'completed'`,
[wo_id, nextSeq, companyCode]
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
);
}
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 마스터 자동완료 캐스케이드 (분할 행인 경우)
if (parent_process_id) {
let prevGoodQty = instrQty;
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await pool.query(
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3`,
[wo_id, prevSeq, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
}
}
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
const siblingCheck = await pool.query(
`SELECT
COALESCE(SUM(input_qty::int), 0) as total_input,
COUNT(*) FILTER (WHERE status != 'completed') as incomplete_count
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NOT NULL`,
[wo_id, seq_no, companyCode]
);
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const totalInput = parseInt(siblingCheck.rows[0].total_input, 10) || 0;
const incompleteCount = parseInt(siblingCheck.rows[0].incomplete_count, 10) || 0;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
const remainingAcceptable = prevGoodQty - totalInput;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
if (incompleteCount === 0 && remainingAcceptable <= 0) {
await pool.query(
`UPDATE work_order_process
SET status = 'completed',
result_status = 'confirmed',
completed_at = NOW()::text,
completed_by = $3,
updated_date = NOW()
WHERE id = $1 AND company_code = $2
AND status != 'completed'`,
[parent_process_id, companyCode, userId]
);
logger.info("[pop/production] confirmResult: 마스터 자동 완료", {
masterId: parent_process_id, totalInput, prevGoodQty,
});
}
}
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 작업지시 전체 완료 판정
await checkAndCompleteWorkInstruction(pool, wo_id, companyCode, userId);
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
logger.info("[pop/production] confirm-result 완료", {
companyCode,
work_order_process_id,
userId,
finalStatus: result.rows[0].status,
});
return res.json({
success: true,
data: result.rows[0],
});
} catch (error: any) {
logger.error("[pop/production] confirm-result 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "실적 확정 중 오류가 발생했습니다.",
});
}
};
/**
* (work_order_process_log에서 )
* total_production_qty =
*/
export const getResultHistory = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const rawWopId = req.query.work_order_process_id;
const work_order_process_id = Array.isArray(rawWopId) ? rawWopId[0] : rawWopId;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (!work_order_process_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id는 필수입니다.",
});
}
// 소유권 확인
const ownerCheck = await pool.query(
`SELECT id FROM work_order_process WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
if (ownerCheck.rowCount === 0) {
return res.status(404).json({ success: false, message: "공정을 찾을 수 없습니다." });
}
// 같은 changed_at 기준으로 그룹핑하여 차수별 이력 추출
// total_production_qty가 증가한(new_value > old_value) 로그만 = 실적 등록 시점
const historyResult = await pool.query(
`WITH grouped AS (
SELECT
changed_at,
MAX(changed_by) as changed_by,
MAX(CASE WHEN changed_column = 'total_production_qty' THEN old_value END) as total_old,
MAX(CASE WHEN changed_column = 'total_production_qty' THEN new_value END) as total_new,
MAX(CASE WHEN changed_column = 'good_qty' THEN old_value END) as good_old,
MAX(CASE WHEN changed_column = 'good_qty' THEN new_value END) as good_new,
MAX(CASE WHEN changed_column = 'defect_qty' THEN old_value END) as defect_old,
MAX(CASE WHEN changed_column = 'defect_qty' THEN new_value END) as defect_new
FROM work_order_process_log
WHERE original_id = $1
AND changed_column IN ('total_production_qty', 'good_qty', 'defect_qty')
AND new_value IS NOT NULL
GROUP BY changed_at
)
SELECT * FROM grouped
WHERE total_new IS NOT NULL
AND (COALESCE(total_new::int, 0) - COALESCE(total_old::int, 0)) > 0
ORDER BY changed_at ASC`,
[work_order_process_id]
);
const batches = historyResult.rows.map((row: any, idx: number) => {
const batchQty = (parseInt(row.total_new, 10) || 0) - (parseInt(row.total_old, 10) || 0);
const batchGood = (parseInt(row.good_new, 10) || 0) - (parseInt(row.good_old, 10) || 0);
const batchDefect = (parseInt(row.defect_new, 10) || 0) - (parseInt(row.defect_old, 10) || 0);
return {
seq: idx + 1,
batch_qty: batchQty,
batch_good: batchGood,
batch_defect: batchDefect,
accumulated_total: parseInt(row.total_new, 10) || 0,
changed_at: row.changed_at,
changed_by: row.changed_by,
};
});
logger.info("[pop/production] result-history 조회", {
work_order_process_id,
batchCount: batches.length,
});
return res.json({
success: true,
data: batches,
});
} catch (error: any) {
logger.error("[pop/production] result-history 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "이력 조회 중 오류가 발생했습니다.",
});
}
};
/**
* +
* GET /api/pop/production/available-qty?work_order_process_id=xxx
* : { prevGoodQty, myInputQty, availableQty, instructionQty }
*/
export const getAvailableQty = async (req: AuthenticatedRequest, res: Response) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const rawWopId = req.query.work_order_process_id;
const work_order_process_id = Array.isArray(rawWopId) ? rawWopId[0] : rawWopId;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (!work_order_process_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id가 필요합니다.",
});
}
const current = await pool.query(
`SELECT wop.seq_no, wop.wo_id, wop.parent_process_id,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
wi.qty as instruction_qty
FROM work_order_process wop
JOIN work_instruction wi ON wop.wo_id = wi.id AND wop.company_code = wi.company_code
WHERE wop.id = $1 AND wop.company_code = $2`,
[work_order_process_id, companyCode]
);
if (current.rowCount === 0) {
return res.status(404).json({ success: false, message: "공정을 찾을 수 없습니다." });
}
const { seq_no, wo_id, instruction_qty } = current.rows[0];
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const instrQty = parseInt(instruction_qty, 10) || 0;
const seqNum = parseInt(seq_no, 10);
// 같은 공정(wo_id + seq_no)의 모든 분할 행 접수량 합산
const totalAccepted = await pool.query(
`SELECT COALESCE(SUM(input_qty::int), 0) as total_input
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NOT NULL`,
[wo_id, seq_no, companyCode]
);
const myInputQty = parseInt(totalAccepted.rows[0].total_input, 10) || 0;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 앞공정 양품+특채 합산
let prevGoodQty = instrQty;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3`,
[wo_id, prevSeq, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
}
const availableQty = Math.max(0, prevGoodQty - myInputQty);
logger.info("[pop/production] available-qty 조회", {
work_order_process_id,
prevGoodQty,
myInputQty,
availableQty,
instructionQty: instrQty,
});
return res.json({
success: true,
data: {
prevGoodQty,
myInputQty,
availableQty,
instructionQty: instrQty,
},
});
} catch (error: any) {
logger.error("[pop/production] available-qty 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "접수가능량 조회 중 오류가 발생했습니다.",
});
}
};
/**
* ( )
* POST /api/pop/production/accept-process
* body: { work_order_process_id, accept_qty }
* - = .good_qty - .input_qty ( - input_qty)
* - (in_progress )
* - status: acceptable/waiting -> in_progress ( in_progress면 )
*/
export const acceptProcess = async (req: AuthenticatedRequest, res: Response) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_order_process_id, accept_qty } = req.body;
if (!work_order_process_id || !accept_qty) {
return res.status(400).json({
success: false,
message: "work_order_process_id와 accept_qty가 필요합니다.",
});
}
const qty = parseInt(accept_qty, 10);
if (qty <= 0) {
return res.status(400).json({ success: false, message: "접수 수량은 1 이상이어야 합니다." });
}
// 원본(마스터) 행 조회 - parent_process_id가 NULL인 행 또는 직접 지정된 행
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const current = await pool.query(
`SELECT wop.id, wop.seq_no, wop.wo_id, wop.status, wop.parent_process_id,
wop.process_code, wop.process_name, wop.is_required, wop.is_fixed_order,
wop.standard_time, wop.equipment_code, wop.routing_detail_id,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
wi.qty as instruction_qty
FROM work_order_process wop
JOIN work_instruction wi ON wop.wo_id = wi.id AND wop.company_code = wi.company_code
WHERE wop.id = $1 AND wop.company_code = $2`,
[work_order_process_id, companyCode]
);
if (current.rowCount === 0) {
return res.status(404).json({ success: false, message: "공정을 찾을 수 없습니다." });
}
const row = current.rows[0];
// 접수 대상은 원본(마스터) 행이어야 함
const masterId = row.parent_process_id || row.id;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (row.status === "completed") {
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
return res.status(400).json({ success: false, message: "이미 완료된 공정입니다." });
}
if (row.status !== "acceptable") {
return res.status(400).json({ success: false, message: `원본 공정 상태(${row.status})에서는 접수할 수 없습니다. 접수가능 상태의 카드에서 접수해주세요.` });
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
const instrQty = parseInt(row.instruction_qty, 10) || 0;
const seqNum = parseInt(row.seq_no, 10);
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
// 같은 공정(wo_id + seq_no)의 모든 분할 행 접수량 합산
const totalAccepted = await pool.query(
`SELECT COALESCE(SUM(input_qty::int), 0) as total_input
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3
AND parent_process_id IS NOT NULL`,
[row.wo_id, row.seq_no, companyCode]
);
const currentTotalInput = totalAccepted.rows[0].total_input;
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
// 앞공정 양품+특채 합산
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
let prevGoodQty = instrQty;
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await pool.query(
feat: BLOCK MES-HARDEN Phase 0~3 + 공정 흐름 스트립 필/칩 UI 개편 MES 불량 처분 체계(disposition 3종)를 구현하고, 공정 카드의 흐름 스트립을 현재 공정 중심 필/칩 윈도우로 전면 재설계한다. [Phase 0: 기반 안정화] - confirmResult: SUM 버그 수정 + 마스터 캐스케이드 완료 판정 - checkAndCompleteWorkInstruction: 헬퍼 함수 추출 (saveResult/confirmResult 양쪽에서 work_instruction 상태 갱신) - saveResult: 초과 생산 에러 -> 경고 로그로 변경 [Phase 1: UI 정리] - DISPOSITION_OPTIONS: 5종 -> 3종(폐기/재작업/특채) - 카드 수동 완료 버튼: in_progress + 생산 있음 + 미완료 시 표시 (__manualComplete -> confirmResult 호출) [Phase 2: 양품 계산 서버화] - concession_qty/is_rework/rework_source_id DB 컬럼 추가 - saveResult: defect_detail disposition별 서버 양품 계산 (addGood = addProduction - addDefect, addConcession 분리) - prevGoodQty 5곳: SUM(good_qty) + SUM(concession_qty) 통일 - 프론트 특채 표시: MesInProgressMetrics/MesCompletedMetrics [Phase 3: 재작업 카드] - saveResult: disposition=rework 시 동일 공정에 분할행 자동 INSERT (is_rework='Y', rework_source_id 연결, status='acceptable') - 프론트: amber "재작업" 배지 + MesAcceptableMetrics 재작업 전용 UI - 재작업 카드 접수가능 수량 버그 수정 (마스터 qty -> input_qty) [공정 흐름 스트립 UI 개편] - ProcessFlowStrip: 바 형태 -> 필/칩 5슬롯 윈도우 (+N/이전/현재/다음/+N, 현재 공정 항상 중앙) - 색상: 지나온=emerald(완료)/slate, 현재=primary, 완료=emerald, 대기=muted, 남은=amber
2026-03-18 16:38:22 +09:00
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
FROM work_order_process
WHERE wo_id = $1 AND seq_no = $2 AND company_code = $3`,
[row.wo_id, prevSeq, companyCode]
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
}
}
const availableQty = prevGoodQty - currentTotalInput;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (qty > availableQty) {
return res.status(400).json({
success: false,
message: `접수가능량(${availableQty})을 초과합니다. (앞공정 완료: ${prevGoodQty}, 기접수합계: ${currentTotalInput})`,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
}
// 분할 행 INSERT (원본 행에서 공정 정보 복사)
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
const result = await pool.query(
`INSERT INTO work_order_process (
wo_id, seq_no, process_code, process_name, is_required, is_fixed_order,
standard_time, equipment_code, routing_detail_id,
status, input_qty, good_qty, defect_qty, total_production_qty,
result_status, accepted_by, accepted_at, started_at,
parent_process_id, company_code, writer
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9,
'in_progress', $10, '0', '0', '0',
'draft', $11, NOW()::text, NOW()::text,
$12, $13, $11
) RETURNING id, input_qty, status, process_name, result_status, accepted_by`,
[
row.wo_id, row.seq_no, row.process_code, row.process_name,
row.is_required, row.is_fixed_order, row.standard_time,
row.equipment_code, row.routing_detail_id,
String(qty), userId, masterId, companyCode,
]
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
);
// 분할 행에 체크리스트 복사 (마스터의 routing_detail_id 또는 마스터의 기존 체크리스트에서)
const splitId = result.rows[0].id;
const checklistCount = await copyChecklistToSplit(
pool, masterId, splitId, row.routing_detail_id, companyCode, userId
);
// 마스터는 항상 acceptable 유지 (completed 전환은 saveResult에서 처리)
const newTotalInput = currentTotalInput + qty;
logger.info("[pop/production] accept-process 분할 접수 완료", {
companyCode, userId, masterId,
splitId,
acceptedQty: qty,
totalAccepted: newTotalInput,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
prevGoodQty,
checklistCount,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
return res.json({
success: true,
data: result.rows[0],
message: `${qty}개 접수 완료 (총 접수합계: ${newTotalInput})`,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
} catch (error: any) {
logger.error("[pop/production] accept-process 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "접수 중 오류가 발생했습니다.",
});
}
};
/**
* 취소: input_qty를 0 status를 acceptable로
* 조건: 아직 (total_production_qty)
*/
export const cancelAccept = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_order_process_id } = req.body;
if (!work_order_process_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id는 필수입니다.",
});
}
const current = await pool.query(
`SELECT id, status, input_qty, total_production_qty, result_status,
parent_process_id, wo_id, seq_no, process_name
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
FROM work_order_process
WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
if (current.rowCount === 0) {
return res.status(404).json({ success: false, message: "공정을 찾을 수 없습니다." });
}
const proc = current.rows[0];
// 분할 행만 취소 가능 (원본 행은 취소 대상이 아님)
if (!proc.parent_process_id) {
return res.status(400).json({
success: false,
message: "원본 공정은 접수 취소할 수 없습니다. 분할된 접수 카드에서 취소해주세요.",
});
}
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (proc.status !== "in_progress") {
return res.status(400).json({
success: false,
message: `현재 상태(${proc.status})에서는 접수 취소할 수 없습니다. 진행중 상태만 가능합니다.`,
});
}
const totalProduced = parseInt(proc.total_production_qty ?? "0", 10) || 0;
const currentInputQty = parseInt(proc.input_qty ?? "0", 10) || 0;
const unproducedQty = currentInputQty - totalProduced;
if (unproducedQty <= 0) {
return res.status(400).json({
success: false,
message: "취소할 미소진 접수분이 없습니다. 모든 접수량에 대해 실적이 등록되었습니다.",
});
}
let cancelledQty = unproducedQty;
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
if (totalProduced === 0) {
// 실적이 없으면 분할 행 완전 삭제
await pool.query(
`DELETE FROM work_order_process WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
} else {
// 실적이 있으면 input_qty를 실적 수량으로 축소 + 접수분 전량 생산이므로 completed
await pool.query(
`UPDATE work_order_process
SET input_qty = $3, status = 'completed', result_status = 'confirmed',
completed_at = NOW()::text, completed_by = $4,
updated_date = NOW(), writer = $4
WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode, String(totalProduced), userId]
);
}
// 원본(마스터) 행을 다시 acceptable로 복원 (잔여 접수 가능하도록)
await pool.query(
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
`UPDATE work_order_process
SET status = 'acceptable', updated_date = NOW()
WHERE id = $1 AND company_code = $2 AND parent_process_id IS NULL`,
[proc.parent_process_id, companyCode]
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
);
logger.info("[pop/production] cancel-accept 완료 (분할 행)", {
companyCode, userId, work_order_process_id,
masterId: proc.parent_process_id,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
previousInputQty: currentInputQty,
totalProduced,
cancelledQty,
action: totalProduced === 0 ? "DELETE" : "SHRINK",
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
return res.json({
success: true,
data: { id: work_order_process_id, process_name: proc.process_name },
message: `미소진 ${cancelledQty}개 접수가 취소되었습니다.`,
feat: BLOCK MES-REWORK - mes-process-card 전용 카드 + batch_done 워크플로우 + 실적 관리 강화 MES 카드를 CSS Grid 다중 셀 방식에서 Flexbox 기반 단일 전용 카드(mes-process-card)로 전환하고, batch_done 상태를 도입하여 부분 확정 후 추가접수 워크플로우를 구현한다. [mes-process-card 전용 카드] - CardCellType "mes-process-card" 신규: 상태별 좌측 보더+배경, 공정 흐름 스트립, 클릭 모달 - MesAcceptableMetrics / MesInProgressMetrics / MesCompletedMetrics 서브 컴포넌트 - 워크플로우 기반 activeBtn 결정 로직 (상태+잔여량 조합으로 버튼 1개만 표시) - 하드코딩 취소 버튼 제거, DB 설정 "접수취소" 라벨 인터셉트로 통합 [batch_done 워크플로우] - confirmResult API: 부분 확정 시 status = 'batch_done' (진행 탭 숨김 + 접수가능 탭 유지) - acceptProcess API: batch_done -> in_progress 복귀 (추가접수) - 카드 복제 로직에 batch_done 포함 (잔여량 있으면 접수가능 탭에 클론 카드) - status 매핑에 batch_done 추가 (semantic: active) [실적 관리 강화] - PopWorkDetailComponent: 실적 입력 UI 전면 구현 (차수별 등록, 누적 실적, 이력 표시) - 모든 실적 저장 시 process_completed 이벤트 발행 (카드 리스트 즉시 갱신) - 전량접수+전량생산 시 자동 완료 (status=completed, result_status=confirmed) [버그 수정] - 서브 필터 변경 시 __process_* 필드 미갱신 -> processFields 재주입 - cancelAccept SQL inconsistent types -> boolean 파라미터 분리 - 접수취소 라벨 매핑 누락 -> taskPreset 조건 확장
2026-03-17 21:36:43 +09:00
});
} catch (error: any) {
logger.error("[pop/production] cancel-accept 오류:", error);
return res.status(500).json({
success: false,
message: error.message || "접수 취소 중 오류가 발생했습니다.",
});
}
};
/**
* (POP )
*/
export const getWarehouses = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const result = await pool.query(
`SELECT id, warehouse_code, warehouse_name, warehouse_type
FROM warehouse_info
WHERE company_code = $1 AND COALESCE(status, '') != '삭제'
ORDER BY warehouse_name`,
[companyCode]
);
return res.json({ success: true, data: result.rows });
} catch (error: any) {
logger.error("[pop/production] 창고 목록 조회 실패:", error);
return res.status(500).json({ success: false, message: error.message });
}
};
/**
* ()
* warehouseId는 warehouse_info.id warehouse_code를 warehouse_location과
*/
export const getWarehouseLocations = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const { warehouseId } = req.params;
if (!warehouseId) {
return res.status(400).json({ success: false, message: "warehouseId는 필수입니다." });
}
// warehouse_info.id → warehouse_code 변환
const whInfo = await pool.query(
`SELECT warehouse_code FROM warehouse_info WHERE id = $1 AND company_code = $2`,
[warehouseId, companyCode]
);
if (whInfo.rowCount === 0) {
return res.json({ success: true, data: [] });
}
const warehouseCode = whInfo.rows[0].warehouse_code;
const result = await pool.query(
`SELECT id, location_code, location_name
FROM warehouse_location
WHERE warehouse_code = $1 AND company_code = $2
ORDER BY location_name`,
[warehouseCode, companyCode]
);
return res.json({ success: true, data: result.rows });
} catch (error: any) {
logger.error("[pop/production] 창고 위치 조회 실패:", error);
return res.status(500).json({ success: false, message: error.message });
}
};
/**
*
* wo_id에서 seq_no보다 ( )
*/
export const isLastProcess = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const { processId } = req.params;
if (!processId) {
return res.json({ success: true, data: { isLast: false } });
}
// 현재 공정의 wo_id와 seq_no 조회 (분할 행이면 parent의 seq_no 기준)
const process = await pool.query(
`SELECT wo_id, seq_no, parent_process_id
FROM work_order_process
WHERE id = $1 AND company_code = $2`,
[processId, companyCode]
);
if (process.rowCount === 0) {
return res.json({ success: true, data: { isLast: false } });
}
const { wo_id, seq_no, parent_process_id } = process.rows[0];
// 분할 행이면 마스터의 seq_no 기준으로 판단
let effectiveSeqNo = seq_no;
if (parent_process_id) {
const master = await pool.query(
`SELECT seq_no FROM work_order_process WHERE id = $1 AND company_code = $2`,
[parent_process_id, companyCode]
);
if (master.rowCount > 0) {
effectiveSeqNo = master.rows[0].seq_no;
}
}
const next = await pool.query(
`SELECT id FROM work_order_process
WHERE wo_id = $1 AND company_code = $2
AND CAST(seq_no AS int) > CAST($3 AS int)
AND parent_process_id IS NULL
LIMIT 1`,
[wo_id, companyCode, effectiveSeqNo]
);
// 현재 공정의 기존 창고 설정도 반환 (기본값 세팅용)
const warehouseInfo = await pool.query(
`SELECT target_warehouse_id, target_location_code
FROM work_order_process
WHERE id = $1 AND company_code = $2`,
[processId, companyCode]
);
return res.json({
success: true,
data: {
isLast: next.rowCount === 0,
woId: wo_id,
seqNo: effectiveSeqNo,
targetWarehouseId: warehouseInfo.rows[0]?.target_warehouse_id || null,
targetLocationCode: warehouseInfo.rows[0]?.target_location_code || null,
},
});
} catch (error: any) {
logger.error("[pop/production] 마지막 공정 확인 오류:", error);
return res.status(500).json({ success: false, message: error.message });
}
};
/**
* /
* .
* checkAndCompleteWorkInstruction이 .
*/
export const updateTargetWarehouse = async (
req: AuthenticatedRequest,
res: Response
) => {
const pool = getPool();
try {
const companyCode = req.user!.companyCode;
const userId = req.user!.userId;
const { work_order_process_id, target_warehouse_id, target_location_code } = req.body;
if (!work_order_process_id || !target_warehouse_id) {
return res.status(400).json({
success: false,
message: "work_order_process_id와 target_warehouse_id는 필수입니다.",
});
}
// 분할 행이면 마스터 행도 함께 업데이트
const procInfo = await pool.query(
`SELECT parent_process_id FROM work_order_process WHERE id = $1 AND company_code = $2`,
[work_order_process_id, companyCode]
);
const idsToUpdate = [work_order_process_id];
if (procInfo.rowCount > 0 && procInfo.rows[0].parent_process_id) {
idsToUpdate.push(procInfo.rows[0].parent_process_id);
}
for (const id of idsToUpdate) {
await pool.query(
`UPDATE work_order_process
SET target_warehouse_id = $3,
target_location_code = $4,
writer = $5,
updated_date = NOW()
WHERE id = $1 AND company_code = $2`,
[id, companyCode, target_warehouse_id, target_location_code || null, userId]
);
}
logger.info("[pop/production] 목표 창고 업데이트", {
companyCode, userId, work_order_process_id,
target_warehouse_id, target_location_code,
updatedIds: idsToUpdate,
});
return res.json({ success: true, data: { target_warehouse_id, target_location_code } });
} catch (error: any) {
logger.error("[pop/production] 목표 창고 업데이트 오류:", error);
return res.status(500).json({ success: false, message: error.message });
}
};