diff --git a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/edit/page.tsx b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/edit/page.tsx index 1205ca29..0fdf3cfe 100644 --- a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/edit/page.tsx +++ b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/edit/page.tsx @@ -1,26 +1,562 @@ -'use client'; - -import { use, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; - -interface PageProps { - params: Promise<{ id: string }>; -} +"use client"; /** - * V2 하위 호환성: /[id]/edit → /[id]?mode=edit 리다이렉트 + * 수주 수정 페이지 + * + * - 기본 정보 (읽기전용) + * - 수주/배송 정보 (편집 가능) + * - 비고 (편집 가능) + * - 품목 내역 (생산 시작 후 수정 불가) */ -export default function OrderEditPage({ params }: PageProps) { - const { id } = use(params); - const router = useRouter(); - useEffect(() => { - router.replace(`/sales/order-management-sales/${id}?mode=edit`); - }, [id, router]); +import { useState, useEffect } from "react"; +import { useRouter, useParams } from "next/navigation"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Label } from "@/components/ui/label"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { FileText, AlertTriangle } from "lucide-react"; +import { toast } from "sonner"; +import { PageLayout } from "@/components/organisms/PageLayout"; +import { PageHeader } from "@/components/organisms/PageHeader"; +import { FormActions } from "@/components/organisms/FormActions"; +import { BadgeSm } from "@/components/atoms/BadgeSm"; +import { formatAmount } from "@/utils/formatAmount"; +import { + OrderItem, + getOrderById, + updateOrder, + type OrderStatus, +} from "@/components/orders"; +// 수정 폼 데이터 +interface EditFormData { + // 읽기전용 정보 + lotNumber: string; + quoteNumber: string; + client: string; + siteName: string; + manager: string; + contact: string; + status: OrderStatus; + + // 수정 가능 정보 + expectedShipDate: string; + expectedShipDateUndecided: boolean; + deliveryRequestDate: string; + deliveryMethod: string; + shippingCost: string; + receiver: string; + receiverContact: string; + address: string; + addressDetail: string; + remarks: string; + + // 품목 (수정 제한) + items: OrderItem[]; + canEditItems: boolean; + subtotal: number; + discountRate: number; + totalAmount: number; +} + +// 배송방식 옵션 +const DELIVERY_METHODS = [ + { value: "direct", label: "직접배차" }, + { value: "pickup", label: "상차" }, + { value: "courier", label: "택배" }, +]; + +// 운임비용 옵션 +const SHIPPING_COSTS = [ + { value: "free", label: "무료" }, + { value: "prepaid", label: "선불" }, + { value: "collect", label: "착불" }, + { value: "negotiable", label: "협의" }, +]; + + +// 상태 뱃지 헬퍼 +function getOrderStatusBadge(status: OrderStatus) { + const statusConfig: Record = { + order_registered: { label: "수주등록", className: "bg-gray-100 text-gray-700 border-gray-200" }, + order_confirmed: { label: "수주확정", className: "bg-gray-100 text-gray-700 border-gray-200" }, + production_ordered: { label: "생산지시완료", className: "bg-blue-100 text-blue-700 border-blue-200" }, + in_production: { label: "생산중", className: "bg-green-100 text-green-700 border-green-200" }, + rework: { label: "재작업중", className: "bg-orange-100 text-orange-700 border-orange-200" }, + work_completed: { label: "작업완료", className: "bg-blue-600 text-white border-blue-600" }, + shipped: { label: "출하완료", className: "bg-gray-500 text-white border-gray-500" }, + cancelled: { label: "취소", className: "bg-red-100 text-red-700 border-red-200" }, + }; + const config = statusConfig[status]; return ( -
-
리다이렉트 중...
-
+ + {config.label} + ); } + +export default function OrderEditPage() { + const router = useRouter(); + const params = useParams(); + const orderId = params.id as string; + + const [form, setForm] = useState(null); + const [loading, setLoading] = useState(true); + const [isSaving, setIsSaving] = useState(false); + + // 데이터 로드 (API) + useEffect(() => { + async function loadOrder() { + try { + setLoading(true); + const result = await getOrderById(orderId); + if (result.success && result.data) { + const order = result.data; + // 상태에 따라 품목 수정 가능 여부 결정 + const canEditItems = !["in_production", "rework", "work_completed", "shipped"].includes( + order.status + ); + // Order 데이터를 EditFormData로 변환 + setForm({ + lotNumber: order.lotNumber, + quoteNumber: order.quoteNumber || "", + client: order.client, + siteName: order.siteName, + manager: order.manager || "", + contact: order.contact || "", + status: order.status, + expectedShipDate: order.expectedShipDate || "", + expectedShipDateUndecided: !order.expectedShipDate, + deliveryRequestDate: order.deliveryRequestDate || "", + deliveryMethod: order.deliveryMethod || "", + shippingCost: order.shippingCost || "", + receiver: order.receiver || "", + receiverContact: order.receiverContact || "", + address: order.address || "", + addressDetail: order.addressDetail || "", + remarks: order.remarks || "", + items: order.items || [], + canEditItems, + subtotal: order.subtotal || order.amount, + discountRate: order.discountRate || 0, + totalAmount: order.amount, + }); + } else { + toast.error(result.error || "수주 정보를 불러오는데 실패했습니다."); + router.push("/sales/order-management-sales"); + } + } catch (error) { + console.error("Error loading order:", error); + toast.error("수주 정보를 불러오는 중 오류가 발생했습니다."); + router.push("/sales/order-management-sales"); + } finally { + setLoading(false); + } + } + loadOrder(); + }, [orderId, router]); + + const handleCancel = () => { + router.push(`/sales/order-management-sales/${orderId}`); + }; + + const handleSave = async () => { + if (!form) return; + + // 유효성 검사 + if (!form.deliveryRequestDate) { + toast.error("납품요청일을 입력해주세요."); + return; + } + if (!form.receiver.trim()) { + toast.error("수신(반장/업체)을 입력해주세요."); + return; + } + if (!form.receiverContact.trim()) { + toast.error("수신처 연락처를 입력해주세요."); + return; + } + + setIsSaving(true); + try { + // API 연동 + // 주의: clientId를 보내지 않으면 기존 값 유지됨 + // clientName과 clientContact는 반드시 보내야 기존 값이 유지됨 + const result = await updateOrder(orderId, { + clientName: form.client, + clientContact: form.contact, + siteName: form.siteName, + expectedShipDate: form.expectedShipDateUndecided ? undefined : form.expectedShipDate, + deliveryRequestDate: form.deliveryRequestDate, + deliveryMethod: form.deliveryMethod, + shippingCost: form.shippingCost, + receiver: form.receiver, + receiverContact: form.receiverContact, + address: form.address, + addressDetail: form.addressDetail, + remarks: form.remarks, + items: form.items.map((item) => ({ + itemId: item.id ? parseInt(item.id, 10) : undefined, + itemCode: item.itemCode, + itemName: item.itemName, + specification: item.spec, + quantity: item.quantity, + unit: item.unit, + unitPrice: item.unitPrice, + })), + }); + + if (result.success) { + toast.success("수주가 수정되었습니다."); + router.push(`/sales/order-management-sales/${orderId}`); + } else { + toast.error(result.error || "수주 수정에 실패했습니다."); + } + } catch (error) { + console.error("Error updating order:", error); + toast.error("수주 수정 중 오류가 발생했습니다."); + } finally { + setIsSaving(false); + } + }; + + if (loading || !form) { + return ( + +
+
+
+ + ); + } + + return ( + + {/* 헤더 */} + + + {form.lotNumber} + + {getOrderStatusBadge(form.status)} +
+ } + /> + +
+ {/* 기본 정보 (읽기전용) */} + + + + 기본 정보 + (읽기전용) + + + +
+
+ +

{form.lotNumber}

+
+
+ +

{form.quoteNumber}

+
+
+ +

{form.manager}

+
+
+ +

{form.client}

+
+
+ +

{form.siteName}

+
+
+ +

{form.contact}

+
+
+
+
+ + {/* 수주/배송 정보 (편집 가능) */} + + + 수주/배송 정보 + + +
+ {/* 출고예정일 */} +
+ +
+ + setForm({ ...form, expectedShipDate: e.target.value }) + } + disabled={form.expectedShipDateUndecided} + className="flex-1" + /> +
+ + setForm({ + ...form, + expectedShipDateUndecided: checked as boolean, + expectedShipDate: checked ? "" : form.expectedShipDate, + }) + } + /> + +
+
+
+ + {/* 납품요청일 */} +
+ + + setForm({ ...form, deliveryRequestDate: e.target.value }) + } + /> +
+ + {/* 배송방식 */} +
+ + +
+ + {/* 운임비용 */} +
+ + +
+ + {/* 수신(반장/업체) */} +
+ + + setForm({ ...form, receiver: e.target.value }) + } + /> +
+ + {/* 수신처 연락처 */} +
+ + + setForm({ ...form, receiverContact: e.target.value }) + } + /> +
+ + {/* 수신처 주소 */} +
+ + + setForm({ ...form, address: e.target.value }) + } + placeholder="주소" + className="mb-2" + /> + + setForm({ ...form, addressDetail: e.target.value }) + } + placeholder="상세주소" + /> +
+
+
+
+ + {/* 비고 */} + + + 비고 + + +