/** * 採購單表單管理 Hook */ import { useState, useEffect } from "react"; import type { PurchaseOrder, PurchaseOrderItem, Supplier, PurchaseOrderStatus } from "@/types/purchase-order"; import { calculateSubtotal } from "@/utils/purchase-order"; interface UsePurchaseOrderFormProps { order?: PurchaseOrder; suppliers: Supplier[]; } export function usePurchaseOrderForm({ order, suppliers }: UsePurchaseOrderFormProps) { const [supplierId, setSupplierId] = useState(""); const [expectedDate, setExpectedDate] = useState(""); const [items, setItems] = useState([]); const [notes, setNotes] = useState(""); const [status, setStatus] = useState("draft"); const [warehouseId, setWarehouseId] = useState(""); const [invoiceNumber, setInvoiceNumber] = useState(""); const [invoiceDate, setInvoiceDate] = useState(""); const [invoiceAmount, setInvoiceAmount] = useState(""); // 載入編輯訂單資料 useEffect(() => { if (order) { setSupplierId(order.supplierId); setExpectedDate(order.expectedDate); setItems(order.items); setNotes(order.remark || ""); setStatus(order.status); setWarehouseId(order.warehouse_id || ""); setInvoiceNumber(order.invoiceNumber || ""); setInvoiceDate(order.invoiceDate || ""); setInvoiceAmount(order.invoiceAmount ? String(order.invoiceAmount) : ""); } }, [order]); const resetForm = () => { setSupplierId(""); setExpectedDate(""); setItems([]); setNotes(""); setStatus("draft"); setWarehouseId(""); setInvoiceNumber(""); setInvoiceDate(""); setInvoiceAmount(""); }; const selectedSupplier = suppliers.find((s) => String(s.id) === String(supplierId)); const isOrderSent = order && order.status !== "draft"; // 新增商品項目 const addItem = () => { if (!selectedSupplier) return; setItems([ ...items, { productId: "", productName: "", quantity: 1, unitPrice: 0, subtotal: 0, selectedUnit: "base", }, ]); }; // 移除商品項目 const removeItem = (index: number) => { setItems(items.filter((_, i) => i !== index)); }; // 更新商品項目 const updateItem = (index: number, field: keyof PurchaseOrderItem, value: any) => { const newItems = [...items]; const item = { ...newItems[index] }; if (field === "productId" && selectedSupplier) { // value is productId string const product = selectedSupplier.commonProducts.find((p) => p.productId === value); if (product) { // @ts-ignore item.productId = value; item.productName = product.productName; item.base_unit_id = product.base_unit_id; item.base_unit_name = product.base_unit_name; item.large_unit_id = product.large_unit_id; item.large_unit_name = product.large_unit_name; item.purchase_unit_id = product.purchase_unit_id; item.conversion_rate = product.conversion_rate; item.unitPrice = product.lastPrice; item.previousPrice = product.lastPrice; // 決定預設單位 const isPurchaseUnitLarge = product.purchase_unit_id && product.large_unit_id && product.purchase_unit_id === product.large_unit_id; if (isPurchaseUnitLarge) { item.selectedUnit = 'large'; item.unitId = product.large_unit_id; } else { item.selectedUnit = 'base'; item.unitId = product.base_unit_id; } // 初始小計 = 數量 * 單價 item.subtotal = calculateSubtotal(Number(item.quantity), Number(item.unitPrice)); } } else if (field === "selectedUnit") { // @ts-ignore item.selectedUnit = value; if (value === 'large') { item.unitId = item.large_unit_id; } else { item.unitId = item.base_unit_id; } // Switch unit doesn't change Total Amount (Subtotal), but implies Unit Price changes? // Actually if I switch unit, the Quantity is usually for that unit. // If I have 1 Box ($100), and switch to Pc. Quantity is still 1. // Total is $100. So Unit Price (per Pc) becomes $100. // This seems safely consistent with "Total Amount" anchor. } else { // @ts-ignore item[field] = value; } // 重新計算 (Always derive UnitPrice from Subtotal and Quantity) // 除了剛剛已經算過 subtotal 的 productId case if (field !== "productId") { if (item.quantity > 0) { item.unitPrice = Number(item.subtotal) / Number(item.quantity); } else { item.unitPrice = 0; } } newItems[index] = item; setItems(newItems); }; return { // State supplierId, expectedDate, items, notes, status, selectedSupplier, isOrderSent, warehouseId, invoiceNumber, invoiceDate, invoiceAmount, // Setters setSupplierId, setExpectedDate, setNotes, setStatus, setWarehouseId, setInvoiceNumber, setInvoiceDate, setInvoiceAmount, // Methods addItem, removeItem, updateItem, resetForm, }; }