Andrew Wallo 6 月之前
父節點
當前提交
5323fe2864

+ 3
- 3
app/Filament/Company/Resources/Purchases/BillResource.php 查看文件

@@ -122,17 +122,17 @@ class BillResource extends Resource
122 122
                                     Header::make($settings->resolveColumnLabel('item_name', 'Items'))
123 123
                                         ->width($hasDiscounts ? '15%' : '20%'),
124 124
                                     Header::make('Description')
125
-                                        ->width($hasDiscounts ? '15%' : '20%'), // Reduced from 25%/30%
125
+                                        ->width($hasDiscounts ? '15%' : '20%'),
126 126
                                     Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
127 127
                                         ->width('10%'),
128 128
                                     Header::make($settings->resolveColumnLabel('price_name', 'Price'))
129 129
                                         ->width('10%'),
130 130
                                     Header::make('Taxes')
131
-                                        ->width($hasDiscounts ? '20%' : '30%'), // Increased from 15%/20%
131
+                                        ->width($hasDiscounts ? '20%' : '30%'),
132 132
                                 ];
133 133
 
134 134
                                 if ($hasDiscounts) {
135
-                                    $headers[] = Header::make('Discounts')->width('20%'); // Increased from 15%
135
+                                    $headers[] = Header::make('Discounts')->width('20%');
136 136
                                 }
137 137
 
138 138
                                 $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))

+ 52
- 12
app/Filament/Company/Resources/Sales/EstimateResource.php 查看文件

@@ -2,12 +2,16 @@
2 2
 
3 3
 namespace App\Filament\Company\Resources\Sales;
4 4
 
5
+use App\Enums\Accounting\AdjustmentCategory;
6
+use App\Enums\Accounting\AdjustmentStatus;
7
+use App\Enums\Accounting\AdjustmentType;
5 8
 use App\Enums\Accounting\DocumentDiscountMethod;
6 9
 use App\Enums\Accounting\DocumentType;
7 10
 use App\Enums\Accounting\EstimateStatus;
8 11
 use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\EstimatesRelationManager;
9 12
 use App\Filament\Company\Resources\Sales\EstimateResource\Pages;
10 13
 use App\Filament\Company\Resources\Sales\EstimateResource\Widgets;
14
+use App\Filament\Forms\Components\CreateAdjustmentSelect;
11 15
 use App\Filament\Forms\Components\CreateCurrencySelect;
12 16
 use App\Filament\Forms\Components\DocumentFooterSection;
13 17
 use App\Filament\Forms\Components\DocumentHeaderSection;
@@ -16,6 +20,7 @@ use App\Filament\Tables\Actions\ReplicateBulkAction;
16 20
 use App\Filament\Tables\Columns;
17 21
 use App\Filament\Tables\Filters\DateRangeFilter;
18 22
 use App\Models\Accounting\Adjustment;
23
+use App\Models\Accounting\DocumentLineItem;
19 24
 use App\Models\Accounting\Estimate;
20 25
 use App\Models\Common\Client;
21 26
 use App\Models\Common\Offering;
@@ -124,17 +129,17 @@ class EstimateResource extends Resource
124 129
                                     Header::make($settings->resolveColumnLabel('item_name', 'Items'))
125 130
                                         ->width($hasDiscounts ? '15%' : '20%'),
126 131
                                     Header::make('Description')
127
-                                        ->width($hasDiscounts ? '25%' : '30%'),
132
+                                        ->width($hasDiscounts ? '15%' : '20%'),
128 133
                                     Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
129 134
                                         ->width('10%'),
130 135
                                     Header::make($settings->resolveColumnLabel('price_name', 'Price'))
131 136
                                         ->width('10%'),
132 137
                                     Header::make('Taxes')
133
-                                        ->width($hasDiscounts ? '15%' : '20%'),
138
+                                        ->width($hasDiscounts ? '20%' : '30%'),
134 139
                                 ];
135 140
 
136 141
                                 if ($hasDiscounts) {
137
-                                    $headers[] = Header::make('Discounts')->width('15%');
142
+                                    $headers[] = Header::make('Discounts')->width('20%');
138 143
                                 }
139 144
 
140 145
                                 $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
@@ -150,9 +155,40 @@ class EstimateResource extends Resource
150 155
                                     ->searchable()
151 156
                                     ->required()
152 157
                                     ->live()
153
-                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
158
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state, ?DocumentLineItem $record) {
154 159
                                         $offeringId = $state;
155
-                                        $offeringRecord = Offering::with(['salesTaxes', 'salesDiscounts'])->find($offeringId);
160
+                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
161
+                                        $isPerLineItem = $discountMethod->isPerLineItem();
162
+
163
+                                        $existingTaxIds = [];
164
+                                        $existingDiscountIds = [];
165
+
166
+                                        if ($record) {
167
+                                            $existingTaxIds = $record->salesTaxes()->pluck('adjustments.id')->toArray();
168
+                                            if ($isPerLineItem) {
169
+                                                $existingDiscountIds = $record->salesDiscounts()->pluck('adjustments.id')->toArray();
170
+                                            }
171
+                                        }
172
+
173
+                                        $with = [
174
+                                            'salesTaxes' => static function ($query) use ($existingTaxIds) {
175
+                                                $query->where(static function ($query) use ($existingTaxIds) {
176
+                                                    $query->where('status', AdjustmentStatus::Active)
177
+                                                        ->orWhereIn('adjustments.id', $existingTaxIds);
178
+                                                });
179
+                                            },
180
+                                        ];
181
+
182
+                                        if ($isPerLineItem) {
183
+                                            $with['salesDiscounts'] = static function ($query) use ($existingDiscountIds) {
184
+                                                $query->where(static function ($query) use ($existingDiscountIds) {
185
+                                                    $query->where('status', AdjustmentStatus::Active)
186
+                                                        ->orWhereIn('adjustments.id', $existingDiscountIds);
187
+                                                });
188
+                                            };
189
+                                        }
190
+
191
+                                        $offeringRecord = Offering::with($with)->find($offeringId);
156 192
 
157 193
                                         if (! $offeringRecord) {
158 194
                                             return;
@@ -164,8 +200,7 @@ class EstimateResource extends Resource
164 200
                                         $set('unit_price', $unitPrice);
165 201
                                         $set('salesTaxes', $offeringRecord->salesTaxes->pluck('id')->toArray());
166 202
 
167
-                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
168
-                                        if ($discountMethod->isPerLineItem()) {
203
+                                        if ($isPerLineItem) {
169 204
                                             $set('salesDiscounts', $offeringRecord->salesDiscounts->pluck('id')->toArray());
170 205
                                         }
171 206
                                     }),
@@ -182,19 +217,24 @@ class EstimateResource extends Resource
182 217
                                     ->live()
183 218
                                     ->maxValue(9999999999.99)
184 219
                                     ->default(0),
185
-                                Forms\Components\Select::make('salesTaxes')
186
-                                    ->relationship('salesTaxes', 'name')
220
+                                CreateAdjustmentSelect::make('salesTaxes')
221
+                                    ->label('Taxes')
222
+                                    ->category(AdjustmentCategory::Tax)
223
+                                    ->type(AdjustmentType::Sales)
224
+                                    ->adjustmentsRelationship('salesTaxes')
187 225
                                     ->saveRelationshipsUsing(null)
188 226
                                     ->dehydrated(true)
189 227
                                     ->preload()
190 228
                                     ->multiple()
191 229
                                     ->live()
192 230
                                     ->searchable(),
193
-                                Forms\Components\Select::make('salesDiscounts')
194
-                                    ->relationship('salesDiscounts', 'name')
231
+                                CreateAdjustmentSelect::make('salesDiscounts')
232
+                                    ->label('Discounts')
233
+                                    ->category(AdjustmentCategory::Discount)
234
+                                    ->type(AdjustmentType::Sales)
235
+                                    ->adjustmentsRelationship('salesDiscounts')
195 236
                                     ->saveRelationshipsUsing(null)
196 237
                                     ->dehydrated(true)
197
-                                    ->preload()
198 238
                                     ->multiple()
199 239
                                     ->live()
200 240
                                     ->hidden(function (Forms\Get $get) {

+ 52
- 12
app/Filament/Company/Resources/Sales/InvoiceResource.php 查看文件

@@ -3,6 +3,9 @@
3 3
 namespace App\Filament\Company\Resources\Sales;
4 4
 
5 5
 use App\Collections\Accounting\DocumentCollection;
6
+use App\Enums\Accounting\AdjustmentCategory;
7
+use App\Enums\Accounting\AdjustmentStatus;
8
+use App\Enums\Accounting\AdjustmentType;
6 9
 use App\Enums\Accounting\DocumentDiscountMethod;
7 10
 use App\Enums\Accounting\DocumentType;
8 11
 use App\Enums\Accounting\InvoiceStatus;
@@ -11,6 +14,7 @@ use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\Invoice
11 14
 use App\Filament\Company\Resources\Sales\InvoiceResource\Pages;
12 15
 use App\Filament\Company\Resources\Sales\InvoiceResource\RelationManagers;
13 16
 use App\Filament\Company\Resources\Sales\InvoiceResource\Widgets;
17
+use App\Filament\Forms\Components\CreateAdjustmentSelect;
14 18
 use App\Filament\Forms\Components\CreateCurrencySelect;
15 19
 use App\Filament\Forms\Components\DocumentFooterSection;
16 20
 use App\Filament\Forms\Components\DocumentHeaderSection;
@@ -19,6 +23,7 @@ use App\Filament\Tables\Actions\ReplicateBulkAction;
19 23
 use App\Filament\Tables\Columns;
20 24
 use App\Filament\Tables\Filters\DateRangeFilter;
21 25
 use App\Models\Accounting\Adjustment;
26
+use App\Models\Accounting\DocumentLineItem;
22 27
 use App\Models\Accounting\Invoice;
23 28
 use App\Models\Banking\BankAccount;
24 29
 use App\Models\Common\Client;
@@ -137,17 +142,17 @@ class InvoiceResource extends Resource
137 142
                                     Header::make($settings->resolveColumnLabel('item_name', 'Items'))
138 143
                                         ->width($hasDiscounts ? '15%' : '20%'),
139 144
                                     Header::make('Description')
140
-                                        ->width($hasDiscounts ? '25%' : '30%'),
145
+                                        ->width($hasDiscounts ? '15%' : '20%'),
141 146
                                     Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
142 147
                                         ->width('10%'),
143 148
                                     Header::make($settings->resolveColumnLabel('price_name', 'Price'))
144 149
                                         ->width('10%'),
145 150
                                     Header::make('Taxes')
146
-                                        ->width($hasDiscounts ? '15%' : '20%'),
151
+                                        ->width($hasDiscounts ? '20%' : '30%'),
147 152
                                 ];
148 153
 
149 154
                                 if ($hasDiscounts) {
150
-                                    $headers[] = Header::make('Discounts')->width('15%');
155
+                                    $headers[] = Header::make('Discounts')->width('20%');
151 156
                                 }
152 157
 
153 158
                                 $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
@@ -163,9 +168,40 @@ class InvoiceResource extends Resource
163 168
                                     ->searchable()
164 169
                                     ->required()
165 170
                                     ->live()
166
-                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
171
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state, ?DocumentLineItem $record) {
167 172
                                         $offeringId = $state;
168
-                                        $offeringRecord = Offering::with(['salesTaxes', 'salesDiscounts'])->find($offeringId);
173
+                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
174
+                                        $isPerLineItem = $discountMethod->isPerLineItem();
175
+
176
+                                        $existingTaxIds = [];
177
+                                        $existingDiscountIds = [];
178
+
179
+                                        if ($record) {
180
+                                            $existingTaxIds = $record->salesTaxes()->pluck('adjustments.id')->toArray();
181
+                                            if ($isPerLineItem) {
182
+                                                $existingDiscountIds = $record->salesDiscounts()->pluck('adjustments.id')->toArray();
183
+                                            }
184
+                                        }
185
+
186
+                                        $with = [
187
+                                            'salesTaxes' => static function ($query) use ($existingTaxIds) {
188
+                                                $query->where(static function ($query) use ($existingTaxIds) {
189
+                                                    $query->where('status', AdjustmentStatus::Active)
190
+                                                        ->orWhereIn('adjustments.id', $existingTaxIds);
191
+                                                });
192
+                                            },
193
+                                        ];
194
+
195
+                                        if ($isPerLineItem) {
196
+                                            $with['salesDiscounts'] = static function ($query) use ($existingDiscountIds) {
197
+                                                $query->where(static function ($query) use ($existingDiscountIds) {
198
+                                                    $query->where('status', AdjustmentStatus::Active)
199
+                                                        ->orWhereIn('adjustments.id', $existingDiscountIds);
200
+                                                });
201
+                                            };
202
+                                        }
203
+
204
+                                        $offeringRecord = Offering::with($with)->find($offeringId);
169 205
 
170 206
                                         if (! $offeringRecord) {
171 207
                                             return;
@@ -177,8 +213,7 @@ class InvoiceResource extends Resource
177 213
                                         $set('unit_price', $unitPrice);
178 214
                                         $set('salesTaxes', $offeringRecord->salesTaxes->pluck('id')->toArray());
179 215
 
180
-                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
181
-                                        if ($discountMethod->isPerLineItem()) {
216
+                                        if ($isPerLineItem) {
182 217
                                             $set('salesDiscounts', $offeringRecord->salesDiscounts->pluck('id')->toArray());
183 218
                                         }
184 219
                                     }),
@@ -195,19 +230,24 @@ class InvoiceResource extends Resource
195 230
                                     ->live()
196 231
                                     ->maxValue(9999999999.99)
197 232
                                     ->default(0),
198
-                                Forms\Components\Select::make('salesTaxes')
199
-                                    ->relationship('salesTaxes', 'name')
233
+                                CreateAdjustmentSelect::make('salesTaxes')
234
+                                    ->label('Taxes')
235
+                                    ->category(AdjustmentCategory::Tax)
236
+                                    ->type(AdjustmentType::Sales)
237
+                                    ->adjustmentsRelationship('salesTaxes')
200 238
                                     ->saveRelationshipsUsing(null)
201 239
                                     ->dehydrated(true)
202 240
                                     ->preload()
203 241
                                     ->multiple()
204 242
                                     ->live()
205 243
                                     ->searchable(),
206
-                                Forms\Components\Select::make('salesDiscounts')
207
-                                    ->relationship('salesDiscounts', 'name')
244
+                                CreateAdjustmentSelect::make('salesDiscounts')
245
+                                    ->label('Discounts')
246
+                                    ->category(AdjustmentCategory::Discount)
247
+                                    ->type(AdjustmentType::Sales)
248
+                                    ->adjustmentsRelationship('salesDiscounts')
208 249
                                     ->saveRelationshipsUsing(null)
209 250
                                     ->dehydrated(true)
210
-                                    ->preload()
211 251
                                     ->multiple()
212 252
                                     ->live()
213 253
                                     ->hidden(function (Forms\Get $get) {

+ 52
- 12
app/Filament/Company/Resources/Sales/RecurringInvoiceResource.php 查看文件

@@ -2,18 +2,23 @@
2 2
 
3 3
 namespace App\Filament\Company\Resources\Sales;
4 4
 
5
+use App\Enums\Accounting\AdjustmentCategory;
6
+use App\Enums\Accounting\AdjustmentStatus;
7
+use App\Enums\Accounting\AdjustmentType;
5 8
 use App\Enums\Accounting\DocumentDiscountMethod;
6 9
 use App\Enums\Accounting\DocumentType;
7 10
 use App\Enums\Accounting\RecurringInvoiceStatus;
8 11
 use App\Enums\Setting\PaymentTerms;
9 12
 use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\RecurringInvoicesRelationManager;
10 13
 use App\Filament\Company\Resources\Sales\RecurringInvoiceResource\Pages;
14
+use App\Filament\Forms\Components\CreateAdjustmentSelect;
11 15
 use App\Filament\Forms\Components\CreateCurrencySelect;
12 16
 use App\Filament\Forms\Components\DocumentFooterSection;
13 17
 use App\Filament\Forms\Components\DocumentHeaderSection;
14 18
 use App\Filament\Forms\Components\DocumentTotals;
15 19
 use App\Filament\Tables\Columns;
16 20
 use App\Models\Accounting\Adjustment;
21
+use App\Models\Accounting\DocumentLineItem;
17 22
 use App\Models\Accounting\RecurringInvoice;
18 23
 use App\Models\Common\Client;
19 24
 use App\Models\Common\Offering;
@@ -108,17 +113,17 @@ class RecurringInvoiceResource extends Resource
108 113
                                     Header::make($settings->resolveColumnLabel('item_name', 'Items'))
109 114
                                         ->width($hasDiscounts ? '15%' : '20%'),
110 115
                                     Header::make('Description')
111
-                                        ->width($hasDiscounts ? '25%' : '30%'),
116
+                                        ->width($hasDiscounts ? '15%' : '20%'),
112 117
                                     Header::make($settings->resolveColumnLabel('unit_name', 'Quantity'))
113 118
                                         ->width('10%'),
114 119
                                     Header::make($settings->resolveColumnLabel('price_name', 'Price'))
115 120
                                         ->width('10%'),
116 121
                                     Header::make('Taxes')
117
-                                        ->width($hasDiscounts ? '15%' : '20%'),
122
+                                        ->width($hasDiscounts ? '20%' : '30%'),
118 123
                                 ];
119 124
 
120 125
                                 if ($hasDiscounts) {
121
-                                    $headers[] = Header::make('Discounts')->width('15%');
126
+                                    $headers[] = Header::make('Discounts')->width('20%');
122 127
                                 }
123 128
 
124 129
                                 $headers[] = Header::make($settings->resolveColumnLabel('amount_name', 'Amount'))
@@ -134,9 +139,40 @@ class RecurringInvoiceResource extends Resource
134 139
                                     ->searchable()
135 140
                                     ->required()
136 141
                                     ->live()
137
-                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
142
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state, ?DocumentLineItem $record) {
138 143
                                         $offeringId = $state;
139
-                                        $offeringRecord = Offering::with(['salesTaxes', 'salesDiscounts'])->find($offeringId);
144
+                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
145
+                                        $isPerLineItem = $discountMethod->isPerLineItem();
146
+
147
+                                        $existingTaxIds = [];
148
+                                        $existingDiscountIds = [];
149
+
150
+                                        if ($record) {
151
+                                            $existingTaxIds = $record->salesTaxes()->pluck('adjustments.id')->toArray();
152
+                                            if ($isPerLineItem) {
153
+                                                $existingDiscountIds = $record->salesDiscounts()->pluck('adjustments.id')->toArray();
154
+                                            }
155
+                                        }
156
+
157
+                                        $with = [
158
+                                            'salesTaxes' => static function ($query) use ($existingTaxIds) {
159
+                                                $query->where(static function ($query) use ($existingTaxIds) {
160
+                                                    $query->where('status', AdjustmentStatus::Active)
161
+                                                        ->orWhereIn('adjustments.id', $existingTaxIds);
162
+                                                });
163
+                                            },
164
+                                        ];
165
+
166
+                                        if ($isPerLineItem) {
167
+                                            $with['salesDiscounts'] = static function ($query) use ($existingDiscountIds) {
168
+                                                $query->where(static function ($query) use ($existingDiscountIds) {
169
+                                                    $query->where('status', AdjustmentStatus::Active)
170
+                                                        ->orWhereIn('adjustments.id', $existingDiscountIds);
171
+                                                });
172
+                                            };
173
+                                        }
174
+
175
+                                        $offeringRecord = Offering::with($with)->find($offeringId);
140 176
 
141 177
                                         if (! $offeringRecord) {
142 178
                                             return;
@@ -148,8 +184,7 @@ class RecurringInvoiceResource extends Resource
148 184
                                         $set('unit_price', $unitPrice);
149 185
                                         $set('salesTaxes', $offeringRecord->salesTaxes->pluck('id')->toArray());
150 186
 
151
-                                        $discountMethod = DocumentDiscountMethod::parse($get('../../discount_method'));
152
-                                        if ($discountMethod->isPerLineItem()) {
187
+                                        if ($isPerLineItem) {
153 188
                                             $set('salesDiscounts', $offeringRecord->salesDiscounts->pluck('id')->toArray());
154 189
                                         }
155 190
                                     }),
@@ -166,19 +201,24 @@ class RecurringInvoiceResource extends Resource
166 201
                                     ->live()
167 202
                                     ->maxValue(9999999999.99)
168 203
                                     ->default(0),
169
-                                Forms\Components\Select::make('salesTaxes')
170
-                                    ->relationship('salesTaxes', 'name')
204
+                                CreateAdjustmentSelect::make('salesTaxes')
205
+                                    ->label('Taxes')
206
+                                    ->category(AdjustmentCategory::Tax)
207
+                                    ->type(AdjustmentType::Sales)
208
+                                    ->adjustmentsRelationship('salesTaxes')
171 209
                                     ->saveRelationshipsUsing(null)
172 210
                                     ->dehydrated(true)
173 211
                                     ->preload()
174 212
                                     ->multiple()
175 213
                                     ->live()
176 214
                                     ->searchable(),
177
-                                Forms\Components\Select::make('salesDiscounts')
178
-                                    ->relationship('salesDiscounts', 'name')
215
+                                CreateAdjustmentSelect::make('salesDiscounts')
216
+                                    ->label('Discounts')
217
+                                    ->category(AdjustmentCategory::Discount)
218
+                                    ->type(AdjustmentType::Sales)
219
+                                    ->adjustmentsRelationship('salesDiscounts')
179 220
                                     ->saveRelationshipsUsing(null)
180 221
                                     ->dehydrated(true)
181
-                                    ->preload()
182 222
                                     ->multiple()
183 223
                                     ->live()
184 224
                                     ->hidden(function (Forms\Get $get) {

Loading…
取消
儲存