feat: 優化採購單操作紀錄與統一刪除確認 UI

- 優化採購單更新與刪除的活動紀錄邏輯 (PurchaseOrderController)
  - 整合更新異動為單一紀錄,包含品項差異
  - 刪除時記錄當下品項快照
- 統一採購單刪除確認介面,使用 AlertDialog 取代原生 confirm (PurchaseOrderActions)
- Refactor: 將 ActivityDetailDialog 移至 Components/ActivityLog 並優化樣式與大數據顯示
- 調整 UI 文字:將「總金額」統一為「小計」
- 其他模型與 Controller 的活動紀錄支援更新
This commit is contained in:
2026-01-19 15:32:41 +08:00
parent 18edb3cb69
commit a8091276b8
20 changed files with 1114 additions and 482 deletions

View File

@@ -12,28 +12,40 @@ interface UsePurchaseOrderFormProps {
}
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>("");
const [invoiceNumber, setInvoiceNumber] = useState("");
const [invoiceDate, setInvoiceDate] = useState("");
const [invoiceAmount, setInvoiceAmount] = useState("");
const [supplierId, setSupplierId] = useState(order?.supplierId || "");
const [expectedDate, setExpectedDate] = useState(order?.expectedDate || "");
const [items, setItems] = useState<PurchaseOrderItem[]>(order?.items || []);
const [notes, setNotes] = useState(order?.remark || "");
const [status, setStatus] = useState<PurchaseOrderStatus>(order?.status || "draft");
const [warehouseId, setWarehouseId] = useState<string | number>(order?.warehouse_id || "");
const [invoiceNumber, setInvoiceNumber] = useState(order?.invoiceNumber || "");
const [invoiceDate, setInvoiceDate] = useState(order?.invoiceDate || "");
const [invoiceAmount, setInvoiceAmount] = useState(order?.invoiceAmount ? String(order.invoiceAmount) : "");
const [taxAmount, setTaxAmount] = useState<string | number>(
order?.taxAmount !== undefined && order.taxAmount !== null ? order.taxAmount :
(order?.tax_amount !== undefined && order.tax_amount !== null ? order.tax_amount : "")
);
const [isTaxManual, setIsTaxManual] = useState(!!(order?.taxAmount !== undefined || order?.tax_amount !== undefined));
// 載入編輯訂單資料
// 同步外部傳入的 order 更新 (例如重新執行 edit 路由)
useEffect(() => {
if (order) {
setSupplierId(order.supplierId);
setExpectedDate(order.expectedDate);
setItems(order.items);
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) : "");
const val = order.taxAmount !== undefined && order.taxAmount !== null ? order.taxAmount :
(order.tax_amount !== undefined && order.tax_amount !== null ? order.tax_amount : "");
setTaxAmount(val);
if (val !== "") {
setIsTaxManual(true);
}
}
}, [order]);
@@ -47,6 +59,8 @@ export function usePurchaseOrderForm({ order, suppliers }: UsePurchaseOrderFormP
setInvoiceNumber("");
setInvoiceDate("");
setInvoiceAmount("");
setTaxAmount("");
setIsTaxManual(false);
};
const selectedSupplier = suppliers.find((s) => String(s.id) === String(supplierId));
@@ -154,6 +168,8 @@ export function usePurchaseOrderForm({ order, suppliers }: UsePurchaseOrderFormP
invoiceNumber,
invoiceDate,
invoiceAmount,
taxAmount,
isTaxManual,
// Setters
setSupplierId,
@@ -164,6 +180,8 @@ export function usePurchaseOrderForm({ order, suppliers }: UsePurchaseOrderFormP
setInvoiceNumber,
setInvoiceDate,
setInvoiceAmount,
setTaxAmount,
setIsTaxManual,
// Methods
addItem,