Andrew Wallo 1 年之前
父節點
當前提交
d798f61699
共有 29 個檔案被更改,包括 633 行新增422 行删除
  1. 14
    5
      app/Casts/TransactionAmountCast.php
  2. 11
    4
      app/Concerns/CompanyOwned.php
  3. 2
    13
      app/Concerns/HandlesResourceRecordCreation.php
  4. 5
    9
      app/Filament/Company/Clusters/Settings/Pages/CompanyDefault.php
  5. 1
    44
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource.php
  6. 0
    28
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/CreateCurrency.php
  7. 0
    28
      app/Filament/Company/Clusters/Settings/Resources/CurrencyResource/Pages/EditCurrency.php
  8. 6
    0
      app/Filament/Company/Pages/Accounting/Transactions.php
  9. 133
    0
      app/Filament/Company/Pages/Concerns/HasFiltersForm.php
  10. 3
    3
      app/Filament/Company/Pages/Reports/AccountBalances.php
  11. 5
    6
      app/Filament/Company/Pages/Reports/AccountTransactions.php
  12. 122
    16
      app/Filament/Company/Pages/Reports/BaseReportPage.php
  13. 4
    5
      app/Filament/Company/Pages/Reports/IncomeStatement.php
  14. 3
    3
      app/Filament/Company/Pages/Reports/TrialBalance.php
  15. 11
    4
      app/Filament/Company/Resources/Banking/AccountResource.php
  16. 21
    0
      app/Filament/Company/Resources/Banking/AccountResource/Pages/CreateAccount.php
  17. 17
    0
      app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php
  18. 2
    1
      app/Filament/Forms/Components/DateRangeSelect.php
  19. 27
    22
      app/Listeners/ConfigureCompanyDefault.php
  20. 0
    1
      app/Listeners/SyncAssociatedModels.php
  21. 15
    2
      app/Scopes/CurrentCompanyScope.php
  22. 2
    0
      app/Services/AccountService.php
  23. 99
    99
      composer.lock
  24. 87
    87
      package-lock.json
  25. 9
    11
      resources/css/filament/company/theme.css
  26. 1
    1
      resources/views/components/company/tables/reports/detailed-report.blade.php
  27. 14
    7
      resources/views/components/panel-shift-dropdown.blade.php
  28. 1
    1
      resources/views/filament/company/pages/reports/account-transactions.blade.php
  29. 18
    22
      resources/views/filament/company/pages/reports/income-statement.blade.php

+ 14
- 5
app/Casts/TransactionAmountCast.php 查看文件

11
 
11
 
12
 class TransactionAmountCast implements CastsAttributes
12
 class TransactionAmountCast implements CastsAttributes
13
 {
13
 {
14
+    private array $currencyCache = [];
15
+
14
     public function get(Model $model, string $key, mixed $value, array $attributes): string
16
     public function get(Model $model, string $key, mixed $value, array $attributes): string
15
     {
17
     {
16
         // Attempt to retrieve the currency code from the related bankAccount->account model
18
         // Attempt to retrieve the currency code from the related bankAccount->account model
17
-        $currency_code = $this->getCurrencyCodeFromBankAccountId($attributes['bank_account_id'] ?? null);
19
+        $currencyCode = $this->getCurrencyCodeFromBankAccountId($attributes['bank_account_id'] ?? null);
18
 
20
 
19
         if ($value !== null) {
21
         if ($value !== null) {
20
-            return CurrencyConverter::prepareForMutator($value, $currency_code);
22
+            return CurrencyConverter::prepareForMutator($value, $currencyCode);
21
         }
23
         }
22
 
24
 
23
         return '';
25
         return '';
28
      */
30
      */
29
     public function set(Model $model, string $key, mixed $value, array $attributes): int
31
     public function set(Model $model, string $key, mixed $value, array $attributes): int
30
     {
32
     {
31
-        $currency_code = $this->getCurrencyCodeFromBankAccountId($attributes['bank_account_id'] ?? null);
33
+        $currencyCode = $this->getCurrencyCodeFromBankAccountId($attributes['bank_account_id'] ?? null);
32
 
34
 
33
         if (is_numeric($value)) {
35
         if (is_numeric($value)) {
34
             $value = (string) $value;
36
             $value = (string) $value;
36
             throw new UnexpectedValueException('Expected string or numeric value for money cast');
38
             throw new UnexpectedValueException('Expected string or numeric value for money cast');
37
         }
39
         }
38
 
40
 
39
-        return CurrencyConverter::prepareForAccessor($value, $currency_code);
41
+        return CurrencyConverter::prepareForAccessor($value, $currencyCode);
40
     }
42
     }
41
 
43
 
42
     /**
44
     /**
49
             return CurrencyAccessor::getDefaultCurrency();
51
             return CurrencyAccessor::getDefaultCurrency();
50
         }
52
         }
51
 
53
 
54
+        if (isset($this->currencyCache[$bankAccountId])) {
55
+            return $this->currencyCache[$bankAccountId];
56
+        }
57
+
52
         $bankAccount = BankAccount::find($bankAccountId);
58
         $bankAccount = BankAccount::find($bankAccountId);
53
 
59
 
54
-        return $bankAccount?->account?->currency_code ?? CurrencyAccessor::getDefaultCurrency();
60
+        $currencyCode = $bankAccount?->account?->currency_code ?? CurrencyAccessor::getDefaultCurrency();
61
+        $this->currencyCache[$bankAccountId] = $currencyCode;
62
+
63
+        return $currencyCode;
55
     }
64
     }
56
 }
65
 }

+ 11
- 4
app/Concerns/CompanyOwned.php 查看文件

15
     {
15
     {
16
         static::creating(static function ($model) {
16
         static::creating(static function ($model) {
17
             if (empty($model->company_id)) {
17
             if (empty($model->company_id)) {
18
-                if (Auth::check() && Auth::user()->currentCompany) {
19
-                    $model->company_id = Auth::user()->currentCompany->id;
18
+                $companyId = session('current_company_id');
19
+
20
+                if (! $companyId && Auth::check() && Auth::user()->currentCompany) {
21
+                    $companyId = Auth::user()->currentCompany->id;
22
+                    session(['current_company_id' => $companyId]);
23
+                }
24
+
25
+                if ($companyId) {
26
+                    $model->company_id = $companyId;
20
                 } else {
27
                 } else {
21
-                    Log::info('CompanyOwned trait: No company_id set on model ' . get_class($model) . ' ' . $model->id);
28
+                    Log::error('CurrentCompanyScope: No company_id found for user ' . Auth::id());
22
 
29
 
23
-                    throw new ModelNotFoundException('CompanyOwned trait: No company_id set on model ' . get_class($model) . ' ' . $model->id);
30
+                    throw new ModelNotFoundException('CurrentCompanyScope: No company_id set in the session or on the user.');
24
                 }
31
                 }
25
             }
32
             }
26
         });
33
         });

+ 2
- 13
app/Concerns/HandlesResourceRecordCreation.php 查看文件

3
 namespace App\Concerns;
3
 namespace App\Concerns;
4
 
4
 
5
 use App\Models\User;
5
 use App\Models\User;
6
-use BackedEnum;
7
 use Illuminate\Database\Eloquent\Builder;
6
 use Illuminate\Database\Eloquent\Builder;
8
 use Illuminate\Database\Eloquent\Model;
7
 use Illuminate\Database\Eloquent\Model;
9
 
8
 
11
 {
10
 {
12
     protected function handleRecordCreationWithUniqueField(array $data, Model $model, User $user, ?string $uniqueField = null, ?array $evaluatedTypes = null): Model
11
     protected function handleRecordCreationWithUniqueField(array $data, Model $model, User $user, ?string $uniqueField = null, ?array $evaluatedTypes = null): Model
13
     {
12
     {
14
-        if (is_array($evaluatedTypes)) {
15
-            $evaluatedTypes = $this->ensureCreationEnumValues($evaluatedTypes);
16
-        }
17
-
18
-        if ($uniqueField && ! in_array($data[$uniqueField] ?? '', $evaluatedTypes ?? [], true)) {
13
+        // If evaluatedTypes is provided, ensure the unique field value is within the allowed types
14
+        if ($uniqueField && $evaluatedTypes && ! in_array($data[$uniqueField] ?? '', $evaluatedTypes, true)) {
19
             $data['enabled'] = false;
15
             $data['enabled'] = false;
20
             $instance = $model->newInstance($data);
16
             $instance = $model->newInstance($data);
21
             $instance->save();
17
             $instance->save();
43
         return $instance;
39
         return $instance;
44
     }
40
     }
45
 
41
 
46
-    private function ensureCreationEnumValues(array $evaluatedTypes): array
47
-    {
48
-        return array_map(static function ($type) {
49
-            return $type instanceof BackedEnum ? $type->value : $type;
50
-        }, $evaluatedTypes);
51
-    }
52
-
53
     private function toggleRecords(Builder $query, bool &$shouldBeEnabled): void
42
     private function toggleRecords(Builder $query, bool &$shouldBeEnabled): void
54
     {
43
     {
55
         if ($shouldBeEnabled) {
44
         if ($shouldBeEnabled) {

+ 5
- 9
app/Filament/Company/Clusters/Settings/Pages/CompanyDefault.php 查看文件

6
 use App\Filament\Company\Clusters\Settings;
6
 use App\Filament\Company\Clusters\Settings;
7
 use App\Models\Banking\BankAccount;
7
 use App\Models\Banking\BankAccount;
8
 use App\Models\Setting\CompanyDefault as CompanyDefaultModel;
8
 use App\Models\Setting\CompanyDefault as CompanyDefaultModel;
9
-use App\Models\Setting\Currency;
10
 use App\Models\Setting\Discount;
9
 use App\Models\Setting\Discount;
11
 use App\Models\Setting\Tax;
10
 use App\Models\Setting\Tax;
12
 use Filament\Actions\Action;
11
 use Filament\Actions\Action;
13
 use Filament\Actions\ActionGroup;
12
 use Filament\Actions\ActionGroup;
14
 use Filament\Forms\Components\Component;
13
 use Filament\Forms\Components\Component;
14
+use Filament\Forms\Components\Placeholder;
15
 use Filament\Forms\Components\Section;
15
 use Filament\Forms\Components\Section;
16
 use Filament\Forms\Components\Select;
16
 use Filament\Forms\Components\Select;
17
 use Filament\Forms\Form;
17
 use Filament\Forms\Form;
133
                     ->selectablePlaceholder(false)
133
                     ->selectablePlaceholder(false)
134
                     ->searchable()
134
                     ->searchable()
135
                     ->preload(),
135
                     ->preload(),
136
-                Select::make('currency_code')
137
-                    ->softRequired()
138
-                    ->localizeLabel('Currency')
139
-                    ->relationship('currency', 'name')
140
-                    ->getOptionLabelFromRecordUsing(static fn (Currency $record) => "{$record->code} {$record->symbol} - {$record->name}")
141
-                    ->saveRelationshipsUsing(null)
142
-                    ->searchable()
143
-                    ->preload(),
136
+                Placeholder::make('currency_code')
137
+                    ->label(translate('Currency'))
138
+                    ->hintIcon('heroicon-o-question-mark-circle', 'You cannot change this after your company has been created. You can still use other currencies for transactions.')
139
+                    ->content(static fn (CompanyDefaultModel $record) => "{$record->currency->code} {$record->currency->symbol} - {$record->currency->name}"),
144
             ])->columns();
140
             ])->columns();
145
     }
141
     }
146
 
142
 

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

19
 use Filament\Tables;
19
 use Filament\Tables;
20
 use Filament\Tables\Table;
20
 use Filament\Tables\Table;
21
 use Illuminate\Database\Eloquent\Collection;
21
 use Illuminate\Database\Eloquent\Collection;
22
-use Wallo\FilamentSelectify\Components\ToggleButton;
23
 
22
 
24
 class CurrencyResource extends Resource
23
 class CurrencyResource extends Resource
25
 {
24
 {
51
                             ->live()
50
                             ->live()
52
                             ->required()
51
                             ->required()
53
                             ->localizeLabel()
52
                             ->localizeLabel()
54
-                            ->hidden(static fn (Forms\Get $get, $state): bool => $get('enabled') && $state !== null)
55
                             ->afterStateUpdated(static function (Forms\Set $set, $state) {
53
                             ->afterStateUpdated(static function (Forms\Set $set, $state) {
56
                                 $fields = ['name', 'precision', 'symbol', 'symbol_first', 'decimal_mark', 'thousands_separator'];
54
                                 $fields = ['name', 'precision', 'symbol', 'symbol_first', 'decimal_mark', 'thousands_separator'];
57
 
55
 
71
 
69
 
72
                                 array_walk($fields, static fn ($field) => $set($field, $currencyDetails[$field] ?? null));
70
                                 array_walk($fields, static fn ($field) => $set($field, $currencyDetails[$field] ?? null));
73
                             }),
71
                             }),
74
-                        Forms\Components\TextInput::make('code')
75
-                            ->localizeLabel()
76
-                            ->hidden(static fn (Forms\Get $get): bool => ! ($get('enabled') && $get('code') !== null))
77
-                            ->disabled(static fn (Forms\Get $get): bool => $get('enabled'))
78
-                            ->dehydrated()
79
-                            ->required(),
80
                         Forms\Components\TextInput::make('name')
72
                         Forms\Components\TextInput::make('name')
81
                             ->localizeLabel()
73
                             ->localizeLabel()
82
                             ->maxLength(50)
74
                             ->maxLength(50)
86
                             ->rule('gt:0')
78
                             ->rule('gt:0')
87
                             ->live()
79
                             ->live()
88
                             ->localizeLabel()
80
                             ->localizeLabel()
89
-                            ->disabled(static fn (?CurrencyModel $record): bool => $record?->isEnabled() ?? false)
90
-                            ->dehydrated()
91
                             ->required(),
81
                             ->required(),
92
                         Forms\Components\Select::make('precision')
82
                         Forms\Components\Select::make('precision')
93
                             ->localizeLabel()
83
                             ->localizeLabel()
123
                                 };
113
                                 };
124
                             })
114
                             })
125
                             ->nullable(),
115
                             ->nullable(),
126
-                        ToggleButton::make('enabled')
127
-                            ->localizeLabel('Default')
128
-                            ->onLabel(CurrencyModel::enabledLabel())
129
-                            ->offLabel(CurrencyModel::disabledLabel())
130
-                            ->disabled(static fn (?CurrencyModel $record): bool => $record?->isEnabled() ?? false)
131
-                            ->dehydrated()
132
-                            ->live()
133
-                            ->afterStateUpdated(static function (Forms\Set $set, Forms\Get $get, $state) {
134
-                                $enabledState = (bool) $state;
135
-                                $code = $get('code');
136
-
137
-                                if (! $code) {
138
-                                    return;
139
-                                }
140
-
141
-                                if ($enabledState) {
142
-                                    $set('rate', 1);
143
-
144
-                                    return;
145
-                                }
146
-
147
-                                $forexEnabled = Forex::isEnabled();
148
-                                if ($forexEnabled) {
149
-                                    $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
150
-                                    $exchangeRate = Forex::getCachedExchangeRate($defaultCurrencyCode, $code);
151
-                                    if ($exchangeRate !== null) {
152
-                                        $set('rate', $exchangeRate);
153
-                                    }
154
-                                }
155
-                            }),
156
                     ])->columns(),
116
                     ])->columns(),
157
             ]);
117
             ]);
158
     }
118
     }
230
             ])
190
             ])
231
             ->checkIfRecordIsSelectableUsing(static function (CurrencyModel $record) {
191
             ->checkIfRecordIsSelectableUsing(static function (CurrencyModel $record) {
232
                 return $record->isDisabled();
192
                 return $record->isDisabled();
233
-            })
234
-            ->emptyStateActions([
235
-                Tables\Actions\CreateAction::make(),
236
-            ]);
193
+            });
237
     }
194
     }
238
 
195
 
239
     public static function getPages(): array
196
     public static function getPages(): array

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

2
 
2
 
3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
4
 
4
 
5
-use App\Concerns\HandlesResourceRecordCreation;
6
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
5
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
7
-use App\Models\Setting\Currency;
8
 use Filament\Resources\Pages\CreateRecord;
6
 use Filament\Resources\Pages\CreateRecord;
9
-use Filament\Support\Exceptions\Halt;
10
-use Illuminate\Database\Eloquent\Model;
11
-use Illuminate\Support\Facades\Auth;
12
 
7
 
13
 class CreateCurrency extends CreateRecord
8
 class CreateCurrency extends CreateRecord
14
 {
9
 {
15
-    use HandlesResourceRecordCreation;
16
-
17
     protected static string $resource = CurrencyResource::class;
10
     protected static string $resource = CurrencyResource::class;
18
 
11
 
19
     protected function getRedirectUrl(): string
12
     protected function getRedirectUrl(): string
20
     {
13
     {
21
         return $this->getResource()::getUrl('index');
14
         return $this->getResource()::getUrl('index');
22
     }
15
     }
23
-
24
-    protected function mutateFormDataBeforeCreate(array $data): array
25
-    {
26
-        $data['enabled'] = (bool) $data['enabled'];
27
-
28
-        return $data;
29
-    }
30
-
31
-    /**
32
-     * @throws Halt
33
-     */
34
-    protected function handleRecordCreation(array $data): Model
35
-    {
36
-        $user = Auth::user();
37
-
38
-        if (! $user) {
39
-            throw new Halt('No authenticated user found');
40
-        }
41
-
42
-        return $this->handleRecordCreationWithUniqueField($data, new Currency, $user);
43
-    }
44
 }
16
 }

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

2
 
2
 
3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
3
 namespace App\Filament\Company\Clusters\Settings\Resources\CurrencyResource\Pages;
4
 
4
 
5
-use App\Concerns\HandlesResourceRecordUpdate;
6
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
5
 use App\Filament\Company\Clusters\Settings\Resources\CurrencyResource;
7
-use App\Models\Setting\Currency;
8
 use Filament\Actions;
6
 use Filament\Actions;
9
 use Filament\Resources\Pages\EditRecord;
7
 use Filament\Resources\Pages\EditRecord;
10
-use Filament\Support\Exceptions\Halt;
11
-use Illuminate\Database\Eloquent\Model;
12
-use Illuminate\Support\Facades\Auth;
13
 
8
 
14
 class EditCurrency extends EditRecord
9
 class EditCurrency extends EditRecord
15
 {
10
 {
16
-    use HandlesResourceRecordUpdate;
17
-
18
     protected static string $resource = CurrencyResource::class;
11
     protected static string $resource = CurrencyResource::class;
19
 
12
 
20
     protected function getHeaderActions(): array
13
     protected function getHeaderActions(): array
28
     {
21
     {
29
         return $this->getResource()::getUrl('index');
22
         return $this->getResource()::getUrl('index');
30
     }
23
     }
31
-
32
-    protected function mutateFormDataBeforeSave(array $data): array
33
-    {
34
-        $data['enabled'] = (bool) $data['enabled'];
35
-
36
-        return $data;
37
-    }
38
-
39
-    /**
40
-     * @throws Halt
41
-     */
42
-    protected function handleRecordUpdate(Model | Currency $record, array $data): Model | Currency
43
-    {
44
-        $user = Auth::user();
45
-
46
-        if (! $user) {
47
-            throw new Halt('No authenticated user found');
48
-        }
49
-
50
-        return $this->handleRecordUpdateWithUniqueField($record, $data, $user);
51
-    }
52
 }
24
 }

+ 6
- 0
app/Filament/Company/Pages/Accounting/Transactions.php 查看文件

217
         return $table
217
         return $table
218
             ->query(static::getEloquentQuery())
218
             ->query(static::getEloquentQuery())
219
             ->modifyQueryUsing(function (Builder $query) {
219
             ->modifyQueryUsing(function (Builder $query) {
220
+                $query->with([
221
+                    'account',
222
+                    'bankAccount.account',
223
+                    'journalEntries.account',
224
+                ]);
225
+
220
                 if ($this->bankAccountIdFiltered !== 'all') {
226
                 if ($this->bankAccountIdFiltered !== 'all') {
221
                     $query->where('bank_account_id', $this->bankAccountIdFiltered);
227
                     $query->where('bank_account_id', $this->bankAccountIdFiltered);
222
                 }
228
                 }

+ 133
- 0
app/Filament/Company/Pages/Concerns/HasFiltersForm.php 查看文件

1
+<?php
2
+
3
+namespace App\Filament\Company\Pages\Concerns;
4
+
5
+use Filament\Actions\Action;
6
+use Filament\Forms\Form;
7
+use Illuminate\Support\Arr;
8
+use Illuminate\Support\Carbon;
9
+use Livewire\Attributes\Url;
10
+
11
+trait HasFiltersForm
12
+{
13
+    /**
14
+     * @var array<string, mixed> | null
15
+     */
16
+    #[Url(keep: true)]
17
+    public ?array $filters = null;
18
+
19
+    /**
20
+     * @var array<string, mixed> | null
21
+     */
22
+    public ?array $deferredFilters = null;
23
+
24
+    public function mountHasFiltersForm(): void
25
+    {
26
+        if (method_exists($this, 'loadDefaultDateRange')) {
27
+            $this->loadDefaultDateRange();
28
+        }
29
+
30
+        $this->initializeFilters();
31
+    }
32
+
33
+    public function initializeFilters(): void
34
+    {
35
+        if (! count($this->filters ?? [])) {
36
+            $this->filters = null;
37
+        }
38
+
39
+        $this->getFiltersForm()->fill($this->filters ?? []);
40
+
41
+        $this->applyFilters();
42
+    }
43
+
44
+    protected function getForms(): array
45
+    {
46
+        return [
47
+            'toggledTableColumnForm',
48
+            'filtersForm' => $this->getFiltersForm(),
49
+        ];
50
+    }
51
+
52
+    public function filtersForm(Form $form): Form
53
+    {
54
+        return $form;
55
+    }
56
+
57
+    public function getFiltersForm(): Form
58
+    {
59
+        return $this->filtersForm($this->makeForm()
60
+            ->statePath('deferredFilters'));
61
+    }
62
+
63
+    public function updatedFilters(): void
64
+    {
65
+        $this->deferredFilters = $this->filters;
66
+
67
+        $this->handleFilterUpdates();
68
+    }
69
+
70
+    protected function isValidDate($date): bool
71
+    {
72
+        return strtotime($date) !== false;
73
+    }
74
+
75
+    protected function handleFilterUpdates(): void
76
+    {
77
+        //
78
+    }
79
+
80
+    public function applyFilters(): void
81
+    {
82
+        $normalizedFilters = $this->deferredFilters;
83
+
84
+        $this->normalizeFilters($normalizedFilters);
85
+
86
+        $this->filters = $normalizedFilters;
87
+
88
+        $this->handleFilterUpdates();
89
+
90
+        if (method_exists($this, 'loadReportData')) {
91
+            $this->loadReportData();
92
+        }
93
+    }
94
+
95
+    protected function normalizeFilters(array &$filters): void
96
+    {
97
+        foreach ($filters as $name => &$value) {
98
+            if ($name === 'dateRange') {
99
+                unset($filters[$name]);
100
+            } elseif ($this->isValidDate($value)) {
101
+                $filters[$name] = Carbon::parse($value)->toDateString();
102
+            }
103
+        }
104
+    }
105
+
106
+    public function getFiltersApplyAction(): Action
107
+    {
108
+        return Action::make('applyFilters')
109
+            ->label(__('filament-tables::table.filters.actions.apply.label'))
110
+            ->action('applyFilters')
111
+            ->button();
112
+    }
113
+
114
+    public function getFilterState(string $name): mixed
115
+    {
116
+        return Arr::get($this->filters, $name);
117
+    }
118
+
119
+    public function setFilterState(string $name, mixed $value): void
120
+    {
121
+        Arr::set($this->filters, $name, $value);
122
+    }
123
+
124
+    public function getDeferredFilterState(string $name): mixed
125
+    {
126
+        return Arr::get($this->deferredFilters, $name);
127
+    }
128
+
129
+    public function setDeferredFilterState(string $name, mixed $value): void
130
+    {
131
+        Arr::set($this->deferredFilters, $name, $value);
132
+    }
133
+}

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

84
 
84
 
85
     protected function buildReport(array $columns): ReportDTO
85
     protected function buildReport(array $columns): ReportDTO
86
     {
86
     {
87
-        return $this->reportService->buildAccountBalanceReport($this->startDate, $this->endDate, $columns);
87
+        return $this->reportService->buildAccountBalanceReport($this->getFormattedStartDate(), $this->getFormattedEndDate(), $columns);
88
     }
88
     }
89
 
89
 
90
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
90
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
94
 
94
 
95
     public function exportCSV(): StreamedResponse
95
     public function exportCSV(): StreamedResponse
96
     {
96
     {
97
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->startDate, $this->endDate);
97
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
98
     }
98
     }
99
 
99
 
100
     public function exportPDF(): StreamedResponse
100
     public function exportPDF(): StreamedResponse
101
     {
101
     {
102
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->startDate, $this->endDate);
102
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
103
     }
103
     }
104
 }
104
 }

+ 5
- 6
app/Filament/Company/Pages/Reports/AccountTransactions.php 查看文件

34
     protected ExportService $exportService;
34
     protected ExportService $exportService;
35
 
35
 
36
     #[Url]
36
     #[Url]
37
-    public ?string $account_id = 'all';
37
+    public ?string $selectedAccount = 'all';
38
 
38
 
39
     public function boot(ReportService $reportService, ExportService $exportService): void
39
     public function boot(ReportService $reportService, ExportService $exportService): void
40
     {
40
     {
71
     {
71
     {
72
         return $form
72
         return $form
73
             ->columns(4)
73
             ->columns(4)
74
-            ->live()
75
             ->schema([
74
             ->schema([
76
-                Select::make('account_id')
75
+                Select::make('selectedAccount')
77
                     ->label('Account')
76
                     ->label('Account')
78
                     ->options($this->getAccountOptions())
77
                     ->options($this->getAccountOptions())
79
                     ->selectablePlaceholder(false)
78
                     ->selectablePlaceholder(false)
109
 
108
 
110
     protected function buildReport(array $columns): ReportDTO
109
     protected function buildReport(array $columns): ReportDTO
111
     {
110
     {
112
-        return $this->reportService->buildAccountTransactionsReport($this->startDate, $this->endDate, $columns, $this->account_id);
111
+        return $this->reportService->buildAccountTransactionsReport($this->getFormattedStartDate(), $this->getFormattedEndDate(), $columns, $this->selectedAccount);
113
     }
112
     }
114
 
113
 
115
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
114
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
119
 
118
 
120
     public function exportCSV(): StreamedResponse
119
     public function exportCSV(): StreamedResponse
121
     {
120
     {
122
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->startDate, $this->endDate);
121
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
123
     }
122
     }
124
 
123
 
125
     public function exportPDF(): StreamedResponse
124
     public function exportPDF(): StreamedResponse
126
     {
125
     {
127
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->startDate, $this->endDate);
126
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
128
     }
127
     }
129
 
128
 
130
     public function getEmptyStateHeading(): string | Htmlable
129
     public function getEmptyStateHeading(): string | Htmlable

+ 122
- 16
app/Filament/Company/Pages/Reports/BaseReportPage.php 查看文件

19
 use Filament\Support\Enums\IconPosition;
19
 use Filament\Support\Enums\IconPosition;
20
 use Filament\Support\Enums\IconSize;
20
 use Filament\Support\Enums\IconSize;
21
 use Filament\Support\Facades\FilamentIcon;
21
 use Filament\Support\Facades\FilamentIcon;
22
+use Illuminate\Support\Arr;
22
 use Illuminate\Support\Carbon;
23
 use Illuminate\Support\Carbon;
23
 use Livewire\Attributes\Computed;
24
 use Livewire\Attributes\Computed;
24
 use Livewire\Attributes\Session;
25
 use Livewire\Attributes\Session;
26
+use Livewire\Attributes\Url;
25
 use Symfony\Component\HttpFoundation\StreamedResponse;
27
 use Symfony\Component\HttpFoundation\StreamedResponse;
26
 
28
 
27
 abstract class BaseReportPage extends Page
29
 abstract class BaseReportPage extends Page
28
 {
30
 {
29
-    public string $startDate = '';
30
-
31
-    public string $endDate = '';
31
+    /**
32
+     * @var array<string, mixed> | null
33
+     */
34
+    #[Url(keep: true)]
35
+    public ?array $filters = null;
32
 
36
 
33
-    public string $dateRange = '';
37
+    /**
38
+     * @var array<string, mixed> | null
39
+     */
40
+    public ?array $deferredFilters = null;
34
 
41
 
35
     public string $fiscalYearStartDate = '';
42
     public string $fiscalYearStartDate = '';
36
 
43
 
62
 
69
 
63
         $this->loadDefaultDateRange();
70
         $this->loadDefaultDateRange();
64
 
71
 
72
+        $this->initializeFilters();
73
+
65
         $this->loadDefaultTableColumnToggleState();
74
         $this->loadDefaultTableColumnToggleState();
66
     }
75
     }
67
 
76
 
77
+    public function initializeFilters(): void
78
+    {
79
+        if (! count($this->filters ?? [])) {
80
+            $this->filters = null;
81
+        }
82
+
83
+        $this->getFiltersForm()->fill($this->filters);
84
+
85
+        $this->applyFilters();
86
+    }
87
+
68
     protected function getForms(): array
88
     protected function getForms(): array
69
     {
89
     {
70
         return [
90
         return [
71
             'toggleTableColumnForm',
91
             'toggleTableColumnForm',
72
-            'form',
92
+            'filtersForm' => $this->getFiltersForm(),
73
         ];
93
         ];
74
     }
94
     }
75
 
95
 
96
+    public function filtersForm(Form $form): Form
97
+    {
98
+        return $form;
99
+    }
100
+
101
+    public function getFiltersForm(): Form
102
+    {
103
+        return $this->filtersForm($this->makeForm()
104
+            ->statePath('deferredFilters'));
105
+    }
106
+
107
+    public function updatedFilters(): void
108
+    {
109
+        $this->deferredFilters = $this->filters;
110
+
111
+        $this->handleFilterUpdates();
112
+    }
113
+
114
+    protected function isValidDate($date): bool
115
+    {
116
+        return strtotime($date) !== false;
117
+    }
118
+
119
+    protected function handleFilterUpdates(): void
120
+    {
121
+        //
122
+    }
123
+
124
+    public function applyFilters(): void
125
+    {
126
+        $normalizedFilters = $this->deferredFilters;
127
+
128
+        $this->normalizeFilters($normalizedFilters);
129
+
130
+        $this->filters = $normalizedFilters;
131
+
132
+        $this->handleFilterUpdates();
133
+
134
+        $this->loadReportData();
135
+    }
136
+
137
+    protected function normalizeFilters(array &$filters): void
138
+    {
139
+        foreach ($filters as $name => &$value) {
140
+            if ($name === 'dateRange') {
141
+                unset($filters[$name]);
142
+            } elseif ($this->isValidDate($value)) {
143
+                $filters[$name] = Carbon::parse($value)->toDateString();
144
+            }
145
+        }
146
+    }
147
+
148
+    public function getFiltersApplyAction(): Action
149
+    {
150
+        return Action::make('applyFilters')
151
+            ->label(__('filament-tables::table.filters.actions.apply.label'))
152
+            ->action('applyFilters')
153
+            ->button();
154
+    }
155
+
156
+    public function getFilterState(string $name): mixed
157
+    {
158
+        return Arr::get($this->filters, $name);
159
+    }
160
+
161
+    public function setFilterState(string $name, mixed $value): void
162
+    {
163
+        Arr::set($this->filters, $name, $value);
164
+    }
165
+
166
+    public function getDeferredFilterState(string $name): mixed
167
+    {
168
+        return Arr::get($this->deferredFilters, $name);
169
+    }
170
+
171
+    public function setDeferredFilterState(string $name, mixed $value): void
172
+    {
173
+        Arr::set($this->deferredFilters, $name, $value);
174
+    }
175
+
76
     protected function initializeProperties(): void
176
     protected function initializeProperties(): void
77
     {
177
     {
78
         $this->company = auth()->user()->currentCompany;
178
         $this->company = auth()->user()->currentCompany;
82
 
182
 
83
     protected function loadDefaultDateRange(): void
183
     protected function loadDefaultDateRange(): void
84
     {
184
     {
85
-        if (empty($this->dateRange)) {
86
-            $this->dateRange = $this->getDefaultDateRange();
185
+        if (! $this->getDeferredFilterState('dateRange')) {
186
+            $this->setFilterState('dateRange', $this->getDefaultDateRange());
87
             $this->setDateRange(Carbon::parse($this->fiscalYearStartDate), Carbon::parse($this->fiscalYearEndDate));
187
             $this->setDateRange(Carbon::parse($this->fiscalYearStartDate), Carbon::parse($this->fiscalYearEndDate));
88
         }
188
         }
89
     }
189
     }
154
 
254
 
155
     public function setDateRange(Carbon $start, Carbon $end): void
255
     public function setDateRange(Carbon $start, Carbon $end): void
156
     {
256
     {
157
-        $this->startDate = $start->startOfDay()->toDateTimeString();
158
-        $this->endDate = $end->isFuture() ? now()->endOfDay()->toDateTimeString() : $end->endOfDay()->toDateTimeString();
257
+        $this->setFilterState('startDate', $start->startOfDay()->toDateTimeString());
258
+        $this->setFilterState('endDate', $end->isFuture() ? now()->endOfDay()->toDateTimeString() : $end->endOfDay()->toDateTimeString());
259
+    }
260
+
261
+    public function getFormattedStartDate(): string
262
+    {
263
+        return Carbon::parse($this->getFilterState('startDate'))->startOfDay()->toDateTimeString();
264
+    }
265
+
266
+    public function getFormattedEndDate(): string
267
+    {
268
+        return Carbon::parse($this->getFilterState('endDate'))->endOfDay()->toDateTimeString();
159
     }
269
     }
160
 
270
 
161
     public function toggleColumnsAction(): Action
271
     public function toggleColumnsAction(): Action
228
             ->endDateField('endDate');
338
             ->endDateField('endDate');
229
     }
339
     }
230
 
340
 
231
-    protected function resetDateRange(): void
232
-    {
233
-        $this->dateRange = $this->getDefaultDateRange();
234
-        $this->setDateRange(Carbon::parse($this->fiscalYearStartDate), Carbon::parse($this->fiscalYearEndDate));
235
-    }
236
-
237
     protected function getStartDateFormComponent(): Component
341
     protected function getStartDateFormComponent(): Component
238
     {
342
     {
239
         return DatePicker::make('startDate')
343
         return DatePicker::make('startDate')
240
             ->label('Start Date')
344
             ->label('Start Date')
241
-            ->afterStateUpdated(static function (Set $set) {
345
+            ->live()
346
+            ->afterStateUpdated(static function ($state, Set $set) {
242
                 $set('dateRange', 'Custom');
347
                 $set('dateRange', 'Custom');
243
             });
348
             });
244
     }
349
     }
247
     {
352
     {
248
         return DatePicker::make('endDate')
353
         return DatePicker::make('endDate')
249
             ->label('End Date')
354
             ->label('End Date')
355
+            ->live()
250
             ->afterStateUpdated(static function (Set $set) {
356
             ->afterStateUpdated(static function (Set $set) {
251
                 $set('dateRange', 'Custom');
357
                 $set('dateRange', 'Custom');
252
             });
358
             });

+ 4
- 5
app/Filament/Company/Pages/Reports/IncomeStatement.php 查看文件

47
         ];
47
         ];
48
     }
48
     }
49
 
49
 
50
-    public function form(Form $form): Form
50
+    public function filtersForm(Form $form): Form
51
     {
51
     {
52
         return $form
52
         return $form
53
             ->inlineLabel()
53
             ->inlineLabel()
54
             ->columns()
54
             ->columns()
55
-            ->live()
56
             ->schema([
55
             ->schema([
57
                 $this->getDateRangeFormComponent(),
56
                 $this->getDateRangeFormComponent(),
58
                 Cluster::make([
57
                 Cluster::make([
64
 
63
 
65
     protected function buildReport(array $columns): ReportDTO
64
     protected function buildReport(array $columns): ReportDTO
66
     {
65
     {
67
-        return $this->reportService->buildIncomeStatementReport($this->startDate, $this->endDate, $columns);
66
+        return $this->reportService->buildIncomeStatementReport($this->getFormattedStartDate(), $this->getFormattedEndDate(), $columns);
68
     }
67
     }
69
 
68
 
70
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
69
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
74
 
73
 
75
     public function exportCSV(): StreamedResponse
74
     public function exportCSV(): StreamedResponse
76
     {
75
     {
77
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->startDate, $this->endDate);
76
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
78
     }
77
     }
79
 
78
 
80
     public function exportPDF(): StreamedResponse
79
     public function exportPDF(): StreamedResponse
81
     {
80
     {
82
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->startDate, $this->endDate);
81
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
83
     }
82
     }
84
 }
83
 }

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

70
 
70
 
71
     protected function buildReport(array $columns): ReportDTO
71
     protected function buildReport(array $columns): ReportDTO
72
     {
72
     {
73
-        return $this->reportService->buildTrialBalanceReport($this->startDate, $this->endDate, $columns);
73
+        return $this->reportService->buildTrialBalanceReport($this->getFormattedStartDate(), $this->getFormattedEndDate(), $columns);
74
     }
74
     }
75
 
75
 
76
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
76
     protected function getTransformer(ReportDTO $reportDTO): ExportableReport
80
 
80
 
81
     public function exportCSV(): StreamedResponse
81
     public function exportCSV(): StreamedResponse
82
     {
82
     {
83
-        return $this->exportService->exportToCsv($this->company, $this->report, $this->startDate, $this->endDate);
83
+        return $this->exportService->exportToCsv($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
84
     }
84
     }
85
 
85
 
86
     public function exportPDF(): StreamedResponse
86
     public function exportPDF(): StreamedResponse
87
     {
87
     {
88
-        return $this->exportService->exportToPdf($this->company, $this->report, $this->startDate, $this->endDate);
88
+        return $this->exportService->exportToPdf($this->company, $this->report, $this->getFilterState('startDate'), $this->getFilterState('endDate'));
89
     }
89
     }
90
 }
90
 }

+ 11
- 4
app/Filament/Company/Resources/Banking/AccountResource.php 查看文件

15
 use Filament\Support\Enums\FontWeight;
15
 use Filament\Support\Enums\FontWeight;
16
 use Filament\Tables;
16
 use Filament\Tables;
17
 use Filament\Tables\Table;
17
 use Filament\Tables\Table;
18
+use Illuminate\Database\Eloquent\Builder;
18
 use Illuminate\Support\Collection;
19
 use Illuminate\Support\Collection;
19
 use Illuminate\Support\Facades\Auth;
20
 use Illuminate\Support\Facades\Auth;
20
 use Illuminate\Validation\Rules\Unique;
21
 use Illuminate\Validation\Rules\Unique;
44
                             ->localizeLabel()
45
                             ->localizeLabel()
45
                             ->searchable()
46
                             ->searchable()
46
                             ->columnSpan(1)
47
                             ->columnSpan(1)
48
+                            ->disabledOn('edit')
47
                             ->default(BankAccountType::DEFAULT)
49
                             ->default(BankAccountType::DEFAULT)
48
                             ->live()
50
                             ->live()
49
                             ->afterStateUpdated(static function (Forms\Set $set, $state, ?BankAccount $bankAccount, string $operation) {
51
                             ->afterStateUpdated(static function (Forms\Set $set, $state, ?BankAccount $bankAccount, string $operation) {
64
                             ->schema([
66
                             ->schema([
65
                                 Forms\Components\Select::make('subtype_id')
67
                                 Forms\Components\Select::make('subtype_id')
66
                                     ->options(static fn (Forms\Get $get) => static::groupSubtypesBySubtypeType(BankAccountType::parse($get('data.type', true))))
68
                                     ->options(static fn (Forms\Get $get) => static::groupSubtypesBySubtypeType(BankAccountType::parse($get('data.type', true))))
69
+                                    ->disabledOn('edit')
67
                                     ->localizeLabel()
70
                                     ->localizeLabel()
68
                                     ->searchable()
71
                                     ->searchable()
69
                                     ->live()
72
                                     ->live()
79
                                     ->localizeLabel()
82
                                     ->localizeLabel()
80
                                     ->required(),
83
                                     ->required(),
81
                                 CreateCurrencySelect::make('currency_code')
84
                                 CreateCurrencySelect::make('currency_code')
85
+                                    ->disabledOn('edit')
82
                                     ->relationship('currency', 'name'),
86
                                     ->relationship('currency', 'name'),
83
                             ]),
87
                             ]),
84
                         Forms\Components\Group::make()
88
                         Forms\Components\Group::make()
104
     public static function table(Table $table): Table
108
     public static function table(Table $table): Table
105
     {
109
     {
106
         return $table
110
         return $table
111
+            ->modifyQueryUsing(function (Builder $query) {
112
+                $query->with([
113
+                    'account',
114
+                    'account.subtype',
115
+                ]);
116
+            })
107
             ->columns([
117
             ->columns([
108
                 Tables\Columns\TextColumn::make('account.name')
118
                 Tables\Columns\TextColumn::make('account.name')
109
                     ->localizeLabel('Account')
119
                     ->localizeLabel('Account')
138
             ])
148
             ])
139
             ->checkIfRecordIsSelectableUsing(static function (BankAccount $record) {
149
             ->checkIfRecordIsSelectableUsing(static function (BankAccount $record) {
140
                 return $record->isDisabled();
150
                 return $record->isDisabled();
141
-            })
142
-            ->emptyStateActions([
143
-                Tables\Actions\CreateAction::make(),
144
-            ]);
151
+            });
145
     }
152
     }
146
 
153
 
147
     public static function getPages(): array
154
     public static function getPages(): array

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

2
 
2
 
3
 namespace App\Filament\Company\Resources\Banking\AccountResource\Pages;
3
 namespace App\Filament\Company\Resources\Banking\AccountResource\Pages;
4
 
4
 
5
+use App\Concerns\HandlesResourceRecordCreation;
5
 use App\Filament\Company\Resources\Banking\AccountResource;
6
 use App\Filament\Company\Resources\Banking\AccountResource;
7
+use App\Models\Banking\BankAccount;
6
 use Filament\Resources\Pages\CreateRecord;
8
 use Filament\Resources\Pages\CreateRecord;
9
+use Filament\Support\Exceptions\Halt;
10
+use Illuminate\Database\Eloquent\Model;
11
+use Illuminate\Support\Facades\Auth;
7
 
12
 
8
 class CreateAccount extends CreateRecord
13
 class CreateAccount extends CreateRecord
9
 {
14
 {
15
+    use HandlesResourceRecordCreation;
16
+
10
     protected static string $resource = AccountResource::class;
17
     protected static string $resource = AccountResource::class;
11
 
18
 
12
     protected function getRedirectUrl(): string
19
     protected function getRedirectUrl(): string
20
 
27
 
21
         return $data;
28
         return $data;
22
     }
29
     }
30
+
31
+    /**
32
+     * @throws Halt
33
+     */
34
+    protected function handleRecordCreation(array $data): Model
35
+    {
36
+        $user = Auth::user();
37
+
38
+        if (! $user) {
39
+            throw new Halt('No authenticated user found');
40
+        }
41
+
42
+        return $this->handleRecordCreationWithUniqueField($data, new BankAccount, $user);
43
+    }
23
 }
44
 }

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

5
 use App\Concerns\HandlesResourceRecordUpdate;
5
 use App\Concerns\HandlesResourceRecordUpdate;
6
 use App\Filament\Company\Resources\Banking\AccountResource;
6
 use App\Filament\Company\Resources\Banking\AccountResource;
7
 use Filament\Resources\Pages\EditRecord;
7
 use Filament\Resources\Pages\EditRecord;
8
+use Filament\Support\Exceptions\Halt;
9
+use Illuminate\Database\Eloquent\Model;
10
+use Illuminate\Support\Facades\Auth;
8
 
11
 
9
 class EditAccount extends EditRecord
12
 class EditAccount extends EditRecord
10
 {
13
 {
30
 
33
 
31
         return $data;
34
         return $data;
32
     }
35
     }
36
+
37
+    /**
38
+     * @throws Halt
39
+     */
40
+    protected function handleRecordUpdate(Model $record, array $data): Model
41
+    {
42
+        $user = Auth::user();
43
+
44
+        if (! $user) {
45
+            throw new Halt('No authenticated user found');
46
+        }
47
+
48
+        return $this->handleRecordUpdateWithUniqueField($record, $data, $user);
49
+    }
33
 }
50
 }

+ 2
- 1
app/Filament/Forms/Components/DateRangeSelect.php 查看文件

30
         $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
30
         $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
31
 
31
 
32
         $this->options($this->getDateRangeOptions())
32
         $this->options($this->getDateRangeOptions())
33
+            ->live()
33
             ->afterStateUpdated(function ($state, Set $set) {
34
             ->afterStateUpdated(function ($state, Set $set) {
34
                 $this->updateDateRange($state, $set);
35
                 $this->updateDateRange($state, $set);
35
             });
36
             });
165
 
166
 
166
     public function setDateRange(Carbon $start, Carbon $end, Set $set): void
167
     public function setDateRange(Carbon $start, Carbon $end, Set $set): void
167
     {
168
     {
168
-        $set($this->startDateField, $start->startOfDay()->toDateTimeString());
169
+        $set($this->startDateField, $start->startOfDay()->toDateString());
169
         $set($this->endDateField, $end->isFuture() ? now()->endOfDay()->toDateTimeString() : $end->endOfDay()->toDateTimeString());
170
         $set($this->endDateField, $end->isFuture() ? now()->endOfDay()->toDateTimeString() : $end->endOfDay()->toDateTimeString());
170
     }
171
     }
171
 }
172
 }

+ 27
- 22
app/Listeners/ConfigureCompanyDefault.php 查看文件

26
     public function handle(CompanyConfigured $event): void
26
     public function handle(CompanyConfigured $event): void
27
     {
27
     {
28
         $company = $event->company;
28
         $company = $event->company;
29
+
30
+        session([
31
+            'current_company_id' => $company->id,
32
+            'default_language' => $company->locale->language ?? config('transmatic.source_locale'),
33
+            'default_timezone' => $company->locale->timezone ?? config('app.timezone'),
34
+            'default_pagination_page_option' => $company->appearance->records_per_page->value ?? RecordsPerPage::DEFAULT,
35
+            'default_sort' => $company->appearance->table_sort_direction->value ?? TableSortDirection::DEFAULT,
36
+            'default_primary_color' => $company->appearance->primary_color->value ?? PrimaryColor::DEFAULT,
37
+            'default_font' => $company->appearance->font->value ?? Font::DEFAULT,
38
+            'default_date_format' => $company->locale->date_format->value ?? DateFormat::DEFAULT,
39
+            'default_week_start' => $company->locale->week_start->value ?? WeekStart::DEFAULT,
40
+        ]);
41
+
42
+        app()->setLocale(session('default_language'));
43
+        locale_set_default(session('default_language'));
44
+        config(['app.timezone' => session('default_timezone')]);
45
+        date_default_timezone_set(session('default_timezone'));
46
+
29
         $paginationPageOptions = RecordsPerPage::caseValues();
47
         $paginationPageOptions = RecordsPerPage::caseValues();
30
-        $defaultPaginationPageOption = $company->appearance->records_per_page->value ?? RecordsPerPage::DEFAULT;
31
-        $defaultSort = $company->appearance->table_sort_direction->value ?? TableSortDirection::DEFAULT;
32
-        $defaultPrimaryColor = $company->appearance->primary_color ?? PrimaryColor::from(PrimaryColor::DEFAULT);
33
-        $defaultFont = $company->appearance->font->value ?? Font::DEFAULT;
34
-        $default_language = $company->locale->language ?? config('transmatic.source_locale');
35
-        $defaultTimezone = $company->locale->timezone ?? config('app.timezone');
36
-        $dateFormat = $company->locale->date_format->value ?? DateFormat::DEFAULT;
37
-        $weekStart = $company->locale->week_start->value ?? WeekStart::DEFAULT;
38
-
39
-        app()->setLocale($default_language);
40
-        locale_set_default($default_language);
41
-        config(['app.timezone' => $defaultTimezone]);
42
-        date_default_timezone_set($defaultTimezone);
43
-
44
-        Table::configureUsing(static function (Table $table) use ($paginationPageOptions, $defaultSort, $defaultPaginationPageOption): void {
48
+
49
+        Table::configureUsing(static function (Table $table) use ($paginationPageOptions): void {
45
 
50
 
46
             $table
51
             $table
47
                 ->paginationPageOptions($paginationPageOptions)
52
                 ->paginationPageOptions($paginationPageOptions)
48
-                ->defaultSort(column: 'id', direction: $defaultSort)
49
-                ->defaultPaginationPageOption($defaultPaginationPageOption);
53
+                ->defaultSort(column: 'id', direction: session('default_sort'))
54
+                ->defaultPaginationPageOption(session('default_pagination_page_option'));
50
         }, isImportant: true);
55
         }, isImportant: true);
51
 
56
 
52
         FilamentColor::register([
57
         FilamentColor::register([
53
-            'primary' => $defaultPrimaryColor->getColor(),
58
+            'primary' => PrimaryColor::from(session('default_primary_color'))->getColor(),
54
         ]);
59
         ]);
55
 
60
 
56
         Filament::getPanel('company')
61
         Filament::getPanel('company')
57
-            ->font($defaultFont)
62
+            ->font(session('default_font'))
58
             ->brandName($company->name);
63
             ->brandName($company->name);
59
 
64
 
60
-        DatePicker::configureUsing(static function (DatePicker $component) use ($dateFormat, $weekStart) {
65
+        DatePicker::configureUsing(static function (DatePicker $component) {
61
             $component
66
             $component
62
-                ->displayFormat($dateFormat)
63
-                ->firstDayOfWeek($weekStart);
67
+                ->displayFormat(session('default_date_format'))
68
+                ->firstDayOfWeek(session('default_week_start'));
64
         });
69
         });
65
 
70
 
66
         Tab::configureUsing(static function (Tab $tab) {
71
         Tab::configureUsing(static function (Tab $tab) {

+ 0
- 1
app/Listeners/SyncAssociatedModels.php 查看文件

40
 
40
 
41
         $keyToMethodMap = [
41
         $keyToMethodMap = [
42
             'bank_account_id' => 'bankAccount',
42
             'bank_account_id' => 'bankAccount',
43
-            'currency_code' => 'currency',
44
             'sales_tax_id' => 'salesTax',
43
             'sales_tax_id' => 'salesTax',
45
             'purchase_tax_id' => 'purchaseTax',
44
             'purchase_tax_id' => 'purchaseTax',
46
             'sales_discount_id' => 'salesDiscount',
45
             'sales_discount_id' => 'salesDiscount',

+ 15
- 2
app/Scopes/CurrentCompanyScope.php 查看文件

4
 
4
 
5
 use Illuminate\Database\Eloquent\Builder;
5
 use Illuminate\Database\Eloquent\Builder;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
+use Illuminate\Database\Eloquent\ModelNotFoundException;
7
 use Illuminate\Database\Eloquent\Scope;
8
 use Illuminate\Database\Eloquent\Scope;
8
 use Illuminate\Support\Facades\Auth;
9
 use Illuminate\Support\Facades\Auth;
10
+use Illuminate\Support\Facades\Log;
9
 
11
 
10
 class CurrentCompanyScope implements Scope
12
 class CurrentCompanyScope implements Scope
11
 {
13
 {
14
      */
16
      */
15
     public function apply(Builder $builder, Model $model): void
17
     public function apply(Builder $builder, Model $model): void
16
     {
18
     {
17
-        if (Auth::check() && Auth::user()->currentCompany) {
18
-            $builder->where("{$model->getTable()}.company_id", Auth::user()->currentCompany->id);
19
+        $companyId = session('current_company_id');
20
+
21
+        if (! $companyId && Auth::check() && Auth::user()->currentCompany) {
22
+            $companyId = Auth::user()->currentCompany->id;
23
+            session(['current_company_id' => $companyId]);
24
+        }
25
+
26
+        if ($companyId) {
27
+            $builder->where("{$model->getTable()}.company_id", $companyId);
28
+        } else {
29
+            Log::error('CurrentCompanyScope: No company_id found for user ' . Auth::id());
30
+
31
+            throw new ModelNotFoundException('CurrentCompanyScope: No company_id set in the session or on the user.');
19
         }
32
         }
20
     }
33
     }
21
 }
34
 }

+ 2
- 0
app/Services/AccountService.php 查看文件

73
 
73
 
74
     public function getAccountBalances(string $startDate, string $endDate, array $accountIds = []): Builder
74
     public function getAccountBalances(string $startDate, string $endDate, array $accountIds = []): Builder
75
     {
75
     {
76
+        $accountIds = array_map('intval', $accountIds);
77
+
76
         $query = Account::query()
78
         $query = Account::query()
77
             ->select([
79
             ->select([
78
                 'accounts.id',
80
                 'accounts.id',

+ 99
- 99
composer.lock 查看文件

497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.320.7",
500
+            "version": "3.321.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": "702b9955160d2dacdf2cdf4d4476fcf95eae1aaf"
504
+                "reference": "c04f8f30891cee8480c132778cd4cc486467e77a"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/702b9955160d2dacdf2cdf4d4476fcf95eae1aaf",
509
-                "reference": "702b9955160d2dacdf2cdf4d4476fcf95eae1aaf",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c04f8f30891cee8480c132778cd4cc486467e77a",
509
+                "reference": "c04f8f30891cee8480c132778cd4cc486467e77a",
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.320.7"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.321.2"
593
             },
593
             },
594
-            "time": "2024-08-23T18:13:50+00:00"
594
+            "time": "2024-08-30T18:14:40+00:00"
595
         },
595
         },
596
         {
596
         {
597
             "name": "aws/aws-sdk-php-laravel",
597
             "name": "aws/aws-sdk-php-laravel",
1738
         },
1738
         },
1739
         {
1739
         {
1740
             "name": "filament/actions",
1740
             "name": "filament/actions",
1741
-            "version": "v3.2.107",
1741
+            "version": "v3.2.110",
1742
             "source": {
1742
             "source": {
1743
                 "type": "git",
1743
                 "type": "git",
1744
                 "url": "https://github.com/filamentphp/actions.git",
1744
                 "url": "https://github.com/filamentphp/actions.git",
1745
-                "reference": "de5ce76f20ee21af92b951dec2a5c533ecacbc79"
1745
+                "reference": "5d6e4fe444f1ef04d373518248a445bbcc3ca272"
1746
             },
1746
             },
1747
             "dist": {
1747
             "dist": {
1748
                 "type": "zip",
1748
                 "type": "zip",
1749
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/de5ce76f20ee21af92b951dec2a5c533ecacbc79",
1750
-                "reference": "de5ce76f20ee21af92b951dec2a5c533ecacbc79",
1749
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/5d6e4fe444f1ef04d373518248a445bbcc3ca272",
1750
+                "reference": "5d6e4fe444f1ef04d373518248a445bbcc3ca272",
1751
                 "shasum": ""
1751
                 "shasum": ""
1752
             },
1752
             },
1753
             "require": {
1753
             "require": {
1787
                 "issues": "https://github.com/filamentphp/filament/issues",
1787
                 "issues": "https://github.com/filamentphp/filament/issues",
1788
                 "source": "https://github.com/filamentphp/filament"
1788
                 "source": "https://github.com/filamentphp/filament"
1789
             },
1789
             },
1790
-            "time": "2024-08-22T12:07:53+00:00"
1790
+            "time": "2024-08-26T07:22:35+00:00"
1791
         },
1791
         },
1792
         {
1792
         {
1793
             "name": "filament/filament",
1793
             "name": "filament/filament",
1794
-            "version": "v3.2.107",
1794
+            "version": "v3.2.110",
1795
             "source": {
1795
             "source": {
1796
                 "type": "git",
1796
                 "type": "git",
1797
                 "url": "https://github.com/filamentphp/panels.git",
1797
                 "url": "https://github.com/filamentphp/panels.git",
1798
-                "reference": "2675472f2bdd4e765a1f3e533231bda7750a2881"
1798
+                "reference": "130636e90e821154e0ce60dcbc7b358d2a1a716f"
1799
             },
1799
             },
1800
             "dist": {
1800
             "dist": {
1801
                 "type": "zip",
1801
                 "type": "zip",
1802
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/2675472f2bdd4e765a1f3e533231bda7750a2881",
1803
-                "reference": "2675472f2bdd4e765a1f3e533231bda7750a2881",
1802
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/130636e90e821154e0ce60dcbc7b358d2a1a716f",
1803
+                "reference": "130636e90e821154e0ce60dcbc7b358d2a1a716f",
1804
                 "shasum": ""
1804
                 "shasum": ""
1805
             },
1805
             },
1806
             "require": {
1806
             "require": {
1852
                 "issues": "https://github.com/filamentphp/filament/issues",
1852
                 "issues": "https://github.com/filamentphp/filament/issues",
1853
                 "source": "https://github.com/filamentphp/filament"
1853
                 "source": "https://github.com/filamentphp/filament"
1854
             },
1854
             },
1855
-            "time": "2024-08-20T08:32:50+00:00"
1855
+            "time": "2024-08-30T01:52:09+00:00"
1856
         },
1856
         },
1857
         {
1857
         {
1858
             "name": "filament/forms",
1858
             "name": "filament/forms",
1859
-            "version": "v3.2.107",
1859
+            "version": "v3.2.110",
1860
             "source": {
1860
             "source": {
1861
                 "type": "git",
1861
                 "type": "git",
1862
                 "url": "https://github.com/filamentphp/forms.git",
1862
                 "url": "https://github.com/filamentphp/forms.git",
1863
-                "reference": "0f80913deb90bfe9e1850ab35e80a34194cfb652"
1863
+                "reference": "02fe2e211993f6291b719a093ed6f63e17125e9a"
1864
             },
1864
             },
1865
             "dist": {
1865
             "dist": {
1866
                 "type": "zip",
1866
                 "type": "zip",
1867
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/0f80913deb90bfe9e1850ab35e80a34194cfb652",
1868
-                "reference": "0f80913deb90bfe9e1850ab35e80a34194cfb652",
1867
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/02fe2e211993f6291b719a093ed6f63e17125e9a",
1868
+                "reference": "02fe2e211993f6291b719a093ed6f63e17125e9a",
1869
                 "shasum": ""
1869
                 "shasum": ""
1870
             },
1870
             },
1871
             "require": {
1871
             "require": {
1908
                 "issues": "https://github.com/filamentphp/filament/issues",
1908
                 "issues": "https://github.com/filamentphp/filament/issues",
1909
                 "source": "https://github.com/filamentphp/filament"
1909
                 "source": "https://github.com/filamentphp/filament"
1910
             },
1910
             },
1911
-            "time": "2024-08-22T12:07:43+00:00"
1911
+            "time": "2024-08-30T18:04:06+00:00"
1912
         },
1912
         },
1913
         {
1913
         {
1914
             "name": "filament/infolists",
1914
             "name": "filament/infolists",
1915
-            "version": "v3.2.107",
1915
+            "version": "v3.2.110",
1916
             "source": {
1916
             "source": {
1917
                 "type": "git",
1917
                 "type": "git",
1918
                 "url": "https://github.com/filamentphp/infolists.git",
1918
                 "url": "https://github.com/filamentphp/infolists.git",
1963
         },
1963
         },
1964
         {
1964
         {
1965
             "name": "filament/notifications",
1965
             "name": "filament/notifications",
1966
-            "version": "v3.2.107",
1966
+            "version": "v3.2.110",
1967
             "source": {
1967
             "source": {
1968
                 "type": "git",
1968
                 "type": "git",
1969
                 "url": "https://github.com/filamentphp/notifications.git",
1969
                 "url": "https://github.com/filamentphp/notifications.git",
2015
         },
2015
         },
2016
         {
2016
         {
2017
             "name": "filament/support",
2017
             "name": "filament/support",
2018
-            "version": "v3.2.107",
2018
+            "version": "v3.2.110",
2019
             "source": {
2019
             "source": {
2020
                 "type": "git",
2020
                 "type": "git",
2021
                 "url": "https://github.com/filamentphp/support.git",
2021
                 "url": "https://github.com/filamentphp/support.git",
2022
-                "reference": "f00b84d43d157c85837108a7eeaceabbaf6044ab"
2022
+                "reference": "78e25428c754fcbb30c321d5dda439c760de9837"
2023
             },
2023
             },
2024
             "dist": {
2024
             "dist": {
2025
                 "type": "zip",
2025
                 "type": "zip",
2026
-                "url": "https://api.github.com/repos/filamentphp/support/zipball/f00b84d43d157c85837108a7eeaceabbaf6044ab",
2027
-                "reference": "f00b84d43d157c85837108a7eeaceabbaf6044ab",
2026
+                "url": "https://api.github.com/repos/filamentphp/support/zipball/78e25428c754fcbb30c321d5dda439c760de9837",
2027
+                "reference": "78e25428c754fcbb30c321d5dda439c760de9837",
2028
                 "shasum": ""
2028
                 "shasum": ""
2029
             },
2029
             },
2030
             "require": {
2030
             "require": {
2070
                 "issues": "https://github.com/filamentphp/filament/issues",
2070
                 "issues": "https://github.com/filamentphp/filament/issues",
2071
                 "source": "https://github.com/filamentphp/filament"
2071
                 "source": "https://github.com/filamentphp/filament"
2072
             },
2072
             },
2073
-            "time": "2024-08-22T12:08:05+00:00"
2073
+            "time": "2024-08-26T07:22:57+00:00"
2074
         },
2074
         },
2075
         {
2075
         {
2076
             "name": "filament/tables",
2076
             "name": "filament/tables",
2077
-            "version": "v3.2.107",
2077
+            "version": "v3.2.110",
2078
             "source": {
2078
             "source": {
2079
                 "type": "git",
2079
                 "type": "git",
2080
                 "url": "https://github.com/filamentphp/tables.git",
2080
                 "url": "https://github.com/filamentphp/tables.git",
2081
-                "reference": "5de49ef865e8788bb29d58723b88977b593a7b02"
2081
+                "reference": "129943d1b4e6c1edeef53e804eb56ef78a932a6c"
2082
             },
2082
             },
2083
             "dist": {
2083
             "dist": {
2084
                 "type": "zip",
2084
                 "type": "zip",
2085
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/5de49ef865e8788bb29d58723b88977b593a7b02",
2086
-                "reference": "5de49ef865e8788bb29d58723b88977b593a7b02",
2085
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/129943d1b4e6c1edeef53e804eb56ef78a932a6c",
2086
+                "reference": "129943d1b4e6c1edeef53e804eb56ef78a932a6c",
2087
                 "shasum": ""
2087
                 "shasum": ""
2088
             },
2088
             },
2089
             "require": {
2089
             "require": {
2122
                 "issues": "https://github.com/filamentphp/filament/issues",
2122
                 "issues": "https://github.com/filamentphp/filament/issues",
2123
                 "source": "https://github.com/filamentphp/filament"
2123
                 "source": "https://github.com/filamentphp/filament"
2124
             },
2124
             },
2125
-            "time": "2024-08-22T12:08:13+00:00"
2125
+            "time": "2024-08-30T01:52:14+00:00"
2126
         },
2126
         },
2127
         {
2127
         {
2128
             "name": "filament/widgets",
2128
             "name": "filament/widgets",
2129
-            "version": "v3.2.107",
2129
+            "version": "v3.2.110",
2130
             "source": {
2130
             "source": {
2131
                 "type": "git",
2131
                 "type": "git",
2132
                 "url": "https://github.com/filamentphp/widgets.git",
2132
                 "url": "https://github.com/filamentphp/widgets.git",
6411
         },
6411
         },
6412
         {
6412
         {
6413
             "name": "spatie/laravel-package-tools",
6413
             "name": "spatie/laravel-package-tools",
6414
-            "version": "1.16.4",
6414
+            "version": "1.16.5",
6415
             "source": {
6415
             "source": {
6416
                 "type": "git",
6416
                 "type": "git",
6417
                 "url": "https://github.com/spatie/laravel-package-tools.git",
6417
                 "url": "https://github.com/spatie/laravel-package-tools.git",
6418
-                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53"
6418
+                "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2"
6419
             },
6419
             },
6420
             "dist": {
6420
             "dist": {
6421
                 "type": "zip",
6421
                 "type": "zip",
6422
-                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
6423
-                "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53",
6422
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/c7413972cf22ffdff97b68499c22baa04eddb6a2",
6423
+                "reference": "c7413972cf22ffdff97b68499c22baa04eddb6a2",
6424
                 "shasum": ""
6424
                 "shasum": ""
6425
             },
6425
             },
6426
             "require": {
6426
             "require": {
6459
             ],
6459
             ],
6460
             "support": {
6460
             "support": {
6461
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
6461
                 "issues": "https://github.com/spatie/laravel-package-tools/issues",
6462
-                "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4"
6462
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.5"
6463
             },
6463
             },
6464
             "funding": [
6464
             "funding": [
6465
                 {
6465
                 {
6467
                     "type": "github"
6467
                     "type": "github"
6468
                 }
6468
                 }
6469
             ],
6469
             ],
6470
-            "time": "2024-03-20T07:29:11+00:00"
6470
+            "time": "2024-08-27T18:56:10+00:00"
6471
         },
6471
         },
6472
         {
6472
         {
6473
             "name": "squirephp/model",
6473
             "name": "squirephp/model",
6654
         },
6654
         },
6655
         {
6655
         {
6656
             "name": "symfony/console",
6656
             "name": "symfony/console",
6657
-            "version": "v7.1.3",
6657
+            "version": "v7.1.4",
6658
             "source": {
6658
             "source": {
6659
                 "type": "git",
6659
                 "type": "git",
6660
                 "url": "https://github.com/symfony/console.git",
6660
                 "url": "https://github.com/symfony/console.git",
6661
-                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
6661
+                "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111"
6662
             },
6662
             },
6663
             "dist": {
6663
             "dist": {
6664
                 "type": "zip",
6664
                 "type": "zip",
6665
-                "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
6666
-                "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
6665
+                "url": "https://api.github.com/repos/symfony/console/zipball/1eed7af6961d763e7832e874d7f9b21c3ea9c111",
6666
+                "reference": "1eed7af6961d763e7832e874d7f9b21c3ea9c111",
6667
                 "shasum": ""
6667
                 "shasum": ""
6668
             },
6668
             },
6669
             "require": {
6669
             "require": {
6727
                 "terminal"
6727
                 "terminal"
6728
             ],
6728
             ],
6729
             "support": {
6729
             "support": {
6730
-                "source": "https://github.com/symfony/console/tree/v7.1.3"
6730
+                "source": "https://github.com/symfony/console/tree/v7.1.4"
6731
             },
6731
             },
6732
             "funding": [
6732
             "funding": [
6733
                 {
6733
                 {
6743
                     "type": "tidelift"
6743
                     "type": "tidelift"
6744
                 }
6744
                 }
6745
             ],
6745
             ],
6746
-            "time": "2024-07-26T12:41:01+00:00"
6746
+            "time": "2024-08-15T22:48:53+00:00"
6747
         },
6747
         },
6748
         {
6748
         {
6749
             "name": "symfony/css-selector",
6749
             "name": "symfony/css-selector",
7110
         },
7110
         },
7111
         {
7111
         {
7112
             "name": "symfony/finder",
7112
             "name": "symfony/finder",
7113
-            "version": "v7.1.3",
7113
+            "version": "v7.1.4",
7114
             "source": {
7114
             "source": {
7115
                 "type": "git",
7115
                 "type": "git",
7116
                 "url": "https://github.com/symfony/finder.git",
7116
                 "url": "https://github.com/symfony/finder.git",
7117
-                "reference": "717c6329886f32dc65e27461f80f2a465412fdca"
7117
+                "reference": "d95bbf319f7d052082fb7af147e0f835a695e823"
7118
             },
7118
             },
7119
             "dist": {
7119
             "dist": {
7120
                 "type": "zip",
7120
                 "type": "zip",
7121
-                "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
7122
-                "reference": "717c6329886f32dc65e27461f80f2a465412fdca",
7121
+                "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823",
7122
+                "reference": "d95bbf319f7d052082fb7af147e0f835a695e823",
7123
                 "shasum": ""
7123
                 "shasum": ""
7124
             },
7124
             },
7125
             "require": {
7125
             "require": {
7154
             "description": "Finds files and directories via an intuitive fluent interface",
7154
             "description": "Finds files and directories via an intuitive fluent interface",
7155
             "homepage": "https://symfony.com",
7155
             "homepage": "https://symfony.com",
7156
             "support": {
7156
             "support": {
7157
-                "source": "https://github.com/symfony/finder/tree/v7.1.3"
7157
+                "source": "https://github.com/symfony/finder/tree/v7.1.4"
7158
             },
7158
             },
7159
             "funding": [
7159
             "funding": [
7160
                 {
7160
                 {
7170
                     "type": "tidelift"
7170
                     "type": "tidelift"
7171
                 }
7171
                 }
7172
             ],
7172
             ],
7173
-            "time": "2024-07-24T07:08:44+00:00"
7173
+            "time": "2024-08-13T14:28:19+00:00"
7174
         },
7174
         },
7175
         {
7175
         {
7176
             "name": "symfony/html-sanitizer",
7176
             "name": "symfony/html-sanitizer",
7320
         },
7320
         },
7321
         {
7321
         {
7322
             "name": "symfony/http-kernel",
7322
             "name": "symfony/http-kernel",
7323
-            "version": "v7.1.3",
7323
+            "version": "v7.1.4",
7324
             "source": {
7324
             "source": {
7325
                 "type": "git",
7325
                 "type": "git",
7326
                 "url": "https://github.com/symfony/http-kernel.git",
7326
                 "url": "https://github.com/symfony/http-kernel.git",
7327
-                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186"
7327
+                "reference": "6efcbd1b3f444f631c386504fc83eeca25963747"
7328
             },
7328
             },
7329
             "dist": {
7329
             "dist": {
7330
                 "type": "zip",
7330
                 "type": "zip",
7331
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186",
7332
-                "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186",
7331
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6efcbd1b3f444f631c386504fc83eeca25963747",
7332
+                "reference": "6efcbd1b3f444f631c386504fc83eeca25963747",
7333
                 "shasum": ""
7333
                 "shasum": ""
7334
             },
7334
             },
7335
             "require": {
7335
             "require": {
7414
             "description": "Provides a structured process for converting a Request into a Response",
7414
             "description": "Provides a structured process for converting a Request into a Response",
7415
             "homepage": "https://symfony.com",
7415
             "homepage": "https://symfony.com",
7416
             "support": {
7416
             "support": {
7417
-                "source": "https://github.com/symfony/http-kernel/tree/v7.1.3"
7417
+                "source": "https://github.com/symfony/http-kernel/tree/v7.1.4"
7418
             },
7418
             },
7419
             "funding": [
7419
             "funding": [
7420
                 {
7420
                 {
7430
                     "type": "tidelift"
7430
                     "type": "tidelift"
7431
                 }
7431
                 }
7432
             ],
7432
             ],
7433
-            "time": "2024-07-26T14:58:15+00:00"
7433
+            "time": "2024-08-30T17:02:28+00:00"
7434
         },
7434
         },
7435
         {
7435
         {
7436
             "name": "symfony/intl",
7436
             "name": "symfony/intl",
7597
         },
7597
         },
7598
         {
7598
         {
7599
             "name": "symfony/mime",
7599
             "name": "symfony/mime",
7600
-            "version": "v7.1.2",
7600
+            "version": "v7.1.4",
7601
             "source": {
7601
             "source": {
7602
                 "type": "git",
7602
                 "type": "git",
7603
                 "url": "https://github.com/symfony/mime.git",
7603
                 "url": "https://github.com/symfony/mime.git",
7604
-                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc"
7604
+                "reference": "ccaa6c2503db867f472a587291e764d6a1e58758"
7605
             },
7605
             },
7606
             "dist": {
7606
             "dist": {
7607
                 "type": "zip",
7607
                 "type": "zip",
7608
-                "url": "https://api.github.com/repos/symfony/mime/zipball/26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
7609
-                "reference": "26a00b85477e69a4bab63b66c5dce64f18b0cbfc",
7608
+                "url": "https://api.github.com/repos/symfony/mime/zipball/ccaa6c2503db867f472a587291e764d6a1e58758",
7609
+                "reference": "ccaa6c2503db867f472a587291e764d6a1e58758",
7610
                 "shasum": ""
7610
                 "shasum": ""
7611
             },
7611
             },
7612
             "require": {
7612
             "require": {
7661
                 "mime-type"
7661
                 "mime-type"
7662
             ],
7662
             ],
7663
             "support": {
7663
             "support": {
7664
-                "source": "https://github.com/symfony/mime/tree/v7.1.2"
7664
+                "source": "https://github.com/symfony/mime/tree/v7.1.4"
7665
             },
7665
             },
7666
             "funding": [
7666
             "funding": [
7667
                 {
7667
                 {
7677
                     "type": "tidelift"
7677
                     "type": "tidelift"
7678
                 }
7678
                 }
7679
             ],
7679
             ],
7680
-            "time": "2024-06-28T10:03:55+00:00"
7680
+            "time": "2024-08-13T14:28:19+00:00"
7681
         },
7681
         },
7682
         {
7682
         {
7683
             "name": "symfony/polyfill-ctype",
7683
             "name": "symfony/polyfill-ctype",
8452
         },
8452
         },
8453
         {
8453
         {
8454
             "name": "symfony/routing",
8454
             "name": "symfony/routing",
8455
-            "version": "v7.1.3",
8455
+            "version": "v7.1.4",
8456
             "source": {
8456
             "source": {
8457
                 "type": "git",
8457
                 "type": "git",
8458
                 "url": "https://github.com/symfony/routing.git",
8458
                 "url": "https://github.com/symfony/routing.git",
8459
-                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0"
8459
+                "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7"
8460
             },
8460
             },
8461
             "dist": {
8461
             "dist": {
8462
                 "type": "zip",
8462
                 "type": "zip",
8463
-                "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
8464
-                "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
8463
+                "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
8464
+                "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
8465
                 "shasum": ""
8465
                 "shasum": ""
8466
             },
8466
             },
8467
             "require": {
8467
             "require": {
8513
                 "url"
8513
                 "url"
8514
             ],
8514
             ],
8515
             "support": {
8515
             "support": {
8516
-                "source": "https://github.com/symfony/routing/tree/v7.1.3"
8516
+                "source": "https://github.com/symfony/routing/tree/v7.1.4"
8517
             },
8517
             },
8518
             "funding": [
8518
             "funding": [
8519
                 {
8519
                 {
8529
                     "type": "tidelift"
8529
                     "type": "tidelift"
8530
                 }
8530
                 }
8531
             ],
8531
             ],
8532
-            "time": "2024-07-17T06:10:24+00:00"
8532
+            "time": "2024-08-29T08:16:25+00:00"
8533
         },
8533
         },
8534
         {
8534
         {
8535
             "name": "symfony/service-contracts",
8535
             "name": "symfony/service-contracts",
8616
         },
8616
         },
8617
         {
8617
         {
8618
             "name": "symfony/string",
8618
             "name": "symfony/string",
8619
-            "version": "v7.1.3",
8619
+            "version": "v7.1.4",
8620
             "source": {
8620
             "source": {
8621
                 "type": "git",
8621
                 "type": "git",
8622
                 "url": "https://github.com/symfony/string.git",
8622
                 "url": "https://github.com/symfony/string.git",
8623
-                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
8623
+                "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b"
8624
             },
8624
             },
8625
             "dist": {
8625
             "dist": {
8626
                 "type": "zip",
8626
                 "type": "zip",
8627
-                "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
8628
-                "reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
8627
+                "url": "https://api.github.com/repos/symfony/string/zipball/6cd670a6d968eaeb1c77c2e76091c45c56bc367b",
8628
+                "reference": "6cd670a6d968eaeb1c77c2e76091c45c56bc367b",
8629
                 "shasum": ""
8629
                 "shasum": ""
8630
             },
8630
             },
8631
             "require": {
8631
             "require": {
8683
                 "utf8"
8683
                 "utf8"
8684
             ],
8684
             ],
8685
             "support": {
8685
             "support": {
8686
-                "source": "https://github.com/symfony/string/tree/v7.1.3"
8686
+                "source": "https://github.com/symfony/string/tree/v7.1.4"
8687
             },
8687
             },
8688
             "funding": [
8688
             "funding": [
8689
                 {
8689
                 {
8699
                     "type": "tidelift"
8699
                     "type": "tidelift"
8700
                 }
8700
                 }
8701
             ],
8701
             ],
8702
-            "time": "2024-07-22T10:25:37+00:00"
8702
+            "time": "2024-08-12T09:59:40+00:00"
8703
         },
8703
         },
8704
         {
8704
         {
8705
             "name": "symfony/translation",
8705
             "name": "symfony/translation",
8875
         },
8875
         },
8876
         {
8876
         {
8877
             "name": "symfony/uid",
8877
             "name": "symfony/uid",
8878
-            "version": "v7.1.1",
8878
+            "version": "v7.1.4",
8879
             "source": {
8879
             "source": {
8880
                 "type": "git",
8880
                 "type": "git",
8881
                 "url": "https://github.com/symfony/uid.git",
8881
                 "url": "https://github.com/symfony/uid.git",
8882
-                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277"
8882
+                "reference": "82177535395109075cdb45a70533aa3d7a521cdf"
8883
             },
8883
             },
8884
             "dist": {
8884
             "dist": {
8885
                 "type": "zip",
8885
                 "type": "zip",
8886
-                "url": "https://api.github.com/repos/symfony/uid/zipball/bb59febeecc81528ff672fad5dab7f06db8c8277",
8887
-                "reference": "bb59febeecc81528ff672fad5dab7f06db8c8277",
8886
+                "url": "https://api.github.com/repos/symfony/uid/zipball/82177535395109075cdb45a70533aa3d7a521cdf",
8887
+                "reference": "82177535395109075cdb45a70533aa3d7a521cdf",
8888
                 "shasum": ""
8888
                 "shasum": ""
8889
             },
8889
             },
8890
             "require": {
8890
             "require": {
8929
                 "uuid"
8929
                 "uuid"
8930
             ],
8930
             ],
8931
             "support": {
8931
             "support": {
8932
-                "source": "https://github.com/symfony/uid/tree/v7.1.1"
8932
+                "source": "https://github.com/symfony/uid/tree/v7.1.4"
8933
             },
8933
             },
8934
             "funding": [
8934
             "funding": [
8935
                 {
8935
                 {
8945
                     "type": "tidelift"
8945
                     "type": "tidelift"
8946
                 }
8946
                 }
8947
             ],
8947
             ],
8948
-            "time": "2024-05-31T14:57:53+00:00"
8948
+            "time": "2024-08-12T09:59:40+00:00"
8949
         },
8949
         },
8950
         {
8950
         {
8951
             "name": "symfony/var-dumper",
8951
             "name": "symfony/var-dumper",
8952
-            "version": "v7.1.3",
8952
+            "version": "v7.1.4",
8953
             "source": {
8953
             "source": {
8954
                 "type": "git",
8954
                 "type": "git",
8955
                 "url": "https://github.com/symfony/var-dumper.git",
8955
                 "url": "https://github.com/symfony/var-dumper.git",
8956
-                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f"
8956
+                "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa"
8957
             },
8957
             },
8958
             "dist": {
8958
             "dist": {
8959
                 "type": "zip",
8959
                 "type": "zip",
8960
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f",
8961
-                "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f",
8960
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a5fa7481b199090964d6fd5dab6294d5a870c7aa",
8961
+                "reference": "a5fa7481b199090964d6fd5dab6294d5a870c7aa",
8962
                 "shasum": ""
8962
                 "shasum": ""
8963
             },
8963
             },
8964
             "require": {
8964
             "require": {
9012
                 "dump"
9012
                 "dump"
9013
             ],
9013
             ],
9014
             "support": {
9014
             "support": {
9015
-                "source": "https://github.com/symfony/var-dumper/tree/v7.1.3"
9015
+                "source": "https://github.com/symfony/var-dumper/tree/v7.1.4"
9016
             },
9016
             },
9017
             "funding": [
9017
             "funding": [
9018
                 {
9018
                 {
9028
                     "type": "tidelift"
9028
                     "type": "tidelift"
9029
                 }
9029
                 }
9030
             ],
9030
             ],
9031
-            "time": "2024-07-26T12:41:01+00:00"
9031
+            "time": "2024-08-30T16:12:47+00:00"
9032
         },
9032
         },
9033
         {
9033
         {
9034
             "name": "tijsverkoyen/css-to-inline-styles",
9034
             "name": "tijsverkoyen/css-to-inline-styles",
10103
         },
10103
         },
10104
         {
10104
         {
10105
             "name": "phpstan/phpstan",
10105
             "name": "phpstan/phpstan",
10106
-            "version": "1.11.11",
10106
+            "version": "1.12.0",
10107
             "source": {
10107
             "source": {
10108
                 "type": "git",
10108
                 "type": "git",
10109
                 "url": "https://github.com/phpstan/phpstan.git",
10109
                 "url": "https://github.com/phpstan/phpstan.git",
10110
-                "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3"
10110
+                "reference": "384af967d35b2162f69526c7276acadce534d0e1"
10111
             },
10111
             },
10112
             "dist": {
10112
             "dist": {
10113
                 "type": "zip",
10113
                 "type": "zip",
10114
-                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3",
10115
-                "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3",
10114
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1",
10115
+                "reference": "384af967d35b2162f69526c7276acadce534d0e1",
10116
                 "shasum": ""
10116
                 "shasum": ""
10117
             },
10117
             },
10118
             "require": {
10118
             "require": {
10157
                     "type": "github"
10157
                     "type": "github"
10158
                 }
10158
                 }
10159
             ],
10159
             ],
10160
-            "time": "2024-08-19T14:37:29+00:00"
10160
+            "time": "2024-08-27T09:18:05+00:00"
10161
         },
10161
         },
10162
         {
10162
         {
10163
             "name": "phpunit/php-code-coverage",
10163
             "name": "phpunit/php-code-coverage",
12302
         },
12302
         },
12303
         {
12303
         {
12304
             "name": "symfony/yaml",
12304
             "name": "symfony/yaml",
12305
-            "version": "v7.1.1",
12305
+            "version": "v7.1.4",
12306
             "source": {
12306
             "source": {
12307
                 "type": "git",
12307
                 "type": "git",
12308
                 "url": "https://github.com/symfony/yaml.git",
12308
                 "url": "https://github.com/symfony/yaml.git",
12309
-                "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
12309
+                "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b"
12310
             },
12310
             },
12311
             "dist": {
12311
             "dist": {
12312
                 "type": "zip",
12312
                 "type": "zip",
12313
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
12314
-                "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
12313
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/92e080b851c1c655c786a2da77f188f2dccd0f4b",
12314
+                "reference": "92e080b851c1c655c786a2da77f188f2dccd0f4b",
12315
                 "shasum": ""
12315
                 "shasum": ""
12316
             },
12316
             },
12317
             "require": {
12317
             "require": {
12353
             "description": "Loads and dumps YAML files",
12353
             "description": "Loads and dumps YAML files",
12354
             "homepage": "https://symfony.com",
12354
             "homepage": "https://symfony.com",
12355
             "support": {
12355
             "support": {
12356
-                "source": "https://github.com/symfony/yaml/tree/v7.1.1"
12356
+                "source": "https://github.com/symfony/yaml/tree/v7.1.4"
12357
             },
12357
             },
12358
             "funding": [
12358
             "funding": [
12359
                 {
12359
                 {
12369
                     "type": "tidelift"
12369
                     "type": "tidelift"
12370
                 }
12370
                 }
12371
             ],
12371
             ],
12372
-            "time": "2024-05-31T14:57:53+00:00"
12372
+            "time": "2024-08-12T09:59:40+00:00"
12373
         },
12373
         },
12374
         {
12374
         {
12375
             "name": "theseer/tokenizer",
12375
             "name": "theseer/tokenizer",

+ 87
- 87
package-lock.json 查看文件

541
             }
541
             }
542
         },
542
         },
543
         "node_modules/@rollup/rollup-android-arm-eabi": {
543
         "node_modules/@rollup/rollup-android-arm-eabi": {
544
-            "version": "4.21.0",
545
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz",
546
-            "integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==",
544
+            "version": "4.21.2",
545
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
546
+            "integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
547
             "cpu": [
547
             "cpu": [
548
                 "arm"
548
                 "arm"
549
             ],
549
             ],
555
             ]
555
             ]
556
         },
556
         },
557
         "node_modules/@rollup/rollup-android-arm64": {
557
         "node_modules/@rollup/rollup-android-arm64": {
558
-            "version": "4.21.0",
559
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz",
560
-            "integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==",
558
+            "version": "4.21.2",
559
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
560
+            "integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
561
             "cpu": [
561
             "cpu": [
562
                 "arm64"
562
                 "arm64"
563
             ],
563
             ],
569
             ]
569
             ]
570
         },
570
         },
571
         "node_modules/@rollup/rollup-darwin-arm64": {
571
         "node_modules/@rollup/rollup-darwin-arm64": {
572
-            "version": "4.21.0",
573
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz",
574
-            "integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==",
572
+            "version": "4.21.2",
573
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
574
+            "integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
575
             "cpu": [
575
             "cpu": [
576
                 "arm64"
576
                 "arm64"
577
             ],
577
             ],
583
             ]
583
             ]
584
         },
584
         },
585
         "node_modules/@rollup/rollup-darwin-x64": {
585
         "node_modules/@rollup/rollup-darwin-x64": {
586
-            "version": "4.21.0",
587
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz",
588
-            "integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==",
586
+            "version": "4.21.2",
587
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
588
+            "integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
589
             "cpu": [
589
             "cpu": [
590
                 "x64"
590
                 "x64"
591
             ],
591
             ],
597
             ]
597
             ]
598
         },
598
         },
599
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
599
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
600
-            "version": "4.21.0",
601
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz",
602
-            "integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==",
600
+            "version": "4.21.2",
601
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
602
+            "integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
603
             "cpu": [
603
             "cpu": [
604
                 "arm"
604
                 "arm"
605
             ],
605
             ],
611
             ]
611
             ]
612
         },
612
         },
613
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
613
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
614
-            "version": "4.21.0",
615
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz",
616
-            "integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==",
614
+            "version": "4.21.2",
615
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
616
+            "integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
617
             "cpu": [
617
             "cpu": [
618
                 "arm"
618
                 "arm"
619
             ],
619
             ],
625
             ]
625
             ]
626
         },
626
         },
627
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
627
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
628
-            "version": "4.21.0",
629
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz",
630
-            "integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==",
628
+            "version": "4.21.2",
629
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
630
+            "integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
631
             "cpu": [
631
             "cpu": [
632
                 "arm64"
632
                 "arm64"
633
             ],
633
             ],
639
             ]
639
             ]
640
         },
640
         },
641
         "node_modules/@rollup/rollup-linux-arm64-musl": {
641
         "node_modules/@rollup/rollup-linux-arm64-musl": {
642
-            "version": "4.21.0",
643
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz",
644
-            "integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==",
642
+            "version": "4.21.2",
643
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
644
+            "integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
645
             "cpu": [
645
             "cpu": [
646
                 "arm64"
646
                 "arm64"
647
             ],
647
             ],
653
             ]
653
             ]
654
         },
654
         },
655
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
655
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
656
-            "version": "4.21.0",
657
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz",
658
-            "integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==",
656
+            "version": "4.21.2",
657
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
658
+            "integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
659
             "cpu": [
659
             "cpu": [
660
                 "ppc64"
660
                 "ppc64"
661
             ],
661
             ],
667
             ]
667
             ]
668
         },
668
         },
669
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
669
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
670
-            "version": "4.21.0",
671
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz",
672
-            "integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==",
670
+            "version": "4.21.2",
671
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
672
+            "integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
673
             "cpu": [
673
             "cpu": [
674
                 "riscv64"
674
                 "riscv64"
675
             ],
675
             ],
681
             ]
681
             ]
682
         },
682
         },
683
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
683
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
684
-            "version": "4.21.0",
685
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz",
686
-            "integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==",
684
+            "version": "4.21.2",
685
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
686
+            "integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
687
             "cpu": [
687
             "cpu": [
688
                 "s390x"
688
                 "s390x"
689
             ],
689
             ],
695
             ]
695
             ]
696
         },
696
         },
697
         "node_modules/@rollup/rollup-linux-x64-gnu": {
697
         "node_modules/@rollup/rollup-linux-x64-gnu": {
698
-            "version": "4.21.0",
699
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz",
700
-            "integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==",
698
+            "version": "4.21.2",
699
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
700
+            "integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
701
             "cpu": [
701
             "cpu": [
702
                 "x64"
702
                 "x64"
703
             ],
703
             ],
709
             ]
709
             ]
710
         },
710
         },
711
         "node_modules/@rollup/rollup-linux-x64-musl": {
711
         "node_modules/@rollup/rollup-linux-x64-musl": {
712
-            "version": "4.21.0",
713
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz",
714
-            "integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==",
712
+            "version": "4.21.2",
713
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
714
+            "integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
715
             "cpu": [
715
             "cpu": [
716
                 "x64"
716
                 "x64"
717
             ],
717
             ],
723
             ]
723
             ]
724
         },
724
         },
725
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
725
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
726
-            "version": "4.21.0",
727
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz",
728
-            "integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==",
726
+            "version": "4.21.2",
727
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
728
+            "integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
729
             "cpu": [
729
             "cpu": [
730
                 "arm64"
730
                 "arm64"
731
             ],
731
             ],
737
             ]
737
             ]
738
         },
738
         },
739
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
739
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
740
-            "version": "4.21.0",
741
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz",
742
-            "integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==",
740
+            "version": "4.21.2",
741
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
742
+            "integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
743
             "cpu": [
743
             "cpu": [
744
                 "ia32"
744
                 "ia32"
745
             ],
745
             ],
751
             ]
751
             ]
752
         },
752
         },
753
         "node_modules/@rollup/rollup-win32-x64-msvc": {
753
         "node_modules/@rollup/rollup-win32-x64-msvc": {
754
-            "version": "4.21.0",
755
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz",
756
-            "integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==",
754
+            "version": "4.21.2",
755
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
756
+            "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
757
             "cpu": [
757
             "cpu": [
758
                 "x64"
758
                 "x64"
759
             ],
759
             ],
765
             ]
765
             ]
766
         },
766
         },
767
         "node_modules/@tailwindcss/forms": {
767
         "node_modules/@tailwindcss/forms": {
768
-            "version": "0.5.7",
769
-            "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz",
770
-            "integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==",
768
+            "version": "0.5.8",
769
+            "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.8.tgz",
770
+            "integrity": "sha512-DJs7B7NPD0JH7BVvdHWNviWmunlFhuEkz7FyFxE4japOWYMLl9b1D6+Z9mivJJPWr6AEbmlPqgiFRyLwFB1SgQ==",
771
             "dev": true,
771
             "dev": true,
772
             "license": "MIT",
772
             "license": "MIT",
773
             "dependencies": {
773
             "dependencies": {
774
                 "mini-svg-data-uri": "^1.2.3"
774
                 "mini-svg-data-uri": "^1.2.3"
775
             },
775
             },
776
             "peerDependencies": {
776
             "peerDependencies": {
777
-                "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
777
+                "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20"
778
             }
778
             }
779
         },
779
         },
780
         "node_modules/@tailwindcss/typography": {
780
         "node_modules/@tailwindcss/typography": {
781
-            "version": "0.5.14",
782
-            "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.14.tgz",
783
-            "integrity": "sha512-ZvOCjUbsJBjL9CxQBn+VEnFpouzuKhxh2dH8xMIWHILL+HfOYtlAkWcyoon8LlzE53d2Yo6YO6pahKKNW3q1YQ==",
781
+            "version": "0.5.15",
782
+            "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz",
783
+            "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==",
784
             "dev": true,
784
             "dev": true,
785
             "license": "MIT",
785
             "license": "MIT",
786
             "dependencies": {
786
             "dependencies": {
790
                 "postcss-selector-parser": "6.0.10"
790
                 "postcss-selector-parser": "6.0.10"
791
             },
791
             },
792
             "peerDependencies": {
792
             "peerDependencies": {
793
-                "tailwindcss": ">=3.0.0 || insiders"
793
+                "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20"
794
             }
794
             }
795
         },
795
         },
796
         "node_modules/@types/estree": {
796
         "node_modules/@types/estree": {
900
             }
900
             }
901
         },
901
         },
902
         "node_modules/axios": {
902
         "node_modules/axios": {
903
-            "version": "1.7.5",
904
-            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz",
905
-            "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==",
903
+            "version": "1.7.6",
904
+            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.6.tgz",
905
+            "integrity": "sha512-Ekur6XDwhnJ5RgOCaxFnXyqlPALI3rVeukZMwOdfghW7/wGz784BYKiQq+QD8NPcr91KRo30KfHOchyijwWw7g==",
906
             "dev": true,
906
             "dev": true,
907
             "license": "MIT",
907
             "license": "MIT",
908
             "dependencies": {
908
             "dependencies": {
998
             }
998
             }
999
         },
999
         },
1000
         "node_modules/caniuse-lite": {
1000
         "node_modules/caniuse-lite": {
1001
-            "version": "1.0.30001651",
1002
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
1003
-            "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
1001
+            "version": "1.0.30001655",
1002
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz",
1003
+            "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==",
1004
             "dev": true,
1004
             "dev": true,
1005
             "funding": [
1005
             "funding": [
1006
                 {
1006
                 {
1212
             }
1212
             }
1213
         },
1213
         },
1214
         "node_modules/escalade": {
1214
         "node_modules/escalade": {
1215
-            "version": "3.1.2",
1216
-            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
1217
-            "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
1215
+            "version": "3.2.0",
1216
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1217
+            "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1218
             "dev": true,
1218
             "dev": true,
1219
             "license": "MIT",
1219
             "license": "MIT",
1220
             "engines": {
1220
             "engines": {
1826
             }
1826
             }
1827
         },
1827
         },
1828
         "node_modules/postcss": {
1828
         "node_modules/postcss": {
1829
-            "version": "8.4.41",
1830
-            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
1831
-            "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
1829
+            "version": "8.4.42",
1830
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.42.tgz",
1831
+            "integrity": "sha512-hywKUQB9Ra4dR1mGhldy5Aj1X3MWDSIA1cEi+Uy0CjheLvP6Ual5RlwMCh8i/X121yEDLDIKBsrCQ8ba3FDMfQ==",
1832
             "dev": true,
1832
             "dev": true,
1833
             "funding": [
1833
             "funding": [
1834
                 {
1834
                 {
2171
             }
2171
             }
2172
         },
2172
         },
2173
         "node_modules/rollup": {
2173
         "node_modules/rollup": {
2174
-            "version": "4.21.0",
2175
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz",
2176
-            "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==",
2174
+            "version": "4.21.2",
2175
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
2176
+            "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
2177
             "dev": true,
2177
             "dev": true,
2178
             "license": "MIT",
2178
             "license": "MIT",
2179
             "dependencies": {
2179
             "dependencies": {
2187
                 "npm": ">=8.0.0"
2187
                 "npm": ">=8.0.0"
2188
             },
2188
             },
2189
             "optionalDependencies": {
2189
             "optionalDependencies": {
2190
-                "@rollup/rollup-android-arm-eabi": "4.21.0",
2191
-                "@rollup/rollup-android-arm64": "4.21.0",
2192
-                "@rollup/rollup-darwin-arm64": "4.21.0",
2193
-                "@rollup/rollup-darwin-x64": "4.21.0",
2194
-                "@rollup/rollup-linux-arm-gnueabihf": "4.21.0",
2195
-                "@rollup/rollup-linux-arm-musleabihf": "4.21.0",
2196
-                "@rollup/rollup-linux-arm64-gnu": "4.21.0",
2197
-                "@rollup/rollup-linux-arm64-musl": "4.21.0",
2198
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0",
2199
-                "@rollup/rollup-linux-riscv64-gnu": "4.21.0",
2200
-                "@rollup/rollup-linux-s390x-gnu": "4.21.0",
2201
-                "@rollup/rollup-linux-x64-gnu": "4.21.0",
2202
-                "@rollup/rollup-linux-x64-musl": "4.21.0",
2203
-                "@rollup/rollup-win32-arm64-msvc": "4.21.0",
2204
-                "@rollup/rollup-win32-ia32-msvc": "4.21.0",
2205
-                "@rollup/rollup-win32-x64-msvc": "4.21.0",
2190
+                "@rollup/rollup-android-arm-eabi": "4.21.2",
2191
+                "@rollup/rollup-android-arm64": "4.21.2",
2192
+                "@rollup/rollup-darwin-arm64": "4.21.2",
2193
+                "@rollup/rollup-darwin-x64": "4.21.2",
2194
+                "@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
2195
+                "@rollup/rollup-linux-arm-musleabihf": "4.21.2",
2196
+                "@rollup/rollup-linux-arm64-gnu": "4.21.2",
2197
+                "@rollup/rollup-linux-arm64-musl": "4.21.2",
2198
+                "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
2199
+                "@rollup/rollup-linux-riscv64-gnu": "4.21.2",
2200
+                "@rollup/rollup-linux-s390x-gnu": "4.21.2",
2201
+                "@rollup/rollup-linux-x64-gnu": "4.21.2",
2202
+                "@rollup/rollup-linux-x64-musl": "4.21.2",
2203
+                "@rollup/rollup-win32-arm64-msvc": "4.21.2",
2204
+                "@rollup/rollup-win32-ia32-msvc": "4.21.2",
2205
+                "@rollup/rollup-win32-x64-msvc": "4.21.2",
2206
                 "fsevents": "~2.3.2"
2206
                 "fsevents": "~2.3.2"
2207
             }
2207
             }
2208
         },
2208
         },

+ 9
- 11
resources/css/filament/company/theme.css 查看文件

13
 }
13
 }
14
 
14
 
15
 .choices__group {
15
 .choices__group {
16
-    color: rgba(var(--gray-900), 1);
17
-    font-weight: bold;
16
+    @apply text-gray-900 dark:text-white font-semibold;
18
 }
17
 }
19
 
18
 
20
 .choices[data-type="select-one"] .choices__inner {
19
 .choices[data-type="select-one"] .choices__inner {
25
     box-sizing: border-box;
24
     box-sizing: border-box;
26
 }
25
 }
27
 
26
 
28
-.choices__item {
27
+.choices:not(.is-disabled) .choices__item {
29
     cursor: pointer;
28
     cursor: pointer;
30
 }
29
 }
31
 
30
 
148
     left: 0;
147
     left: 0;
149
     width: 100%;
148
     width: 100%;
150
     height: 100%;
149
     height: 100%;
151
-    background-image:
152
-        linear-gradient(99.6deg,
153
-            rgba(232, 233, 235, 1) 10.6%,
154
-            rgba(240, 241, 243, 1) 32.9%,
155
-            rgba(248, 249, 251, 0.7) 50%,
156
-            rgba(240, 241, 243, 1) 67.1%,
157
-            rgba(232, 233, 235, 1) 83.4%);
150
+    background-image: linear-gradient(99.6deg,
151
+    rgba(232, 233, 235, 1) 10.6%,
152
+    rgba(240, 241, 243, 1) 32.9%,
153
+    rgba(248, 249, 251, 0.7) 50%,
154
+    rgba(240, 241, 243, 1) 67.1%,
155
+    rgba(232, 233, 235, 1) 83.4%);
158
     pointer-events: none;
156
     pointer-events: none;
159
     z-index: -1;
157
     z-index: -1;
160
 }
158
 }
178
         rgba(var(--primary-900), 0.5) 45%,
176
         rgba(var(--primary-900), 0.5) 45%,
179
         rgba(var(--primary-950), 0.3) 60%,
177
         rgba(var(--primary-950), 0.3) 60%,
180
         rgba(var(--primary-950), 0.1) 75%,
178
         rgba(var(--primary-950), 0.1) 75%,
181
-        rgba(3,7,18,0) 100%
179
+        rgba(3, 7, 18, 0) 100%
182
     );
180
     );
183
     width: 100%;
181
     width: 100%;
184
     height: 100%;
182
     height: 100%;

+ 1
- 1
resources/views/components/company/tables/reports/detailed-report.blade.php 查看文件

34
                                         icon="heroicon-o-arrow-top-right-on-square"
34
                                         icon="heroicon-o-arrow-top-right-on-square"
35
                                         :icon-position="\Filament\Support\Enums\IconPosition::After"
35
                                         :icon-position="\Filament\Support\Enums\IconPosition::After"
36
                                         :icon-size="\Filament\Support\Enums\IconSize::Small"
36
                                         :icon-size="\Filament\Support\Enums\IconSize::Small"
37
-                                        href="{{ \App\Filament\Company\Pages\Reports\AccountTransactions::getUrl(['account_id' => $cell['id']]) }}"
37
+                                        href="{{ \App\Filament\Company\Pages\Reports\AccountTransactions::getUrl(['selectedAccount' => $cell['id']]) }}"
38
                                     >
38
                                     >
39
                                         {{ $cell['name'] }}
39
                                         {{ $cell['name'] }}
40
                                     </x-filament::link>
40
                                     </x-filament::link>

+ 14
- 7
resources/views/components/panel-shift-dropdown.blade.php 查看文件

11
     $panels = $component->getNavigationAsHierarchyArray();
11
     $panels = $component->getNavigationAsHierarchyArray();
12
 @endphp
12
 @endphp
13
 
13
 
14
-<div x-data="panelShiftDropdown">
15
-    <div x-on:click="toggleDropdown()" class="flex cursor-pointer">
14
+<div x-data="panelShiftDropdown" x-on:click.outside="closeDropdown">
15
+    <div x-on:click="toggleDropdown" class="flex cursor-pointer">
16
         <button
16
         <button
17
             type="button"
17
             type="button"
18
             class="fi-tenant-menu-trigger group flex w-full items-center justify-center gap-x-3 rounded-lg p-2 text-sm font-medium outline-none transition duration-75 hover:bg-gray-100 focus-visible:bg-gray-100 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
18
             class="fi-tenant-menu-trigger group flex w-full items-center justify-center gap-x-3 rounded-lg p-2 text-sm font-medium outline-none transition duration-75 hover:bg-gray-100 focus-visible:bg-gray-100 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
41
             />
41
             />
42
         </button>
42
         </button>
43
     </div>
43
     </div>
44
-    <div x-show="open" class="flex flex-col transition duration-200 ease-in-out grow shrink mt-4 absolute z-10 w-screen max-w-[360px] end-8 rounded-lg bg-white shadow-lg ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 overflow-hidden">
44
+    <div x-show="open"
45
+         class="flex flex-col transition duration-200 ease-in-out grow shrink mt-4 absolute z-10 w-screen max-w-[360px] end-8 rounded-lg bg-white shadow-lg ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 overflow-hidden">
45
         @foreach($panels as $panelId => $panel)
46
         @foreach($panels as $panelId => $panel)
46
             <x-panel-shift-dropdown.panel :panel-id="$panelId">
47
             <x-panel-shift-dropdown.panel :panel-id="$panelId">
47
                 @if($panelId !== 'main' && isset($panel['label']))
48
                 @if($panelId !== 'main' && isset($panel['label']))
48
-                    <x-panel-shift-dropdown.subpanel-header :label="$panel['label']" :panel-id="$panelId" />
49
+                    <x-panel-shift-dropdown.subpanel-header :label="$panel['label']" :panel-id="$panelId"/>
49
                 @endif
50
                 @endif
50
                 @if($panel['renderItems'])
51
                 @if($panel['renderItems'])
51
                     @foreach($panel['items'] as $item)
52
                     @foreach($panel['items'] as $item)
52
-                        <x-panel-shift-dropdown.content-handler :item="$item" />
53
+                        <x-panel-shift-dropdown.content-handler :item="$item"/>
53
                     @endforeach
54
                     @endforeach
54
                 @endif
55
                 @endif
55
                 @if($panelId === 'company-settings')
56
                 @if($panelId === 'company-settings')
56
-                    <x-panel-shift-dropdown.company-settings :current-tenant="$currentTenant" icon="heroicon-m-building-office-2" />
57
+                    <x-panel-shift-dropdown.company-settings :current-tenant="$currentTenant"
58
+                                                             icon="heroicon-m-building-office-2"/>
57
                 @endif
59
                 @endif
58
                 @if($panelId === 'company-switcher')
60
                 @if($panelId === 'company-switcher')
59
-                    <x-panel-shift-dropdown.company-switcher :current-tenant="$currentTenant" icon="heroicon-m-adjustments-horizontal" />
61
+                    <x-panel-shift-dropdown.company-switcher :current-tenant="$currentTenant"
62
+                                                             icon="heroicon-m-adjustments-horizontal"/>
60
                 @endif
63
                 @endif
61
                 @if($panelId === 'display-and-accessibility')
64
                 @if($panelId === 'display-and-accessibility')
62
                     <x-panel-shift-dropdown.display-accessibility icon="heroicon-s-moon"/>
65
                     <x-panel-shift-dropdown.display-accessibility icon="heroicon-s-moon"/>
91
                 this.open = !this.open;
94
                 this.open = !this.open;
92
             },
95
             },
93
 
96
 
97
+            closeDropdown() {
98
+                this.open = false;
99
+            },
100
+
94
             setActiveMenu(menu) {
101
             setActiveMenu(menu) {
95
                 this.transitionPanel(menu, 'forward');
102
                 this.transitionPanel(menu, 'forward');
96
             },
103
             },

+ 1
- 1
resources/views/filament/company/pages/reports/account-transactions.blade.php 查看文件

4
             {{ $this->form }}
4
             {{ $this->form }}
5
         </form>
5
         </form>
6
     </x-filament::section>
6
     </x-filament::section>
7
-    
7
+
8
     <x-filament-tables::container>
8
     <x-filament-tables::container>
9
         <div class="es-table__header-ctn"></div>
9
         <div class="es-table__header-ctn"></div>
10
         <div
10
         <div

+ 18
- 22
resources/views/filament/company/pages/reports/income-statement.blade.php 查看文件

1
 <x-filament-panels::page>
1
 <x-filament-panels::page>
2
     <x-filament::section>
2
     <x-filament::section>
3
-        <form wire:submit="loadReportData">
4
-            <div class="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 md:gap-8">
5
-                <!-- Form Container -->
6
-                <div class="flex-grow">
7
-                    {{ $this->form }}
8
-                </div>
3
+        <div class="flex flex-col md:flex-row items-start md:items-center justify-between gap-4 md:gap-8">
4
+            <!-- Form Container -->
5
+            <div class="flex-grow">
6
+                {{ $this->getFiltersForm() }}
7
+            </div>
9
 
8
 
10
-                <!-- Grouping Button and Column Toggle -->
11
-                <div class="flex flex-col md:flex-row items-start md:items-center gap-4 md:gap-8 flex-shrink-0">
12
-                    @if($this->hasToggleableColumns())
13
-                        <x-filament-tables::column-toggle.dropdown
14
-                            :form="$this->toggleTableColumnForm"
15
-                            :trigger-action="$this->toggleColumnsAction"
16
-                        />
17
-                    @endif
18
-                    <x-filament::button type="submit" wire:target="loadReportData" class="flex-shrink-0">
19
-                        Update Report
20
-                    </x-filament::button>
21
-                </div>
9
+            <!-- Grouping Button and Column Toggle -->
10
+            <div class="flex flex-col md:flex-row items-start md:items-center gap-4 md:gap-8 flex-shrink-0">
11
+                @if($this->hasToggleableColumns())
12
+                    <x-filament-tables::column-toggle.dropdown
13
+                        :form="$this->toggleTableColumnForm"
14
+                        :trigger-action="$this->toggleColumnsAction"
15
+                    />
16
+                @endif
17
+                {{ $this->getFiltersApplyAction() }}
22
             </div>
18
             </div>
23
-        </form>
19
+        </div>
24
     </x-filament::section>
20
     </x-filament::section>
25
 
21
 
26
 
22
 
63
 
59
 
64
     <x-filament-tables::container>
60
     <x-filament-tables::container>
65
         <div class="es-table__header-ctn"></div>
61
         <div class="es-table__header-ctn"></div>
66
-        <div wire:init="loadReportData"
62
+        <div wire:init="applyFilters"
67
              class="relative divide-y divide-gray-200 overflow-x-auto dark:divide-white/10 dark:border-t-white/10 min-h-64">
63
              class="relative divide-y divide-gray-200 overflow-x-auto dark:divide-white/10 dark:border-t-white/10 min-h-64">
68
             @if($this->reportLoaded)
64
             @if($this->reportLoaded)
69
-                <div wire:loading.remove wire:target="loadReportData">
65
+                <div wire:loading.remove wire:target="applyFilters">
70
                     @if($this->report)
66
                     @if($this->report)
71
                         <x-company.tables.reports.detailed-report :report="$this->report"/>
67
                         <x-company.tables.reports.detailed-report :report="$this->report"/>
72
                     @endif
68
                     @endif
73
                 </div>
69
                 </div>
74
             @else
70
             @else
75
                 <div class="absolute inset-0 flex items-center justify-center">
71
                 <div class="absolute inset-0 flex items-center justify-center">
76
-                    <div wire:loading wire:target="loadReportData">
72
+                    <div wire:loading wire:target="applyFilters">
77
                         <x-filament::loading-indicator class="p-6 text-primary-700 dark:text-primary-300"/>
73
                         <x-filament::loading-indicator class="p-6 text-primary-700 dark:text-primary-300"/>
78
                     </div>
74
                     </div>
79
                 </div>
75
                 </div>

Loading…
取消
儲存