|  | @@ -10,6 +10,7 @@ use App\Enums\Accounting\DocumentDiscountMethod;
 | 
		
	
		
			
			| 10 | 10 |  use App\Enums\Accounting\DocumentType;
 | 
		
	
		
			
			| 11 | 11 |  use App\Enums\Accounting\InvoiceStatus;
 | 
		
	
		
			
			| 12 | 12 |  use App\Enums\Accounting\PaymentMethod;
 | 
		
	
		
			
			|  | 13 | +use App\Enums\Setting\PaymentTerms;
 | 
		
	
		
			
			| 13 | 14 |  use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\InvoicesRelationManager;
 | 
		
	
		
			
			| 14 | 15 |  use App\Filament\Company\Resources\Sales\InvoiceResource\Pages;
 | 
		
	
		
			
			| 15 | 16 |  use App\Filament\Company\Resources\Sales\InvoiceResource\Widgets;
 | 
		
	
	
		
			
			|  | @@ -41,8 +42,10 @@ use Filament\Support\Enums\Alignment;
 | 
		
	
		
			
			| 41 | 42 |  use Filament\Support\Enums\MaxWidth;
 | 
		
	
		
			
			| 42 | 43 |  use Filament\Tables;
 | 
		
	
		
			
			| 43 | 44 |  use Filament\Tables\Table;
 | 
		
	
		
			
			|  | 45 | +use Guava\FilamentClusters\Forms\Cluster;
 | 
		
	
		
			
			| 44 | 46 |  use Illuminate\Database\Eloquent\Builder;
 | 
		
	
		
			
			| 45 | 47 |  use Illuminate\Database\Eloquent\Collection;
 | 
		
	
		
			
			|  | 48 | +use Illuminate\Support\Carbon;
 | 
		
	
		
			
			| 46 | 49 |  use Illuminate\Support\Facades\Auth;
 | 
		
	
		
			
			| 47 | 50 |  
 | 
		
	
		
			
			| 48 | 51 |  class InvoiceResource extends Resource
 | 
		
	
	
		
			
			|  | @@ -92,21 +95,57 @@ class InvoiceResource extends Resource
 | 
		
	
		
			
			| 92 | 95 |                                      ->default(static fn () => Invoice::getNextDocumentNumber()),
 | 
		
	
		
			
			| 93 | 96 |                                  Forms\Components\TextInput::make('order_number')
 | 
		
	
		
			
			| 94 | 97 |                                      ->label('P.O/S.O Number'),
 | 
		
	
		
			
			| 95 |  | -                                Forms\Components\DatePicker::make('date')
 | 
		
	
		
			
			| 96 |  | -                                    ->label('Invoice date')
 | 
		
	
		
			
			| 97 |  | -                                    ->live()
 | 
		
	
		
			
			| 98 |  | -                                    ->default(now())
 | 
		
	
		
			
			| 99 |  | -                                    ->disabled(function (?Invoice $record) {
 | 
		
	
		
			
			| 100 |  | -                                        return $record?->hasPayments();
 | 
		
	
		
			
			| 101 |  | -                                    })
 | 
		
	
		
			
			| 102 |  | -                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
 | 
		
	
		
			
			| 103 |  | -                                        $date = $state;
 | 
		
	
		
			
			| 104 |  | -                                        $dueDate = $get('due_date');
 | 
		
	
		
			
			|  | 98 | +                                Cluster::make([
 | 
		
	
		
			
			|  | 99 | +                                    Forms\Components\DatePicker::make('date')
 | 
		
	
		
			
			|  | 100 | +                                        ->label('Invoice date')
 | 
		
	
		
			
			|  | 101 | +                                        ->live()
 | 
		
	
		
			
			|  | 102 | +                                        ->default(now())
 | 
		
	
		
			
			|  | 103 | +                                        ->disabled(function (?Invoice $record) {
 | 
		
	
		
			
			|  | 104 | +                                            return $record?->hasPayments();
 | 
		
	
		
			
			|  | 105 | +                                        })
 | 
		
	
		
			
			|  | 106 | +                                        ->columnSpan(2)
 | 
		
	
		
			
			|  | 107 | +                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
 | 
		
	
		
			
			|  | 108 | +                                            $date = $state;
 | 
		
	
		
			
			|  | 109 | +                                            $dueDate = $get('due_date');
 | 
		
	
		
			
			|  | 110 | +
 | 
		
	
		
			
			|  | 111 | +                                            if ($date && $dueDate && $date > $dueDate) {
 | 
		
	
		
			
			|  | 112 | +                                                $set('due_date', $date);
 | 
		
	
		
			
			|  | 113 | +                                            }
 | 
		
	
		
			
			| 105 | 114 |  
 | 
		
	
		
			
			| 106 |  | -                                        if ($date && $dueDate && $date > $dueDate) {
 | 
		
	
		
			
			| 107 |  | -                                            $set('due_date', $date);
 | 
		
	
		
			
			| 108 |  | -                                        }
 | 
		
	
		
			
			| 109 |  | -                                    }),
 | 
		
	
		
			
			|  | 115 | +                                            // Update due date based on payment terms if selected
 | 
		
	
		
			
			|  | 116 | +                                            $paymentTerms = $get('payment_terms');
 | 
		
	
		
			
			|  | 117 | +                                            if ($date && $paymentTerms && $paymentTerms !== 'custom') {
 | 
		
	
		
			
			|  | 118 | +                                                $terms = PaymentTerms::parse($paymentTerms);
 | 
		
	
		
			
			|  | 119 | +                                                $set('due_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
 | 
		
	
		
			
			|  | 120 | +                                            }
 | 
		
	
		
			
			|  | 121 | +                                        }),
 | 
		
	
		
			
			|  | 122 | +                                    Forms\Components\Select::make('payment_terms')
 | 
		
	
		
			
			|  | 123 | +                                        ->label('Payment terms')
 | 
		
	
		
			
			|  | 124 | +                                        ->options(function () {
 | 
		
	
		
			
			|  | 125 | +                                            return collect(PaymentTerms::cases())
 | 
		
	
		
			
			|  | 126 | +                                                ->mapWithKeys(function (PaymentTerms $paymentTerm) {
 | 
		
	
		
			
			|  | 127 | +                                                    return [$paymentTerm->value => $paymentTerm->getLabel()];
 | 
		
	
		
			
			|  | 128 | +                                                })
 | 
		
	
		
			
			|  | 129 | +                                                ->put('custom', 'Custom')
 | 
		
	
		
			
			|  | 130 | +                                                ->toArray();
 | 
		
	
		
			
			|  | 131 | +                                        })
 | 
		
	
		
			
			|  | 132 | +                                        ->selectablePlaceholder(false)
 | 
		
	
		
			
			|  | 133 | +                                        ->default($settings->payment_terms->value)
 | 
		
	
		
			
			|  | 134 | +                                        ->live()
 | 
		
	
		
			
			|  | 135 | +                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
 | 
		
	
		
			
			|  | 136 | +                                            if (! $state || $state === 'custom') {
 | 
		
	
		
			
			|  | 137 | +                                                return;
 | 
		
	
		
			
			|  | 138 | +                                            }
 | 
		
	
		
			
			|  | 139 | +
 | 
		
	
		
			
			|  | 140 | +                                            $date = $get('date');
 | 
		
	
		
			
			|  | 141 | +                                            if ($date) {
 | 
		
	
		
			
			|  | 142 | +                                                $terms = PaymentTerms::parse($state);
 | 
		
	
		
			
			|  | 143 | +                                                $set('due_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
 | 
		
	
		
			
			|  | 144 | +                                            }
 | 
		
	
		
			
			|  | 145 | +                                        }),
 | 
		
	
		
			
			|  | 146 | +                                ])
 | 
		
	
		
			
			|  | 147 | +                                    ->label('Invoice date')
 | 
		
	
		
			
			|  | 148 | +                                    ->columns(3),
 | 
		
	
		
			
			| 110 | 149 |                                  Forms\Components\DatePicker::make('due_date')
 | 
		
	
		
			
			| 111 | 150 |                                      ->label('Payment due')
 | 
		
	
		
			
			| 112 | 151 |                                      ->default(function () use ($settings) {
 | 
		
	
	
		
			
			|  | @@ -114,6 +153,26 @@ class InvoiceResource extends Resource
 | 
		
	
		
			
			| 114 | 153 |                                      })
 | 
		
	
		
			
			| 115 | 154 |                                      ->minDate(static function (Forms\Get $get) {
 | 
		
	
		
			
			| 116 | 155 |                                          return $get('date') ?? now();
 | 
		
	
		
			
			|  | 156 | +                                    })
 | 
		
	
		
			
			|  | 157 | +                                    ->live()
 | 
		
	
		
			
			|  | 158 | +                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
 | 
		
	
		
			
			|  | 159 | +                                        if (! $state) {
 | 
		
	
		
			
			|  | 160 | +                                            return;
 | 
		
	
		
			
			|  | 161 | +                                        }
 | 
		
	
		
			
			|  | 162 | +
 | 
		
	
		
			
			|  | 163 | +                                        $invoiceDate = $get('date');
 | 
		
	
		
			
			|  | 164 | +                                        $paymentTerms = $get('payment_terms');
 | 
		
	
		
			
			|  | 165 | +
 | 
		
	
		
			
			|  | 166 | +                                        if (! $invoiceDate || $paymentTerms === 'custom') {
 | 
		
	
		
			
			|  | 167 | +                                            return;
 | 
		
	
		
			
			|  | 168 | +                                        }
 | 
		
	
		
			
			|  | 169 | +
 | 
		
	
		
			
			|  | 170 | +                                        $term = PaymentTerms::parse($paymentTerms);
 | 
		
	
		
			
			|  | 171 | +                                        $expectedDueDate = Carbon::parse($invoiceDate)->addDays($term->getDays());
 | 
		
	
		
			
			|  | 172 | +
 | 
		
	
		
			
			|  | 173 | +                                        if (! Carbon::parse($state)->isSameDay($expectedDueDate)) {
 | 
		
	
		
			
			|  | 174 | +                                            $set('payment_terms', 'custom');
 | 
		
	
		
			
			|  | 175 | +                                        }
 | 
		
	
		
			
			| 117 | 176 |                                      }),
 | 
		
	
		
			
			| 118 | 177 |                                  Forms\Components\Select::make('discount_method')
 | 
		
	
		
			
			| 119 | 178 |                                      ->label('Discount method')
 | 
		
	
	
		
			
			|  | @@ -509,7 +568,6 @@ class InvoiceResource extends Resource
 | 
		
	
		
			
			| 509 | 568 |                          ->successNotificationTitle('Invoices replicated successfully')
 | 
		
	
		
			
			| 510 | 569 |                          ->failureNotificationTitle('Failed to replicate invoices')
 | 
		
	
		
			
			| 511 | 570 |                          ->databaseTransaction()
 | 
		
	
		
			
			| 512 |  | -                        ->deselectRecordsAfterCompletion()
 | 
		
	
		
			
			| 513 | 571 |                          ->excludeAttributes([
 | 
		
	
		
			
			| 514 | 572 |                              'status',
 | 
		
	
		
			
			| 515 | 573 |                              'amount_paid',
 |