瀏覽代碼

refactor Export logic and resource redirect url

3.x
wallo 1 年之前
父節點
當前提交
d78a8c9620
共有 20 個文件被更改,包括 392 次插入210 次删除
  1. 14
    0
      app/Contracts/ExportableReport.php
  2. 1
    1
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/CreateCurrency.php
  3. 2
    2
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/EditCurrency.php
  4. 1
    1
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/CreateDiscount.php
  5. 1
    1
      app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/EditDiscount.php
  6. 1
    1
      app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/CreateTax.php
  7. 1
    1
      app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/EditTax.php
  8. 21
    38
      app/Filament/Company/Pages/Reports/AccountBalances.php
  9. 62
    29
      app/Filament/Company/Pages/Reports/BaseReportPage.php
  10. 34
    5
      app/Filament/Company/Pages/Reports/TrialBalance.php
  11. 1
    1
      app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php
  12. 2
    2
      app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php
  13. 1
    1
      app/Filament/Company/Resources/Core/DepartmentResource/Pages/CreateDepartment.php
  14. 2
    2
      app/Filament/Company/Resources/Core/DepartmentResource/Pages/EditDepartment.php
  15. 0
    76
      app/Services/AccountBalancesExportService.php
  16. 57
    0
      app/Services/ExportService.php
  17. 78
    0
      app/Transformers/AccountBalanceReportTransformer.php
  18. 69
    0
      app/Transformers/TrialBalanceReportTransformer.php
  19. 5
    5
      composer.lock
  20. 39
    44
      resources/views/components/company/reports/report-pdf.blade.php

+ 14
- 0
app/Contracts/ExportableReport.php 查看文件

@@ -0,0 +1,14 @@
1
+<?php
2
+
3
+namespace App\Contracts;
4
+
5
+interface ExportableReport
6
+{
7
+    public function getTitle(): string;
8
+
9
+    public function getHeaders(): array;
10
+
11
+    public function getData(): array;
12
+
13
+    public function getOverallTotals(): array;
14
+}

+ 1
- 1
app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/CreateCurrency.php 查看文件

@@ -18,7 +18,7 @@ class CreateCurrency extends CreateRecord
18 18
 
19 19
     protected function getRedirectUrl(): string
20 20
     {
21
-        return $this->previousUrl;
21
+        return $this->getResource()::getUrl('index');
22 22
     }
23 23
 
24 24
     protected function mutateFormDataBeforeCreate(array $data): array

+ 2
- 2
app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/EditCurrency.php 查看文件

@@ -24,9 +24,9 @@ class EditCurrency extends EditRecord
24 24
         ];
25 25
     }
26 26
 
27
-    protected function getRedirectUrl(): ?string
27
+    protected function getRedirectUrl(): string
28 28
     {
29
-        return $this->previousUrl;
29
+        return $this->getResource()::getUrl('index');
30 30
     }
31 31
 
32 32
     protected function mutateFormDataBeforeSave(array $data): array

+ 1
- 1
app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/CreateDiscount.php 查看文件

@@ -18,7 +18,7 @@ class CreateDiscount extends CreateRecord
18 18
 
19 19
     protected function getRedirectUrl(): string
20 20
     {
21
-        return $this->previousUrl;
21
+        return $this->getResource()::getUrl('index');
22 22
     }
23 23
 
24 24
     protected function mutateFormDataBeforeCreate(array $data): array

+ 1
- 1
app/Filament/Company/Clusters/Settings/Resources/DiscountResource/Pages/EditDiscount.php 查看文件

@@ -25,7 +25,7 @@ class EditDiscount extends EditRecord
25 25
 
26 26
     protected function getRedirectUrl(): string
27 27
     {
28
-        return $this->previousUrl;
28
+        return $this->getResource()::getUrl('index');
29 29
     }
30 30
 
31 31
     protected function mutateFormDataBeforeSave(array $data): array

+ 1
- 1
app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/CreateTax.php 查看文件

@@ -18,7 +18,7 @@ class CreateTax extends CreateRecord
18 18
 
19 19
     protected function getRedirectUrl(): string
20 20
     {
21
-        return $this->previousUrl;
21
+        return $this->getResource()::getUrl('index');
22 22
     }
23 23
 
24 24
     protected function mutateFormDataBeforeCreate(array $data): array

+ 1
- 1
app/Filament/Company/Clusters/Settings/Resources/TaxResource/Pages/EditTax.php 查看文件

@@ -25,7 +25,7 @@ class EditTax extends EditRecord
25 25
 
26 26
     protected function getRedirectUrl(): string
27 27
     {
28
-        return $this->previousUrl;
28
+        return $this->getResource()::getUrl('index');
29 29
     }
30 30
 
31 31
     protected function mutateFormDataBeforeSave(array $data): array

+ 21
- 38
app/Filament/Company/Pages/Reports/AccountBalances.php 查看文件

@@ -3,14 +3,11 @@
3 3
 namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\DTO\ReportDTO;
6
-use App\Services\AccountBalancesExportService;
6
+use App\Services\ExportService;
7 7
 use App\Services\ReportService;
8
-use Barryvdh\DomPDF\Facade\Pdf;
9
-use Filament\Actions\Action;
10
-use Filament\Actions\ActionGroup;
11
-use Filament\Support\Enums\IconPosition;
12
-use Filament\Support\Enums\IconSize;
13
-use Illuminate\Support\Carbon;
8
+use App\Transformers\AccountBalanceReportTransformer;
9
+use Filament\Forms\Components\Split;
10
+use Filament\Forms\Form;
14 11
 use Symfony\Component\HttpFoundation\StreamedResponse;
15 12
 
16 13
 class AccountBalances extends BaseReportPage
@@ -25,12 +22,12 @@ class AccountBalances extends BaseReportPage
25 22
 
26 23
     public ReportDTO $accountBalanceReport;
27 24
 
28
-    protected AccountBalancesExportService $accountBalancesExportService;
25
+    protected ExportService $exportService;
29 26
 
30
-    public function boot(ReportService $reportService, AccountBalancesExportService $accountBalancesExportService): void
27
+    public function boot(ReportService $reportService, ExportService $exportService): void
31 28
     {
32 29
         $this->reportService = $reportService;
33
-        $this->accountBalancesExportService = $accountBalancesExportService;
30
+        $this->exportService = $exportService;
34 31
     }
35 32
 
36 33
     public function loadReportData(): void
@@ -38,43 +35,29 @@ class AccountBalances extends BaseReportPage
38 35
         $this->accountBalanceReport = $this->reportService->buildAccountBalanceReport($this->startDate, $this->endDate);
39 36
     }
40 37
 
41
-    protected function getHeaderActions(): array
38
+    public function form(Form $form): Form
42 39
     {
43
-        return [
44
-            ActionGroup::make([
45
-                Action::make('exportCSV')
46
-                    ->label('CSV')
47
-                    ->action(fn () => $this->exportCSV()),
48
-                Action::make('exportPDF')
49
-                    ->label('PDF')
50
-                    ->action(fn () => $this->exportPDF()),
51
-            ])
52
-                ->label('Export')
53
-                ->button()
54
-                ->outlined()
55
-                ->dropdownWidth('max-w-[7rem]')
56
-                ->dropdownPlacement('bottom-end')
57
-                ->icon('heroicon-c-chevron-down')
58
-                ->iconSize(IconSize::Small)
59
-                ->iconPosition(IconPosition::After),
60
-        ];
40
+        return $form
41
+            ->schema([
42
+                Split::make([
43
+                    $this->getDateRangeFormComponent(),
44
+                    $this->getStartDateFormComponent(),
45
+                    $this->getEndDateFormComponent(),
46
+                ])->live(),
47
+            ]);
61 48
     }
62 49
 
63 50
     public function exportCSV(): StreamedResponse
64 51
     {
65
-        return $this->accountBalancesExportService->exportToCsv($this->company, $this->accountBalanceReport, $this->startDate, $this->endDate);
52
+        $transformer = new AccountBalanceReportTransformer($this->accountBalanceReport);
53
+
54
+        return $this->exportService->exportToCsv($this->company, $transformer, $this->startDate, $this->endDate);
66 55
     }
67 56
 
68 57
     public function exportPDF(): StreamedResponse
69 58
     {
70
-        $pdf = Pdf::loadView('components.company.reports.account-balances', [
71
-            'accountBalanceReport' => $this->accountBalanceReport,
72
-            'startDate' => Carbon::parse($this->startDate)->format('M d, Y'),
73
-            'endDate' => Carbon::parse($this->endDate)->format('M d, Y'),
74
-        ])->setPaper('a4');
59
+        $transformer = new AccountBalanceReportTransformer($this->accountBalanceReport);
75 60
 
76
-        return response()->streamDownload(function () use ($pdf) {
77
-            echo $pdf->stream();
78
-        }, 'account-balances.pdf');
61
+        return $this->exportService->exportToPdf($this->company, $transformer, $this->startDate, $this->endDate);
79 62
     }
80 63
 }

+ 62
- 29
app/Filament/Company/Pages/Reports/BaseReportPage.php 查看文件

@@ -4,12 +4,16 @@ namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\Filament\Forms\Components\DateRangeSelect;
6 6
 use App\Models\Company;
7
+use Filament\Actions\Action;
8
+use Filament\Actions\ActionGroup;
9
+use Filament\Forms\Components\Component;
7 10
 use Filament\Forms\Components\DatePicker;
8
-use Filament\Forms\Components\Split;
9
-use Filament\Forms\Form;
10 11
 use Filament\Forms\Set;
11 12
 use Filament\Pages\Page;
13
+use Filament\Support\Enums\IconPosition;
14
+use Filament\Support\Enums\IconSize;
12 15
 use Illuminate\Support\Carbon;
16
+use Symfony\Component\HttpFoundation\StreamedResponse;
13 17
 
14 18
 abstract class BaseReportPage extends Page
15 19
 {
@@ -36,42 +40,71 @@ abstract class BaseReportPage extends Page
36 40
         $this->loadReportData();
37 41
     }
38 42
 
39
-    abstract protected function loadReportData(): void;
43
+    abstract public function loadReportData(): void;
44
+
45
+    abstract public function exportCSV(): StreamedResponse;
46
+
47
+    abstract public function exportPDF(): StreamedResponse;
40 48
 
41 49
     public function getDefaultDateRange(): string
42 50
     {
43 51
         return 'FY-' . now()->year;
44 52
     }
45 53
 
46
-    public function form(Form $form): Form
47
-    {
48
-        return $form
49
-            ->schema([
50
-                Split::make([
51
-                    DateRangeSelect::make('dateRange')
52
-                        ->label('Date Range')
53
-                        ->selectablePlaceholder(false)
54
-                        ->startDateField('startDate')
55
-                        ->endDateField('endDate'),
56
-                    DatePicker::make('startDate')
57
-                        ->label('Start Date')
58
-                        ->displayFormat('Y-m-d')
59
-                        ->afterStateUpdated(static function (Set $set) {
60
-                            $set('dateRange', 'Custom');
61
-                        }),
62
-                    DatePicker::make('endDate')
63
-                        ->label('End Date')
64
-                        ->displayFormat('Y-m-d')
65
-                        ->afterStateUpdated(static function (Set $set) {
66
-                            $set('dateRange', 'Custom');
67
-                        }),
68
-                ])->live(),
69
-            ]);
70
-    }
71
-
72 54
     public function setDateRange(Carbon $start, Carbon $end): void
73 55
     {
74 56
         $this->startDate = $start->format('Y-m-d');
75 57
         $this->endDate = $end->isFuture() ? now()->format('Y-m-d') : $end->format('Y-m-d');
76 58
     }
59
+
60
+    protected function getHeaderActions(): array
61
+    {
62
+        return [
63
+            ActionGroup::make([
64
+                Action::make('exportCSV')
65
+                    ->label('CSV')
66
+                    ->action(fn () => $this->exportCSV()),
67
+                Action::make('exportPDF')
68
+                    ->label('PDF')
69
+                    ->action(fn () => $this->exportPDF()),
70
+            ])
71
+                ->label('Export')
72
+                ->button()
73
+                ->outlined()
74
+                ->dropdownWidth('max-w-[7rem]')
75
+                ->dropdownPlacement('bottom-end')
76
+                ->icon('heroicon-c-chevron-down')
77
+                ->iconSize(IconSize::Small)
78
+                ->iconPosition(IconPosition::After),
79
+        ];
80
+    }
81
+
82
+    protected function getDateRangeFormComponent(): Component
83
+    {
84
+        return DateRangeSelect::make('dateRange')
85
+            ->label('Date Range')
86
+            ->selectablePlaceholder(false)
87
+            ->startDateField('startDate')
88
+            ->endDateField('endDate');
89
+    }
90
+
91
+    protected function getStartDateFormComponent(): Component
92
+    {
93
+        return DatePicker::make('startDate')
94
+            ->label('Start Date')
95
+            ->displayFormat('Y-m-d')
96
+            ->afterStateUpdated(static function (Set $set) {
97
+                $set('dateRange', 'Custom');
98
+            });
99
+    }
100
+
101
+    protected function getEndDateFormComponent(): Component
102
+    {
103
+        return DatePicker::make('endDate')
104
+            ->label('End Date')
105
+            ->displayFormat('Y-m-d')
106
+            ->afterStateUpdated(static function (Set $set) {
107
+                $set('dateRange', 'Custom');
108
+            });
109
+    }
77 110
 }

+ 34
- 5
app/Filament/Company/Pages/Reports/TrialBalance.php 查看文件

@@ -3,7 +3,12 @@
3 3
 namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\DTO\ReportDTO;
6
+use App\Services\ExportService;
6 7
 use App\Services\ReportService;
8
+use App\Transformers\TrialBalanceReportTransformer;
9
+use Filament\Forms\Components\Split;
10
+use Filament\Forms\Form;
11
+use Symfony\Component\HttpFoundation\StreamedResponse;
7 12
 
8 13
 class TrialBalance extends BaseReportPage
9 14
 {
@@ -17,18 +22,42 @@ class TrialBalance extends BaseReportPage
17 22
 
18 23
     public ReportDTO $trialBalanceReport;
19 24
 
20
-    public function boot(ReportService $reportService): void
25
+    protected ExportService $exportService;
26
+
27
+    public function boot(ReportService $reportService, ExportService $exportService): void
21 28
     {
22 29
         $this->reportService = $reportService;
30
+        $this->exportService = $exportService;
23 31
     }
24 32
 
25
-    public function getDefaultDateRange(): string
33
+    public function loadReportData(): void
26 34
     {
27
-        return 'FY-' . now()->year;
35
+        $this->trialBalanceReport = $this->reportService->buildTrialBalanceReport($this->startDate, $this->endDate);
28 36
     }
29 37
 
30
-    public function loadReportData(): void
38
+    public function form(Form $form): Form
31 39
     {
32
-        $this->trialBalanceReport = $this->reportService->buildTrialBalanceReport($this->startDate, $this->endDate);
40
+        return $form
41
+            ->schema([
42
+                Split::make([
43
+                    $this->getDateRangeFormComponent(),
44
+                    $this->getStartDateFormComponent(),
45
+                    $this->getEndDateFormComponent(),
46
+                ])->live(),
47
+            ]);
48
+    }
49
+
50
+    public function exportCSV(): StreamedResponse
51
+    {
52
+        $transformer = new TrialBalanceReportTransformer($this->trialBalanceReport);
53
+
54
+        return $this->exportService->exportToCsv($this->company, $transformer, $this->startDate, $this->endDate);
55
+    }
56
+
57
+    public function exportPDF(): StreamedResponse
58
+    {
59
+        $transformer = new TrialBalanceReportTransformer($this->trialBalanceReport);
60
+
61
+        return $this->exportService->exportToPdf($this->company, $transformer, $this->startDate, $this->endDate);
33 62
     }
34 63
 }

+ 1
- 1
app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php 查看文件

@@ -11,7 +11,7 @@ class CreateAccount extends CreateRecord
11 11
 
12 12
     protected function getRedirectUrl(): string
13 13
     {
14
-        return $this->previousUrl;
14
+        return $this->getResource()::getUrl('index');
15 15
     }
16 16
 
17 17
     protected function mutateFormDataBeforeCreate(array $data): array

+ 2
- 2
app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php 查看文件

@@ -19,9 +19,9 @@ class EditAccount extends EditRecord
19 19
         ];
20 20
     }
21 21
 
22
-    protected function getRedirectUrl(): ?string
22
+    protected function getRedirectUrl(): string
23 23
     {
24
-        return $this->previousUrl;
24
+        return $this->getResource()::getUrl('index');
25 25
     }
26 26
 
27 27
     protected function mutateFormDataBeforeSave(array $data): array

+ 1
- 1
app/Filament/Company/Resources/Core/DepartmentResource/Pages/CreateDepartment.php 查看文件

@@ -11,6 +11,6 @@ class CreateDepartment extends CreateRecord
11 11
 
12 12
     protected function getRedirectUrl(): string
13 13
     {
14
-        return $this->previousUrl;
14
+        return $this->getResource()::getUrl('index');
15 15
     }
16 16
 }

+ 2
- 2
app/Filament/Company/Resources/Core/DepartmentResource/Pages/EditDepartment.php 查看文件

@@ -17,8 +17,8 @@ class EditDepartment extends EditRecord
17 17
         ];
18 18
     }
19 19
 
20
-    protected function getRedirectUrl(): ?string
20
+    protected function getRedirectUrl(): string
21 21
     {
22
-        return $this->previousUrl;
22
+        return $this->getResource()::getUrl('index');
23 23
     }
24 24
 }

+ 0
- 76
app/Services/AccountBalancesExportService.php 查看文件

@@ -1,76 +0,0 @@
1
-<?php
2
-
3
-namespace App\Services;
4
-
5
-use App\DTO\ReportDTO;
6
-use App\Models\Company;
7
-use Symfony\Component\HttpFoundation\StreamedResponse;
8
-
9
-class AccountBalancesExportService
10
-{
11
-    public function exportToCsv(Company $company, ReportDTO $accountBalanceReport, string $startDate, string $endDate): StreamedResponse
12
-    {
13
-        // Construct the filename
14
-        $filename = $company->name . ' Account Balances ' . $startDate . ' to ' . $endDate . '.csv';
15
-
16
-        $headers = [
17
-            'Content-Type' => 'text/csv',
18
-            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
19
-        ];
20
-
21
-        $callback = static function () use ($company, $startDate, $endDate, $accountBalanceReport) {
22
-            $file = fopen('php://output', 'wb');
23
-
24
-            fputcsv($file, ['Account Balances']);
25
-            fputcsv($file, [$company->name]);
26
-            fputcsv($file, ['Date Range: ' . $startDate . ' to ' . $endDate]);
27
-            fputcsv($file, []);
28
-
29
-            fputcsv($file, ['ACCOUNT CODE', 'ACCOUNT', 'STARTING BALANCE', 'DEBIT', 'CREDIT', 'NET MOVEMENT', 'ENDING BALANCE']);
30
-
31
-            foreach ($accountBalanceReport->categories as $accountCategoryName => $accountCategory) {
32
-                fputcsv($file, ['', $accountCategoryName]);
33
-
34
-                foreach ($accountCategory->accounts as $account) {
35
-                    fputcsv($file, [
36
-                        $account->accountCode,
37
-                        $account->accountName,
38
-                        $account->balance->startingBalance ?? '',
39
-                        $account->balance->debitBalance,
40
-                        $account->balance->creditBalance,
41
-                        $account->balance->netMovement,
42
-                        $account->balance->endingBalance ?? '',
43
-                    ]);
44
-                }
45
-
46
-                // Category Summary row
47
-                fputcsv($file, [
48
-                    '',
49
-                    'Total ' . $accountCategoryName,
50
-                    $accountCategory->summary->startingBalance ?? '',
51
-                    $accountCategory->summary->debitBalance,
52
-                    $accountCategory->summary->creditBalance,
53
-                    $accountCategory->summary->netMovement,
54
-                    $accountCategory->summary->endingBalance ?? '',
55
-                ]);
56
-
57
-                fputcsv($file, []);
58
-            }
59
-
60
-            // Final Row for overall totals
61
-            fputcsv($file, [
62
-                '',
63
-                'Total for all accounts',
64
-                '',
65
-                $accountBalanceReport->overallTotal->debitBalance,
66
-                $accountBalanceReport->overallTotal->creditBalance,
67
-                '',
68
-                '',
69
-            ]);
70
-
71
-            fclose($file);
72
-        };
73
-
74
-        return response()->streamDownload($callback, $filename, $headers);
75
-    }
76
-}

+ 57
- 0
app/Services/ExportService.php 查看文件

@@ -0,0 +1,57 @@
1
+<?php
2
+
3
+namespace App\Services;
4
+
5
+use App\Contracts\ExportableReport;
6
+use App\Models\Company;
7
+use Barryvdh\DomPDF\Facade\Pdf;
8
+use Illuminate\Support\Carbon;
9
+use Symfony\Component\HttpFoundation\StreamedResponse;
10
+
11
+class ExportService
12
+{
13
+    public function exportToCsv(Company $company, ExportableReport $report, string $startDate, string $endDate): StreamedResponse
14
+    {
15
+        $filename = $company->name . ' ' . $report->getTitle() . ' ' . $startDate . ' to ' . $endDate . '.csv';
16
+
17
+        $headers = [
18
+            'Content-Type' => 'text/csv',
19
+            'Content-Disposition' => 'attachment; filename="' . $filename . '"',
20
+        ];
21
+
22
+        $callback = function () use ($report, $company, $startDate, $endDate) {
23
+            $file = fopen('php://output', 'wb');
24
+
25
+            fputcsv($file, [$report->getTitle()]);
26
+            fputcsv($file, [$company->name]);
27
+            fputcsv($file, ['Date Range: ' . $startDate . ' to ' . $endDate]);
28
+            fputcsv($file, []);
29
+
30
+            fputcsv($file, $report->getHeaders());
31
+
32
+            foreach ($report->getData() as $row) {
33
+                fputcsv($file, $row);
34
+            }
35
+
36
+            fputcsv($file, $report->getOverallTotals());
37
+
38
+            fclose($file);
39
+        };
40
+
41
+        return response()->streamDownload($callback, $filename, $headers);
42
+    }
43
+
44
+    public function exportToPdf(Company $company, ExportableReport $report, string $startDate, string $endDate): StreamedResponse
45
+    {
46
+        $pdf = Pdf::loadView('components.company.reports.report-pdf', [
47
+            'company' => $company,
48
+            'report' => $report,
49
+            'startDate' => Carbon::parse($startDate)->format('M d, Y'),
50
+            'endDate' => Carbon::parse($endDate)->format('M d, Y'),
51
+        ])->setPaper('a4');
52
+
53
+        return response()->streamDownload(function () use ($pdf) {
54
+            echo $pdf->stream();
55
+        }, strtolower(str_replace(' ', '-', $company->name . '-' . $report->getTitle())) . '.pdf');
56
+    }
57
+}

+ 78
- 0
app/Transformers/AccountBalanceReportTransformer.php 查看文件

@@ -0,0 +1,78 @@
1
+<?php
2
+
3
+namespace App\Transformers;
4
+
5
+use App\Contracts\ExportableReport;
6
+use App\DTO\ReportDTO;
7
+
8
+class AccountBalanceReportTransformer implements ExportableReport
9
+{
10
+    protected ReportDTO $report;
11
+
12
+    public function __construct(ReportDTO $report)
13
+    {
14
+        $this->report = $report;
15
+    }
16
+
17
+    public function getTitle(): string
18
+    {
19
+        return 'Account Balances';
20
+    }
21
+
22
+    public function getHeaders(): array
23
+    {
24
+        return ['ACCOUNT CODE', 'ACCOUNT', 'STARTING BALANCE', 'DEBIT', 'CREDIT', 'NET MOVEMENT', 'ENDING BALANCE'];
25
+    }
26
+
27
+    public function getData(): array
28
+    {
29
+        $data = [];
30
+
31
+        foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
32
+            // Category Header row
33
+            $data[] = ['', $accountCategoryName];
34
+
35
+            // Account rows
36
+            foreach ($accountCategory->accounts as $account) {
37
+                $data[] = [
38
+                    $account->accountCode,
39
+                    $account->accountName,
40
+                    $account->balance->startingBalance ?? '',
41
+                    $account->balance->debitBalance,
42
+                    $account->balance->creditBalance,
43
+                    $account->balance->netMovement,
44
+                    $account->balance->endingBalance ?? '',
45
+                ];
46
+            }
47
+
48
+            // Category Summary row
49
+            $data[] = [
50
+                '',
51
+                'Total ' . $accountCategoryName,
52
+                $accountCategory->summary->startingBalance ?? '',
53
+                $accountCategory->summary->debitBalance,
54
+                $accountCategory->summary->creditBalance,
55
+                $accountCategory->summary->netMovement,
56
+                $accountCategory->summary->endingBalance ?? '',
57
+            ];
58
+
59
+            // Add an empty row after each category
60
+            $data[] = [''];
61
+        }
62
+
63
+        return $data;
64
+    }
65
+
66
+    public function getOverallTotals(): array
67
+    {
68
+        return [
69
+            '',
70
+            'Total for all accounts',
71
+            '',
72
+            $this->report->overallTotal->debitBalance,
73
+            $this->report->overallTotal->creditBalance,
74
+            '',
75
+            '',
76
+        ];
77
+    }
78
+}

+ 69
- 0
app/Transformers/TrialBalanceReportTransformer.php 查看文件

@@ -0,0 +1,69 @@
1
+<?php
2
+
3
+namespace App\Transformers;
4
+
5
+use App\Contracts\ExportableReport;
6
+use App\DTO\ReportDTO;
7
+
8
+class TrialBalanceReportTransformer implements ExportableReport
9
+{
10
+    protected ReportDTO $report;
11
+
12
+    public function __construct(ReportDTO $report)
13
+    {
14
+        $this->report = $report;
15
+    }
16
+
17
+    public function getTitle(): string
18
+    {
19
+        return 'Trial Balance';
20
+    }
21
+
22
+    public function getHeaders(): array
23
+    {
24
+        return ['ACCOUNT CODE', 'ACCOUNT', 'DEBIT', 'CREDIT'];
25
+    }
26
+
27
+    public function getData(): array
28
+    {
29
+        $data = [];
30
+
31
+        foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
32
+            // Category Header row
33
+            $data[] = ['', $accountCategoryName];
34
+
35
+            // Account rows
36
+            foreach ($accountCategory->accounts as $account) {
37
+                $data[] = [
38
+                    $account->accountCode,
39
+                    $account->accountName,
40
+                    $account->balance->debitBalance,
41
+                    $account->balance->creditBalance,
42
+                ];
43
+            }
44
+
45
+            // Category Summary row
46
+            $data[] = [
47
+                '',
48
+                'Total ' . $accountCategoryName,
49
+                $accountCategory->summary->debitBalance,
50
+                $accountCategory->summary->creditBalance,
51
+            ];
52
+
53
+            // Add an empty row after each category
54
+            $data[] = [''];
55
+        }
56
+
57
+        return $data;
58
+    }
59
+
60
+    public function getOverallTotals(): array
61
+    {
62
+        return [
63
+            '',
64
+            'Total for all accounts',
65
+            $this->report->overallTotal->debitBalance,
66
+            $this->report->overallTotal->creditBalance,
67
+        ];
68
+    }
69
+}

+ 5
- 5
composer.lock 查看文件

@@ -4833,16 +4833,16 @@
4833 4833
         },
4834 4834
         {
4835 4835
             "name": "nesbot/carbon",
4836
-            "version": "3.3.1",
4836
+            "version": "3.4.0",
4837 4837
             "source": {
4838 4838
                 "type": "git",
4839 4839
                 "url": "https://github.com/briannesbitt/Carbon.git",
4840
-                "reference": "8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a"
4840
+                "reference": "8eab8983c83c30e0bacbef8d311e3f3b8172727f"
4841 4841
             },
4842 4842
             "dist": {
4843 4843
                 "type": "zip",
4844
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a",
4845
-                "reference": "8ff64b92c1b1ec84fcde9f8bb9ff2ca34cb8a77a",
4844
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8eab8983c83c30e0bacbef8d311e3f3b8172727f",
4845
+                "reference": "8eab8983c83c30e0bacbef8d311e3f3b8172727f",
4846 4846
                 "shasum": ""
4847 4847
             },
4848 4848
             "require": {
@@ -4935,7 +4935,7 @@
4935 4935
                     "type": "tidelift"
4936 4936
                 }
4937 4937
             ],
4938
-            "time": "2024-05-01T06:54:22+00:00"
4938
+            "time": "2024-05-24T14:26:34+00:00"
4939 4939
         },
4940 4940
         {
4941 4941
             "name": "nette/schema",

resources/views/components/company/reports/account-balances.blade.php → resources/views/components/company/reports/report-pdf.blade.php 查看文件

@@ -3,7 +3,7 @@
3 3
 <head>
4 4
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 5
     <meta name="viewport" content="width=device-width, initial-scale=1">
6
-    <title>Account Balances</title>
6
+    <title>{{ $report->getTitle() }}</title>
7 7
     <style>
8 8
         @page {
9 9
             size: A4;
@@ -21,7 +21,8 @@
21 21
         }
22 22
 
23 23
         /* Align the first column header and data to the left */
24
-        .table-class th:first-child, .table-class td:first-child {
24
+        .table-class th:first-child, .table-class td:first-child,
25
+        .table-class th:nth-child(2), .table-class td:nth-child(2) {
25 26
             text-align: left;
26 27
         }
27 28
 
@@ -29,6 +30,11 @@
29 30
             margin-bottom: 1rem; /* Space between header and table */
30 31
         }
31 32
 
33
+        /* Ensure category name is left-aligned */
34
+        .category-name-cell {
35
+            text-align: left;
36
+        }
37
+
32 38
         .header .title,
33 39
         .header .company-name,
34 40
         .header .date-range {
@@ -61,7 +67,6 @@
61 67
 
62 68
         .spacer-row > td { height: 0.75rem; }
63 69
 
64
-        .summary-row > td,
65 70
         .table-footer-row > td {
66 71
             font-weight: 600;
67 72
             background-color: #ffffff; /* White background for footer */
@@ -70,58 +75,48 @@
70 75
 </head>
71 76
 <body>
72 77
     <div class="header">
73
-        <div class="title">Account Balances</div>
74
-        <div class="company-name">{{ auth()->user()->currentCompany->name }}</div>
78
+        <div class="title">{{ $report->getTitle() }}</div>
79
+        <div class="company-name">{{ $company->name }}</div>
75 80
         <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
76 81
     </div>
77 82
     <table class="table-class">
78 83
         <thead class="table-head" style="display: table-row-group;">
79 84
             <tr>
80
-                <th>Account</th>
81
-                <th>Starting Balance</th>
82
-                <th>Debit</th>
83
-                <th>Credit</th>
84
-                <th>Net Movement</th>
85
-                <th>Ending Balance</th>
85
+                @foreach($report->getHeaders() as $header)
86
+                    <th>{{ $header }}</th>
87
+                @endforeach
86 88
             </tr>
87 89
         </thead>
88
-        @foreach($accountBalanceReport->categories as $accountCategoryName => $accountCategory)
89
-            <tbody>
90
-            <tr class="category-row">
91
-                <td colspan="6">{{ $accountCategoryName }}</td>
92
-            </tr>
93
-            @foreach($accountCategory->accounts as $account)
94
-                <tr>
95
-                    <td>{{ $account->accountName }}</td>
96
-                    <td>{{ $account->balance->startingBalance ?? '' }}</td>
97
-                    <td>{{ $account->balance->debitBalance }}</td>
98
-                    <td>{{ $account->balance->creditBalance }}</td>
99
-                    <td>{{ $account->balance->netMovement }}</td>
100
-                    <td>{{ $account->balance->endingBalance ?? '' }}</td>
101
-                </tr>
90
+        <tbody>
91
+            @foreach($report->getData() as $row)
92
+                @if (count($row) === 2 && empty($row[0]))
93
+                    <tr class="category-row">
94
+                        <td></td>
95
+                        <td class="category-name-cell">{{ $row[1] }}</td>
96
+                        @for ($i = 2; $i < count($report->getHeaders()); $i++)
97
+                            <td></td>
98
+                        @endfor
99
+                    </tr>
100
+                @elseif (count($row) > 2)
101
+                    <tr>
102
+                        @foreach ($row as $cell)
103
+                            <td>{{ $cell }}</td>
104
+                        @endforeach
105
+                    </tr>
106
+                @elseif ($row[0] === '')
107
+                    <tr class="spacer-row">
108
+                        <td colspan="{{ count($report->getHeaders()) }}"></td>
109
+                    </tr>
110
+                @endif
102 111
             @endforeach
103
-            <tr class="summary-row">
104
-                <td>Total {{ $accountCategoryName }}</td>
105
-                <td>{{ $accountCategory->summary->startingBalance ?? '' }}</td>
106
-                <td>{{ $accountCategory->summary->debitBalance }}</td>
107
-                <td>{{ $accountCategory->summary->creditBalance }}</td>
108
-                <td>{{ $accountCategory->summary->netMovement }}</td>
109
-                <td>{{ $accountCategory->summary->endingBalance ?? '' }}</td>
110
-            </tr>
111
-            <tr class="spacer-row">
112
-                <td colspan="6"></td>
113
-            </tr>
114
-            </tbody>
115
-        @endforeach
112
+        </tbody>
116 113
         <tfoot>
117 114
             <tr class="table-footer-row">
118
-                <td>Total for all accounts</td>
119
-                <td></td>
120
-                <td>{{ $accountBalanceReport->overallTotal->debitBalance }}</td>
121
-                <td>{{ $accountBalanceReport->overallTotal->creditBalance }}</td>
122
-                <td></td>
123
-                <td></td>
115
+                @foreach ($report->getOverallTotals() as $total)
116
+                    <td>{{ $total }}</td>
117
+                @endforeach
124 118
             </tr>
125 119
         </tfoot>
126 120
     </table>
127 121
 </body>
122
+</html>

Loading…
取消
儲存