feat(warehouse): 庫存統計卡片加入總金額顯示 (可用/帳面)
This commit is contained in:
@@ -30,8 +30,9 @@ class WarehouseController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$warehouses = $query->withSum('inventories as book_stock', 'quantity') // 帳面庫存 = 所有庫存總和
|
$warehouses = $query->withSum('inventories as book_stock', 'quantity') // 帳面庫存 = 所有庫存總和
|
||||||
|
->withSum('inventories as book_amount', 'total_value') // 帳面金額
|
||||||
->withSum(['inventories as available_stock' => function ($query) {
|
->withSum(['inventories as available_stock' => function ($query) {
|
||||||
// 可用庫存 = 庫存 > 0 且 品質正常 且 (未過期 或 無效期) 且 倉庫類型不為瑕疵倉
|
// 可用庫存條件
|
||||||
$query->where('quantity', '>', 0)
|
$query->where('quantity', '>', 0)
|
||||||
->where('quality_status', 'normal')
|
->where('quality_status', 'normal')
|
||||||
->whereHas('warehouse', function ($q) {
|
->whereHas('warehouse', function ($q) {
|
||||||
@@ -42,6 +43,18 @@ class WarehouseController extends Controller
|
|||||||
->orWhere('expiry_date', '>=', now());
|
->orWhere('expiry_date', '>=', now());
|
||||||
});
|
});
|
||||||
}], 'quantity')
|
}], 'quantity')
|
||||||
|
->withSum(['inventories as available_amount' => function ($query) {
|
||||||
|
// 可用金額條件 (與可用庫存一致)
|
||||||
|
$query->where('quantity', '>', 0)
|
||||||
|
->where('quality_status', 'normal')
|
||||||
|
->whereHas('warehouse', function ($q) {
|
||||||
|
$q->where('type', '!=', \App\Enums\WarehouseType::QUARANTINE);
|
||||||
|
})
|
||||||
|
->where(function ($q) {
|
||||||
|
$q->whereNull('expiry_date')
|
||||||
|
->orWhere('expiry_date', '>=', now());
|
||||||
|
});
|
||||||
|
}], 'total_value')
|
||||||
->addSelect(['low_stock_count' => function ($query) {
|
->addSelect(['low_stock_count' => function ($query) {
|
||||||
$query->selectRaw('count(*)')
|
$query->selectRaw('count(*)')
|
||||||
->from('warehouse_product_safety_stocks as ss')
|
->from('warehouse_product_safety_stocks as ss')
|
||||||
@@ -52,9 +65,6 @@ class WarehouseController extends Controller
|
|||||||
->paginate($perPage)
|
->paginate($perPage)
|
||||||
->withQueryString();
|
->withQueryString();
|
||||||
|
|
||||||
// 移除原本對 is_sellable 的手動修正邏輯,現在由 type 自動過濾
|
|
||||||
|
|
||||||
|
|
||||||
// 計算全域總計 (不分頁)
|
// 計算全域總計 (不分頁)
|
||||||
$totals = [
|
$totals = [
|
||||||
'available_stock' => \App\Modules\Inventory\Models\Inventory::where('quantity', '>', 0)
|
'available_stock' => \App\Modules\Inventory\Models\Inventory::where('quantity', '>', 0)
|
||||||
@@ -66,7 +76,17 @@ class WarehouseController extends Controller
|
|||||||
$q->whereNull('expiry_date')
|
$q->whereNull('expiry_date')
|
||||||
->orWhere('expiry_date', '>=', now());
|
->orWhere('expiry_date', '>=', now());
|
||||||
})->sum('quantity'),
|
})->sum('quantity'),
|
||||||
|
'available_amount' => \App\Modules\Inventory\Models\Inventory::where('quantity', '>', 0)
|
||||||
|
->where('quality_status', 'normal')
|
||||||
|
->whereHas('warehouse', function ($q) {
|
||||||
|
$q->where('type', '!=', \App\Enums\WarehouseType::QUARANTINE);
|
||||||
|
})
|
||||||
|
->where(function ($q) {
|
||||||
|
$q->whereNull('expiry_date')
|
||||||
|
->orWhere('expiry_date', '>=', now());
|
||||||
|
})->sum('total_value'),
|
||||||
'book_stock' => \App\Modules\Inventory\Models\Inventory::sum('quantity'),
|
'book_stock' => \App\Modules\Inventory\Models\Inventory::sum('quantity'),
|
||||||
|
'book_amount' => \App\Modules\Inventory\Models\Inventory::sum('total_value'),
|
||||||
];
|
];
|
||||||
|
|
||||||
return Inertia::render('Warehouse/Index', [
|
return Inertia::render('Warehouse/Index', [
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ interface PageProps {
|
|||||||
};
|
};
|
||||||
totals: {
|
totals: {
|
||||||
available_stock: number;
|
available_stock: number;
|
||||||
|
available_amount: number;
|
||||||
book_stock: number;
|
book_stock: number;
|
||||||
|
book_amount: number;
|
||||||
};
|
};
|
||||||
filters: {
|
filters: {
|
||||||
search?: string;
|
search?: string;
|
||||||
@@ -169,9 +171,16 @@ export default function WarehouseIndex({ warehouses, totals, filters }: PageProp
|
|||||||
<CardContent className="p-6">
|
<CardContent className="p-6">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-sm font-medium text-gray-500 mb-1">可用庫存總計</span>
|
<span className="text-sm font-medium text-gray-500 mb-1">可用庫存總計</span>
|
||||||
|
<div className="flex items-baseline gap-2">
|
||||||
<span className="text-3xl font-bold text-primary-main">
|
<span className="text-3xl font-bold text-primary-main">
|
||||||
{totals.available_stock.toLocaleString()}
|
{totals.available_stock.toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
|
<Can permission="inventory.view_cost">
|
||||||
|
<span className="text-lg font-medium text-gray-400">
|
||||||
|
( 總額:${totals.available_amount?.toLocaleString()} )
|
||||||
|
</span>
|
||||||
|
</Can>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -180,9 +189,16 @@ export default function WarehouseIndex({ warehouses, totals, filters }: PageProp
|
|||||||
<CardContent className="p-6">
|
<CardContent className="p-6">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-sm font-medium text-gray-500 mb-1">帳面庫存總計</span>
|
<span className="text-sm font-medium text-gray-500 mb-1">帳面庫存總計</span>
|
||||||
|
<div className="flex items-baseline gap-2">
|
||||||
<span className="text-3xl font-bold text-gray-700">
|
<span className="text-3xl font-bold text-gray-700">
|
||||||
{totals.book_stock.toLocaleString()}
|
{totals.book_stock.toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
|
<Can permission="inventory.view_cost">
|
||||||
|
<span className="text-lg font-medium text-gray-400">
|
||||||
|
( 總額:${totals.book_amount?.toLocaleString()} )
|
||||||
|
</span>
|
||||||
|
</Can>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
Reference in New Issue
Block a user