[as] chore: 재원협의 코드 수정

This commit is contained in:
2026-09-22 15:02:36 +09:00
parent 0dd2111cb9
commit dc57a491dd
11 changed files with 65 additions and 16 deletions
+1
View File
@@ -41,6 +41,7 @@ export {
validateAllRowsForSave,
validateAplnRow,
validateAtrzOrder,
validateUniqueAtrzAprvr,
validateUniqueSeqNo,
} from "./lib/apln-validators";
export {
@@ -76,3 +76,16 @@ export function validateUniqueSeqNo(rows: ElaprAplnRow[]): string | null {
}
return null;
}
export function validateUniqueAtrzAprvr(rows: ElaprAplnRow[]): string | null {
const pairSet = new Set<string>();
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;
}
@@ -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);
}
@@ -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 });
@@ -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 = {
@@ -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(),
@@ -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 ? (
<Button
color="orange"
type="button"
@@ -329,7 +339,7 @@ function FnrsFormPage({ mode, initialData, createDefaults }: FnrsFormPageProps)
</div>
</SectionCollapsibleGroup>
</form>
{fnrsCnsltnDocNo ? (
{hasCompletedDraft && fnrsCnsltnDocNo ? (
<PwrkCnsltnDocMngDialog
open={isPwrkCnsltnDocMngOpen}
fnrsCnsltnDocNo={fnrsCnsltnDocNo}
+1 -1
View File
@@ -207,7 +207,7 @@ export interface SplmntDmndSaveBase {
splmntArtclComCd?: string | null;
splmntDmndCn?: string;
splmntDmndDt?: string;
splmntDmndAtchFileGroupId?: string;
splmntDmndAtchFileGroupId?: string | null;
splmntCn?: string;
splmntPicNm?: string;
splmntCmptnDt?: string;
@@ -43,12 +43,13 @@ function AttachmentsViewSection({ esntlFileList, etcFileList }: AttachmentsViewS
) : (
<div className="space-y-2">
{files.map((file) => (
<AttachmentDownloadLink
key={file.atflId}
atflId={file.atflId}
fileName={file.orgnlFileNm || "다운로드"}
className="items-center"
/>
<div key={file.atflId}>
<AttachmentDownloadLink
atflId={file.atflId}
fileName={file.orgnlFileNm || "다운로드"}
className="items-center"
/>
</div>
))}
</div>
)}
@@ -282,7 +282,7 @@ function FnrsSharFormSection({ initialSharTree, initialSharAtchFiles }: FnrsShar
<div className="mt-6 px-2 pb-2">
<h3 className="mb-2 text-xl font-semibold">첨부파일</h3>
{!uploadedFile ? (
<p className="mb-2 text-lg text-muted-foreground">
<p className="mb-2 px-1 text-xl text-muted-foreground">
총사업비 신청서(.hwp) 파일을 등록해주세요.
</p>
) : null}
@@ -5,7 +5,11 @@ import { Controller, useFormContext, useWatch } from "react-hook-form";
import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib";
import { AttachmentFileField, SectionCollapsible } from "@/shared/ui";
import { AttachmentDownloadLink, attachService, useDownloadAttachmentByAtflId } from "@/entities/attach";
import {
AttachmentDownloadLink,
attachService,
useDownloadAttachmentByAtflId,
} from "@/entities/attach";
import {
Badge,
Table,
@@ -292,7 +296,7 @@ function SplmntDmndFormSection({ readOnly = false }: SplmntDmndFormSectionProps)
value={field.value ?? ""}
onChange={field.onChange}
onBlur={field.onBlur}
placeholder="보완완료 내용을 입력하세요."
placeholder="보완 완료 내용을 입력하세요."
className="min-h-[6rem] !text-xl"
/>
)}