fix: 재작업 카드 접수 — 자체 input_qty 기반 접수 가능 (앞공정 무관)

This commit is contained in:
SeongHyun Kim
2026-04-06 14:07:11 +09:00
parent 507264a718
commit d1d823d5ca

View File

@@ -1629,33 +1629,51 @@ export const getAvailableQty = async (req: AuthenticatedRequest, res: Response)
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 reworkCheck = await pool.query(
`SELECT is_rework, input_qty FROM work_order_process WHERE id = $1`,
[work_order_process_id]
);
const myInputQty = parseInt(totalAccepted.rows[0].total_input, 10) || 0;
const isRework = reworkCheck.rows[0]?.is_rework === "Y";
// 앞공정 양품+특채 합산 (SPLIT만 — master 이중 집계 방지)
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
let myInputQty: number;
let prevGoodQty: number;
let availableQty: number;
if (isRework) {
// 재작업 카드: 자체 input_qty가 접수 가능 수량
const reworkInput = parseInt(reworkCheck.rows[0]?.input_qty, 10) || 0;
myInputQty = 0;
prevGoodQty = reworkInput;
availableQty = reworkInput;
} else {
// 일반 카드: 앞공정 양품 - 기접수합계 (재작업 카드 제외)
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, prevSeq, companyCode]
AND parent_process_id IS NOT NULL
AND (is_rework IS NULL OR is_rework != 'Y')`,
[wo_id, seq_no, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
}
}
myInputQty = parseInt(totalAccepted.rows[0].total_input, 10) || 0;
const availableQty = Math.max(0, prevGoodQty - myInputQty);
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
AND parent_process_id IS NOT NULL`,
[wo_id, prevSeq, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
}
}
availableQty = Math.max(0, prevGoodQty - myInputQty);
}
logger.info("[pop/production] available-qty 조회", {
work_order_process_id,
@@ -1751,33 +1769,52 @@ export const acceptProcess = async (req: AuthenticatedRequest, res: Response) =>
const instrQty = parseInt(row.instruction_qty, 10) || 0;
const seqNum = parseInt(row.seq_no, 10);
// 같은 공정의 모든 분할 행 접수량 합산 (트랜잭션 내부 — 정확한 값)
const totalAccepted = await client.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 isReworkCard = await client.query(
`SELECT is_rework, input_qty FROM work_order_process WHERE id = $1`,
[work_order_process_id]
);
const currentTotalInput = parseInt(totalAccepted.rows[0].total_input, 10) || 0;
const isRework = isReworkCard.rows[0]?.is_rework === "Y";
const reworkInputQty = parseInt(isReworkCard.rows[0]?.input_qty, 10) || 0;
// 앞공정 양품+특채 합산
let prevGoodQty = instrQty;
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await client.query(
`SELECT COALESCE(SUM(good_qty::int), 0) + COALESCE(SUM(concession_qty::int), 0) as total_good
let prevGoodQty: number;
let currentTotalInput: number;
let availableQty: number;
if (isRework) {
// 재작업 카드: 자체 input_qty가 접수 가능 수량 (앞공정과 무관)
prevGoodQty = reworkInputQty;
currentTotalInput = 0; // 재작업 카드는 자체가 마스터, 분할 행 없음
availableQty = reworkInputQty;
} else {
// 일반 카드: 앞공정 양품 - 기접수합계
const totalAccepted = await client.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, prevSeq, companyCode]
AND parent_process_id IS NOT NULL
AND (is_rework IS NULL OR is_rework != 'Y')`,
[row.wo_id, row.seq_no, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
currentTotalInput = parseInt(totalAccepted.rows[0].total_input, 10) || 0;
prevGoodQty = instrQty;
if (seqNum > 1) {
const prevSeq = String(seqNum - 1);
const prevProcess = await client.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
AND parent_process_id IS NOT NULL`,
[row.wo_id, prevSeq, companyCode]
);
if (prevProcess.rowCount > 0) {
prevGoodQty = parseInt(prevProcess.rows[0].total_good, 10) || 0;
}
}
availableQty = prevGoodQty - currentTotalInput;
}
const availableQty = prevGoodQty - currentTotalInput;
if (qty > availableQty) {
await client.query("ROLLBACK");
client.release();