import { useState, useEffect } from "react"; import { ArrowLeft, Plus, Trash2, Package, Info, Calculator } from "lucide-react"; import { Button } from "@/Components/ui/button"; import { Input } from "@/Components/ui/input"; import { Textarea } from "@/Components/ui/textarea"; import { SearchableSelect } from "@/Components/ui/searchable-select"; import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout"; import { Head, Link, router } from "@inertiajs/react"; import { toast } from "sonner"; import axios from "axios"; interface Product { id: number; name: string; code: string; unit_name: string; } interface Item { product_id: number | null; product_name?: string; product_code?: string; unit_name?: string; batch_number: string; quantity: number; unit_price: number; subtotal: number; remark: string; available_batches: any[]; } interface Props { order?: any; warehouses: { id: number; name: string }[]; products: Product[]; } export default function ShippingOrderCreate({ order, warehouses, products }: Props) { const isEdit = !!order; const [warehouseId, setWarehouseId] = useState(order?.warehouse_id?.toString() || ""); const [customerName, setCustomerName] = useState(order?.customer_name || ""); const [shippingDate, setShippingDate] = useState(order?.shipping_date || new Date().toISOString().split('T')[0]); const [remarks, setRemarks] = useState(order?.remarks || ""); const [items, setItems] = useState(order?.items?.map((item: any) => ({ product_id: item.product_id, batch_number: item.batch_number, quantity: Number(item.quantity), unit_price: Number(item.unit_price), subtotal: Number(item.subtotal), remark: item.remark || "", available_batches: [], })) || []); const [taxAmount, setTaxAmount] = useState(Number(order?.tax_amount) || 0); const totalAmount = items.reduce((sum, item) => sum + item.subtotal, 0); const grandTotal = totalAmount + taxAmount; // 當品項變動時,自動計算稅額 (預設 5%) useEffect(() => { if (!isEdit || (isEdit && order.status === 'draft')) { setTaxAmount(Math.round(totalAmount * 0.05)); } }, [totalAmount]); const addItem = () => { setItems([...items, { product_id: null, batch_number: "", quantity: 1, unit_price: 0, subtotal: 0, remark: "", available_batches: [], }]); }; const removeItem = (index: number) => { setItems(items.filter((_, i) => i !== index)); }; const updateItem = (index: number, updates: Partial) => { const newItems = [...items]; newItems[index] = { ...newItems[index], ...updates }; // 計算小計 if ('quantity' in updates || 'unit_price' in updates) { newItems[index].subtotal = Number(newItems[index].quantity) * Number(newItems[index].unit_price); } setItems(newItems); // 如果商品變動,抓取批號 if ('product_id' in updates && updates.product_id && warehouseId) { fetchBatches(index, updates.product_id, warehouseId); } }; const fetchBatches = async (index: number, productId: number, wId: string) => { try { const response = await axios.get(route('api.warehouses.inventory.batches', { warehouse: wId, productId })); const newItems = [...items]; newItems[index].available_batches = response.data; setItems(newItems); } catch (error) { console.error("Failed to fetch batches", error); } }; const handleSave = () => { if (!warehouseId) { toast.error("請選擇出貨倉庫"); return; } if (!shippingDate) { toast.error("請選擇出貨日期"); return; } if (items.length === 0) { toast.error("請至少新增一個品項"); return; } const data = { warehouse_id: warehouseId, customer_name: customerName, shipping_date: shippingDate, remarks: remarks, total_amount: totalAmount, tax_amount: taxAmount, grand_total: grandTotal, items: items.map(item => ({ product_id: item.product_id, batch_number: item.batch_number, quantity: item.quantity, unit_price: item.unit_price, subtotal: item.subtotal, remark: item.remark, })), }; if (isEdit) { router.put(route('delivery-notes.update', order.id), data); } else { router.post(route('delivery-notes.store'), data); } }; return (

{isEdit ? `編輯出貨單 ${order.doc_no}` : "建立新出貨單"}

{/* 左側:基本資訊 */}

基本資料

({ label: w.name, value: w.id.toString() }))} placeholder="選擇倉庫" />
setShippingDate(e.target.value)} />
setCustomerName(e.target.value)} />