優化採購單與進貨單操作紀錄:新增品項明細、ID 轉名稱解析、前端多數量 key 通用顯示
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 55s
ERP-Deploy-Production / deploy-production (push) Successful in 1m12s

- 重構 PurchaseOrder@tapActivity:支援 vendor_id/warehouse_id/user_id 自動解析為名稱
- 修改 PurchaseOrderController@store:改用 saveQuietly + 手動日誌,建立時紀錄品項明細
- 修正 PurchaseOrderController update/destroy snapshot 跨模組取值為 null 的問題
- 修改 GoodsReceiptService@store:改用 saveQuietly + 手動日誌,建立時紀錄品項明細
- 修改 ActivityDetailDialog.tsx:支援 quantity/quantity_received/requested_qty 多 key 通用渲染
- 新增項目顯示金額與備註,更新項目增加金額與備註變更對比
This commit is contained in:
2026-03-02 17:30:55 +08:00
parent 0a955fb993
commit 036f4a4fb6
5 changed files with 195 additions and 65 deletions

View File

@@ -573,50 +573,76 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
{!Array.isArray(activity.properties?.items_diff) && (
<>
{/* 更新項目 */}
{activity.properties?.items_diff?.updated?.map((item: any, idx: number) => (
<TableRow key={`upd-${idx}`} className="bg-blue-50/10 hover:bg-blue-50/20">
<TableCell className="font-medium">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-200"></Badge>
</TableCell>
<TableCell className="text-sm">
<div className="space-y-1 text-xs">
{item.old?.quantity !== item.new?.quantity && item.old?.quantity !== undefined && (
<div>: <span className="text-gray-500 line-through">{item.old.quantity}</span> <span className="text-blue-700 font-bold">{item.new.quantity}</span></div>
)}
{item.old?.counted_qty !== item.new?.counted_qty && item.old?.counted_qty !== undefined && (
<div>: <span className="text-gray-500 line-through">{item.old.counted_qty ?? '未盤'}</span> <span className="text-blue-700 font-bold">{item.new.counted_qty ?? '未盤'}</span></div>
)}
</div>
</TableCell>
</TableRow>
)) || null}
{activity.properties?.items_diff?.updated?.map((item: any, idx: number) => {
const getQty = (obj: any) => obj?.quantity ?? obj?.quantity_received ?? obj?.requested_qty;
const getAmt = (obj: any) => obj?.subtotal ?? obj?.total_amount;
const oldQty = getQty(item.old);
const newQty = getQty(item.new);
const oldAmt = getAmt(item.old);
const newAmt = getAmt(item.new);
return (
<TableRow key={`upd-${idx}`} className="bg-blue-50/10 hover:bg-blue-50/20">
<TableCell className="font-medium">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-blue-50 text-blue-700 border-blue-200"></Badge>
</TableCell>
<TableCell className="text-sm">
<div className="space-y-1 text-xs">
{oldQty !== newQty && oldQty !== undefined && (
<div>: <span className="text-gray-500 line-through">{oldQty}</span> <span className="text-blue-700 font-bold">{newQty}</span></div>
)}
{oldAmt !== newAmt && oldAmt !== undefined && (
<div>: <span className="text-gray-500 line-through">{oldAmt}</span> <span className="text-blue-700 font-bold">{newAmt}</span></div>
)}
{item.old?.counted_qty !== item.new?.counted_qty && item.old?.counted_qty !== undefined && (
<div>: <span className="text-gray-500 line-through">{item.old.counted_qty ?? '未盤'}</span> <span className="text-blue-700 font-bold">{item.new.counted_qty ?? '未盤'}</span></div>
)}
{item.old?.remark !== item.new?.remark && item.old?.remark !== undefined && (
<div>: <span className="text-gray-500 line-through">{item.old.remark || '無'}</span> <span className="text-blue-700 font-bold">{item.new.remark || '無'}</span></div>
)}
</div>
</TableCell>
</TableRow>
);
}) || null}
{/* 新增項目 */}
{activity.properties?.items_diff?.added?.map((item: any, idx: number) => (
<TableRow key={`add-${idx}`} className="bg-green-50/10 hover:bg-green-50/20">
<TableCell className="font-medium">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-green-50 text-green-700 border-green-200"></Badge>
</TableCell>
<TableCell className="text-sm">
: {item.new?.quantity ?? item.quantity} {item.unit_name || item.new?.unit_name || ''}
</TableCell>
</TableRow>
)) || null}
{activity.properties?.items_diff?.added?.map((item: any, idx: number) => {
const qty = item.new?.quantity ?? item.new?.quantity_received ?? item.new?.requested_qty ?? item.quantity;
const amt = item.new?.subtotal ?? item.new?.total_amount;
const remark = item.new?.remark;
return (
<TableRow key={`add-${idx}`} className="bg-green-50/10 hover:bg-green-50/20">
<TableCell className="font-medium">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-green-50 text-green-700 border-green-200"></Badge>
</TableCell>
<TableCell className="text-sm">
<div className="space-y-0.5 text-xs">
<div>: {qty} {item.unit_name || item.new?.unit_name || ''}</div>
{amt !== undefined && <div>: {amt}</div>}
{remark && <div>: {remark}</div>}
</div>
</TableCell>
</TableRow>
);
}) || null}
{/* 移除項目 */}
{activity.properties?.items_diff?.removed?.map((item: any, idx: number) => (
<TableRow key={`rem-${idx}`} className="bg-red-50/10 hover:bg-red-50/20">
<TableCell className="font-medium text-gray-400 line-through">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-red-50 text-red-700 border-red-200"></Badge>
</TableCell>
<TableCell className="text-sm text-gray-400">
: {item.old?.quantity ?? item.quantity} {item.unit_name || item.old?.unit_name || ''}
</TableCell>
</TableRow>
)) || null}
{activity.properties?.items_diff?.removed?.map((item: any, idx: number) => {
const qty = item.old?.quantity ?? item.old?.quantity_received ?? item.old?.requested_qty ?? item.quantity ?? item.quantity_received;
return (
<TableRow key={`rem-${idx}`} className="bg-red-50/10 hover:bg-red-50/20">
<TableCell className="font-medium text-gray-400 line-through">{item.product_name}</TableCell>
<TableCell className="text-center">
<Badge variant="outline" className="bg-red-50 text-red-700 border-red-200"></Badge>
</TableCell>
<TableCell className="text-sm text-gray-400">
: {qty} {item.unit_name || item.old?.unit_name || ''}
</TableCell>
</TableRow>
);
}) || null}
</>
)}

View File

@@ -106,10 +106,7 @@ export default function CreatePurchaseOrder({
return;
}
if (!expectedDate) {
toast.error("請選擇預計到貨日期");
return;
}
if (items.length === 0) {
toast.error("請至少新增一項採購商品");
@@ -140,7 +137,7 @@ export default function CreatePurchaseOrder({
vendor_id: supplierId,
warehouse_id: warehouseId,
order_date: orderDate,
expected_delivery_date: expectedDate,
expected_delivery_date: expectedDate || null,
remark: notes,
status: status,
invoice_number: invoiceNumber || null,