wallo пре 1 година
родитељ
комит
7e5e921479
26 измењених фајлова са 666 додато и 527 уклоњено
  1. 5
    0
      app/Contracts/ExportableReport.php
  2. 18
    0
      app/DTO/ReportCategoryDTO.php
  3. 12
    0
      app/Filament/Company/Pages/Accounting/AccountChart.php
  4. 32
    8
      app/Filament/Company/Pages/Accounting/Transactions.php
  5. 18
    3
      app/Filament/Company/Pages/Reports/AccountBalances.php
  6. 3
    0
      app/Filament/Company/Pages/Reports/BaseReportPage.php
  7. 9
    4
      app/Filament/Company/Resources/Banking/AccountResource.php
  8. 0
    1
      app/Listeners/ConfigureChartOfAccounts.php
  9. 2
    2
      app/Models/Accounting/Account.php
  10. 0
    2
      app/Models/Company.php
  11. 9
    0
      app/Observers/AccountObserver.php
  12. 0
    88
      app/Providers/EventServiceProvider.php
  13. 0
    1
      app/Repositories/Banking/ConnectedBankAccountRepository.php
  14. 3
    3
      app/Services/ExportService.php
  15. 77
    28
      app/Transformers/AccountBalanceReportTransformer.php
  16. 4
    1
      app/Transformers/BaseReportTransformer.php
  17. 9
    5
      app/Transformers/TrialBalanceReportTransformer.php
  18. 0
    1
      bootstrap/providers.php
  19. 314
    238
      composer.lock
  20. 1
    1
      database/migrations/2023_09_03_100000_create_accounting_tables.php
  21. 129
    129
      package-lock.json
  22. 2
    1
      resources/data/lang/en.json
  23. 3
    3
      resources/views/components/company/reports/report-pdf.blade.php
  24. 3
    3
      resources/views/components/company/tables/reports/detailed-report.blade.php
  25. 11
    3
      resources/views/filament/company/pages/accounting/chart.blade.php
  26. 2
    2
      resources/views/filament/company/pages/reports/account-balances.blade.php

+ 5
- 0
app/Contracts/ExportableReport.php Прегледај датотеку

2
 
2
 
3
 namespace App\Contracts;
3
 namespace App\Contracts;
4
 
4
 
5
+use App\DTO\ReportCategoryDTO;
6
+
5
 interface ExportableReport
7
 interface ExportableReport
6
 {
8
 {
7
     public function getTitle(): string;
9
     public function getTitle(): string;
8
 
10
 
9
     public function getHeaders(): array;
11
     public function getHeaders(): array;
10
 
12
 
13
+    /**
14
+     * @return ReportCategoryDTO[]
15
+     */
11
     public function getCategories(): array;
16
     public function getCategories(): array;
12
 
17
 
13
     public function getOverallTotals(): array;
18
     public function getOverallTotals(): array;

+ 18
- 0
app/DTO/ReportCategoryDTO.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\DTO;
4
+
5
+class ReportCategoryDTO
6
+{
7
+    /**
8
+     * @param  string[]  $header
9
+     * @param  string[][]  $data
10
+     * @param  string[]  $summary
11
+     */
12
+    public function __construct(
13
+        public array $header,
14
+        public array $data,
15
+        public array $summary,
16
+    ) {
17
+    }
18
+}

+ 12
- 0
app/Filament/Company/Pages/Accounting/AccountChart.php Прегледај датотеку

10
 use Filament\Actions\Action;
10
 use Filament\Actions\Action;
11
 use Filament\Actions\CreateAction;
11
 use Filament\Actions\CreateAction;
12
 use Filament\Actions\EditAction;
12
 use Filament\Actions\EditAction;
13
+use Filament\Forms\Components\Checkbox;
13
 use Filament\Forms\Components\Component;
14
 use Filament\Forms\Components\Component;
14
 use Filament\Forms\Components\Select;
15
 use Filament\Forms\Components\Select;
15
 use Filament\Forms\Components\Textarea;
16
 use Filament\Forms\Components\Textarea;
98
                 $this->getNameFormComponent(),
99
                 $this->getNameFormComponent(),
99
                 $this->getCurrencyFormComponent(),
100
                 $this->getCurrencyFormComponent(),
100
                 $this->getDescriptionFormComponent(),
101
                 $this->getDescriptionFormComponent(),
102
+                $this->getArchiveFormComponent(),
101
             ]);
103
             ]);
102
     }
104
     }
103
 
105
 
161
             ->autosize();
163
             ->autosize();
162
     }
164
     }
163
 
165
 
166
+    protected function getArchiveFormComponent(): Component
167
+    {
168
+        return Checkbox::make('archived')
169
+            ->label('Archive Account')
170
+            ->helperText('Archived accounts will not be available for selection in transactions.')
171
+            ->hidden(static function (string $operation): bool {
172
+                return $operation === 'create';
173
+            });
174
+    }
175
+
164
     private function getChartSubtypeOptions($useActiveTab = true): array
176
     private function getChartSubtypeOptions($useActiveTab = true): array
165
     {
177
     {
166
         $subtypes = $useActiveTab ?
178
         $subtypes = $useActiveTab ?

+ 32
- 8
app/Filament/Company/Pages/Accounting/Transactions.php Прегледај датотеку

11
 use App\Filament\Forms\Components\DateRangeSelect;
11
 use App\Filament\Forms\Components\DateRangeSelect;
12
 use App\Filament\Forms\Components\JournalEntryRepeater;
12
 use App\Filament\Forms\Components\JournalEntryRepeater;
13
 use App\Models\Accounting\Account;
13
 use App\Models\Accounting\Account;
14
+use App\Models\Accounting\JournalEntry;
14
 use App\Models\Accounting\Transaction;
15
 use App\Models\Accounting\Transaction;
15
 use App\Models\Banking\BankAccount;
16
 use App\Models\Banking\BankAccount;
16
 use App\Models\Company;
17
 use App\Models\Company;
150
                     ->label('Description'),
151
                     ->label('Description'),
151
                 Forms\Components\Select::make('bank_account_id')
152
                 Forms\Components\Select::make('bank_account_id')
152
                     ->label('Account')
153
                     ->label('Account')
153
-                    ->options(fn () => $this->getBankAccountOptions())
154
+                    ->options(fn (?Transaction $transaction) => $this->getBankAccountOptions(currentBankAccountId: $transaction?->bank_account_id))
154
                     ->live()
155
                     ->live()
155
                     ->searchable()
156
                     ->searchable()
156
                     ->afterStateUpdated(function (Set $set, $state, $old, Get $get) {
157
                     ->afterStateUpdated(function (Set $set, $state, $old, Get $get) {
180
                     ->required(),
181
                     ->required(),
181
                 Forms\Components\Select::make('account_id')
182
                 Forms\Components\Select::make('account_id')
182
                     ->label('Category')
183
                     ->label('Category')
183
-                    ->options(fn (Forms\Get $get) => $this->getChartAccountOptions(type: TransactionType::parse($get('type')), nominalAccountsOnly: true))
184
+                    ->options(fn (Forms\Get $get, ?Transaction $transaction) => $this->getChartAccountOptions(type: TransactionType::parse($get('type')), nominalAccountsOnly: true, currentAccountId: $transaction?->account_id))
184
                     ->searchable()
185
                     ->searchable()
185
                     ->preload()
186
                     ->preload()
186
                     ->required(),
187
                     ->required(),
225
                     ->sortable()
226
                     ->sortable()
226
                     ->localizeDate(),
227
                     ->localizeDate(),
227
                 Tables\Columns\TextColumn::make('description')
228
                 Tables\Columns\TextColumn::make('description')
229
+                    ->label('Description')
228
                     ->limit(30)
230
                     ->limit(30)
229
-                    ->label('Description'),
231
+                    ->toggleable(),
230
                 Tables\Columns\TextColumn::make('bankAccount.account.name')
232
                 Tables\Columns\TextColumn::make('bankAccount.account.name')
231
-                    ->label('Account'),
233
+                    ->label('Account')
234
+                    ->toggleable(),
232
                 Tables\Columns\TextColumn::make('account.name')
235
                 Tables\Columns\TextColumn::make('account.name')
233
                     ->label('Category')
236
                     ->label('Category')
237
+                    ->toggleable()
234
                     ->state(static fn (Transaction $transaction) => $transaction->account->name ?? 'Journal Entry'),
238
                     ->state(static fn (Transaction $transaction) => $transaction->account->name ?? 'Journal Entry'),
235
                 Tables\Columns\TextColumn::make('amount')
239
                 Tables\Columns\TextColumn::make('amount')
236
                     ->label('Amount')
240
                     ->label('Amount')
254
                             ->schema([
258
                             ->schema([
255
                                 Select::make('account_id')
259
                                 Select::make('account_id')
256
                                     ->label('Category')
260
                                     ->label('Category')
257
-                                    ->options(fn () => $this->getChartAccountOptions(nominalAccountsOnly: true))
261
+                                    ->options(fn () => $this->getChartAccountOptions(nominalAccountsOnly: true, onlyWithTransactions: true))
258
                                     ->multiple()
262
                                     ->multiple()
259
                                     ->searchable(),
263
                                     ->searchable(),
260
                                 Select::make('reviewed')
264
                                 Select::make('reviewed')
559
                 ->label('Description'),
563
                 ->label('Description'),
560
             Select::make('account_id')
564
             Select::make('account_id')
561
                 ->label('Account')
565
                 ->label('Account')
562
-                ->options(fn (): array => $this->getChartAccountOptions())
566
+                ->options(fn (?JournalEntry $journalEntry): array => $this->getChartAccountOptions(currentAccountId: $journalEntry?->account_id))
563
                 ->live()
567
                 ->live()
564
                 ->softRequired()
568
                 ->softRequired()
565
                 ->searchable(),
569
                 ->searchable(),
709
         return 'uncategorized';
713
         return 'uncategorized';
710
     }
714
     }
711
 
715
 
712
-    protected function getChartAccountOptions(?TransactionType $type = null, bool $nominalAccountsOnly = false): array
716
+    protected function getChartAccountOptions(?TransactionType $type = null, ?bool $nominalAccountsOnly = null, ?bool $onlyWithTransactions = null, ?int $currentAccountId = null): array
713
     {
717
     {
718
+        $onlyWithTransactions ??= false;
719
+        $nominalAccountsOnly ??= false;
720
+
714
         $excludedCategory = match ($type) {
721
         $excludedCategory = match ($type) {
715
             TransactionType::Deposit => AccountCategory::Expense,
722
             TransactionType::Deposit => AccountCategory::Expense,
716
             TransactionType::Withdrawal => AccountCategory::Revenue,
723
             TransactionType::Withdrawal => AccountCategory::Revenue,
720
         return Account::query()
727
         return Account::query()
721
             ->when($nominalAccountsOnly, fn (Builder $query) => $query->doesntHave('bankAccount'))
728
             ->when($nominalAccountsOnly, fn (Builder $query) => $query->doesntHave('bankAccount'))
722
             ->when($excludedCategory, fn (Builder $query) => $query->whereNot('category', $excludedCategory))
729
             ->when($excludedCategory, fn (Builder $query) => $query->whereNot('category', $excludedCategory))
730
+            ->when($onlyWithTransactions, fn (Builder $query) => $query->has('transactions'))
731
+            ->where(function (Builder $query) use ($currentAccountId) {
732
+                $query->where('archived', false)
733
+                    ->orWhere('id', $currentAccountId);
734
+            })
723
             ->get()
735
             ->get()
724
             ->groupBy(fn (Account $account) => $account->category->getPluralLabel())
736
             ->groupBy(fn (Account $account) => $account->category->getPluralLabel())
725
             ->map(fn (Collection $accounts, string $category) => $accounts->pluck('name', 'id'))
737
             ->map(fn (Collection $accounts, string $category) => $accounts->pluck('name', 'id'))
726
             ->toArray();
738
             ->toArray();
727
     }
739
     }
728
 
740
 
729
-    protected function getBankAccountOptions(?bool $onlyWithTransactions = null, bool $isFilter = false): array
741
+    protected function getBankAccountOptions(?bool $onlyWithTransactions = null, ?bool $isFilter = null, ?int $currentBankAccountId = null): array
730
     {
742
     {
743
+        $isFilter ??= false;
731
         $onlyWithTransactions ??= false;
744
         $onlyWithTransactions ??= false;
732
 
745
 
733
         $options = $isFilter ? [
746
         $options = $isFilter ? [
735
         ] : [];
748
         ] : [];
736
 
749
 
737
         $bankAccountOptions = BankAccount::with('account.subtype')
750
         $bankAccountOptions = BankAccount::with('account.subtype')
751
+            ->whereHas('account', function (Builder $query) use ($isFilter, $currentBankAccountId) {
752
+                if ($isFilter === false) {
753
+                    $query->where('archived', false);
754
+                }
755
+
756
+                if ($currentBankAccountId) {
757
+                    $query->orWhereHas('bankAccount', function (Builder $query) use ($currentBankAccountId) {
758
+                        $query->where('id', $currentBankAccountId);
759
+                    });
760
+                }
761
+            })
738
             ->when($onlyWithTransactions, fn (Builder $query) => $query->has('transactions'))
762
             ->when($onlyWithTransactions, fn (Builder $query) => $query->has('transactions'))
739
             ->get()
763
             ->get()
740
             ->groupBy('account.subtype.name')
764
             ->groupBy('account.subtype.name')

+ 18
- 3
app/Filament/Company/Pages/Reports/AccountBalances.php Прегледај датотеку

6
 use App\Services\ExportService;
6
 use App\Services\ExportService;
7
 use App\Services\ReportService;
7
 use App\Services\ReportService;
8
 use App\Transformers\AccountBalanceReportTransformer;
8
 use App\Transformers\AccountBalanceReportTransformer;
9
+use Filament\Forms\Components\Checkbox;
10
+use Filament\Forms\Components\CheckboxList;
11
+use Filament\Forms\Components\Grid;
9
 use Filament\Forms\Components\Split;
12
 use Filament\Forms\Components\Split;
10
 use Filament\Forms\Form;
13
 use Filament\Forms\Form;
14
+use Guava\FilamentClusters\Forms\Cluster;
11
 use Symfony\Component\HttpFoundation\StreamedResponse;
15
 use Symfony\Component\HttpFoundation\StreamedResponse;
12
 
16
 
13
 class AccountBalances extends BaseReportPage
17
 class AccountBalances extends BaseReportPage
33
     public function loadReportData(): void
37
     public function loadReportData(): void
34
     {
38
     {
35
         $reportDTO = $this->reportService->buildAccountBalanceReport($this->startDate, $this->endDate);
39
         $reportDTO = $this->reportService->buildAccountBalanceReport($this->startDate, $this->endDate);
36
-        $this->accountBalanceReport = new AccountBalanceReportTransformer($reportDTO);
40
+        $options = array_fill_keys($this->options, true);
41
+        $this->accountBalanceReport = new AccountBalanceReportTransformer($reportDTO, $options);
37
     }
42
     }
38
 
43
 
39
     public function form(Form $form): Form
44
     public function form(Form $form): Form
40
     {
45
     {
41
         return $form
46
         return $form
47
+            ->inlineLabel()
42
             ->schema([
48
             ->schema([
43
                 Split::make([
49
                 Split::make([
44
                     $this->getDateRangeFormComponent(),
50
                     $this->getDateRangeFormComponent(),
45
-                    $this->getStartDateFormComponent(),
46
-                    $this->getEndDateFormComponent(),
51
+                    Cluster::make([
52
+                        $this->getStartDateFormComponent(),
53
+                        $this->getEndDateFormComponent(),
54
+                    ])
55
+                        ->hiddenLabel(),
47
                 ])->live(),
56
                 ])->live(),
57
+                CheckboxList::make('options')
58
+                    ->options([
59
+                        'showAccountCode' => 'Show Account Code',
60
+                        'showZeroBalances' => 'Show Zero Balances',
61
+                    ])
62
+                    ->columns(2),
48
             ]);
63
             ]);
49
     }
64
     }
50
 
65
 

+ 3
- 0
app/Filament/Company/Pages/Reports/BaseReportPage.php Прегледај датотеку

29
 
29
 
30
     public Company $company;
30
     public Company $company;
31
 
31
 
32
+    public array $options = [];
33
+
32
     public function mount(): void
34
     public function mount(): void
33
     {
35
     {
34
         $this->company = auth()->user()->currentCompany;
36
         $this->company = auth()->user()->currentCompany;
36
         $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
38
         $this->fiscalYearEndDate = $this->company->locale->fiscalYearEndDate();
37
         $this->dateRange = $this->getDefaultDateRange();
39
         $this->dateRange = $this->getDefaultDateRange();
38
         $this->setDateRange(Carbon::parse($this->fiscalYearStartDate), Carbon::parse($this->fiscalYearEndDate));
40
         $this->setDateRange(Carbon::parse($this->fiscalYearStartDate), Carbon::parse($this->fiscalYearEndDate));
41
+        $this->options = ['showAccountCode'];
39
 
42
 
40
         $this->loadReportData();
43
         $this->loadReportData();
41
     }
44
     }

+ 9
- 4
app/Filament/Company/Resources/Banking/AccountResource.php Прегледај датотеку

11
 use Filament\Forms;
11
 use Filament\Forms;
12
 use Filament\Forms\Form;
12
 use Filament\Forms\Form;
13
 use Filament\Resources\Resource;
13
 use Filament\Resources\Resource;
14
+use Filament\Support\Enums\Alignment;
14
 use Filament\Support\Enums\FontWeight;
15
 use Filament\Support\Enums\FontWeight;
15
 use Filament\Tables;
16
 use Filament\Tables;
16
 use Filament\Tables\Table;
17
 use Filament\Tables\Table;
111
                     ->icon(static fn (BankAccount $record) => $record->isEnabled() ? 'heroicon-o-lock-closed' : null)
112
                     ->icon(static fn (BankAccount $record) => $record->isEnabled() ? 'heroicon-o-lock-closed' : null)
112
                     ->tooltip(static fn (BankAccount $record) => $record->isEnabled() ? 'Default Account' : null)
113
                     ->tooltip(static fn (BankAccount $record) => $record->isEnabled() ? 'Default Account' : null)
113
                     ->iconPosition('after')
114
                     ->iconPosition('after')
114
-                    ->description(static fn (BankAccount $record) => $record->mask ?? null)
115
-                    ->sortable(),
115
+                    ->description(static fn (BankAccount $record) => $record->mask ?? null),
116
+                Tables\Columns\TextColumn::make('account.subtype.name')
117
+                    ->localizeLabel('Subtype')
118
+                    ->sortable()
119
+                    ->toggleable(),
116
                 Tables\Columns\TextColumn::make('account.ending_balance')
120
                 Tables\Columns\TextColumn::make('account.ending_balance')
117
-                    ->localizeLabel('Current Balance')
121
+                    ->localizeLabel('Ending Balance')
118
                     ->state(static fn (BankAccount $record) => $record->account->ending_balance->convert()->formatWithCode())
122
                     ->state(static fn (BankAccount $record) => $record->account->ending_balance->convert()->formatWithCode())
119
-                    ->sortable(),
123
+                    ->toggleable()
124
+                    ->alignment(Alignment::End),
120
             ])
125
             ])
121
             ->filters([
126
             ->filters([
122
                 //
127
                 //

+ 0
- 1
app/Listeners/ConfigureChartOfAccounts.php Прегледај датотеку

72
                     'name' => $accountName,
72
                     'name' => $accountName,
73
                     'currency_code' => CurrencyAccessor::getDefaultCurrency(),
73
                     'currency_code' => CurrencyAccessor::getDefaultCurrency(),
74
                     'description' => $accountDetails['description'] ?? 'No description available.',
74
                     'description' => $accountDetails['description'] ?? 'No description available.',
75
-                    'active' => true,
76
                     'default' => true,
75
                     'default' => true,
77
                     'created_by' => $company->owner->id,
76
                     'created_by' => $company->owner->id,
78
                     'updated_by' => $company->owner->id,
77
                     'updated_by' => $company->owner->id,

+ 2
- 2
app/Models/Accounting/Account.php Прегледај датотеку

39
         'name',
39
         'name',
40
         'currency_code',
40
         'currency_code',
41
         'description',
41
         'description',
42
-        'active',
42
+        'archived',
43
         'default',
43
         'default',
44
         'bank_account_id',
44
         'bank_account_id',
45
         'created_by',
45
         'created_by',
49
     protected $casts = [
49
     protected $casts = [
50
         'category' => AccountCategory::class,
50
         'category' => AccountCategory::class,
51
         'type' => AccountType::class,
51
         'type' => AccountType::class,
52
-        'active' => 'boolean',
52
+        'archived' => 'boolean',
53
         'default' => 'boolean',
53
         'default' => 'boolean',
54
     ];
54
     ];
55
 
55
 

+ 0
- 2
app/Models/Company.php Прегледај датотеку

54
      * @var array<string, class-string>
54
      * @var array<string, class-string>
55
      */
55
      */
56
     protected $dispatchesEvents = [
56
     protected $dispatchesEvents = [
57
-        'created' => CompanyCreated::class,
58
-        'updated' => CompanyUpdated::class,
59
         'deleted' => CompanyDeleted::class,
57
         'deleted' => CompanyDeleted::class,
60
     ];
58
     ];
61
 
59
 

+ 9
- 0
app/Observers/AccountObserver.php Прегледај датотеку

7
 use App\Models\Accounting\Account;
7
 use App\Models\Accounting\Account;
8
 use App\Models\Accounting\AccountSubtype;
8
 use App\Models\Accounting\AccountSubtype;
9
 use App\Utilities\Accounting\AccountCode;
9
 use App\Utilities\Accounting\AccountCode;
10
+use App\Utilities\Currency\CurrencyAccessor;
10
 
11
 
11
 class AccountObserver
12
 class AccountObserver
12
 {
13
 {
13
     public function creating(Account $account): void
14
     public function creating(Account $account): void
14
     {
15
     {
15
         $this->setCategoryAndType($account, true);
16
         $this->setCategoryAndType($account, true);
17
+        $this->setCurrency($account);
16
     }
18
     }
17
 
19
 
18
     public function updating(Account $account): void
20
     public function updating(Account $account): void
35
         }
37
         }
36
     }
38
     }
37
 
39
 
40
+    private function setCurrency(Account $account): void
41
+    {
42
+        if ($account->currency_code === null && $account->subtype->multi_currency === false) {
43
+            $account->currency_code = CurrencyAccessor::getDefaultCurrency();
44
+        }
45
+    }
46
+
38
     private function setFieldsForBankAccount(Account $account): void
47
     private function setFieldsForBankAccount(Account $account): void
39
     {
48
     {
40
         $generatedAccountCode = AccountCode::generate($account->subtype);
49
         $generatedAccountCode = AccountCode::generate($account->subtype);

+ 0
- 88
app/Providers/EventServiceProvider.php Прегледај датотеку

1
-<?php
2
-
3
-namespace App\Providers;
4
-
5
-use App\Events\CompanyConfigured;
6
-use App\Events\CompanyDefaultEvent;
7
-use App\Events\CompanyDefaultUpdated;
8
-use App\Events\CompanyGenerated;
9
-use App\Events\CurrencyRateChanged;
10
-use App\Events\DefaultCurrencyChanged;
11
-use App\Events\PlaidSuccess;
12
-use App\Events\StartTransactionImport;
13
-use App\Listeners\ConfigureChartOfAccounts;
14
-use App\Listeners\ConfigureCompanyDefault;
15
-use App\Listeners\CreateCompanyDefaults;
16
-use App\Listeners\CreateConnectedAccount;
17
-use App\Listeners\HandleTransactionImport;
18
-use App\Listeners\SyncAssociatedModels;
19
-use App\Listeners\SyncWithCompanyDefaults;
20
-use App\Listeners\UpdateAccountBalances;
21
-use App\Listeners\UpdateCurrencyRates;
22
-use Illuminate\Auth\Events\Registered;
23
-use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
24
-use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
25
-
26
-class EventServiceProvider extends ServiceProvider
27
-{
28
-    /**
29
-     * The event to listener mappings for the application.
30
-     *
31
-     * @var array<class-string, array<int, class-string>>
32
-     */
33
-    protected $listen = [
34
-        Registered::class => [
35
-            SendEmailVerificationNotification::class,
36
-        ],
37
-        CompanyDefaultEvent::class => [
38
-            SyncWithCompanyDefaults::class,
39
-        ],
40
-        CompanyDefaultUpdated::class => [
41
-            SyncAssociatedModels::class,
42
-        ],
43
-        CompanyConfigured::class => [
44
-            ConfigureCompanyDefault::class,
45
-        ],
46
-        CompanyGenerated::class => [
47
-            CreateCompanyDefaults::class,
48
-            ConfigureChartOfAccounts::class,
49
-        ],
50
-        DefaultCurrencyChanged::class => [
51
-            UpdateCurrencyRates::class,
52
-        ],
53
-        CurrencyRateChanged::class => [
54
-            UpdateAccountBalances::class,
55
-        ],
56
-        PlaidSuccess::class => [
57
-            CreateConnectedAccount::class,
58
-        ],
59
-        StartTransactionImport::class => [
60
-            HandleTransactionImport::class,
61
-        ],
62
-    ];
63
-
64
-    /**
65
-     * The model observers to register.
66
-     *
67
-     * @var array<string, string|object|array<int, string|object>>
68
-     */
69
-    protected $observers = [
70
-        // Currency::class => [CurrencyObserver::class],
71
-    ];
72
-
73
-    /**
74
-     * Register any events for your application.
75
-     */
76
-    public function boot(): void
77
-    {
78
-        //
79
-    }
80
-
81
-    /**
82
-     * Determine if events and listeners should be automatically discovered.
83
-     */
84
-    public function shouldDiscoverEvents(): bool
85
-    {
86
-        return false;
87
-    }
88
-}

+ 0
- 1
app/Repositories/Banking/ConnectedBankAccountRepository.php Прегледај датотеку

29
             'currency_code' => $connectedBankAccount->currency_code,
29
             'currency_code' => $connectedBankAccount->currency_code,
30
             'description' => $connectedBankAccount->name,
30
             'description' => $connectedBankAccount->name,
31
             'subtype_id' => $accountSubtype->id,
31
             'subtype_id' => $accountSubtype->id,
32
-            'active' => true,
33
         ]);
32
         ]);
34
     }
33
     }
35
 }
34
 }

+ 3
- 3
app/Services/ExportService.php Прегледај датотеку

30
             fputcsv($file, $report->getHeaders());
30
             fputcsv($file, $report->getHeaders());
31
 
31
 
32
             foreach ($report->getCategories() as $category) {
32
             foreach ($report->getCategories() as $category) {
33
-                fputcsv($file, $category['header']);
33
+                fputcsv($file, $category->header);
34
 
34
 
35
-                foreach ($category['data'] as $accountRow) {
35
+                foreach ($category->data as $accountRow) {
36
                     fputcsv($file, $accountRow);
36
                     fputcsv($file, $accountRow);
37
                 }
37
                 }
38
 
38
 
39
-                fputcsv($file, $category['summary']);
39
+                fputcsv($file, $category->summary);
40
                 fputcsv($file, []); // Empty row for spacing
40
                 fputcsv($file, []); // Empty row for spacing
41
             }
41
             }
42
 
42
 

+ 77
- 28
app/Transformers/AccountBalanceReportTransformer.php Прегледај датотеку

3
 namespace App\Transformers;
3
 namespace App\Transformers;
4
 
4
 
5
 use App\DTO\AccountDTO;
5
 use App\DTO\AccountDTO;
6
+use App\DTO\ReportCategoryDTO;
6
 
7
 
7
 class AccountBalanceReportTransformer extends BaseReportTransformer
8
 class AccountBalanceReportTransformer extends BaseReportTransformer
8
 {
9
 {
13
 
14
 
14
     public function getHeaders(): array
15
     public function getHeaders(): array
15
     {
16
     {
16
-        return ['', 'Account', 'Starting Balance', 'Debit', 'Credit', 'Net Movement', 'Ending Balance'];
17
+        $headers = ['Account', 'Starting Balance', 'Debit', 'Credit', 'Net Movement', 'Ending Balance'];
18
+
19
+        if ($this->options['showAccountCode'] ?? false) {
20
+            array_unshift($headers, 'Account Code');
21
+        }
22
+
23
+        return $headers;
17
     }
24
     }
18
 
25
 
19
     public function getRightAlignedColumns(): array
26
     public function getRightAlignedColumns(): array
20
     {
27
     {
21
-        return [2, 3, 4, 5, 6];
28
+        $columns = [1, 2, 3, 4, 5];
29
+
30
+        if ($this->options['showAccountCode'] ?? false) {
31
+            $columns = [2, 3, 4, 5, 6];
32
+        }
33
+
34
+        return $columns;
22
     }
35
     }
23
 
36
 
24
     public function getLeftAlignedColumns(): array
37
     public function getLeftAlignedColumns(): array
25
     {
38
     {
26
-        return [1];
39
+        $columns = [0];
40
+
41
+        if ($this->options['showAccountCode'] ?? false) {
42
+            $columns = [1];
43
+        }
44
+
45
+        return $columns;
27
     }
46
     }
28
 
47
 
29
     public function getCenterAlignedColumns(): array
48
     public function getCenterAlignedColumns(): array
30
     {
49
     {
31
-        return [0];
50
+        if ($this->options['showAccountCode'] ?? false) {
51
+            return [0];
52
+        }
53
+
54
+        return [];
32
     }
55
     }
33
 
56
 
57
+    /**
58
+     * @return ReportCategoryDTO[]
59
+     */
34
     public function getCategories(): array
60
     public function getCategories(): array
35
     {
61
     {
36
         $categories = [];
62
         $categories = [];
37
 
63
 
38
         foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
64
         foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
39
-            $categories[] = [
40
-                'header' => ['', $accountCategoryName, '', '', '', '', ''],
41
-                'data' => array_map(static function (AccountDTO $account) {
42
-                    return [
43
-                        $account->accountCode,
44
-                        $account->accountName,
45
-                        $account->balance->startingBalance ?? '',
46
-                        $account->balance->debitBalance,
47
-                        $account->balance->creditBalance,
48
-                        $account->balance->netMovement,
49
-                        $account->balance->endingBalance ?? '',
50
-                    ];
51
-                }, $accountCategory->accounts),
52
-                'summary' => [
53
-                    '',
54
-                    'Total ' . $accountCategoryName,
55
-                    $accountCategory->summary->startingBalance ?? '',
56
-                    $accountCategory->summary->debitBalance,
57
-                    $accountCategory->summary->creditBalance,
58
-                    $accountCategory->summary->netMovement,
59
-                    $accountCategory->summary->endingBalance ?? '',
60
-                ],
65
+            $header = [$accountCategoryName, '', '', '', '', ''];
66
+
67
+            if ($this->options['showAccountCode'] ?? false) {
68
+                array_unshift($header, '');
69
+            }
70
+
71
+            $data = array_map(function (AccountDTO $account) {
72
+                $row = [
73
+                    $account->accountName,
74
+                    $account->balance->startingBalance ?? '',
75
+                    $account->balance->debitBalance,
76
+                    $account->balance->creditBalance,
77
+                    $account->balance->netMovement ?? '',
78
+                    $account->balance->endingBalance ?? '',
79
+                ];
80
+
81
+                if ($this->options['showAccountCode'] ?? false) {
82
+                    array_unshift($row, $account->accountCode);
83
+                }
84
+
85
+                return $row;
86
+            }, $accountCategory->accounts);
87
+
88
+            $summary = [
89
+                'Total ' . $accountCategoryName,
90
+                $accountCategory->summary->startingBalance ?? '',
91
+                $accountCategory->summary->debitBalance,
92
+                $accountCategory->summary->creditBalance,
93
+                $accountCategory->summary->netMovement ?? '',
94
+                $accountCategory->summary->endingBalance ?? '',
61
             ];
95
             ];
96
+
97
+            if ($this->options['showAccountCode'] ?? false) {
98
+                array_unshift($summary, '');
99
+            }
100
+
101
+            $categories[] = new ReportCategoryDTO(
102
+                header: $header,
103
+                data: $data,
104
+                summary: $summary,
105
+            );
62
         }
106
         }
63
 
107
 
64
         return $categories;
108
         return $categories;
66
 
110
 
67
     public function getOverallTotals(): array
111
     public function getOverallTotals(): array
68
     {
112
     {
69
-        return [
70
-            '',
113
+        $totals = [
71
             'Total for all accounts',
114
             'Total for all accounts',
72
             '',
115
             '',
73
             $this->report->overallTotal->debitBalance,
116
             $this->report->overallTotal->debitBalance,
75
             '',
118
             '',
76
             '',
119
             '',
77
         ];
120
         ];
121
+
122
+        if ($this->options['showAccountCode'] ?? false) {
123
+            array_unshift($totals, '');
124
+        }
125
+
126
+        return $totals;
78
     }
127
     }
79
 }
128
 }

+ 4
- 1
app/Transformers/BaseReportTransformer.php Прегледај датотеку

10
 {
10
 {
11
     protected ReportDTO $report;
11
     protected ReportDTO $report;
12
 
12
 
13
-    public function __construct(ReportDTO $report)
13
+    protected array $options;
14
+
15
+    public function __construct(ReportDTO $report, array $options = [])
14
     {
16
     {
15
         $this->report = $report;
17
         $this->report = $report;
18
+        $this->options = $options;
16
     }
19
     }
17
 
20
 
18
     public function getAlignmentClass(int $index): string
21
     public function getAlignmentClass(int $index): string

+ 9
- 5
app/Transformers/TrialBalanceReportTransformer.php Прегледај датотеку

3
 namespace App\Transformers;
3
 namespace App\Transformers;
4
 
4
 
5
 use App\DTO\AccountDTO;
5
 use App\DTO\AccountDTO;
6
+use App\DTO\ReportCategoryDTO;
6
 
7
 
7
 class TrialBalanceReportTransformer extends BaseReportTransformer
8
 class TrialBalanceReportTransformer extends BaseReportTransformer
8
 {
9
 {
31
         return [0];
32
         return [0];
32
     }
33
     }
33
 
34
 
35
+    /**
36
+     * @return ReportCategoryDTO[]
37
+     */
34
     public function getCategories(): array
38
     public function getCategories(): array
35
     {
39
     {
36
         $categories = [];
40
         $categories = [];
37
 
41
 
38
         foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
42
         foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
39
-            $categories[] = [
40
-                'header' => ['', $accountCategoryName, '', ''],
41
-                'data' => array_map(static function (AccountDTO $account) {
43
+            $categories[] = new ReportCategoryDTO(
44
+                header: ['', $accountCategoryName, '', ''],
45
+                data: array_map(static function (AccountDTO $account) {
42
                     return [
46
                     return [
43
                         $account->accountCode,
47
                         $account->accountCode,
44
                         $account->accountName,
48
                         $account->accountName,
46
                         $account->balance->creditBalance,
50
                         $account->balance->creditBalance,
47
                     ];
51
                     ];
48
                 }, $accountCategory->accounts),
52
                 }, $accountCategory->accounts),
49
-                'summary' => [
53
+                summary: [
50
                     '',
54
                     '',
51
                     'Total ' . $accountCategoryName,
55
                     'Total ' . $accountCategoryName,
52
                     $accountCategory->summary->debitBalance,
56
                     $accountCategory->summary->debitBalance,
53
                     $accountCategory->summary->creditBalance,
57
                     $accountCategory->summary->creditBalance,
54
                 ],
58
                 ],
55
-            ];
59
+            );
56
         }
60
         }
57
 
61
 
58
         return $categories;
62
         return $categories;

+ 0
- 1
bootstrap/providers.php Прегледај датотеку

3
 return [
3
 return [
4
     App\Providers\AppServiceProvider::class,
4
     App\Providers\AppServiceProvider::class,
5
     App\Providers\AuthServiceProvider::class,
5
     App\Providers\AuthServiceProvider::class,
6
-    App\Providers\EventServiceProvider::class,
7
     App\Providers\Filament\AdminPanelProvider::class,
6
     App\Providers\Filament\AdminPanelProvider::class,
8
     App\Providers\FilamentCompaniesServiceProvider::class,
7
     App\Providers\FilamentCompaniesServiceProvider::class,
9
     App\Providers\Filament\UserPanelProvider::class,
8
     App\Providers\Filament\UserPanelProvider::class,

+ 314
- 238
composer.lock
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
database/migrations/2023_09_03_100000_create_accounting_tables.php Прегледај датотеку

59
             $table->string('name')->nullable()->index();
59
             $table->string('name')->nullable()->index();
60
             $table->string('currency_code')->nullable();
60
             $table->string('currency_code')->nullable();
61
             $table->text('description')->nullable();
61
             $table->text('description')->nullable();
62
-            $table->boolean('active')->default(true);
62
+            $table->boolean('archived')->default(false);
63
             $table->boolean('default')->default(false);
63
             $table->boolean('default')->default(false);
64
             $table->foreignId('bank_account_id')->nullable()->constrained('bank_accounts')->cascadeOnDelete();
64
             $table->foreignId('bank_account_id')->nullable()->constrained('bank_accounts')->cascadeOnDelete();
65
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
65
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();

+ 129
- 129
package-lock.json Прегледај датотеку

29
             }
29
             }
30
         },
30
         },
31
         "node_modules/@esbuild/aix-ppc64": {
31
         "node_modules/@esbuild/aix-ppc64": {
32
-            "version": "0.20.2",
33
-            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
34
-            "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
32
+            "version": "0.21.5",
33
+            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
34
+            "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
35
             "cpu": [
35
             "cpu": [
36
                 "ppc64"
36
                 "ppc64"
37
             ],
37
             ],
45
             }
45
             }
46
         },
46
         },
47
         "node_modules/@esbuild/android-arm": {
47
         "node_modules/@esbuild/android-arm": {
48
-            "version": "0.20.2",
49
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
50
-            "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
48
+            "version": "0.21.5",
49
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
50
+            "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
51
             "cpu": [
51
             "cpu": [
52
                 "arm"
52
                 "arm"
53
             ],
53
             ],
61
             }
61
             }
62
         },
62
         },
63
         "node_modules/@esbuild/android-arm64": {
63
         "node_modules/@esbuild/android-arm64": {
64
-            "version": "0.20.2",
65
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
66
-            "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
64
+            "version": "0.21.5",
65
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
66
+            "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
67
             "cpu": [
67
             "cpu": [
68
                 "arm64"
68
                 "arm64"
69
             ],
69
             ],
77
             }
77
             }
78
         },
78
         },
79
         "node_modules/@esbuild/android-x64": {
79
         "node_modules/@esbuild/android-x64": {
80
-            "version": "0.20.2",
81
-            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
82
-            "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
80
+            "version": "0.21.5",
81
+            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
82
+            "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
83
             "cpu": [
83
             "cpu": [
84
                 "x64"
84
                 "x64"
85
             ],
85
             ],
93
             }
93
             }
94
         },
94
         },
95
         "node_modules/@esbuild/darwin-arm64": {
95
         "node_modules/@esbuild/darwin-arm64": {
96
-            "version": "0.20.2",
97
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
98
-            "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
96
+            "version": "0.21.5",
97
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
98
+            "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
99
             "cpu": [
99
             "cpu": [
100
                 "arm64"
100
                 "arm64"
101
             ],
101
             ],
109
             }
109
             }
110
         },
110
         },
111
         "node_modules/@esbuild/darwin-x64": {
111
         "node_modules/@esbuild/darwin-x64": {
112
-            "version": "0.20.2",
113
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
114
-            "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
112
+            "version": "0.21.5",
113
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
114
+            "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
115
             "cpu": [
115
             "cpu": [
116
                 "x64"
116
                 "x64"
117
             ],
117
             ],
125
             }
125
             }
126
         },
126
         },
127
         "node_modules/@esbuild/freebsd-arm64": {
127
         "node_modules/@esbuild/freebsd-arm64": {
128
-            "version": "0.20.2",
129
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
130
-            "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
128
+            "version": "0.21.5",
129
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
130
+            "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
131
             "cpu": [
131
             "cpu": [
132
                 "arm64"
132
                 "arm64"
133
             ],
133
             ],
141
             }
141
             }
142
         },
142
         },
143
         "node_modules/@esbuild/freebsd-x64": {
143
         "node_modules/@esbuild/freebsd-x64": {
144
-            "version": "0.20.2",
145
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
146
-            "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
144
+            "version": "0.21.5",
145
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
146
+            "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
147
             "cpu": [
147
             "cpu": [
148
                 "x64"
148
                 "x64"
149
             ],
149
             ],
157
             }
157
             }
158
         },
158
         },
159
         "node_modules/@esbuild/linux-arm": {
159
         "node_modules/@esbuild/linux-arm": {
160
-            "version": "0.20.2",
161
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
162
-            "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
160
+            "version": "0.21.5",
161
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
162
+            "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
163
             "cpu": [
163
             "cpu": [
164
                 "arm"
164
                 "arm"
165
             ],
165
             ],
173
             }
173
             }
174
         },
174
         },
175
         "node_modules/@esbuild/linux-arm64": {
175
         "node_modules/@esbuild/linux-arm64": {
176
-            "version": "0.20.2",
177
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
178
-            "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
176
+            "version": "0.21.5",
177
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
178
+            "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
179
             "cpu": [
179
             "cpu": [
180
                 "arm64"
180
                 "arm64"
181
             ],
181
             ],
189
             }
189
             }
190
         },
190
         },
191
         "node_modules/@esbuild/linux-ia32": {
191
         "node_modules/@esbuild/linux-ia32": {
192
-            "version": "0.20.2",
193
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
194
-            "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
192
+            "version": "0.21.5",
193
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
194
+            "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
195
             "cpu": [
195
             "cpu": [
196
                 "ia32"
196
                 "ia32"
197
             ],
197
             ],
205
             }
205
             }
206
         },
206
         },
207
         "node_modules/@esbuild/linux-loong64": {
207
         "node_modules/@esbuild/linux-loong64": {
208
-            "version": "0.20.2",
209
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
210
-            "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
208
+            "version": "0.21.5",
209
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
210
+            "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
211
             "cpu": [
211
             "cpu": [
212
                 "loong64"
212
                 "loong64"
213
             ],
213
             ],
221
             }
221
             }
222
         },
222
         },
223
         "node_modules/@esbuild/linux-mips64el": {
223
         "node_modules/@esbuild/linux-mips64el": {
224
-            "version": "0.20.2",
225
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
226
-            "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
224
+            "version": "0.21.5",
225
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
226
+            "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
227
             "cpu": [
227
             "cpu": [
228
                 "mips64el"
228
                 "mips64el"
229
             ],
229
             ],
237
             }
237
             }
238
         },
238
         },
239
         "node_modules/@esbuild/linux-ppc64": {
239
         "node_modules/@esbuild/linux-ppc64": {
240
-            "version": "0.20.2",
241
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
242
-            "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
240
+            "version": "0.21.5",
241
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
242
+            "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
243
             "cpu": [
243
             "cpu": [
244
                 "ppc64"
244
                 "ppc64"
245
             ],
245
             ],
253
             }
253
             }
254
         },
254
         },
255
         "node_modules/@esbuild/linux-riscv64": {
255
         "node_modules/@esbuild/linux-riscv64": {
256
-            "version": "0.20.2",
257
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
258
-            "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
256
+            "version": "0.21.5",
257
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
258
+            "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
259
             "cpu": [
259
             "cpu": [
260
                 "riscv64"
260
                 "riscv64"
261
             ],
261
             ],
269
             }
269
             }
270
         },
270
         },
271
         "node_modules/@esbuild/linux-s390x": {
271
         "node_modules/@esbuild/linux-s390x": {
272
-            "version": "0.20.2",
273
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
274
-            "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
272
+            "version": "0.21.5",
273
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
274
+            "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
275
             "cpu": [
275
             "cpu": [
276
                 "s390x"
276
                 "s390x"
277
             ],
277
             ],
285
             }
285
             }
286
         },
286
         },
287
         "node_modules/@esbuild/linux-x64": {
287
         "node_modules/@esbuild/linux-x64": {
288
-            "version": "0.20.2",
289
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
290
-            "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
288
+            "version": "0.21.5",
289
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
290
+            "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
291
             "cpu": [
291
             "cpu": [
292
                 "x64"
292
                 "x64"
293
             ],
293
             ],
301
             }
301
             }
302
         },
302
         },
303
         "node_modules/@esbuild/netbsd-x64": {
303
         "node_modules/@esbuild/netbsd-x64": {
304
-            "version": "0.20.2",
305
-            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
306
-            "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
304
+            "version": "0.21.5",
305
+            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
306
+            "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
307
             "cpu": [
307
             "cpu": [
308
                 "x64"
308
                 "x64"
309
             ],
309
             ],
317
             }
317
             }
318
         },
318
         },
319
         "node_modules/@esbuild/openbsd-x64": {
319
         "node_modules/@esbuild/openbsd-x64": {
320
-            "version": "0.20.2",
321
-            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
322
-            "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
320
+            "version": "0.21.5",
321
+            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
322
+            "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
323
             "cpu": [
323
             "cpu": [
324
                 "x64"
324
                 "x64"
325
             ],
325
             ],
333
             }
333
             }
334
         },
334
         },
335
         "node_modules/@esbuild/sunos-x64": {
335
         "node_modules/@esbuild/sunos-x64": {
336
-            "version": "0.20.2",
337
-            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
338
-            "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
336
+            "version": "0.21.5",
337
+            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
338
+            "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
339
             "cpu": [
339
             "cpu": [
340
                 "x64"
340
                 "x64"
341
             ],
341
             ],
349
             }
349
             }
350
         },
350
         },
351
         "node_modules/@esbuild/win32-arm64": {
351
         "node_modules/@esbuild/win32-arm64": {
352
-            "version": "0.20.2",
353
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
354
-            "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
352
+            "version": "0.21.5",
353
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
354
+            "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
355
             "cpu": [
355
             "cpu": [
356
                 "arm64"
356
                 "arm64"
357
             ],
357
             ],
365
             }
365
             }
366
         },
366
         },
367
         "node_modules/@esbuild/win32-ia32": {
367
         "node_modules/@esbuild/win32-ia32": {
368
-            "version": "0.20.2",
369
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
370
-            "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
368
+            "version": "0.21.5",
369
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
370
+            "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
371
             "cpu": [
371
             "cpu": [
372
                 "ia32"
372
                 "ia32"
373
             ],
373
             ],
381
             }
381
             }
382
         },
382
         },
383
         "node_modules/@esbuild/win32-x64": {
383
         "node_modules/@esbuild/win32-x64": {
384
-            "version": "0.20.2",
385
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
386
-            "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
384
+            "version": "0.21.5",
385
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
386
+            "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
387
             "cpu": [
387
             "cpu": [
388
                 "x64"
388
                 "x64"
389
             ],
389
             ],
890
             }
890
             }
891
         },
891
         },
892
         "node_modules/browserslist": {
892
         "node_modules/browserslist": {
893
-            "version": "4.23.0",
894
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
895
-            "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
893
+            "version": "4.23.1",
894
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
895
+            "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
896
             "dev": true,
896
             "dev": true,
897
             "funding": [
897
             "funding": [
898
                 {
898
                 {
909
                 }
909
                 }
910
             ],
910
             ],
911
             "dependencies": {
911
             "dependencies": {
912
-                "caniuse-lite": "^1.0.30001587",
913
-                "electron-to-chromium": "^1.4.668",
912
+                "caniuse-lite": "^1.0.30001629",
913
+                "electron-to-chromium": "^1.4.796",
914
                 "node-releases": "^2.0.14",
914
                 "node-releases": "^2.0.14",
915
-                "update-browserslist-db": "^1.0.13"
915
+                "update-browserslist-db": "^1.0.16"
916
             },
916
             },
917
             "bin": {
917
             "bin": {
918
                 "browserslist": "cli.js"
918
                 "browserslist": "cli.js"
931
             }
931
             }
932
         },
932
         },
933
         "node_modules/caniuse-lite": {
933
         "node_modules/caniuse-lite": {
934
-            "version": "1.0.30001625",
935
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz",
936
-            "integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==",
934
+            "version": "1.0.30001634",
935
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz",
936
+            "integrity": "sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA==",
937
             "dev": true,
937
             "dev": true,
938
             "funding": [
938
             "funding": [
939
                 {
939
                 {
1079
             "dev": true
1079
             "dev": true
1080
         },
1080
         },
1081
         "node_modules/electron-to-chromium": {
1081
         "node_modules/electron-to-chromium": {
1082
-            "version": "1.4.784",
1083
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.784.tgz",
1084
-            "integrity": "sha512-9CZwh+sDrhDAeOEFh8s3PqwduzTyYIeYwZolc1b9ENAUt3ePu7R1sJSCWr/820ISssRxCJUyHI9Wb7j+0Uo1AA==",
1082
+            "version": "1.4.803",
1083
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.803.tgz",
1084
+            "integrity": "sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==",
1085
             "dev": true
1085
             "dev": true
1086
         },
1086
         },
1087
         "node_modules/emoji-regex": {
1087
         "node_modules/emoji-regex": {
1091
             "dev": true
1091
             "dev": true
1092
         },
1092
         },
1093
         "node_modules/esbuild": {
1093
         "node_modules/esbuild": {
1094
-            "version": "0.20.2",
1095
-            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
1096
-            "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
1094
+            "version": "0.21.5",
1095
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
1096
+            "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
1097
             "dev": true,
1097
             "dev": true,
1098
             "hasInstallScript": true,
1098
             "hasInstallScript": true,
1099
             "bin": {
1099
             "bin": {
1103
                 "node": ">=12"
1103
                 "node": ">=12"
1104
             },
1104
             },
1105
             "optionalDependencies": {
1105
             "optionalDependencies": {
1106
-                "@esbuild/aix-ppc64": "0.20.2",
1107
-                "@esbuild/android-arm": "0.20.2",
1108
-                "@esbuild/android-arm64": "0.20.2",
1109
-                "@esbuild/android-x64": "0.20.2",
1110
-                "@esbuild/darwin-arm64": "0.20.2",
1111
-                "@esbuild/darwin-x64": "0.20.2",
1112
-                "@esbuild/freebsd-arm64": "0.20.2",
1113
-                "@esbuild/freebsd-x64": "0.20.2",
1114
-                "@esbuild/linux-arm": "0.20.2",
1115
-                "@esbuild/linux-arm64": "0.20.2",
1116
-                "@esbuild/linux-ia32": "0.20.2",
1117
-                "@esbuild/linux-loong64": "0.20.2",
1118
-                "@esbuild/linux-mips64el": "0.20.2",
1119
-                "@esbuild/linux-ppc64": "0.20.2",
1120
-                "@esbuild/linux-riscv64": "0.20.2",
1121
-                "@esbuild/linux-s390x": "0.20.2",
1122
-                "@esbuild/linux-x64": "0.20.2",
1123
-                "@esbuild/netbsd-x64": "0.20.2",
1124
-                "@esbuild/openbsd-x64": "0.20.2",
1125
-                "@esbuild/sunos-x64": "0.20.2",
1126
-                "@esbuild/win32-arm64": "0.20.2",
1127
-                "@esbuild/win32-ia32": "0.20.2",
1128
-                "@esbuild/win32-x64": "0.20.2"
1106
+                "@esbuild/aix-ppc64": "0.21.5",
1107
+                "@esbuild/android-arm": "0.21.5",
1108
+                "@esbuild/android-arm64": "0.21.5",
1109
+                "@esbuild/android-x64": "0.21.5",
1110
+                "@esbuild/darwin-arm64": "0.21.5",
1111
+                "@esbuild/darwin-x64": "0.21.5",
1112
+                "@esbuild/freebsd-arm64": "0.21.5",
1113
+                "@esbuild/freebsd-x64": "0.21.5",
1114
+                "@esbuild/linux-arm": "0.21.5",
1115
+                "@esbuild/linux-arm64": "0.21.5",
1116
+                "@esbuild/linux-ia32": "0.21.5",
1117
+                "@esbuild/linux-loong64": "0.21.5",
1118
+                "@esbuild/linux-mips64el": "0.21.5",
1119
+                "@esbuild/linux-ppc64": "0.21.5",
1120
+                "@esbuild/linux-riscv64": "0.21.5",
1121
+                "@esbuild/linux-s390x": "0.21.5",
1122
+                "@esbuild/linux-x64": "0.21.5",
1123
+                "@esbuild/netbsd-x64": "0.21.5",
1124
+                "@esbuild/openbsd-x64": "0.21.5",
1125
+                "@esbuild/sunos-x64": "0.21.5",
1126
+                "@esbuild/win32-arm64": "0.21.5",
1127
+                "@esbuild/win32-ia32": "0.21.5",
1128
+                "@esbuild/win32-x64": "0.21.5"
1129
             }
1129
             }
1130
         },
1130
         },
1131
         "node_modules/escalade": {
1131
         "node_modules/escalade": {
1207
             }
1207
             }
1208
         },
1208
         },
1209
         "node_modules/foreground-child": {
1209
         "node_modules/foreground-child": {
1210
-            "version": "3.1.1",
1211
-            "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
1212
-            "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
1210
+            "version": "3.2.1",
1211
+            "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
1212
+            "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
1213
             "dev": true,
1213
             "dev": true,
1214
             "dependencies": {
1214
             "dependencies": {
1215
                 "cross-spawn": "^7.0.0",
1215
                 "cross-spawn": "^7.0.0",
1388
             "dev": true
1388
             "dev": true
1389
         },
1389
         },
1390
         "node_modules/jackspeak": {
1390
         "node_modules/jackspeak": {
1391
-            "version": "3.1.2",
1392
-            "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
1393
-            "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
1391
+            "version": "3.4.0",
1392
+            "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
1393
+            "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
1394
             "dev": true,
1394
             "dev": true,
1395
             "dependencies": {
1395
             "dependencies": {
1396
                 "@isaacs/cliui": "^8.0.2"
1396
                 "@isaacs/cliui": "^8.0.2"
1406
             }
1406
             }
1407
         },
1407
         },
1408
         "node_modules/jiti": {
1408
         "node_modules/jiti": {
1409
-            "version": "1.21.0",
1410
-            "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
1411
-            "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
1409
+            "version": "1.21.6",
1410
+            "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
1411
+            "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
1412
             "dev": true,
1412
             "dev": true,
1413
             "bin": {
1413
             "bin": {
1414
                 "jiti": "bin/jiti.js"
1414
                 "jiti": "bin/jiti.js"
1789
             }
1789
             }
1790
         },
1790
         },
1791
         "node_modules/postcss-load-config/node_modules/lilconfig": {
1791
         "node_modules/postcss-load-config/node_modules/lilconfig": {
1792
-            "version": "3.1.1",
1793
-            "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
1794
-            "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
1792
+            "version": "3.1.2",
1793
+            "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
1794
+            "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
1795
             "dev": true,
1795
             "dev": true,
1796
             "engines": {
1796
             "engines": {
1797
                 "node": ">=14"
1797
                 "node": ">=14"
2240
             }
2240
             }
2241
         },
2241
         },
2242
         "node_modules/tailwindcss": {
2242
         "node_modules/tailwindcss": {
2243
-            "version": "3.4.3",
2244
-            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
2245
-            "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
2243
+            "version": "3.4.4",
2244
+            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
2245
+            "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
2246
             "dev": true,
2246
             "dev": true,
2247
             "dependencies": {
2247
             "dependencies": {
2248
                 "@alloc/quick-lru": "^5.2.0",
2248
                 "@alloc/quick-lru": "^5.2.0",
2365
             "dev": true
2365
             "dev": true
2366
         },
2366
         },
2367
         "node_modules/vite": {
2367
         "node_modules/vite": {
2368
-            "version": "5.2.12",
2369
-            "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz",
2370
-            "integrity": "sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==",
2368
+            "version": "5.3.1",
2369
+            "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
2370
+            "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
2371
             "dev": true,
2371
             "dev": true,
2372
             "dependencies": {
2372
             "dependencies": {
2373
-                "esbuild": "^0.20.1",
2373
+                "esbuild": "^0.21.3",
2374
                 "postcss": "^8.4.38",
2374
                 "postcss": "^8.4.38",
2375
                 "rollup": "^4.13.0"
2375
                 "rollup": "^4.13.0"
2376
             },
2376
             },
2536
             }
2536
             }
2537
         },
2537
         },
2538
         "node_modules/yaml": {
2538
         "node_modules/yaml": {
2539
-            "version": "2.4.2",
2540
-            "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
2541
-            "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
2539
+            "version": "2.4.5",
2540
+            "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
2541
+            "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
2542
             "dev": true,
2542
             "dev": true,
2543
             "bin": {
2543
             "bin": {
2544
                 "yaml": "bin.mjs"
2544
                 "yaml": "bin.mjs"

+ 2
- 1
resources/data/lang/en.json Прегледај датотеку

188
     "Live Rate": "Live Rate",
188
     "Live Rate": "Live Rate",
189
     "Edit": "Edit",
189
     "Edit": "Edit",
190
     "Notes": "Notes",
190
     "Notes": "Notes",
191
-    "Terms": "Terms"
191
+    "Terms": "Terms",
192
+    "Ending Balance": "Ending Balance"
192
 }
193
 }

+ 3
- 3
resources/views/components/company/reports/report-pdf.blade.php Прегледај датотеку

107
     @foreach($report->getCategories() as $category)
107
     @foreach($report->getCategories() as $category)
108
         <tbody>
108
         <tbody>
109
         <tr class="category-header-row">
109
         <tr class="category-header-row">
110
-            @foreach($category['header'] as $index => $header)
110
+            @foreach($category->header as $index => $header)
111
                 <td class="{{ $report->getAlignmentClass($index) }}">
111
                 <td class="{{ $report->getAlignmentClass($index) }}">
112
                     {{ $header }}
112
                     {{ $header }}
113
                 </td>
113
                 </td>
114
             @endforeach
114
             @endforeach
115
         </tr>
115
         </tr>
116
-        @foreach($category['data'] as $account)
116
+        @foreach($category->data as $account)
117
             <tr>
117
             <tr>
118
                 @foreach($account as $index => $cell)
118
                 @foreach($account as $index => $cell)
119
                     <td class="{{ $report->getAlignmentClass($index) }}">
119
                     <td class="{{ $report->getAlignmentClass($index) }}">
123
             </tr>
123
             </tr>
124
         @endforeach
124
         @endforeach
125
         <tr class="category-summary-row">
125
         <tr class="category-summary-row">
126
-            @foreach($category['summary'] as $index => $cell)
126
+            @foreach($category->summary as $index => $cell)
127
                 <td class="{{ $report->getAlignmentClass($index) }}">
127
                 <td class="{{ $report->getAlignmentClass($index) }}">
128
                     {{ $cell }}
128
                     {{ $cell }}
129
                 </td>
129
                 </td>

+ 3
- 3
resources/views/components/company/tables/reports/detailed-report.blade.php Прегледај датотеку

13
     @foreach($report->getCategories() as $category)
13
     @foreach($report->getCategories() as $category)
14
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
14
         <tbody class="divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
15
         <tr class="bg-gray-50 dark:bg-white/5">
15
         <tr class="bg-gray-50 dark:bg-white/5">
16
-            @foreach($category['header'] as $index => $header)
16
+            @foreach($category->header as $index => $header)
17
                 <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
17
                 <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
18
                     <div class="px-3 py-2 text-sm font-semibold text-gray-950 dark:text-white">
18
                     <div class="px-3 py-2 text-sm font-semibold text-gray-950 dark:text-white">
19
                         {{ $header }}
19
                         {{ $header }}
21
                 </x-filament-tables::cell>
21
                 </x-filament-tables::cell>
22
             @endforeach
22
             @endforeach
23
         </tr>
23
         </tr>
24
-        @foreach($category['data'] as $account)
24
+        @foreach($category->data as $account)
25
             <tr>
25
             <tr>
26
                 @foreach($account as $index => $cell)
26
                 @foreach($account as $index => $cell)
27
                     <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
27
                     <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
33
             </tr>
33
             </tr>
34
         @endforeach
34
         @endforeach
35
         <tr>
35
         <tr>
36
-            @foreach($category['summary'] as $index => $cell)
36
+            @foreach($category->summary as $index => $cell)
37
                 <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
37
                 <x-filament-tables::cell class="{{ $report->getAlignmentClass($index) }}">
38
                     <div class="px-3 py-2 text-sm leading-6 font-semibold text-gray-950 dark:text-white">
38
                     <div class="px-3 py-2 text-sm leading-6 font-semibold text-gray-950 dark:text-white">
39
                         {{ $cell }}
39
                         {{ $cell }}

+ 11
- 3
resources/views/filament/company/pages/accounting/chart.blade.php Прегледај датотеку

21
                         <table class="es-table table-fixed w-full divide-y divide-gray-200 text-start text-sm dark:divide-white/5">
21
                         <table class="es-table table-fixed w-full divide-y divide-gray-200 text-start text-sm dark:divide-white/5">
22
                             <colgroup>
22
                             <colgroup>
23
                                 <col span="1" style="width: 12.5%;">
23
                                 <col span="1" style="width: 12.5%;">
24
-                                <col span="1" style="width: 25%;">
25
-                                <col span="1" style="width: 40%;">
24
+                                <col span="1" style="width: 20%;">
25
+                                <col span="1" style="width: 35%;">
26
                                 <col span="1" style="width: 15%;">
26
                                 <col span="1" style="width: 15%;">
27
+                                <col span="1" style="width: 10%;">
27
                                 <col span="1" style="width: 7.5%;">
28
                                 <col span="1" style="width: 7.5%;">
28
                             </colgroup>
29
                             </colgroup>
29
                             @foreach($subtypes as $subtype)
30
                             @foreach($subtypes as $subtype)
30
                                 <tbody class="es-table__rowgroup divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
31
                                 <tbody class="es-table__rowgroup divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5">
31
                                 <!-- Subtype Name Header Row -->
32
                                 <!-- Subtype Name Header Row -->
32
                                 <tr class="es-table__row--header bg-gray-50 dark:bg-white/5">
33
                                 <tr class="es-table__row--header bg-gray-50 dark:bg-white/5">
33
-                                    <td colspan="5" class="es-table__cell px-4 py-4">
34
+                                    <td colspan="6" class="es-table__cell px-4 py-4">
34
                                         <div class="es-table__row-content flex items-center space-x-2">
35
                                         <div class="es-table__row-content flex items-center space-x-2">
35
                                             <span class="es-table__row-title text-gray-800 dark:text-gray-200 font-semibold tracking-wider">
36
                                             <span class="es-table__row-title text-gray-800 dark:text-gray-200 font-semibold tracking-wider">
36
                                                 {{ $subtype->name }}
37
                                                 {{ $subtype->name }}
61
                                             </small>
62
                                             </small>
62
                                         </td>
63
                                         </td>
63
                                         <td colspan="2" class="es-table__cell px-4 py-4">{{ $account->description }}</td>
64
                                         <td colspan="2" class="es-table__cell px-4 py-4">{{ $account->description }}</td>
65
+                                        <td colspan="1" class="es-table__cell px-4 py-4">
66
+                                            @if($account->archived)
67
+                                                <x-filament::badge color="gray" size="sm">
68
+                                                    Archived
69
+                                                </x-filament::badge>
70
+                                            @endif
71
+                                        </td>
64
                                         <td colspan="1" class="es-table__cell px-4 py-4">
72
                                         <td colspan="1" class="es-table__cell px-4 py-4">
65
                                             <div>
73
                                             <div>
66
                                                 @if($account->default === false)
74
                                                 @if($account->default === false)

+ 2
- 2
resources/views/filament/company/pages/reports/account-balances.blade.php Прегледај датотеку

3
         <x-filament-tables::container>
3
         <x-filament-tables::container>
4
             <div class="p-6 divide-y divide-gray-200 dark:divide-white/5">
4
             <div class="p-6 divide-y divide-gray-200 dark:divide-white/5">
5
                 <form wire:submit.prevent="loadReportData" class="w-full">
5
                 <form wire:submit.prevent="loadReportData" class="w-full">
6
-                    <div class="flex flex-col md:flex-row items-end justify-center gap-4 md:gap-6">
6
+                    <div class="flex flex-col md:flex-row items-start justify-center gap-4 md:gap-12">
7
                         <div class="flex-grow">
7
                         <div class="flex-grow">
8
                             {{ $this->form }}
8
                             {{ $this->form }}
9
                         </div>
9
                         </div>
10
-                        <x-filament::button type="submit" class="mt-4 md:mt-0">
10
+                        <x-filament::button type="submit" class="mt-4 md:mt-0 flex-shrink-0">
11
                             Update Report
11
                             Update Report
12
                         </x-filament::button>
12
                         </x-filament::button>
13
                     </div>
13
                     </div>

Loading…
Откажи
Сачувај