From d795c74dbd40b2ad96216e5411b32504221cc9df Mon Sep 17 00:00:00 2001 From: SeongHyun Kim Date: Tue, 7 Apr 2026 17:11:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20POP=20=EC=9E=85=EA=B3=A0/=EC=B6=9C?= =?UTF-8?q?=EA=B3=A0=20=EC=B1=84=EB=B2=88=EA=B7=9C=EC=B9=99=EC=9D=84=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=84=A4=EC=A0=95=EA=B3=BC=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 백엔드: - receiving/generate-number: ?ruleId 쿼리 받아 numberingRuleService.allocateCode 사용 - outbound/generate-number: 동일 - ruleId 없거나 실패 시 기존 하드코딩 채번으로 폴백 프론트: - InboundCartPage: 확정 시 화면설정의 popConfig.inbound.numberingRuleId 읽어 ruleId 전달 - OutboundCartPage: 확정 시 화면설정의 popConfig.outbound.numberingRuleId 읽어 ruleId 전달 POP 화면설정에서 채번규칙 선택 → 입고/출고 확정 시 자동 적용 --- .../src/controllers/outboundController.ts | 15 ++++++++++++++- .../src/controllers/receivingController.ts | 16 +++++++++++++++- .../pop/hardcoded/inbound/InboundCartPage.tsx | 8 +++++++- .../pop/hardcoded/outbound/OutboundCartPage.tsx | 8 +++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/backend-node/src/controllers/outboundController.ts b/backend-node/src/controllers/outboundController.ts index b4b942a0..7e77974c 100644 --- a/backend-node/src/controllers/outboundController.ts +++ b/backend-node/src/controllers/outboundController.ts @@ -477,8 +477,21 @@ export async function getItems(req: AuthenticatedRequest, res: Response) { export async function generateNumber(req: AuthenticatedRequest, res: Response) { try { const companyCode = req.user!.companyCode; - const pool = getPool(); + const ruleId = (req.query.ruleId as string) || (req.query.rule_id as string); + // 1순위: POP 화면설정에서 선택한 채번규칙 사용 + if (ruleId && ruleId !== "__none__") { + try { + const { numberingRuleService } = await import("../services/numberingRuleService"); + const newNumber = await numberingRuleService.allocateCode(ruleId, companyCode); + return res.json({ success: true, data: newNumber }); + } catch (e: any) { + logger.warn("선택한 채번규칙 사용 실패, 기본 채번으로 폴백", { ruleId, error: e.message }); + } + } + + // 2순위: 기본 하드코딩 채번 (OUT-YYYY-XXXX) + const pool = getPool(); const today = new Date(); const yyyy = today.getFullYear(); const prefix = `OUT-${yyyy}-`; diff --git a/backend-node/src/controllers/receivingController.ts b/backend-node/src/controllers/receivingController.ts index 8f9c9863..fb358a06 100644 --- a/backend-node/src/controllers/receivingController.ts +++ b/backend-node/src/controllers/receivingController.ts @@ -881,8 +881,22 @@ export async function getItems(req: AuthenticatedRequest, res: Response) { export async function generateNumber(req: AuthenticatedRequest, res: Response) { try { const companyCode = req.user!.companyCode; - const pool = getPool(); + const ruleId = (req.query.ruleId as string) || (req.query.rule_id as string); + // 1순위: POP 화면설정에서 선택한 채번규칙 사용 + if (ruleId && ruleId !== "__none__") { + try { + const { numberingRuleService } = await import("../services/numberingRuleService"); + const newNumber = await numberingRuleService.allocateCode(ruleId, companyCode); + return res.json({ success: true, data: newNumber }); + } catch (e: any) { + logger.warn("선택한 채번규칙 사용 실패, 기본 채번으로 폴백", { ruleId, error: e.message }); + // 폴백 + } + } + + // 2순위: 기본 하드코딩 채번 (RCV-YYYY-XXXX) + const pool = getPool(); const today = new Date(); const yyyy = today.getFullYear(); const prefix = `RCV-${yyyy}-`; diff --git a/frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx b/frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx index 960794b4..06d142c2 100644 --- a/frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx +++ b/frontend/components/pop/hardcoded/inbound/InboundCartPage.tsx @@ -310,9 +310,15 @@ export function InboundCartPage() { try { // 확정 시점에 채번 (동시접속 충돌 방지) + // POP 화면설정에서 선택한 채번규칙 사용 (없으면 기본) let finalNumber = ""; try { - const numRes = await apiClient.get("/receiving/generate-number"); + const settingsRes: any = await apiClient.get("/screen-management/screens/6527/layout-pop").catch(() => null); + const ruleId = settingsRes?.data?.data?.settings?.popConfig?.inbound?.numberingRuleId; + const url = ruleId && ruleId !== "__none__" + ? `/receiving/generate-number?ruleId=${encodeURIComponent(ruleId)}` + : "/receiving/generate-number"; + const numRes = await apiClient.get(url); if (numRes.data?.success && numRes.data?.data) { finalNumber = numRes.data.data; setInboundNumber(finalNumber); diff --git a/frontend/components/pop/hardcoded/outbound/OutboundCartPage.tsx b/frontend/components/pop/hardcoded/outbound/OutboundCartPage.tsx index 918e0510..05fd095f 100644 --- a/frontend/components/pop/hardcoded/outbound/OutboundCartPage.tsx +++ b/frontend/components/pop/hardcoded/outbound/OutboundCartPage.tsx @@ -305,9 +305,15 @@ export function OutboundCartPage() { try { // Generate outbound number at confirm time + // POP 화면설정에서 선택한 채번규칙 사용 (없으면 기본) let finalNumber = ""; try { - const numRes = await apiClient.get("/outbound/generate-number"); + const settingsRes: any = await apiClient.get("/screen-management/screens/5/layout-pop").catch(() => null); + const ruleId = settingsRes?.data?.data?.settings?.popConfig?.outbound?.numberingRuleId; + const url = ruleId && ruleId !== "__none__" + ? `/outbound/generate-number?ruleId=${encodeURIComponent(ruleId)}` + : "/outbound/generate-number"; + const numRes = await apiClient.get(url); if (numRes.data?.success && numRes.data?.data) { finalNumber = numRes.data.data; setOutboundNumber(finalNumber);