From 834b53ea40a82abaaeedc9e6c9756b97df959b9b Mon Sep 17 00:00:00 2001 From: klittle81 <31577819+klittle81@users.noreply.github.com> Date: Sat, 4 Apr 2026 11:22:32 -0400 Subject: [PATCH] Enhance Expense Report - Grouped itemized expenses --- .../Admin/Report/ExpensesReportController.php | 30 ++-- .../views/app/pdf/reports/expenses.blade.php | 128 ++++++++++++++---- 2 files changed, 121 insertions(+), 37 deletions(-) diff --git a/app/Http/Controllers/V1/Admin/Report/ExpensesReportController.php b/app/Http/Controllers/V1/Admin/Report/ExpensesReportController.php index b7b6d678..06671012 100644 --- a/app/Http/Controllers/V1/Admin/Report/ExpensesReportController.php +++ b/app/Http/Controllers/V1/Admin/Report/ExpensesReportController.php @@ -19,7 +19,7 @@ class ExpensesReportController extends Controller * Handle the incoming request. * * @param string $hash - * @return JsonResponse + * @return \Illuminate\Http\JsonResponse */ public function __invoke(Request $request, $hash) { @@ -31,14 +31,26 @@ class ExpensesReportController extends Controller App::setLocale($locale); - $expenseCategories = Expense::with('category') + // Fetch individual expenses (filtered and ordered by date), then group by category + $expenses = Expense::with('category') ->whereCompanyId($company->id) - ->applyFilters($request->only(['from_date', 'to_date'])) - ->expensesAttributes() + ->applyFilters($request->only(['from_date', 'to_date', 'expense_category_id'])) + ->orderBy('expense_date', 'asc') ->get(); - $totalAmount = 0; - foreach ($expenseCategories as $category) { - $totalAmount += $category->total_amount; + + $totalAmount = $expenses->sum('base_amount'); + + $grouped = $expenses->groupBy(function ($item) { + return $item->category ? $item->category->name : trans('expenses.uncategorized'); + }); + + $expenseGroups = collect(); + foreach ($grouped as $categoryName => $group) { + $expenseGroups->push([ + 'name' => $categoryName, + 'expenses' => $group, + 'total' => $group->sum('base_amount'), + ]); } $dateFormat = CompanySetting::getSetting('carbon_date_format', $company->id); @@ -62,7 +74,7 @@ class ExpensesReportController extends Controller ->get(); view()->share([ - 'expenseCategories' => $expenseCategories, + 'expenseGroups' => $expenseGroups, 'colorSettings' => $colorSettings, 'totalExpense' => $totalAmount, 'company' => $company, @@ -82,4 +94,4 @@ class ExpensesReportController extends Controller return $pdf->stream(); } -} +} \ No newline at end of file diff --git a/resources/views/app/pdf/reports/expenses.blade.php b/resources/views/app/pdf/reports/expenses.blade.php index a38c2be7..f83d79d3 100644 --- a/resources/views/app/pdf/reports/expenses.blade.php +++ b/resources/views/app/pdf/reports/expenses.blade.php @@ -33,7 +33,7 @@ .heading-date-range { font-weight: normal; font-size: 15px; - color: #A5ACC1; + color: #606060; width: 100%; text-align: right; padding: 0px; @@ -41,7 +41,7 @@ } .sub-heading-text { - font-weight: normal; + font-weight: bold; font-size: 16px; color: #595959; padding: 0px; @@ -50,8 +50,7 @@ } .expenses-title { - margin-top: 60px; - padding-left: 3px; + margin-top: 30px; font-size: 16px; line-height: 21px; color: #040405; @@ -133,6 +132,84 @@ line-height: 21px; color: #5851D8; } + + /* -- Items Table -- */ + + .items-table { + margin-top: 35px; + padding: 0px 30px 10px 30px; + page-break-before: avoid; + page-break-after: auto; + } + + .items-table hr { + height: 0.1px; + } + + .item-table-heading-left { + font-size: 13.5; + text-align: left; + color: rgba(0, 0, 0, 0.85); + padding: 5px; + padding-bottom: 10px; + } + + .item-table-heading-right { + font-size: 13.5; + text-align: right; + color: rgba(0, 0, 0, 0.85); + padding: 5px; + padding-bottom: 10px; + } + + tr.item-table-heading-row th { + border-bottom: 0.620315px solid #E8E8E8; + font-size: 12px; + line-height: 18px; + } + + .item-table-heading-row { + margin-bottom: 10px; + } + + tr.item-row td { + font-size: 12px; + line-height: 18px; + } + + .item-cell-left { + font-size: 13; + color: #040405; + text-align: left; + padding: 5px; + padding-top: 10px; + border-color: #d9d9d9; + } + + .item-cell-right { + font-size: 13; + color: #040405; + text-align: right; + padding: 5px; + padding-top: 10px; + border-color: #d9d9d9; + } + + .item-description { + color: #595959; + font-size: 9px; + line-height: 12px; + } + + .item-table-group-total { + font-size: 14px; + font-weight: bold; + text-align: right; + color: rgba(0, 0, 0, 0.85); + padding: 5px; + padding-bottom: 10px; + } + @if (App::isLocale('th')) @@ -158,33 +235,28 @@

@lang('pdf_expenses_label')

-
- - @foreach ($expenseCategories as $expenseCategory) - - - + @foreach ($expenseGroups as $group) +

{{ $group['name'] }}

+
-

- {{ $expenseCategory->category->name }} -

-
-

- {!! format_money_pdf($expenseCategory->total_amount, $currency) !!} -

-
+ + + + + + @foreach ($group['expenses'] as $expense) + + + + @endforeach -
@lang('Date')@lang('Note')@lang('Amount')
{{ $expense->formatted_expense_date }}{{ $expense->notes ? $expense->notes : '-' }}{!! format_money_pdf($expense->base_amount, $currency) !!}
-
- - - - - -
-

{!! format_money_pdf($totalExpense, $currency) !!}

-
+ +
+

@lang('Group Total:')   {!! format_money_pdf($group['total'], $currency) !!}

+
+ @endforeach +