Przeglądaj źródła

Merge pull request #137 from andrewdwallo/development-3.x

Development 3.x
3.x
Andrew Wallo 5 miesięcy temu
rodzic
commit
f84b668e82
No account linked to committer's email address

+ 1
- 1
app/Filament/Company/Resources/Common/OfferingResource.php Wyświetl plik

@@ -37,7 +37,7 @@ class OfferingResource extends Resource
37 37
                     ->label('Inactive adjustments')
38 38
                     ->warning()
39 39
                     ->icon('heroicon-o-exclamation-triangle')
40
-                    ->visible(fn (Offering $record) => $record->hasInactiveAdjustments())
40
+                    ->visible(fn (?Offering $record) => $record?->hasInactiveAdjustments())
41 41
                     ->columnSpanFull()
42 42
                     ->description(function (Offering $record) {
43 43
                         $inactiveAdjustments = collect();

+ 74
- 7
app/Filament/Company/Resources/Purchases/BillResource.php Wyświetl plik

@@ -9,6 +9,7 @@ use App\Enums\Accounting\BillStatus;
9 9
 use App\Enums\Accounting\DocumentDiscountMethod;
10 10
 use App\Enums\Accounting\DocumentType;
11 11
 use App\Enums\Accounting\PaymentMethod;
12
+use App\Enums\Setting\PaymentTerms;
12 13
 use App\Filament\Company\Resources\Purchases\BillResource\Pages;
13 14
 use App\Filament\Company\Resources\Purchases\VendorResource\RelationManagers\BillsRelationManager;
14 15
 use App\Filament\Forms\Components\CreateAdjustmentSelect;
@@ -37,8 +38,10 @@ use Filament\Support\Enums\Alignment;
37 38
 use Filament\Support\Enums\MaxWidth;
38 39
 use Filament\Tables;
39 40
 use Filament\Tables\Table;
41
+use Guava\FilamentClusters\Forms\Cluster;
40 42
 use Illuminate\Database\Eloquent\Builder;
41 43
 use Illuminate\Database\Eloquent\Collection;
44
+use Illuminate\Support\Carbon;
42 45
 use Illuminate\Support\Facades\Auth;
43 46
 
44 47
 class BillResource extends Resource
@@ -83,19 +86,83 @@ class BillResource extends Resource
83 86
                                     ->required(),
84 87
                                 Forms\Components\TextInput::make('order_number')
85 88
                                     ->label('P.O/S.O Number'),
86
-                                Forms\Components\DatePicker::make('date')
89
+                                Cluster::make([
90
+                                    Forms\Components\DatePicker::make('date')
91
+                                        ->label('Bill date')
92
+                                        ->live()
93
+                                        ->default(now())
94
+                                        ->disabled(function (?Bill $record) {
95
+                                            return $record?->hasPayments();
96
+                                        })
97
+                                        ->columnSpan(2)
98
+                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
99
+                                            $date = $state;
100
+                                            $dueDate = $get('due_date');
101
+
102
+                                            if ($date && $dueDate && $date > $dueDate) {
103
+                                                $set('due_date', $date);
104
+                                            }
105
+
106
+                                            // Update due date based on payment terms if selected
107
+                                            $paymentTerms = $get('payment_terms');
108
+                                            if ($date && $paymentTerms && $paymentTerms !== 'custom') {
109
+                                                $terms = PaymentTerms::parse($paymentTerms);
110
+                                                $set('due_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
111
+                                            }
112
+                                        }),
113
+                                    Forms\Components\Select::make('payment_terms')
114
+                                        ->label('Payment terms')
115
+                                        ->options(function () {
116
+                                            return collect(PaymentTerms::cases())
117
+                                                ->mapWithKeys(function (PaymentTerms $paymentTerm) {
118
+                                                    return [$paymentTerm->value => $paymentTerm->getLabel()];
119
+                                                })
120
+                                                ->put('custom', 'Custom')
121
+                                                ->toArray();
122
+                                        })
123
+                                        ->selectablePlaceholder(false)
124
+                                        ->default($settings->payment_terms->value)
125
+                                        ->live()
126
+                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
127
+                                            if (! $state || $state === 'custom') {
128
+                                                return;
129
+                                            }
130
+
131
+                                            $date = $get('date');
132
+                                            if ($date) {
133
+                                                $terms = PaymentTerms::parse($state);
134
+                                                $set('due_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
135
+                                            }
136
+                                        }),
137
+                                ])
87 138
                                     ->label('Bill date')
88
-                                    ->default(now())
89
-                                    ->disabled(function (?Bill $record) {
90
-                                        return $record?->hasPayments();
91
-                                    })
92
-                                    ->required(),
139
+                                    ->columns(3),
93 140
                                 Forms\Components\DatePicker::make('due_date')
94 141
                                     ->label('Due date')
95 142
                                     ->default(function () use ($company) {
96 143
                                         return now()->addDays($company->defaultBill->payment_terms->getDays());
97 144
                                     })
98
-                                    ->required(),
145
+                                    ->required()
146
+                                    ->live()
147
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
148
+                                        if (! $state) {
149
+                                            return;
150
+                                        }
151
+
152
+                                        $date = $get('date');
153
+                                        $paymentTerms = $get('payment_terms');
154
+
155
+                                        if (! $date || $paymentTerms === 'custom') {
156
+                                            return;
157
+                                        }
158
+
159
+                                        $term = PaymentTerms::parse($paymentTerms);
160
+                                        $expected = Carbon::parse($date)->addDays($term->getDays());
161
+
162
+                                        if (! Carbon::parse($state)->isSameDay($expected)) {
163
+                                            $set('payment_terms', 'custom');
164
+                                        }
165
+                                    }),
99 166
                                 Forms\Components\Select::make('discount_method')
100 167
                                     ->label('Discount method')
101 168
                                     ->options(DocumentDiscountMethod::class)

+ 1
- 1
app/Filament/Company/Resources/Purchases/BillResource/Pages/ViewBill.php Wyświetl plik

@@ -59,7 +59,7 @@ class ViewBill extends ViewRecord
59 59
                             ->label('Vendor')
60 60
                             ->color('primary')
61 61
                             ->weight(FontWeight::SemiBold)
62
-                            ->url(static fn (Bill $record) => VendorResource::getUrl('edit', ['record' => $record->vendor_id])),
62
+                            ->url(static fn (Bill $record) => VendorResource::getUrl('view', ['record' => $record->vendor_id])),
63 63
                         TextEntry::make('total')
64 64
                             ->label('Total')
65 65
                             ->currency(fn (Bill $record) => $record->currency_code),

+ 2
- 1
app/Filament/Company/Resources/Sales/ClientResource/Widgets/InvoiceOverview.php Wyświetl plik

@@ -59,7 +59,8 @@ class InvoiceOverview extends EnhancedStatsOverviewWidget
59 59
             EnhancedStatsOverviewWidget\EnhancedStat::make('Average Payment Time', $averagePaymentTimeFormatted)
60 60
                 ->suffix('days'),
61 61
             EnhancedStatsOverviewWidget\EnhancedStat::make('Average Invoice Total', CurrencyConverter::formatCentsToMoney($averageInvoiceTotal))
62
-                ->suffix(CurrencyAccessor::getDefaultCurrency()),
62
+                ->suffix(CurrencyAccessor::getDefaultCurrency())
63
+                ->description('Excludes draft and voided invoices'),
63 64
         ];
64 65
     }
65 66
 }

+ 69
- 11
app/Filament/Company/Resources/Sales/EstimateResource.php Wyświetl plik

@@ -8,6 +8,7 @@ use App\Enums\Accounting\AdjustmentType;
8 8
 use App\Enums\Accounting\DocumentDiscountMethod;
9 9
 use App\Enums\Accounting\DocumentType;
10 10
 use App\Enums\Accounting\EstimateStatus;
11
+use App\Enums\Setting\PaymentTerms;
11 12
 use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\EstimatesRelationManager;
12 13
 use App\Filament\Company\Resources\Sales\EstimateResource\Pages;
13 14
 use App\Filament\Company\Resources\Sales\EstimateResource\Widgets;
@@ -36,7 +37,9 @@ use Filament\Resources\Resource;
36 37
 use Filament\Support\Enums\MaxWidth;
37 38
 use Filament\Tables;
38 39
 use Filament\Tables\Table;
40
+use Guava\FilamentClusters\Forms\Cluster;
39 41
 use Illuminate\Database\Eloquent\Collection;
42
+use Illuminate\Support\Carbon;
40 43
 use Illuminate\Support\Facades\Auth;
41 44
 
42 45
 class EstimateResource extends Resource
@@ -83,18 +86,53 @@ class EstimateResource extends Resource
83 86
                                     ->default(static fn () => Estimate::getNextDocumentNumber()),
84 87
                                 Forms\Components\TextInput::make('reference_number')
85 88
                                     ->label('Reference number'),
86
-                                Forms\Components\DatePicker::make('date')
87
-                                    ->label('Estimate date')
88
-                                    ->live()
89
-                                    ->default(now())
90
-                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
91
-                                        $date = $state;
92
-                                        $expirationDate = $get('expiration_date');
89
+                                Cluster::make([
90
+                                    Forms\Components\DatePicker::make('date')
91
+                                        ->label('Estimate date')
92
+                                        ->live()
93
+                                        ->default(now())
94
+                                        ->columnSpan(2)
95
+                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
96
+                                            $date = $state;
97
+                                            $expirationDate = $get('expiration_date');
98
+
99
+                                            if ($date && $expirationDate && $date > $expirationDate) {
100
+                                                $set('expiration_date', $date);
101
+                                            }
93 102
 
94
-                                        if ($date && $expirationDate && $date > $expirationDate) {
95
-                                            $set('expiration_date', $date);
96
-                                        }
97
-                                    }),
103
+                                            $paymentTerms = $get('payment_terms');
104
+                                            if ($date && $paymentTerms && $paymentTerms !== 'custom') {
105
+                                                $terms = PaymentTerms::parse($paymentTerms);
106
+                                                $set('expiration_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
107
+                                            }
108
+                                        }),
109
+                                    Forms\Components\Select::make('payment_terms')
110
+                                        ->label('Payment terms')
111
+                                        ->options(function () {
112
+                                            return collect(PaymentTerms::cases())
113
+                                                ->mapWithKeys(function (PaymentTerms $paymentTerm) {
114
+                                                    return [$paymentTerm->value => $paymentTerm->getLabel()];
115
+                                                })
116
+                                                ->put('custom', 'Custom')
117
+                                                ->toArray();
118
+                                        })
119
+                                        ->selectablePlaceholder(false)
120
+                                        ->default($settings->payment_terms->value)
121
+                                        ->live()
122
+                                        ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
123
+                                            if (! $state || $state === 'custom') {
124
+                                                return;
125
+                                            }
126
+
127
+                                            $date = $get('date');
128
+                                            if ($date) {
129
+                                                $terms = PaymentTerms::parse($state);
130
+                                                $set('expiration_date', Carbon::parse($date)->addDays($terms->getDays())->toDateString());
131
+                                            }
132
+                                        }),
133
+                                ])
134
+                                    ->label('Estimate date')
135
+                                    ->columns(3),
98 136
                                 Forms\Components\DatePicker::make('expiration_date')
99 137
                                     ->label('Expiration date')
100 138
                                     ->default(function () use ($settings) {
@@ -102,6 +140,26 @@ class EstimateResource extends Resource
102 140
                                     })
103 141
                                     ->minDate(static function (Forms\Get $get) {
104 142
                                         return $get('date') ?? now();
143
+                                    })
144
+                                    ->live()
145
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
146
+                                        if (! $state) {
147
+                                            return;
148
+                                        }
149
+
150
+                                        $date = $get('date');
151
+                                        $paymentTerms = $get('payment_terms');
152
+
153
+                                        if (! $date || $paymentTerms === 'custom') {
154
+                                            return;
155
+                                        }
156
+
157
+                                        $term = PaymentTerms::parse($paymentTerms);
158
+                                        $expected = Carbon::parse($date)->addDays($term->getDays());
159
+
160
+                                        if (! Carbon::parse($state)->isSameDay($expected)) {
161
+                                            $set('payment_terms', 'custom');
162
+                                        }
105 163
                                     }),
106 164
                                 Forms\Components\Select::make('discount_method')
107 165
                                     ->label('Discount method')

+ 73
- 15
app/Filament/Company/Resources/Sales/InvoiceResource.php Wyświetl plik

@@ -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',

+ 2
- 1
resources/data/lang/en.json Wyświetl plik

@@ -201,5 +201,6 @@
201 201
     "Budget Details": "Budget Details",
202 202
     "Budget Items": "Budget Items",
203 203
     "Budget Allocations": "Budget Allocations",
204
-    "Account Selection": "Account Selection"
204
+    "Account Selection": "Account Selection",
205
+    "Custom": "Custom"
205 206
 }

Ładowanie…
Anuluj
Zapisz