feat: add total price calculations for raw materials and products in analysis components

This commit is contained in:
Yoga Pangestu 2026-08-15 20:16:49 +07:00
parent 25a316ccf0
commit ef136bd1e7
3 changed files with 19 additions and 3 deletions

View File

@ -8,6 +8,7 @@
use App\Enums\OrderStatus;
use App\Enums\PaymentType;
use App\Enums\PayrollStatus;
use App\Enums\PriceType;
use App\Enums\RawMaterialUnit;
use App\Enums\Role;
use App\Models\Attendance;
@ -18,6 +19,7 @@
use App\Models\LeaveRequest;
use App\Models\Order;
use App\Models\Payroll;
use App\Models\ProductPrice;
use App\Models\ProductVariant;
use App\Models\Purchase;
use App\Models\RawMaterialPrice;
@ -207,10 +209,11 @@ public function getRawMaterialStock(): array
{
$items = RawMaterialPrice::query()
->join('raw_materials', 'raw_material_prices.raw_material_id', '=', 'raw_materials.id')
->select('raw_material_prices.stock', 'raw_materials.unit')
->select('raw_material_prices.stock', 'raw_material_prices.price', 'raw_materials.unit')
->get();
$totalQty = $items->sum('stock');
$totalPrice = $items->sum(fn ($i) => $i->stock * $i->price);
$byUnit = [
'yard' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::YARD->value)->sum('stock'),
@ -220,6 +223,7 @@ public function getRawMaterialStock(): array
return [
'total_stock' => $totalQty,
'total_price' => $totalPrice,
'by_unit' => $byUnit,
];
}
@ -227,15 +231,21 @@ public function getRawMaterialStock(): array
public function getProductStock(): array
{
$variants = ProductVariant::query()
->select('stock', 'reject_stock', 'retail_stock')
->leftJoin('product_prices', function ($join) {
$join->on('product_variants.id', '=', 'product_prices.variant_id')
->where('product_prices.type', '=', PriceType::RETAIL->value);
})
->select('product_variants.stock', 'product_variants.reject_stock', 'product_variants.retail_stock', 'product_prices.price')
->get();
$totalStock = $variants->sum('stock');
$totalRejectStock = $variants->sum('reject_stock');
$totalRetailStock = $variants->sum('retail_stock');
$totalPrice = $variants->sum(fn ($v) => ($v->stock + $v->reject_stock + $v->retail_stock) * ($v->price ?? 0));
return [
'total_stock' => $totalStock + $totalRejectStock + $totalRetailStock,
'total_price' => $totalPrice,
'by_type' => [
'stock' => $totalStock,
'reject_stock' => $totalRejectStock,

View File

@ -31,7 +31,7 @@ export function StatCard({ title, icon: Icon, mainLabel, mainValue, subLabel, de
{subLabel && <p className="text-xs text-muted-foreground">{subLabel}</p>}
{description && <p className="mt-1 text-[10px] text-muted-foreground italic">{description}</p>}
{items.length > 0 && (
<div className={cn('mt-3 grid gap-2', cols === 2 && 'grid-cols-2', cols === 3 && 'grid-cols-3', cols === 4 && 'grid-cols-4')}>
<div className={cn('mt-3 grid gap-2', cols === 2 && 'grid-cols-2', cols === 3 && 'grid-cols-2 sm:grid-cols-3', cols === 4 && 'grid-cols-2 sm:grid-cols-4')}>
{items.map((item, index) => (
<div key={index}>
<p className="text-xs text-muted-foreground">{item.label}</p>

View File

@ -67,6 +67,7 @@ type AnalysisProps = {
};
rawMaterialStock: {
total_stock: number;
total_price: number;
by_unit: {
yard: number;
meter: number;
@ -75,6 +76,7 @@ type AnalysisProps = {
};
productStock: {
total_stock: number;
total_price: number;
by_type: {
stock?: number;
reject_stock?: number;
@ -622,7 +624,9 @@ export default function Analysis({
{ label: 'Yard', value: rawMaterialStock.by_unit?.yard?.toLocaleString('id-ID') ?? '0' },
{ label: 'Meter', value: rawMaterialStock.by_unit?.meter?.toLocaleString('id-ID') ?? '0' },
{ label: 'Kg', value: rawMaterialStock.by_unit?.kilogram?.toLocaleString('id-ID') ?? '0' },
{ label: 'Total Harga', value: `Rp${formatRupiah(rawMaterialStock.total_price)}` },
]}
cols={4}
/>
)}
@ -637,7 +641,9 @@ export default function Analysis({
{ label: 'Bagus', value: (productStock.by_type?.stock ?? 0).toLocaleString('id-ID') },
{ label: 'Reject', value: (productStock.by_type?.reject_stock ?? 0).toLocaleString('id-ID') },
{ label: 'Ecer', value: (productStock.by_type?.retail_stock ?? 0).toLocaleString('id-ID') },
{ label: 'Total Harga', value: `Rp${formatRupiah(productStock.total_price)}` },
]}
cols={4}
/>
)}
</div>