Files
InvoiceShelf/resources/views/app/pdf/reports/expenses.blade.php
Darko Gjorgjijoski 119a1712b0 Port expense report grouped itemized view + i18n + return types from master
Ports the net behaviour from three master commits into v3.0 as a single change, because v3.0 has already diverged structurally (controller moved from V1/Admin/Report to Company/Report, blade has its own CSS rework using the bundled fonts partial, and v3.0's App\Facades\Pdf replaces Barryvdh\DomPDF\Facade\Pdf). The three source commits are: 834b53ea (grouped itemized expenses), e22050bc (DomPDF facade + Pint — adapted to v3.0's App\Facades\Pdf), 0e9f18d4 (expenses.uncategorized + pdf_expense_group_total_label i18n keys + View|Response return type).

Controller: replaces the expenseCategories aggregate fetch with an itemized Expense query ordered by date, groups by category name with expenses.uncategorized fallback, and shares an expenseGroups collection of {name, expenses, total} plus the overall totalExpense. Adds expense_category_id to applyFilters. Updates the docblock return type from JsonResponse to View|Response. Keeps v3.0's App\Facades\Pdf.

Blade: replaces the single expenseCategories aggregate table with a per-group itemized table (date / note / amount columns + per-group total line using the new pdf_expense_group_total_label i18n key). Adds the item-table-* CSS classes and removes the old expense-total-table bottom block.

lang/en.json: adds expenses.uncategorized = "Uncategorized" and pdf_expense_group_total_label = "Group total:".
2026-04-07 17:28:34 +02:00

248 lines
6.7 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<title>@lang('pdf_expense_report_label')</title>
@include("app.pdf.partials.fonts")
<style type="text/css">
body {
}
table {
border-collapse: collapse;
}
.sub-container {
padding: 0px 20px;
}
.report-header {
width: 100%;
}
.heading-text {
font-weight: bold;
font-size: 24px;
color: #5851D8;
width: 100%;
text-align: left;
padding: 0px;
margin: 0px;
}
.heading-date-range {
font-weight: normal;
font-size: 15px;
color: #A5ACC1;
width: 100%;
text-align: right;
padding: 0px;
margin: 0px;
}
.sub-heading-text {
font-weight: normal;
font-size: 16px;
color: #595959;
padding: 0px;
margin: 0px;
margin-top: 6px;
}
.expenses-title {
margin-top: 60px;
padding-left: 3px;
font-size: 16px;
line-height: 21px;
color: #040405;
}
.expenses-table-container {
padding-left: 10px;
}
.expenses-table {
width: 100%;
padding-bottom: 10px;
}
.expense-title {
padding: 0px;
margin: 0px;
font-size: 14px;
line-height: 21px;
color: #595959;
}
.expense-amount {
padding: 0px;
margin: 0px;
font-size: 14px;
line-height: 21px;
text-align: right;
color: #595959;
}
.expense-total-table {
border-top: 1px solid #EAF1FB;
width: 100%;
}
.expense-total-cell {
padding-right: 20px;
padding-top: 10px;
}
.expense-total {
padding-top: 10px;
padding-right: 30px;
padding: 0px;
margin: 0px;
text-align: right;
font-weight: bold;
font-size: 16px;
line-height: 21px;
text-align: right;
color: #040405;
}
.report-footer {
width: 100%;
margin-top: 40px;
padding: 15px 20px;
background: #F9FBFF;
box-sizing: border-box;
}
.report-footer-label {
padding: 0px;
margin: 0px;
text-align: left;
font-weight: bold;
font-size: 16px;
line-height: 21px;
color: #595959;
}
.report-footer-value {
padding: 0px;
margin: 0px;
text-align: right;
font-weight: bold;
font-size: 20px;
line-height: 21px;
color: #5851D8;
}
/* -- Items Table (grouped itemized expenses) -- */
.item-table-heading-left {
font-size: 13.5px;
text-align: left;
color: rgba(0, 0, 0, 0.85);
padding: 5px;
padding-bottom: 10px;
}
.item-table-heading-right {
font-size: 13.5px;
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;
}
tr.item-row td {
font-size: 12px;
line-height: 18px;
}
.item-cell-left {
font-size: 13px;
color: #040405;
text-align: left;
padding: 5px;
padding-top: 10px;
border-color: #d9d9d9;
}
.item-cell-right {
font-size: 13px;
color: #040405;
text-align: right;
padding: 5px;
padding-top: 10px;
border-color: #d9d9d9;
}
.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;
}
</style>
</head>
<body>
<div class="sub-container">
<table class="report-header">
<tr>
<td>
<p class="heading-text">{{ $company->name }}</p>
</td>
<td>
<p class="heading-date-range">{{ $from_date }} - {{ $to_date }}</p>
</td>
</tr>
<tr>
<td colspan="2">
<p class="sub-heading-text">@lang('pdf_expense_report_label')</p>
</td>
</tr>
</table>
<p class="expenses-title">@lang('pdf_expenses_label')</p>
@foreach ($expenseGroups as $group)
<p class="expense-title">{{ $group['name'] }}</p>
<table width="100%" style="margin-bottom:18px;">
<tr class="item-table-heading-row">
<th style="width: 15%;" class="text-left item-table-heading-left">@lang('expenses.date')</th>
<th style="width: 70%;" class="text-left item-table-heading-left">@lang('expenses.note')</th>
<th style="width: 15%;" class="text-right item-table-heading-right">@lang('expenses.amount')</th>
</tr>
@foreach ($group['expenses'] as $expense)
<tr class="item-row">
<td style="width: 15%;" class="text-left item-cell-left">{{ $expense->formatted_expense_date }}</td>
<td style="width: 70%;" class="text-left item-cell-left">{{ $expense->notes ? $expense->notes : '-' }}</td>
<td style="width: 15%;" class="text-right item-cell-right">{!! format_money_pdf($expense->base_amount, $currency) !!}</td>
</tr>
@endforeach
</table>
<div class="item-table-group-total">
<p>@lang('pdf_expense_group_total_label')&nbsp;&nbsp;&nbsp;<span style="color: #5851D8;">{!! format_money_pdf($group['total'], $currency) !!}</span></p>
</div>
@endforeach
</div>
<table class="report-footer">
<tr>
<td>
<p class="report-footer-label">@lang('pdf_total_expenses_label')</p>
</td>
<td>
<p class="report-footer-value">{!! format_money_pdf($totalExpense, $currency) !!}</p>
</td>
</tr>
</table>
</body>
</html>