Andrew Wallo 11 місяці тому
джерело
коміт
72847a74ec
21 змінених файлів з 437 додано та 99 видалено
  1. 4
    0
      app/Contracts/ExportableReport.php
  2. 4
    0
      app/DTO/ReportDTO.php
  3. 2
    2
      app/Filament/Company/Pages/Reports/BalanceSheet.php
  4. 2
    2
      app/Filament/Company/Pages/Reports/CashFlowStatement.php
  5. 2
    2
      app/Filament/Company/Pages/Reports/IncomeStatement.php
  6. 30
    10
      app/Services/ReportService.php
  7. 31
    0
      app/Transformers/BalanceSheetReportTransformer.php
  8. 10
    0
      app/Transformers/BaseReportTransformer.php
  9. 98
    5
      app/Transformers/CashFlowStatementReportTransformer.php
  10. 32
    0
      app/Transformers/IncomeStatementReportTransformer.php
  11. 0
    45
      config/chart-of-accounts.php
  12. 1
    1
      resources/views/components/company/tables/cell.blade.php
  13. 1
    1
      resources/views/components/company/tables/footer.blade.php
  14. 7
    2
      resources/views/components/company/tables/reports/balance-sheet-summary.blade.php
  15. 16
    7
      resources/views/components/company/tables/reports/balance-sheet.blade.php
  16. 71
    0
      resources/views/components/company/tables/reports/cash-flow-statement-summary.blade.php
  17. 34
    10
      resources/views/components/company/tables/reports/cash-flow-statement.blade.php
  18. 10
    7
      resources/views/components/company/tables/reports/income-statement-summary.blade.php
  19. 77
    0
      resources/views/components/company/tables/reports/income-statement.blade.php
  20. 4
    4
      resources/views/filament/company/pages/reports/cash-flow-statement.blade.php
  21. 1
    1
      resources/views/filament/company/pages/reports/income-statement.blade.php

+ 4
- 0
app/Contracts/ExportableReport.php Переглянути файл

@@ -26,4 +26,8 @@ interface ExportableReport
26 26
     public function getPdfView(): string;
27 27
 
28 28
     public function getAlignmentClass(string $columnName): string;
29
+
30
+    public function getStartDate(): ?string;
31
+
32
+    public function getEndDate(): ?string;
29 33
 }

+ 4
- 0
app/DTO/ReportDTO.php Переглянути файл

@@ -2,6 +2,8 @@
2 2
 
3 3
 namespace App\DTO;
4 4
 
5
+use Illuminate\Support\Carbon;
6
+
5 7
 class ReportDTO
6 8
 {
7 9
     public function __construct(
@@ -13,5 +15,7 @@ class ReportDTO
13 15
         public array $fields = [],
14 16
         public ?string $reportType = null,
15 17
         public ?CashFlowOverviewDTO $overview = null,
18
+        public ?Carbon $startDate = null,
19
+        public ?Carbon $endDate = null,
16 20
     ) {}
17 21
 }

+ 2
- 2
app/Filament/Company/Pages/Reports/BalanceSheet.php Переглянути файл

@@ -38,8 +38,8 @@ class BalanceSheet extends BaseReportPage
38 38
         return [
39 39
             Column::make('account_code')
40 40
                 ->label('Account Code')
41
-                ->toggleable()
42
-                ->alignment(Alignment::Center),
41
+                ->toggleable(isToggledHiddenByDefault: true)
42
+                ->alignment(Alignment::Left),
43 43
             Column::make('account_name')
44 44
                 ->label('Account')
45 45
                 ->alignment(Alignment::Left),

+ 2
- 2
app/Filament/Company/Pages/Reports/CashFlowStatement.php Переглянути файл

@@ -40,8 +40,8 @@ class CashFlowStatement extends BaseReportPage
40 40
         return [
41 41
             Column::make('account_code')
42 42
                 ->label('Account Code')
43
-                ->toggleable()
44
-                ->alignment(Alignment::Center),
43
+                ->toggleable(isToggledHiddenByDefault: true)
44
+                ->alignment(Alignment::Left),
45 45
             Column::make('account_name')
46 46
                 ->label('Account')
47 47
                 ->alignment(Alignment::Left),

+ 2
- 2
app/Filament/Company/Pages/Reports/IncomeStatement.php Переглянути файл

@@ -40,8 +40,8 @@ class IncomeStatement extends BaseReportPage
40 40
         return [
41 41
             Column::make('account_code')
42 42
                 ->label('Account Code')
43
-                ->toggleable()
44
-                ->alignment(Alignment::Center),
43
+                ->toggleable(isToggledHiddenByDefault: true)
44
+                ->alignment(Alignment::Left),
45 45
             Column::make('account_name')
46 46
                 ->label('Account')
47 47
                 ->alignment(Alignment::Left),

+ 30
- 10
app/Services/ReportService.php Переглянути файл

@@ -46,7 +46,9 @@ class ReportService
46 46
     {
47 47
         $orderedCategories = AccountCategory::getOrderedCategories();
48 48
 
49
-        $accounts = $this->accountService->getAccountBalances($startDate, $endDate)->get();
49
+        $accounts = $this->accountService->getAccountBalances($startDate, $endDate)
50
+            ->orderByRaw('LENGTH(code), code')
51
+            ->get();
50 52
 
51 53
         $columnNameKeys = array_map(fn (Column $column) => $column->getName(), $columns);
52 54
 
@@ -54,8 +56,7 @@ class ReportService
54 56
         $reportTotalBalances = [];
55 57
 
56 58
         foreach ($orderedCategories as $category) {
57
-            $accountsInCategory = $accounts->where('category', $category)
58
-                ->sortBy('code', SORT_NATURAL);
59
+            $accountsInCategory = $accounts->where('category', $category);
59 60
 
60 61
             $relevantFields = array_intersect($category->getRelevantBalanceFields(), $columnNameKeys);
61 62
 
@@ -97,7 +98,11 @@ class ReportService
97 98
 
98 99
         $formattedReportTotalBalances = $this->formatBalances($reportTotalBalances);
99 100
 
100
-        return new ReportDTO($accountCategories, $formattedReportTotalBalances, $columns);
101
+        return new ReportDTO(
102
+            categories: $accountCategories,
103
+            overallTotal: $formattedReportTotalBalances,
104
+            fields: $columns,
105
+        );
101 106
     }
102 107
 
103 108
     public function calculateAccountBalances(Account $account): array
@@ -154,7 +159,8 @@ class ReportService
154 159
 
155 160
         $accountIds = $accountId !== 'all' ? [$accountId] : [];
156 161
 
157
-        $query = $this->accountService->getAccountBalances($startDate, $endDate, $accountIds);
162
+        $query = $this->accountService->getAccountBalances($startDate, $endDate, $accountIds)
163
+            ->orderByRaw('LENGTH(code), code');
158 164
 
159 165
         $accounts = $query->with(['journalEntries' => $this->accountService->getTransactionDetailsSubquery($startDate, $endDate)])->get();
160 166
 
@@ -245,6 +251,7 @@ class ReportService
245 251
 
246 252
         $accounts = $this->accountService->getAccountBalances($startDateCarbon->toDateTimeString(), $asOfDateCarbon->toDateTimeString())
247 253
             ->when($isPostClosingTrialBalance, fn (Builder $query) => $query->whereNotIn('category', [AccountCategory::Revenue, AccountCategory::Expense]))
254
+            ->orderByRaw('LENGTH(code), code')
248 255
             ->get();
249 256
 
250 257
         $balanceFields = ['debit_balance', 'credit_balance'];
@@ -253,8 +260,7 @@ class ReportService
253 260
         $reportTotalBalances = array_fill_keys($balanceFields, 0);
254 261
 
255 262
         foreach ($orderedCategories as $category) {
256
-            $accountsInCategory = $accounts->where('category', $category)
257
-                ->sortBy('code', SORT_NATURAL);
263
+            $accountsInCategory = $accounts->where('category', $category);
258 264
 
259 265
             $categorySummaryBalances = array_fill_keys($balanceFields, 0);
260 266
 
@@ -432,7 +438,13 @@ class ReportService
432 438
         $netProfit = $grossProfit - $totalExpenses;
433 439
         $formattedReportTotalBalances = $this->formatBalances(['net_movement' => $netProfit]);
434 440
 
435
-        return new ReportDTO($accountCategories, $formattedReportTotalBalances, $columns);
441
+        return new ReportDTO(
442
+            categories: $accountCategories,
443
+            overallTotal: $formattedReportTotalBalances,
444
+            fields: $columns,
445
+            startDate: Carbon::parse($startDate),
446
+            endDate: Carbon::parse($endDate),
447
+        );
436 448
     }
437 449
 
438 450
     public function buildCashFlowStatementReport(string $startDate, string $endDate, array $columns = []): ReportDTO
@@ -451,7 +463,9 @@ class ReportService
451 463
             categories: $sections,
452 464
             overallTotal: $totalCashFlows,
453 465
             fields: $columns,
454
-            overview: $overview
466
+            overview: $overview,
467
+            startDate: Carbon::parse($startDate),
468
+            endDate: Carbon::parse($endDate),
455 469
         );
456 470
     }
457 471
 
@@ -759,6 +773,12 @@ class ReportService
759 773
 
760 774
         $formattedReportTotalBalances = $this->formatBalances(['ending_balance' => $netAssets]);
761 775
 
762
-        return new ReportDTO($accountCategories, $formattedReportTotalBalances, $columns);
776
+        return new ReportDTO(
777
+            categories: $accountCategories,
778
+            overallTotal: $formattedReportTotalBalances,
779
+            fields: $columns,
780
+            startDate: $startDateCarbon,
781
+            endDate: $asOfDateCarbon,
782
+        );
763 783
     }
764 784
 }

+ 31
- 0
app/Transformers/BalanceSheetReportTransformer.php Переглянути файл

@@ -244,6 +244,37 @@ class BalanceSheetReportTransformer extends SummaryReportTransformer
244 244
         return [];
245 245
     }
246 246
 
247
+    public function getTitleHeaders(): array
248
+    {
249
+        return once(function (): array {
250
+            $headers = [];
251
+
252
+            $dateRange = $this->getEndDate() ? $this->getEndDate() : '';
253
+
254
+            foreach ($this->getColumns() as $column) {
255
+                $headers[$column->getName()] = match ($column->getName()) {
256
+                    'account_name' => 'ACCOUNTS',
257
+                    'ending_balance' => $dateRange,
258
+                    default => '',
259
+                };
260
+            }
261
+
262
+            return $headers;
263
+        });
264
+    }
265
+
266
+    public function getSummaryTitleHeaders(): array
267
+    {
268
+        return once(function (): array {
269
+            $headers = $this->getTitleHeaders();
270
+
271
+            // Remove the account_code key if it exists
272
+            unset($headers['account_code']);
273
+
274
+            return $headers;
275
+        });
276
+    }
277
+
247 278
     public function getSummary(): array
248 279
     {
249 280
         return [

+ 10
- 0
app/Transformers/BaseReportTransformer.php Переглянути файл

@@ -76,4 +76,14 @@ abstract class BaseReportTransformer implements ExportableReport
76 76
             return 'text-left';
77 77
         });
78 78
     }
79
+
80
+    public function getStartDate(): ?string
81
+    {
82
+        return $this->report->startDate?->toDefaultDateFormat();
83
+    }
84
+
85
+    public function getEndDate(): ?string
86
+    {
87
+        return $this->report->endDate?->toDefaultDateFormat();
88
+    }
79 89
 }

+ 98
- 5
app/Transformers/CashFlowStatementReportTransformer.php Переглянути файл

@@ -146,7 +146,7 @@ class CashFlowStatementReportTransformer extends SummaryReportTransformer
146 146
 
147 147
                 foreach ($columns as $column) {
148 148
                     $typeSummary[$column->getName()] = match ($column->getName()) {
149
-                        'account_name' => 'Total ' . $typeName,
149
+                        'account_name' => $typeName,
150 150
                         'net_movement' => $type->summary->netMovement ?? '',
151 151
                         default => '',
152 152
                     };
@@ -185,21 +185,21 @@ class CashFlowStatementReportTransformer extends SummaryReportTransformer
185 185
     {
186 186
         return [
187 187
             [
188
-                'label' => 'Gross Cash Inflow',
188
+                'label' => 'Total Cash Inflows',
189 189
                 'value' => $this->report->overallTotal->debitBalance ?? '',
190 190
             ],
191 191
             [
192
-                'label' => 'Gross Cash Outflow',
192
+                'label' => 'Total Cash Outflows',
193 193
                 'value' => $this->report->overallTotal->creditBalance ?? '',
194 194
             ],
195 195
             [
196
-                'label' => 'Net Cash Change',
196
+                'label' => 'Net Cash Flow',
197 197
                 'value' => $this->report->overallTotal->netMovement ?? '',
198 198
             ],
199 199
         ];
200 200
     }
201 201
 
202
-    public function getSummaryAlignedWithColumns(): array
202
+    public function getOverviewAlignedWithColumns(): array
203 203
     {
204 204
         $summary = [];
205 205
 
@@ -220,6 +220,72 @@ class CashFlowStatementReportTransformer extends SummaryReportTransformer
220 220
         return $summary;
221 221
     }
222 222
 
223
+    public function getSummaryOverviewAlignedWithColumns(): array
224
+    {
225
+        return array_map(static function ($row) {
226
+            unset($row['account_code']);
227
+
228
+            return $row;
229
+        }, $this->getOverviewAlignedWithColumns());
230
+    }
231
+
232
+    public function getCashInflowAndOutflowHeaders(): array
233
+    {
234
+        return once(function (): array {
235
+            $headers = [];
236
+
237
+            $dateRange = $this->getStartDate() && $this->getEndDate()
238
+                ? "{$this->getStartDate()} - {$this->getEndDate()}"
239
+                : '';
240
+
241
+            foreach ($this->getColumns() as $column) {
242
+                $headers[$column->getName()] = match ($column->getName()) {
243
+                    'account_name' => 'CASH INFLOWS AND OUTFLOWS',
244
+                    'net_movement' => $dateRange,
245
+                    default => '',
246
+                };
247
+            }
248
+
249
+            return $headers;
250
+        });
251
+    }
252
+
253
+    public function getSummaryCashInflowAndOutflowHeaders(): array
254
+    {
255
+        return once(function (): array {
256
+            $headers = $this->getCashInflowAndOutflowHeaders();
257
+
258
+            // Remove the account_code key if it exists
259
+            unset($headers['account_code']);
260
+
261
+            return $headers;
262
+        });
263
+    }
264
+
265
+    public function getOverviewHeaders(): array
266
+    {
267
+        return once(function (): array {
268
+            $headers = [];
269
+
270
+            foreach ($this->getColumns() as $column) {
271
+                $headers[$column->getName()] = $column->getName() === 'account_name' ? 'OVERVIEW' : '';
272
+            }
273
+
274
+            return $headers;
275
+        });
276
+    }
277
+
278
+    public function getSummaryOverviewHeaders(): array
279
+    {
280
+        return once(function (): array {
281
+            $headers = $this->getOverviewHeaders();
282
+
283
+            unset($headers['account_code']);
284
+
285
+            return $headers;
286
+        });
287
+    }
288
+
223 289
     public function getOverview(): array
224 290
     {
225 291
         $categories = [];
@@ -270,4 +336,31 @@ class CashFlowStatementReportTransformer extends SummaryReportTransformer
270 336
 
271 337
         return $categories;
272 338
     }
339
+
340
+    public function getSummaryOverview(): array
341
+    {
342
+        $summaryCategories = [];
343
+
344
+        $columns = $this->getSummaryColumns();
345
+
346
+        foreach ($this->report->overview->categories as $categoryName => $category) {
347
+            $categorySummary = [];
348
+
349
+            foreach ($columns as $column) {
350
+                $categorySummary[$column->getName()] = match ($column->getName()) {
351
+                    'account_name' => $categoryName,
352
+                    'net_movement' => $category->summary->startingBalance ?? $category->summary->endingBalance ?? '',
353
+                    default => '',
354
+                };
355
+            }
356
+
357
+            $summaryCategories[] = new ReportCategoryDTO(
358
+                header: [],
359
+                data: [],
360
+                summary: $categorySummary,
361
+            );
362
+        }
363
+
364
+        return $summaryCategories;
365
+    }
273 366
 }

+ 32
- 0
app/Transformers/IncomeStatementReportTransformer.php Переглянути файл

@@ -179,6 +179,38 @@ class IncomeStatementReportTransformer extends SummaryReportTransformer
179 179
         return $totals;
180 180
     }
181 181
 
182
+    public function getTitleHeaders(): array
183
+    {
184
+        return once(function (): array {
185
+            $headers = [];
186
+
187
+            $dateRange = $this->getStartDate() && $this->getEndDate()
188
+                ? "{$this->getStartDate()} - {$this->getEndDate()}"
189
+                : '';
190
+
191
+            foreach ($this->getColumns() as $column) {
192
+                $headers[$column->getName()] = match ($column->getName()) {
193
+                    'account_name' => 'ACCOUNTS',
194
+                    'net_movement' => $dateRange,
195
+                    default => '',
196
+                };
197
+            }
198
+
199
+            return $headers;
200
+        });
201
+    }
202
+
203
+    public function getSummaryTitleHeaders(): array
204
+    {
205
+        return once(function (): array {
206
+            $headers = $this->getTitleHeaders();
207
+
208
+            unset($headers['account_code']);
209
+
210
+            return $headers;
211
+        });
212
+    }
213
+
182 214
     public function getSummary(): array
183 215
     {
184 216
         return [

+ 0
- 45
config/chart-of-accounts.php Переглянути файл

@@ -454,49 +454,4 @@ return [
454 454
             ],
455 455
         ],
456 456
     ],
457
-
458
-    'cash_flow' => [
459
-        'operating_activities' => [
460
-            'directly_listed' => [
461
-                'operating_revenue',
462
-                'uncategorized_revenue',
463
-                'operating_expense',
464
-                'non_operating_expense', // e.g., interest expense
465
-                'uncategorized_expense',
466
-                'current_asset', // All current assets except for 'Cash and Cash Equivalents'
467
-            ],
468
-            'adjustments' => [
469
-                'types' => [
470
-                    'contra_asset', // Adjustments like accumulated depreciation
471
-                    'current_liability', // Changes in accounts like Accounts Payable, Accrued Expenses
472
-                ],
473
-            ],
474
-        ],
475
-        'investing_activities' => [
476
-            'directly_listed' => [
477
-                'non_current_asset', // Purchases or sales of long-term assets
478
-            ],
479
-            'adjustments' => [
480
-                'types' => [
481
-                    'non_operating_revenue', // Gains or losses on asset sales
482
-                ],
483
-            ],
484
-        ],
485
-        'financing_activities' => [
486
-            'directly_listed' => [
487
-                'equity', // Cash flows from issuing stock, dividends paid
488
-                'non_current_liability', // Cash flows related to long-term debt
489
-                'short_term_borrowings', // Proceeds or repayments of short-term loans
490
-            ],
491
-        ],
492
-        'missing_activities' => [
493
-            'types' => [
494
-                'contra_liability', // Adjustments, not direct cash flows
495
-                'contra_equity', // E.g., treasury stock adjustments
496
-                'contra_revenue', // Sales returns or allowances
497
-                'contra_expense', // Purchase discounts
498
-                'Cash and Cash Equivalents', // Only appears in beginning/ending balances
499
-            ],
500
-        ],
501
-    ],
502 457
 ];

+ 1
- 1
resources/views/components/company/tables/cell.blade.php Переглянути файл

@@ -10,7 +10,7 @@
10 10
     @class([
11 11
         $alignmentClass,
12 12
         'last-of-type:pe-1 sm:last-of-type:pe-3',
13
-        'ps-3 sm:ps-6' => $indent,
13
+        'ps-4 sm:first-of-type:ps-7' => $indent,
14 14
         'p-0 first-of-type:ps-1 sm:first-of-type:ps-3' => ! $indent,
15 15
     ])
16 16
 >

+ 1
- 1
resources/views/components/company/tables/footer.blade.php Переглянути файл

@@ -5,7 +5,7 @@
5 5
     <tr class="bg-gray-50 dark:bg-white/5">
6 6
         @foreach($totals as $totalIndex => $totalCell)
7 7
             <x-filament-tables::cell class="{{ $alignmentClass($totalIndex) }}">
8
-                <div class="px-3 py-3 text-sm leading-6 font-semibold text-gray-950 dark:text-white">
8
+                <div class="px-3 py-3.5 text-sm font-semibold leading-6 text-gray-950 dark:text-white">
9 9
                     {{ $totalCell }}
10 10
                 </div>
11 11
             </x-filament-tables::cell>

+ 7
- 2
resources/views/components/company/tables/reports/balance-sheet-summary.blade.php Переглянути файл

@@ -1,5 +1,10 @@
1
-<table class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5">
2
-    <x-company.tables.header :headers="$report->getSummaryHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        <col span="1" style="width: 65%;">
4
+        <col span="1" style="width: 35%;">
5
+    </colgroup>
6
+    <x-company.tables.header :headers="$report->getSummaryTitleHeaders()"
7
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
3 8
     @foreach($report->getSummaryCategories() as $accountCategory)
4 9
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
5 10
         <x-company.tables.category-header :category-headers="$accountCategory->header"

+ 16
- 7
resources/views/components/company/tables/reports/balance-sheet.blade.php Переглянути файл

@@ -1,5 +1,15 @@
1
-<table class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5">
2
-    <x-company.tables.header :headers="$report->getHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        @if(array_key_exists('account_code', $report->getHeaders()))
4
+            <col span="1" style="width: 20%;">
5
+            <col span="1" style="width: 55%;">
6
+            <col span="1" style="width: 25%;">
7
+        @else
8
+            <col span="1" style="width: 65%;">
9
+            <col span="1" style="width: 35%;">
10
+        @endif
11
+    </colgroup>
12
+    <x-company.tables.header :headers="$report->getTitleHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
3 13
     @foreach($report->getCategories() as $accountCategory)
4 14
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
5 15
         <x-company.tables.category-header :category-headers="$accountCategory->header"
@@ -7,8 +17,7 @@
7 17
         @foreach($accountCategory->data as $categoryAccount)
8 18
             <tr>
9 19
                 @foreach($categoryAccount as $accountIndex => $categoryAccountCell)
10
-                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)"
11
-                                           indent="true">
20
+                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)">
12 21
                         @if(is_array($categoryAccountCell) && isset($categoryAccountCell['name']))
13 22
                             @if($categoryAccountCell['name'] === 'Retained Earnings' && isset($categoryAccountCell['start_date']) && isset($categoryAccountCell['end_date']))
14 23
                                 <x-filament::link
@@ -53,7 +62,7 @@
53 62
             <tr class="bg-gray-50 dark:bg-white/5">
54 63
                 @foreach($accountType->header as $accountTypeHeaderIndex => $accountTypeHeaderCell)
55 64
                     <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountTypeHeaderIndex)"
56
-                                           indent="true" bold="true">
65
+                                           :indent="$accountTypeHeaderIndex === 'account_name'" bold="true">
57 66
                         {{ $accountTypeHeaderCell }}
58 67
                     </x-company.tables.cell>
59 68
                 @endforeach
@@ -62,7 +71,7 @@
62 71
                 <tr>
63 72
                     @foreach($typeAccount as $accountIndex => $typeAccountCell)
64 73
                         <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)"
65
-                                               indent="true">
74
+                                               :indent="$accountIndex === 'account_name'">
66 75
                             @if(is_array($typeAccountCell) && isset($typeAccountCell['name']))
67 76
                                 @if($typeAccountCell['name'] === 'Retained Earnings' && isset($typeAccountCell['start_date']) && isset($typeAccountCell['end_date']))
68 77
                                     <x-filament::link
@@ -106,7 +115,7 @@
106 115
             <tr>
107 116
                 @foreach($accountType->summary as $accountTypeSummaryIndex => $accountTypeSummaryCell)
108 117
                     <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountTypeSummaryIndex)"
109
-                                           indent="true" bold="true">
118
+                                           :indent="$accountTypeSummaryIndex === 'account_name'" bold="true">
110 119
                         {{ $accountTypeSummaryCell }}
111 120
                     </x-company.tables.cell>
112 121
                 @endforeach

+ 71
- 0
resources/views/components/company/tables/reports/cash-flow-statement-summary.blade.php Переглянути файл

@@ -0,0 +1,71 @@
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        <col span="1" style="width: 65%;">
4
+        <col span="1" style="width: 35%;">
5
+    </colgroup>
6
+    <x-company.tables.header :headers="$report->getSummaryCashInflowAndOutflowHeaders()"
7
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
8
+    @foreach($report->getSummaryCategories() as $accountCategory)
9
+        <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
10
+        <x-company.tables.category-header :category-headers="$accountCategory->header"
11
+                                          :alignment-class="[$report, 'getAlignmentClass']"/>
12
+        @foreach($accountCategory->types as $accountType)
13
+            <tr>
14
+                @foreach($accountType->summary as $accountTypeSummaryIndex => $accountTypeSummaryCell)
15
+                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountTypeSummaryIndex)">
16
+                        {{ $accountTypeSummaryCell }}
17
+                    </x-company.tables.cell>
18
+                @endforeach
19
+            </tr>
20
+        @endforeach
21
+        <tr>
22
+            @foreach($accountCategory->summary as $accountCategorySummaryIndex => $accountCategorySummaryCell)
23
+                <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountCategorySummaryIndex)"
24
+                                       bold="true" :underline-bold="$loop->last">
25
+                    {{ $accountCategorySummaryCell }}
26
+                </x-company.tables.cell>
27
+            @endforeach
28
+        </tr>
29
+        <tr>
30
+            <td colspan="{{ count($report->getSummaryHeaders()) }}">
31
+                <div class="min-h-12"></div>
32
+            </td>
33
+        </tr>
34
+        </tbody>
35
+    @endforeach
36
+</table>
37
+
38
+<table class="w-full table-fixed divide-y border-t divide-gray-200 dark:divide-white/5">
39
+    <colgroup>
40
+        <col span="1" style="width: 65%;">
41
+        <col span="1" style="width: 35%;">
42
+    </colgroup>
43
+    <x-company.tables.header :headers="$report->getSummaryOverviewHeaders()"
44
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
45
+    @foreach($report->getSummaryOverview() as $overviewCategory)
46
+        <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
47
+        <tr class="bg-gray-50 dark:bg-white/5">
48
+            @foreach($overviewCategory->summary as $overviewSummaryIndex => $overviewSummaryCell)
49
+                <x-company.tables.cell :alignment-class="$report->getAlignmentClass($overviewSummaryIndex)" bold="true">
50
+                    {{ $overviewSummaryCell }}
51
+                </x-company.tables.cell>
52
+            @endforeach
53
+        </tr>
54
+        @if($overviewCategory->summary['account_name'] === 'Starting Balance')
55
+            @foreach($report->getSummaryOverviewAlignedWithColumns() as $summaryRow)
56
+                <tr>
57
+                    @foreach($summaryRow as $summaryIndex => $summaryCell)
58
+                        <x-company.tables.cell :alignment-class="$report->getAlignmentClass($summaryIndex)"
59
+                                               :bold="$loop->parent->last"
60
+                                               :underline-bold="$loop->parent->last && $summaryIndex === 'net_movement'"
61
+                                               :underline-thin="$loop->parent->remaining === 1 && $summaryIndex === 'net_movement'"
62
+                        >
63
+                            {{ $summaryCell }}
64
+                        </x-company.tables.cell>
65
+                    @endforeach
66
+                </tr>
67
+            @endforeach
68
+        @endif
69
+        </tbody>
70
+    @endforeach
71
+</table>

+ 34
- 10
resources/views/components/company/tables/reports/cash-flow-statement.blade.php Переглянути файл

@@ -1,5 +1,16 @@
1
-<table class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5">
2
-    <x-company.tables.header :headers="$report->getHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        @if(array_key_exists('account_code', $report->getHeaders()))
4
+            <col span="1" style="width: 20%;">
5
+            <col span="1" style="width: 55%;">
6
+            <col span="1" style="width: 25%;">
7
+        @else
8
+            <col span="1" style="width: 65%;">
9
+            <col span="1" style="width: 35%;">
10
+        @endif
11
+    </colgroup>
12
+    <x-company.tables.header :headers="$report->getCashInflowAndOutflowHeaders()"
13
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
3 14
     @foreach($report->getCategories() as $accountCategory)
4 15
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
5 16
         <x-company.tables.category-header :category-headers="$accountCategory->header"
@@ -7,8 +18,7 @@
7 18
         @foreach($accountCategory->data as $categoryAccount)
8 19
             <tr>
9 20
                 @foreach($categoryAccount as $accountIndex => $categoryAccountCell)
10
-                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)"
11
-                                           indent="true">
21
+                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)">
12 22
                         @if(is_array($categoryAccountCell) && isset($categoryAccountCell['name']))
13 23
                             @if($categoryAccountCell['name'] === 'Retained Earnings' && isset($categoryAccountCell['start_date']) && isset($categoryAccountCell['end_date']))
14 24
                                 <x-filament::link
@@ -53,7 +63,7 @@
53 63
             <tr class="bg-gray-50 dark:bg-white/5">
54 64
                 @foreach($accountType->header as $accountTypeHeaderIndex => $accountTypeHeaderCell)
55 65
                     <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountTypeHeaderIndex)"
56
-                                           indent="true" bold="true">
66
+                                           :indent="$accountTypeHeaderIndex === 'account_name'" bold="true">
57 67
                         {{ $accountTypeHeaderCell }}
58 68
                     </x-company.tables.cell>
59 69
                 @endforeach
@@ -62,7 +72,7 @@
62 72
                 <tr>
63 73
                     @foreach($typeAccount as $accountIndex => $typeAccountCell)
64 74
                         <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)"
65
-                                               indent="true">
75
+                                               :indent="$accountIndex === 'account_name'">
66 76
                             @if(is_array($typeAccountCell) && isset($typeAccountCell['name']))
67 77
                                 @if($typeAccountCell['name'] === 'Retained Earnings' && isset($typeAccountCell['start_date']) && isset($typeAccountCell['end_date']))
68 78
                                     <x-filament::link
@@ -106,7 +116,7 @@
106 116
             <tr>
107 117
                 @foreach($accountType->summary as $accountTypeSummaryIndex => $accountTypeSummaryCell)
108 118
                     <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountTypeSummaryIndex)"
109
-                                           indent="true" bold="true">
119
+                                           :indent="$accountIndex === 'account_name'" bold="true">
110 120
                         {{ $accountTypeSummaryCell }}
111 121
                     </x-company.tables.cell>
112 122
                 @endforeach
@@ -127,6 +137,22 @@
127 137
         </tr>
128 138
         </tbody>
129 139
     @endforeach
140
+    <x-company.tables.footer :totals="$report->getOverallTotals()" :alignment-class="[$report, 'getAlignmentClass']"/>
141
+</table>
142
+
143
+<table class="w-full table-fixed divide-y border-t divide-gray-200 dark:divide-white/5">
144
+    <colgroup>
145
+        @if(array_key_exists('account_code', $report->getHeaders()))
146
+            <col span="1" style="width: 20%;">
147
+            <col span="1" style="width: 55%;">
148
+            <col span="1" style="width: 25%;">
149
+        @else
150
+            <col span="1" style="width: 65%;">
151
+            <col span="1" style="width: 35%;">
152
+        @endif
153
+    </colgroup>
154
+    <x-company.tables.header :headers="$report->getOverviewHeaders()"
155
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
130 156
     @foreach($report->getOverview() as $overviewCategory)
131 157
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
132 158
         <x-company.tables.category-header :category-headers="$overviewCategory->header"
@@ -169,8 +195,7 @@
169 195
             @endforeach
170 196
         </tr>
171 197
         @if($overviewCategory->header['account_name'] === 'Starting Balance')
172
-            <!-- Insert Gross Cash Inflow, Gross Cash Outflow, and Net Cash Change here -->
173
-            @foreach($report->getSummaryAlignedWithColumns() as $summaryRow)
198
+            @foreach($report->getOverviewAlignedWithColumns() as $summaryRow)
174 199
                 <tr>
175 200
                     @foreach($summaryRow as $summaryIndex => $summaryCell)
176 201
                         <x-company.tables.cell :alignment-class="$report->getAlignmentClass($summaryIndex)"
@@ -186,5 +211,4 @@
186 211
         @endif
187 212
         </tbody>
188 213
     @endforeach
189
-    <x-company.tables.footer :totals="$report->getOverallTotals()" :alignment-class="[$report, 'getAlignmentClass']"/>
190 214
 </table>

+ 10
- 7
resources/views/components/company/tables/reports/income-statement-summary.blade.php Переглянути файл

@@ -1,5 +1,10 @@
1
-<table class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5">
2
-    <x-company.tables.header :headers="$report->getSummaryHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        <col span="1" style="width: 65%;">
4
+        <col span="1" style="width: 35%;">
5
+    </colgroup>
6
+    <x-company.tables.header :headers="$report->getSummaryTitleHeaders()"
7
+                             :alignment-class="[$report, 'getAlignmentClass']"/>
3 8
     @foreach($report->getSummaryCategories() as $accountCategory)
4 9
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
5 10
         <tr>
@@ -13,11 +18,9 @@
13 18
         @if($accountCategory->header['account_name'] === 'Cost of Goods Sold')
14 19
             <tr class="bg-gray-50 dark:bg-white/5">
15 20
                 @foreach($report->getGrossProfit() as $grossProfitIndex => $grossProfitCell)
16
-                    <x-filament-tables::cell class="{{ $report->getAlignmentClass($grossProfitIndex) }}">
17
-                        <div class="px-3 py-2 text-sm leading-6 font-semibold text-gray-950 dark:text-white">
18
-                            {{ $grossProfitCell }}
19
-                        </div>
20
-                    </x-filament-tables::cell>
21
+                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($grossProfitIndex)" bold="true">
22
+                        {{ $grossProfitCell }}
23
+                    </x-company.tables.cell>
21 24
                 @endforeach
22 25
             </tr>
23 26
         @endif

+ 77
- 0
resources/views/components/company/tables/reports/income-statement.blade.php Переглянути файл

@@ -0,0 +1,77 @@
1
+<table class="w-full table-fixed divide-y divide-gray-200 dark:divide-white/5">
2
+    <colgroup>
3
+        @if(array_key_exists('account_code', $report->getHeaders()))
4
+            <col span="1" style="width: 20%;">
5
+            <col span="1" style="width: 55%;">
6
+            <col span="1" style="width: 25%;">
7
+        @else
8
+            <col span="1" style="width: 65%;">
9
+            <col span="1" style="width: 35%;">
10
+        @endif
11
+    </colgroup>
12
+    <x-company.tables.header :headers="$report->getTitleHeaders()" :alignment-class="[$report, 'getAlignmentClass']"/>
13
+    @foreach($report->getCategories() as $accountCategory)
14
+        <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
15
+        <x-company.tables.category-header :category-headers="$accountCategory->header"
16
+                                          :alignment-class="[$report, 'getAlignmentClass']"/>
17
+        @foreach($accountCategory->data as $categoryAccount)
18
+            <tr>
19
+                @foreach($categoryAccount as $accountIndex => $categoryAccountCell)
20
+                    <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountIndex)">
21
+                        @if(is_array($categoryAccountCell) && isset($categoryAccountCell['name']))
22
+                            @if($categoryAccountCell['name'] === 'Retained Earnings' && isset($categoryAccountCell['start_date']) && isset($categoryAccountCell['end_date']))
23
+                                <x-filament::link
24
+                                    color="primary"
25
+                                    target="_blank"
26
+                                    icon="heroicon-o-arrow-top-right-on-square"
27
+                                    :icon-position="\Filament\Support\Enums\IconPosition::After"
28
+                                    :icon-size="\Filament\Support\Enums\IconSize::Small"
29
+                                    href="{{ \App\Filament\Company\Pages\Reports\IncomeStatement::getUrl([
30
+                                            'startDate' => $categoryAccountCell['start_date'],
31
+                                            'endDate' => $categoryAccountCell['end_date']
32
+                                        ]) }}"
33
+                                >
34
+                                    {{ $categoryAccountCell['name'] }}
35
+                                </x-filament::link>
36
+                            @elseif(isset($categoryAccountCell['id']) && isset($categoryAccountCell['start_date']) && isset($categoryAccountCell['end_date']))
37
+                                <x-filament::link
38
+                                    color="primary"
39
+                                    target="_blank"
40
+                                    icon="heroicon-o-arrow-top-right-on-square"
41
+                                    :icon-position="\Filament\Support\Enums\IconPosition::After"
42
+                                    :icon-size="\Filament\Support\Enums\IconSize::Small"
43
+                                    href="{{ \App\Filament\Company\Pages\Reports\AccountTransactions::getUrl([
44
+                                            'startDate' => $categoryAccountCell['start_date'],
45
+                                            'endDate' => $categoryAccountCell['end_date'],
46
+                                            'selectedAccount' => $categoryAccountCell['id']
47
+                                        ]) }}"
48
+                                >
49
+                                    {{ $categoryAccountCell['name'] }}
50
+                                </x-filament::link>
51
+                            @else
52
+                                {{ $categoryAccountCell['name'] }}
53
+                            @endif
54
+                        @else
55
+                            {{ $categoryAccountCell }}
56
+                        @endif
57
+                    </x-company.tables.cell>
58
+                @endforeach
59
+            </tr>
60
+        @endforeach
61
+        <tr>
62
+            @foreach($accountCategory->summary as $accountCategorySummaryIndex => $accountCategorySummaryCell)
63
+                <x-company.tables.cell :alignment-class="$report->getAlignmentClass($accountCategorySummaryIndex)"
64
+                                       bold="true">
65
+                    {{ $accountCategorySummaryCell }}
66
+                </x-company.tables.cell>
67
+            @endforeach
68
+        </tr>
69
+        <tr>
70
+            <td colspan="{{ count($report->getHeaders()) }}">
71
+                <div class="min-h-12"></div>
72
+            </td>
73
+        </tr>
74
+        </tbody>
75
+    @endforeach
76
+    <x-company.tables.footer :totals="$report->getOverallTotals()" :alignment-class="[$report, 'getAlignmentClass']"/>
77
+</table>

+ 4
- 4
resources/views/filament/company/pages/reports/cash-flow-statement.blade.php Переглянути файл

@@ -31,15 +31,15 @@
31 31
                         <div class="text-gray-600 font-medium mb-2">{{ $summary['label'] }}</div>
32 32
 
33 33
                         @php
34
-                            $isNetEarnings = $summary['label'] === 'Net Earnings';
34
+                            $isNetCashFlow = $summary['label'] === 'Net Cash Flow';
35 35
                             $isPositive = money($summary['value'], \App\Utilities\Currency\CurrencyAccessor::getDefaultCurrency())->isPositive();
36 36
                         @endphp
37 37
 
38 38
                         <strong
39 39
                             @class([
40 40
                                 'text-lg',
41
-                                'text-green-700' => $isNetEarnings && $isPositive,
42
-                                'text-danger-700' => $isNetEarnings && ! $isPositive,
41
+                                'text-green-700' => $isNetCashFlow && $isPositive,
42
+                                'text-danger-700' => $isNetCashFlow && ! $isPositive,
43 43
                             ])
44 44
                         >
45 45
                             {{ $summary['value'] }}
@@ -77,7 +77,7 @@
77 77
     <x-company.tables.container :report-loaded="$this->reportLoaded">
78 78
         @if($this->report)
79 79
             @if($activeTab === 'summary')
80
-                <x-company.tables.reports.income-statement-summary :report="$this->report"/>
80
+                <x-company.tables.reports.cash-flow-statement-summary :report="$this->report"/>
81 81
             @elseif($activeTab === 'details')
82 82
                 <x-company.tables.reports.cash-flow-statement :report="$this->report"/>
83 83
             @endif

+ 1
- 1
resources/views/filament/company/pages/reports/income-statement.blade.php Переглянути файл

@@ -79,7 +79,7 @@
79 79
             @if($activeTab === 'summary')
80 80
                 <x-company.tables.reports.income-statement-summary :report="$this->report"/>
81 81
             @elseif($activeTab === 'details')
82
-                <x-company.tables.reports.detailed-report :report="$this->report"/>
82
+                <x-company.tables.reports.income-statement :report="$this->report"/>
83 83
             @endif
84 84
         @endif
85 85
     </x-company.tables.container>

Завантаження…
Відмінити
Зберегти