feat: Add total asset calculation and display to dashboard, and make stat card trend/previous values optional.
This commit is contained in:
parent
48b2d5c6ad
commit
ee435131fc
@ -221,6 +221,36 @@ public function render(): View
|
||||
$profitMargin = $totalIncome > 0 ? ($netProfit / $totalIncome) * 100 : 0;
|
||||
$itemsPerOrder = $totalOrdersCount > 0 ? $totalItemsCount / $totalOrdersCount : 0;
|
||||
|
||||
// Total Asset Calculation
|
||||
$totalAsset = (int) Perfume::query()
|
||||
->join('outlet_perfume', 'perfumes.id', '=', 'outlet_perfume.perfume_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_perfume.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(outlet_perfume.stock AS DECIMAL) * perfumes.cost_price'));
|
||||
|
||||
$totalAsset += (int) Product::query()
|
||||
->join('outlet_product', 'products.id', '=', 'outlet_product.product_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_product.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(outlet_product.stock AS DECIMAL) * products.cost_price'));
|
||||
|
||||
$totalAsset += (int) Bottle::query()
|
||||
->join('bottle_outlet', 'bottles.id', '=', 'bottle_outlet.bottle_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('bottle_outlet.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(bottle_outlet.stock AS DECIMAL) * bottles.cost_price'));
|
||||
|
||||
if (empty($this->selectedOutletIds)) {
|
||||
$totalAsset += (int) Perfume::query()
|
||||
->join('perfume_warehouse', 'perfumes.id', '=', 'perfume_warehouse.perfume_id')
|
||||
->sum(DB::raw('CAST(perfume_warehouse.stock AS DECIMAL) * perfumes.cost_price'));
|
||||
|
||||
$totalAsset += (int) Product::query()
|
||||
->join('product_warehouse', 'products.id', '=', 'product_warehouse.product_id')
|
||||
->sum(DB::raw('CAST(product_warehouse.stock AS DECIMAL) * products.cost_price'));
|
||||
|
||||
$totalAsset += (int) Bottle::query()
|
||||
->join('bottle_warehouse', 'bottles.id', '=', 'bottle_warehouse.bottle_id')
|
||||
->sum(DB::raw('CAST(bottle_warehouse.stock AS DECIMAL) * bottles.cost_price'));
|
||||
}
|
||||
|
||||
$customerOrders = (clone $orderQuery)->select('customer_id', DB::raw('count(*) as count'))
|
||||
->whereNotNull('customer_id')
|
||||
->groupBy('customer_id')
|
||||
@ -240,6 +270,11 @@ public function render(): View
|
||||
'value' => round($profitMargin, 1).'%',
|
||||
'description' => 'Persentase keuntungan bersih dibandingkan dengan total pendapatan.',
|
||||
] : null,
|
||||
$user->hasRole(['Developer', 'Owner']) ? [
|
||||
'title' => 'Total Aset',
|
||||
'value' => formatCurrencyNumber($totalAsset, 'Rp'),
|
||||
'description' => 'Total nilai aset dari stok barang yang ada (Parfum, Produk, Botol) berdasarkan harga modal.',
|
||||
] : null,
|
||||
[
|
||||
'title' => 'Loyalty Rate',
|
||||
'value' => round($loyaltyRate, 1).'%',
|
||||
|
||||
@ -166,6 +166,36 @@ public function render(): View
|
||||
$todayProfitMargin = $todayIncome > 0 ? ($todayNetProfit / $todayIncome) * 100 : 0;
|
||||
$yesterdayProfitMargin = $yesterdayIncome > 0 ? ($yesterdayNetProfit / $yesterdayIncome) * 100 : 0;
|
||||
|
||||
// New Card: Total Asset
|
||||
$totalAsset = (int) Perfume::query()
|
||||
->join('outlet_perfume', 'perfumes.id', 'outlet_perfume.perfume_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_perfume.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(outlet_perfume.stock AS DECIMAL) * perfumes.cost_price'));
|
||||
|
||||
$totalAsset += (int) Product::query()
|
||||
->join('outlet_product', 'products.id', 'outlet_product.product_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('outlet_product.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(outlet_product.stock AS DECIMAL) * products.cost_price'));
|
||||
|
||||
$totalAsset += (int) Bottle::query()
|
||||
->join('bottle_outlet', 'bottles.id', 'bottle_outlet.bottle_id')
|
||||
->when(! empty($outletIds), fn ($q) => $q->whereIn('bottle_outlet.outlet_id', $outletIds))
|
||||
->sum(DB::raw('CAST(bottle_outlet.stock AS DECIMAL) * bottles.cost_price'));
|
||||
|
||||
if (empty($this->selectedOutletIds)) {
|
||||
$totalAsset += (int) Perfume::query()
|
||||
->join('perfume_warehouse', 'perfumes.id', 'perfume_warehouse.perfume_id')
|
||||
->sum(DB::raw('CAST(perfume_warehouse.stock AS DECIMAL) * perfumes.cost_price'));
|
||||
|
||||
$totalAsset += (int) Product::query()
|
||||
->join('product_warehouse', 'products.id', 'product_warehouse.product_id')
|
||||
->sum(DB::raw('CAST(product_warehouse.stock AS DECIMAL) * products.cost_price'));
|
||||
|
||||
$totalAsset += (int) Bottle::query()
|
||||
->join('bottle_warehouse', 'bottles.id', 'bottle_warehouse.bottle_id')
|
||||
->sum(DB::raw('CAST(bottle_warehouse.stock AS DECIMAL) * bottles.cost_price'));
|
||||
}
|
||||
|
||||
// --- Chart Data Logic ---
|
||||
|
||||
// 1. Hourly Sales Comparison (Today vs Yesterday)
|
||||
@ -305,6 +335,12 @@ public function render(): View
|
||||
'description' => 'Persentase keuntungan bersih dibandingkan dengan total pendapatan.',
|
||||
] : null,
|
||||
|
||||
$user->hasRole(['Developer', 'Owner']) ? [
|
||||
'title' => 'Total Aset',
|
||||
'value' => formatCurrencyNumber($totalAsset, 'Rp'),
|
||||
'description' => 'Total nilai aset dari stok barang yang ada (Parfum, Produk, Botol) berdasarkan harga modal.',
|
||||
] : null,
|
||||
|
||||
[
|
||||
'title' => 'Total Order',
|
||||
'value' => $todayOrder,
|
||||
|
||||
@ -33,14 +33,18 @@ class="!px-1 border-none bg-transparent hover:bg-zinc-300 dark:hover:bg-zinc-600
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-1">
|
||||
<flux:heading size="xl">{{ $stat['value'] }}</flux:heading>
|
||||
<flux:subheading size="xs">{{ $stat['previous'] }}</flux:subheading>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-1 font-medium text-sm @if ($stat['trendUp']) text-green-600 dark:text-green-400 @else text-red-500 dark:text-red-400 @endif">
|
||||
<flux:icon :icon="$stat['trendUp'] ? 'arrow-trending-up' : 'arrow-trending-down'"
|
||||
variant="micro" />
|
||||
{{ $stat['trend'] }}
|
||||
@if (isset($stat['previous']))
|
||||
<flux:subheading size="xs">{{ $stat['previous'] }}</flux:subheading>
|
||||
@endif
|
||||
</div>
|
||||
@if (isset($stat['trend']))
|
||||
<div
|
||||
class="flex items-center gap-1 font-medium text-sm @if ($stat['trendUp']) text-green-600 dark:text-green-400 @else text-red-500 dark:text-red-400 @endif">
|
||||
<flux:icon :icon="$stat['trendUp'] ? 'arrow-trending-up' : 'arrow-trending-down'"
|
||||
variant="micro" />
|
||||
{{ $stat['trend'] }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user