優化採購單與進貨單操作紀錄:新增品項明細、ID 轉名稱解析、前端多數量 key 通用顯示
- 重構 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:
@@ -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}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user