구매관리 발주서 _outsourcing/_english 양식 + 양식 선택 모달

- 양식 선택 모달 신설 (운영판 wace 1:1: 일반/외주가공/영문/취소)
- 외주가공 발주서 다이얼로그 — 타이틀 변경, 좌 4필드, 그리드 WORK_ORDER_NO/업체명/제품명/부품명
- 영문 발주서 다이얼로그 — 영문 헤더, 2열 5행 필드(Shipment/Attn.to/Packing/Validity/Remarks),
  CURRENCY 컬럼, TOTAL, 서명영역(stamp_seal)
- proposal 발주서생성 → 양식 선택 모달, order 행클릭 → row.form_type 자동 분기
- listVendorOptions: client_mng.status 컬럼 부재로 빈배열 반환 → use_yn 사용 (RPS 함정)
- listUserOptions: name/position/phone/email alias 추가 (담당자 select 자동 채움)
- init API: USER_INFO 에서 안동윤/서동민 user_id lookup → sales_mng_user_id 자동 채움
This commit is contained in:
hjjeong
2026-05-19 14:12:33 +09:00
parent 806153174c
commit 8258c2f0cf
7 changed files with 1336 additions and 20 deletions
@@ -21,6 +21,9 @@ import { exportToExcel } from "@/lib/utils/excelExport";
import { Button } from "@/components/ui/button";
import { Pencil, Trash2 } from "lucide-react";
import { PurchaseOrderGeneralFormDialog } from "@/components/purchase/PurchaseOrderGeneralFormDialog";
import { PurchaseOrderOutsourcingFormDialog } from "@/components/purchase/PurchaseOrderOutsourcingFormDialog";
import { PurchaseOrderEnglishFormDialog } from "@/components/purchase/PurchaseOrderEnglishFormDialog";
import { PurchaseOrderFormType } from "@/components/purchase/PurchaseOrderFormTypeSelectDialog";
import { useConfirmDialog } from "@/components/common/ConfirmDialog";
const MAIL_SEND_OPTS: SmartSelectOption[] = [
@@ -69,9 +72,9 @@ export default function PurchaseOrderWacePage() {
const [productOpts, setProductOpts] = useState<OptionItem[]>([]);
const [purchaseOpts, setPurchaseOpts] = useState<OptionItem[]>([]);
// 수정 다이얼로그
const [editOpen, setEditOpen] = useState(false);
// 수정 다이얼로그 — form_type 따라 자동 분기
const [editObjid, setEditObjid] = useState<string>("");
const [editFormType, setEditFormType] = useState<PurchaseOrderFormType | "">("");
const { confirm, ConfirmDialogComponent } = useConfirmDialog();
const yearOpts = useMemo(() => getYearOptions(), []);
@@ -153,8 +156,10 @@ export default function PurchaseOrderWacePage() {
disabled={checkedIds.length !== 1}
onClick={() => {
const id = checkedIds[0]; if (!id) return;
const row = rows.find((r: any) => String(r.objid) === id);
const ft = (String(row?.form_type || "general") as PurchaseOrderFormType);
setEditObjid(id);
setEditOpen(true);
setEditFormType(ft);
}}>
<Pencil className="h-3.5 w-3.5" />
</Button>
@@ -278,15 +283,27 @@ export default function PurchaseOrderWacePage() {
onRowClick={(row: any) => {
if (!row?.objid) return;
setEditObjid(String(row.objid));
setEditOpen(true);
setEditFormType(String(row.form_type || "general") as PurchaseOrderFormType);
}}
/>
<PurchaseOrderGeneralFormDialog
open={editOpen}
open={editFormType === "general"}
pomObjid={editObjid}
onClose={() => setEditOpen(false)}
onSaved={() => { setEditOpen(false); fetchList(); }}
onClose={() => setEditFormType("")}
onSaved={() => { setEditFormType(""); fetchList(); }}
/>
<PurchaseOrderOutsourcingFormDialog
open={editFormType === "outsourcing"}
pomObjid={editObjid}
onClose={() => setEditFormType("")}
onSaved={() => { setEditFormType(""); fetchList(); }}
/>
<PurchaseOrderEnglishFormDialog
open={editFormType === "english"}
pomObjid={editObjid}
onClose={() => setEditFormType("")}
onSaved={() => { setEditFormType(""); fetchList(); }}
/>
{ConfirmDialogComponent}
@@ -18,6 +18,12 @@ import { apiClient } from "@/lib/api/client";
import { purchaseApi, PurchaseListFilter, OptionItem } from "@/lib/api/purchase";
import { exportToExcel } from "@/lib/utils/excelExport";
import { PurchaseOrderGeneralFormDialog } from "@/components/purchase/PurchaseOrderGeneralFormDialog";
import { PurchaseOrderOutsourcingFormDialog } from "@/components/purchase/PurchaseOrderOutsourcingFormDialog";
import { PurchaseOrderEnglishFormDialog } from "@/components/purchase/PurchaseOrderEnglishFormDialog";
import {
PurchaseOrderFormTypeSelectDialog,
PurchaseOrderFormType,
} from "@/components/purchase/PurchaseOrderFormTypeSelectDialog";
const PARENT_PURCHASE_TYPE = "0001814"; // 구매유형 comm_code
const PARENT_PART_TYPE = "0000001"; // 제품구분 comm_code
@@ -47,8 +53,9 @@ export default function ProposalPage() {
const [partTypeOpts, setPartTypeOpts] = useState<SmartSelectOption[]>([]);
const [userOpts, setUserOpts] = useState<OptionItem[]>([]);
// 발주서생성 다이얼로그
const [orderFormOpen, setOrderFormOpen] = useState(false);
// 발주서생성 — 양식 선택 모달 → 양식별 다이얼로그
const [typeSelectOpen, setTypeSelectOpen] = useState(false);
const [orderFormType, setOrderFormType] = useState<PurchaseOrderFormType | "">("");
const [orderFormProposalId, setOrderFormProposalId] = useState<string>("");
const fetchList = useCallback(async (override?: Partial<PurchaseListFilter>) => {
@@ -133,7 +140,7 @@ export default function ProposalPage() {
const proposalId = checkedIds[0];
if (!proposalId) return;
setOrderFormProposalId(proposalId);
setOrderFormOpen(true);
setTypeSelectOpen(true);
}}>
<ClipboardCheck className="h-3.5 w-3.5" />
</Button>
@@ -205,11 +212,29 @@ export default function ProposalPage() {
showChart
/>
<PurchaseOrderFormTypeSelectDialog
open={typeSelectOpen}
onClose={() => setTypeSelectOpen(false)}
onSelect={(t) => setOrderFormType(t)}
/>
<PurchaseOrderGeneralFormDialog
open={orderFormOpen}
open={orderFormType === "general"}
proposalObjid={orderFormProposalId}
onClose={() => setOrderFormOpen(false)}
onSaved={() => { setOrderFormOpen(false); fetchList(); }}
onClose={() => setOrderFormType("")}
onSaved={() => { setOrderFormType(""); fetchList(); }}
/>
<PurchaseOrderOutsourcingFormDialog
open={orderFormType === "outsourcing"}
proposalObjid={orderFormProposalId}
onClose={() => setOrderFormType("")}
onSaved={() => { setOrderFormType(""); fetchList(); }}
/>
<PurchaseOrderEnglishFormDialog
open={orderFormType === "english"}
proposalObjid={orderFormProposalId}
onClose={() => setOrderFormType("")}
onSaved={() => { setOrderFormType(""); fetchList(); }}
/>
</div>
);