123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
/**
|
|
* 採購單表單管理 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<PurchaseOrderItem[]>([]);
|
|
const [notes, setNotes] = useState("");
|
|
const [status, setStatus] = useState<PurchaseOrderStatus>("draft");
|
|
const [warehouseId, setWarehouseId] = useState<string | number>("");
|
|
|
|
// 載入編輯訂單資料
|
|
useEffect(() => {
|
|
if (order) {
|
|
setSupplierId(order.supplierId);
|
|
setExpectedDate(order.expectedDate);
|
|
setItems(order.items);
|
|
setNotes(order.remark || "");
|
|
setStatus(order.status);
|
|
setWarehouseId(order.warehouse_id || "");
|
|
}
|
|
}, [order]);
|
|
|
|
const resetForm = () => {
|
|
setSupplierId("");
|
|
setExpectedDate("");
|
|
setItems([]);
|
|
setNotes("");
|
|
setStatus("draft");
|
|
setWarehouseId("");
|
|
};
|
|
|
|
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: 0,
|
|
unit: "",
|
|
unitPrice: 0,
|
|
subtotal: 0,
|
|
},
|
|
]);
|
|
};
|
|
|
|
// 移除商品項目
|
|
const removeItem = (index: number) => {
|
|
setItems(items.filter((_, i) => i !== index));
|
|
};
|
|
|
|
// 更新商品項目
|
|
const updateItem = (index: number, field: keyof PurchaseOrderItem, value: string | number) => {
|
|
const newItems = [...items];
|
|
newItems[index] = { ...newItems[index], [field]: value };
|
|
|
|
// 當選擇商品時,自動填入商品資訊
|
|
if (field === "productId" && selectedSupplier) {
|
|
const product = selectedSupplier.commonProducts.find((p) => p.productId === value);
|
|
if (product) {
|
|
newItems[index].productName = product.productName;
|
|
newItems[index].unit = product.unit;
|
|
newItems[index].base_unit = product.base_unit;
|
|
newItems[index].purchase_unit = product.purchase_unit;
|
|
newItems[index].conversion_rate = product.conversion_rate;
|
|
newItems[index].unitPrice = product.lastPrice;
|
|
newItems[index].previousPrice = product.lastPrice;
|
|
}
|
|
}
|
|
|
|
// 計算小計
|
|
if (field === "quantity" || field === "unitPrice") {
|
|
newItems[index].subtotal = calculateSubtotal(
|
|
Number(newItems[index].quantity),
|
|
Number(newItems[index].unitPrice)
|
|
);
|
|
}
|
|
|
|
setItems(newItems);
|
|
};
|
|
|
|
return {
|
|
// State
|
|
supplierId,
|
|
expectedDate,
|
|
items,
|
|
notes,
|
|
status,
|
|
selectedSupplier,
|
|
isOrderSent,
|
|
warehouseId,
|
|
|
|
// Setters
|
|
setSupplierId,
|
|
setExpectedDate,
|
|
setNotes,
|
|
setStatus,
|
|
setWarehouseId,
|
|
|
|
// Methods
|
|
addItem,
|
|
removeItem,
|
|
updateItem,
|
|
resetForm,
|
|
};
|
|
}
|