Andrew Wallo 1 year ago
parent
commit
fe4633e07a

+ 0
- 2
app/Contracts/AccountHandler.php View File

21
 
21
 
22
     public function getTotalBalanceForAllBankAccounts(string $startDate, string $endDate): Money;
22
     public function getTotalBalanceForAllBankAccounts(string $startDate, string $endDate): Money;
23
 
23
 
24
-    public function getAccountCategoryOrder(): array;
25
-
26
     public function getEarliestTransactionDate(): string;
24
     public function getEarliestTransactionDate(): string;
27
 }
25
 }

+ 65
- 0
app/Enums/Accounting/AccountCategory.php View File

38
 
38
 
39
         return null;
39
         return null;
40
     }
40
     }
41
+
42
+    /**
43
+     * Determines if the account typically has a normal debit balance.
44
+     *
45
+     * In accounting, assets and expenses typically have a normal debit balance.
46
+     * A debit increases the balance of these accounts, while a credit decreases it.
47
+     */
48
+    public function isNormalDebitBalance(): bool
49
+    {
50
+        return in_array($this, [self::Asset, self::Expense], true);
51
+    }
52
+
53
+    /**
54
+     * Determines if the account typically has a normal credit balance.
55
+     *
56
+     * In accounting, liabilities, equity, and revenue typically have a normal credit balance.
57
+     * A credit increases the balance of these accounts, while a debit decreases it.
58
+     */
59
+    public function isNormalCreditBalance(): bool
60
+    {
61
+        return ! $this->isNormalDebitBalance();
62
+    }
63
+
64
+    /**
65
+     * Determines if the account is a nominal account.
66
+     *
67
+     * In accounting, nominal accounts are temporary accounts that are closed at the end of each accounting period,
68
+     * with their net balances transferred to Retained Earnings (a real account).
69
+     */
70
+    public function isNominal(): bool
71
+    {
72
+        return in_array($this, [self::Revenue, self::Expense], true);
73
+    }
74
+
75
+    /**
76
+     * Determines if the account is a real account.
77
+     *
78
+     * In accounting, real accounts are permanent accounts that retain their balances across accounting periods.
79
+     * They are not closed at the end of each accounting period.
80
+     */
81
+    public function isReal(): bool
82
+    {
83
+        return ! $this->isNominal();
84
+    }
85
+
86
+    public function getRelevantBalanceFields(): array
87
+    {
88
+        $commonFields = ['debit_balance', 'credit_balance', 'net_movement'];
89
+
90
+        return match ($this->isReal()) {
91
+            true => [...$commonFields, 'starting_balance', 'ending_balance'],
92
+            false => $commonFields,
93
+        };
94
+    }
95
+
96
+    public static function getOrderedCategories(): array
97
+    {
98
+        return [
99
+            self::Asset,
100
+            self::Liability,
101
+            self::Equity,
102
+            self::Revenue,
103
+            self::Expense,
104
+        ];
105
+    }
41
 }
106
 }

+ 1
- 1
app/Filament/Company/Pages/Accounting/Transactions.php View File

224
                 Tables\Columns\TextColumn::make('posted_at')
224
                 Tables\Columns\TextColumn::make('posted_at')
225
                     ->label('Date')
225
                     ->label('Date')
226
                     ->sortable()
226
                     ->sortable()
227
-                    ->localizeDate(),
227
+                    ->defaultDateFormat(),
228
                 Tables\Columns\TextColumn::make('description')
228
                 Tables\Columns\TextColumn::make('description')
229
                     ->label('Description')
229
                     ->label('Description')
230
                     ->limit(30)
230
                     ->limit(30)

+ 1
- 1
app/Filament/Company/Pages/Reports/AccountTransactions.php View File

96
         $accounts = Account::query()
96
         $accounts = Account::query()
97
             ->get()
97
             ->get()
98
             ->groupBy(fn (Account $account) => $account->category->getPluralLabel())
98
             ->groupBy(fn (Account $account) => $account->category->getPluralLabel())
99
-            ->map(fn (Collection $accounts, string $category) => $accounts->pluck('name', 'id'))
99
+            ->map(fn (Collection $accounts) => $accounts->pluck('name', 'id'))
100
             ->toArray();
100
             ->toArray();
101
 
101
 
102
         $allAccountsOption = [
102
         $allAccountsOption = [

+ 2
- 2
app/Filament/Company/Pages/Reports/BaseReportPage.php View File

238
     {
238
     {
239
         return DatePicker::make('startDate')
239
         return DatePicker::make('startDate')
240
             ->label('Start Date')
240
             ->label('Start Date')
241
-            ->displayFormat('Y-m-d')
241
+            ->defaultDateFormat()
242
             ->afterStateUpdated(static function (Set $set) {
242
             ->afterStateUpdated(static function (Set $set) {
243
                 $set('dateRange', 'Custom');
243
                 $set('dateRange', 'Custom');
244
             });
244
             });
248
     {
248
     {
249
         return DatePicker::make('endDate')
249
         return DatePicker::make('endDate')
250
             ->label('End Date')
250
             ->label('End Date')
251
-            ->displayFormat('Y-m-d')
251
+            ->defaultDateFormat()
252
             ->afterStateUpdated(static function (Set $set) {
252
             ->afterStateUpdated(static function (Set $set) {
253
                 $set('dateRange', 'Custom');
253
                 $set('dateRange', 'Custom');
254
             });
254
             });

+ 23
- 1
app/Providers/MacroServiceProvider.php View File

11
 use App\Utilities\Currency\CurrencyAccessor;
11
 use App\Utilities\Currency\CurrencyAccessor;
12
 use BackedEnum;
12
 use BackedEnum;
13
 use Closure;
13
 use Closure;
14
+use Filament\Forms\Components\DatePicker;
14
 use Filament\Forms\Components\Field;
15
 use Filament\Forms\Components\Field;
15
 use Filament\Forms\Components\TextInput;
16
 use Filament\Forms\Components\TextInput;
16
 use Filament\Tables\Columns\TextColumn;
17
 use Filament\Tables\Columns\TextColumn;
54
             return $this;
55
             return $this;
55
         });
56
         });
56
 
57
 
57
-        TextColumn::macro('localizeDate', function (): static {
58
+        TextColumn::macro('defaultDateFormat', function (): static {
58
             $localization = Localization::firstOrFail();
59
             $localization = Localization::firstOrFail();
59
 
60
 
60
             $dateFormat = $localization->date_format->value ?? DateFormat::DEFAULT;
61
             $dateFormat = $localization->date_format->value ?? DateFormat::DEFAULT;
65
             return $this;
66
             return $this;
66
         });
67
         });
67
 
68
 
69
+        DatePicker::macro('defaultDateFormat', function (): static {
70
+            $localization = Localization::firstOrFail();
71
+
72
+            $dateFormat = $localization->date_format->value ?? DateFormat::DEFAULT;
73
+            $timezone = $localization->timezone ?? Carbon::now()->timezoneName;
74
+
75
+            $this->displayFormat($dateFormat)
76
+                ->timezone($timezone);
77
+
78
+            return $this;
79
+        });
80
+
68
         TextColumn::macro('currency', function (string | Closure | null $currency = null, ?bool $convert = null): static {
81
         TextColumn::macro('currency', function (string | Closure | null $currency = null, ?bool $convert = null): static {
69
             $this->formatStateUsing(static function (TextColumn $column, $state) use ($currency, $convert): ?string {
82
             $this->formatStateUsing(static function (TextColumn $column, $state) use ($currency, $convert): ?string {
70
                 if (blank($state)) {
83
                 if (blank($state)) {
209
 
222
 
210
             return '';
223
             return '';
211
         });
224
         });
225
+
226
+        Carbon::macro('toDefaultDateFormat', function () {
227
+            $localization = Localization::firstOrFail();
228
+
229
+            $dateFormat = $localization->date_format->value ?? DateFormat::DEFAULT;
230
+            $timezone = $localization->timezone ?? Carbon::now()->timezoneName;
231
+
232
+            return $this->setTimezone($timezone)->format($dateFormat);
233
+        });
212
     }
234
     }
213
 }
235
 }

+ 84
- 117
app/Services/AccountService.php View File

11
 use App\Utilities\Currency\CurrencyAccessor;
11
 use App\Utilities\Currency\CurrencyAccessor;
12
 use App\ValueObjects\Money;
12
 use App\ValueObjects\Money;
13
 use Closure;
13
 use Closure;
14
-use Illuminate\Database\Query\Builder;
14
+use Illuminate\Database\Eloquent\Builder;
15
 use Illuminate\Database\Query\JoinClause;
15
 use Illuminate\Database\Query\JoinClause;
16
+use Illuminate\Support\Carbon;
16
 use Illuminate\Support\Facades\DB;
17
 use Illuminate\Support\Facades\DB;
17
 
18
 
18
 class AccountService implements AccountHandler
19
 class AccountService implements AccountHandler
53
         return new Money($balances['starting_balance'], $account->currency_code);
54
         return new Money($balances['starting_balance'], $account->currency_code);
54
     }
55
     }
55
 
56
 
56
-    public function getStartingBalanceSubquery($startDate, $accountIds = null): Builder
57
+    public function getTransactionDetailsSubquery(string $startDate, string $endDate): Closure
57
     {
58
     {
58
-        return DB::table('journal_entries')
59
-            ->select('journal_entries.account_id')
60
-            ->selectRaw('
61
-                COALESCE(SUM(
62
-                    CASE
63
-                        WHEN accounts.category IN ("asset", "expense") THEN
64
-                            CASE WHEN journal_entries.type = "debit" THEN journal_entries.amount ELSE -journal_entries.amount END
65
-                        ELSE
66
-                            CASE WHEN journal_entries.type = "credit" THEN journal_entries.amount ELSE -journal_entries.amount END
67
-                    END
68
-                ), 0) AS starting_balance
69
-            ')
70
-            ->join('transactions', 'transactions.id', '=', 'journal_entries.transaction_id')
71
-            ->join('accounts', 'accounts.id', '=', 'journal_entries.account_id')
72
-            ->where('transactions.posted_at', '<', $startDate)
73
-            ->groupBy('journal_entries.account_id');
74
-    }
75
-
76
-    public function getTotalDebitSubquery($startDate, $endDate, $accountIds = null): Builder
77
-    {
78
-        return DB::table('journal_entries')
79
-            ->select('journal_entries.account_id')
80
-            ->selectRaw('
81
-                COALESCE(SUM(CASE WHEN journal_entries.type = "debit" THEN journal_entries.amount ELSE 0 END), 0) as total_debit
82
-            ')
83
-            ->join('transactions', 'transactions.id', '=', 'journal_entries.transaction_id')
84
-            ->whereBetween('transactions.posted_at', [$startDate, $endDate])
85
-            ->groupBy('journal_entries.account_id');
86
-    }
59
+        $endOfDay = Carbon::parse($endDate)->endOfDay()->toDateTimeString();
87
 
60
 
88
-    public function getTotalCreditSubquery($startDate, $endDate, $accountIds = null): Builder
89
-    {
90
-        return DB::table('journal_entries')
91
-            ->select('journal_entries.account_id')
92
-            ->selectRaw('
93
-                COALESCE(SUM(CASE WHEN journal_entries.type = "credit" THEN journal_entries.amount ELSE 0 END), 0) as total_credit
94
-            ')
95
-            ->join('transactions', 'transactions.id', '=', 'journal_entries.transaction_id')
96
-            ->whereBetween('transactions.posted_at', [$startDate, $endDate])
97
-            ->groupBy('journal_entries.account_id');
98
-    }
99
-
100
-    public function getTransactionDetailsSubquery($startDate, $endDate): Closure
101
-    {
102
-        return function ($query) use ($startDate, $endDate) {
61
+        return static function ($query) use ($startDate, $endOfDay) {
103
             $query->select(
62
             $query->select(
104
                 'journal_entries.id',
63
                 'journal_entries.id',
105
                 'journal_entries.account_id',
64
                 'journal_entries.account_id',
108
                 'journal_entries.amount',
67
                 'journal_entries.amount',
109
                 DB::raw('journal_entries.amount * IF(journal_entries.type = "debit", 1, -1) AS signed_amount')
68
                 DB::raw('journal_entries.amount * IF(journal_entries.type = "debit", 1, -1) AS signed_amount')
110
             )
69
             )
111
-                ->whereBetween('transactions.posted_at', [$startDate, $endDate])
70
+                ->whereBetween('transactions.posted_at', [$startDate, $endOfDay])
112
                 ->join('transactions', 'transactions.id', '=', 'journal_entries.transaction_id')
71
                 ->join('transactions', 'transactions.id', '=', 'journal_entries.transaction_id')
113
                 ->orderBy('transactions.posted_at')
72
                 ->orderBy('transactions.posted_at')
114
                 ->with('transaction:id,type,description,posted_at');
73
                 ->with('transaction:id,type,description,posted_at');
115
         };
74
         };
116
     }
75
     }
117
 
76
 
118
-    public function getAccountBalances(string $startDate, string $endDate, array $accountIds = []): \Illuminate\Database\Eloquent\Builder
77
+    public function getAccountBalances(string $startDate, string $endDate, array $accountIds = []): Builder
119
     {
78
     {
79
+        $endOfDay = Carbon::parse($endDate)->endOfDay()->toDateTimeString();
80
+
120
         $query = Account::query()
81
         $query = Account::query()
121
             ->select([
82
             ->select([
122
                 'accounts.id',
83
                 'accounts.id',
126
                 'accounts.currency_code',
87
                 'accounts.currency_code',
127
                 'accounts.code',
88
                 'accounts.code',
128
             ])
89
             ])
129
-            ->leftJoinSub($this->getStartingBalanceSubquery($startDate), 'starting_balance', function (JoinClause $join) {
130
-                $join->on('accounts.id', '=', 'starting_balance.account_id');
131
-            })
132
-            ->leftJoinSub($this->getTotalDebitSubquery($startDate, $endDate), 'total_debit', function (JoinClause $join) {
133
-                $join->on('accounts.id', '=', 'total_debit.account_id');
134
-            })
135
-            ->leftJoinSub($this->getTotalCreditSubquery($startDate, $endDate), 'total_credit', function (JoinClause $join) {
136
-                $join->on('accounts.id', '=', 'total_credit.account_id');
137
-            })
138
             ->addSelect([
90
             ->addSelect([
139
-                DB::raw('COALESCE(starting_balance.starting_balance, 0) as starting_balance'),
140
-                DB::raw('COALESCE(total_debit.total_debit, 0) as total_debit'),
141
-                DB::raw('COALESCE(total_credit.total_credit, 0) as total_credit'),
91
+                DB::raw("
92
+                    COALESCE(
93
+                        IF(accounts.category IN ('asset', 'expense'),
94
+                            SUM(IF(journal_entries.type = 'debit' AND transactions.posted_at < ?, journal_entries.amount, 0)) -
95
+                            SUM(IF(journal_entries.type = 'credit' AND transactions.posted_at < ?, journal_entries.amount, 0)),
96
+                            SUM(IF(journal_entries.type = 'credit' AND transactions.posted_at < ?, journal_entries.amount, 0)) -
97
+                            SUM(IF(journal_entries.type = 'debit' AND transactions.posted_at < ?, journal_entries.amount, 0))
98
+                        ), 0
99
+                    ) AS starting_balance
100
+                "),
101
+                DB::raw("
102
+                    COALESCE(SUM(
103
+                        IF(journal_entries.type = 'debit' AND transactions.posted_at BETWEEN ? AND ?, journal_entries.amount, 0)
104
+                    ), 0) AS total_debit
105
+                "),
106
+                DB::raw("
107
+                    COALESCE(SUM(
108
+                        IF(journal_entries.type = 'credit' AND transactions.posted_at BETWEEN ? AND ?, journal_entries.amount, 0)
109
+                    ), 0) AS total_credit
110
+                "),
142
             ])
111
             ])
143
-            ->with(['subtype:id,name'])
144
-            ->whereHas('journalEntries.transaction', function ($query) use ($startDate, $endDate) {
145
-                $query->whereBetween('posted_at', [$startDate, $endDate]);
146
-            });
112
+            ->join('journal_entries', 'journal_entries.account_id', '=', 'accounts.id')
113
+            ->join('transactions', function (JoinClause $join) use ($endOfDay) {
114
+                $join->on('transactions.id', '=', 'journal_entries.transaction_id')
115
+                    ->where('transactions.posted_at', '<=', $endOfDay);
116
+            })
117
+            ->groupBy('accounts.id')
118
+            ->with(['subtype:id,name']);
147
 
119
 
148
         if (! empty($accountIds)) {
120
         if (! empty($accountIds)) {
149
             $query->whereIn('accounts.id', $accountIds);
121
             $query->whereIn('accounts.id', $accountIds);
150
         }
122
         }
151
 
123
 
124
+        $query->addBinding([$startDate, $startDate, $startDate, $startDate, $startDate, $endOfDay, $startDate, $endOfDay], 'select');
125
+
152
         return $query;
126
         return $query;
153
     }
127
     }
154
 
128
 
129
+    public function getTotalBalanceForAllBankAccounts(string $startDate, string $endDate): Money
130
+    {
131
+        $endOfDay = Carbon::parse($endDate)->endOfDay()->toDateTimeString();
132
+
133
+        $accountIds = Account::whereHas('bankAccount')
134
+            ->pluck('id')
135
+            ->toArray();
136
+
137
+        if (empty($accountIds)) {
138
+            return new Money(0, CurrencyAccessor::getDefaultCurrency());
139
+        }
140
+
141
+        $result = DB::table('journal_entries')
142
+            ->join('transactions', function (JoinClause $join) use ($endOfDay) {
143
+                $join->on('transactions.id', '=', 'journal_entries.transaction_id')
144
+                    ->where('transactions.posted_at', '<=', $endOfDay);
145
+            })
146
+            ->whereIn('journal_entries.account_id', $accountIds)
147
+            ->selectRaw('
148
+            SUM(CASE
149
+                WHEN transactions.posted_at < ? AND journal_entries.type = "debit" THEN journal_entries.amount
150
+                WHEN transactions.posted_at < ? AND journal_entries.type = "credit" THEN -journal_entries.amount
151
+                ELSE 0
152
+            END) AS totalStartingBalance,
153
+            SUM(CASE
154
+                WHEN transactions.posted_at BETWEEN ? AND ? AND journal_entries.type = "debit" THEN journal_entries.amount
155
+                WHEN transactions.posted_at BETWEEN ? AND ? AND journal_entries.type = "credit" THEN -journal_entries.amount
156
+                ELSE 0
157
+            END) AS totalNetMovement
158
+        ', [
159
+                $startDate,
160
+                $startDate,
161
+                $startDate,
162
+                $endOfDay,
163
+                $startDate,
164
+                $endOfDay,
165
+            ])
166
+            ->first();
167
+
168
+        $totalBalance = $result->totalStartingBalance + $result->totalNetMovement;
169
+
170
+        return new Money($totalBalance, CurrencyAccessor::getDefaultCurrency());
171
+    }
172
+
155
     public function getEndingBalance(Account $account, string $startDate, string $endDate): ?Money
173
     public function getEndingBalance(Account $account, string $startDate, string $endDate): ?Money
156
     {
174
     {
157
         $calculatedBalances = $this->calculateBalances($account, $startDate, $endDate);
175
         $calculatedBalances = $this->calculateBalances($account, $startDate, $endDate);
175
         })
193
         })
176
             ->where('type', 'credit')
194
             ->where('type', 'credit')
177
             ->whereHas('transaction', static function ($query) use ($startDate) {
195
             ->whereHas('transaction', static function ($query) use ($startDate) {
178
-                $query->where('posted_at', '<=', $startDate);
196
+                $query->where('posted_at', '<', $startDate);
179
             })
197
             })
180
             ->sum('amount');
198
             ->sum('amount');
181
 
199
 
184
         })
202
         })
185
             ->where('type', 'debit')
203
             ->where('type', 'debit')
186
             ->whereHas('transaction', static function ($query) use ($startDate) {
204
             ->whereHas('transaction', static function ($query) use ($startDate) {
187
-                $query->where('posted_at', '<=', $startDate);
205
+                $query->where('posted_at', '<', $startDate);
188
             })
206
             })
189
             ->sum('amount');
207
             ->sum('amount');
190
 
208
 
251
         return array_filter($balances, static fn ($value) => $value !== null);
269
         return array_filter($balances, static fn ($value) => $value !== null);
252
     }
270
     }
253
 
271
 
254
-    public function getTotalBalanceForAllBankAccounts(string $startDate, string $endDate): Money
255
-    {
256
-        $accountIds = Account::whereHas('bankAccount')
257
-            ->pluck('id')
258
-            ->toArray();
259
-
260
-        if (empty($accountIds)) {
261
-            return new Money(0, CurrencyAccessor::getDefaultCurrency());
262
-        }
263
-
264
-        $result = DB::table('journal_entries')
265
-            ->join('transactions', 'journal_entries.transaction_id', '=', 'transactions.id')
266
-            ->whereIn('journal_entries.account_id', $accountIds)
267
-            ->where('transactions.posted_at', '<=', $endDate)
268
-            ->selectRaw('
269
-            SUM(CASE
270
-                WHEN transactions.posted_at <= ? AND journal_entries.type = "debit" THEN journal_entries.amount
271
-                WHEN transactions.posted_at <= ? AND journal_entries.type = "credit" THEN -journal_entries.amount
272
-                ELSE 0
273
-            END) AS totalStartingBalance,
274
-            SUM(CASE
275
-                WHEN transactions.posted_at BETWEEN ? AND ? AND journal_entries.type = "debit" THEN journal_entries.amount
276
-                WHEN transactions.posted_at BETWEEN ? AND ? AND journal_entries.type = "credit" THEN -journal_entries.amount
277
-                ELSE 0
278
-            END) AS totalNetMovement
279
-        ', [
280
-                $startDate,
281
-                $startDate,
282
-                $startDate,
283
-                $endDate,
284
-                $startDate,
285
-                $endDate,
286
-            ])
287
-            ->first();
288
-
289
-        $totalBalance = $result->totalStartingBalance + $result->totalNetMovement;
290
-
291
-        return new Money($totalBalance, CurrencyAccessor::getDefaultCurrency());
292
-    }
293
-
294
-    public function getAccountCategoryOrder(): array
295
-    {
296
-        return [
297
-            AccountCategory::Asset->getPluralLabel(),
298
-            AccountCategory::Liability->getPluralLabel(),
299
-            AccountCategory::Equity->getPluralLabel(),
300
-            AccountCategory::Revenue->getPluralLabel(),
301
-            AccountCategory::Expense->getPluralLabel(),
302
-        ];
303
-    }
304
-
305
     public function getEarliestTransactionDate(): string
272
     public function getEarliestTransactionDate(): string
306
     {
273
     {
307
         $earliestDate = Transaction::oldest('posted_at')
274
         $earliestDate = Transaction::oldest('posted_at')

+ 71
- 139
app/Services/ReportService.php View File

8
 use App\DTO\AccountTransactionDTO;
8
 use App\DTO\AccountTransactionDTO;
9
 use App\DTO\ReportDTO;
9
 use App\DTO\ReportDTO;
10
 use App\Enums\Accounting\AccountCategory;
10
 use App\Enums\Accounting\AccountCategory;
11
-use App\Enums\Accounting\JournalEntryType;
12
 use App\Models\Accounting\Account;
11
 use App\Models\Accounting\Account;
13
 use App\Support\Column;
12
 use App\Support\Column;
14
 use App\Utilities\Currency\CurrencyAccessor;
13
 use App\Utilities\Currency\CurrencyAccessor;
15
-use Illuminate\Support\Collection;
16
 
14
 
17
 class ReportService
15
 class ReportService
18
 {
16
 {
37
         );
35
         );
38
     }
36
     }
39
 
37
 
40
-    private function filterBalances(array $balances, array $fields): array
41
-    {
42
-        return array_filter($balances, static fn ($key) => in_array($key, $fields, true), ARRAY_FILTER_USE_KEY);
43
-    }
44
-
45
-    private function getCategoryGroupedAccounts(array $allCategories): Collection
46
-    {
47
-        return Account::whereHas('journalEntries')
48
-            ->select(['id', 'name', 'currency_code', 'category', 'code'])
49
-            ->get()
50
-            ->groupBy(fn (Account $account) => $account->category->getPluralLabel())
51
-            ->sortBy(static fn (Collection $groupedAccounts, string $key) => array_search($key, $allCategories, true));
52
-    }
53
-
54
     public function buildAccountBalanceReport(string $startDate, string $endDate, array $columns = []): ReportDTO
38
     public function buildAccountBalanceReport(string $startDate, string $endDate, array $columns = []): ReportDTO
55
     {
39
     {
56
-        $allCategories = $this->accountService->getAccountCategoryOrder();
57
-
58
-        $accountIds = Account::whereHas('journalEntries')->pluck('id')->toArray();
59
-
60
-        $accounts = $this->accountService->getAccountBalances($startDate, $endDate, $accountIds)->get();
40
+        $orderedCategories = AccountCategory::getOrderedCategories();
61
 
41
 
62
-        $balanceFields = ['starting_balance', 'debit_balance', 'credit_balance', 'net_movement', 'ending_balance'];
42
+        $accounts = $this->accountService->getAccountBalances($startDate, $endDate)->get();
63
 
43
 
64
         $columnNameKeys = array_map(fn (Column $column) => $column->getName(), $columns);
44
         $columnNameKeys = array_map(fn (Column $column) => $column->getName(), $columns);
65
 
45
 
66
-        $updatedBalanceFields = array_filter($balanceFields, fn (string $balanceField) => in_array($balanceField, $columnNameKeys, true));
67
-
68
         $accountCategories = [];
46
         $accountCategories = [];
69
-        $reportTotalBalances = array_fill_keys($updatedBalanceFields, 0);
47
+        $reportTotalBalances = [];
48
+
49
+        foreach ($orderedCategories as $category) {
50
+            $accountsInCategory = $accounts->where('category', $category)
51
+                ->sortBy('code', SORT_NATURAL);
70
 
52
 
71
-        foreach ($allCategories as $categoryPluralName) {
72
-            $categoryName = AccountCategory::fromPluralLabel($categoryPluralName);
73
-            $accountsInCategory = $accounts->where('category', $categoryName)->keyBy('id');
74
-            $categorySummaryBalances = array_fill_keys($updatedBalanceFields, 0);
53
+            $relevantFields = array_intersect($category->getRelevantBalanceFields(), $columnNameKeys);
54
+
55
+            $categorySummaryBalances = array_fill_keys($relevantFields, 0);
75
 
56
 
76
             $categoryAccounts = [];
57
             $categoryAccounts = [];
77
 
58
 
59
+            /** @var Account $account */
78
             foreach ($accountsInCategory as $account) {
60
             foreach ($accountsInCategory as $account) {
79
-                $accountBalances = $this->calculateAccountBalances($account, $categoryName);
61
+                $accountBalances = $this->calculateAccountBalances($account, $category);
80
 
62
 
81
-                if ($this->hasZeroBalanceSum($accountBalances)) {
82
-                    continue;
63
+                foreach ($relevantFields as $field) {
64
+                    $categorySummaryBalances[$field] += $accountBalances[$field];
83
                 }
65
                 }
84
 
66
 
85
-                foreach ($accountBalances as $accountBalanceType => $accountBalance) {
86
-                    if (array_key_exists($accountBalanceType, $categorySummaryBalances)) {
87
-                        $categorySummaryBalances[$accountBalanceType] += $accountBalance;
88
-                    }
89
-                }
90
-
91
-                $filteredAccountBalances = $this->filterBalances($accountBalances, $updatedBalanceFields);
92
-                $formattedAccountBalances = $this->formatBalances($filteredAccountBalances);
67
+                $formattedAccountBalances = $this->formatBalances($accountBalances);
93
 
68
 
94
                 $categoryAccounts[] = new AccountDTO(
69
                 $categoryAccounts[] = new AccountDTO(
95
                     $account->name,
70
                     $account->name,
99
                 );
74
                 );
100
             }
75
             }
101
 
76
 
102
-            $this->adjustAccountBalanceCategoryFields($categoryName, $categorySummaryBalances);
103
-
104
-            foreach ($updatedBalanceFields as $field) {
105
-                if (array_key_exists($field, $categorySummaryBalances)) {
106
-                    $reportTotalBalances[$field] += $categorySummaryBalances[$field];
107
-                }
77
+            foreach ($relevantFields as $field) {
78
+                $reportTotalBalances[$field] = ($reportTotalBalances[$field] ?? 0) + $categorySummaryBalances[$field];
108
             }
79
             }
109
 
80
 
110
-            $filteredCategorySummaryBalances = $this->filterBalances($categorySummaryBalances, $updatedBalanceFields);
111
-            $formattedCategorySummaryBalances = $this->formatBalances($filteredCategorySummaryBalances);
81
+            $formattedCategorySummaryBalances = $this->formatBalances($categorySummaryBalances);
112
 
82
 
113
-            $accountCategories[$categoryPluralName] = new AccountCategoryDTO(
83
+            $accountCategories[$category->getPluralLabel()] = new AccountCategoryDTO(
114
                 $categoryAccounts,
84
                 $categoryAccounts,
115
                 $formattedCategorySummaryBalances,
85
                 $formattedCategorySummaryBalances,
116
             );
86
             );
128
             'credit_balance' => $account->total_credit ?? 0,
98
             'credit_balance' => $account->total_credit ?? 0,
129
         ];
99
         ];
130
 
100
 
131
-        if (in_array($category, [AccountCategory::Liability, AccountCategory::Equity, AccountCategory::Revenue])) {
132
-            $balances['net_movement'] = $balances['credit_balance'] - $balances['debit_balance'];
133
-        } else {
101
+        if ($category->isNormalDebitBalance()) {
134
             $balances['net_movement'] = $balances['debit_balance'] - $balances['credit_balance'];
102
             $balances['net_movement'] = $balances['debit_balance'] - $balances['credit_balance'];
103
+        } else {
104
+            $balances['net_movement'] = $balances['credit_balance'] - $balances['debit_balance'];
135
         }
105
         }
136
 
106
 
137
-        if (! in_array($category, [AccountCategory::Expense, AccountCategory::Revenue], true)) {
107
+        if ($category->isReal()) {
138
             $balances['starting_balance'] = $account->starting_balance ?? 0;
108
             $balances['starting_balance'] = $account->starting_balance ?? 0;
139
-            $balances['ending_balance'] = $balances['starting_balance'] + $balances['credit_balance'] - $balances['debit_balance'];
109
+            $balances['ending_balance'] = $balances['starting_balance'] + $balances['net_movement'];
140
         }
110
         }
141
 
111
 
142
         return $balances;
112
         return $balances;
143
     }
113
     }
144
 
114
 
145
-    private function adjustAccountBalanceCategoryFields(AccountCategory $category, array &$categorySummaryBalances): void
146
-    {
147
-        if (in_array($category, [AccountCategory::Expense, AccountCategory::Revenue], true)) {
148
-            unset($categorySummaryBalances['starting_balance'], $categorySummaryBalances['ending_balance']);
149
-        }
150
-    }
151
-
152
-    private function hasZeroBalanceSum(array $balances): bool
153
-    {
154
-        return array_sum(array_map('abs', $balances)) === 0;
155
-    }
156
-
157
     public function buildAccountTransactionsReport(string $startDate, string $endDate, ?array $columns = null, ?string $accountId = 'all'): ReportDTO
115
     public function buildAccountTransactionsReport(string $startDate, string $endDate, ?array $columns = null, ?string $accountId = 'all'): ReportDTO
158
     {
116
     {
159
         $columns ??= [];
117
         $columns ??= [];
189
                 $transaction = $journalEntry->transaction;
147
                 $transaction = $journalEntry->transaction;
190
                 $signedAmount = $journalEntry->signed_amount;
148
                 $signedAmount = $journalEntry->signed_amount;
191
 
149
 
192
-                // Adjust balance based on account category
193
-                if (in_array($account->category, [AccountCategory::Asset, AccountCategory::Expense])) {
150
+                if ($account->category->isNormalDebitBalance()) {
194
                     $currentBalance += $signedAmount;
151
                     $currentBalance += $signedAmount;
195
                 } else {
152
                 } else {
196
                     $currentBalance -= $signedAmount;
153
                     $currentBalance -= $signedAmount;
197
                 }
154
                 }
198
 
155
 
156
+                $formattedAmount = money(abs($signedAmount), $defaultCurrency)->format();
157
+
199
                 $accountTransactions[] = new AccountTransactionDTO(
158
                 $accountTransactions[] = new AccountTransactionDTO(
200
                     id: $transaction->id,
159
                     id: $transaction->id,
201
-                    date: $transaction->posted_at->format('Y-m-d'),
202
-                    description: $transaction->description ?? '',
203
-                    debit: $journalEntry->type === JournalEntryType::Debit ? money(abs($signedAmount), $defaultCurrency)->format() : '',
204
-                    credit: $journalEntry->type === JournalEntryType::Credit ? money(abs($signedAmount), $defaultCurrency)->format() : '',
160
+                    date: $transaction->posted_at->toDefaultDateFormat(),
161
+                    description: $transaction->description ?? 'Add a description',
162
+                    debit: $journalEntry->type->isDebit() ? $formattedAmount : '',
163
+                    credit: $journalEntry->type->isCredit() ? $formattedAmount : '',
205
                     balance: money($currentBalance, $defaultCurrency)->format(),
164
                     balance: money($currentBalance, $defaultCurrency)->format(),
206
                     type: $transaction->type,
165
                     type: $transaction->type,
207
                     tableAction: $transaction->type->isJournal() ? 'updateJournalTransaction' : 'updateTransaction'
166
                     tableAction: $transaction->type->isJournal() ? 'updateJournalTransaction' : 'updateTransaction'
242
         return new ReportDTO(categories: $reportCategories, fields: $columns);
201
         return new ReportDTO(categories: $reportCategories, fields: $columns);
243
     }
202
     }
244
 
203
 
245
-    private function buildReport(array $allCategories, Collection $categoryGroupedAccounts, callable $balanceCalculator, array $balanceFields, array $allFields, ?callable $initializeCategoryBalances = null, bool $includeRetainedEarnings = false, ?string $startDate = null): ReportDTO
204
+    public function buildTrialBalanceReport(string $startDate, string $endDate, array $columns = []): ReportDTO
246
     {
205
     {
206
+        $orderedCategories = AccountCategory::getOrderedCategories();
207
+
208
+        $accounts = $this->accountService->getAccountBalances($startDate, $endDate)->get();
209
+
210
+        $balanceFields = ['debit_balance', 'credit_balance'];
211
+
247
         $accountCategories = [];
212
         $accountCategories = [];
248
         $reportTotalBalances = array_fill_keys($balanceFields, 0);
213
         $reportTotalBalances = array_fill_keys($balanceFields, 0);
249
 
214
 
250
-        foreach ($allCategories as $categoryName) {
251
-            $accountsInCategory = $categoryGroupedAccounts[$categoryName] ?? collect();
252
-            $categorySummaryBalances = array_fill_keys($balanceFields, 0);
215
+        foreach ($orderedCategories as $category) {
216
+            $accountsInCategory = $accounts->where('category', $category)
217
+                ->sortBy('code', SORT_NATURAL);
253
 
218
 
254
-            if ($initializeCategoryBalances) {
255
-                $initializeCategoryBalances($categoryName, $categorySummaryBalances);
256
-            }
219
+            $categorySummaryBalances = array_fill_keys($balanceFields, 0);
257
 
220
 
258
             $categoryAccounts = [];
221
             $categoryAccounts = [];
259
 
222
 
223
+            /** @var Account $account */
260
             foreach ($accountsInCategory as $account) {
224
             foreach ($accountsInCategory as $account) {
261
-                /** @var Account $account */
262
-                $accountBalances = $balanceCalculator($account);
225
+                $accountBalances = $this->calculateAccountBalances($account, $category);
263
 
226
 
264
-                if (array_sum($accountBalances) === 0) {
265
-                    continue;
266
-                }
227
+                $endingBalance = $accountBalances['ending_balance'] ?? $accountBalances['net_movement'];
228
+
229
+                $trialBalance = $this->calculateTrialBalance($account->category, $endingBalance);
267
 
230
 
268
-                foreach ($accountBalances as $accountBalanceType => $accountBalance) {
269
-                    if (array_key_exists($accountBalanceType, $categorySummaryBalances)) {
270
-                        $categorySummaryBalances[$accountBalanceType] += $accountBalance;
271
-                    }
231
+                foreach ($trialBalance as $balanceType => $balance) {
232
+                    $categorySummaryBalances[$balanceType] += $balance;
272
                 }
233
                 }
273
 
234
 
274
-                $filteredAccountBalances = $this->filterBalances($accountBalances, $balanceFields);
275
-                $formattedAccountBalances = $this->formatBalances($filteredAccountBalances);
235
+                $formattedAccountBalances = $this->formatBalances($trialBalance);
276
 
236
 
277
                 $categoryAccounts[] = new AccountDTO(
237
                 $categoryAccounts[] = new AccountDTO(
278
                     $account->name,
238
                     $account->name,
282
                 );
242
                 );
283
             }
243
             }
284
 
244
 
285
-            if ($includeRetainedEarnings && $categoryName === AccountCategory::Equity->getPluralLabel()) {
286
-                $retainedEarnings = $this->accountService->getRetainedEarnings($startDate);
287
-                $retainedEarningsAmount = $retainedEarnings->getAmount();
288
-
289
-                if ($retainedEarningsAmount >= 0) {
290
-                    $categorySummaryBalances['credit_balance'] += $retainedEarningsAmount;
291
-                    $categoryAccounts[] = new AccountDTO(
292
-                        'Retained Earnings',
293
-                        'RE',
294
-                        null,
295
-                        $this->formatBalances(['debit_balance' => 0, 'credit_balance' => $retainedEarningsAmount])
296
-                    );
297
-                } else {
298
-                    $categorySummaryBalances['debit_balance'] += abs($retainedEarningsAmount);
299
-                    $categoryAccounts[] = new AccountDTO(
300
-                        'Retained Earnings',
301
-                        'RE',
302
-                        null,
303
-                        $this->formatBalances(['debit_balance' => abs($retainedEarningsAmount), 'credit_balance' => 0])
304
-                    );
305
-                }
245
+            if ($category === AccountCategory::Equity) {
246
+                $retainedEarningsAmount = $this->accountService->getRetainedEarnings($startDate)->getAmount();
247
+                $isCredit = $retainedEarningsAmount >= 0;
248
+
249
+                $categorySummaryBalances[$isCredit ? 'credit_balance' : 'debit_balance'] += abs($retainedEarningsAmount);
250
+
251
+                $categoryAccounts[] = new AccountDTO(
252
+                    'Retained Earnings',
253
+                    'RE',
254
+                    null,
255
+                    $this->formatBalances([
256
+                        'debit_balance' => $isCredit ? 0 : abs($retainedEarningsAmount),
257
+                        'credit_balance' => $isCredit ? $retainedEarningsAmount : 0,
258
+                    ])
259
+                );
306
             }
260
             }
307
 
261
 
308
-            foreach ($balanceFields as $field) {
309
-                if (array_key_exists($field, $categorySummaryBalances)) {
310
-                    $reportTotalBalances[$field] += $categorySummaryBalances[$field];
311
-                }
262
+            foreach ($categorySummaryBalances as $balanceType => $balance) {
263
+                $reportTotalBalances[$balanceType] += $balance;
312
             }
264
             }
313
 
265
 
314
-            $filteredCategorySummaryBalances = $this->filterBalances($categorySummaryBalances, $balanceFields);
315
-            $formattedCategorySummaryBalances = $this->formatBalances($filteredCategorySummaryBalances);
266
+            $formattedCategorySummaryBalances = $this->formatBalances($categorySummaryBalances);
316
 
267
 
317
-            $accountCategories[$categoryName] = new AccountCategoryDTO(
268
+            $accountCategories[$category->getPluralLabel()] = new AccountCategoryDTO(
318
                 $categoryAccounts,
269
                 $categoryAccounts,
319
                 $formattedCategorySummaryBalances,
270
                 $formattedCategorySummaryBalances,
320
             );
271
             );
322
 
273
 
323
         $formattedReportTotalBalances = $this->formatBalances($reportTotalBalances);
274
         $formattedReportTotalBalances = $this->formatBalances($reportTotalBalances);
324
 
275
 
325
-        return new ReportDTO($accountCategories, $formattedReportTotalBalances, $allFields);
326
-    }
327
-
328
-    public function buildTrialBalanceReport(string $startDate, string $endDate, array $columns = []): ReportDTO
329
-    {
330
-        $allCategories = $this->accountService->getAccountCategoryOrder();
331
-
332
-        $categoryGroupedAccounts = $this->getCategoryGroupedAccounts($allCategories);
333
-
334
-        $balanceFields = ['debit_balance', 'credit_balance'];
335
-
336
-        return $this->buildReport($allCategories, $categoryGroupedAccounts, function (Account $account) use ($startDate, $endDate) {
337
-            $endingBalance = $this->accountService->getEndingBalance($account, $startDate, $endDate)?->getAmount() ?? 0;
338
-
339
-            if ($endingBalance === 0) {
340
-                return [];
341
-            }
342
-
343
-            return $this->calculateTrialBalance($account->category, $endingBalance);
344
-        }, $balanceFields, $columns, null, true, $startDate);
276
+        return new ReportDTO($accountCategories, $formattedReportTotalBalances, $columns);
345
     }
277
     }
346
 
278
 
347
     private function calculateTrialBalance(AccountCategory $category, int $endingBalance): array
279
     private function calculateTrialBalance(AccountCategory $category, int $endingBalance): array
348
     {
280
     {
349
-        if (in_array($category, [AccountCategory::Asset, AccountCategory::Expense], true)) {
281
+        if ($category->isNormalDebitBalance()) {
350
             if ($endingBalance >= 0) {
282
             if ($endingBalance >= 0) {
351
                 return ['debit_balance' => $endingBalance, 'credit_balance' => 0];
283
                 return ['debit_balance' => $endingBalance, 'credit_balance' => 0];
352
             }
284
             }

+ 107
- 296
composer.lock View File

497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.319.1",
500
+            "version": "3.320.2",
501
             "source": {
501
             "source": {
502
                 "type": "git",
502
                 "type": "git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "78d9f8823a5796e9188a4ddcd9ef2374e47d8b7f"
504
+                "reference": "dbae075b861316237d63418715f8bf4bfdd9d33d"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/78d9f8823a5796e9188a4ddcd9ef2374e47d8b7f",
509
-                "reference": "78d9f8823a5796e9188a4ddcd9ef2374e47d8b7f",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/dbae075b861316237d63418715f8bf4bfdd9d33d",
509
+                "reference": "dbae075b861316237d63418715f8bf4bfdd9d33d",
510
                 "shasum": ""
510
                 "shasum": ""
511
             },
511
             },
512
             "require": {
512
             "require": {
589
             "support": {
589
             "support": {
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.319.1"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.320.2"
593
             },
593
             },
594
-            "time": "2024-08-08T18:05:03+00:00"
594
+            "time": "2024-08-16T18:06:17+00:00"
595
         },
595
         },
596
         {
596
         {
597
             "name": "aws/aws-sdk-php-laravel",
597
             "name": "aws/aws-sdk-php-laravel",
897
         },
897
         },
898
         {
898
         {
899
             "name": "blade-ui-kit/blade-icons",
899
             "name": "blade-ui-kit/blade-icons",
900
-            "version": "1.7.0",
900
+            "version": "1.7.1",
901
             "source": {
901
             "source": {
902
                 "type": "git",
902
                 "type": "git",
903
                 "url": "https://github.com/blade-ui-kit/blade-icons.git",
903
                 "url": "https://github.com/blade-ui-kit/blade-icons.git",
904
-                "reference": "74275f44c71e815b85bf7cea66e3bf98c57fb7e4"
904
+                "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595"
905
             },
905
             },
906
             "dist": {
906
             "dist": {
907
                 "type": "zip",
907
                 "type": "zip",
908
-                "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/74275f44c71e815b85bf7cea66e3bf98c57fb7e4",
909
-                "reference": "74275f44c71e815b85bf7cea66e3bf98c57fb7e4",
908
+                "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/8f787baf09d88cdfd6ec4dbaba11ebfa885f0595",
909
+                "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595",
910
                 "shasum": ""
910
                 "shasum": ""
911
             },
911
             },
912
             "require": {
912
             "require": {
974
                     "type": "paypal"
974
                     "type": "paypal"
975
                 }
975
                 }
976
             ],
976
             ],
977
-            "time": "2024-07-29T21:49:30+00:00"
977
+            "time": "2024-08-14T14:25:11+00:00"
978
         },
978
         },
979
         {
979
         {
980
             "name": "brick/math",
980
             "name": "brick/math",
1038
         },
1038
         },
1039
         {
1039
         {
1040
             "name": "carbonphp/carbon-doctrine-types",
1040
             "name": "carbonphp/carbon-doctrine-types",
1041
-            "version": "2.1.0",
1041
+            "version": "3.2.0",
1042
             "source": {
1042
             "source": {
1043
                 "type": "git",
1043
                 "type": "git",
1044
                 "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
1044
                 "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
1045
-                "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb"
1045
+                "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d"
1046
             },
1046
             },
1047
             "dist": {
1047
             "dist": {
1048
                 "type": "zip",
1048
                 "type": "zip",
1049
-                "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb",
1050
-                "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb",
1049
+                "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
1050
+                "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d",
1051
                 "shasum": ""
1051
                 "shasum": ""
1052
             },
1052
             },
1053
             "require": {
1053
             "require": {
1054
-                "php": "^7.4 || ^8.0"
1054
+                "php": "^8.1"
1055
             },
1055
             },
1056
             "conflict": {
1056
             "conflict": {
1057
-                "doctrine/dbal": "<3.7.0 || >=4.0.0"
1057
+                "doctrine/dbal": "<4.0.0 || >=5.0.0"
1058
             },
1058
             },
1059
             "require-dev": {
1059
             "require-dev": {
1060
-                "doctrine/dbal": "^3.7.0",
1060
+                "doctrine/dbal": "^4.0.0",
1061
                 "nesbot/carbon": "^2.71.0 || ^3.0.0",
1061
                 "nesbot/carbon": "^2.71.0 || ^3.0.0",
1062
                 "phpunit/phpunit": "^10.3"
1062
                 "phpunit/phpunit": "^10.3"
1063
             },
1063
             },
1087
             ],
1087
             ],
1088
             "support": {
1088
             "support": {
1089
                 "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
1089
                 "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
1090
-                "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0"
1090
+                "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0"
1091
             },
1091
             },
1092
             "funding": [
1092
             "funding": [
1093
                 {
1093
                 {
1103
                     "type": "tidelift"
1103
                     "type": "tidelift"
1104
                 }
1104
                 }
1105
             ],
1105
             ],
1106
-            "time": "2023-12-11T17:09:12+00:00"
1106
+            "time": "2024-02-09T16:56:22+00:00"
1107
         },
1107
         },
1108
         {
1108
         {
1109
             "name": "danharrin/date-format-converter",
1109
             "name": "danharrin/date-format-converter",
1285
             },
1285
             },
1286
             "time": "2024-07-08T12:26:09+00:00"
1286
             "time": "2024-07-08T12:26:09+00:00"
1287
         },
1287
         },
1288
-        {
1289
-            "name": "doctrine/cache",
1290
-            "version": "2.2.0",
1291
-            "source": {
1292
-                "type": "git",
1293
-                "url": "https://github.com/doctrine/cache.git",
1294
-                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
1295
-            },
1296
-            "dist": {
1297
-                "type": "zip",
1298
-                "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
1299
-                "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
1300
-                "shasum": ""
1301
-            },
1302
-            "require": {
1303
-                "php": "~7.1 || ^8.0"
1304
-            },
1305
-            "conflict": {
1306
-                "doctrine/common": ">2.2,<2.4"
1307
-            },
1308
-            "require-dev": {
1309
-                "cache/integration-tests": "dev-master",
1310
-                "doctrine/coding-standard": "^9",
1311
-                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
1312
-                "psr/cache": "^1.0 || ^2.0 || ^3.0",
1313
-                "symfony/cache": "^4.4 || ^5.4 || ^6",
1314
-                "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
1315
-            },
1316
-            "type": "library",
1317
-            "autoload": {
1318
-                "psr-4": {
1319
-                    "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
1320
-                }
1321
-            },
1322
-            "notification-url": "https://packagist.org/downloads/",
1323
-            "license": [
1324
-                "MIT"
1325
-            ],
1326
-            "authors": [
1327
-                {
1328
-                    "name": "Guilherme Blanco",
1329
-                    "email": "guilhermeblanco@gmail.com"
1330
-                },
1331
-                {
1332
-                    "name": "Roman Borschel",
1333
-                    "email": "roman@code-factory.org"
1334
-                },
1335
-                {
1336
-                    "name": "Benjamin Eberlei",
1337
-                    "email": "kontakt@beberlei.de"
1338
-                },
1339
-                {
1340
-                    "name": "Jonathan Wage",
1341
-                    "email": "jonwage@gmail.com"
1342
-                },
1343
-                {
1344
-                    "name": "Johannes Schmitt",
1345
-                    "email": "schmittjoh@gmail.com"
1346
-                }
1347
-            ],
1348
-            "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
1349
-            "homepage": "https://www.doctrine-project.org/projects/cache.html",
1350
-            "keywords": [
1351
-                "abstraction",
1352
-                "apcu",
1353
-                "cache",
1354
-                "caching",
1355
-                "couchdb",
1356
-                "memcached",
1357
-                "php",
1358
-                "redis",
1359
-                "xcache"
1360
-            ],
1361
-            "support": {
1362
-                "issues": "https://github.com/doctrine/cache/issues",
1363
-                "source": "https://github.com/doctrine/cache/tree/2.2.0"
1364
-            },
1365
-            "funding": [
1366
-                {
1367
-                    "url": "https://www.doctrine-project.org/sponsorship.html",
1368
-                    "type": "custom"
1369
-                },
1370
-                {
1371
-                    "url": "https://www.patreon.com/phpdoctrine",
1372
-                    "type": "patreon"
1373
-                },
1374
-                {
1375
-                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
1376
-                    "type": "tidelift"
1377
-                }
1378
-            ],
1379
-            "time": "2022-05-20T20:07:39+00:00"
1380
-        },
1381
         {
1288
         {
1382
             "name": "doctrine/dbal",
1289
             "name": "doctrine/dbal",
1383
-            "version": "3.8.7",
1290
+            "version": "4.1.0",
1384
             "source": {
1291
             "source": {
1385
                 "type": "git",
1292
                 "type": "git",
1386
                 "url": "https://github.com/doctrine/dbal.git",
1293
                 "url": "https://github.com/doctrine/dbal.git",
1387
-                "reference": "2093d670ca17f634f3c095ec10a20687eccebd99"
1294
+                "reference": "2377cd41609aa51bee822c8d207317a3f363a558"
1388
             },
1295
             },
1389
             "dist": {
1296
             "dist": {
1390
                 "type": "zip",
1297
                 "type": "zip",
1391
-                "url": "https://api.github.com/repos/doctrine/dbal/zipball/2093d670ca17f634f3c095ec10a20687eccebd99",
1392
-                "reference": "2093d670ca17f634f3c095ec10a20687eccebd99",
1298
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/2377cd41609aa51bee822c8d207317a3f363a558",
1299
+                "reference": "2377cd41609aa51bee822c8d207317a3f363a558",
1393
                 "shasum": ""
1300
                 "shasum": ""
1394
             },
1301
             },
1395
             "require": {
1302
             "require": {
1396
-                "composer-runtime-api": "^2",
1397
-                "doctrine/cache": "^1.11|^2.0",
1398
                 "doctrine/deprecations": "^0.5.3|^1",
1303
                 "doctrine/deprecations": "^0.5.3|^1",
1399
-                "doctrine/event-manager": "^1|^2",
1400
-                "php": "^7.4 || ^8.0",
1304
+                "php": "^8.1",
1401
                 "psr/cache": "^1|^2|^3",
1305
                 "psr/cache": "^1|^2|^3",
1402
                 "psr/log": "^1|^2|^3"
1306
                 "psr/log": "^1|^2|^3"
1403
             },
1307
             },
1404
             "require-dev": {
1308
             "require-dev": {
1405
                 "doctrine/coding-standard": "12.0.0",
1309
                 "doctrine/coding-standard": "12.0.0",
1406
                 "fig/log-test": "^1",
1310
                 "fig/log-test": "^1",
1407
-                "jetbrains/phpstorm-stubs": "2023.1",
1311
+                "jetbrains/phpstorm-stubs": "2023.2",
1408
                 "phpstan/phpstan": "1.11.7",
1312
                 "phpstan/phpstan": "1.11.7",
1313
+                "phpstan/phpstan-phpunit": "1.4.0",
1409
                 "phpstan/phpstan-strict-rules": "^1.6",
1314
                 "phpstan/phpstan-strict-rules": "^1.6",
1410
-                "phpunit/phpunit": "9.6.20",
1411
-                "psalm/plugin-phpunit": "0.18.4",
1315
+                "phpunit/phpunit": "10.5.28",
1316
+                "psalm/plugin-phpunit": "0.19.0",
1412
                 "slevomat/coding-standard": "8.13.1",
1317
                 "slevomat/coding-standard": "8.13.1",
1413
                 "squizlabs/php_codesniffer": "3.10.2",
1318
                 "squizlabs/php_codesniffer": "3.10.2",
1414
-                "symfony/cache": "^5.4|^6.0|^7.0",
1415
-                "symfony/console": "^4.4|^5.4|^6.0|^7.0",
1416
-                "vimeo/psalm": "4.30.0"
1319
+                "symfony/cache": "^6.3.8|^7.0",
1320
+                "symfony/console": "^5.4|^6.3|^7.0",
1321
+                "vimeo/psalm": "5.24.0"
1417
             },
1322
             },
1418
             "suggest": {
1323
             "suggest": {
1419
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
1324
                 "symfony/console": "For helpful console commands such as SQL execution and import of files."
1420
             },
1325
             },
1421
-            "bin": [
1422
-                "bin/doctrine-dbal"
1423
-            ],
1424
             "type": "library",
1326
             "type": "library",
1425
             "autoload": {
1327
             "autoload": {
1426
                 "psr-4": {
1328
                 "psr-4": {
1473
             ],
1375
             ],
1474
             "support": {
1376
             "support": {
1475
                 "issues": "https://github.com/doctrine/dbal/issues",
1377
                 "issues": "https://github.com/doctrine/dbal/issues",
1476
-                "source": "https://github.com/doctrine/dbal/tree/3.8.7"
1378
+                "source": "https://github.com/doctrine/dbal/tree/4.1.0"
1477
             },
1379
             },
1478
             "funding": [
1380
             "funding": [
1479
                 {
1381
                 {
1489
                     "type": "tidelift"
1391
                     "type": "tidelift"
1490
                 }
1392
                 }
1491
             ],
1393
             ],
1492
-            "time": "2024-08-07T11:57:25+00:00"
1394
+            "time": "2024-08-15T07:37:07+00:00"
1493
         },
1395
         },
1494
         {
1396
         {
1495
             "name": "doctrine/deprecations",
1397
             "name": "doctrine/deprecations",
1538
             },
1440
             },
1539
             "time": "2024-01-30T19:34:25+00:00"
1441
             "time": "2024-01-30T19:34:25+00:00"
1540
         },
1442
         },
1541
-        {
1542
-            "name": "doctrine/event-manager",
1543
-            "version": "2.0.1",
1544
-            "source": {
1545
-                "type": "git",
1546
-                "url": "https://github.com/doctrine/event-manager.git",
1547
-                "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e"
1548
-            },
1549
-            "dist": {
1550
-                "type": "zip",
1551
-                "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e",
1552
-                "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e",
1553
-                "shasum": ""
1554
-            },
1555
-            "require": {
1556
-                "php": "^8.1"
1557
-            },
1558
-            "conflict": {
1559
-                "doctrine/common": "<2.9"
1560
-            },
1561
-            "require-dev": {
1562
-                "doctrine/coding-standard": "^12",
1563
-                "phpstan/phpstan": "^1.8.8",
1564
-                "phpunit/phpunit": "^10.5",
1565
-                "vimeo/psalm": "^5.24"
1566
-            },
1567
-            "type": "library",
1568
-            "autoload": {
1569
-                "psr-4": {
1570
-                    "Doctrine\\Common\\": "src"
1571
-                }
1572
-            },
1573
-            "notification-url": "https://packagist.org/downloads/",
1574
-            "license": [
1575
-                "MIT"
1576
-            ],
1577
-            "authors": [
1578
-                {
1579
-                    "name": "Guilherme Blanco",
1580
-                    "email": "guilhermeblanco@gmail.com"
1581
-                },
1582
-                {
1583
-                    "name": "Roman Borschel",
1584
-                    "email": "roman@code-factory.org"
1585
-                },
1586
-                {
1587
-                    "name": "Benjamin Eberlei",
1588
-                    "email": "kontakt@beberlei.de"
1589
-                },
1590
-                {
1591
-                    "name": "Jonathan Wage",
1592
-                    "email": "jonwage@gmail.com"
1593
-                },
1594
-                {
1595
-                    "name": "Johannes Schmitt",
1596
-                    "email": "schmittjoh@gmail.com"
1597
-                },
1598
-                {
1599
-                    "name": "Marco Pivetta",
1600
-                    "email": "ocramius@gmail.com"
1601
-                }
1602
-            ],
1603
-            "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
1604
-            "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
1605
-            "keywords": [
1606
-                "event",
1607
-                "event dispatcher",
1608
-                "event manager",
1609
-                "event system",
1610
-                "events"
1611
-            ],
1612
-            "support": {
1613
-                "issues": "https://github.com/doctrine/event-manager/issues",
1614
-                "source": "https://github.com/doctrine/event-manager/tree/2.0.1"
1615
-            },
1616
-            "funding": [
1617
-                {
1618
-                    "url": "https://www.doctrine-project.org/sponsorship.html",
1619
-                    "type": "custom"
1620
-                },
1621
-                {
1622
-                    "url": "https://www.patreon.com/phpdoctrine",
1623
-                    "type": "patreon"
1624
-                },
1625
-                {
1626
-                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
1627
-                    "type": "tidelift"
1628
-                }
1629
-            ],
1630
-            "time": "2024-05-22T20:47:39+00:00"
1631
-        },
1632
         {
1443
         {
1633
             "name": "doctrine/inflector",
1444
             "name": "doctrine/inflector",
1634
             "version": "2.0.10",
1445
             "version": "2.0.10",
1927
         },
1738
         },
1928
         {
1739
         {
1929
             "name": "filament/actions",
1740
             "name": "filament/actions",
1930
-            "version": "v3.2.97",
1741
+            "version": "v3.2.102",
1931
             "source": {
1742
             "source": {
1932
                 "type": "git",
1743
                 "type": "git",
1933
                 "url": "https://github.com/filamentphp/actions.git",
1744
                 "url": "https://github.com/filamentphp/actions.git",
1934
-                "reference": "aff18fda397dbf3e9f449f9a9360f3359b154c0e"
1745
+                "reference": "1ce746a4a75975f1844c175201f1f03443c48c95"
1935
             },
1746
             },
1936
             "dist": {
1747
             "dist": {
1937
                 "type": "zip",
1748
                 "type": "zip",
1938
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/aff18fda397dbf3e9f449f9a9360f3359b154c0e",
1939
-                "reference": "aff18fda397dbf3e9f449f9a9360f3359b154c0e",
1749
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/1ce746a4a75975f1844c175201f1f03443c48c95",
1750
+                "reference": "1ce746a4a75975f1844c175201f1f03443c48c95",
1940
                 "shasum": ""
1751
                 "shasum": ""
1941
             },
1752
             },
1942
             "require": {
1753
             "require": {
1976
                 "issues": "https://github.com/filamentphp/filament/issues",
1787
                 "issues": "https://github.com/filamentphp/filament/issues",
1977
                 "source": "https://github.com/filamentphp/filament"
1788
                 "source": "https://github.com/filamentphp/filament"
1978
             },
1789
             },
1979
-            "time": "2024-07-31T11:53:04+00:00"
1790
+            "time": "2024-08-14T16:52:38+00:00"
1980
         },
1791
         },
1981
         {
1792
         {
1982
             "name": "filament/filament",
1793
             "name": "filament/filament",
1983
-            "version": "v3.2.97",
1794
+            "version": "v3.2.102",
1984
             "source": {
1795
             "source": {
1985
                 "type": "git",
1796
                 "type": "git",
1986
                 "url": "https://github.com/filamentphp/panels.git",
1797
                 "url": "https://github.com/filamentphp/panels.git",
1987
-                "reference": "9e0b750546a51fdbc67b1232f2399385587dcc9a"
1798
+                "reference": "99c703952af053e1ef22a4dd556eba589a574d87"
1988
             },
1799
             },
1989
             "dist": {
1800
             "dist": {
1990
                 "type": "zip",
1801
                 "type": "zip",
1991
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/9e0b750546a51fdbc67b1232f2399385587dcc9a",
1992
-                "reference": "9e0b750546a51fdbc67b1232f2399385587dcc9a",
1802
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/99c703952af053e1ef22a4dd556eba589a574d87",
1803
+                "reference": "99c703952af053e1ef22a4dd556eba589a574d87",
1993
                 "shasum": ""
1804
                 "shasum": ""
1994
             },
1805
             },
1995
             "require": {
1806
             "require": {
2041
                 "issues": "https://github.com/filamentphp/filament/issues",
1852
                 "issues": "https://github.com/filamentphp/filament/issues",
2042
                 "source": "https://github.com/filamentphp/filament"
1853
                 "source": "https://github.com/filamentphp/filament"
2043
             },
1854
             },
2044
-            "time": "2024-07-31T11:53:12+00:00"
1855
+            "time": "2024-08-14T16:52:48+00:00"
2045
         },
1856
         },
2046
         {
1857
         {
2047
             "name": "filament/forms",
1858
             "name": "filament/forms",
2048
-            "version": "v3.2.97",
1859
+            "version": "v3.2.102",
2049
             "source": {
1860
             "source": {
2050
                 "type": "git",
1861
                 "type": "git",
2051
                 "url": "https://github.com/filamentphp/forms.git",
1862
                 "url": "https://github.com/filamentphp/forms.git",
2052
-                "reference": "d679d30ae1c345740920e45b0334b5eacc76f7aa"
1863
+                "reference": "32ef8b049ac3c4577407cdc10e576082863f7e47"
2053
             },
1864
             },
2054
             "dist": {
1865
             "dist": {
2055
                 "type": "zip",
1866
                 "type": "zip",
2056
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/d679d30ae1c345740920e45b0334b5eacc76f7aa",
2057
-                "reference": "d679d30ae1c345740920e45b0334b5eacc76f7aa",
1867
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/32ef8b049ac3c4577407cdc10e576082863f7e47",
1868
+                "reference": "32ef8b049ac3c4577407cdc10e576082863f7e47",
2058
                 "shasum": ""
1869
                 "shasum": ""
2059
             },
1870
             },
2060
             "require": {
1871
             "require": {
2097
                 "issues": "https://github.com/filamentphp/filament/issues",
1908
                 "issues": "https://github.com/filamentphp/filament/issues",
2098
                 "source": "https://github.com/filamentphp/filament"
1909
                 "source": "https://github.com/filamentphp/filament"
2099
             },
1910
             },
2100
-            "time": "2024-07-31T11:53:08+00:00"
1911
+            "time": "2024-08-15T19:37:09+00:00"
2101
         },
1912
         },
2102
         {
1913
         {
2103
             "name": "filament/infolists",
1914
             "name": "filament/infolists",
2104
-            "version": "v3.2.97",
1915
+            "version": "v3.2.102",
2105
             "source": {
1916
             "source": {
2106
                 "type": "git",
1917
                 "type": "git",
2107
                 "url": "https://github.com/filamentphp/infolists.git",
1918
                 "url": "https://github.com/filamentphp/infolists.git",
2108
-                "reference": "af2266e0cf9d26e88ea6153d608f11aa9cebb59e"
1919
+                "reference": "96403f2842e4c485f32110e4456b7a3bbcb1e835"
2109
             },
1920
             },
2110
             "dist": {
1921
             "dist": {
2111
                 "type": "zip",
1922
                 "type": "zip",
2112
-                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/af2266e0cf9d26e88ea6153d608f11aa9cebb59e",
2113
-                "reference": "af2266e0cf9d26e88ea6153d608f11aa9cebb59e",
1923
+                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/96403f2842e4c485f32110e4456b7a3bbcb1e835",
1924
+                "reference": "96403f2842e4c485f32110e4456b7a3bbcb1e835",
2114
                 "shasum": ""
1925
                 "shasum": ""
2115
             },
1926
             },
2116
             "require": {
1927
             "require": {
2148
                 "issues": "https://github.com/filamentphp/filament/issues",
1959
                 "issues": "https://github.com/filamentphp/filament/issues",
2149
                 "source": "https://github.com/filamentphp/filament"
1960
                 "source": "https://github.com/filamentphp/filament"
2150
             },
1961
             },
2151
-            "time": "2024-07-31T11:53:07+00:00"
1962
+            "time": "2024-08-14T16:52:44+00:00"
2152
         },
1963
         },
2153
         {
1964
         {
2154
             "name": "filament/notifications",
1965
             "name": "filament/notifications",
2155
-            "version": "v3.2.97",
1966
+            "version": "v3.2.102",
2156
             "source": {
1967
             "source": {
2157
                 "type": "git",
1968
                 "type": "git",
2158
                 "url": "https://github.com/filamentphp/notifications.git",
1969
                 "url": "https://github.com/filamentphp/notifications.git",
2204
         },
2015
         },
2205
         {
2016
         {
2206
             "name": "filament/support",
2017
             "name": "filament/support",
2207
-            "version": "v3.2.97",
2018
+            "version": "v3.2.102",
2208
             "source": {
2019
             "source": {
2209
                 "type": "git",
2020
                 "type": "git",
2210
                 "url": "https://github.com/filamentphp/support.git",
2021
                 "url": "https://github.com/filamentphp/support.git",
2211
-                "reference": "94c5349b8fed252499314bd2149fadf96ddaf6d6"
2022
+                "reference": "7dc30bc972b5c29572bd285bfb7c3f24e909522a"
2212
             },
2023
             },
2213
             "dist": {
2024
             "dist": {
2214
                 "type": "zip",
2025
                 "type": "zip",
2215
-                "url": "https://api.github.com/repos/filamentphp/support/zipball/94c5349b8fed252499314bd2149fadf96ddaf6d6",
2216
-                "reference": "94c5349b8fed252499314bd2149fadf96ddaf6d6",
2026
+                "url": "https://api.github.com/repos/filamentphp/support/zipball/7dc30bc972b5c29572bd285bfb7c3f24e909522a",
2027
+                "reference": "7dc30bc972b5c29572bd285bfb7c3f24e909522a",
2217
                 "shasum": ""
2028
                 "shasum": ""
2218
             },
2029
             },
2219
             "require": {
2030
             "require": {
2220
                 "blade-ui-kit/blade-heroicons": "^2.2.1",
2031
                 "blade-ui-kit/blade-heroicons": "^2.2.1",
2221
-                "doctrine/dbal": "^3.2",
2032
+                "doctrine/dbal": "^3.2|^4.0",
2222
                 "ext-intl": "*",
2033
                 "ext-intl": "*",
2223
                 "illuminate/contracts": "^10.45|^11.0",
2034
                 "illuminate/contracts": "^10.45|^11.0",
2224
                 "illuminate/support": "^10.45|^11.0",
2035
                 "illuminate/support": "^10.45|^11.0",
2225
                 "illuminate/view": "^10.45|^11.0",
2036
                 "illuminate/view": "^10.45|^11.0",
2037
+                "kirschbaum-development/eloquent-power-joins": "^3.0",
2226
                 "livewire/livewire": "^3.4.10",
2038
                 "livewire/livewire": "^3.4.10",
2227
                 "php": "^8.1",
2039
                 "php": "^8.1",
2228
                 "ryangjchandler/blade-capture-directive": "^0.2|^0.3|^1.0",
2040
                 "ryangjchandler/blade-capture-directive": "^0.2|^0.3|^1.0",
2258
                 "issues": "https://github.com/filamentphp/filament/issues",
2070
                 "issues": "https://github.com/filamentphp/filament/issues",
2259
                 "source": "https://github.com/filamentphp/filament"
2071
                 "source": "https://github.com/filamentphp/filament"
2260
             },
2072
             },
2261
-            "time": "2024-07-31T11:53:25+00:00"
2073
+            "time": "2024-08-13T12:36:11+00:00"
2262
         },
2074
         },
2263
         {
2075
         {
2264
             "name": "filament/tables",
2076
             "name": "filament/tables",
2265
-            "version": "v3.2.97",
2077
+            "version": "v3.2.102",
2266
             "source": {
2078
             "source": {
2267
                 "type": "git",
2079
                 "type": "git",
2268
                 "url": "https://github.com/filamentphp/tables.git",
2080
                 "url": "https://github.com/filamentphp/tables.git",
2269
-                "reference": "0e6e96bde5337b26944ce3a657ae6755bef82d1e"
2081
+                "reference": "072592eba6d29d5f82e2cacfaf6ec7b4309d66da"
2270
             },
2082
             },
2271
             "dist": {
2083
             "dist": {
2272
                 "type": "zip",
2084
                 "type": "zip",
2273
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/0e6e96bde5337b26944ce3a657ae6755bef82d1e",
2274
-                "reference": "0e6e96bde5337b26944ce3a657ae6755bef82d1e",
2085
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/072592eba6d29d5f82e2cacfaf6ec7b4309d66da",
2086
+                "reference": "072592eba6d29d5f82e2cacfaf6ec7b4309d66da",
2275
                 "shasum": ""
2087
                 "shasum": ""
2276
             },
2088
             },
2277
             "require": {
2089
             "require": {
2284
                 "illuminate/filesystem": "^10.45|^11.0",
2096
                 "illuminate/filesystem": "^10.45|^11.0",
2285
                 "illuminate/support": "^10.45|^11.0",
2097
                 "illuminate/support": "^10.45|^11.0",
2286
                 "illuminate/view": "^10.45|^11.0",
2098
                 "illuminate/view": "^10.45|^11.0",
2287
-                "kirschbaum-development/eloquent-power-joins": "^3.0",
2288
                 "php": "^8.1",
2099
                 "php": "^8.1",
2289
                 "spatie/laravel-package-tools": "^1.9"
2100
                 "spatie/laravel-package-tools": "^1.9"
2290
             },
2101
             },
2311
                 "issues": "https://github.com/filamentphp/filament/issues",
2122
                 "issues": "https://github.com/filamentphp/filament/issues",
2312
                 "source": "https://github.com/filamentphp/filament"
2123
                 "source": "https://github.com/filamentphp/filament"
2313
             },
2124
             },
2314
-            "time": "2024-07-31T11:53:24+00:00"
2125
+            "time": "2024-08-12T16:38:51+00:00"
2315
         },
2126
         },
2316
         {
2127
         {
2317
             "name": "filament/widgets",
2128
             "name": "filament/widgets",
2318
-            "version": "v3.2.97",
2129
+            "version": "v3.2.102",
2319
             "source": {
2130
             "source": {
2320
                 "type": "git",
2131
                 "type": "git",
2321
                 "url": "https://github.com/filamentphp/widgets.git",
2132
                 "url": "https://github.com/filamentphp/widgets.git",
3697
         },
3508
         },
3698
         {
3509
         {
3699
             "name": "league/commonmark",
3510
             "name": "league/commonmark",
3700
-            "version": "2.5.1",
3511
+            "version": "2.5.3",
3701
             "source": {
3512
             "source": {
3702
                 "type": "git",
3513
                 "type": "git",
3703
                 "url": "https://github.com/thephpleague/commonmark.git",
3514
                 "url": "https://github.com/thephpleague/commonmark.git",
3704
-                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c"
3515
+                "reference": "b650144166dfa7703e62a22e493b853b58d874b0"
3705
             },
3516
             },
3706
             "dist": {
3517
             "dist": {
3707
                 "type": "zip",
3518
                 "type": "zip",
3708
-                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c",
3709
-                "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c",
3519
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0",
3520
+                "reference": "b650144166dfa7703e62a22e493b853b58d874b0",
3710
                 "shasum": ""
3521
                 "shasum": ""
3711
             },
3522
             },
3712
             "require": {
3523
             "require": {
3719
             },
3530
             },
3720
             "require-dev": {
3531
             "require-dev": {
3721
                 "cebe/markdown": "^1.0",
3532
                 "cebe/markdown": "^1.0",
3722
-                "commonmark/cmark": "0.31.0",
3723
-                "commonmark/commonmark.js": "0.31.0",
3533
+                "commonmark/cmark": "0.31.1",
3534
+                "commonmark/commonmark.js": "0.31.1",
3724
                 "composer/package-versions-deprecated": "^1.8",
3535
                 "composer/package-versions-deprecated": "^1.8",
3725
                 "embed/embed": "^4.4",
3536
                 "embed/embed": "^4.4",
3726
                 "erusev/parsedown": "^1.0",
3537
                 "erusev/parsedown": "^1.0",
3799
                     "type": "tidelift"
3610
                     "type": "tidelift"
3800
                 }
3611
                 }
3801
             ],
3612
             ],
3802
-            "time": "2024-07-24T12:52:09+00:00"
3613
+            "time": "2024-08-16T11:46:16+00:00"
3803
         },
3614
         },
3804
         {
3615
         {
3805
             "name": "league/config",
3616
             "name": "league/config",
5529
         },
5340
         },
5530
         {
5341
         {
5531
             "name": "phpseclib/phpseclib",
5342
             "name": "phpseclib/phpseclib",
5532
-            "version": "3.0.39",
5343
+            "version": "3.0.41",
5533
             "source": {
5344
             "source": {
5534
                 "type": "git",
5345
                 "type": "git",
5535
                 "url": "https://github.com/phpseclib/phpseclib.git",
5346
                 "url": "https://github.com/phpseclib/phpseclib.git",
5536
-                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485"
5347
+                "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb"
5537
             },
5348
             },
5538
             "dist": {
5349
             "dist": {
5539
                 "type": "zip",
5350
                 "type": "zip",
5540
-                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/211ebc399c6e73c225a018435fe5ae209d1d1485",
5541
-                "reference": "211ebc399c6e73c225a018435fe5ae209d1d1485",
5351
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/621c73f7dcb310b61de34d1da4c4204e8ace6ceb",
5352
+                "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb",
5542
                 "shasum": ""
5353
                 "shasum": ""
5543
             },
5354
             },
5544
             "require": {
5355
             "require": {
5619
             ],
5430
             ],
5620
             "support": {
5431
             "support": {
5621
                 "issues": "https://github.com/phpseclib/phpseclib/issues",
5432
                 "issues": "https://github.com/phpseclib/phpseclib/issues",
5622
-                "source": "https://github.com/phpseclib/phpseclib/tree/3.0.39"
5433
+                "source": "https://github.com/phpseclib/phpseclib/tree/3.0.41"
5623
             },
5434
             },
5624
             "funding": [
5435
             "funding": [
5625
                 {
5436
                 {
5635
                     "type": "tidelift"
5446
                     "type": "tidelift"
5636
                 }
5447
                 }
5637
             ],
5448
             ],
5638
-            "time": "2024-06-24T06:27:33+00:00"
5449
+            "time": "2024-08-12T00:13:54+00:00"
5639
         },
5450
         },
5640
         {
5451
         {
5641
             "name": "psr/cache",
5452
             "name": "psr/cache",
10671
         },
10482
         },
10672
         {
10483
         {
10673
             "name": "phpunit/phpunit",
10484
             "name": "phpunit/phpunit",
10674
-            "version": "10.5.29",
10485
+            "version": "10.5.30",
10675
             "source": {
10486
             "source": {
10676
                 "type": "git",
10487
                 "type": "git",
10677
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
10488
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
10678
-                "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f"
10489
+                "reference": "b15524febac0153876b4ba9aab3326c2ee94c897"
10679
             },
10490
             },
10680
             "dist": {
10491
             "dist": {
10681
                 "type": "zip",
10492
                 "type": "zip",
10682
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e9e80872b4e8064401788ee8a32d40b4455318f",
10683
-                "reference": "8e9e80872b4e8064401788ee8a32d40b4455318f",
10493
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b15524febac0153876b4ba9aab3326c2ee94c897",
10494
+                "reference": "b15524febac0153876b4ba9aab3326c2ee94c897",
10684
                 "shasum": ""
10495
                 "shasum": ""
10685
             },
10496
             },
10686
             "require": {
10497
             "require": {
10701
                 "phpunit/php-timer": "^6.0.0",
10512
                 "phpunit/php-timer": "^6.0.0",
10702
                 "sebastian/cli-parser": "^2.0.1",
10513
                 "sebastian/cli-parser": "^2.0.1",
10703
                 "sebastian/code-unit": "^2.0.0",
10514
                 "sebastian/code-unit": "^2.0.0",
10704
-                "sebastian/comparator": "^5.0.1",
10515
+                "sebastian/comparator": "^5.0.2",
10705
                 "sebastian/diff": "^5.1.1",
10516
                 "sebastian/diff": "^5.1.1",
10706
                 "sebastian/environment": "^6.1.0",
10517
                 "sebastian/environment": "^6.1.0",
10707
                 "sebastian/exporter": "^5.1.2",
10518
                 "sebastian/exporter": "^5.1.2",
10752
             "support": {
10563
             "support": {
10753
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
10564
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
10754
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
10565
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
10755
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.29"
10566
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.30"
10756
             },
10567
             },
10757
             "funding": [
10568
             "funding": [
10758
                 {
10569
                 {
10768
                     "type": "tidelift"
10579
                     "type": "tidelift"
10769
                 }
10580
                 }
10770
             ],
10581
             ],
10771
-            "time": "2024-07-30T11:08:00+00:00"
10582
+            "time": "2024-08-13T06:09:37+00:00"
10772
         },
10583
         },
10773
         {
10584
         {
10774
             "name": "rector/rector",
10585
             "name": "rector/rector",
10775
-            "version": "1.2.2",
10586
+            "version": "1.2.3",
10776
             "source": {
10587
             "source": {
10777
                 "type": "git",
10588
                 "type": "git",
10778
                 "url": "https://github.com/rectorphp/rector.git",
10589
                 "url": "https://github.com/rectorphp/rector.git",
10779
-                "reference": "044e6364017882d1e346da8690eeabc154da5495"
10590
+                "reference": "2433e95410aef1b34b15d7f1b6a134365a4ddb39"
10780
             },
10591
             },
10781
             "dist": {
10592
             "dist": {
10782
                 "type": "zip",
10593
                 "type": "zip",
10783
-                "url": "https://api.github.com/repos/rectorphp/rector/zipball/044e6364017882d1e346da8690eeabc154da5495",
10784
-                "reference": "044e6364017882d1e346da8690eeabc154da5495",
10594
+                "url": "https://api.github.com/repos/rectorphp/rector/zipball/2433e95410aef1b34b15d7f1b6a134365a4ddb39",
10595
+                "reference": "2433e95410aef1b34b15d7f1b6a134365a4ddb39",
10785
                 "shasum": ""
10596
                 "shasum": ""
10786
             },
10597
             },
10787
             "require": {
10598
             "require": {
10788
                 "php": "^7.2|^8.0",
10599
                 "php": "^7.2|^8.0",
10789
-                "phpstan/phpstan": "^1.11"
10600
+                "phpstan/phpstan": "^1.11.9"
10790
             },
10601
             },
10791
             "conflict": {
10602
             "conflict": {
10792
                 "rector/rector-doctrine": "*",
10603
                 "rector/rector-doctrine": "*",
10819
             ],
10630
             ],
10820
             "support": {
10631
             "support": {
10821
                 "issues": "https://github.com/rectorphp/rector/issues",
10632
                 "issues": "https://github.com/rectorphp/rector/issues",
10822
-                "source": "https://github.com/rectorphp/rector/tree/1.2.2"
10633
+                "source": "https://github.com/rectorphp/rector/tree/1.2.3"
10823
             },
10634
             },
10824
             "funding": [
10635
             "funding": [
10825
                 {
10636
                 {
10827
                     "type": "github"
10638
                     "type": "github"
10828
                 }
10639
                 }
10829
             ],
10640
             ],
10830
-            "time": "2024-07-25T07:44:34+00:00"
10641
+            "time": "2024-08-12T16:36:46+00:00"
10831
         },
10642
         },
10832
         {
10643
         {
10833
             "name": "sebastian/cli-parser",
10644
             "name": "sebastian/cli-parser",
10999
         },
10810
         },
11000
         {
10811
         {
11001
             "name": "sebastian/comparator",
10812
             "name": "sebastian/comparator",
11002
-            "version": "5.0.1",
10813
+            "version": "5.0.2",
11003
             "source": {
10814
             "source": {
11004
                 "type": "git",
10815
                 "type": "git",
11005
                 "url": "https://github.com/sebastianbergmann/comparator.git",
10816
                 "url": "https://github.com/sebastianbergmann/comparator.git",
11006
-                "reference": "2db5010a484d53ebf536087a70b4a5423c102372"
10817
+                "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53"
11007
             },
10818
             },
11008
             "dist": {
10819
             "dist": {
11009
                 "type": "zip",
10820
                 "type": "zip",
11010
-                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372",
11011
-                "reference": "2db5010a484d53ebf536087a70b4a5423c102372",
10821
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53",
10822
+                "reference": "2d3e04c3b4c1e84a5e7382221ad8883c8fbc4f53",
11012
                 "shasum": ""
10823
                 "shasum": ""
11013
             },
10824
             },
11014
             "require": {
10825
             "require": {
11019
                 "sebastian/exporter": "^5.0"
10830
                 "sebastian/exporter": "^5.0"
11020
             },
10831
             },
11021
             "require-dev": {
10832
             "require-dev": {
11022
-                "phpunit/phpunit": "^10.3"
10833
+                "phpunit/phpunit": "^10.4"
11023
             },
10834
             },
11024
             "type": "library",
10835
             "type": "library",
11025
             "extra": {
10836
             "extra": {
11064
             "support": {
10875
             "support": {
11065
                 "issues": "https://github.com/sebastianbergmann/comparator/issues",
10876
                 "issues": "https://github.com/sebastianbergmann/comparator/issues",
11066
                 "security": "https://github.com/sebastianbergmann/comparator/security/policy",
10877
                 "security": "https://github.com/sebastianbergmann/comparator/security/policy",
11067
-                "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1"
10878
+                "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.2"
11068
             },
10879
             },
11069
             "funding": [
10880
             "funding": [
11070
                 {
10881
                 {
11072
                     "type": "github"
10883
                     "type": "github"
11073
                 }
10884
                 }
11074
             ],
10885
             ],
11075
-            "time": "2023-08-14T13:18:12+00:00"
10886
+            "time": "2024-08-12T06:03:08+00:00"
11076
         },
10887
         },
11077
         {
10888
         {
11078
             "name": "sebastian/complexity",
10889
             "name": "sebastian/complexity",
12612
         },
12423
         },
12613
         {
12424
         {
12614
             "name": "zbateson/mail-mime-parser",
12425
             "name": "zbateson/mail-mime-parser",
12615
-            "version": "3.0.2",
12426
+            "version": "3.0.3",
12616
             "source": {
12427
             "source": {
12617
                 "type": "git",
12428
                 "type": "git",
12618
                 "url": "https://github.com/zbateson/mail-mime-parser.git",
12429
                 "url": "https://github.com/zbateson/mail-mime-parser.git",
12619
-                "reference": "9a240522ae5e4eaeb7bf72c9bc88fe89dfb014a3"
12430
+                "reference": "e0d4423fe27850c9dd301190767dbc421acc2f19"
12620
             },
12431
             },
12621
             "dist": {
12432
             "dist": {
12622
                 "type": "zip",
12433
                 "type": "zip",
12623
-                "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/9a240522ae5e4eaeb7bf72c9bc88fe89dfb014a3",
12624
-                "reference": "9a240522ae5e4eaeb7bf72c9bc88fe89dfb014a3",
12434
+                "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/e0d4423fe27850c9dd301190767dbc421acc2f19",
12435
+                "reference": "e0d4423fe27850c9dd301190767dbc421acc2f19",
12625
                 "shasum": ""
12436
                 "shasum": ""
12626
             },
12437
             },
12627
             "require": {
12438
             "require": {
12684
                     "type": "github"
12495
                     "type": "github"
12685
                 }
12496
                 }
12686
             ],
12497
             ],
12687
-            "time": "2024-05-01T16:49:29+00:00"
12498
+            "time": "2024-08-10T18:44:09+00:00"
12688
         },
12499
         },
12689
         {
12500
         {
12690
             "name": "zbateson/mb-wrapper",
12501
             "name": "zbateson/mb-wrapper",

+ 22
- 22
package-lock.json View File

900
             }
900
             }
901
         },
901
         },
902
         "node_modules/axios": {
902
         "node_modules/axios": {
903
-            "version": "1.7.3",
904
-            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz",
905
-            "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==",
903
+            "version": "1.7.4",
904
+            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
905
+            "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
906
             "dev": true,
906
             "dev": true,
907
             "license": "MIT",
907
             "license": "MIT",
908
             "dependencies": {
908
             "dependencies": {
1159
             "license": "MIT"
1159
             "license": "MIT"
1160
         },
1160
         },
1161
         "node_modules/electron-to-chromium": {
1161
         "node_modules/electron-to-chromium": {
1162
-            "version": "1.5.5",
1163
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz",
1164
-            "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==",
1162
+            "version": "1.5.10",
1163
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.10.tgz",
1164
+            "integrity": "sha512-C3RDERDjrNW262GCRvpoer3a0Ksd66CtgDLxMHhzShQ8fhL4kwnpVXsJPAKg9xJjIROXUbLBrvtOzVAjALMIWA==",
1165
             "dev": true,
1165
             "dev": true,
1166
             "license": "ISC"
1166
             "license": "ISC"
1167
         },
1167
         },
1968
             }
1968
             }
1969
         },
1969
         },
1970
         "node_modules/postcss-nested/node_modules/postcss-selector-parser": {
1970
         "node_modules/postcss-nested/node_modules/postcss-selector-parser": {
1971
-            "version": "6.1.1",
1972
-            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
1973
-            "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==",
1971
+            "version": "6.1.2",
1972
+            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
1973
+            "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
1974
             "dev": true,
1974
             "dev": true,
1975
             "license": "MIT",
1975
             "license": "MIT",
1976
             "dependencies": {
1976
             "dependencies": {
2056
             }
2056
             }
2057
         },
2057
         },
2058
         "node_modules/postcss-nesting/node_modules/postcss-selector-parser": {
2058
         "node_modules/postcss-nesting/node_modules/postcss-selector-parser": {
2059
-            "version": "6.1.1",
2060
-            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
2061
-            "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==",
2059
+            "version": "6.1.2",
2060
+            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
2061
+            "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
2062
             "dev": true,
2062
             "dev": true,
2063
             "license": "MIT",
2063
             "license": "MIT",
2064
             "dependencies": {
2064
             "dependencies": {
2417
             }
2417
             }
2418
         },
2418
         },
2419
         "node_modules/tailwindcss": {
2419
         "node_modules/tailwindcss": {
2420
-            "version": "3.4.9",
2421
-            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz",
2422
-            "integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==",
2420
+            "version": "3.4.10",
2421
+            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
2422
+            "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
2423
             "dev": true,
2423
             "dev": true,
2424
             "license": "MIT",
2424
             "license": "MIT",
2425
             "dependencies": {
2425
             "dependencies": {
2455
             }
2455
             }
2456
         },
2456
         },
2457
         "node_modules/tailwindcss/node_modules/postcss-selector-parser": {
2457
         "node_modules/tailwindcss/node_modules/postcss-selector-parser": {
2458
-            "version": "6.1.1",
2459
-            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
2460
-            "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==",
2458
+            "version": "6.1.2",
2459
+            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
2460
+            "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
2461
             "dev": true,
2461
             "dev": true,
2462
             "license": "MIT",
2462
             "license": "MIT",
2463
             "dependencies": {
2463
             "dependencies": {
2550
             "license": "MIT"
2550
             "license": "MIT"
2551
         },
2551
         },
2552
         "node_modules/vite": {
2552
         "node_modules/vite": {
2553
-            "version": "5.4.0",
2554
-            "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz",
2555
-            "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==",
2553
+            "version": "5.4.1",
2554
+            "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz",
2555
+            "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==",
2556
             "dev": true,
2556
             "dev": true,
2557
             "license": "MIT",
2557
             "license": "MIT",
2558
             "dependencies": {
2558
             "dependencies": {
2559
                 "esbuild": "^0.21.3",
2559
                 "esbuild": "^0.21.3",
2560
-                "postcss": "^8.4.40",
2560
+                "postcss": "^8.4.41",
2561
                 "rollup": "^4.13.0"
2561
                 "rollup": "^4.13.0"
2562
             },
2562
             },
2563
             "bin": {
2563
             "bin": {

Loading…
Cancel
Save