|
@@ -8,8 +8,8 @@ use App\Enums\Accounting\JournalEntryType;
|
8
|
8
|
use App\Enums\Accounting\TransactionType;
|
9
|
9
|
use App\Facades\Accounting;
|
10
|
10
|
use App\Filament\Company\Pages\Service\ConnectedAccount;
|
|
11
|
+use App\Filament\Forms\Components\CustomTableRepeater;
|
11
|
12
|
use App\Filament\Forms\Components\DateRangeSelect;
|
12
|
|
-use App\Filament\Forms\Components\JournalEntryRepeater;
|
13
|
13
|
use App\Filament\Tables\Actions\ReplicateBulkAction;
|
14
|
14
|
use App\Models\Accounting\Account;
|
15
|
15
|
use App\Models\Accounting\JournalEntry;
|
|
@@ -538,19 +538,18 @@ class Transactions extends Page implements HasTable
|
538
|
538
|
]);
|
539
|
539
|
}
|
540
|
540
|
|
541
|
|
- protected function getJournalEntriesTableRepeater(): JournalEntryRepeater
|
|
541
|
+ protected function getJournalEntriesTableRepeater(): CustomTableRepeater
|
542
|
542
|
{
|
543
|
|
- return JournalEntryRepeater::make('journalEntries')
|
|
543
|
+ return CustomTableRepeater::make('journalEntries')
|
544
|
544
|
->relationship('journalEntries')
|
545
|
545
|
->hiddenLabel()
|
546
|
546
|
->columns(4)
|
547
|
547
|
->headers($this->getJournalEntriesTableRepeaterHeaders())
|
548
|
548
|
->schema($this->getJournalEntriesTableRepeaterSchema())
|
549
|
|
- ->streamlined()
|
550
|
|
- ->deletable(fn (JournalEntryRepeater $repeater) => $repeater->getItemsCount() > 2)
|
|
549
|
+ ->deletable(fn (CustomTableRepeater $repeater) => $repeater->getItemsCount() > 2)
|
551
|
550
|
->deleteAction(function (Forms\Components\Actions\Action $action) {
|
552
|
551
|
return $action
|
553
|
|
- ->action(function (array $arguments, JournalEntryRepeater $component): void {
|
|
552
|
+ ->action(function (array $arguments, CustomTableRepeater $component): void {
|
554
|
553
|
$items = $component->getState();
|
555
|
554
|
|
556
|
555
|
$amount = $items[$arguments['item']]['amount'];
|
|
@@ -565,6 +564,44 @@ class Transactions extends Page implements HasTable
|
565
|
564
|
$component->callAfterStateUpdated();
|
566
|
565
|
});
|
567
|
566
|
})
|
|
567
|
+ ->rules([
|
|
568
|
+ function () {
|
|
569
|
+ return function (string $attribute, $value, \Closure $fail) {
|
|
570
|
+ if (empty($value) || ! is_array($value)) {
|
|
571
|
+ $fail('Journal entries are required.');
|
|
572
|
+
|
|
573
|
+ return;
|
|
574
|
+ }
|
|
575
|
+
|
|
576
|
+ $hasDebit = false;
|
|
577
|
+ $hasCredit = false;
|
|
578
|
+
|
|
579
|
+ foreach ($value as $entry) {
|
|
580
|
+ if (! isset($entry['type'])) {
|
|
581
|
+ continue;
|
|
582
|
+ }
|
|
583
|
+
|
|
584
|
+ if (JournalEntryType::parse($entry['type'])->isDebit()) {
|
|
585
|
+ $hasDebit = true;
|
|
586
|
+ } elseif (JournalEntryType::parse($entry['type'])->isCredit()) {
|
|
587
|
+ $hasCredit = true;
|
|
588
|
+ }
|
|
589
|
+
|
|
590
|
+ if ($hasDebit && $hasCredit) {
|
|
591
|
+ break;
|
|
592
|
+ }
|
|
593
|
+ }
|
|
594
|
+
|
|
595
|
+ if (! $hasDebit) {
|
|
596
|
+ $fail('At least one debit entry is required.');
|
|
597
|
+ }
|
|
598
|
+
|
|
599
|
+ if (! $hasCredit) {
|
|
600
|
+ $fail('At least one credit entry is required.');
|
|
601
|
+ }
|
|
602
|
+ };
|
|
603
|
+ },
|
|
604
|
+ ])
|
568
|
605
|
->minItems(2)
|
569
|
606
|
->defaultItems(2)
|
570
|
607
|
->addable(false)
|
|
@@ -634,7 +671,7 @@ class Transactions extends Page implements HasTable
|
634
|
671
|
->color($type->isDebit() ? 'primary' : 'gray')
|
635
|
672
|
->iconSize(IconSize::Small)
|
636
|
673
|
->iconPosition(IconPosition::Before)
|
637
|
|
- ->action(function (JournalEntryRepeater $component) use ($type) {
|
|
674
|
+ ->action(function (CustomTableRepeater $component) use ($type) {
|
638
|
675
|
$state = $component->getState();
|
639
|
676
|
$newUuid = (string) Str::uuid();
|
640
|
677
|
$state[$newUuid] = $this->defaultEntry($type);
|