Andrew Wallo 6 miesięcy temu
rodzic
commit
da7020a9b6

+ 1
- 0
app/Filament/Company/Resources/Sales/InvoiceResource.php Wyświetl plik

@@ -413,6 +413,7 @@ class InvoiceResource extends Resource
413 413
                             ->url(static fn (Invoice $record) => Pages\ViewInvoice::getUrl(['record' => $record])),
414 414
                         Invoice::getReplicateAction(Tables\Actions\ReplicateAction::class),
415 415
                         Invoice::getApproveDraftAction(Tables\Actions\Action::class),
416
+                        Invoice::getBlockedApproveAction(Tables\Actions\Action::class),
416 417
                         Invoice::getMarkAsSentAction(Tables\Actions\Action::class),
417 418
                         Tables\Actions\Action::make('recordPayment')
418 419
                             ->label(fn (Invoice $record) => $record->status === InvoiceStatus::Overpaid ? 'Refund Overpayment' : 'Record Payment')

+ 1
- 0
app/Filament/Company/Resources/Sales/InvoiceResource/Pages/ViewInvoice.php Wyświetl plik

@@ -40,6 +40,7 @@ class ViewInvoice extends ViewRecord
40 40
             Actions\ActionGroup::make([
41 41
                 Actions\ActionGroup::make([
42 42
                     Invoice::getApproveDraftAction(),
43
+                    Invoice::getBlockedApproveAction(),
43 44
                     Invoice::getMarkAsSentAction(),
44 45
                     Invoice::getPrintDocumentAction(),
45 46
                     Invoice::getReplicateAction(),

+ 10
- 0
app/Models/Accounting/Adjustment.php Wyświetl plik

@@ -99,6 +99,16 @@ class Adjustment extends Model
99 99
         return $this->category->isDiscount() && $this->type->isPurchase();
100 100
     }
101 101
 
102
+    public function isActive(): bool
103
+    {
104
+        return $this->status === AdjustmentStatus::Active;
105
+    }
106
+
107
+    public function isInactive(): bool
108
+    {
109
+        return ! $this->isActive();
110
+    }
111
+
102 112
     public function canBePaused(): bool
103 113
     {
104 114
         return $this->status === AdjustmentStatus::Active;

+ 53
- 1
app/Models/Accounting/Invoice.php Wyświetl plik

@@ -22,6 +22,8 @@ use App\Utilities\Currency\CurrencyConverter;
22 22
 use Filament\Actions\Action;
23 23
 use Filament\Actions\MountableAction;
24 24
 use Filament\Actions\ReplicateAction;
25
+use Filament\Actions\StaticAction;
26
+use Filament\Support\Enums\Alignment;
25 27
 use Illuminate\Database\Eloquent\Attributes\CollectedBy;
26 28
 use Illuminate\Database\Eloquent\Attributes\ObservedBy;
27 29
 use Illuminate\Database\Eloquent\Builder;
@@ -31,6 +33,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
31 33
 use Illuminate\Database\Eloquent\Relations\MorphMany;
32 34
 use Illuminate\Database\Eloquent\Relations\MorphOne;
33 35
 use Illuminate\Support\Carbon;
36
+use Illuminate\Support\HtmlString;
34 37
 
35 38
 #[CollectedBy(DocumentCollection::class)]
36 39
 #[ObservedBy(InvoiceObserver::class)]
@@ -458,14 +461,63 @@ class Invoice extends Document
458 461
         return CurrencyConverter::convertCentsToFormatSimple($convertedCents);
459 462
     }
460 463
 
464
+    public function hasInactiveAdjustments(): bool
465
+    {
466
+        return $this->lineItems->contains(function (DocumentLineItem $lineItem) {
467
+            return $lineItem->adjustments->contains(function (Adjustment $adjustment) {
468
+                return $adjustment->isInactive();
469
+            });
470
+        });
471
+    }
472
+
473
+    // TODO: Potentially handle this another way
474
+    public static function getBlockedApproveAction(string $action = Action::class): MountableAction
475
+    {
476
+        return $action::make('blockedApprove')
477
+            ->label('Approve')
478
+            ->icon('heroicon-m-check-circle')
479
+            ->visible(fn (self $record) => $record->canBeApproved() && $record->hasInactiveAdjustments())
480
+            ->requiresConfirmation()
481
+            ->modalAlignment(Alignment::Start)
482
+            ->modalIconColor('danger')
483
+            ->modalDescription(function (self $record) {
484
+                $inactiveAdjustments = collect();
485
+
486
+                foreach ($record->lineItems as $lineItem) {
487
+                    foreach ($lineItem->adjustments as $adjustment) {
488
+                        if ($adjustment->isInactive() && $inactiveAdjustments->doesntContain($adjustment->name)) {
489
+                            $inactiveAdjustments->push($adjustment->name);
490
+                        }
491
+                    }
492
+                }
493
+
494
+                $output = "<p class='text-sm mb-4'>This invoice contains inactive adjustments that need to be addressed before approval:</p>";
495
+                $output .= "<ul role='list' class='list-disc list-inside space-y-1 text-sm'>";
496
+
497
+                foreach ($inactiveAdjustments as $name) {
498
+                    $output .= "<li class='py-1'><span class='font-medium'>{$name}</span></li>";
499
+                }
500
+
501
+                $output .= '</ul>';
502
+                $output .= "<p class='text-sm mt-4'>Please update these adjustments before approving the invoice.</p>";
503
+
504
+                return new HtmlString($output);
505
+            })
506
+            ->modalSubmitAction(function (StaticAction $action, self $record) {
507
+                $action->label('Edit Invoice')
508
+                    ->url(InvoiceResource\Pages\EditInvoice::getUrl(['record' => $record->id]));
509
+            });
510
+    }
511
+
461 512
     public static function getApproveDraftAction(string $action = Action::class): MountableAction
462 513
     {
463 514
         return $action::make('approveDraft')
464 515
             ->label('Approve')
465 516
             ->icon('heroicon-m-check-circle')
466 517
             ->visible(function (self $record) {
467
-                return $record->canBeApproved();
518
+                return $record->canBeApproved() && ! $record->hasInactiveAdjustments();
468 519
             })
520
+            ->requiresConfirmation()
469 521
             ->databaseTransaction()
470 522
             ->successNotificationTitle('Invoice approved')
471 523
             ->action(function (self $record, MountableAction $action) {

Ładowanie…
Anuluj
Zapisz