feat: 更新庫存報表、銷售匯入及採購單相關功能
This commit is contained in:
@@ -24,9 +24,17 @@ class InventoryReportController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$filters = $request->only([
|
||||
'date_from', 'date_to', 'warehouse_id', 'category_id', 'search', 'per_page'
|
||||
'date_from', 'date_to', 'warehouse_id', 'category_id', 'search', 'per_page',
|
||||
'sort_by', 'sort_order'
|
||||
]);
|
||||
|
||||
if (!isset($filters['date_from'])) {
|
||||
$filters['date_from'] = date('Y-m-d');
|
||||
}
|
||||
if (!isset($filters['date_to'])) {
|
||||
$filters['date_to'] = date('Y-m-d');
|
||||
}
|
||||
|
||||
$reportData = $this->reportService->getReportData($filters, $request->input('per_page', 10));
|
||||
$summary = $this->reportService->getSummary($filters);
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ class InventoryReportExport implements FromCollection, WithHeadings, WithMapping
|
||||
'分類',
|
||||
'進貨量',
|
||||
'出貨量',
|
||||
'調撥入',
|
||||
'調撥出',
|
||||
'調整量',
|
||||
'淨變動',
|
||||
];
|
||||
@@ -47,6 +49,8 @@ class InventoryReportExport implements FromCollection, WithHeadings, WithMapping
|
||||
$row->category_name ?? '-',
|
||||
$row->inbound_qty,
|
||||
$row->outbound_qty,
|
||||
$row->transfer_in_qty,
|
||||
$row->transfer_out_qty,
|
||||
$row->adjust_qty,
|
||||
$row->net_change,
|
||||
];
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -16,8 +16,17 @@ class SalesImportController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$perPage = $request->input('per_page', 10);
|
||||
$search = $request->input('search');
|
||||
|
||||
$batches = SalesImportBatch::with('importer')
|
||||
->when($search, function ($query, $search) {
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('id', 'like', "%{$search}%")
|
||||
->orWhereHas('importer', function ($u) use ($search) {
|
||||
$u->where('name', 'like', "%{$search}%");
|
||||
});
|
||||
});
|
||||
})
|
||||
->orderByDesc('created_at')
|
||||
->paginate($perPage)
|
||||
->withQueryString();
|
||||
@@ -25,7 +34,8 @@ class SalesImportController extends Controller
|
||||
return Inertia::render('Sales/Import/Index', [
|
||||
'batches' => $batches,
|
||||
'filters' => [
|
||||
'per_page' => $perPage,
|
||||
'per_page' => (string) $perPage,
|
||||
'search' => $search,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user