Procházet zdrojové kódy

export pdf summary table and refactor

3.x
Andrew Wallo před 11 měsíci
rodič
revize
4b7b8dfd27
24 změnil soubory, kde provedl 865 přidání a 743 odebrání
  1. 2
    0
      app/Contracts/HasSummaryReport.php
  2. 24
    0
      app/Filament/Company/Pages/Concerns/HasReportTabs.php
  3. 8
    8
      app/Filament/Company/Pages/Reports.php
  4. 0
    4
      app/Filament/Company/Pages/Reports/AccountBalances.php
  5. 0
    4
      app/Filament/Company/Pages/Reports/AccountTransactions.php
  6. 5
    8
      app/Filament/Company/Pages/Reports/BalanceSheet.php
  7. 26
    0
      app/Filament/Company/Pages/Reports/BaseReportPage.php
  8. 5
    10
      app/Filament/Company/Pages/Reports/CashFlowStatement.php
  9. 5
    10
      app/Filament/Company/Pages/Reports/IncomeStatement.php
  10. 0
    4
      app/Filament/Company/Pages/Reports/TrialBalance.php
  11. 141
    46
      app/Services/ExportService.php
  12. 6
    8
      app/Transformers/IncomeStatementReportTransformer.php
  13. 5
    0
      app/Transformers/SummaryReportTransformer.php
  14. 59
    149
      resources/views/components/company/reports/account-transactions-report-pdf.blade.php
  15. 168
    284
      resources/views/components/company/reports/cash-flow-statement-pdf.blade.php
  16. 61
    0
      resources/views/components/company/reports/income-statement-summary-pdf.blade.php
  17. 114
    0
      resources/views/components/company/reports/layout.blade.php
  18. 94
    202
      resources/views/components/company/reports/report-pdf.blade.php
  19. 136
    0
      resources/views/components/company/reports/summary-report-pdf.blade.php
  20. 1
    1
      resources/views/components/company/tables/reports/income-statement-summary.blade.php
  21. 2
    2
      resources/views/components/report-tabs.blade.php
  22. 1
    1
      resources/views/filament/company/pages/reports/balance-sheet.blade.php
  23. 1
    1
      resources/views/filament/company/pages/reports/cash-flow-statement.blade.php
  24. 1
    1
      resources/views/filament/company/pages/reports/income-statement.blade.php

+ 2
- 0
app/Contracts/HasSummaryReport.php Zobrazit soubor

@@ -20,4 +20,6 @@ interface HasSummaryReport
20 20
     public function getSummaryCategories(): array;
21 21
 
22 22
     public function getSummaryOverallTotals(): array;
23
+
24
+    public function getSummaryPdfView(): string;
23 25
 }

+ 24
- 0
app/Filament/Company/Pages/Concerns/HasReportTabs.php Zobrazit soubor

@@ -0,0 +1,24 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Pages\Concerns;
4
+
5
+use Livewire\Attributes\Url;
6
+
7
+trait HasReportTabs
8
+{
9
+    #[Url]
10
+    public ?string $activeTab = 'summary';
11
+
12
+    public function getTabs(): array
13
+    {
14
+        return [
15
+            'summary' => 'Summary',
16
+            'details' => 'Details',
17
+        ];
18
+    }
19
+
20
+    public function getActiveTab(): string
21
+    {
22
+        return $this->activeTab;
23
+    }
24
+}

+ 8
- 8
app/Filament/Company/Pages/Reports.php Zobrazit soubor

@@ -27,54 +27,54 @@ class Reports extends Page
27 27
             ->schema([
28 28
                 Section::make('Financial Statements')
29 29
                     ->aside()
30
-                    ->description('Key financial statements that provide a snapshot of your company’s financial health.')
30
+                    ->description('Key financial statements that provide an overview of your company’s financial health and performance.')
31 31
                     ->extraAttributes(['class' => 'es-report-card'])
32 32
                     ->schema([
33 33
                         ReportEntry::make('income_statement')
34 34
                             ->hiddenLabel()
35 35
                             ->heading('Income Statement')
36
-                            ->description('Tracks revenue and expenses to show profit or loss over a specific period of time.')
36
+                            ->description('Shows revenue, expenses, and net earnings over a period, indicating overall financial performance.')
37 37
                             ->icon('heroicon-o-chart-bar')
38 38
                             ->iconColor(Color::Indigo)
39 39
                             ->url(IncomeStatement::getUrl()),
40 40
                         ReportEntry::make('balance_sheet')
41 41
                             ->hiddenLabel()
42 42
                             ->heading('Balance Sheet')
43
-                            ->description('Snapshot of assets, liabilities, and equity at a specific point in time.')
43
+                            ->description('Displays your company’s assets, liabilities, and equity at a single point in time, showing overall financial health and stability.')
44 44
                             ->icon('heroicon-o-clipboard-document-list')
45 45
                             ->iconColor(Color::Emerald)
46 46
                             ->url(BalanceSheet::getUrl()),
47 47
                         ReportEntry::make('cash_flow_statement')
48 48
                             ->hiddenLabel()
49 49
                             ->heading('Cash Flow Statement')
50
-                            ->description('Shows cash inflows and outflows over a specific period of time.')
50
+                            ->description('Tracks cash inflows and outflows, giving insight into liquidity and cash management over a period.')
51 51
                             ->icon('heroicon-o-document-currency-dollar')
52 52
                             ->iconColor(Color::Cyan)
53 53
                             ->url(CashFlowStatement::getUrl()),
54 54
                     ]),
55 55
                 Section::make('Detailed Reports')
56 56
                     ->aside()
57
-                    ->description('Dig into the details of your company’s transactions, balances, and accounts.')
57
+                    ->description('Detailed reports that provide a comprehensive view of your company’s financial transactions and account balances.')
58 58
                     ->extraAttributes(['class' => 'es-report-card'])
59 59
                     ->schema([
60 60
                         ReportEntry::make('account_balances')
61 61
                             ->hiddenLabel()
62 62
                             ->heading('Account Balances')
63
-                            ->description('Summary view of balances and activity for all accounts.')
63
+                            ->description('Lists all accounts and their balances, including starting, debit, credit, net movement, and ending balances.')
64 64
                             ->icon('heroicon-o-currency-dollar')
65 65
                             ->iconColor(Color::Teal)
66 66
                             ->url(AccountBalances::getUrl()),
67 67
                         ReportEntry::make('trial_balance')
68 68
                             ->hiddenLabel()
69 69
                             ->heading('Trial Balance')
70
-                            ->description('The sum of all debit and credit balances for all accounts on a single day. This helps to ensure that the books are in balance.')
70
+                            ->description('Summarizes all account debits and credits on a specific date to verify the ledger is balanced.')
71 71
                             ->icon('heroicon-o-scale')
72 72
                             ->iconColor(Color::Sky)
73 73
                             ->url(TrialBalance::getUrl()),
74 74
                         ReportEntry::make('account_transactions')
75 75
                             ->hiddenLabel()
76 76
                             ->heading('Account Transactions')
77
-                            ->description('A record of all transactions for a company. The general ledger is the core of a company\'s financial records.')
77
+                            ->description('A record of all transactions, essential for monitoring and reconciling financial activity in the ledger.')
78 78
                             ->icon('heroicon-o-adjustments-horizontal')
79 79
                             ->iconColor(Color::Amber)
80 80
                             ->url(AccountTransactions::getUrl()),

+ 0
- 4
app/Filament/Company/Pages/Reports/AccountBalances.php Zobrazit soubor

@@ -17,10 +17,6 @@ class AccountBalances extends BaseReportPage
17 17
 {
18 18
     protected static string $view = 'filament.company.pages.reports.detailed-report';
19 19
 
20
-    protected static ?string $slug = 'reports/account-balances';
21
-
22
-    protected static bool $shouldRegisterNavigation = false;
23
-
24 20
     protected ReportService $reportService;
25 21
 
26 22
     protected ExportService $exportService;

+ 0
- 4
app/Filament/Company/Pages/Reports/AccountTransactions.php Zobrazit soubor

@@ -27,10 +27,6 @@ class AccountTransactions extends BaseReportPage
27 27
 {
28 28
     protected static string $view = 'filament.company.pages.reports.account-transactions';
29 29
 
30
-    protected static ?string $slug = 'reports/account-transactions';
31
-
32
-    protected static bool $shouldRegisterNavigation = false;
33
-
34 30
     protected ReportService $reportService;
35 31
 
36 32
     protected ExportService $exportService;

+ 5
- 8
app/Filament/Company/Pages/Reports/BalanceSheet.php Zobrazit soubor

@@ -4,6 +4,7 @@ namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\Contracts\ExportableReport;
6 6
 use App\DTO\ReportDTO;
7
+use App\Filament\Company\Pages\Concerns\HasReportTabs;
7 8
 use App\Filament\Forms\Components\DateRangeSelect;
8 9
 use App\Services\ExportService;
9 10
 use App\Services\ReportService;
@@ -11,22 +12,18 @@ use App\Support\Column;
11 12
 use App\Transformers\BalanceSheetReportTransformer;
12 13
 use Filament\Forms\Form;
13 14
 use Filament\Support\Enums\Alignment;
14
-use Livewire\Attributes\Url;
15 15
 use Symfony\Component\HttpFoundation\StreamedResponse;
16 16
 
17 17
 class BalanceSheet extends BaseReportPage
18 18
 {
19
-    protected static string $view = 'filament.company.pages.reports.balance-sheet';
19
+    use HasReportTabs;
20 20
 
21
-    protected static bool $shouldRegisterNavigation = false;
21
+    protected static string $view = 'filament.company.pages.reports.balance-sheet';
22 22
 
23 23
     protected ReportService $reportService;
24 24
 
25 25
     protected ExportService $exportService;
26 26
 
27
-    #[Url]
28
-    public ?string $activeTab = 'summary';
29
-
30 27
     public function boot(ReportService $reportService, ExportService $exportService): void
31 28
     {
32 29
         $this->reportService = $reportService;
@@ -77,11 +74,11 @@ class BalanceSheet extends BaseReportPage
77 74
 
78 75
     public function exportCSV(): StreamedResponse
79 76
     {
80
-        return $this->exportService->exportToCsv($this->company, $this->report, endDate: $this->getFilterState('asOfDate'));
77
+        return $this->exportService->exportToCsv($this->company, $this->report, endDate: $this->getFilterState('asOfDate'), activeTab: $this->getActiveTab());
81 78
     }
82 79
 
83 80
     public function exportPDF(): StreamedResponse
84 81
     {
85
-        return $this->exportService->exportToPdf($this->company, $this->report, endDate: $this->getFilterState('asOfDate'));
82
+        return $this->exportService->exportToPdf($this->company, $this->report, endDate: $this->getFilterState('asOfDate'), activeTab: $this->getActiveTab());
86 83
     }
87 84
 }

+ 26
- 0
app/Filament/Company/Pages/Reports/BaseReportPage.php Zobrazit soubor

@@ -6,6 +6,7 @@ use App\Contracts\ExportableReport;
6 6
 use App\DTO\ReportDTO;
7 7
 use App\Filament\Company\Pages\Concerns\HasDeferredFiltersForm;
8 8
 use App\Filament\Company\Pages\Concerns\HasTableColumnToggleForm;
9
+use App\Filament\Company\Pages\Reports;
9 10
 use App\Filament\Forms\Components\DateRangeSelect;
10 11
 use App\Models\Company;
11 12
 use App\Services\DateRangeService;
@@ -62,6 +63,31 @@ abstract class BaseReportPage extends Page
62 63
         $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
63 64
     }
64 65
 
66
+    public static function shouldRegisterNavigation(): bool
67
+    {
68
+        return false;
69
+    }
70
+
71
+    public static function getSlug(): string
72
+    {
73
+        $prefix = Reports::getSlug() . '/';
74
+
75
+        if (filled(static::$slug)) {
76
+            return $prefix . static::$slug;
77
+        }
78
+
79
+        return $prefix . str(class_basename(static::class))
80
+            ->kebab()
81
+            ->slug();
82
+    }
83
+
84
+    public function getBreadcrumbs(): array
85
+    {
86
+        return [
87
+            Reports::getUrl() => Reports::getNavigationLabel(),
88
+        ];
89
+    }
90
+
65 91
     protected function loadDefaultDateRange(): void
66 92
     {
67 93
         $flatFields = $this->getFiltersForm()->getFlatFields();

+ 5
- 10
app/Filament/Company/Pages/Reports/CashFlowStatement.php Zobrazit soubor

@@ -4,6 +4,7 @@ namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\Contracts\ExportableReport;
6 6
 use App\DTO\ReportDTO;
7
+use App\Filament\Company\Pages\Concerns\HasReportTabs;
7 8
 use App\Services\ExportService;
8 9
 use App\Services\ReportService;
9 10
 use App\Support\Column;
@@ -11,24 +12,18 @@ use App\Transformers\CashFlowStatementReportTransformer;
11 12
 use Filament\Forms\Form;
12 13
 use Filament\Support\Enums\Alignment;
13 14
 use Guava\FilamentClusters\Forms\Cluster;
14
-use Livewire\Attributes\Url;
15 15
 use Symfony\Component\HttpFoundation\StreamedResponse;
16 16
 
17 17
 class CashFlowStatement extends BaseReportPage
18 18
 {
19
-    protected static string $view = 'filament.company.pages.reports.cash-flow-statement';
20
-
21
-    protected static ?string $slug = 'reports/cash-flow-statement';
19
+    use HasReportTabs;
22 20
 
23
-    protected static bool $shouldRegisterNavigation = false;
21
+    protected static string $view = 'filament.company.pages.reports.cash-flow-statement';
24 22
 
25 23
     protected ReportService $reportService;
26 24
 
27 25
     protected ExportService $exportService;
28 26
 
29
-    #[Url]
30
-    public ?string $activeTab = 'summary';
31
-
32 27
     public function boot(ReportService $reportService, ExportService $exportService): void
33 28
     {
34 29
         $this->reportService = $reportService;
@@ -77,11 +72,11 @@ class CashFlowStatement extends BaseReportPage
77 72
 
78 73
     public function exportCSV(): StreamedResponse
79 74
     {
80
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
75
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'), $this->getActiveTab());
81 76
     }
82 77
 
83 78
     public function exportPDF(): StreamedResponse
84 79
     {
85
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
80
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'), $this->getActiveTab());
86 81
     }
87 82
 }

+ 5
- 10
app/Filament/Company/Pages/Reports/IncomeStatement.php Zobrazit soubor

@@ -4,6 +4,7 @@ namespace App\Filament\Company\Pages\Reports;
4 4
 
5 5
 use App\Contracts\ExportableReport;
6 6
 use App\DTO\ReportDTO;
7
+use App\Filament\Company\Pages\Concerns\HasReportTabs;
7 8
 use App\Services\ExportService;
8 9
 use App\Services\ReportService;
9 10
 use App\Support\Column;
@@ -11,24 +12,18 @@ use App\Transformers\IncomeStatementReportTransformer;
11 12
 use Filament\Forms\Form;
12 13
 use Filament\Support\Enums\Alignment;
13 14
 use Guava\FilamentClusters\Forms\Cluster;
14
-use Livewire\Attributes\Url;
15 15
 use Symfony\Component\HttpFoundation\StreamedResponse;
16 16
 
17 17
 class IncomeStatement extends BaseReportPage
18 18
 {
19
-    protected static string $view = 'filament.company.pages.reports.income-statement';
20
-
21
-    protected static ?string $slug = 'reports/income-statement';
19
+    use HasReportTabs;
22 20
 
23
-    protected static bool $shouldRegisterNavigation = false;
21
+    protected static string $view = 'filament.company.pages.reports.income-statement';
24 22
 
25 23
     protected ReportService $reportService;
26 24
 
27 25
     protected ExportService $exportService;
28 26
 
29
-    #[Url]
30
-    public ?string $activeTab = 'summary';
31
-
32 27
     public function boot(ReportService $reportService, ExportService $exportService): void
33 28
     {
34 29
         $this->reportService = $reportService;
@@ -77,11 +72,11 @@ class IncomeStatement extends BaseReportPage
77 72
 
78 73
     public function exportCSV(): StreamedResponse
79 74
     {
80
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
75
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'), $this->getActiveTab());
81 76
     }
82 77
 
83 78
     public function exportPDF(): StreamedResponse
84 79
     {
85
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
80
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'), $this->getActiveTab());
86 81
     }
87 82
 }

+ 0
- 4
app/Filament/Company/Pages/Reports/TrialBalance.php Zobrazit soubor

@@ -18,10 +18,6 @@ class TrialBalance extends BaseReportPage
18 18
 {
19 19
     protected static string $view = 'filament.company.pages.reports.trial-balance';
20 20
 
21
-    protected static ?string $slug = 'reports/trial-balance';
22
-
23
-    protected static bool $shouldRegisterNavigation = false;
24
-
25 21
     protected ReportService $reportService;
26 22
 
27 23
     protected ExportService $exportService;

+ 141
- 46
app/Services/ExportService.php Zobrazit soubor

@@ -3,6 +3,7 @@
3 3
 namespace App\Services;
4 4
 
5 5
 use App\Contracts\ExportableReport;
6
+use App\Contracts\HasSummaryReport;
6 7
 use App\Models\Company;
7 8
 use App\Transformers\CashFlowStatementReportTransformer;
8 9
 use Barryvdh\Snappy\Facades\SnappyPdf;
@@ -16,7 +17,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
16 17
 
17 18
 class ExportService
18 19
 {
19
-    public function exportToCsv(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null): StreamedResponse
20
+    public function exportToCsv(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null, ?string $activeTab = null): StreamedResponse
20 21
     {
21 22
         if ($startDate && $endDate) {
22 23
             $formattedStartDate = Carbon::parse($startDate)->toDateString();
@@ -36,7 +37,7 @@ class ExportService
36 37
             'Content-Disposition' => 'attachment; filename="' . $filename . '"',
37 38
         ];
38 39
 
39
-        $callback = function () use ($startDate, $endDate, $report, $company) {
40
+        $callback = function () use ($startDate, $endDate, $report, $company, $activeTab) {
40 41
             $csv = Writer::createFromStream(fopen('php://output', 'wb'));
41 42
             $csv->setOutputBOM(Bom::Utf8);
42 43
 
@@ -53,65 +54,118 @@ class ExportService
53 54
             $csv->insertOne([$dateLabel]);
54 55
             $csv->insertOne([]);
55 56
 
56
-            $csv->insertOne($report->getHeaders());
57
+            if ($activeTab === 'summary') {
58
+                $this->writeSummaryTableToCsv($csv, $report);
59
+            } else {
60
+                $this->writeDetailedTableToCsv($csv, $report);
61
+            }
62
+        };
57 63
 
58
-            foreach ($report->getCategories() as $category) {
59
-                $this->writeDataRowsToCsv($csv, $category->header, $category->data, $report->getColumns());
64
+        return response()->streamDownload($callback, $filename, $headers);
65
+    }
60 66
 
61
-                foreach ($category->types ?? [] as $type) {
62
-                    $this->writeDataRowsToCsv($csv, $type->header, $type->data, $report->getColumns());
67
+    /**
68
+     * @throws CannotInsertRecord
69
+     * @throws Exception
70
+     */
71
+    protected function writeSummaryTableToCsv(Writer $csv, ExportableReport $report): void
72
+    {
73
+        /** @var HasSummaryReport $report */
74
+        $csv->insertOne($report->getSummaryHeaders());
63 75
 
64
-                    if (filled($type->summary)) {
65
-                        $csv->insertOne($type->summary);
66
-                    }
67
-                }
76
+        foreach ($report->getSummaryCategories() as $category) {
77
+            if (filled($category->header)) {
78
+                $csv->insertOne($category->header);
79
+            }
68 80
 
69
-                if (filled($category->summary)) {
70
-                    $csv->insertOne($category->summary);
71
-                }
81
+            foreach ($category->types ?? [] as $type) {
82
+                $csv->insertOne($type->summary);
83
+            }
72 84
 
85
+            if (filled($category->summary)) {
86
+                $csv->insertOne($category->summary);
87
+            }
88
+
89
+            if ($category->summary['account_name'] === 'Cost of Goods Sold' && method_exists($report, 'getGrossProfit') && filled($report->getGrossProfit())) {
90
+                $csv->insertOne($report->getGrossProfit());
91
+            }
92
+
93
+            if (filled($category->header)) {
73 94
                 $csv->insertOne([]);
74 95
             }
96
+        }
97
+
98
+        if (method_exists($report, 'getSummaryOverviewHeaders') && filled($report->getSummaryOverviewHeaders())) {
99
+            $this->writeSummaryOverviewTableToCsv($csv, $report);
100
+        }
101
+
102
+        if (filled($report->getSummaryOverallTotals())) {
103
+            $csv->insertOne($report->getSummaryOverallTotals());
104
+        }
105
+    }
106
+
107
+    /**
108
+     * @throws CannotInsertRecord
109
+     * @throws Exception
110
+     */
111
+    protected function writeDetailedTableToCsv(Writer $csv, ExportableReport $report): void
112
+    {
113
+        $csv->insertOne($report->getHeaders());
75 114
 
76
-            if ($report->getTitle() === 'Cash Flow Statement') {
77
-                $this->writeOverviewTableToCsv($csv, $report);
115
+        foreach ($report->getCategories() as $category) {
116
+            $this->writeDataRowsToCsv($csv, $category->header, $category->data, $report->getColumns());
117
+
118
+            foreach ($category->types ?? [] as $type) {
119
+                $this->writeDataRowsToCsv($csv, $type->header, $type->data, $report->getColumns());
120
+
121
+                if (filled($type->summary)) {
122
+                    $csv->insertOne($type->summary);
123
+                }
78 124
             }
79 125
 
80
-            if (filled($report->getOverallTotals())) {
81
-                $csv->insertOne($report->getOverallTotals());
126
+            if (filled($category->summary)) {
127
+                $csv->insertOne($category->summary);
82 128
             }
83
-        };
84 129
 
85
-        return response()->streamDownload($callback, $filename, $headers);
130
+            $csv->insertOne([]);
131
+        }
132
+
133
+        if (method_exists($report, 'getOverviewHeaders') && filled($report->getOverviewHeaders())) {
134
+            $this->writeOverviewTableToCsv($csv, $report);
135
+        }
136
+
137
+        if (filled($report->getOverallTotals())) {
138
+            $csv->insertOne($report->getOverallTotals());
139
+        }
86 140
     }
87 141
 
88 142
     /**
89 143
      * @throws CannotInsertRecord
90 144
      * @throws Exception
91 145
      */
92
-    protected function writeOverviewTableToCsv(Writer $csv, ExportableReport $report): void
146
+    protected function writeSummaryOverviewTableToCsv(Writer $csv, ExportableReport $report): void
93 147
     {
94 148
         /** @var CashFlowStatementReportTransformer $report */
95
-        $headers = $report->getOverviewHeaders();
149
+        $headers = $report->getSummaryOverviewHeaders();
96 150
 
97 151
         if (filled($headers)) {
98 152
             $csv->insertOne($headers);
99 153
         }
100 154
 
101
-        foreach ($report->getOverview() as $overviewCategory) {
155
+        foreach ($report->getSummaryOverview() as $overviewCategory) {
102 156
             if (filled($overviewCategory->header)) {
103
-                $this->writeDataRowsToCsv($csv, $overviewCategory->header, $overviewCategory->data, $report->getColumns());
157
+                $this->writeDataRowsToCsv($csv, $overviewCategory->header, $overviewCategory->data, $report->getSummaryColumns());
104 158
             }
105 159
 
106 160
             if (filled($overviewCategory->summary)) {
107 161
                 $csv->insertOne($overviewCategory->summary);
108 162
             }
109 163
 
110
-            if ($overviewCategory->header['account_name'] === 'Starting Balance') {
111
-                foreach ($report->getOverviewAlignedWithColumns() as $summaryRow) {
164
+            if ($overviewCategory->summary['account_name'] === 'Starting Balance') {
165
+                foreach ($report->getSummaryOverviewAlignedWithColumns() as $summaryRow) {
112 166
                     $row = [];
113 167
 
114
-                    foreach ($report->getColumns() as $column) {
168
+                    foreach ($report->getSummaryColumns() as $column) {
115 169
                         $columnName = $column->getName();
116 170
                         $row[] = $summaryRow[$columnName] ?? '';
117 171
                     }
@@ -124,31 +178,43 @@ class ExportService
124 178
         }
125 179
     }
126 180
 
127
-    public function exportToPdf(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null): StreamedResponse
181
+    /**
182
+     * @throws CannotInsertRecord
183
+     * @throws Exception
184
+     */
185
+    protected function writeOverviewTableToCsv(Writer $csv, ExportableReport $report): void
128 186
     {
129
-        if ($startDate && $endDate) {
130
-            $formattedStartDate = Carbon::parse($startDate)->toDateString();
131
-            $formattedEndDate = Carbon::parse($endDate)->toDateString();
132
-            $dateLabel = $formattedStartDate . ' to ' . $formattedEndDate;
133
-        } else {
134
-            $formattedAsOfDate = Carbon::parse($endDate)->toDateString();
135
-            $dateLabel = $formattedAsOfDate;
187
+        /** @var CashFlowStatementReportTransformer $report */
188
+        $headers = $report->getOverviewHeaders();
189
+
190
+        if (filled($headers)) {
191
+            $csv->insertOne($headers);
136 192
         }
137 193
 
138
-        $timestamp = Carbon::now()->format('Y-m-d_H-i-s');
194
+        foreach ($report->getOverview() as $overviewCategory) {
195
+            if (filled($overviewCategory->header)) {
196
+                $this->writeDataRowsToCsv($csv, $overviewCategory->header, $overviewCategory->data, $report->getColumns());
197
+            }
139 198
 
140
-        $filename = $company->name . ' ' . $report->getTitle() . ' ' . $dateLabel . ' ' . $timestamp . '.pdf';
199
+            if (filled($overviewCategory->summary)) {
200
+                $csv->insertOne($overviewCategory->summary);
201
+            }
141 202
 
142
-        $pdf = SnappyPdf::loadView($report->getPdfView(), [
143
-            'company' => $company,
144
-            'report' => $report,
145
-            'startDate' => $startDate ? Carbon::parse($startDate)->toDefaultDateFormat() : null,
146
-            'endDate' => $endDate ? Carbon::parse($endDate)->toDefaultDateFormat() : null,
147
-        ]);
203
+            if ($overviewCategory->header['account_name'] === 'Starting Balance') {
204
+                foreach ($report->getOverviewAlignedWithColumns() as $summaryRow) {
205
+                    $row = [];
148 206
 
149
-        return response()->streamDownload(function () use ($pdf) {
150
-            echo $pdf->inline();
151
-        }, $filename);
207
+                    foreach ($report->getColumns() as $column) {
208
+                        $columnName = $column->getName();
209
+                        $row[] = $summaryRow[$columnName] ?? '';
210
+                    }
211
+
212
+                    if (array_filter($row)) {
213
+                        $csv->insertOne($row);
214
+                    }
215
+                }
216
+            }
217
+        }
152 218
     }
153 219
 
154 220
     /**
@@ -189,4 +255,33 @@ class ExportService
189 255
             $csv->insertOne($row);
190 256
         }
191 257
     }
258
+
259
+    public function exportToPdf(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null, ?string $activeTab = null): StreamedResponse
260
+    {
261
+        if ($startDate && $endDate) {
262
+            $formattedStartDate = Carbon::parse($startDate)->toDateString();
263
+            $formattedEndDate = Carbon::parse($endDate)->toDateString();
264
+            $dateLabel = $formattedStartDate . ' to ' . $formattedEndDate;
265
+        } else {
266
+            $formattedAsOfDate = Carbon::parse($endDate)->toDateString();
267
+            $dateLabel = $formattedAsOfDate;
268
+        }
269
+
270
+        $timestamp = Carbon::now()->format('Y-m-d_H-i-s');
271
+
272
+        $filename = $company->name . ' ' . $report->getTitle() . ' ' . $dateLabel . ' ' . $timestamp . '.pdf';
273
+
274
+        $view = $activeTab === 'summary' ? $report->getSummaryPdfView() : $report->getPdfView();
275
+
276
+        $pdf = SnappyPdf::loadView($view, [
277
+            'company' => $company,
278
+            'report' => $report,
279
+            'startDate' => $startDate ? Carbon::parse($startDate)->toDefaultDateFormat() : null,
280
+            'endDate' => $endDate ? Carbon::parse($endDate)->toDefaultDateFormat() : null,
281
+        ]);
282
+
283
+        return response()->streamDownload(function () use ($pdf) {
284
+            echo $pdf->inline();
285
+        }, $filename);
286
+    }
192 287
 }

+ 6
- 8
app/Transformers/IncomeStatementReportTransformer.php Zobrazit soubor

@@ -22,6 +22,11 @@ class IncomeStatementReportTransformer extends SummaryReportTransformer
22 22
         $this->calculateTotals();
23 23
     }
24 24
 
25
+    public function getSummaryPdfView(): string
26
+    {
27
+        return 'components.company.reports.income-statement-summary-pdf';
28
+    }
29
+
25 30
     public function getTitle(): string
26 31
     {
27 32
         return 'Income Statement';
@@ -96,13 +101,6 @@ class IncomeStatementReportTransformer extends SummaryReportTransformer
96 101
         $columns = $this->getSummaryColumns();
97 102
 
98 103
         foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
99
-            // Header for the main category
100
-            $categoryHeader = [];
101
-
102
-            foreach ($columns as $column) {
103
-                $categoryHeader[$column->getName()] = $column->getName() === 'account_name' ? $accountCategoryName : '';
104
-            }
105
-
106 104
             // Category-level summary
107 105
             $categorySummary = [];
108 106
             foreach ($columns as $column) {
@@ -115,7 +113,7 @@ class IncomeStatementReportTransformer extends SummaryReportTransformer
115 113
 
116 114
             // Add the category summary to the final array
117 115
             $summaryCategories[$accountCategoryName] = new ReportCategoryDTO(
118
-                header: $categoryHeader,
116
+                header: [],
119 117
                 data: [], // No direct accounts are needed here, only summaries
120 118
                 summary: $categorySummary,
121 119
                 types: [] // No types for the income statement

+ 5
- 0
app/Transformers/SummaryReportTransformer.php Zobrazit soubor

@@ -31,4 +31,9 @@ abstract class SummaryReportTransformer extends BaseReportTransformer implements
31 31
             return $headers;
32 32
         });
33 33
     }
34
+
35
+    public function getSummaryPdfView(): string
36
+    {
37
+        return 'components.company.reports.summary-report-pdf';
38
+    }
34 39
 }

+ 59
- 149
resources/views/components/company/reports/account-transactions-report-pdf.blade.php Zobrazit soubor

@@ -1,155 +1,65 @@
1
-<!DOCTYPE html>
2
-<html lang="en">
3
-<head>
4
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
-    <meta name="viewport" content="width=device-width, initial-scale=1">
6
-    <title>{{ $report->getTitle() }}</title>
7
-    <style>
8
-        .category-header-row > td {
9
-            background-color: #f3f4f6;
10
-            font-weight: bold;
11
-        }
12
-
13
-        .category-summary-row > td,
14
-        .table-footer-row > td {
15
-            background-color: #ffffff;
16
-            font-weight: bold;
17
-        }
18
-
19
-        .company-name {
20
-            font-size: 1.125rem;
21
-            font-weight: bold;
22
-        }
23
-
24
-        .date-range {
25
-            font-size: 0.875rem;
26
-        }
27
-
28
-        .header {
29
-            color: #374151;
30
-            margin-bottom: 1rem;
31
-        }
32
-
33
-        .header div + div {
34
-            margin-top: 0.5rem;
35
-        }
36
-
37
-        .spacer-row > td {
38
-            height: 0.75rem;
39
-        }
40
-
41
-        .table-body tr {
42
-            background-color: #ffffff;
43
-        }
44
-
45
-        .table-class {
46
-            border-collapse: collapse;
47
-            width: 100%;
48
-        }
49
-
50
-        .table-class td,
51
-        .table-class th {
52
-            border-bottom: 1px solid #d1d5db;
53
-            color: #374151;
54
-            font-size: 0.75rem;
55
-            line-height: 1rem;
56
-            padding: 0.75rem;
57
-        }
58
-
59
-        .table-head {
60
-            display: table-row-group;
61
-        }
62
-
63
-        .text-center {
64
-            text-align: center;
65
-        }
66
-
67
-        .text-left {
68
-            text-align: left;
69
-        }
70
-
71
-        .text-right {
72
-            text-align: right;
73
-        }
74
-
75
-        .title {
76
-            font-size: 1.5rem;
77
-        }
78
-
79
-        .whitespace-normal {
80
-            white-space: normal;
81
-        }
82
-
83
-        .whitespace-nowrap {
84
-            white-space: nowrap;
85
-        }
86
-
87
-        table tfoot {
88
-            display: table-row-group;
89
-        }
90
-    </style>
91
-</head>
92
-<body>
93
-<div class="header">
94
-    <div class="title">{{ $report->getTitle() }}</div>
95
-    <div class="company-name">{{ $company->name }}</div>
96
-    <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
97
-</div>
98
-<table class="table-class">
99
-    <thead class="table-head">
100
-    <tr>
101
-        @foreach($report->getHeaders() as $index => $header)
102
-            <th class="{{ $report->getAlignmentClass($index) }}">
103
-                {{ $header }}
104
-            </th>
105
-        @endforeach
106
-    </tr>
107
-    </thead>
108
-    @foreach($report->getCategories() as $category)
109
-        <tbody>
110
-        <tr class="category-header-row">
111
-            <td colspan="{{ count($report->getHeaders()) }}">
112
-                <div>
113
-                    @foreach($category->header as $headerRow)
114
-                        <div>
115
-                            @foreach($headerRow as $headerValue)
116
-                                @if (!empty($headerValue))
117
-                                    {{ $headerValue }}
118
-                                @endif
119
-                            @endforeach
120
-                        </div>
121
-                    @endforeach
122
-                </div>
123
-            </td>
1
+@extends('components.company.reports.layout')
2
+
3
+@section('content')
4
+    <div class="header">
5
+        <div class="title">{{ $report->getTitle() }}</div>
6
+        <div class="company-name">{{ $company->name }}</div>
7
+        <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
8
+    </div>
9
+    <table class="table-class">
10
+        <thead class="table-head">
11
+        <tr>
12
+            @foreach($report->getHeaders() as $index => $header)
13
+                <th class="{{ $report->getAlignmentClass($index) }}">
14
+                    {{ $header }}
15
+                </th>
16
+            @endforeach
124 17
         </tr>
125
-        @foreach($category->data as $dataIndex => $transaction)
126
-            <tr
127
-                @class([
128
-                    'category-header-row' => $loop->first || $loop->last || $loop->remaining === 1,
129
-                ])>
130
-                @foreach($transaction as $cellIndex => $cell)
131
-                    <td @class([
18
+        </thead>
19
+        @foreach($report->getCategories() as $category)
20
+            <tbody>
21
+            <tr class="category-header-row">
22
+                <td colspan="{{ count($report->getHeaders()) }}">
23
+                    <div>
24
+                        @foreach($category->header as $headerRow)
25
+                            <div>
26
+                                @foreach($headerRow as $headerValue)
27
+                                    @if (!empty($headerValue))
28
+                                        {{ $headerValue }}
29
+                                    @endif
30
+                                @endforeach
31
+                            </div>
32
+                        @endforeach
33
+                    </div>
34
+                </td>
35
+            </tr>
36
+            @foreach($category->data as $dataIndex => $transaction)
37
+                <tr
38
+                    @class([
39
+                        'category-header-row' => $loop->first || $loop->last || $loop->remaining === 1,
40
+                    ])>
41
+                    @foreach($transaction as $cellIndex => $cell)
42
+                        <td @class([
132 43
                             $report->getAlignmentClass($cellIndex),
133 44
                             'whitespace-normal' => $cellIndex === 'description',
134 45
                             'whitespace-nowrap' => $cellIndex !== 'description',
135 46
                         ])
136
-                    >
137
-                        @if(is_array($cell) && isset($cell['description']))
138
-                            {{ $cell['description'] }}
139
-                        @else
140
-                            {{ $cell }}
141
-                        @endif
142
-                    </td>
143
-                @endforeach
144
-            </tr>
47
+                        >
48
+                            @if(is_array($cell) && isset($cell['description']))
49
+                                {{ $cell['description'] }}
50
+                            @else
51
+                                {{ $cell }}
52
+                            @endif
53
+                        </td>
54
+                    @endforeach
55
+                </tr>
56
+            @endforeach
57
+            @unless($loop->last)
58
+                <tr class="spacer-row">
59
+                    <td colspan="{{ count($report->getHeaders()) }}"></td>
60
+                </tr>
61
+            @endunless
62
+            </tbody>
145 63
         @endforeach
146
-        @unless($loop->last)
147
-            <tr class="spacer-row">
148
-                <td colspan="{{ count($report->getHeaders()) }}"></td>
149
-            </tr>
150
-        @endunless
151
-        </tbody>
152
-    @endforeach
153
-</table>
154
-</body>
155
-</html>
64
+    </table>
65
+@endsection

+ 168
- 284
resources/views/components/company/reports/cash-flow-statement-pdf.blade.php Zobrazit soubor

@@ -1,334 +1,218 @@
1
-<!DOCTYPE html>
2
-<html lang="en">
3
-<head>
4
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
-    <meta name="viewport" content="width=device-width, initial-scale=1">
6
-    <title>{{ $report->getTitle() }}</title>
7
-    <style>
8
-        .font-bold {
9
-            font-weight: bold;
10
-        }
11
-
12
-        .category-header-row > td,
13
-        .type-header-row > td {
14
-            background-color: #f3f4f6;
15
-            font-weight: bold;
16
-        }
17
-
18
-        .category-summary-row > td,
19
-        .table-footer-row > td,
20
-        .type-summary-row > td {
21
-            background-color: #ffffff;
22
-            font-weight: bold;
23
-        }
24
-
25
-        .cell {
26
-            padding-bottom: 5px;
27
-            position: relative;
28
-        }
29
-
30
-        .company-name {
31
-            font-size: 1.125rem;
32
-            font-weight: bold;
33
-        }
34
-
35
-        .date-range {
36
-            font-size: 0.875rem;
37
-        }
38
-
39
-        .header {
40
-            color: #374151;
41
-            margin-bottom: 1rem;
42
-        }
43
-
44
-        .header div + div {
45
-            margin-top: 0.5rem;
46
-        }
47
-
48
-        .spacer-row > td {
49
-            height: 0.75rem;
50
-        }
51
-
52
-        .table-body tr {
53
-            background-color: #ffffff;
54
-        }
55
-
56
-        .table-class {
57
-            border-collapse: collapse;
58
-            table-layout: fixed;
59
-            width: 100%;
60
-        }
61
-
62
-        .table-class .type-row-indent {
63
-            padding-left: 1.5rem;
64
-        }
65
-
66
-        .table-class td,
67
-        .table-class th {
68
-            border-bottom: 1px solid #d1d5db;
69
-            color: #374151;
70
-            font-size: 0.75rem;
71
-            line-height: 1rem;
72
-            padding: 0.75rem;
73
-        }
74
-
75
-        .table-head {
76
-            display: table-row-group;
77
-        }
78
-
79
-        .text-center {
80
-            text-align: center;
81
-        }
82
-
83
-        .text-left {
84
-            text-align: left;
85
-        }
86
-
87
-        .text-right {
88
-            text-align: right;
89
-        }
90
-
91
-        .title {
92
-            font-size: 1.5rem;
93
-        }
94
-
95
-        .table-class .underline-bold {
96
-            border-bottom: 2px solid #374151;
97
-        }
98
-
99
-        .table-class .underline-thin {
100
-            border-bottom: 1px solid #374151;
101
-        }
102
-
103
-        .whitespace-normal {
104
-            white-space: normal;
105
-        }
106
-
107
-        .whitespace-nowrap {
108
-            white-space: nowrap;
109
-        }
110
-
111
-        table tfoot {
112
-            display: table-row-group;
113
-        }
114
-    </style>
115
-</head>
116
-<body>
117
-<div class="header">
118
-    <div class="title">{{ $report->getTitle() }}</div>
119
-    <div class="company-name">{{ $company->name }}</div>
120
-    @if($startDate && $endDate)
121
-        <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
122
-    @else
123
-        <div class="date-range">As of {{ $endDate }}</div>
124
-    @endif
125
-</div>
126
-<table class="table-class">
127
-    <colgroup>
128
-        @if(array_key_exists('account_code', $report->getHeaders()))
129
-            <col span="1" style="width: 20%;">
130
-            <col span="1" style="width: 55%;">
131
-            <col span="1" style="width: 25%;">
1
+@extends('components.company.reports.layout')
2
+
3
+@section('content')
4
+    <div class="header">
5
+        <div class="title">{{ $report->getTitle() }}</div>
6
+        <div class="company-name">{{ $company->name }}</div>
7
+        @if($startDate && $endDate)
8
+            <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
132 9
         @else
133
-            <col span="1" style="width: 65%;">
134
-            <col span="1" style="width: 35%;">
10
+            <div class="date-range">As of {{ $endDate }}</div>
135 11
         @endif
136
-    </colgroup>
137
-    <thead class="table-head">
138
-    <tr>
139
-        @foreach($report->getHeaders() as $index => $header)
140
-            <th class="{{ $report->getAlignmentClass($index) }}">
141
-                {{ $header }}
142
-            </th>
143
-        @endforeach
144
-    </tr>
145
-    </thead>
146
-    @foreach($report->getCategories() as $category)
147
-        <tbody>
148
-        <tr class="category-header-row">
149
-            @foreach($category->header as $index => $header)
150
-                <td class="{{ $report->getAlignmentClass($index) }}">
12
+    </div>
13
+    <table class="table-class">
14
+        <colgroup>
15
+            @if(array_key_exists('account_code', $report->getHeaders()))
16
+                <col span="1" style="width: 20%;">
17
+                <col span="1" style="width: 55%;">
18
+                <col span="1" style="width: 25%;">
19
+            @else
20
+                <col span="1" style="width: 65%;">
21
+                <col span="1" style="width: 35%;">
22
+            @endif
23
+        </colgroup>
24
+        <thead class="table-head">
25
+        <tr>
26
+            @foreach($report->getHeaders() as $index => $header)
27
+                <th class="{{ $report->getAlignmentClass($index) }}">
151 28
                     {{ $header }}
152
-                </td>
29
+                </th>
153 30
             @endforeach
154 31
         </tr>
155
-        @foreach($category->data as $account)
156
-            <tr>
157
-                @foreach($account as $index => $cell)
158
-                    <td @class([
32
+        </thead>
33
+        @foreach($report->getCategories() as $category)
34
+            <tbody>
35
+            <tr class="category-header-row">
36
+                @foreach($category->header as $index => $header)
37
+                    <td class="{{ $report->getAlignmentClass($index) }}">
38
+                        {{ $header }}
39
+                    </td>
40
+                @endforeach
41
+            </tr>
42
+            @foreach($category->data as $account)
43
+                <tr>
44
+                    @foreach($account as $index => $cell)
45
+                        <td @class([
159 46
                             $report->getAlignmentClass($index),
160 47
                             'whitespace-normal' => $index === 'account_name',
161 48
                             'whitespace-nowrap' => $index !== 'account_name',
162 49
                         ])
163
-                    >
164
-                        @if(is_array($cell) && isset($cell['name']))
165
-                            {{ $cell['name'] }}
166
-                        @else
167
-                            {{ $cell }}
168
-                        @endif
169
-                    </td>
170
-                @endforeach
171
-            </tr>
172
-        @endforeach
50
+                        >
51
+                            @if(is_array($cell) && isset($cell['name']))
52
+                                {{ $cell['name'] }}
53
+                            @else
54
+                                {{ $cell }}
55
+                            @endif
56
+                        </td>
57
+                    @endforeach
58
+                </tr>
59
+            @endforeach
173 60
 
174
-        <!-- Category Types -->
175
-        @foreach($category->types ?? [] as $type)
176
-            <!-- Type Header -->
177
-            <tr class="type-header-row">
178
-                @foreach($type->header as $index => $header)
179
-                    <td @class([
61
+            <!-- Category Types -->
62
+            @foreach($category->types ?? [] as $type)
63
+                <!-- Type Header -->
64
+                <tr class="type-header-row">
65
+                    @foreach($type->header as $index => $header)
66
+                        <td @class([
180 67
                             $report->getAlignmentClass($index),
181 68
                             'type-row-indent' => $index === 'account_name',
182 69
                         ])
183
-                    >
184
-                        {{ $header }}
185
-                    </td>
186
-                @endforeach
187
-            </tr>
70
+                        >
71
+                            {{ $header }}
72
+                        </td>
73
+                    @endforeach
74
+                </tr>
188 75
 
189
-            <!-- Type Data -->
190
-            @foreach($type->data as $typeRow)
191
-                <tr class="type-data-row">
192
-                    @foreach($typeRow as $index => $cell)
193
-                        <td @class([
76
+                <!-- Type Data -->
77
+                @foreach($type->data as $typeRow)
78
+                    <tr class="type-data-row">
79
+                        @foreach($typeRow as $index => $cell)
80
+                            <td @class([
194 81
                                 $report->getAlignmentClass($index),
195 82
                                 'whitespace-normal type-row-indent' => $index === 'account_name',
196 83
                                 'whitespace-nowrap' => $index !== 'account_name',
197 84
                             ])
85
+                            >
86
+                                @if(is_array($cell) && isset($cell['name']))
87
+                                    {{ $cell['name'] }}
88
+                                @else
89
+                                    {{ $cell }}
90
+                                @endif
91
+                            </td>
92
+                        @endforeach
93
+                    </tr>
94
+                @endforeach
95
+
96
+                <!-- Type Summary -->
97
+                <tr class="type-summary-row">
98
+                    @foreach($type->summary as $index => $cell)
99
+                        <td @class([
100
+                            $report->getAlignmentClass($index),
101
+                            'type-row-indent' => $index === 'account_name',
102
+                        ])
198 103
                         >
199
-                            @if(is_array($cell) && isset($cell['name']))
200
-                                {{ $cell['name'] }}
201
-                            @else
202
-                                {{ $cell }}
203
-                            @endif
104
+                            {{ $cell }}
204 105
                         </td>
205 106
                     @endforeach
206 107
                 </tr>
207 108
             @endforeach
208 109
 
209
-            <!-- Type Summary -->
210
-            <tr class="type-summary-row">
211
-                @foreach($type->summary as $index => $cell)
110
+            <tr class="category-summary-row">
111
+                @foreach($category->summary as $index => $cell)
212 112
                     <td @class([
213
-                            $report->getAlignmentClass($index),
214
-                            'type-row-indent' => $index === 'account_name',
215
-                        ])
113
+                        $report->getAlignmentClass($index),
114
+                        'underline-bold' => $loop->last,
115
+                    ])
216 116
                     >
217 117
                         {{ $cell }}
218 118
                     </td>
219 119
                 @endforeach
220 120
             </tr>
221
-        @endforeach
222 121
 
223
-        <tr class="category-summary-row">
224
-            @foreach($category->summary as $index => $cell)
225
-                <td @class([
226
-                        'cell',
227
-                        $report->getAlignmentClass($index),
228
-                        'underline-bold' => $loop->last,
229
-                    ])
230
-                >
231
-                    {{ $cell }}
122
+            @unless($loop->last && empty($report->getOverallTotals()))
123
+                <tr class="spacer-row">
124
+                    <td colspan="{{ count($report->getHeaders()) }}"></td>
125
+                </tr>
126
+            @endunless
127
+            </tbody>
128
+        @endforeach
129
+        <tfoot>
130
+        <tr class="table-footer-row">
131
+            @foreach ($report->getOverallTotals() as $index => $total)
132
+                <td class="{{ $report->getAlignmentClass($index) }}">
133
+                    {{ $total }}
232 134
                 </td>
233 135
             @endforeach
234 136
         </tr>
235
-
236
-        @unless($loop->last && empty($report->getOverallTotals()))
237
-            <tr class="spacer-row">
238
-                <td colspan="{{ count($report->getHeaders()) }}"></td>
239
-            </tr>
240
-        @endunless
241
-        </tbody>
242
-    @endforeach
243
-    <tfoot>
244
-    <tr class="table-footer-row">
245
-        @foreach ($report->getOverallTotals() as $index => $total)
246
-            <td class="{{ $report->getAlignmentClass($index) }}">
247
-                {{ $total }}
248
-            </td>
249
-        @endforeach
250
-    </tr>
251
-    </tfoot>
252
-</table>
253
-
254
-<!-- Second Overview Table -->
255
-<table class="table-class">
256
-    <colgroup>
257
-        @if(array_key_exists('account_code', $report->getHeaders()))
258
-            <col span="1" style="width: 20%;">
259
-            <col span="1" style="width: 55%;">
260
-            <col span="1" style="width: 25%;">
261
-        @else
262
-            <col span="1" style="width: 65%;">
263
-            <col span="1" style="width: 35%;">
264
-        @endif
265
-    </colgroup>
266
-    <thead class="table-head">
267
-    <tr>
268
-        @foreach($report->getOverviewHeaders() as $index => $header)
269
-            <th class="{{ $report->getAlignmentClass($index) }}">
270
-                {{ $header }}
271
-            </th>
272
-        @endforeach
273
-    </tr>
274
-    </thead>
275
-    <!-- Overview Content -->
276
-    @foreach($report->getOverview() as $overviewCategory)
277
-        <tbody>
278
-        <tr class="category-header-row">
279
-            @foreach($overviewCategory->header as $index => $header)
280
-                <td class="{{ $report->getAlignmentClass($index) }}">
137
+        </tfoot>
138
+    </table>
139
+
140
+    <!-- Second Overview Table -->
141
+    <table class="table-class" style="margin-top: 40px;">
142
+        <colgroup>
143
+            @if(array_key_exists('account_code', $report->getHeaders()))
144
+                <col span="1" style="width: 20%;">
145
+                <col span="1" style="width: 55%;">
146
+                <col span="1" style="width: 25%;">
147
+            @else
148
+                <col span="1" style="width: 65%;">
149
+                <col span="1" style="width: 35%;">
150
+            @endif
151
+        </colgroup>
152
+        <thead class="table-head">
153
+        <tr>
154
+            @foreach($report->getOverviewHeaders() as $index => $header)
155
+                <th class="{{ $report->getAlignmentClass($index) }}">
281 156
                     {{ $header }}
282
-                </td>
157
+                </th>
283 158
             @endforeach
284 159
         </tr>
285
-        @foreach($overviewCategory->data as $overviewAccount)
286
-            <tr>
287
-                @foreach($overviewAccount as $index => $cell)
288
-                    <td @class([
160
+        </thead>
161
+        <!-- Overview Content -->
162
+        @foreach($report->getOverview() as $overviewCategory)
163
+            <tbody>
164
+            <tr class="category-header-row">
165
+                @foreach($overviewCategory->header as $index => $header)
166
+                    <td class="{{ $report->getAlignmentClass($index) }}">
167
+                        {{ $header }}
168
+                    </td>
169
+                @endforeach
170
+            </tr>
171
+            @foreach($overviewCategory->data as $overviewAccount)
172
+                <tr>
173
+                    @foreach($overviewAccount as $index => $cell)
174
+                        <td @class([
289 175
                             $report->getAlignmentClass($index),
290 176
                             'whitespace-normal' => $index === 'account_name',
291 177
                             'whitespace-nowrap' => $index !== 'account_name',
292 178
                         ])
293
-                    >
294
-                        @if(is_array($cell) && isset($cell['name']))
295
-                            {{ $cell['name'] }}
296
-                        @else
297
-                            {{ $cell }}
298
-                        @endif
179
+                        >
180
+                            @if(is_array($cell) && isset($cell['name']))
181
+                                {{ $cell['name'] }}
182
+                            @else
183
+                                {{ $cell }}
184
+                            @endif
185
+                        </td>
186
+                    @endforeach
187
+                </tr>
188
+            @endforeach
189
+            <!-- Summary Row -->
190
+            <tr class="category-summary-row">
191
+                @foreach($overviewCategory->summary as $index => $summaryCell)
192
+                    <td class="{{ $report->getAlignmentClass($index) }}">
193
+                        {{ $summaryCell }}
299 194
                     </td>
300 195
                 @endforeach
301 196
             </tr>
302
-        @endforeach
303
-        <!-- Summary Row -->
304
-        <tr class="category-summary-row">
305
-            @foreach($overviewCategory->summary as $index => $summaryCell)
306
-                <td class="{{ $report->getAlignmentClass($index) }}">
307
-                    {{ $summaryCell }}
308
-                </td>
309
-            @endforeach
310
-        </tr>
311 197
 
312
-        @if($overviewCategory->header['account_name'] === 'Starting Balance')
313
-            @foreach($report->getOverviewAlignedWithColumns() as $summaryRow)
314
-                <tr>
315
-                    @foreach($summaryRow as $index => $summaryCell)
316
-                        <td @class([
317
-                                'cell',
198
+            @if($overviewCategory->header['account_name'] === 'Starting Balance')
199
+                @foreach($report->getOverviewAlignedWithColumns() as $summaryRow)
200
+                    <tr>
201
+                        @foreach($summaryRow as $index => $summaryCell)
202
+                            <td @class([
318 203
                                 $report->getAlignmentClass($index),
319 204
                                 'font-bold' => $loop->parent->last,
320 205
                                 'underline-thin' => $loop->parent->remaining === 1 && $index === 'net_movement',
321 206
                                 'underline-bold' => $loop->parent->last && $index === 'net_movement',
322 207
                             ])
323
-                        >
324
-                            {{ $summaryCell }}
325
-                        </td>
326
-                    @endforeach
327
-                </tr>
328
-            @endforeach
329
-        @endif
330
-        </tbody>
331
-    @endforeach
332
-</table>
333
-</body>
334
-</html>
208
+                            >
209
+                                {{ $summaryCell }}
210
+                            </td>
211
+                        @endforeach
212
+                    </tr>
213
+                @endforeach
214
+            @endif
215
+            </tbody>
216
+        @endforeach
217
+    </table>
218
+@endsection

+ 61
- 0
resources/views/components/company/reports/income-statement-summary-pdf.blade.php Zobrazit soubor

@@ -0,0 +1,61 @@
1
+@extends('components.company.reports.layout')
2
+
3
+@section('content')
4
+    <div class="header">
5
+        <div class="title">{{ $report->getTitle() }}</div>
6
+        <div class="company-name">{{ $company->name }}</div>
7
+        @if($startDate && $endDate)
8
+            <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
9
+        @else
10
+            <div class="date-range">As of {{ $endDate }}</div>
11
+        @endif
12
+    </div>
13
+    <table class="table-class">
14
+        <colgroup>
15
+            <col span="1" style="width: 65%;">
16
+            <col span="1" style="width: 35%;">
17
+        </colgroup>
18
+        <thead class="table-head">
19
+        <tr>
20
+            @foreach($report->getSummaryHeaders() as $index => $header)
21
+                <th class="{{ $report->getAlignmentClass($index) }}">
22
+                    {{ $header }}
23
+                </th>
24
+            @endforeach
25
+        </tr>
26
+        </thead>
27
+        @foreach($report->getSummaryCategories() as $category)
28
+            <tbody>
29
+            <tr>
30
+                @foreach($category->summary as $index => $cell)
31
+                    <td @class([
32
+                        $report->getAlignmentClass($index),
33
+                    ])
34
+                    >
35
+                        {{ $cell }}
36
+                    </td>
37
+                @endforeach
38
+            </tr>
39
+
40
+            @if($category->summary['account_name'] === 'Cost of Goods Sold')
41
+                <tr class="category-header-row">
42
+                    @foreach($report->getGrossProfit() as $grossProfitIndex => $grossProfitCell)
43
+                        <td class="{{ $report->getAlignmentClass($grossProfitIndex) }}">
44
+                            {{ $grossProfitCell }}
45
+                        </td>
46
+                    @endforeach
47
+                </tr>
48
+            @endif
49
+            </tbody>
50
+        @endforeach
51
+        <tfoot>
52
+        <tr class="category-header-row">
53
+            @foreach ($report->getOverallTotals() as $index => $total)
54
+                <td class="{{ $report->getAlignmentClass($index) }}">
55
+                    {{ $total }}
56
+                </td>
57
+            @endforeach
58
+        </tr>
59
+        </tfoot>
60
+    </table>
61
+@endsection

+ 114
- 0
resources/views/components/company/reports/layout.blade.php Zobrazit soubor

@@ -0,0 +1,114 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+<head>
4
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
+    <meta name="viewport" content="width=device-width, initial-scale=1">
6
+    <title>{{ $report->getTitle() }}</title>
7
+    <style>
8
+        .font-bold {
9
+            font-weight: bold;
10
+        }
11
+
12
+        .category-header-row > td,
13
+        .type-header-row > td {
14
+            background-color: #f3f4f6;
15
+            font-weight: bold;
16
+        }
17
+
18
+        .category-summary-row > td,
19
+        .table-footer-row > td,
20
+        .type-summary-row > td {
21
+            background-color: #ffffff;
22
+            font-weight: bold;
23
+        }
24
+
25
+        .company-name {
26
+            font-size: 1.125rem;
27
+            font-weight: bold;
28
+        }
29
+
30
+        .date-range {
31
+            font-size: 0.875rem;
32
+        }
33
+
34
+        .header {
35
+            color: #374151;
36
+            margin-bottom: 1rem;
37
+        }
38
+
39
+        .header div + div {
40
+            margin-top: 0.5rem;
41
+        }
42
+
43
+        .spacer-row > td {
44
+            height: 0.75rem;
45
+        }
46
+
47
+        .table-body tr {
48
+            background-color: #ffffff;
49
+        }
50
+
51
+        .table-class {
52
+            border-collapse: collapse;
53
+            table-layout: fixed;
54
+            width: 100%;
55
+        }
56
+
57
+        .table-class .type-row-indent {
58
+            padding-left: 1.5rem;
59
+        }
60
+
61
+        .table-class td,
62
+        .table-class th {
63
+            border-bottom: 1px solid #d1d5db;
64
+            color: #374151;
65
+            font-size: 0.75rem;
66
+            line-height: 1rem;
67
+            padding: 0.75rem;
68
+        }
69
+
70
+        .table-head {
71
+            display: table-row-group;
72
+        }
73
+
74
+        .text-center {
75
+            text-align: center;
76
+        }
77
+
78
+        .text-left {
79
+            text-align: left;
80
+        }
81
+
82
+        .text-right {
83
+            text-align: right;
84
+        }
85
+
86
+        .title {
87
+            font-size: 1.5rem;
88
+        }
89
+
90
+        .table-class .underline-bold {
91
+            border-bottom: 2px solid #374151;
92
+        }
93
+
94
+        .table-class .underline-thin {
95
+            border-bottom: 1px solid #374151;
96
+        }
97
+
98
+        .whitespace-normal {
99
+            white-space: normal;
100
+        }
101
+
102
+        .whitespace-nowrap {
103
+            white-space: nowrap;
104
+        }
105
+
106
+        table tfoot {
107
+            display: table-row-group;
108
+        }
109
+    </style>
110
+</head>
111
+<body>
112
+@yield('content')
113
+</body>
114
+</html>

+ 94
- 202
resources/views/components/company/reports/report-pdf.blade.php Zobrazit soubor

@@ -1,184 +1,42 @@
1
-<!DOCTYPE html>
2
-<html lang="en">
3
-<head>
4
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
-    <meta name="viewport" content="width=device-width, initial-scale=1">
6
-    <title>{{ $report->getTitle() }}</title>
7
-    <style>
8
-        .font-bold {
9
-            font-weight: bold;
10
-        }
11
-
12
-        .category-header-row > td,
13
-        .type-header-row > td {
14
-            background-color: #f3f4f6;
15
-            font-weight: bold;
16
-        }
17
-
18
-        .category-summary-row > td,
19
-        .table-footer-row > td,
20
-        .type-summary-row > td {
21
-            background-color: #ffffff;
22
-            font-weight: bold;
23
-        }
24
-
25
-        .company-name {
26
-            font-size: 1.125rem;
27
-            font-weight: bold;
28
-        }
29
-
30
-        .date-range {
31
-            font-size: 0.875rem;
32
-        }
33
-
34
-        .header {
35
-            color: #374151;
36
-            margin-bottom: 1rem;
37
-        }
38
-
39
-        .header div + div {
40
-            margin-top: 0.5rem;
41
-        }
42
-
43
-        .spacer-row > td {
44
-            height: 0.75rem;
45
-        }
46
-
47
-        .table-body tr {
48
-            background-color: #ffffff;
49
-        }
50
-
51
-        .table-class {
52
-            border-collapse: collapse;
53
-            width: 100%;
54
-        }
55
-
56
-        .table-class .type-row-indent {
57
-            padding-left: 1.5rem;
58
-        }
59
-
60
-        .table-class td,
61
-        .table-class th {
62
-            border-bottom: 1px solid #d1d5db;
63
-            color: #374151;
64
-            font-size: 0.75rem;
65
-            line-height: 1rem;
66
-            padding: 0.75rem;
67
-        }
68
-
69
-        .table-head {
70
-            display: table-row-group;
71
-        }
72
-
73
-        .text-center {
74
-            text-align: center;
75
-        }
76
-
77
-        .text-left {
78
-            text-align: left;
79
-        }
80
-
81
-        .text-right {
82
-            text-align: right;
83
-        }
84
-
85
-        .title {
86
-            font-size: 1.5rem;
87
-        }
88
-
89
-        .table-class .underline-bold {
90
-            border-bottom: 2px solid #374151;
91
-        }
92
-
93
-        .table-class .underline-thin {
94
-            border-bottom: 1px solid #374151;
95
-        }
96
-
97
-        .whitespace-normal {
98
-            white-space: normal;
99
-        }
100
-
101
-        .whitespace-nowrap {
102
-            white-space: nowrap;
103
-        }
104
-
105
-        table tfoot {
106
-            display: table-row-group;
107
-        }
108
-    </style>
109
-</head>
110
-<body>
111
-<div class="header">
112
-    <div class="title">{{ $report->getTitle() }}</div>
113
-    <div class="company-name">{{ $company->name }}</div>
114
-    @if($startDate && $endDate)
115
-        <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
116
-    @else
117
-        <div class="date-range">As of {{ $endDate }}</div>
118
-    @endif
119
-</div>
120
-<table class="table-class">
121
-    <thead class="table-head">
122
-    <tr>
123
-        @foreach($report->getHeaders() as $index => $header)
124
-            <th class="{{ $report->getAlignmentClass($index) }}">
125
-                {{ $header }}
126
-            </th>
127
-        @endforeach
128
-    </tr>
129
-    </thead>
130
-    @foreach($report->getCategories() as $category)
131
-        <tbody>
132
-        <tr class="category-header-row">
133
-            @foreach($category->header as $index => $header)
134
-                <td class="{{ $report->getAlignmentClass($index) }}">
1
+@extends('components.company.reports.layout')
2
+
3
+@section('content')
4
+    <div class="header">
5
+        <div class="title">{{ $report->getTitle() }}</div>
6
+        <div class="company-name">{{ $company->name }}</div>
7
+        @if($startDate && $endDate)
8
+            <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
9
+        @else
10
+            <div class="date-range">As of {{ $endDate }}</div>
11
+        @endif
12
+    </div>
13
+    <table class="table-class">
14
+        <thead class="table-head">
15
+        <tr>
16
+            @foreach($report->getHeaders() as $index => $header)
17
+                <th class="{{ $report->getAlignmentClass($index) }}">
135 18
                     {{ $header }}
136
-                </td>
19
+                </th>
137 20
             @endforeach
138 21
         </tr>
139
-        @foreach($category->data as $account)
140
-            <tr>
141
-                @foreach($account as $index => $cell)
142
-                    <td @class([
143
-                            $report->getAlignmentClass($index),
144
-                            'whitespace-normal' => $index === 'account_name',
145
-                            'whitespace-nowrap' => $index !== 'account_name',
146
-                        ])
147
-                    >
148
-                        @if(is_array($cell) && isset($cell['name']))
149
-                            {{ $cell['name'] }}
150
-                        @else
151
-                            {{ $cell }}
152
-                        @endif
153
-                    </td>
154
-                @endforeach
155
-            </tr>
156
-        @endforeach
157
-
158
-        <!-- Category Types -->
159
-        @foreach($category->types ?? [] as $type)
160
-            <!-- Type Header -->
161
-            <tr class="type-header-row">
162
-                @foreach($type->header as $index => $header)
163
-                    <td @class([
164
-                            $report->getAlignmentClass($index),
165
-                            'type-row-indent' => $index === 'account_name',
166
-                        ])
167
-                    >
22
+        </thead>
23
+        @foreach($report->getCategories() as $category)
24
+            <tbody>
25
+            <tr class="category-header-row">
26
+                @foreach($category->header as $index => $header)
27
+                    <td class="{{ $report->getAlignmentClass($index) }}">
168 28
                         {{ $header }}
169 29
                     </td>
170 30
                 @endforeach
171 31
             </tr>
172
-
173
-            <!-- Type Data -->
174
-            @foreach($type->data as $typeRow)
175
-                <tr class="type-data-row">
176
-                    @foreach($typeRow as $index => $cell)
32
+            @foreach($category->data as $account)
33
+                <tr>
34
+                    @foreach($account as $index => $cell)
177 35
                         <td @class([
178
-                                $report->getAlignmentClass($index),
179
-                                'whitespace-normal type-row-indent' => $index === 'account_name',
180
-                                'whitespace-nowrap' => $index !== 'account_name',
181
-                            ])
36
+                            $report->getAlignmentClass($index),
37
+                            'whitespace-normal' => $index === 'account_name',
38
+                            'whitespace-nowrap' => $index !== 'account_name',
39
+                        ])
182 40
                         >
183 41
                             @if(is_array($cell) && isset($cell['name']))
184 42
                                 {{ $cell['name'] }}
@@ -190,44 +48,78 @@
190 48
                 </tr>
191 49
             @endforeach
192 50
 
193
-            <!-- Type Summary -->
194
-            <tr class="type-summary-row">
195
-                @foreach($type->summary as $index => $cell)
196
-                    <td @class([
51
+            <!-- Category Types -->
52
+            @foreach($category->types ?? [] as $type)
53
+                <!-- Type Header -->
54
+                <tr class="type-header-row">
55
+                    @foreach($type->header as $index => $header)
56
+                        <td @class([
197 57
                             $report->getAlignmentClass($index),
198 58
                             'type-row-indent' => $index === 'account_name',
199 59
                         ])
200
-                    >
60
+                        >
61
+                            {{ $header }}
62
+                        </td>
63
+                    @endforeach
64
+                </tr>
65
+
66
+                <!-- Type Data -->
67
+                @foreach($type->data as $typeRow)
68
+                    <tr class="type-data-row">
69
+                        @foreach($typeRow as $index => $cell)
70
+                            <td @class([
71
+                                $report->getAlignmentClass($index),
72
+                                'whitespace-normal type-row-indent' => $index === 'account_name',
73
+                                'whitespace-nowrap' => $index !== 'account_name',
74
+                            ])
75
+                            >
76
+                                @if(is_array($cell) && isset($cell['name']))
77
+                                    {{ $cell['name'] }}
78
+                                @else
79
+                                    {{ $cell }}
80
+                                @endif
81
+                            </td>
82
+                        @endforeach
83
+                    </tr>
84
+                @endforeach
85
+
86
+                <!-- Type Summary -->
87
+                <tr class="type-summary-row">
88
+                    @foreach($type->summary as $index => $cell)
89
+                        <td @class([
90
+                            $report->getAlignmentClass($index),
91
+                            'type-row-indent' => $index === 'account_name',
92
+                        ])
93
+                        >
94
+                            {{ $cell }}
95
+                        </td>
96
+                    @endforeach
97
+                </tr>
98
+            @endforeach
99
+
100
+            <tr class="category-summary-row">
101
+                @foreach($category->summary as $index => $cell)
102
+                    <td class="{{ $report->getAlignmentClass($index) }}">
201 103
                         {{ $cell }}
202 104
                     </td>
203 105
                 @endforeach
204 106
             </tr>
205
-        @endforeach
206 107
 
207
-        <tr class="category-summary-row">
208
-            @foreach($category->summary as $index => $cell)
108
+            @unless($loop->last && empty($report->getOverallTotals()))
109
+                <tr class="spacer-row">
110
+                    <td colspan="{{ count($report->getHeaders()) }}"></td>
111
+                </tr>
112
+            @endunless
113
+            </tbody>
114
+        @endforeach
115
+        <tfoot>
116
+        <tr class="table-footer-row">
117
+            @foreach ($report->getOverallTotals() as $index => $total)
209 118
                 <td class="{{ $report->getAlignmentClass($index) }}">
210
-                    {{ $cell }}
119
+                    {{ $total }}
211 120
                 </td>
212 121
             @endforeach
213 122
         </tr>
214
-
215
-        @unless($loop->last && empty($report->getOverallTotals()))
216
-            <tr class="spacer-row">
217
-                <td colspan="{{ count($report->getHeaders()) }}"></td>
218
-            </tr>
219
-        @endunless
220
-        </tbody>
221
-    @endforeach
222
-    <tfoot>
223
-    <tr class="table-footer-row">
224
-        @foreach ($report->getOverallTotals() as $index => $total)
225
-            <td class="{{ $report->getAlignmentClass($index) }}">
226
-                {{ $total }}
227
-            </td>
228
-        @endforeach
229
-    </tr>
230
-    </tfoot>
231
-</table>
232
-</body>
233
-</html>
123
+        </tfoot>
124
+    </table>
125
+@endsection

+ 136
- 0
resources/views/components/company/reports/summary-report-pdf.blade.php Zobrazit soubor

@@ -0,0 +1,136 @@
1
+@extends('components.company.reports.layout')
2
+
3
+@section('content')
4
+    <div class="header">
5
+        <div class="title">{{ $report->getTitle() }}</div>
6
+        <div class="company-name">{{ $company->name }}</div>
7
+        @if($startDate && $endDate)
8
+            <div class="date-range">Date Range: {{ $startDate }} to {{ $endDate }}</div>
9
+        @else
10
+            <div class="date-range">As of {{ $endDate }}</div>
11
+        @endif
12
+    </div>
13
+    <table class="table-class">
14
+        <colgroup>
15
+            <col span="1" style="width: 65%;">
16
+            <col span="1" style="width: 35%;">
17
+        </colgroup>
18
+        <thead class="table-head">
19
+        <tr>
20
+            @foreach($report->getSummaryHeaders() as $index => $header)
21
+                <th class="{{ $report->getAlignmentClass($index) }}">
22
+                    {{ $header }}
23
+                </th>
24
+            @endforeach
25
+        </tr>
26
+        </thead>
27
+        @foreach($report->getSummaryCategories() as $category)
28
+            <tbody>
29
+            <tr class="category-header-row">
30
+                @foreach($category->header as $index => $header)
31
+                    <td class="{{ $report->getAlignmentClass($index) }}">
32
+                        {{ $header }}
33
+                    </td>
34
+                @endforeach
35
+            </tr>
36
+
37
+            <!-- Category Types -->
38
+            @foreach($category->types ?? [] as $type)
39
+                <!-- Type Summary -->
40
+                <tr>
41
+                    @foreach($type->summary as $index => $cell)
42
+                        <td @class([
43
+                            $report->getAlignmentClass($index),
44
+                        ])
45
+                        >
46
+                            {{ $cell }}
47
+                        </td>
48
+                    @endforeach
49
+                </tr>
50
+            @endforeach
51
+
52
+            <tr class="category-summary-row">
53
+                @foreach($category->summary as $index => $cell)
54
+                    <td @class([
55
+                        $report->getAlignmentClass($index),
56
+                        'underline-bold' => $loop->last && $report->getTitle() === 'Cash Flow Statement',
57
+                    ])
58
+                    >
59
+                        {{ $cell }}
60
+                    </td>
61
+                @endforeach
62
+            </tr>
63
+
64
+            @if($category->summary['account_name'] === 'Cost of Goods Sold')
65
+                <tr class="category-header-row">
66
+                    @foreach($report->getGrossProfit() as $grossProfitIndex => $grossProfitCell)
67
+                        <td class="{{ $report->getAlignmentClass($grossProfitIndex) }}">
68
+                            {{ $grossProfitCell }}
69
+                        </td>
70
+                    @endforeach
71
+                </tr>
72
+            @endif
73
+            </tbody>
74
+        @endforeach
75
+        <tfoot>
76
+        <tr class="table-footer-row">
77
+            @foreach ($report->getOverallTotals() as $index => $total)
78
+                <td class="{{ $report->getAlignmentClass($index) }}">
79
+                    {{ $total }}
80
+                </td>
81
+            @endforeach
82
+        </tr>
83
+        </tfoot>
84
+    </table>
85
+
86
+    <!-- Second Overview Table -->
87
+    @if(method_exists($report, 'getSummaryOverviewHeaders') && filled($report->getSummaryOverviewHeaders()))
88
+        <table class="table-class" style="margin-top: 40px;">
89
+            <colgroup>
90
+                <col span="1" style="width: 65%;">
91
+                <col span="1" style="width: 35%;">
92
+            </colgroup>
93
+            <thead class="table-head">
94
+            <tr>
95
+                @foreach($report->getOverviewHeaders() as $index => $header)
96
+                    <th class="{{ $report->getAlignmentClass($index) }}">
97
+                        {{ $header }}
98
+                    </th>
99
+                @endforeach
100
+            </tr>
101
+            </thead>
102
+            <!-- Overview Content -->
103
+            @foreach($report->getSummaryOverview() as $overviewCategory)
104
+                <tbody>
105
+                <!-- Summary Row -->
106
+                <tr class="category-header-row">
107
+                    @foreach($overviewCategory->summary as $index => $summaryCell)
108
+                        <td class="{{ $report->getAlignmentClass($index) }}">
109
+                            {{ $summaryCell }}
110
+                        </td>
111
+                    @endforeach
112
+                </tr>
113
+
114
+                @if($overviewCategory->summary['account_name'] === 'Starting Balance')
115
+                    @foreach($report->getSummaryOverviewAlignedWithColumns() as $summaryRow)
116
+                        <tr>
117
+                            @foreach($summaryRow as $index => $summaryCell)
118
+                                <td @class([
119
+                                'cell',
120
+                                $report->getAlignmentClass($index),
121
+                                'font-bold' => $loop->parent->last,
122
+                                'underline-thin' => $loop->parent->remaining === 1 && $index === 'net_movement',
123
+                                'underline-bold' => $loop->parent->last && $index === 'net_movement',
124
+                            ])
125
+                                >
126
+                                    {{ $summaryCell }}
127
+                                </td>
128
+                            @endforeach
129
+                        </tr>
130
+                    @endforeach
131
+                @endif
132
+                </tbody>
133
+            @endforeach
134
+        </table>
135
+    @endif
136
+@endsection

+ 1
- 1
resources/views/components/company/tables/reports/income-statement-summary.blade.php Zobrazit soubor

@@ -15,7 +15,7 @@
15 15
             @endforeach
16 16
         </tr>
17 17
 
18
-        @if($accountCategory->header['account_name'] === 'Cost of Goods Sold')
18
+        @if($accountCategory->summary['account_name'] === 'Cost of Goods Sold')
19 19
             <tr class="bg-gray-50 dark:bg-white/5">
20 20
                 @foreach($report->getGrossProfit() as $grossProfitIndex => $grossProfitCell)
21 21
                     <x-company.tables.cell :alignment-class="$report->getAlignmentClass($grossProfitIndex)" bold="true">

+ 2
- 2
resources/views/components/report-tabs.blade.php Zobrazit soubor

@@ -1,10 +1,10 @@
1 1
 @props([
2 2
     'activeTab' => 'summary',
3
-    'tabLabels' => ['summary' => 'Summary', 'details' => 'Details'],
3
+    'tabs' => ['summary' => 'Summary', 'details' => 'Details'],
4 4
 ])
5 5
 
6 6
 <x-filament::tabs>
7
-    @foreach ($tabLabels as $tabKey => $label)
7
+    @foreach ($tabs as $tabKey => $label)
8 8
         <x-filament::tabs.item
9 9
             :active="$activeTab === $tabKey"
10 10
             wire:click="$set('activeTab', '{{ $tabKey }}')"

+ 1
- 1
resources/views/filament/company/pages/reports/balance-sheet.blade.php Zobrazit soubor

@@ -28,7 +28,7 @@
28 28
         target-label="Net Assets"
29 29
     />
30 30
 
31
-    <x-report-tabs :activeTab="$activeTab"/>
31
+    <x-report-tabs :active-tab="$activeTab" :tabs="$this->getTabs()"/>
32 32
 
33 33
     <x-company.tables.container :report-loaded="$this->reportLoaded">
34 34
         @if($this->report)

+ 1
- 1
resources/views/filament/company/pages/reports/cash-flow-statement.blade.php Zobrazit soubor

@@ -26,7 +26,7 @@
26 26
         target-label="Net Cash Flow"
27 27
     />
28 28
 
29
-    <x-report-tabs :activeTab="$activeTab"/>
29
+    <x-report-tabs :active-tab="$activeTab" :tabs="$this->getTabs()"/>
30 30
 
31 31
     <x-company.tables.container :report-loaded="$this->reportLoaded">
32 32
         @if($this->report)

+ 1
- 1
resources/views/filament/company/pages/reports/income-statement.blade.php Zobrazit soubor

@@ -26,7 +26,7 @@
26 26
         target-label="Net Earnings"
27 27
     />
28 28
 
29
-    <x-report-tabs :activeTab="$activeTab"/>
29
+    <x-report-tabs :active-tab="$activeTab" :tabs="$this->getTabs()"/>
30 30
 
31 31
     <x-company.tables.container :report-loaded="$this->reportLoaded">
32 32
         @if($this->report)

Načítá se…
Zrušit
Uložit