From ae1cc7b9a9efef59e804f1794ca1944d50385eec Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 14 Aug 2026 04:21:26 +0700 Subject: [PATCH] feat: enhance expense summary and monthly expense calculations with user role-based purchase visibility --- app/Services/AnalysisService.php | 51 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/app/Services/AnalysisService.php b/app/Services/AnalysisService.php index b14d291..c3b6d73 100644 --- a/app/Services/AnalysisService.php +++ b/app/Services/AnalysisService.php @@ -448,12 +448,18 @@ public function getExpenseSummary(?string $startDate, ?string $endDate, ?User $u $advanceQuery = EmployeeAdvance::where('status', EmployeeAdvanceStatus::REPAID); $this->applyDateFilter($advanceQuery, $startDate, $endDate, 'employee_advances.created_at'); - $purchaseQuery = Purchase::query(); - $this->applyDateFilter($purchaseQuery, $startDate, $endDate, 'purchases.created_at'); - $expenseTotal = (clone $expenseQuery)->sum('amount'); $advanceTotal = (clone $advanceQuery)->sum('amount'); - $purchaseTotal = (clone $purchaseQuery)->sum('total'); + + $includePurchase = $user && $this->isPurchaseVisible($user); + + if ($includePurchase) { + $purchaseQuery = Purchase::query(); + $this->applyDateFilter($purchaseQuery, $startDate, $endDate, 'purchases.created_at'); + $purchaseTotal = (clone $purchaseQuery)->sum('total'); + } else { + $purchaseTotal = 0; + } return [ 'total' => (int) ($expenseTotal + $advanceTotal + $purchaseTotal), @@ -521,16 +527,6 @@ public function getMonthlyExpense(?string $startDate, ?string $endDate, ?User $u ->get() ->keyBy('month'); - $purchaseMonthly = Purchase::query(); - $this->applyDateFilter($purchaseMonthly, $startDate, $endDate, 'purchases.created_at'); - - $purchaseByMonth = (clone $purchaseMonthly)->toBase() - ->selectRaw("DATE_FORMAT(created_at, '%b %Y') as month") - ->selectRaw('COALESCE(SUM(total), 0) as purchase') - ->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')"), DB::raw("DATE_FORMAT(created_at, '%b %Y')")) - ->get() - ->keyBy('month'); - $advanceMonthly = EmployeeAdvance::where('status', EmployeeAdvanceStatus::REPAID); $this->applyDateFilter($advanceMonthly, $startDate, $endDate, 'employee_advances.created_at'); @@ -541,6 +537,22 @@ public function getMonthlyExpense(?string $startDate, ?string $endDate, ?User $u ->get() ->keyBy('month'); + $includePurchase = $user && $this->isPurchaseVisible($user); + + if ($includePurchase) { + $purchaseMonthly = Purchase::query(); + $this->applyDateFilter($purchaseMonthly, $startDate, $endDate, 'purchases.created_at'); + + $purchaseByMonth = (clone $purchaseMonthly)->toBase() + ->selectRaw("DATE_FORMAT(created_at, '%b %Y') as month") + ->selectRaw('COALESCE(SUM(total), 0) as purchase') + ->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')"), DB::raw("DATE_FORMAT(created_at, '%b %Y')")) + ->get() + ->keyBy('month'); + } else { + $purchaseByMonth = collect(); + } + $allMonths = []; foreach ([$expenseByMonth, $purchaseByMonth, $advanceByMonth] as $data) { foreach ($data as $month => $row) { @@ -554,7 +566,7 @@ public function getMonthlyExpense(?string $startDate, ?string $endDate, ?User $u $row['purchase'] = (int) ($purchaseByMonth[$month]->purchase ?? 0); $row['expense'] = (int) ($expenseByMonth[$month]->expense ?? 0); $row['advance'] = (int) ($advanceByMonth[$month]->advance ?? 0); - $row['total'] = $row['purchase'] + $row['expense'] + $row['advance']; + $row['total'] = $row['expense'] + $row['advance'] + $row['purchase']; } return array_values($allMonths); @@ -843,6 +855,15 @@ private function isMarketingUser(User $user): bool ]); } + private function isPurchaseVisible(User $user): bool + { + return $user->hasAnyRole([ + Role::DEVELOPER->value, + Role::OWNER->value, + Role::ADMIN_BAHAN_BAKU->value, + ]); + } + private function applyMarketingFilter(Builder $query, User $user, string $column = 'marketing_id'): Builder { if ($this->isMarketingUser($user)) {