Andrew Wallo 8 months ago
parent
commit
fe4a8b61f1

+ 25
- 0
app/DTO/ClientBalanceDTO.php View File

@@ -0,0 +1,25 @@
1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+use App\Contracts\MoneyFormattableDTO;
6
+
7
+class ClientBalanceDTO implements MoneyFormattableDTO
8
+{
9
+    public function __construct(
10
+        public ?string $totalBalance,
11
+        public ?string $paidBalance,
12
+        public ?string $unpaidBalance,
13
+        public ?string $overdueBalance = null,
14
+    ) {}
15
+
16
+    public static function fromArray(array $balances): static
17
+    {
18
+        return new static(
19
+            totalBalance: $balances['total_balance'] ?? null,
20
+            paidBalance: $balances['paid_balance'] ?? null,
21
+            unpaidBalance: $balances['unpaid_balance'] ?? null,
22
+            overdueBalance: $balances['overdue_balance'] ?? null,
23
+        );
24
+    }
25
+}

+ 2
- 1
app/DTO/ClientReportDTO.php View File

@@ -7,6 +7,7 @@ readonly class ClientReportDTO
7 7
     public function __construct(
8 8
         public string $clientName,
9 9
         public string $clientId,
10
-        public AgingBucketDTO $aging,
10
+        public ?AgingBucketDTO $aging = null,
11
+        public ?ClientBalanceDTO $balance = null,
11 12
     ) {}
12 13
 }

+ 1
- 0
app/DTO/ReportDTO.php View File

@@ -13,6 +13,7 @@ class ReportDTO
13 13
         public array $categories,
14 14
         public ?AccountBalanceDTO $overallTotal = null,
15 15
         public ?AgingBucketDTO $agingSummary = null,
16
+        public ?ClientBalanceDTO $clientBalanceTotal = null,
16 17
         public array $fields = [],
17 18
         public ?string $reportType = null,
18 19
         public ?CashFlowOverviewDTO $overview = null,

+ 9
- 8
app/Filament/Company/Pages/Reports.php View File

@@ -8,6 +8,7 @@ use App\Filament\Company\Pages\Reports\AccountsReceivableAging;
8 8
 use App\Filament\Company\Pages\Reports\AccountTransactions;
9 9
 use App\Filament\Company\Pages\Reports\BalanceSheet;
10 10
 use App\Filament\Company\Pages\Reports\CashFlowStatement;
11
+use App\Filament\Company\Pages\Reports\ClientBalanceSummary;
11 12
 use App\Filament\Company\Pages\Reports\IncomeStatement;
12 13
 use App\Filament\Company\Pages\Reports\TrialBalance;
13 14
 use App\Filament\Infolists\Components\ReportEntry;
@@ -74,25 +75,25 @@ class Reports extends Page
74 75
                             ->iconColor(Color::Cyan)
75 76
                             ->url(CashFlowStatement::getUrl()),
76 77
                     ]),
77
-                Section::make('Customer Reports')
78
+                Section::make('Client Reports')
78 79
                     ->aside()
79
-                    ->description('Reports that provide detailed information on your company’s customer transactions and balances.')
80
+                    ->description('Reports that provide detailed information on your company’s client transactions and balances.')
80 81
                     ->extraAttributes(['class' => 'es-report-card'])
81 82
                     ->schema([
82 83
                         ReportEntry::make('ar_aging')
83 84
                             ->hiddenLabel()
84 85
                             ->heading('Accounts Receivable Aging')
85
-                            ->description('Lists outstanding receivables by customer, showing how long invoices have been unpaid.')
86
+                            ->description('Lists outstanding receivables by client, showing how long invoices have been unpaid.')
86 87
                             ->icon('heroicon-o-calendar-date-range')
87 88
                             ->iconColor(Color::Indigo)
88 89
                             ->url(AccountsReceivableAging::getUrl()),
89
-                        ReportEntry::make('income_by_customer')
90
+                        ReportEntry::make('client_balance_summary')
90 91
                             ->hiddenLabel()
91
-                            ->heading('Income by Customer')
92
-                            ->description('Shows revenue generated by each customer, helping identify top customers and opportunities for growth.')
93
-                            ->icon('heroicon-o-arrow-trending-up')
92
+                            ->heading('Client Balance Summary')
93
+                            ->description('Shows total invoiced amounts, payments received, and outstanding balances for each client, helping identify top clients and opportunities for growth.')
94
+                            ->icon('heroicon-o-receipt-percent')
94 95
                             ->iconColor(Color::Emerald)
95
-                            ->url('#'),
96
+                            ->url(ClientBalanceSummary::getUrl()),
96 97
                     ]),
97 98
                 Section::make('Vendor Reports')
98 99
                     ->aside()

+ 98
- 0
app/Filament/Company/Pages/Reports/ClientBalanceSummary.php View File

@@ -0,0 +1,98 @@
1
+<?php
2
+
3
+namespace App\Filament\Company\Pages\Reports;
4
+
5
+use App\Contracts\ExportableReport;
6
+use App\DTO\ReportDTO;
7
+use App\Services\ExportService;
8
+use App\Services\ReportService;
9
+use App\Support\Column;
10
+use App\Transformers\ClientBalanceSummaryReportTransformer;
11
+use Filament\Forms\Form;
12
+use Filament\Support\Enums\Alignment;
13
+use Guava\FilamentClusters\Forms\Cluster;
14
+use Symfony\Component\HttpFoundation\StreamedResponse;
15
+
16
+class ClientBalanceSummary extends BaseReportPage
17
+{
18
+    protected static string $view = 'filament.company.pages.reports.detailed-report';
19
+
20
+    protected ReportService $reportService;
21
+
22
+    protected ExportService $exportService;
23
+
24
+    public function boot(ReportService $reportService, ExportService $exportService): void
25
+    {
26
+        $this->reportService = $reportService;
27
+        $this->exportService = $exportService;
28
+    }
29
+
30
+    public function getTable(): array
31
+    {
32
+        return [
33
+            Column::make('client_name')
34
+                ->label('Client')
35
+                ->alignment(Alignment::Left),
36
+            Column::make('total_balance')
37
+                ->label('Total')
38
+                ->toggleable()
39
+                ->alignment(Alignment::Right),
40
+            Column::make('paid_balance')
41
+                ->label('Paid')
42
+                ->toggleable()
43
+                ->alignment(Alignment::Right),
44
+            Column::make('unpaid_balance')
45
+                ->label('Unpaid')
46
+                ->toggleable()
47
+                ->alignment(Alignment::Right),
48
+        ];
49
+    }
50
+
51
+    public function filtersForm(Form $form): Form
52
+    {
53
+        return $form
54
+            ->inlineLabel()
55
+            ->columns()
56
+            ->schema([
57
+                $this->getDateRangeFormComponent(),
58
+                Cluster::make([
59
+                    $this->getStartDateFormComponent(),
60
+                    $this->getEndDateFormComponent(),
61
+                ])->hiddenLabel(),
62
+            ]);
63
+    }
64
+
65
+    protected function buildReport(array $columns): ReportDTO
66
+    {
67
+        return $this->reportService->buildClientBalanceSummaryReport(
68
+            $this->getFormattedStartDate(),
69
+            $this->getFormattedEndDate(),
70
+            $columns
71
+        );
72
+    }
73
+
74
+    protected function getTransformer(ReportDTO $reportDTO): ExportableReport
75
+    {
76
+        return new ClientBalanceSummaryReportTransformer($reportDTO);
77
+    }
78
+
79
+    public function exportCSV(): StreamedResponse
80
+    {
81
+        return $this->exportService->exportToCsv(
82
+            $this->company,
83
+            $this->report,
84
+            $this->getFilterState('startDate'),
85
+            $this->getFilterState('endDate')
86
+        );
87
+    }
88
+
89
+    public function exportPDF(): StreamedResponse
90
+    {
91
+        return $this->exportService->exportToPdf(
92
+            $this->company,
93
+            $this->report,
94
+            $this->getFilterState('startDate'),
95
+            $this->getFilterState('endDate')
96
+        );
97
+    }
98
+}

+ 5
- 0
app/Providers/MacroServiceProvider.php View File

@@ -22,6 +22,7 @@ use Filament\Tables\Columns\TextColumn;
22 22
 use Filament\Tables\Contracts\HasTable;
23 23
 use Illuminate\Contracts\Support\Htmlable;
24 24
 use Illuminate\Support\Carbon;
25
+use Illuminate\Support\Collection;
25 26
 use Illuminate\Support\HtmlString;
26 27
 use Illuminate\Support\ServiceProvider;
27 28
 
@@ -40,6 +41,10 @@ class MacroServiceProvider extends ServiceProvider
40 41
      */
41 42
     public function boot(): void
42 43
     {
44
+        Collection::macro('whereNot', function (callable | string $key, mixed $value = null): Collection {
45
+            return $this->where($key, '!=', $value);
46
+        });
47
+
43 48
         TextInput::macro('money', function (string | Closure | null $currency = null, bool $useAffix = true): static {
44 49
             $currency ??= CurrencyAccessor::getDefaultCurrency();
45 50
 

+ 2
- 0
app/Services/AccountService.php View File

@@ -381,6 +381,7 @@ class AccountService
381 381
                 'invoices.client_id',
382 382
                 'invoices.due_date',
383 383
                 'invoices.amount_due',
384
+                'invoices.currency_code',
384 385
                 DB::raw('DATEDIFF(?, invoices.due_date) as days_overdue'),
385 386
             ])
386 387
             ->addBinding([$asOfDate], 'select')
@@ -398,6 +399,7 @@ class AccountService
398 399
                 'bills.vendor_id',
399 400
                 'bills.due_date',
400 401
                 'bills.amount_due',
402
+                'bills.currency_code',
401 403
                 DB::raw('DATEDIFF(?, bills.due_date) as days_overdue'),
402 404
             ])
403 405
             ->addBinding([$asOfDate], 'select')

+ 92
- 24
app/Services/ReportService.php View File

@@ -2,6 +2,7 @@
2 2
 
3 3
 namespace App\Services;
4 4
 
5
+use App\Collections\Accounting\DocumentCollection;
5 6
 use App\Contracts\MoneyFormattableDTO;
6 7
 use App\DTO\AccountBalanceDTO;
7 8
 use App\DTO\AccountCategoryDTO;
@@ -10,13 +11,18 @@ use App\DTO\AccountTransactionDTO;
10 11
 use App\DTO\AccountTypeDTO;
11 12
 use App\DTO\AgingBucketDTO;
12 13
 use App\DTO\CashFlowOverviewDTO;
14
+use App\DTO\ClientBalanceDTO;
15
+use App\DTO\ClientReportDTO;
13 16
 use App\DTO\EntityReportDTO;
14 17
 use App\DTO\ReportDTO;
15 18
 use App\Enums\Accounting\AccountCategory;
16 19
 use App\Enums\Accounting\AccountType;
17 20
 use App\Enums\Accounting\DocumentEntityType;
21
+use App\Enums\Accounting\InvoiceStatus;
18 22
 use App\Enums\Accounting\TransactionType;
19 23
 use App\Models\Accounting\Account;
24
+use App\Models\Accounting\Bill;
25
+use App\Models\Accounting\Invoice;
20 26
 use App\Models\Accounting\Transaction;
21 27
 use App\Support\Column;
22 28
 use App\Utilities\Currency\CurrencyAccessor;
@@ -838,43 +844,44 @@ class ReportService
838 844
     ): ReportDTO {
839 845
         $asOfDateCarbon = Carbon::parse($asOfDate);
840 846
 
847
+        /** @var DocumentCollection<int,DocumentCollection<int,Invoice|Bill>> $documents */
841 848
         $documents = $entityType === DocumentEntityType::Client
842 849
             ? $this->accountService->getUnpaidClientInvoices($asOfDate)->with(['client:id,name'])->get()->groupBy('client_id')
843 850
             : $this->accountService->getUnpaidVendorBills($asOfDate)->with(['vendor:id,name'])->get()->groupBy('vendor_id');
844 851
 
845 852
         $categories = [];
846
-
847
-        $agingBuckets = ['current' => 0];
848
-
853
+        $totalAging = [
854
+            'current' => 0,
855
+        ];
849 856
         for ($i = 1; $i <= $numberOfPeriods; $i++) {
850
-            $agingBuckets["period_{$i}"] = 0;
857
+            $totalAging["period_{$i}"] = 0;
851 858
         }
852
-
853
-        $agingBuckets['over_periods'] = 0;
854
-        $agingBuckets['total'] = 0;
855
-
856
-        $totalAging = $agingBuckets;
859
+        $totalAging['over_periods'] = 0;
860
+        $totalAging['total'] = 0;
857 861
 
858 862
         foreach ($documents as $entityId => $entityDocuments) {
859
-            $aging = $agingBuckets;
860
-
861
-            foreach ($entityDocuments as $document) {
862
-                $daysOverdue = $document->days_overdue ?? 0;
863
-                $balance = $document->getRawOriginal('amount_due');
863
+            $aging = [
864
+                'current' => $entityDocuments
865
+                    ->filter(static fn ($doc) => ($doc->days_overdue ?? 0) <= 0)
866
+                    ->sumMoneyInDefaultCurrency('amount_due'),
867
+            ];
864 868
 
865
-                if ($daysOverdue <= 0) {
866
-                    $aging['current'] += $balance;
867
-                } else {
868
-                    $period = ceil($daysOverdue / $daysPerPeriod);
869
+            for ($i = 1; $i <= $numberOfPeriods; $i++) {
870
+                $min = ($i - 1) * $daysPerPeriod;
871
+                $max = $i * $daysPerPeriod;
872
+                $aging["period_{$i}"] = $entityDocuments
873
+                    ->filter(static function ($doc) use ($min, $max) {
874
+                        $days = $doc->days_overdue ?? 0;
869 875
 
870
-                    if ($period <= $numberOfPeriods) {
871
-                        $aging["period_{$period}"] += $balance;
872
-                    } else {
873
-                        $aging['over_periods'] += $balance;
874
-                    }
875
-                }
876
+                        return $days > $min && $days <= $max;
877
+                    })
878
+                    ->sumMoneyInDefaultCurrency('amount_due');
876 879
             }
877 880
 
881
+            $aging['over_periods'] = $entityDocuments
882
+                ->filter(static fn ($doc) => ($doc->days_overdue ?? 0) > ($numberOfPeriods * $daysPerPeriod))
883
+                ->sumMoneyInDefaultCurrency('amount_due');
884
+
878 885
             $aging['total'] = array_sum($aging);
879 886
 
880 887
             foreach ($aging as $bucket => $amount) {
@@ -899,4 +906,65 @@ class ReportService
899 906
             endDate: $asOfDateCarbon,
900 907
         );
901 908
     }
909
+
910
+    public function buildClientBalanceSummaryReport(string $startDate, string $endDate, array $columns = []): ReportDTO
911
+    {
912
+        /** @var DocumentCollection<int,DocumentCollection<int,Invoice>> $invoices */
913
+        $invoices = Invoice::query()
914
+            ->whereBetween('date', [$startDate, $endDate])
915
+            ->whereNotIn('status', [
916
+                InvoiceStatus::Draft,
917
+                InvoiceStatus::Void,
918
+            ])
919
+            ->whereNotNull('approved_at')
920
+            ->with(['client:id,name'])
921
+            ->get()
922
+            ->groupBy('client_id');
923
+
924
+        $clients = [];
925
+        $totalBalance = 0;
926
+        $totalPaidBalance = 0;
927
+        $totalUnpaidBalance = 0;
928
+
929
+        foreach ($invoices as $clientInvoices) {
930
+            $clientTotalBalance = $clientInvoices->sumMoneyInDefaultCurrency('total');
931
+
932
+            $clientPaidBalance = $clientInvoices->sumMoneyInDefaultCurrency('amount_paid');
933
+
934
+            $clientUnpaidBalance = $clientInvoices->whereNot('status', InvoiceStatus::Overpaid)
935
+                ->sumMoneyInDefaultCurrency('amount_due');
936
+
937
+            $totalBalance += $clientTotalBalance;
938
+            $totalPaidBalance += $clientPaidBalance;
939
+            $totalUnpaidBalance += $clientUnpaidBalance;
940
+
941
+            $formattedBalances = $this->formatBalances([
942
+                'total_balance' => $clientTotalBalance,
943
+                'paid_balance' => $clientPaidBalance,
944
+                'unpaid_balance' => $clientUnpaidBalance,
945
+            ], ClientBalanceDTO::class);
946
+
947
+            $client = $clientInvoices->first()->client;
948
+
949
+            $clients[] = new ClientReportDTO(
950
+                clientName: $client->name,
951
+                clientId: $client->id,
952
+                balance: $formattedBalances,
953
+            );
954
+        }
955
+
956
+        $clientBalanceTotal = $this->formatBalances([
957
+            'total_balance' => $totalBalance,
958
+            'paid_balance' => $totalPaidBalance,
959
+            'unpaid_balance' => $totalUnpaidBalance,
960
+        ], ClientBalanceDTO::class);
961
+
962
+        return new ReportDTO(
963
+            categories: ['Clients' => $clients],
964
+            clientBalanceTotal: $clientBalanceTotal,
965
+            fields: $columns,
966
+            startDate: Carbon::parse($startDate),
967
+            endDate: Carbon::parse($endDate),
968
+        );
969
+    }
902 970
 }

+ 68
- 0
app/Transformers/ClientBalanceSummaryReportTransformer.php View File

@@ -0,0 +1,68 @@
1
+<?php
2
+
3
+namespace App\Transformers;
4
+
5
+use App\DTO\ClientReportDTO;
6
+use App\DTO\ReportCategoryDTO;
7
+
8
+class ClientBalanceSummaryReportTransformer extends BaseReportTransformer
9
+{
10
+    public function getTitle(): string
11
+    {
12
+        return 'Client Balance Summary';
13
+    }
14
+
15
+    /**
16
+     * @return ReportCategoryDTO[]
17
+     */
18
+    public function getCategories(): array
19
+    {
20
+        $categories = [];
21
+
22
+        foreach ($this->report->categories as $categoryName => $category) {
23
+            $data = array_map(function (ClientReportDTO $client) {
24
+                $row = [];
25
+
26
+                foreach ($this->getColumns() as $column) {
27
+                    $row[$column->getName()] = match ($column->getName()) {
28
+                        'client_name' => [
29
+                            'name' => $client->clientName,
30
+                            'id' => $client->clientId,
31
+                        ],
32
+                        'total_balance' => $client->balance->totalBalance,
33
+                        'paid_balance' => $client->balance->paidBalance,
34
+                        'unpaid_balance' => $client->balance->unpaidBalance,
35
+                        default => '',
36
+                    };
37
+                }
38
+
39
+                return $row;
40
+            }, $category);
41
+
42
+            $categories[] = new ReportCategoryDTO(
43
+                header: null,
44
+                data: $data,
45
+                summary: null,
46
+            );
47
+        }
48
+
49
+        return $categories;
50
+    }
51
+
52
+    public function getOverallTotals(): array
53
+    {
54
+        $totals = [];
55
+
56
+        foreach ($this->getColumns() as $column) {
57
+            $totals[$column->getName()] = match ($column->getName()) {
58
+                'client_name' => 'Total for all clients',
59
+                'total_balance' => $this->report->clientBalanceTotal->totalBalance,
60
+                'paid_balance' => $this->report->clientBalanceTotal->paidBalance,
61
+                'unpaid_balance' => $this->report->clientBalanceTotal->unpaidBalance,
62
+                default => '',
63
+            };
64
+        }
65
+
66
+        return $totals;
67
+    }
68
+}

+ 58
- 58
composer.lock View File

@@ -497,16 +497,16 @@
497 497
         },
498 498
         {
499 499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.339.2",
500
+            "version": "3.339.4",
501 501
             "source": {
502 502
                 "type": "git",
503 503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "2f4e85dd8466ffe5186887f8f1466a0248c6c094"
504
+                "reference": "ea62ad03645ef7a1d3f1cda2de49f0869de3c582"
505 505
             },
506 506
             "dist": {
507 507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2f4e85dd8466ffe5186887f8f1466a0248c6c094",
509
-                "reference": "2f4e85dd8466ffe5186887f8f1466a0248c6c094",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ea62ad03645ef7a1d3f1cda2de49f0869de3c582",
509
+                "reference": "ea62ad03645ef7a1d3f1cda2de49f0869de3c582",
510 510
                 "shasum": ""
511 511
             },
512 512
             "require": {
@@ -589,9 +589,9 @@
589 589
             "support": {
590 590
                 "forum": "https://github.com/aws/aws-sdk-php/discussions",
591 591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.339.2"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.339.4"
593 593
             },
594
-            "time": "2025-01-29T19:53:29+00:00"
594
+            "time": "2025-01-31T19:04:39+00:00"
595 595
         },
596 596
         {
597 597
             "name": "aws/aws-sdk-php-laravel",
@@ -1733,16 +1733,16 @@
1733 1733
         },
1734 1734
         {
1735 1735
             "name": "filament/actions",
1736
-            "version": "v3.2.135",
1736
+            "version": "v3.2.136",
1737 1737
             "source": {
1738 1738
                 "type": "git",
1739 1739
                 "url": "https://github.com/filamentphp/actions.git",
1740
-                "reference": "dee2ca6d11e0ea3efb1190eabf6e483dbe2320ff"
1740
+                "reference": "cdefacc18993050cdd37e8e980ec66ca4109ae9a"
1741 1741
             },
1742 1742
             "dist": {
1743 1743
                 "type": "zip",
1744
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/dee2ca6d11e0ea3efb1190eabf6e483dbe2320ff",
1745
-                "reference": "dee2ca6d11e0ea3efb1190eabf6e483dbe2320ff",
1744
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/cdefacc18993050cdd37e8e980ec66ca4109ae9a",
1745
+                "reference": "cdefacc18993050cdd37e8e980ec66ca4109ae9a",
1746 1746
                 "shasum": ""
1747 1747
             },
1748 1748
             "require": {
@@ -1782,20 +1782,20 @@
1782 1782
                 "issues": "https://github.com/filamentphp/filament/issues",
1783 1783
                 "source": "https://github.com/filamentphp/filament"
1784 1784
             },
1785
-            "time": "2025-01-24T09:27:43+00:00"
1785
+            "time": "2025-01-31T11:08:24+00:00"
1786 1786
         },
1787 1787
         {
1788 1788
             "name": "filament/filament",
1789
-            "version": "v3.2.135",
1789
+            "version": "v3.2.136",
1790 1790
             "source": {
1791 1791
                 "type": "git",
1792 1792
                 "url": "https://github.com/filamentphp/panels.git",
1793
-                "reference": "bee6e1fd7b51f7dbffd03bc277b220bcfb8c45bb"
1793
+                "reference": "c92daf4b6e4b478be5d32d5e1b404ba92bb45414"
1794 1794
             },
1795 1795
             "dist": {
1796 1796
                 "type": "zip",
1797
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/bee6e1fd7b51f7dbffd03bc277b220bcfb8c45bb",
1798
-                "reference": "bee6e1fd7b51f7dbffd03bc277b220bcfb8c45bb",
1797
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/c92daf4b6e4b478be5d32d5e1b404ba92bb45414",
1798
+                "reference": "c92daf4b6e4b478be5d32d5e1b404ba92bb45414",
1799 1799
                 "shasum": ""
1800 1800
             },
1801 1801
             "require": {
@@ -1847,20 +1847,20 @@
1847 1847
                 "issues": "https://github.com/filamentphp/filament/issues",
1848 1848
                 "source": "https://github.com/filamentphp/filament"
1849 1849
             },
1850
-            "time": "2025-01-24T09:27:52+00:00"
1850
+            "time": "2025-01-31T11:08:29+00:00"
1851 1851
         },
1852 1852
         {
1853 1853
             "name": "filament/forms",
1854
-            "version": "v3.2.135",
1854
+            "version": "v3.2.136",
1855 1855
             "source": {
1856 1856
                 "type": "git",
1857 1857
                 "url": "https://github.com/filamentphp/forms.git",
1858
-                "reference": "e17618c921cd0300341a53d0eb2174c51e649565"
1858
+                "reference": "8856b3b3714a0efae65d9f817fcc1934b6f34fda"
1859 1859
             },
1860 1860
             "dist": {
1861 1861
                 "type": "zip",
1862
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/e17618c921cd0300341a53d0eb2174c51e649565",
1863
-                "reference": "e17618c921cd0300341a53d0eb2174c51e649565",
1862
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/8856b3b3714a0efae65d9f817fcc1934b6f34fda",
1863
+                "reference": "8856b3b3714a0efae65d9f817fcc1934b6f34fda",
1864 1864
                 "shasum": ""
1865 1865
             },
1866 1866
             "require": {
@@ -1903,20 +1903,20 @@
1903 1903
                 "issues": "https://github.com/filamentphp/filament/issues",
1904 1904
                 "source": "https://github.com/filamentphp/filament"
1905 1905
             },
1906
-            "time": "2025-01-24T09:27:50+00:00"
1906
+            "time": "2025-01-31T11:08:23+00:00"
1907 1907
         },
1908 1908
         {
1909 1909
             "name": "filament/infolists",
1910
-            "version": "v3.2.135",
1910
+            "version": "v3.2.136",
1911 1911
             "source": {
1912 1912
                 "type": "git",
1913 1913
                 "url": "https://github.com/filamentphp/infolists.git",
1914
-                "reference": "3330966b87da7d2078b62556428c279a6e8ff17c"
1914
+                "reference": "35c6dcbae24ae5fb086aeb1d13e2996442001674"
1915 1915
             },
1916 1916
             "dist": {
1917 1917
                 "type": "zip",
1918
-                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/3330966b87da7d2078b62556428c279a6e8ff17c",
1919
-                "reference": "3330966b87da7d2078b62556428c279a6e8ff17c",
1918
+                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/35c6dcbae24ae5fb086aeb1d13e2996442001674",
1919
+                "reference": "35c6dcbae24ae5fb086aeb1d13e2996442001674",
1920 1920
                 "shasum": ""
1921 1921
             },
1922 1922
             "require": {
@@ -1954,20 +1954,20 @@
1954 1954
                 "issues": "https://github.com/filamentphp/filament/issues",
1955 1955
                 "source": "https://github.com/filamentphp/filament"
1956 1956
             },
1957
-            "time": "2025-01-24T09:27:49+00:00"
1957
+            "time": "2025-01-31T11:08:24+00:00"
1958 1958
         },
1959 1959
         {
1960 1960
             "name": "filament/notifications",
1961
-            "version": "v3.2.135",
1961
+            "version": "v3.2.136",
1962 1962
             "source": {
1963 1963
                 "type": "git",
1964 1964
                 "url": "https://github.com/filamentphp/notifications.git",
1965
-                "reference": "e864c50bc0b6e9eb46b5e3d93a672a66f80a0fbe"
1965
+                "reference": "214845e9f613716304707441c8227d2d70b2aabf"
1966 1966
             },
1967 1967
             "dist": {
1968 1968
                 "type": "zip",
1969
-                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/e864c50bc0b6e9eb46b5e3d93a672a66f80a0fbe",
1970
-                "reference": "e864c50bc0b6e9eb46b5e3d93a672a66f80a0fbe",
1969
+                "url": "https://api.github.com/repos/filamentphp/notifications/zipball/214845e9f613716304707441c8227d2d70b2aabf",
1970
+                "reference": "214845e9f613716304707441c8227d2d70b2aabf",
1971 1971
                 "shasum": ""
1972 1972
             },
1973 1973
             "require": {
@@ -2006,11 +2006,11 @@
2006 2006
                 "issues": "https://github.com/filamentphp/filament/issues",
2007 2007
                 "source": "https://github.com/filamentphp/filament"
2008 2008
             },
2009
-            "time": "2025-01-24T09:27:49+00:00"
2009
+            "time": "2025-01-31T11:08:23+00:00"
2010 2010
         },
2011 2011
         {
2012 2012
             "name": "filament/support",
2013
-            "version": "v3.2.135",
2013
+            "version": "v3.2.136",
2014 2014
             "source": {
2015 2015
                 "type": "git",
2016 2016
                 "url": "https://github.com/filamentphp/support.git",
@@ -2069,16 +2069,16 @@
2069 2069
         },
2070 2070
         {
2071 2071
             "name": "filament/tables",
2072
-            "version": "v3.2.135",
2072
+            "version": "v3.2.136",
2073 2073
             "source": {
2074 2074
                 "type": "git",
2075 2075
                 "url": "https://github.com/filamentphp/tables.git",
2076
-                "reference": "db63ab6fd7c2046dc9b1fc6fbd92df0a1aabb54e"
2076
+                "reference": "1b1d9c3b837c11408ad28240dc9e3e33340d870b"
2077 2077
             },
2078 2078
             "dist": {
2079 2079
                 "type": "zip",
2080
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/db63ab6fd7c2046dc9b1fc6fbd92df0a1aabb54e",
2081
-                "reference": "db63ab6fd7c2046dc9b1fc6fbd92df0a1aabb54e",
2080
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/1b1d9c3b837c11408ad28240dc9e3e33340d870b",
2081
+                "reference": "1b1d9c3b837c11408ad28240dc9e3e33340d870b",
2082 2082
                 "shasum": ""
2083 2083
             },
2084 2084
             "require": {
@@ -2117,20 +2117,20 @@
2117 2117
                 "issues": "https://github.com/filamentphp/filament/issues",
2118 2118
                 "source": "https://github.com/filamentphp/filament"
2119 2119
             },
2120
-            "time": "2025-01-24T09:28:02+00:00"
2120
+            "time": "2025-01-31T11:08:58+00:00"
2121 2121
         },
2122 2122
         {
2123 2123
             "name": "filament/widgets",
2124
-            "version": "v3.2.135",
2124
+            "version": "v3.2.136",
2125 2125
             "source": {
2126 2126
                 "type": "git",
2127 2127
                 "url": "https://github.com/filamentphp/widgets.git",
2128
-                "reference": "9f6674daceced7d5045494d0bf7e1d2908ea439d"
2128
+                "reference": "3b95cfc23cf7a2b112ca65b067a33c1af7f79dc7"
2129 2129
             },
2130 2130
             "dist": {
2131 2131
                 "type": "zip",
2132
-                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/9f6674daceced7d5045494d0bf7e1d2908ea439d",
2133
-                "reference": "9f6674daceced7d5045494d0bf7e1d2908ea439d",
2132
+                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/3b95cfc23cf7a2b112ca65b067a33c1af7f79dc7",
2133
+                "reference": "3b95cfc23cf7a2b112ca65b067a33c1af7f79dc7",
2134 2134
                 "shasum": ""
2135 2135
             },
2136 2136
             "require": {
@@ -2161,7 +2161,7 @@
2161 2161
                 "issues": "https://github.com/filamentphp/filament/issues",
2162 2162
                 "source": "https://github.com/filamentphp/filament"
2163 2163
             },
2164
-            "time": "2025-01-10T12:48:52+00:00"
2164
+            "time": "2025-01-31T11:08:59+00:00"
2165 2165
         },
2166 2166
         {
2167 2167
             "name": "firebase/php-jwt",
@@ -3051,16 +3051,16 @@
3051 3051
         },
3052 3052
         {
3053 3053
             "name": "laravel/framework",
3054
-            "version": "v11.41.0",
3054
+            "version": "v11.41.3",
3055 3055
             "source": {
3056 3056
                 "type": "git",
3057 3057
                 "url": "https://github.com/laravel/framework.git",
3058
-                "reference": "42d6ae000c868c2abfa946da46702f2358493482"
3058
+                "reference": "3ef433d5865f30a19b6b1be247586068399b59cc"
3059 3059
             },
3060 3060
             "dist": {
3061 3061
                 "type": "zip",
3062
-                "url": "https://api.github.com/repos/laravel/framework/zipball/42d6ae000c868c2abfa946da46702f2358493482",
3063
-                "reference": "42d6ae000c868c2abfa946da46702f2358493482",
3062
+                "url": "https://api.github.com/repos/laravel/framework/zipball/3ef433d5865f30a19b6b1be247586068399b59cc",
3063
+                "reference": "3ef433d5865f30a19b6b1be247586068399b59cc",
3064 3064
                 "shasum": ""
3065 3065
             },
3066 3066
             "require": {
@@ -3262,7 +3262,7 @@
3262 3262
                 "issues": "https://github.com/laravel/framework/issues",
3263 3263
                 "source": "https://github.com/laravel/framework"
3264 3264
             },
3265
-            "time": "2025-01-28T15:22:55+00:00"
3265
+            "time": "2025-01-30T13:25:22+00:00"
3266 3266
         },
3267 3267
         {
3268 3268
             "name": "laravel/prompts",
@@ -5136,16 +5136,16 @@
5136 5136
         },
5137 5137
         {
5138 5138
             "name": "openspout/openspout",
5139
-            "version": "v4.28.4",
5139
+            "version": "v4.28.5",
5140 5140
             "source": {
5141 5141
                 "type": "git",
5142 5142
                 "url": "https://github.com/openspout/openspout.git",
5143
-                "reference": "68d58235c7c1164b3d231b798975b9b0b2b79b15"
5143
+                "reference": "ab05a09fe6fce57c90338f83280648a9786ce36b"
5144 5144
             },
5145 5145
             "dist": {
5146 5146
                 "type": "zip",
5147
-                "url": "https://api.github.com/repos/openspout/openspout/zipball/68d58235c7c1164b3d231b798975b9b0b2b79b15",
5148
-                "reference": "68d58235c7c1164b3d231b798975b9b0b2b79b15",
5147
+                "url": "https://api.github.com/repos/openspout/openspout/zipball/ab05a09fe6fce57c90338f83280648a9786ce36b",
5148
+                "reference": "ab05a09fe6fce57c90338f83280648a9786ce36b",
5149 5149
                 "shasum": ""
5150 5150
             },
5151 5151
             "require": {
@@ -5159,13 +5159,13 @@
5159 5159
             },
5160 5160
             "require-dev": {
5161 5161
                 "ext-zlib": "*",
5162
-                "friendsofphp/php-cs-fixer": "^3.66.1",
5162
+                "friendsofphp/php-cs-fixer": "^3.68.3",
5163 5163
                 "infection/infection": "^0.29.10",
5164
-                "phpbench/phpbench": "^1.3.1",
5165
-                "phpstan/phpstan": "^2.1.1",
5166
-                "phpstan/phpstan-phpunit": "^2.0.3",
5164
+                "phpbench/phpbench": "^1.4.0",
5165
+                "phpstan/phpstan": "^2.1.2",
5166
+                "phpstan/phpstan-phpunit": "^2.0.4",
5167 5167
                 "phpstan/phpstan-strict-rules": "^2",
5168
-                "phpunit/phpunit": "^11.5.2"
5168
+                "phpunit/phpunit": "^11.5.4"
5169 5169
             },
5170 5170
             "suggest": {
5171 5171
                 "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
@@ -5213,7 +5213,7 @@
5213 5213
             ],
5214 5214
             "support": {
5215 5215
                 "issues": "https://github.com/openspout/openspout/issues",
5216
-                "source": "https://github.com/openspout/openspout/tree/v4.28.4"
5216
+                "source": "https://github.com/openspout/openspout/tree/v4.28.5"
5217 5217
             },
5218 5218
             "funding": [
5219 5219
                 {
@@ -5225,7 +5225,7 @@
5225 5225
                     "type": "github"
5226 5226
                 }
5227 5227
             ],
5228
-            "time": "2025-01-07T11:48:34+00:00"
5228
+            "time": "2025-01-30T13:51:11+00:00"
5229 5229
         },
5230 5230
         {
5231 5231
             "name": "paragonie/constant_time_encoding",

+ 6
- 6
package-lock.json View File

@@ -1235,9 +1235,9 @@
1235 1235
             "license": "MIT"
1236 1236
         },
1237 1237
         "node_modules/electron-to-chromium": {
1238
-            "version": "1.5.89",
1239
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.89.tgz",
1240
-            "integrity": "sha512-okLMJSmbI+XHr8aG+wCK+VPH+d38sHMED6/q1CTsCNkqfdOZL3k2ThWnh44HL6bJKj9cabPCSVLDv9ynsIm8qg==",
1238
+            "version": "1.5.90",
1239
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz",
1240
+            "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==",
1241 1241
             "dev": true,
1242 1242
             "license": "ISC"
1243 1243
         },
@@ -1330,9 +1330,9 @@
1330 1330
             }
1331 1331
         },
1332 1332
         "node_modules/fastq": {
1333
-            "version": "1.18.0",
1334
-            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
1335
-            "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
1333
+            "version": "1.19.0",
1334
+            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
1335
+            "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
1336 1336
             "dev": true,
1337 1337
             "license": "ISC",
1338 1338
             "dependencies": {

+ 4
- 0
resources/css/filament/company/theme.css View File

@@ -10,6 +10,10 @@
10 10
 
11 11
 @config 'tailwind.config.js';
12 12
 
13
+.fi-sidebar-nav {
14
+    scrollbar-width: thin;
15
+}
16
+
13 17
 .fi-ta-empty-state-icon-ctn {
14 18
     @apply bg-platinum;
15 19
 }

+ 3
- 0
resources/views/filament/company/pages/reports/income-by-customer.blade.php View File

@@ -0,0 +1,3 @@
1
+<x-filament-panels::page>
2
+
3
+</x-filament-panels::page>

Loading…
Cancel
Save