Andrew Wallo 5 месяцев назад
Родитель
Сommit
331313305c

+ 44
- 7
app/Filament/Company/Pages/Accounting/Transactions.php Просмотреть файл

@@ -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);

+ 21
- 0
app/Filament/Forms/Components/CustomTableRepeater.php Просмотреть файл

@@ -5,6 +5,8 @@ namespace App\Filament\Forms\Components;
5 5
 use Awcodes\TableRepeater\Components\TableRepeater;
6 6
 use Closure;
7 7
 use Filament\Forms\Components\Actions\Action;
8
+use Illuminate\Contracts\Support\Htmlable;
9
+use Illuminate\Contracts\View\View;
8 10
 
9 11
 class CustomTableRepeater extends TableRepeater
10 12
 {
@@ -12,6 +14,8 @@ class CustomTableRepeater extends TableRepeater
12 14
 
13 15
     protected bool | Closure $reorderAtStart = false;
14 16
 
17
+    protected View | Htmlable | Closure | null $footerItem = null;
18
+
15 19
     /**
16 20
      * @var array<string> | Closure | null
17 21
      */
@@ -48,6 +52,23 @@ class CustomTableRepeater extends TableRepeater
48 52
         return $this->evaluate($this->reorderAtStart) && $this->isReorderable();
49 53
     }
50 54
 
55
+    public function footerItem(View | Htmlable | Closure | null $footer = null): static
56
+    {
57
+        $this->footerItem = $footer;
58
+
59
+        return $this;
60
+    }
61
+
62
+    public function getFooterItem(): View | Htmlable | null
63
+    {
64
+        return $this->evaluate($this->footerItem);
65
+    }
66
+
67
+    public function hasFooterItem(): bool
68
+    {
69
+        return $this->footerItem !== null;
70
+    }
71
+
51 72
     /**
52 73
      * @param  array<string> | Closure | null  $attributes
53 74
      */

+ 25
- 22
resources/views/filament/forms/components/custom-table-repeater.blade.php Просмотреть файл

@@ -222,30 +222,33 @@
222 222
             </div>
223 223
         @endif
224 224
 
225
-        @if ($addAction->isVisible() || filled($visibleExtraActions))
226
-            <ul
227
-                @class([
228
-                    'relative flex gap-4',
229
-                    match ($getAddActionAlignment()) {
230
-                        Alignment::Start, Alignment::Left => 'justify-start',
231
-                        Alignment::End, Alignment::Right => 'justify-end',
232
-                        default =>  'justify-center',
233
-                    },
234
-                ])
235
-            >
236
-                @if ($addAction->isVisible())
237
-                    <li>
238
-                        {{ $addAction }}
239
-                    </li>
225
+        @if ($addAction->isVisible() || filled($visibleExtraActions) || $hasFooterItem())
226
+            <div class="flex justify-between items-start">
227
+                <!-- Actions grouped to the left -->
228
+                @if ($addAction->isVisible() || filled($visibleExtraActions))
229
+                    <ul class="flex gap-4">
230
+                        @if ($addAction->isVisible())
231
+                            <li>
232
+                                {{ $addAction }}
233
+                            </li>
234
+                        @endif
235
+                        @if (filled($visibleExtraActions))
236
+                            @foreach ($visibleExtraActions as $extraAction)
237
+                                <li>
238
+                                    {{ $extraAction }}
239
+                                </li>
240
+                            @endforeach
241
+                        @endif
242
+                    </ul>
240 243
                 @endif
241
-                @if (filled($visibleExtraActions))
242
-                    @foreach ($visibleExtraActions as $extraAction)
243
-                        <li>
244
-                            {{ ($extraAction) }}
245
-                        </li>
246
-                    @endforeach
244
+
245
+                <!-- Container for Footer Item to the right -->
246
+                @if($hasFooterItem())
247
+                    <div>
248
+                        {{ $getFooterItem() }}
249
+                    </div>
247 250
                 @endif
248
-            </ul>
251
+            </div>
249 252
         @endif
250 253
     </div>
251 254
 </x-dynamic-component>

Загрузка…
Отмена
Сохранить