Przeglądaj źródła

wip refactor

3.x
Andrew Wallo 9 miesięcy temu
rodzic
commit
22a5c35d0c

+ 45
- 0
app/Enums/Accounting/DocumentType.php Wyświetl plik

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 Wyświetl plik

4
 
4
 
5
 use App\Enums\Accounting\BillStatus;
5
 use App\Enums\Accounting\BillStatus;
6
 use App\Enums\Accounting\DocumentDiscountMethod;
6
 use App\Enums\Accounting\DocumentDiscountMethod;
7
+use App\Enums\Accounting\DocumentType;
7
 use App\Enums\Accounting\PaymentMethod;
8
 use App\Enums\Accounting\PaymentMethod;
8
 use App\Filament\Company\Resources\Purchases\BillResource\Pages;
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
 use App\Filament\Tables\Actions\ReplicateBulkAction;
12
 use App\Filament\Tables\Actions\ReplicateBulkAction;
11
 use App\Filament\Tables\Filters\DateRangeFilter;
13
 use App\Filament\Tables\Filters\DateRangeFilter;
12
 use App\Models\Accounting\Adjustment;
14
 use App\Models\Accounting\Adjustment;
13
 use App\Models\Accounting\Bill;
15
 use App\Models\Accounting\Bill;
14
 use App\Models\Banking\BankAccount;
16
 use App\Models\Banking\BankAccount;
15
 use App\Models\Common\Offering;
17
 use App\Models\Common\Offering;
18
+use App\Models\Common\Vendor;
19
+use App\Utilities\Currency\CurrencyAccessor;
16
 use App\Utilities\Currency\CurrencyConverter;
20
 use App\Utilities\Currency\CurrencyConverter;
21
+use App\Utilities\RateCalculator;
17
 use Awcodes\TableRepeater\Components\TableRepeater;
22
 use Awcodes\TableRepeater\Components\TableRepeater;
18
 use Awcodes\TableRepeater\Header;
23
 use Awcodes\TableRepeater\Header;
19
 use Closure;
24
 use Closure;
49
                                     ->relationship('vendor', 'name')
54
                                     ->relationship('vendor', 'name')
50
                                     ->preload()
55
                                     ->preload()
51
                                     ->searchable()
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
                             Forms\Components\Group::make([
72
                             Forms\Components\Group::make([
55
                                 Forms\Components\TextInput::make('bill_number')
73
                                 Forms\Components\TextInput::make('bill_number')
170
                                         $unitPrice = max((float) ($get('unit_price') ?? 0), 0);
188
                                         $unitPrice = max((float) ($get('unit_price') ?? 0), 0);
171
                                         $purchaseTaxes = $get('purchaseTaxes') ?? [];
189
                                         $purchaseTaxes = $get('purchaseTaxes') ?? [];
172
                                         $purchaseDiscounts = $get('purchaseDiscounts') ?? [];
190
                                         $purchaseDiscounts = $get('purchaseDiscounts') ?? [];
191
+                                        $currencyCode = $get('../../currency_code') ?? CurrencyAccessor::getDefaultCurrency();
173
 
192
 
174
                                         $subtotal = $quantity * $unitPrice;
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
                                         // Final total
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 Wyświetl plik

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

app/Filament/Forms/Components/BillTotals.php → app/Filament/Forms/Components/DocumentTotals.php Wyświetl plik

3
 namespace App\Filament\Forms\Components;
3
 namespace App\Filament\Forms\Components;
4
 
4
 
5
 use App\Enums\Accounting\AdjustmentComputation;
5
 use App\Enums\Accounting\AdjustmentComputation;
6
+use App\Enums\Accounting\DocumentType;
6
 use Filament\Forms\Components\Grid;
7
 use Filament\Forms\Components\Grid;
7
 use Filament\Forms\Components\Select;
8
 use Filament\Forms\Components\Select;
8
 use Filament\Forms\Components\TextInput;
9
 use Filament\Forms\Components\TextInput;
9
 use Filament\Forms\Get;
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
     protected function setUp(): void
18
     protected function setUp(): void
16
     {
19
     {
34
                 ->live(),
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 Wyświetl plik

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 Wyświetl plik

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 Wyświetl plik

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 Wyświetl plik

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 Wyświetl plik

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

+ 85
- 85
composer.lock Wyświetl plik

4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
4
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
         "This file is @generated automatically"
5
         "This file is @generated automatically"
6
     ],
6
     ],
7
-    "content-hash": "7301f370a98e2573adf4e6b4e7ab4a8e",
7
+    "content-hash": "a04479d57fe01a2694ad92a8901363ea",
8
     "packages": [
8
     "packages": [
9
         {
9
         {
10
             "name": "akaunting/laravel-money",
10
             "name": "akaunting/laravel-money",
497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.334.6",
500
+            "version": "3.336.0",
501
             "source": {
501
             "source": {
502
                 "type": "git",
502
                 "type": "git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "2b0be3aded849d3b7bb0b53ea3295c7cecdeeee7"
504
+                "reference": "5a62003bf183e32da038056a4b9077c27224e034"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
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
                 "shasum": ""
510
                 "shasum": ""
511
             },
511
             },
512
             "require": {
512
             "require": {
589
             "support": {
589
             "support": {
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
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
             "name": "aws/aws-sdk-php-laravel",
597
             "name": "aws/aws-sdk-php-laravel",
1662
         },
1662
         },
1663
         {
1663
         {
1664
             "name": "filament/actions",
1664
             "name": "filament/actions",
1665
-            "version": "v3.2.129",
1665
+            "version": "v3.2.131",
1666
             "source": {
1666
             "source": {
1667
                 "type": "git",
1667
                 "type": "git",
1668
                 "url": "https://github.com/filamentphp/actions.git",
1668
                 "url": "https://github.com/filamentphp/actions.git",
1669
-                "reference": "1ee8b0a890b53e8b0b341134d3ba9bdaeee294d3"
1669
+                "reference": "8d9ceaf392eeff55fd335f5169d14f84af8c325e"
1670
             },
1670
             },
1671
             "dist": {
1671
             "dist": {
1672
                 "type": "zip",
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
                 "shasum": ""
1675
                 "shasum": ""
1676
             },
1676
             },
1677
             "require": {
1677
             "require": {
1711
                 "issues": "https://github.com/filamentphp/filament/issues",
1711
                 "issues": "https://github.com/filamentphp/filament/issues",
1712
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/filament",
1717
             "name": "filament/filament",
1718
-            "version": "v3.2.129",
1718
+            "version": "v3.2.131",
1719
             "source": {
1719
             "source": {
1720
                 "type": "git",
1720
                 "type": "git",
1721
                 "url": "https://github.com/filamentphp/panels.git",
1721
                 "url": "https://github.com/filamentphp/panels.git",
1722
-                "reference": "9a327a54dec24e0b12c437ef799828f492cb882a"
1722
+                "reference": "21febddcc6720b250b41386805a8dbd1deef2c56"
1723
             },
1723
             },
1724
             "dist": {
1724
             "dist": {
1725
                 "type": "zip",
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
                 "shasum": ""
1728
                 "shasum": ""
1729
             },
1729
             },
1730
             "require": {
1730
             "require": {
1776
                 "issues": "https://github.com/filamentphp/filament/issues",
1776
                 "issues": "https://github.com/filamentphp/filament/issues",
1777
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/forms",
1782
             "name": "filament/forms",
1783
-            "version": "v3.2.129",
1783
+            "version": "v3.2.131",
1784
             "source": {
1784
             "source": {
1785
                 "type": "git",
1785
                 "type": "git",
1786
                 "url": "https://github.com/filamentphp/forms.git",
1786
                 "url": "https://github.com/filamentphp/forms.git",
1787
-                "reference": "e6133bdc03de05dfe23eac386b49e51093338883"
1787
+                "reference": "72429b0df9c3d123273dd51ba62b764e2114697c"
1788
             },
1788
             },
1789
             "dist": {
1789
             "dist": {
1790
                 "type": "zip",
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
                 "shasum": ""
1793
                 "shasum": ""
1794
             },
1794
             },
1795
             "require": {
1795
             "require": {
1832
                 "issues": "https://github.com/filamentphp/filament/issues",
1832
                 "issues": "https://github.com/filamentphp/filament/issues",
1833
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/infolists",
1838
             "name": "filament/infolists",
1839
-            "version": "v3.2.129",
1839
+            "version": "v3.2.131",
1840
             "source": {
1840
             "source": {
1841
                 "type": "git",
1841
                 "type": "git",
1842
                 "url": "https://github.com/filamentphp/infolists.git",
1842
                 "url": "https://github.com/filamentphp/infolists.git",
1843
-                "reference": "0db994330e7fe21a9684256ea1fc34fee916a8d6"
1843
+                "reference": "15c200a3172b88a6247ff4b7230f69982d848194"
1844
             },
1844
             },
1845
             "dist": {
1845
             "dist": {
1846
                 "type": "zip",
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
                 "shasum": ""
1849
                 "shasum": ""
1850
             },
1850
             },
1851
             "require": {
1851
             "require": {
1883
                 "issues": "https://github.com/filamentphp/filament/issues",
1883
                 "issues": "https://github.com/filamentphp/filament/issues",
1884
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/notifications",
1889
             "name": "filament/notifications",
1890
-            "version": "v3.2.129",
1890
+            "version": "v3.2.131",
1891
             "source": {
1891
             "source": {
1892
                 "type": "git",
1892
                 "type": "git",
1893
                 "url": "https://github.com/filamentphp/notifications.git",
1893
                 "url": "https://github.com/filamentphp/notifications.git",
1939
         },
1939
         },
1940
         {
1940
         {
1941
             "name": "filament/support",
1941
             "name": "filament/support",
1942
-            "version": "v3.2.129",
1942
+            "version": "v3.2.131",
1943
             "source": {
1943
             "source": {
1944
                 "type": "git",
1944
                 "type": "git",
1945
                 "url": "https://github.com/filamentphp/support.git",
1945
                 "url": "https://github.com/filamentphp/support.git",
1946
-                "reference": "e8aed9684d5c58ff7dde9517c7f1af44d575d871"
1946
+                "reference": "ddc16d8da50d73f7300671b70c9dcb942d845d9d"
1947
             },
1947
             },
1948
             "dist": {
1948
             "dist": {
1949
                 "type": "zip",
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
                 "shasum": ""
1952
                 "shasum": ""
1953
             },
1953
             },
1954
             "require": {
1954
             "require": {
1994
                 "issues": "https://github.com/filamentphp/filament/issues",
1994
                 "issues": "https://github.com/filamentphp/filament/issues",
1995
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/tables",
2000
             "name": "filament/tables",
2001
-            "version": "v3.2.129",
2001
+            "version": "v3.2.131",
2002
             "source": {
2002
             "source": {
2003
                 "type": "git",
2003
                 "type": "git",
2004
                 "url": "https://github.com/filamentphp/tables.git",
2004
                 "url": "https://github.com/filamentphp/tables.git",
2005
-                "reference": "acdec73ae82961654a52a22ed9f53207cfee2ef8"
2005
+                "reference": "224aea12a4a4cfcd158b53df94cdd190f8226cac"
2006
             },
2006
             },
2007
             "dist": {
2007
             "dist": {
2008
                 "type": "zip",
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
                 "shasum": ""
2011
                 "shasum": ""
2012
             },
2012
             },
2013
             "require": {
2013
             "require": {
2046
                 "issues": "https://github.com/filamentphp/filament/issues",
2046
                 "issues": "https://github.com/filamentphp/filament/issues",
2047
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "filament/widgets",
2052
             "name": "filament/widgets",
2053
-            "version": "v3.2.129",
2053
+            "version": "v3.2.131",
2054
             "source": {
2054
             "source": {
2055
                 "type": "git",
2055
                 "type": "git",
2056
                 "url": "https://github.com/filamentphp/widgets.git",
2056
                 "url": "https://github.com/filamentphp/widgets.git",
2057
-                "reference": "6de1c84d71168fd1c6a5b1ae1e1b4ec5ee4b6f55"
2057
+                "reference": "869a419fe42e2cf1b9461f2d1e702e2fcad030ae"
2058
             },
2058
             },
2059
             "dist": {
2059
             "dist": {
2060
                 "type": "zip",
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
                 "shasum": ""
2063
                 "shasum": ""
2064
             },
2064
             },
2065
             "require": {
2065
             "require": {
2090
                 "issues": "https://github.com/filamentphp/filament/issues",
2090
                 "issues": "https://github.com/filamentphp/filament/issues",
2091
                 "source": "https://github.com/filamentphp/filament"
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
             "name": "firebase/php-jwt",
2096
             "name": "firebase/php-jwt",
2980
         },
2980
         },
2981
         {
2981
         {
2982
             "name": "laravel/framework",
2982
             "name": "laravel/framework",
2983
-            "version": "v11.35.1",
2983
+            "version": "v11.36.1",
2984
             "source": {
2984
             "source": {
2985
                 "type": "git",
2985
                 "type": "git",
2986
                 "url": "https://github.com/laravel/framework.git",
2986
                 "url": "https://github.com/laravel/framework.git",
2987
-                "reference": "dcfa130ede1a6fa4343dc113410963e791ad34fb"
2987
+                "reference": "df06f5163f4550641fdf349ebc04916a61135a64"
2988
             },
2988
             },
2989
             "dist": {
2989
             "dist": {
2990
                 "type": "zip",
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
                 "shasum": ""
2993
                 "shasum": ""
2994
             },
2994
             },
2995
             "require": {
2995
             "require": {
3010
                 "guzzlehttp/uri-template": "^1.0",
3010
                 "guzzlehttp/uri-template": "^1.0",
3011
                 "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
3011
                 "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
3012
                 "laravel/serializable-closure": "^1.3|^2.0",
3012
                 "laravel/serializable-closure": "^1.3|^2.0",
3013
-                "league/commonmark": "^2.2.1",
3013
+                "league/commonmark": "^2.6",
3014
                 "league/flysystem": "^3.25.1",
3014
                 "league/flysystem": "^3.25.1",
3015
                 "league/flysystem-local": "^3.25.1",
3015
                 "league/flysystem-local": "^3.25.1",
3016
                 "league/uri": "^7.5.1",
3016
                 "league/uri": "^7.5.1",
3025
                 "symfony/console": "^7.0.3",
3025
                 "symfony/console": "^7.0.3",
3026
                 "symfony/error-handler": "^7.0.3",
3026
                 "symfony/error-handler": "^7.0.3",
3027
                 "symfony/finder": "^7.0.3",
3027
                 "symfony/finder": "^7.0.3",
3028
-                "symfony/http-foundation": "^7.0.3",
3028
+                "symfony/http-foundation": "^7.2.0",
3029
                 "symfony/http-kernel": "^7.0.3",
3029
                 "symfony/http-kernel": "^7.0.3",
3030
                 "symfony/mailer": "^7.0.3",
3030
                 "symfony/mailer": "^7.0.3",
3031
                 "symfony/mime": "^7.0.3",
3031
                 "symfony/mime": "^7.0.3",
3191
                 "issues": "https://github.com/laravel/framework/issues",
3191
                 "issues": "https://github.com/laravel/framework/issues",
3192
                 "source": "https://github.com/laravel/framework"
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
             "name": "laravel/prompts",
3197
             "name": "laravel/prompts",
3254
         },
3254
         },
3255
         {
3255
         {
3256
             "name": "laravel/sanctum",
3256
             "name": "laravel/sanctum",
3257
-            "version": "v4.0.6",
3257
+            "version": "v4.0.7",
3258
             "source": {
3258
             "source": {
3259
                 "type": "git",
3259
                 "type": "git",
3260
                 "url": "https://github.com/laravel/sanctum.git",
3260
                 "url": "https://github.com/laravel/sanctum.git",
3261
-                "reference": "9e069e36d90b1e1f41886efa0fe9800a6b354694"
3261
+                "reference": "698064236a46df016e64a7eb059b1414e0b281df"
3262
             },
3262
             },
3263
             "dist": {
3263
             "dist": {
3264
                 "type": "zip",
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
                 "shasum": ""
3267
                 "shasum": ""
3268
             },
3268
             },
3269
             "require": {
3269
             "require": {
3314
                 "issues": "https://github.com/laravel/sanctum/issues",
3314
                 "issues": "https://github.com/laravel/sanctum/issues",
3315
                 "source": "https://github.com/laravel/sanctum"
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
             "name": "laravel/serializable-closure",
3320
             "name": "laravel/serializable-closure",
3321
-            "version": "v2.0.0",
3321
+            "version": "v2.0.1",
3322
             "source": {
3322
             "source": {
3323
                 "type": "git",
3323
                 "type": "git",
3324
                 "url": "https://github.com/laravel/serializable-closure.git",
3324
                 "url": "https://github.com/laravel/serializable-closure.git",
3325
-                "reference": "0d8d3d8086984996df86596a86dea60398093a81"
3325
+                "reference": "613b2d4998f85564d40497e05e89cb6d9bd1cbe8"
3326
             },
3326
             },
3327
             "dist": {
3327
             "dist": {
3328
                 "type": "zip",
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
                 "shasum": ""
3331
                 "shasum": ""
3332
             },
3332
             },
3333
             "require": {
3333
             "require": {
3375
                 "issues": "https://github.com/laravel/serializable-closure/issues",
3375
                 "issues": "https://github.com/laravel/serializable-closure/issues",
3376
                 "source": "https://github.com/laravel/serializable-closure"
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
             "name": "laravel/socialite",
3381
             "name": "laravel/socialite",
3382
-            "version": "v5.16.0",
3382
+            "version": "v5.16.1",
3383
             "source": {
3383
             "source": {
3384
                 "type": "git",
3384
                 "type": "git",
3385
                 "url": "https://github.com/laravel/socialite.git",
3385
                 "url": "https://github.com/laravel/socialite.git",
3386
-                "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf"
3386
+                "reference": "4e5be83c0b3ecf81b2ffa47092e917d1f79dce71"
3387
             },
3387
             },
3388
             "dist": {
3388
             "dist": {
3389
                 "type": "zip",
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
                 "shasum": ""
3392
                 "shasum": ""
3393
             },
3393
             },
3394
             "require": {
3394
             "require": {
3398
                 "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3398
                 "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3399
                 "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3399
                 "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
3400
                 "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0",
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
                 "php": "^7.2|^8.0",
3402
                 "php": "^7.2|^8.0",
3403
                 "phpseclib/phpseclib": "^3.0"
3403
                 "phpseclib/phpseclib": "^3.0"
3404
             },
3404
             },
3447
                 "issues": "https://github.com/laravel/socialite/issues",
3447
                 "issues": "https://github.com/laravel/socialite/issues",
3448
                 "source": "https://github.com/laravel/socialite"
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
             "name": "laravel/tinker",
3453
             "name": "laravel/tinker",
3706
         },
3706
         },
3707
         {
3707
         {
3708
             "name": "league/csv",
3708
             "name": "league/csv",
3709
-            "version": "9.20.0",
3709
+            "version": "9.20.1",
3710
             "source": {
3710
             "source": {
3711
                 "type": "git",
3711
                 "type": "git",
3712
                 "url": "https://github.com/thephpleague/csv.git",
3712
                 "url": "https://github.com/thephpleague/csv.git",
3713
-                "reference": "553579df208641ada6ffb450b3a151e2fcfa4f31"
3713
+                "reference": "491d1e79e973a7370c7571dc0fe4a7241f4936ee"
3714
             },
3714
             },
3715
             "dist": {
3715
             "dist": {
3716
                 "type": "zip",
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
                 "shasum": ""
3719
                 "shasum": ""
3720
             },
3720
             },
3721
             "require": {
3721
             "require": {
3789
                     "type": "github"
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
             "name": "league/flysystem",
3795
             "name": "league/flysystem",
4374
         },
4374
         },
4375
         {
4375
         {
4376
             "name": "matomo/device-detector",
4376
             "name": "matomo/device-detector",
4377
-            "version": "6.4.1",
4377
+            "version": "6.4.2",
4378
             "source": {
4378
             "source": {
4379
                 "type": "git",
4379
                 "type": "git",
4380
                 "url": "https://github.com/matomo-org/device-detector.git",
4380
                 "url": "https://github.com/matomo-org/device-detector.git",
4381
-                "reference": "0d364e0dd6c177da3c24cd4049178026324fd7ac"
4381
+                "reference": "806e52d214b05ddead1a1d4304c7592f61f95976"
4382
             },
4382
             },
4383
             "dist": {
4383
             "dist": {
4384
                 "type": "zip",
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
                 "shasum": ""
4387
                 "shasum": ""
4388
             },
4388
             },
4389
             "require": {
4389
             "require": {
4439
                 "source": "https://github.com/matomo-org/matomo",
4439
                 "source": "https://github.com/matomo-org/matomo",
4440
                 "wiki": "https://dev.matomo.org/"
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
             "name": "monolog/monolog",
4445
             "name": "monolog/monolog",
5065
         },
5065
         },
5066
         {
5066
         {
5067
             "name": "openspout/openspout",
5067
             "name": "openspout/openspout",
5068
-            "version": "v4.28.2",
5068
+            "version": "v4.28.3",
5069
             "source": {
5069
             "source": {
5070
                 "type": "git",
5070
                 "type": "git",
5071
                 "url": "https://github.com/openspout/openspout.git",
5071
                 "url": "https://github.com/openspout/openspout.git",
5072
-                "reference": "d6dd654b5db502f28c5773edfa785b516745a142"
5072
+                "reference": "12b5eddcc230a97a9a67a722ad75c247e1a16750"
5073
             },
5073
             },
5074
             "dist": {
5074
             "dist": {
5075
                 "type": "zip",
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
                 "shasum": ""
5078
                 "shasum": ""
5079
             },
5079
             },
5080
             "require": {
5080
             "require": {
5094
                 "phpstan/phpstan": "^2.0.3",
5094
                 "phpstan/phpstan": "^2.0.3",
5095
                 "phpstan/phpstan-phpunit": "^2.0.1",
5095
                 "phpstan/phpstan-phpunit": "^2.0.1",
5096
                 "phpstan/phpstan-strict-rules": "^2",
5096
                 "phpstan/phpstan-strict-rules": "^2",
5097
-                "phpunit/phpunit": "^11.4.4"
5097
+                "phpunit/phpunit": "^11.5.0"
5098
             },
5098
             },
5099
             "suggest": {
5099
             "suggest": {
5100
                 "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
5100
                 "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)",
5142
             ],
5142
             ],
5143
             "support": {
5143
             "support": {
5144
                 "issues": "https://github.com/openspout/openspout/issues",
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
             "funding": [
5147
             "funding": [
5148
                 {
5148
                 {
5154
                     "type": "github"
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
             "name": "paragonie/constant_time_encoding",
5160
             "name": "paragonie/constant_time_encoding",
12817
             "type": "library",
12817
             "type": "library",
12818
             "extra": {
12818
             "extra": {
12819
                 "thanks": {
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
             "autoload": {
12824
             "autoload": {

+ 12
- 12
package-lock.json Wyświetl plik

1057
             }
1057
             }
1058
         },
1058
         },
1059
         "node_modules/caniuse-lite": {
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
             "dev": true,
1063
             "dev": true,
1064
             "funding": [
1064
             "funding": [
1065
                 {
1065
                 {
1218
             "license": "MIT"
1218
             "license": "MIT"
1219
         },
1219
         },
1220
         "node_modules/electron-to-chromium": {
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
             "dev": true,
1224
             "dev": true,
1225
             "license": "ISC"
1225
             "license": "ISC"
1226
         },
1226
         },
1569
             }
1569
             }
1570
         },
1570
         },
1571
         "node_modules/jiti": {
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
             "dev": true,
1575
             "dev": true,
1576
             "license": "MIT",
1576
             "license": "MIT",
1577
             "bin": {
1577
             "bin": {
2470
             }
2470
             }
2471
         },
2471
         },
2472
         "node_modules/tailwindcss": {
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
             "dev": true,
2476
             "dev": true,
2477
             "license": "MIT",
2477
             "license": "MIT",
2478
             "dependencies": {
2478
             "dependencies": {

+ 0
- 61
resources/views/filament/forms/components/bill-totals.blade.php Wyświetl plik

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 Wyświetl plik

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

Ładowanie…
Anuluj
Zapisz