import { useState } from "react"; import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout"; import { Head, Link, router } from "@inertiajs/react"; import { SearchableSelect } from "@/Components/ui/searchable-select"; import { Button } from "@/Components/ui/button"; import { Input } from "@/Components/ui/input"; import { Textarea } from "@/Components/ui/textarea"; import { Label } from "@/Components/ui/label"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/Components/ui/table"; import { toast } from "sonner"; import { Store, Plus, Trash2, Loader2, Save, SendHorizontal, ArrowLeft, } from "lucide-react"; interface Product { id: number; name: string; code: string; unit_name: string; } interface Warehouse { id: number; name: string; type: string; } interface RequisitionItem { product_id: string; requested_qty: string; remark: string; } interface Props { requisition?: { id: number; store_warehouse_id: number; remark: string | null; status: string; items: { id: number; product_id: number; requested_qty: number; remark: string | null; }[]; }; warehouses: Warehouse[]; products: Product[]; } export default function Create({ requisition, warehouses, products }: Props) { const isEditing = !!requisition; const [storeWarehouseId, setStoreWarehouseId] = useState( requisition?.store_warehouse_id?.toString() || "" ); const [remark, setRemark] = useState(requisition?.remark || ""); const [items, setItems] = useState( requisition?.items?.map((item) => ({ product_id: item.product_id.toString(), requested_qty: item.requested_qty.toString(), remark: item.remark || "", })) || [{ product_id: "", requested_qty: "", remark: "" }] ); const [saving, setSaving] = useState(false); const [submitting, setSubmitting] = useState(false); const addItem = () => { setItems([...items, { product_id: "", requested_qty: "", remark: "" }]); }; const removeItem = (index: number) => { if (items.length <= 1) { toast.error("至少需要一項商品"); return; } setItems(items.filter((_, i) => i !== index)); }; const updateItem = (index: number, field: keyof RequisitionItem, value: string) => { const newItems = [...items]; newItems[index] = { ...newItems[index], [field]: value }; setItems(newItems); }; const validate = (): boolean => { if (!storeWarehouseId) { toast.error("請選擇申請倉庫"); return false; } if (items.length === 0) { toast.error("至少需要一項商品"); return false; } for (let i = 0; i < items.length; i++) { if (!items[i].product_id) { toast.error(`第 ${i + 1} 行請選擇商品`); return false; } const qty = parseInt(items[i].requested_qty); if (!qty || qty < 1) { toast.error(`第 ${i + 1} 行需求數量必須大於等於 1`); return false; } } // 檢查是否有重複商品 const productIds = items.map((item) => item.product_id); if (new Set(productIds).size !== productIds.length) { toast.error("不可重複選擇商品"); return false; } return true; }; const handleSave = (submitImmediately: boolean = false) => { if (!validate()) return; const setter = submitImmediately ? setSubmitting : setSaving; setter(true); const payload = { store_warehouse_id: storeWarehouseId, remark: remark || null, items: items.map((item) => ({ product_id: parseInt(item.product_id), requested_qty: parseFloat(item.requested_qty), remark: item.remark || null, })), submit_immediately: submitImmediately, }; if (isEditing) { router.put(route("store-requisitions.update", [requisition!.id]), payload, { onFinish: () => setter(false), }); } else { router.post(route("store-requisitions.store"), payload, { onFinish: () => setter(false), }); } }; // 已選商品列表(用於過濾下拉選項) const selectedProductIds = items.map((item) => item.product_id).filter(Boolean); return (
{/* 返回按鈕 */}
{/* 頁面標題 */}

{isEditing ? `編輯叫貨單 ${requisition?.status === "rejected" ? "(重新提交)" : ""}` : "新增叫貨單"}

選擇需要補貨的倉庫,並填入所需商品與數量。

{/* 基本資訊 */}

基本資訊

({ label: w.name, value: w.id.toString(), }))} placeholder="請選擇倉庫" className="h-9" />

選擇需要補貨的倉庫