"use client"; // 자재관리 > 불출의뢰서 — 자재불출 처리 다이얼로그 // wace 1:1: materialRequestDetailPopUp.jsp / acceptInventoryRequestInfo.do // 라인별 OUT_QTY / OUT_DATE / ACQ_USER 입력 후 OUTSTATUS='complete' 처리. // 읽기전용(조회) 모드도 지원. import React, { useEffect, useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Save, X } from "lucide-react"; import { toast } from "sonner"; import { Input } from "@/components/ui/input"; import { NumberInput } from "@/components/common/NumberInput"; import { DateInput } from "@/components/common/DateInput"; import { SmartSelect } from "@/components/common/SmartSelect"; import { inventoryMngApi, OptionItem } from "@/lib/api/inventoryMng"; interface LineRow { objid: string; part_no: string; part_name: string; material: string; spec: string; location: string; sub_location: string; request_qty: string; out_qty: number | ""; out_date: string; acq_user: string; writer_name: string; } interface Props { open: boolean; onClose: () => void; onSaved: () => void; masterObjid: string; readOnly?: boolean; // 미접수/완료 상태에서 조회만 } export function IssueDispatchDialog({ open, onClose, onSaved, masterObjid, readOnly }: Props) { const [master, setMaster] = useState(null); const [rows, setRows] = useState([]); const [userOpts, setUserOpts] = useState([]); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [bulkUser, setBulkUser] = useState(""); const [bulkDate, setBulkDate] = useState(new Date().toISOString().slice(0, 10)); useEffect(() => { if (!open || !masterObjid) return; setMaster(null); setRows([]); setLoading(true); (async () => { try { const [detail, users] = await Promise.all([ inventoryMngApi.getIssue(masterObjid), inventoryMngApi.users(), ]); setMaster(detail.master); setRows((detail.lines ?? []).map((l: any) => ({ objid: l.objid, part_no: l.part_no ?? "", part_name: l.part_name ?? "", material: l.material ?? "", spec: l.spec ?? "", location: l.location ?? "", sub_location: l.sub_location ?? "", request_qty: l.request_qty ?? "0", out_qty: l.out_qty ? Number(l.out_qty) : "", out_date: l.out_date ?? "", acq_user: l.acq_user ?? "", writer_name: l.writer_name ?? "", }))); setUserOpts(users); } catch (e: any) { toast.error(e?.response?.data?.message ?? e?.message ?? "조회 실패"); } finally { setLoading(false); } })(); }, [open, masterObjid]); const handleRow = (idx: number, patch: Partial) => setRows(rs => rs.map((r, i) => i === idx ? { ...r, ...patch } : r)); const handleApplyBulk = () => { setRows(rs => rs.map(r => ({ ...r, acq_user: bulkUser || r.acq_user, out_date: bulkDate || r.out_date, }))); }; const handleSave = async () => { const lines = rows.filter(r => r.out_qty !== "" && Number(r.out_qty) > 0); if (!lines.length) return toast.info("불출수량을 입력해주세요."); for (const r of lines) { if (Number(r.out_qty) > Number(r.request_qty)) { return toast.warning(`${r.part_no}: 의뢰수량(${r.request_qty}) 초과는 불가합니다.`); } if (!r.out_date) return toast.info(`${r.part_no}: 인계일을 입력해주세요.`); if (!r.acq_user) return toast.info(`${r.part_no}: 인수자를 선택해주세요.`); } setSaving(true); try { await inventoryMngApi.dispatchIssue({ master_objid: masterObjid, lines: lines.map(r => ({ objid: r.objid, out_qty: Number(r.out_qty), out_date: r.out_date, acq_user: r.acq_user, })), }); toast.success("자재 불출 처리가 완료되었습니다."); onSaved(); onClose(); } catch (e: any) { toast.error(e?.response?.data?.message ?? e?.message ?? "불출 실패"); } finally { setSaving(false); } }; return ( !v && onClose()}> {readOnly ? "불출의뢰 상세" : "자재 불출"} {master?.inventory_out_no ? ` — ${master.inventory_out_no}` : ""} {readOnly ? "불출의뢰 라인을 조회합니다." : "라인별 불출수량 / 인계일 / 인수자를 입력하고 저장하세요."} {master && (
의뢰일: {master.request_date ?? "-"}
의뢰자: {master.request_user_name ?? master.request_id ?? "-"}
접수: {master.reception_status === "reception" ? "접수" : "미접수"} {master.reception_date ? ` / ${master.reception_date}` : ""}
특이사항: {master.remark || "-"}
)} {!readOnly && (
일괄적용: 인계일
인수자
)}
{loading && } {!loading && rows.length === 0 && ( )} {rows.map((r, i) => ( ))}
품번 품명 규격 재질 Location 의뢰수량 불출수량 인계일 인수자
조회 중...
라인이 없습니다.
{r.part_no} {r.part_name} {r.spec} {r.material} {r.location}{r.sub_location ? ` / ${r.sub_location}` : ""} {Number(r.request_qty ?? 0).toLocaleString()} {readOnly ? {r.out_qty === "" ? "" : Number(r.out_qty).toLocaleString()} : handleRow(i, { out_qty: v })} />} {readOnly ? {r.out_date} : handleRow(i, { out_date: v })} />} {readOnly ? {r.acq_user} : handleRow(i, { acq_user: v })} />}
{!readOnly && ( )}
); }