feat: 更新庫存報表、銷售匯入及採購單相關功能
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 1m3s

This commit is contained in:
2026-02-10 17:18:59 +08:00
parent 593ce94734
commit 220478641d
11 changed files with 590 additions and 409 deletions

View File

@@ -30,6 +30,8 @@ class InventoryReportService
$warehouseId = $filters['warehouse_id'] ?? null;
$categoryId = $filters['category_id'] ?? null;
$search = $filters['search'] ?? null;
$sortBy = $filters['sort_by'] ?? 'product_code';
$sortOrder = $filters['sort_order'] ?? 'asc';
// 若無任何篩選條件,直接回傳空資料
if (!$dateFrom && !$dateTo && !$warehouseId && !$categoryId && !$search) {
@@ -54,9 +56,12 @@ class InventoryReportService
DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('入庫', '手動入庫') AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as inbound_qty"),
// 出貨量type 為 出庫 (排除 調撥出庫) (取絕對值)
DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type IN ('出庫') AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as outbound_qty"),
// 調撥入type 為 調撥入庫
DB::raw("SUM(CASE WHEN inventory_transactions.type = '調撥入庫' AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as transfer_in_qty"),
// 調撥出type 為 調撥出庫 (取絕對值)
DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type = '調撥出庫' AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as transfer_out_qty"),
// 調整量type 為 庫存調整, 手動編輯
DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('庫存調整', '手動編輯') THEN inventory_transactions.quantity ELSE 0 END) as adjust_qty"),
// 調撥淨額 (隱藏欄位,但包含在 net_change)
// 淨變動:總和 (包含所有類型:進貨、出貨、調整、調撥)
DB::raw("SUM(inventory_transactions.quantity) as net_change"),
])
@@ -92,7 +97,7 @@ class InventoryReportService
});
}
// 分組與排序
// 分組
$query->groupBy([
'products.id',
'products.code',
@@ -100,7 +105,20 @@ class InventoryReportService
'categories.name'
]);
$query->orderBy('products.code', 'asc');
// 動態排序
$allowedSortFields = [
'product_code' => 'products.code',
'product_name' => 'products.name',
'inbound_qty' => 'inbound_qty',
'outbound_qty' => 'outbound_qty',
'transfer_in_qty' => 'transfer_in_qty',
'transfer_out_qty' => 'transfer_out_qty',
'adjust_qty' => 'adjust_qty',
'net_change' => 'net_change',
];
$sortColumn = $allowedSortFields[$sortBy] ?? 'products.code';
$query->orderBy($sortColumn, $sortOrder === 'desc' ? 'desc' : 'asc');
if ($perPage) {
@@ -169,6 +187,8 @@ class InventoryReportService
return $query->select([
DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('入庫', '手動入庫') AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as total_inbound"),
DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type IN ('出庫') AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as total_outbound"),
DB::raw("SUM(CASE WHEN inventory_transactions.type = '調撥入庫' AND inventory_transactions.quantity > 0 THEN inventory_transactions.quantity ELSE 0 END) as total_transfer_in"),
DB::raw("ABS(SUM(CASE WHEN inventory_transactions.type = '調撥出庫' AND inventory_transactions.quantity < 0 THEN inventory_transactions.quantity ELSE 0 END)) as total_transfer_out"),
DB::raw("SUM(CASE WHEN inventory_transactions.type IN ('庫存調整', '手動編輯') THEN inventory_transactions.quantity ELSE 0 END) as total_adjust"),
DB::raw("SUM(inventory_transactions.quantity) as total_net_change"),
])->first();