기무주서쿠의원장님 살려주십쇼

This commit is contained in:
DDD1542
2026-04-14 16:45:12 +09:00
parent 030ffb581b
commit 4d55aebe61
4 changed files with 167 additions and 33 deletions

View File

@@ -65,6 +65,7 @@ export async function getList(req: AuthenticatedRequest, res: Response) {
const whereClause =
conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
// 같은 (company_code, inbound_number) 헤더가 N건일 때 1건만 사용 (중복 헤더 가드)
const query = `
SELECT
im.id, im.company_code, im.inbound_number, im.inbound_type, im.inbound_date,
@@ -90,7 +91,11 @@ export async function getList(req: AuthenticatedRequest, res: Response) {
id.seq_no,
id.inbound_type AS detail_inbound_type,
wh.warehouse_name
FROM inbound_mng im
FROM (
SELECT DISTINCT ON (h.company_code, h.inbound_number) h.*
FROM inbound_mng h
ORDER BY h.company_code, h.inbound_number, h.created_date NULLS LAST
) im
LEFT JOIN inbound_detail id
ON id.inbound_id = im.inbound_number AND id.company_code = im.company_code
LEFT JOIN warehouse_info wh
@@ -146,9 +151,25 @@ export async function create(req: AuthenticatedRequest, res: Response) {
await client.query("BEGIN");
// 1. 헤더 INSERT (inbound_mng) — 품목 컬럼은 NULL
const headerResult = await client.query(
`INSERT INTO inbound_mng (
// 1. 헤더 — 같은 (company_code, inbound_number) 헤더가 있으면 reuse, 없으면 INSERT (멱등성)
let headerRow: any;
const existingHeader = await client.query(
`SELECT * FROM inbound_mng
WHERE company_code = $1 AND inbound_number = $2
ORDER BY created_date NULLS LAST
LIMIT 1`,
[companyCode, inboundNumber],
);
if (existingHeader.rows.length > 0) {
headerRow = existingHeader.rows[0];
logger.info("입고 헤더 reuse (멱등)", {
companyCode,
inboundNumber,
headerId: headerRow.id,
});
} else {
const headerResult = await client.query(
`INSERT INTO inbound_mng (
id, company_code, inbound_number, inbound_type, inbound_date,
warehouse_code, location_code,
inbound_status, inspector, manager, memo,
@@ -159,22 +180,22 @@ export async function create(req: AuthenticatedRequest, res: Response) {
$7, $8, $9, $10,
NOW(), $11, $11, '입고'
) RETURNING *`,
[
companyCode,
inboundNumber,
inboundType,
inbound_date || items[0].inbound_date,
warehouse_code || items[0].warehouse_code || null,
location_code || items[0].location_code || null,
items[0].inbound_status || "대기",
inspector || items[0].inspector || null,
manager || items[0].manager || null,
memo || items[0].memo || null,
userId,
],
);
const headerRow = headerResult.rows[0];
[
companyCode,
inboundNumber,
inboundType,
inbound_date || items[0].inbound_date,
warehouse_code || items[0].warehouse_code || null,
location_code || items[0].location_code || null,
items[0].inbound_status || "대기",
inspector || items[0].inspector || null,
manager || items[0].manager || null,
memo || items[0].memo || null,
userId,
],
);
headerRow = headerResult.rows[0];
}
const insertedDetails: any[] = [];
// 2. 디테일 INSERT (inbound_detail) + 재고/발주 업데이트