From dc57a491dd72a12d7726893d86dfd8c1c56e4ef9 Mon Sep 17 00:00:00 2001 From: bicochan Date: Tue, 22 Sep 2026 15:02:36 +0900 Subject: [PATCH] =?UTF-8?q?[as]=20chore:=20=EC=9E=AC=EC=9B=90=ED=98=91?= =?UTF-8?q?=EC=9D=98=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/as/src/entities/elapr/index.ts | 1 + .../src/entities/elapr/lib/apln-validators.ts | 13 +++++++++++++ .../elapr/ui/elapr-apln-picker-grid.tsx | 8 +++++++- .../elapr/ui/elapr-doc-prgrs-picker-dialog.tsx | 7 +++++++ .../elapr/ui/elapr-tmplt-picker-dialog.tsx | 7 +++++++ .../model/fnrs-cnsltn-apply-payload-schema.ts | 2 +- .../pages/fnrs-cnsltn/ui/fnrs-form-page.tsx | 18 ++++++++++++++---- apps/as/src/shared/model/pbadms-sprt.ts | 2 +- .../ui/attachments-view-section.tsx | 13 +++++++------ .../pbadms-sprt/ui/fnrs-shar-form-section.tsx | 2 +- .../ui/splmnt-dmnd-form-section.tsx | 8 ++++++-- 11 files changed, 65 insertions(+), 16 deletions(-) diff --git a/apps/as/src/entities/elapr/index.ts b/apps/as/src/entities/elapr/index.ts index 777245649..2210dfc17 100644 --- a/apps/as/src/entities/elapr/index.ts +++ b/apps/as/src/entities/elapr/index.ts @@ -41,6 +41,7 @@ export { validateAllRowsForSave, validateAplnRow, validateAtrzOrder, + validateUniqueAtrzAprvr, validateUniqueSeqNo, } from "./lib/apln-validators"; export { diff --git a/apps/as/src/entities/elapr/lib/apln-validators.ts b/apps/as/src/entities/elapr/lib/apln-validators.ts index 8b75b4279..8ff1d997e 100644 --- a/apps/as/src/entities/elapr/lib/apln-validators.ts +++ b/apps/as/src/entities/elapr/lib/apln-validators.ts @@ -76,3 +76,16 @@ export function validateUniqueSeqNo(rows: ElaprAplnRow[]): string | null { } return null; } + +export function validateUniqueAtrzAprvr(rows: ElaprAplnRow[]): string | null { + const pairSet = new Set(); + for (const row of getVisibleRows(rows)) { + const atrz = row.atrzSeComCd?.trim(); + const aprvr = row.aprvrUuid?.trim(); + if (!atrz || !aprvr) continue; + const key = `${atrz}::${aprvr}`; + if (pairSet.has(key)) return "동일한 결재구분과 결재자가 중복됩니다."; + pairSet.add(key); + } + return null; +} diff --git a/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx b/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx index c8c84e1c6..f5a065ff6 100644 --- a/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx @@ -17,7 +17,7 @@ import { } from "@common/components"; import { useElaprAplnPage } from "../api/queries"; -import { validateAplnRow } from "../lib/apln-validators"; +import { validateAplnRow, validateUniqueAtrzAprvr } from "../lib/apln-validators"; import { useAplnRows } from "../lib/use-apln-rows"; import { useDndSensors } from "../lib/use-dnd-sensors"; import type { ElaprApln } from "../model/elapr-apln-interface"; @@ -110,6 +110,12 @@ function ElaprAplnPickerGrid({ return; } + const duplicateError = validateUniqueAtrzAprvr(rows); + if (duplicateError) { + alert(duplicateError); + return; + } + commitEdit(row.rowKey); } diff --git a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-picker-dialog.tsx b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-picker-dialog.tsx index 0d9b5161e..ec235ec5e 100644 --- a/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-picker-dialog.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-doc-prgrs-picker-dialog.tsx @@ -17,6 +17,7 @@ import { getVisibleRows, validateAllRowsForSave, validateAtrzOrder, + validateUniqueAtrzAprvr, validateUniqueSeqNo, } from "../lib/apln-validators"; import { mapDocPrgrsToAplnRows } from "../lib/doc-prgrs-to-apln-rows"; @@ -90,6 +91,12 @@ function ElaprDocPrgrsPickerDialog({ return; } + const atrzAprvrError = validateUniqueAtrzAprvr(aplnRows); + if (atrzAprvrError) { + alert(atrzAprvrError); + return; + } + const visibleRows = getVisibleRows(aplnRows); onConfirm?.({ aplnRows: visibleRows }); diff --git a/apps/as/src/entities/elapr/ui/elapr-tmplt-picker-dialog.tsx b/apps/as/src/entities/elapr/ui/elapr-tmplt-picker-dialog.tsx index aa70932e9..b61672ef8 100644 --- a/apps/as/src/entities/elapr/ui/elapr-tmplt-picker-dialog.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-tmplt-picker-dialog.tsx @@ -17,6 +17,7 @@ import { getVisibleRows, validateAllRowsForSave, validateAtrzOrder, + validateUniqueAtrzAprvr, validateUniqueSeqNo, } from "../lib/apln-validators"; import type { ElaprAplnRow } from "../model/elapr-apln-row-types"; @@ -106,6 +107,12 @@ function ElaprTmpltPickerDialog({ return; } + const atrzAprvrError = validateUniqueAtrzAprvr(aplnRows); + if (atrzAprvrError) { + alert(atrzAprvrError); + return; + } + const visibleRows = getVisibleRows(aplnRows); const payload: ElaprTmpltPickerConfirmPayload = { diff --git a/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-apply-payload-schema.ts b/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-apply-payload-schema.ts index 709ae9012..75b2a1804 100644 --- a/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-apply-payload-schema.ts +++ b/apps/as/src/entities/fnrs-cnsltn/model/fnrs-cnsltn-apply-payload-schema.ts @@ -65,7 +65,7 @@ export const fnrsCnsltnSplmntDmndItemSchema = z.object({ splmntArtclComCd: z.string().nullish(), splmntDmndCn: z.string().optional(), splmntDmndDt: z.string().optional(), - splmntDmndAtchFileGroupId: z.string().optional(), + splmntDmndAtchFileGroupId: z.string().nullish(), splmntCn: z.string().optional(), splmntPicNm: z.string().optional(), splmntCmptnDt: z.string().optional(), diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx index 87a3dc4b0..cff36df8a 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/fnrs-form-page.tsx @@ -18,6 +18,7 @@ import { fnrsCnsltnMngService, } from "@/entities/fnrs-cnsltn"; import { useFnrsSharSeMngTree } from "@/entities/fnrs-shar-se"; +import { findCompletedPwrkDraft, usePwrkCnsltnMngByUpDocNo } from "@/entities/pwrk-cnsltn-mng"; import { AttachmentsFormSection, buildAcntgCostItems, @@ -35,7 +36,10 @@ import { } from "@/widgets/pbadms-sprt"; import { Button } from "@common/components"; -import { type FnrsCnsltnRegistFormData, fnrsCnsltnRegistSchema } from "../lib/fnrs-cnsltn-regist-schema"; +import { + type FnrsCnsltnRegistFormData, + fnrsCnsltnRegistSchema, +} from "../lib/fnrs-cnsltn-regist-schema"; import { buildFormPayload, getCreateDefaultValues, @@ -68,6 +72,12 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps) const isSplmntPrgrsStts = initialData?.detDto?.prgrsSttsComCd === "SL"; const fnrsCnsltnDocNo = initialData?.detDto?.fnrsCnsltnDocNo; + const { data: pwrkCnsltnData } = usePwrkCnsltnMngByUpDocNo( + fnrsCnsltnDocNo, + isSplmntPrgrsStts && Boolean(fnrsCnsltnDocNo), + ); + const hasCompletedDraft = Boolean(findCompletedPwrkDraft(pwrkCnsltnData)); + const { data: masterSharTree = [] } = useFnrsSharSeMngTree(); const { data: acntgTree = [] } = useAcntgSeMngTree(); const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "FNRS" }); @@ -126,7 +136,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps) (item) => !item.splmntCn || !item.splmntCn.trim(), ); if (hasEmptySplmntCn) { - alert("보완요청내용이 있습니다. 보완 완료내용을 입력해 주세요."); + alert("보완 요청 내용이 있습니다.\n보완 완료 내용을 입력해 주세요."); return; } @@ -305,7 +315,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps) ) : ( <> - {fnrsCnsltnDocNo ? ( + {hasCompletedDraft ? (