瀏覽代碼

wip refactor

3.x
Andrew Wallo 9 月之前
父節點
當前提交
22a5c35d0c

+ 45
- 0
app/Enums/Accounting/DocumentType.php 查看文件

@@ -0,0 +1,45 @@
1
+<?php
2
+
3
+namespace App\Enums\Accounting;
4
+
5
+use Filament\Support\Contracts\HasIcon;
6
+use Filament\Support\Contracts\HasLabel;
7
+
8
+enum DocumentType: string implements HasIcon, HasLabel
9
+{
10
+    case Invoice = 'invoice';
11
+    case Bill = 'bill';
12
+    // TODO: Add estimate
13
+    // case Estimate = 'estimate';
14
+
15
+    public const DEFAULT = self::Invoice->value;
16
+
17
+    public function getLabel(): ?string
18
+    {
19
+        return $this->name;
20
+    }
21
+
22
+    public function getIcon(): ?string
23
+    {
24
+        return match ($this->value) {
25
+            self::Invoice->value => 'heroicon-o-document-duplicate',
26
+            self::Bill->value => 'heroicon-o-clipboard-document-list',
27
+        };
28
+    }
29
+
30
+    public function getTaxKey(): string
31
+    {
32
+        return match ($this) {
33
+            self::Invoice => 'salesTaxes',
34
+            self::Bill => 'purchaseTaxes',
35
+        };
36
+    }
37
+
38
+    public function getDiscountKey(): string
39
+    {
40
+        return match ($this) {
41
+            self::Invoice => 'salesDiscounts',
42
+            self::Bill => 'purchaseDiscounts',
43
+        };
44
+    }
45
+}

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

@@ -4,16 +4,21 @@ namespace App\Filament\Company\Resources\Purchases;
4 4
 
5 5
 use App\Enums\Accounting\BillStatus;
6 6
 use App\Enums\Accounting\DocumentDiscountMethod;
7
+use App\Enums\Accounting\DocumentType;
7 8
 use App\Enums\Accounting\PaymentMethod;
8 9
 use App\Filament\Company\Resources\Purchases\BillResource\Pages;
9
-use App\Filament\Forms\Components\BillTotals;
10
+use App\Filament\Forms\Components\CreateCurrencySelect;
11
+use App\Filament\Forms\Components\DocumentTotals;
10 12
 use App\Filament\Tables\Actions\ReplicateBulkAction;
11 13
 use App\Filament\Tables\Filters\DateRangeFilter;
12 14
 use App\Models\Accounting\Adjustment;
13 15
 use App\Models\Accounting\Bill;
14 16
 use App\Models\Banking\BankAccount;
15 17
 use App\Models\Common\Offering;
18
+use App\Models\Common\Vendor;
19
+use App\Utilities\Currency\CurrencyAccessor;
16 20
 use App\Utilities\Currency\CurrencyConverter;
21
+use App\Utilities\RateCalculator;
17 22
 use Awcodes\TableRepeater\Components\TableRepeater;
18 23
 use Awcodes\TableRepeater\Header;
19 24
 use Closure;
@@ -49,7 +54,20 @@ class BillResource extends Resource
49 54
                                     ->relationship('vendor', 'name')
50 55
                                     ->preload()
51 56
                                     ->searchable()
52
-                                    ->required(),
57
+                                    ->required()
58
+                                    ->live()
59
+                                    ->afterStateUpdated(function (Forms\Set $set, Forms\Get $get, $state) {
60
+                                        if (! $state) {
61
+                                            return;
62
+                                        }
63
+
64
+                                        $currencyCode = Vendor::find($state)?->currency_code;
65
+
66
+                                        if ($currencyCode) {
67
+                                            $set('currency_code', $currencyCode);
68
+                                        }
69
+                                    }),
70
+                                CreateCurrencySelect::make('currency_code'),
53 71
                             ]),
54 72
                             Forms\Components\Group::make([
55 73
                                 Forms\Components\TextInput::make('bill_number')
@@ -170,30 +188,40 @@ class BillResource extends Resource
170 188
                                         $unitPrice = max((float) ($get('unit_price') ?? 0), 0);
171 189
                                         $purchaseTaxes = $get('purchaseTaxes') ?? [];
172 190
                                         $purchaseDiscounts = $get('purchaseDiscounts') ?? [];
191
+                                        $currencyCode = $get('../../currency_code') ?? CurrencyAccessor::getDefaultCurrency();
173 192
 
174 193
                                         $subtotal = $quantity * $unitPrice;
175 194
 
176
-                                        // Calculate tax amount based on subtotal
177
-                                        $taxAmount = 0;
178
-                                        if (! empty($purchaseTaxes)) {
179
-                                            $taxRates = Adjustment::whereIn('id', $purchaseTaxes)->pluck('rate');
180
-                                            $taxAmount = collect($taxRates)->sum(fn ($rate) => $subtotal * ($rate / 100));
181
-                                        }
182
-
183
-                                        // Calculate discount amount based on subtotal
184
-                                        $discountAmount = 0;
185
-                                        if (! empty($purchaseDiscounts)) {
186
-                                            $discountRates = Adjustment::whereIn('id', $purchaseDiscounts)->pluck('rate');
187
-                                            $discountAmount = collect($discountRates)->sum(fn ($rate) => $subtotal * ($rate / 100));
188
-                                        }
195
+                                        $subtotalInCents = CurrencyConverter::convertToCents($subtotal, $currencyCode);
196
+
197
+                                        $taxAmountInCents = Adjustment::whereIn('id', $purchaseTaxes)
198
+                                            ->get()
199
+                                            ->sum(function (Adjustment $adjustment) use ($subtotalInCents) {
200
+                                                if ($adjustment->computation->isPercentage()) {
201
+                                                    return RateCalculator::calculatePercentage($subtotalInCents, $adjustment->getRawOriginal('rate'));
202
+                                                } else {
203
+                                                    return $adjustment->getRawOriginal('rate');
204
+                                                }
205
+                                            });
206
+
207
+                                        $discountAmountInCents = Adjustment::whereIn('id', $purchaseDiscounts)
208
+                                            ->get()
209
+                                            ->sum(function (Adjustment $adjustment) use ($subtotalInCents) {
210
+                                                if ($adjustment->computation->isPercentage()) {
211
+                                                    return RateCalculator::calculatePercentage($subtotalInCents, $adjustment->getRawOriginal('rate'));
212
+                                                } else {
213
+                                                    return $adjustment->getRawOriginal('rate');
214
+                                                }
215
+                                            });
189 216
 
190 217
                                         // Final total
191
-                                        $total = $subtotal + ($taxAmount - $discountAmount);
218
+                                        $totalInCents = $subtotalInCents + ($taxAmountInCents - $discountAmountInCents);
192 219
 
193
-                                        return CurrencyConverter::formatToMoney($total);
220
+                                        return CurrencyConverter::formatCentsToMoney($totalInCents, $currencyCode);
194 221
                                     }),
195 222
                             ]),
196
-                        BillTotals::make(),
223
+                        DocumentTotals::make()
224
+                            ->type(DocumentType::Bill),
197 225
                     ]),
198 226
             ]);
199 227
     }

+ 4
- 2
app/Filament/Company/Resources/Sales/InvoiceResource.php 查看文件

@@ -4,13 +4,14 @@ namespace App\Filament\Company\Resources\Sales;
4 4
 
5 5
 use App\Collections\Accounting\InvoiceCollection;
6 6
 use App\Enums\Accounting\DocumentDiscountMethod;
7
+use App\Enums\Accounting\DocumentType;
7 8
 use App\Enums\Accounting\InvoiceStatus;
8 9
 use App\Enums\Accounting\PaymentMethod;
9 10
 use App\Filament\Company\Resources\Sales\InvoiceResource\Pages;
10 11
 use App\Filament\Company\Resources\Sales\InvoiceResource\RelationManagers;
11 12
 use App\Filament\Company\Resources\Sales\InvoiceResource\Widgets;
12 13
 use App\Filament\Forms\Components\CreateCurrencySelect;
13
-use App\Filament\Forms\Components\InvoiceTotals;
14
+use App\Filament\Forms\Components\DocumentTotals;
14 15
 use App\Filament\Tables\Actions\ReplicateBulkAction;
15 16
 use App\Filament\Tables\Filters\DateRangeFilter;
16 17
 use App\Models\Accounting\Adjustment;
@@ -276,7 +277,8 @@ class InvoiceResource extends Resource
276 277
                                         return CurrencyConverter::formatCentsToMoney($totalInCents, $currencyCode);
277 278
                                     }),
278 279
                             ]),
279
-                        InvoiceTotals::make(),
280
+                        DocumentTotals::make()
281
+                            ->type(DocumentType::Invoice),
280 282
                         Forms\Components\Textarea::make('terms')
281 283
                             ->columnSpanFull(),
282 284
                     ]),

app/Filament/Forms/Components/BillTotals.php → app/Filament/Forms/Components/DocumentTotals.php 查看文件

@@ -3,14 +3,17 @@
3 3
 namespace App\Filament\Forms\Components;
4 4
 
5 5
 use App\Enums\Accounting\AdjustmentComputation;
6
+use App\Enums\Accounting\DocumentType;
6 7
 use Filament\Forms\Components\Grid;
7 8
 use Filament\Forms\Components\Select;
8 9
 use Filament\Forms\Components\TextInput;
9 10
 use Filament\Forms\Get;
10 11
 
11
-class BillTotals extends Grid
12
+class DocumentTotals extends Grid
12 13
 {
13
-    protected string $view = 'filament.forms.components.bill-totals';
14
+    protected string $view = 'filament.forms.components.document-totals';
15
+
16
+    protected DocumentType $documentType = DocumentType::Invoice;
14 17
 
15 18
     protected function setUp(): void
16 19
     {
@@ -34,4 +37,20 @@ class BillTotals extends Grid
34 37
                 ->live(),
35 38
         ]);
36 39
     }
40
+
41
+    public function type(DocumentType | string $type): static
42
+    {
43
+        if (is_string($type)) {
44
+            $type = DocumentType::from($type);
45
+        }
46
+
47
+        $this->documentType = $type;
48
+
49
+        return $this;
50
+    }
51
+
52
+    public function getType(): DocumentType
53
+    {
54
+        return $this->documentType;
55
+    }
37 56
 }

+ 0
- 37
app/Filament/Forms/Components/InvoiceTotals.php 查看文件

@@ -1,37 +0,0 @@
1
-<?php
2
-
3
-namespace App\Filament\Forms\Components;
4
-
5
-use App\Enums\Accounting\AdjustmentComputation;
6
-use Filament\Forms\Components\Grid;
7
-use Filament\Forms\Components\Select;
8
-use Filament\Forms\Components\TextInput;
9
-use Filament\Forms\Get;
10
-
11
-class InvoiceTotals extends Grid
12
-{
13
-    protected string $view = 'filament.forms.components.invoice-totals';
14
-
15
-    protected function setUp(): void
16
-    {
17
-        parent::setUp();
18
-
19
-        $this->schema([
20
-            TextInput::make('discount_rate')
21
-                ->label('Discount Rate')
22
-                ->hiddenLabel()
23
-                ->live()
24
-                ->rate(computation: static fn (Get $get) => $get('discount_computation'), showAffix: false),
25
-            Select::make('discount_computation')
26
-                ->label('Discount Computation')
27
-                ->hiddenLabel()
28
-                ->options([
29
-                    'percentage' => '%',
30
-                    'fixed' => '$',
31
-                ])
32
-                ->default(AdjustmentComputation::Percentage)
33
-                ->selectablePlaceholder(false)
34
-                ->live(),
35
-        ]);
36
-    }
37
-}

+ 0
- 78
app/View/Models/BillTotalViewModel.php 查看文件

@@ -1,78 +0,0 @@
1
-<?php
2
-
3
-namespace App\View\Models;
4
-
5
-use App\Enums\Accounting\AdjustmentComputation;
6
-use App\Enums\Accounting\DocumentDiscountMethod;
7
-use App\Models\Accounting\Adjustment;
8
-use App\Models\Accounting\Bill;
9
-use App\Utilities\Currency\CurrencyConverter;
10
-
11
-class BillTotalViewModel
12
-{
13
-    public function __construct(
14
-        public ?Bill $bill,
15
-        public ?array $data = null
16
-    ) {}
17
-
18
-    public function buildViewData(): array
19
-    {
20
-        $lineItems = collect($this->data['lineItems'] ?? []);
21
-
22
-        $subtotal = $lineItems->sum(static function ($item) {
23
-            $quantity = max((float) ($item['quantity'] ?? 0), 0);
24
-            $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
25
-
26
-            return $quantity * $unitPrice;
27
-        });
28
-
29
-        $taxTotal = $lineItems->reduce(function ($carry, $item) {
30
-            $quantity = max((float) ($item['quantity'] ?? 0), 0);
31
-            $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
32
-            $purchaseTaxes = $item['purchaseTaxes'] ?? [];
33
-            $lineTotal = $quantity * $unitPrice;
34
-
35
-            $taxAmount = Adjustment::whereIn('id', $purchaseTaxes)
36
-                ->pluck('rate')
37
-                ->sum(fn ($rate) => $lineTotal * ($rate / 100));
38
-
39
-            return $carry + $taxAmount;
40
-        }, 0);
41
-
42
-        // Calculate discount based on method
43
-        $discountMethod = DocumentDiscountMethod::parse($this->data['discount_method']) ?? DocumentDiscountMethod::PerLineItem;
44
-
45
-        if ($discountMethod->isPerLineItem()) {
46
-            $discountTotal = $lineItems->reduce(function ($carry, $item) {
47
-                $quantity = max((float) ($item['quantity'] ?? 0), 0);
48
-                $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
49
-                $purchaseDiscounts = $item['purchaseDiscounts'] ?? [];
50
-                $lineTotal = $quantity * $unitPrice;
51
-
52
-                $discountAmount = Adjustment::whereIn('id', $purchaseDiscounts)
53
-                    ->pluck('rate')
54
-                    ->sum(fn ($rate) => $lineTotal * ($rate / 100));
55
-
56
-                return $carry + $discountAmount;
57
-            }, 0);
58
-        } else {
59
-            $discountComputation = AdjustmentComputation::parse($this->data['discount_computation']) ?? AdjustmentComputation::Percentage;
60
-            $discountRate = (float) ($this->data['discount_rate'] ?? 0);
61
-
62
-            if ($discountComputation->isPercentage()) {
63
-                $discountTotal = $subtotal * ($discountRate / 100);
64
-            } else {
65
-                $discountTotal = $discountRate;
66
-            }
67
-        }
68
-
69
-        $grandTotal = $subtotal + ($taxTotal - $discountTotal);
70
-
71
-        return [
72
-            'subtotal' => CurrencyConverter::formatToMoney($subtotal),
73
-            'taxTotal' => CurrencyConverter::formatToMoney($taxTotal),
74
-            'discountTotal' => CurrencyConverter::formatToMoney($discountTotal),
75
-            'grandTotal' => CurrencyConverter::formatToMoney($grandTotal),
76
-        ];
77
-    }
78
-}

+ 122
- 0
app/View/Models/DocumentTotalViewModel.php 查看文件

@@ -0,0 +1,122 @@
1
+<?php
2
+
3
+namespace App\View\Models;
4
+
5
+use App\Enums\Accounting\AdjustmentComputation;
6
+use App\Enums\Accounting\DocumentDiscountMethod;
7
+use App\Enums\Accounting\DocumentType;
8
+use App\Models\Accounting\Adjustment;
9
+use App\Utilities\Currency\CurrencyAccessor;
10
+use App\Utilities\Currency\CurrencyConverter;
11
+use App\Utilities\RateCalculator;
12
+use Illuminate\Support\Number;
13
+
14
+class DocumentTotalViewModel
15
+{
16
+    public function __construct(
17
+        public ?array $data,
18
+        public DocumentType $documentType = DocumentType::Invoice,
19
+    ) {}
20
+
21
+    public function buildViewData(): array
22
+    {
23
+        $currencyCode = $this->data['currency_code'] ?? CurrencyAccessor::getDefaultCurrency();
24
+        $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
25
+
26
+        $lineItems = collect($this->data['lineItems'] ?? []);
27
+
28
+        $subtotalInCents = $lineItems->sum(fn ($item) => $this->calculateLineSubtotalInCents($item, $currencyCode));
29
+
30
+        $taxTotalInCents = $this->calculateAdjustmentsTotalInCents($lineItems, $this->documentType->getTaxKey(), $currencyCode);
31
+        $discountTotalInCents = $this->calculateDiscountTotalInCents($lineItems, $subtotalInCents, $currencyCode);
32
+
33
+        $grandTotalInCents = $subtotalInCents + ($taxTotalInCents - $discountTotalInCents);
34
+
35
+        $conversionMessage = $this->buildConversionMessage($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
36
+
37
+        return [
38
+            'subtotal' => CurrencyConverter::formatCentsToMoney($subtotalInCents, $currencyCode),
39
+            'taxTotal' => CurrencyConverter::formatCentsToMoney($taxTotalInCents, $currencyCode),
40
+            'discountTotal' => CurrencyConverter::formatCentsToMoney($discountTotalInCents, $currencyCode),
41
+            'grandTotal' => CurrencyConverter::formatCentsToMoney($grandTotalInCents, $currencyCode),
42
+            'conversionMessage' => $conversionMessage,
43
+        ];
44
+    }
45
+
46
+    private function calculateLineSubtotalInCents(array $item, string $currencyCode): int
47
+    {
48
+        $quantity = max((float) ($item['quantity'] ?? 0), 0);
49
+        $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
50
+
51
+        $subtotal = $quantity * $unitPrice;
52
+
53
+        return CurrencyConverter::convertToCents($subtotal, $currencyCode);
54
+    }
55
+
56
+    private function calculateAdjustmentsTotalInCents($lineItems, string $key, string $currencyCode): int
57
+    {
58
+        return $lineItems->reduce(function ($carry, $item) use ($key, $currencyCode) {
59
+            $quantity = max((float) ($item['quantity'] ?? 0), 0);
60
+            $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
61
+            $adjustmentIds = $item[$key] ?? [];
62
+            $lineTotal = $quantity * $unitPrice;
63
+
64
+            $lineTotalInCents = CurrencyConverter::convertToCents($lineTotal, $currencyCode);
65
+
66
+            $adjustmentTotal = Adjustment::whereIn('id', $adjustmentIds)
67
+                ->get()
68
+                ->sum(function (Adjustment $adjustment) use ($lineTotalInCents) {
69
+                    if ($adjustment->computation->isPercentage()) {
70
+                        return RateCalculator::calculatePercentage($lineTotalInCents, $adjustment->getRawOriginal('rate'));
71
+                    } else {
72
+                        return $adjustment->getRawOriginal('rate');
73
+                    }
74
+                });
75
+
76
+            return $carry + $adjustmentTotal;
77
+        }, 0);
78
+    }
79
+
80
+    private function calculateDiscountTotalInCents($lineItems, int $subtotalInCents, string $currencyCode): int
81
+    {
82
+        $discountMethod = DocumentDiscountMethod::parse($this->data['discount_method']) ?? DocumentDiscountMethod::PerLineItem;
83
+
84
+        if ($discountMethod->isPerLineItem()) {
85
+            return $this->calculateAdjustmentsTotalInCents($lineItems, $this->documentType->getDiscountKey(), $currencyCode);
86
+        }
87
+
88
+        $discountComputation = AdjustmentComputation::parse($this->data['discount_computation']) ?? AdjustmentComputation::Percentage;
89
+        $discountRate = $this->data['discount_rate'] ?? '0';
90
+
91
+        if ($discountComputation->isPercentage()) {
92
+            $scaledDiscountRate = RateCalculator::parseLocalizedRate($discountRate);
93
+
94
+            return RateCalculator::calculatePercentage($subtotalInCents, $scaledDiscountRate);
95
+        }
96
+
97
+        return CurrencyConverter::convertToCents($discountRate, $currencyCode);
98
+    }
99
+
100
+    private function buildConversionMessage(int $grandTotalInCents, string $currencyCode, string $defaultCurrencyCode): ?string
101
+    {
102
+        if ($currencyCode === $defaultCurrencyCode) {
103
+            return null;
104
+        }
105
+
106
+        $rate = currency($currencyCode)->getRate();
107
+        $indirectRate = 1 / $rate;
108
+
109
+        $convertedTotalInCents = CurrencyConverter::convertBalance($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
110
+
111
+        $formattedRate = Number::format($indirectRate, maxPrecision: 10);
112
+
113
+        return sprintf(
114
+            'Currency conversion: %s (%s) at an exchange rate of 1 %s = %s %s',
115
+            CurrencyConverter::formatCentsToMoney($convertedTotalInCents, $defaultCurrencyCode),
116
+            $defaultCurrencyCode,
117
+            $currencyCode,
118
+            $formattedRate,
119
+            $defaultCurrencyCode
120
+        );
121
+    }
122
+}

+ 0
- 116
app/View/Models/InvoiceTotalViewModel.php 查看文件

@@ -1,116 +0,0 @@
1
-<?php
2
-
3
-namespace App\View\Models;
4
-
5
-use App\Enums\Accounting\AdjustmentComputation;
6
-use App\Enums\Accounting\DocumentDiscountMethod;
7
-use App\Models\Accounting\Adjustment;
8
-use App\Models\Accounting\Invoice;
9
-use App\Utilities\Currency\CurrencyAccessor;
10
-use App\Utilities\Currency\CurrencyConverter;
11
-use App\Utilities\RateCalculator;
12
-
13
-class InvoiceTotalViewModel
14
-{
15
-    public function __construct(
16
-        public ?Invoice $invoice,
17
-        public ?array $data = null
18
-    ) {}
19
-
20
-    public function buildViewData(): array
21
-    {
22
-        $currencyCode = $this->data['currency_code'] ?? CurrencyAccessor::getDefaultCurrency();
23
-        $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
24
-
25
-        $lineItems = collect($this->data['lineItems'] ?? []);
26
-
27
-        $subtotalInCents = $lineItems->sum(static function ($item) use ($currencyCode) {
28
-            $quantity = max((float) ($item['quantity'] ?? 0), 0);
29
-            $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
30
-
31
-            $subtotal = $quantity * $unitPrice;
32
-
33
-            return CurrencyConverter::convertToCents($subtotal, $currencyCode);
34
-        });
35
-
36
-        $taxTotalInCents = $lineItems->reduce(function ($carry, $item) use ($currencyCode) {
37
-            $quantity = max((float) ($item['quantity'] ?? 0), 0);
38
-            $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
39
-            $salesTaxes = $item['salesTaxes'] ?? [];
40
-            $lineTotal = $quantity * $unitPrice;
41
-
42
-            $lineTotalInCents = CurrencyConverter::convertToCents($lineTotal, $currencyCode);
43
-
44
-            $taxAmountInCents = Adjustment::whereIn('id', $salesTaxes)
45
-                ->get()
46
-                ->sum(function (Adjustment $adjustment) use ($lineTotalInCents) {
47
-                    if ($adjustment->computation->isPercentage()) {
48
-                        return RateCalculator::calculatePercentage($lineTotalInCents, $adjustment->getRawOriginal('rate'));
49
-                    } else {
50
-                        return $adjustment->getRawOriginal('rate');
51
-                    }
52
-                });
53
-
54
-            return $carry + $taxAmountInCents;
55
-        }, 0);
56
-
57
-        // Calculate discount based on method
58
-        $discountMethod = DocumentDiscountMethod::parse($this->data['discount_method']) ?? DocumentDiscountMethod::PerLineItem;
59
-
60
-        if ($discountMethod->isPerLineItem()) {
61
-            $discountTotalInCents = $lineItems->reduce(function ($carry, $item) use ($currencyCode) {
62
-                $quantity = max((float) ($item['quantity'] ?? 0), 0);
63
-                $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
64
-                $salesDiscounts = $item['salesDiscounts'] ?? [];
65
-                $lineTotalInCents = CurrencyConverter::convertToCents($quantity * $unitPrice, $currencyCode);
66
-
67
-                $discountAmountInCents = Adjustment::whereIn('id', $salesDiscounts)
68
-                    ->get()
69
-                    ->sum(function (Adjustment $adjustment) use ($lineTotalInCents) {
70
-                        if ($adjustment->computation->isPercentage()) {
71
-                            return RateCalculator::calculatePercentage($lineTotalInCents, $adjustment->getRawOriginal('rate'));
72
-                        } else {
73
-                            return $adjustment->getRawOriginal('rate');
74
-                        }
75
-                    });
76
-
77
-                return $carry + $discountAmountInCents;
78
-            }, 0);
79
-        } else {
80
-            $discountComputation = AdjustmentComputation::parse($this->data['discount_computation']) ?? AdjustmentComputation::Percentage;
81
-            $discountRate = $this->data['discount_rate'] ?? '0';
82
-
83
-            if ($discountComputation->isPercentage()) {
84
-                $scaledDiscountRate = RateCalculator::parseLocalizedRate($discountRate);
85
-                $discountTotalInCents = RateCalculator::calculatePercentage($subtotalInCents, $scaledDiscountRate);
86
-            } else {
87
-                $discountTotalInCents = CurrencyConverter::convertToCents($discountRate, $currencyCode);
88
-            }
89
-        }
90
-
91
-        $grandTotalInCents = $subtotalInCents + ($taxTotalInCents - $discountTotalInCents);
92
-
93
-        $conversionMessage = null;
94
-
95
-        if ($currencyCode !== $defaultCurrencyCode) {
96
-            $rate = currency($currencyCode)->getRate();
97
-
98
-            $convertedTotalInCents = CurrencyConverter::convertBalance($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
99
-
100
-            $conversionMessage = sprintf(
101
-                'Currency conversion: %s (%s) at an exchange rate of %s',
102
-                CurrencyConverter::formatCentsToMoney($convertedTotalInCents, $defaultCurrencyCode),
103
-                $defaultCurrencyCode,
104
-                $rate
105
-            );
106
-        }
107
-
108
-        return [
109
-            'subtotal' => CurrencyConverter::formatCentsToMoney($subtotalInCents, $currencyCode),
110
-            'taxTotal' => CurrencyConverter::formatCentsToMoney($taxTotalInCents, $currencyCode),
111
-            'discountTotal' => CurrencyConverter::formatCentsToMoney($discountTotalInCents, $currencyCode),
112
-            'grandTotal' => CurrencyConverter::formatCentsToMoney($grandTotalInCents, $currencyCode),
113
-            'conversionMessage' => $conversionMessage,
114
-        ];
115
-    }
116
-}

+ 1
- 1
composer.json 查看文件

@@ -17,7 +17,7 @@
17 17
         "andrewdwallo/transmatic": "^1.1",
18 18
         "awcodes/filament-table-repeater": "^3.0",
19 19
         "barryvdh/laravel-snappy": "^1.0",
20
-        "filament/filament": "v3.2.129",
20
+        "filament/filament": "^3.2",
21 21
         "guava/filament-clusters": "^1.1",
22 22
         "guzzlehttp/guzzle": "^7.8",
23 23
         "jaocero/radio-deck": "^1.2",

+ 85
- 85
composer.lock 查看文件

@@ -4,7 +4,7 @@
4 4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 5
         "This file is @generated automatically"
6 6
     ],
7
-    "content-hash": "7301f370a98e2573adf4e6b4e7ab4a8e",
7
+    "content-hash": "a04479d57fe01a2694ad92a8901363ea",
8 8
     "packages": [
9 9
         {
10 10
             "name": "akaunting/laravel-money",
@@ -497,16 +497,16 @@
497 497
         },
498 498
         {
499 499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.334.6",
500
+            "version": "3.336.0",
501 501
             "source": {
502 502
                 "type": "git",
503 503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "2b0be3aded849d3b7bb0b53ea3295c7cecdeeee7"
504
+                "reference": "5a62003bf183e32da038056a4b9077c27224e034"
505 505
             },
506 506
             "dist": {
507 507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2b0be3aded849d3b7bb0b53ea3295c7cecdeeee7",
509
-                "reference": "2b0be3aded849d3b7bb0b53ea3295c7cecdeeee7",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/5a62003bf183e32da038056a4b9077c27224e034",
509
+                "reference": "5a62003bf183e32da038056a4b9077c27224e034",
510 510
                 "shasum": ""
511 511
             },
512 512
             "require": {
@@ -589,9 +589,9 @@
589 589
             "support": {
590 590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591 591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.334.6"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.336.0"
593 593
             },
594
-            "time": "2024-12-13T19:18:29+00:00"
594
+            "time": "2024-12-18T19:04:32+00:00"
595 595
         },
596 596
         {
597 597
             "name": "aws/aws-sdk-php-laravel",
@@ -1662,16 +1662,16 @@
1662 1662
         },
1663 1663
         {
1664 1664
             "name": "filament/actions",
1665
-            "version": "v3.2.129",
1665
+            "version": "v3.2.131",
1666 1666
             "source": {
1667 1667
                 "type": "git",
1668 1668
                 "url": "https://github.com/filamentphp/actions.git",
1669
-                "reference": "1ee8b0a890b53e8b0b341134d3ba9bdaeee294d3"
1669
+                "reference": "8d9ceaf392eeff55fd335f5169d14f84af8c325e"
1670 1670
             },
1671 1671
             "dist": {
1672 1672
                 "type": "zip",
1673
-                "url": "https://api.github.com/repos/filamentphp/actions/zipball/1ee8b0a890b53e8b0b341134d3ba9bdaeee294d3",
1674
-                "reference": "1ee8b0a890b53e8b0b341134d3ba9bdaeee294d3",
1673
+                "url": "https://api.github.com/repos/filamentphp/actions/zipball/8d9ceaf392eeff55fd335f5169d14f84af8c325e",
1674
+                "reference": "8d9ceaf392eeff55fd335f5169d14f84af8c325e",
1675 1675
                 "shasum": ""
1676 1676
             },
1677 1677
             "require": {
@@ -1711,20 +1711,20 @@
1711 1711
                 "issues": "https://github.com/filamentphp/filament/issues",
1712 1712
                 "source": "https://github.com/filamentphp/filament"
1713 1713
             },
1714
-            "time": "2024-12-05T08:56:37+00:00"
1714
+            "time": "2024-12-17T13:03:16+00:00"
1715 1715
         },
1716 1716
         {
1717 1717
             "name": "filament/filament",
1718
-            "version": "v3.2.129",
1718
+            "version": "v3.2.131",
1719 1719
             "source": {
1720 1720
                 "type": "git",
1721 1721
                 "url": "https://github.com/filamentphp/panels.git",
1722
-                "reference": "9a327a54dec24e0b12c437ef799828f492cb882a"
1722
+                "reference": "21febddcc6720b250b41386805a8dbd1deef2c56"
1723 1723
             },
1724 1724
             "dist": {
1725 1725
                 "type": "zip",
1726
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/9a327a54dec24e0b12c437ef799828f492cb882a",
1727
-                "reference": "9a327a54dec24e0b12c437ef799828f492cb882a",
1726
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/21febddcc6720b250b41386805a8dbd1deef2c56",
1727
+                "reference": "21febddcc6720b250b41386805a8dbd1deef2c56",
1728 1728
                 "shasum": ""
1729 1729
             },
1730 1730
             "require": {
@@ -1776,20 +1776,20 @@
1776 1776
                 "issues": "https://github.com/filamentphp/filament/issues",
1777 1777
                 "source": "https://github.com/filamentphp/filament"
1778 1778
             },
1779
-            "time": "2024-12-11T09:05:49+00:00"
1779
+            "time": "2024-12-17T13:03:11+00:00"
1780 1780
         },
1781 1781
         {
1782 1782
             "name": "filament/forms",
1783
-            "version": "v3.2.129",
1783
+            "version": "v3.2.131",
1784 1784
             "source": {
1785 1785
                 "type": "git",
1786 1786
                 "url": "https://github.com/filamentphp/forms.git",
1787
-                "reference": "e6133bdc03de05dfe23eac386b49e51093338883"
1787
+                "reference": "72429b0df9c3d123273dd51ba62b764e2114697c"
1788 1788
             },
1789 1789
             "dist": {
1790 1790
                 "type": "zip",
1791
-                "url": "https://api.github.com/repos/filamentphp/forms/zipball/e6133bdc03de05dfe23eac386b49e51093338883",
1792
-                "reference": "e6133bdc03de05dfe23eac386b49e51093338883",
1791
+                "url": "https://api.github.com/repos/filamentphp/forms/zipball/72429b0df9c3d123273dd51ba62b764e2114697c",
1792
+                "reference": "72429b0df9c3d123273dd51ba62b764e2114697c",
1793 1793
                 "shasum": ""
1794 1794
             },
1795 1795
             "require": {
@@ -1832,20 +1832,20 @@
1832 1832
                 "issues": "https://github.com/filamentphp/filament/issues",
1833 1833
                 "source": "https://github.com/filamentphp/filament"
1834 1834
             },
1835
-            "time": "2024-12-11T09:05:38+00:00"
1835
+            "time": "2024-12-17T13:03:11+00:00"
1836 1836
         },
1837 1837
         {
1838 1838
             "name": "filament/infolists",
1839
-            "version": "v3.2.129",
1839
+            "version": "v3.2.131",
1840 1840
             "source": {
1841 1841
                 "type": "git",
1842 1842
                 "url": "https://github.com/filamentphp/infolists.git",
1843
-                "reference": "0db994330e7fe21a9684256ea1fc34fee916a8d6"
1843
+                "reference": "15c200a3172b88a6247ff4b7230f69982d848194"
1844 1844
             },
1845 1845
             "dist": {
1846 1846
                 "type": "zip",
1847
-                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/0db994330e7fe21a9684256ea1fc34fee916a8d6",
1848
-                "reference": "0db994330e7fe21a9684256ea1fc34fee916a8d6",
1847
+                "url": "https://api.github.com/repos/filamentphp/infolists/zipball/15c200a3172b88a6247ff4b7230f69982d848194",
1848
+                "reference": "15c200a3172b88a6247ff4b7230f69982d848194",
1849 1849
                 "shasum": ""
1850 1850
             },
1851 1851
             "require": {
@@ -1883,11 +1883,11 @@
1883 1883
                 "issues": "https://github.com/filamentphp/filament/issues",
1884 1884
                 "source": "https://github.com/filamentphp/filament"
1885 1885
             },
1886
-            "time": "2024-12-11T09:05:38+00:00"
1886
+            "time": "2024-12-17T13:03:14+00:00"
1887 1887
         },
1888 1888
         {
1889 1889
             "name": "filament/notifications",
1890
-            "version": "v3.2.129",
1890
+            "version": "v3.2.131",
1891 1891
             "source": {
1892 1892
                 "type": "git",
1893 1893
                 "url": "https://github.com/filamentphp/notifications.git",
@@ -1939,16 +1939,16 @@
1939 1939
         },
1940 1940
         {
1941 1941
             "name": "filament/support",
1942
-            "version": "v3.2.129",
1942
+            "version": "v3.2.131",
1943 1943
             "source": {
1944 1944
                 "type": "git",
1945 1945
                 "url": "https://github.com/filamentphp/support.git",
1946
-                "reference": "e8aed9684d5c58ff7dde9517c7f1af44d575d871"
1946
+                "reference": "ddc16d8da50d73f7300671b70c9dcb942d845d9d"
1947 1947
             },
1948 1948
             "dist": {
1949 1949
                 "type": "zip",
1950
-                "url": "https://api.github.com/repos/filamentphp/support/zipball/e8aed9684d5c58ff7dde9517c7f1af44d575d871",
1951
-                "reference": "e8aed9684d5c58ff7dde9517c7f1af44d575d871",
1950
+                "url": "https://api.github.com/repos/filamentphp/support/zipball/ddc16d8da50d73f7300671b70c9dcb942d845d9d",
1951
+                "reference": "ddc16d8da50d73f7300671b70c9dcb942d845d9d",
1952 1952
                 "shasum": ""
1953 1953
             },
1954 1954
             "require": {
@@ -1994,20 +1994,20 @@
1994 1994
                 "issues": "https://github.com/filamentphp/filament/issues",
1995 1995
                 "source": "https://github.com/filamentphp/filament"
1996 1996
             },
1997
-            "time": "2024-12-11T09:05:54+00:00"
1997
+            "time": "2024-12-17T13:03:15+00:00"
1998 1998
         },
1999 1999
         {
2000 2000
             "name": "filament/tables",
2001
-            "version": "v3.2.129",
2001
+            "version": "v3.2.131",
2002 2002
             "source": {
2003 2003
                 "type": "git",
2004 2004
                 "url": "https://github.com/filamentphp/tables.git",
2005
-                "reference": "acdec73ae82961654a52a22ed9f53207cfee2ef8"
2005
+                "reference": "224aea12a4a4cfcd158b53df94cdd190f8226cac"
2006 2006
             },
2007 2007
             "dist": {
2008 2008
                 "type": "zip",
2009
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/acdec73ae82961654a52a22ed9f53207cfee2ef8",
2010
-                "reference": "acdec73ae82961654a52a22ed9f53207cfee2ef8",
2009
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/224aea12a4a4cfcd158b53df94cdd190f8226cac",
2010
+                "reference": "224aea12a4a4cfcd158b53df94cdd190f8226cac",
2011 2011
                 "shasum": ""
2012 2012
             },
2013 2013
             "require": {
@@ -2046,20 +2046,20 @@
2046 2046
                 "issues": "https://github.com/filamentphp/filament/issues",
2047 2047
                 "source": "https://github.com/filamentphp/filament"
2048 2048
             },
2049
-            "time": "2024-12-11T09:05:54+00:00"
2049
+            "time": "2024-12-17T13:03:09+00:00"
2050 2050
         },
2051 2051
         {
2052 2052
             "name": "filament/widgets",
2053
-            "version": "v3.2.129",
2053
+            "version": "v3.2.131",
2054 2054
             "source": {
2055 2055
                 "type": "git",
2056 2056
                 "url": "https://github.com/filamentphp/widgets.git",
2057
-                "reference": "6de1c84d71168fd1c6a5b1ae1e1b4ec5ee4b6f55"
2057
+                "reference": "869a419fe42e2cf1b9461f2d1e702e2fcad030ae"
2058 2058
             },
2059 2059
             "dist": {
2060 2060
                 "type": "zip",
2061
-                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/6de1c84d71168fd1c6a5b1ae1e1b4ec5ee4b6f55",
2062
-                "reference": "6de1c84d71168fd1c6a5b1ae1e1b4ec5ee4b6f55",
2061
+                "url": "https://api.github.com/repos/filamentphp/widgets/zipball/869a419fe42e2cf1b9461f2d1e702e2fcad030ae",
2062
+                "reference": "869a419fe42e2cf1b9461f2d1e702e2fcad030ae",
2063 2063
                 "shasum": ""
2064 2064
             },
2065 2065
             "require": {
@@ -2090,7 +2090,7 @@
2090 2090
                 "issues": "https://github.com/filamentphp/filament/issues",
2091 2091
                 "source": "https://github.com/filamentphp/filament"
2092 2092
             },
2093
-            "time": "2024-11-27T16:52:29+00:00"
2093
+            "time": "2024-12-17T13:03:07+00:00"
2094 2094
         },
2095 2095
         {
2096 2096
             "name": "firebase/php-jwt",
@@ -2980,16 +2980,16 @@
2980 2980
         },
2981 2981
         {
2982 2982
             "name": "laravel/framework",
2983
-            "version": "v11.35.1",
2983
+            "version": "v11.36.1",
2984 2984
             "source": {
2985 2985
                 "type": "git",
2986 2986
                 "url": "https://github.com/laravel/framework.git",
2987
-                "reference": "dcfa130ede1a6fa4343dc113410963e791ad34fb"
2987
+                "reference": "df06f5163f4550641fdf349ebc04916a61135a64"
2988 2988
             },
2989 2989
             "dist": {
2990 2990
                 "type": "zip",
2991
-                "url": "https://api.github.com/repos/laravel/framework/zipball/dcfa130ede1a6fa4343dc113410963e791ad34fb",
2992
-                "reference": "dcfa130ede1a6fa4343dc113410963e791ad34fb",
2991
+                "url": "https://api.github.com/repos/laravel/framework/zipball/df06f5163f4550641fdf349ebc04916a61135a64",
2992
+                "reference": "df06f5163f4550641fdf349ebc04916a61135a64",
2993 2993
                 "shasum": ""
2994 2994
             },
2995 2995
             "require": {
@@ -3010,7 +3010,7 @@
3010 3010
                 "guzzlehttp/uri-template": "^1.0",
3011 3011
                 "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
3012 3012
                 "laravel/serializable-closure": "^1.3|^2.0",
3013
-                "league/commonmark": "^2.2.1",
3013
+                "league/commonmark": "^2.6",
3014 3014
                 "league/flysystem": "^3.25.1",
3015 3015
                 "league/flysystem-local": "^3.25.1",
3016 3016
                 "league/uri": "^7.5.1",
@@ -3025,7 +3025,7 @@
3025 3025
                 "symfony/console": "^7.0.3",
3026 3026
                 "symfony/error-handler": "^7.0.3",
3027 3027
                 "symfony/finder": "^7.0.3",
3028
-                "symfony/http-foundation": "^7.0.3",
3028
+                "symfony/http-foundation": "^7.2.0",
3029 3029
                 "symfony/http-kernel": "^7.0.3",
3030 3030
                 "symfony/mailer": "^7.0.3",
3031 3031
                 "symfony/mime": "^7.0.3",
@@ -3191,7 +3191,7 @@
3191 3191
                 "issues": "https://github.com/laravel/framework/issues",
3192 3192
                 "source": "https://github.com/laravel/framework"
3193 3193
             },
3194
-            "time": "2024-12-12T18:25:58+00:00"
3194
+            "time": "2024-12-17T22:32:08+00:00"
3195 3195
         },
3196 3196
         {
3197 3197
             "name": "laravel/prompts",
@@ -3254,16 +3254,16 @@
3254 3254
         },
3255 3255
         {
3256 3256
             "name": "laravel/sanctum",
3257
-            "version": "v4.0.6",
3257
+            "version": "v4.0.7",
3258 3258
             "source": {
3259 3259
                 "type": "git",
3260 3260
                 "url": "https://github.com/laravel/sanctum.git",
3261
-                "reference": "9e069e36d90b1e1f41886efa0fe9800a6b354694"
3261
+                "reference": "698064236a46df016e64a7eb059b1414e0b281df"
3262 3262
             },
3263 3263
             "dist": {
3264 3264
                 "type": "zip",
3265
-                "url": "https://api.github.com/repos/laravel/sanctum/zipball/9e069e36d90b1e1f41886efa0fe9800a6b354694",
3266
-                "reference": "9e069e36d90b1e1f41886efa0fe9800a6b354694",
3265
+                "url": "https://api.github.com/repos/laravel/sanctum/zipball/698064236a46df016e64a7eb059b1414e0b281df",
3266
+                "reference": "698064236a46df016e64a7eb059b1414e0b281df",
3267 3267
                 "shasum": ""
3268 3268
             },
3269 3269
             "require": {
@@ -3314,20 +3314,20 @@
3314 3314
                 "issues": "https://github.com/laravel/sanctum/issues",
3315 3315
                 "source": "https://github.com/laravel/sanctum"
3316 3316
             },
3317
-            "time": "2024-11-26T21:18:33+00:00"
3317
+            "time": "2024-12-11T16:40:21+00:00"
3318 3318
         },
3319 3319
         {
3320 3320
             "name": "laravel/serializable-closure",
3321
-            "version": "v2.0.0",
3321
+            "version": "v2.0.1",
3322 3322
             "source": {
3323 3323
                 "type": "git",
3324 3324
                 "url": "https://github.com/laravel/serializable-closure.git",
3325
-                "reference": "0d8d3d8086984996df86596a86dea60398093a81"
3325
+                "reference": "613b2d4998f85564d40497e05e89cb6d9bd1cbe8"
3326 3326
             },
3327 3327
             "dist": {
3328 3328
                 "type": "zip",
3329
-                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/0d8d3d8086984996df86596a86dea60398093a81",
3330
-                "reference": "0d8d3d8086984996df86596a86dea60398093a81",
3329
+                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/613b2d4998f85564d40497e05e89cb6d9bd1cbe8",
3330
+                "reference": "613b2d4998f85564d40497e05e89cb6d9bd1cbe8",
3331 3331
                 "shasum": ""
3332 3332
             },
3333 3333
             "require": {
@@ -3375,20 +3375,20 @@
3375 3375
                 "issues": "https://github.com/laravel/serializable-closure/issues",
3376 3376
                 "source": "https://github.com/laravel/serializable-closure"
3377 3377
             },
3378
-            "time": "2024-11-19T01:38:44+00:00"
3378
+            "time": "2024-12-16T15:26:28+00:00"
3379 3379
         },
3380 3380
         {
3381 3381
             "name": "laravel/socialite",
3382
-            "version": "v5.16.0",
3382
+            "version": "v5.16.1",
3383 3383
             "source": {
3384 3384
                 "type": "git",
3385 3385
                 "url": "https://github.com/laravel/socialite.git",
3386
-                "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf"
3386
+                "reference": "4e5be83c0b3ecf81b2ffa47092e917d1f79dce71"
3387 3387
             },
3388 3388
             "dist": {
3389 3389
                 "type": "zip",
3390
-                "url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
3391
-                "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
3390
+                "url": "https://api.github.com/repos/laravel/socialite/zipball/4e5be83c0b3ecf81b2ffa47092e917d1f79dce71",
3391
+                "reference": "4e5be83c0b3ecf81b2ffa47092e917d1f79dce71",
3392 3392
                 "shasum": ""
3393 3393
             },
3394 3394
             "require": {
@@ -3398,7 +3398,7 @@
3398 3398
                 "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3399 3399
                 "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3400 3400
                 "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3401
-                "league/oauth1-client": "^1.10.1",
3401
+                "league/oauth1-client": "^1.11",
3402 3402
                 "php": "^7.2|^8.0",
3403 3403
                 "phpseclib/phpseclib": "^3.0"
3404 3404
             },
@@ -3447,7 +3447,7 @@
3447 3447
                 "issues": "https://github.com/laravel/socialite/issues",
3448 3448
                 "source": "https://github.com/laravel/socialite"
3449 3449
             },
3450
-            "time": "2024-09-03T09:46:57+00:00"
3450
+            "time": "2024-12-11T16:43:51+00:00"
3451 3451
         },
3452 3452
         {
3453 3453
             "name": "laravel/tinker",
@@ -3706,16 +3706,16 @@
3706 3706
         },
3707 3707
         {
3708 3708
             "name": "league/csv",
3709
-            "version": "9.20.0",
3709
+            "version": "9.20.1",
3710 3710
             "source": {
3711 3711
                 "type": "git",
3712 3712
                 "url": "https://github.com/thephpleague/csv.git",
3713
-                "reference": "553579df208641ada6ffb450b3a151e2fcfa4f31"
3713
+                "reference": "491d1e79e973a7370c7571dc0fe4a7241f4936ee"
3714 3714
             },
3715 3715
             "dist": {
3716 3716
                 "type": "zip",
3717
-                "url": "https://api.github.com/repos/thephpleague/csv/zipball/553579df208641ada6ffb450b3a151e2fcfa4f31",
3718
-                "reference": "553579df208641ada6ffb450b3a151e2fcfa4f31",
3717
+                "url": "https://api.github.com/repos/thephpleague/csv/zipball/491d1e79e973a7370c7571dc0fe4a7241f4936ee",
3718
+                "reference": "491d1e79e973a7370c7571dc0fe4a7241f4936ee",
3719 3719
                 "shasum": ""
3720 3720
             },
3721 3721
             "require": {
@@ -3789,7 +3789,7 @@
3789 3789
                     "type": "github"
3790 3790
                 }
3791 3791
             ],
3792
-            "time": "2024-12-13T15:49:27+00:00"
3792
+            "time": "2024-12-18T10:11:15+00:00"
3793 3793
         },
3794 3794
         {
3795 3795
             "name": "league/flysystem",
@@ -4374,16 +4374,16 @@
4374 4374
         },
4375 4375
         {
4376 4376
             "name": "matomo/device-detector",
4377
-            "version": "6.4.1",
4377
+            "version": "6.4.2",
4378 4378
             "source": {
4379 4379
                 "type": "git",
4380 4380
                 "url": "https://github.com/matomo-org/device-detector.git",
4381
-                "reference": "0d364e0dd6c177da3c24cd4049178026324fd7ac"
4381
+                "reference": "806e52d214b05ddead1a1d4304c7592f61f95976"
4382 4382
             },
4383 4383
             "dist": {
4384 4384
                 "type": "zip",
4385
-                "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/0d364e0dd6c177da3c24cd4049178026324fd7ac",
4386
-                "reference": "0d364e0dd6c177da3c24cd4049178026324fd7ac",
4385
+                "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/806e52d214b05ddead1a1d4304c7592f61f95976",
4386
+                "reference": "806e52d214b05ddead1a1d4304c7592f61f95976",
4387 4387
                 "shasum": ""
4388 4388
             },
4389 4389
             "require": {
@@ -4439,7 +4439,7 @@
4439 4439
                 "source": "https://github.com/matomo-org/matomo",
4440 4440
                 "wiki": "https://dev.matomo.org/"
4441 4441
             },
4442
-            "time": "2024-09-24T13:50:04+00:00"
4442
+            "time": "2024-12-16T16:38:01+00:00"
4443 4443
         },
4444 4444
         {
4445 4445
             "name": "monolog/monolog",
@@ -5065,16 +5065,16 @@
5065 5065
         },
5066 5066
         {
5067 5067
             "name": "openspout/openspout",
5068
-            "version": "v4.28.2",
5068
+            "version": "v4.28.3",
5069 5069
             "source": {
5070 5070
                 "type": "git",
5071 5071
                 "url": "https://github.com/openspout/openspout.git",
5072
-                "reference": "d6dd654b5db502f28c5773edfa785b516745a142"
5072
+                "reference": "12b5eddcc230a97a9a67a722ad75c247e1a16750"
5073 5073
             },
5074 5074
             "dist": {
5075 5075
                 "type": "zip",
5076
-                "url": "https://api.github.com/repos/openspout/openspout/zipball/d6dd654b5db502f28c5773edfa785b516745a142",
5077
-                "reference": "d6dd654b5db502f28c5773edfa785b516745a142",
5076
+                "url": "https://api.github.com/repos/openspout/openspout/zipball/12b5eddcc230a97a9a67a722ad75c247e1a16750",
5077
+                "reference": "12b5eddcc230a97a9a67a722ad75c247e1a16750",
5078 5078
                 "shasum": ""
5079 5079
             },
5080 5080
             "require": {
@@ -5094,7 +5094,7 @@
5094 5094
                 "phpstan/phpstan": "^2.0.3",
5095 5095
                 "phpstan/phpstan-phpunit": "^2.0.1",
5096 5096
                 "phpstan/phpstan-strict-rules": "^2",
5097
-                "phpunit/phpunit": "^11.4.4"
5097
+                "phpunit/phpunit": "^11.5.0"
5098 5098
             },
5099 5099
             "suggest": {
5100 5100
                 "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
@@ -5142,7 +5142,7 @@
5142 5142
             ],
5143 5143
             "support": {
5144 5144
                 "issues": "https://github.com/openspout/openspout/issues",
5145
-                "source": "https://github.com/openspout/openspout/tree/v4.28.2"
5145
+                "source": "https://github.com/openspout/openspout/tree/v4.28.3"
5146 5146
             },
5147 5147
             "funding": [
5148 5148
                 {
@@ -5154,7 +5154,7 @@
5154 5154
                     "type": "github"
5155 5155
                 }
5156 5156
             ],
5157
-            "time": "2024-12-06T06:17:37+00:00"
5157
+            "time": "2024-12-17T11:28:11+00:00"
5158 5158
         },
5159 5159
         {
5160 5160
             "name": "paragonie/constant_time_encoding",
@@ -12817,8 +12817,8 @@
12817 12817
             "type": "library",
12818 12818
             "extra": {
12819 12819
                 "thanks": {
12820
-                    "name": "symfony/polyfill",
12821
-                    "url": "https://github.com/symfony/polyfill"
12820
+                    "url": "https://github.com/symfony/polyfill",
12821
+                    "name": "symfony/polyfill"
12822 12822
                 }
12823 12823
             },
12824 12824
             "autoload": {

+ 12
- 12
package-lock.json 查看文件

@@ -1057,9 +1057,9 @@
1057 1057
             }
1058 1058
         },
1059 1059
         "node_modules/caniuse-lite": {
1060
-            "version": "1.0.30001688",
1061
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz",
1062
-            "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==",
1060
+            "version": "1.0.30001689",
1061
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz",
1062
+            "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==",
1063 1063
             "dev": true,
1064 1064
             "funding": [
1065 1065
                 {
@@ -1218,9 +1218,9 @@
1218 1218
             "license": "MIT"
1219 1219
         },
1220 1220
         "node_modules/electron-to-chromium": {
1221
-            "version": "1.5.73",
1222
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz",
1223
-            "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==",
1221
+            "version": "1.5.74",
1222
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
1223
+            "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
1224 1224
             "dev": true,
1225 1225
             "license": "ISC"
1226 1226
         },
@@ -1569,9 +1569,9 @@
1569 1569
             }
1570 1570
         },
1571 1571
         "node_modules/jiti": {
1572
-            "version": "1.21.6",
1573
-            "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
1574
-            "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
1572
+            "version": "1.21.7",
1573
+            "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
1574
+            "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
1575 1575
             "dev": true,
1576 1576
             "license": "MIT",
1577 1577
             "bin": {
@@ -2470,9 +2470,9 @@
2470 2470
             }
2471 2471
         },
2472 2472
         "node_modules/tailwindcss": {
2473
-            "version": "3.4.16",
2474
-            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz",
2475
-            "integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==",
2473
+            "version": "3.4.17",
2474
+            "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
2475
+            "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
2476 2476
             "dev": true,
2477 2477
             "license": "MIT",
2478 2478
             "dependencies": {

+ 0
- 61
resources/views/filament/forms/components/bill-totals.blade.php 查看文件

@@ -1,61 +0,0 @@
1
-@php
2
-    use App\Enums\Accounting\DocumentDiscountMethod;
3
-    use App\Utilities\Currency\CurrencyAccessor;
4
-    use App\View\Models\BillTotalViewModel;
5
-
6
-    $data = $this->form->getRawState();
7
-    $viewModel = new BillTotalViewModel($this->record, $data);
8
-    extract($viewModel->buildViewData(), EXTR_SKIP);
9
-
10
-    $discountMethod = DocumentDiscountMethod::parse($data['discount_method']);
11
-    $isPerDocumentDiscount = $discountMethod->isPerDocument();
12
-@endphp
13
-
14
-<div class="totals-summary w-full pr-14">
15
-    <table class="w-full text-right table-fixed">
16
-        <colgroup>
17
-            <col class="w-[20%]"> {{-- Items --}}
18
-            <col class="w-[30%]"> {{-- Description --}}
19
-            <col class="w-[10%]"> {{-- Quantity --}}
20
-            <col class="w-[10%]"> {{-- Price --}}
21
-            <col class="w-[20%]"> {{-- Taxes --}}
22
-            <col class="w-[10%]"> {{-- Amount --}}
23
-        </colgroup>
24
-        <tbody>
25
-            <tr>
26
-                <td colspan="4"></td>
27
-                <td class="text-sm px-4 py-2 font-medium leading-6 text-gray-950 dark:text-white">Subtotal:</td>
28
-                <td class="text-sm pl-4 py-2 leading-6">{{ $subtotal }}</td>
29
-            </tr>
30
-            <tr>
31
-                <td colspan="4"></td>
32
-                <td class="text-sm px-4 py-2 font-medium leading-6 text-gray-950 dark:text-white">Taxes:</td>
33
-                <td class="text-sm pl-4 py-2 leading-6">{{ $taxTotal }}</td>
34
-            </tr>
35
-            @if($isPerDocumentDiscount)
36
-                <tr>
37
-                    <td colspan="4" class="text-sm px-4 py-2 font-medium leading-6 text-gray-950 dark:text-white text-right">Discount:</td>
38
-                    <td class="text-sm px-4 py-2">
39
-                        <div class="flex justify-between space-x-2">
40
-                            @foreach($getChildComponentContainer()->getComponents() as $component)
41
-                                <div class="flex-1">{{ $component }}</div>
42
-                            @endforeach
43
-                        </div>
44
-                    </td>
45
-                    <td class="text-sm pl-4 py-2 leading-6">({{ $discountTotal }})</td>
46
-                </tr>
47
-            @else
48
-                <tr>
49
-                    <td colspan="4"></td>
50
-                    <td class="text-sm px-4 py-2 font-medium leading-6 text-gray-950 dark:text-white">Discounts:</td>
51
-                    <td class="text-sm pl-4 py-2 leading-6">({{ $discountTotal }})</td>
52
-                </tr>
53
-            @endif
54
-            <tr class="font-semibold">
55
-                <td colspan="4"></td>
56
-                <td class="text-sm px-4 py-2 font-medium leading-6 text-gray-950 dark:text-white">Total:</td>
57
-                <td class="text-sm pl-4 py-2 leading-6">{{ $grandTotal }}</td>
58
-            </tr>
59
-        </tbody>
60
-    </table>
61
-</div>

resources/views/filament/forms/components/invoice-totals.blade.php → resources/views/filament/forms/components/document-totals.blade.php 查看文件

@@ -1,10 +1,11 @@
1 1
 @php
2 2
     use App\Enums\Accounting\DocumentDiscountMethod;
3 3
     use App\Utilities\Currency\CurrencyAccessor;
4
-    use App\View\Models\InvoiceTotalViewModel;
4
+    use App\View\Models\DocumentTotalViewModel;
5 5
 
6 6
     $data = $this->form->getRawState();
7
-    $viewModel = new InvoiceTotalViewModel($this->record, $data);
7
+    $type = $getType();
8
+    $viewModel = new DocumentTotalViewModel($data, $type);
8 9
     extract($viewModel->buildViewData(), EXTR_SKIP);
9 10
 
10 11
     $discountMethod = DocumentDiscountMethod::parse($data['discount_method']);

Loading…
取消
儲存