Andrew Wallo 6 mesi fa
parent
commit
f88a874277

+ 0
- 7
app/Filament/Company/Resources/Purchases/BillResource.php Vedi File

@@ -578,13 +578,6 @@ class BillResource extends Resource
578 578
             ]);
579 579
     }
580 580
 
581
-    public static function getRelations(): array
582
-    {
583
-        return [
584
-            BillResource\RelationManagers\PaymentsRelationManager::class,
585
-        ];
586
-    }
587
-
588 581
     public static function getPages(): array
589 582
     {
590 583
         return [

+ 7
- 0
app/Filament/Company/Resources/Purchases/BillResource/Pages/ViewBill.php Vedi File

@@ -79,4 +79,11 @@ class ViewBill extends ViewRecord
79 79
                     ]),
80 80
             ]);
81 81
     }
82
+
83
+    protected function getAllRelationManagers(): array
84
+    {
85
+        return [
86
+            BillResource\RelationManagers\PaymentsRelationManager::class,
87
+        ];
88
+    }
82 89
 }

+ 119
- 46
app/Filament/Company/Resources/Purchases/BillResource/RelationManagers/PaymentsRelationManager.php Vedi File

@@ -4,7 +4,6 @@ namespace App\Filament\Company\Resources\Purchases\BillResource\RelationManagers
4 4
 
5 5
 use App\Enums\Accounting\PaymentMethod;
6 6
 use App\Enums\Accounting\TransactionType;
7
-use App\Filament\Company\Resources\Purchases\BillResource\Pages\ViewBill;
8 7
 use App\Models\Accounting\Bill;
9 8
 use App\Models\Accounting\Transaction;
10 9
 use App\Models\Banking\BankAccount;
@@ -19,7 +18,6 @@ use Filament\Support\Enums\FontWeight;
19 18
 use Filament\Support\Enums\MaxWidth;
20 19
 use Filament\Tables;
21 20
 use Filament\Tables\Table;
22
-use Illuminate\Database\Eloquent\Model;
23 21
 
24 22
 class PaymentsRelationManager extends RelationManager
25 23
 {
@@ -36,11 +34,6 @@ class PaymentsRelationManager extends RelationManager
36 34
         return false;
37 35
     }
38 36
 
39
-    public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
40
-    {
41
-        return $pageClass === ViewBill::class;
42
-    }
43
-
44 37
     public function form(Form $form): Form
45 38
     {
46 39
         return $form
@@ -48,59 +41,139 @@ class PaymentsRelationManager extends RelationManager
48 41
             ->schema([
49 42
                 Forms\Components\DatePicker::make('posted_at')
50 43
                     ->label('Date'),
51
-                Forms\Components\TextInput::make('amount')
52
-                    ->label('Amount')
53
-                    ->required()
54
-                    ->money()
55
-                    ->live(onBlur: true)
56
-                    ->helperText(function (RelationManager $livewire, $state, ?Transaction $record) {
57
-                        if (! CurrencyConverter::isValidAmount($state)) {
44
+                Forms\Components\Grid::make()
45
+                    ->schema([
46
+                        Forms\Components\Select::make('bank_account_id')
47
+                            ->label('Account')
48
+                            ->required()
49
+                            ->live()
50
+                            ->options(function () {
51
+                                return BankAccount::query()
52
+                                    ->join('accounts', 'bank_accounts.account_id', '=', 'accounts.id')
53
+                                    ->select(['bank_accounts.id', 'accounts.name', 'accounts.currency_code'])
54
+                                    ->get()
55
+                                    ->mapWithKeys(function ($account) {
56
+                                        $label = $account->name;
57
+                                        if ($account->currency_code) {
58
+                                            $label .= " ({$account->currency_code})";
59
+                                        }
60
+
61
+                                        return [$account->id => $label];
62
+                                    })
63
+                                    ->toArray();
64
+                            })
65
+                            ->searchable(),
66
+                        Forms\Components\TextInput::make('amount')
67
+                            ->label('Amount')
68
+                            ->required()
69
+                            ->money(function (RelationManager $livewire) {
70
+                                /** @var Bill $bill */
71
+                                $bill = $livewire->getOwnerRecord();
72
+
73
+                                return $bill->currency_code;
74
+                            })
75
+                            ->live(onBlur: true)
76
+                            ->helperText(function (RelationManager $livewire, $state, ?Transaction $record) {
77
+                                /** @var Bill $ownerRecord */
78
+                                $ownerRecord = $livewire->getOwnerRecord();
79
+
80
+                                $billCurrency = $ownerRecord->currency_code;
81
+
82
+                                if (! CurrencyConverter::isValidAmount($state, $billCurrency)) {
83
+                                    return null;
84
+                                }
85
+
86
+                                $amountDue = $ownerRecord->getRawOriginal('amount_due');
87
+
88
+                                $amount = CurrencyConverter::convertToCents($state, $billCurrency);
89
+
90
+                                if ($amount <= 0) {
91
+                                    return 'Please enter a valid positive amount';
92
+                                }
93
+
94
+                                $currentPaymentAmount = $record?->getRawOriginal('amount') ?? 0;
95
+
96
+                                $newAmountDue = $amountDue - $amount + $currentPaymentAmount;
97
+
98
+                                return match (true) {
99
+                                    $newAmountDue > 0 => 'Amount due after payment will be ' . CurrencyConverter::formatCentsToMoney($newAmountDue, $billCurrency),
100
+                                    $newAmountDue === 0 => 'Bill will be fully paid',
101
+                                    default => 'Amount exceeds bill total by ' . CurrencyConverter::formatCentsToMoney(abs($newAmountDue), $billCurrency),
102
+                                };
103
+                            })
104
+                            ->rules([
105
+                                static fn (RelationManager $livewire): Closure => static function (string $attribute, $value, Closure $fail) use ($livewire) {
106
+                                    /** @var Bill $bill */
107
+                                    $bill = $livewire->getOwnerRecord();
108
+
109
+                                    if (! CurrencyConverter::isValidAmount($value, $bill->currency_code)) {
110
+                                        $fail('Please enter a valid amount');
111
+                                    }
112
+                                },
113
+                            ]),
114
+                    ])->columns(2),
115
+                Forms\Components\Placeholder::make('currency_conversion')
116
+                    ->label('Currency Conversion')
117
+                    ->content(function (Forms\Get $get, RelationManager $livewire) {
118
+                        $amount = $get('amount');
119
+                        $bankAccountId = $get('bank_account_id');
120
+
121
+                        /** @var Bill $bill */
122
+                        $bill = $livewire->getOwnerRecord();
123
+                        $billCurrency = $bill->currency_code;
124
+
125
+                        if (empty($amount) || empty($bankAccountId) || ! CurrencyConverter::isValidAmount($amount, $billCurrency)) {
58 126
                             return null;
59 127
                         }
60 128
 
61
-                        /** @var Bill $ownerRecord */
62
-                        $ownerRecord = $livewire->getOwnerRecord();
63
-
64
-                        $amountDue = $ownerRecord->getRawOriginal('amount_due');
129
+                        $bankAccount = BankAccount::with('account')->find($bankAccountId);
130
+                        if (! $bankAccount) {
131
+                            return null;
132
+                        }
65 133
 
66
-                        $amount = CurrencyConverter::convertToCents($state);
134
+                        $bankCurrency = $bankAccount->account->currency_code ?? CurrencyAccessor::getDefaultCurrency();
67 135
 
68
-                        if ($amount <= 0) {
69
-                            return 'Please enter a valid positive amount';
136
+                        // If currencies are the same, no conversion needed
137
+                        if ($billCurrency === $bankCurrency) {
138
+                            return null;
70 139
                         }
71 140
 
72
-                        $currentPaymentAmount = $record?->getRawOriginal('amount') ?? 0;
141
+                        // Convert amount from bill currency to bank currency
142
+                        $amountInBillCurrencyCents = CurrencyConverter::convertToCents($amount, $billCurrency);
143
+                        $amountInBankCurrencyCents = CurrencyConverter::convertBalance(
144
+                            $amountInBillCurrencyCents,
145
+                            $billCurrency,
146
+                            $bankCurrency
147
+                        );
73 148
 
74
-                        $newAmountDue = $amountDue - $amount + $currentPaymentAmount;
149
+                        $formattedBankAmount = CurrencyConverter::formatCentsToMoney($amountInBankCurrencyCents, $bankCurrency);
75 150
 
76
-                        return match (true) {
77
-                            $newAmountDue > 0 => 'Amount due after payment will be ' . CurrencyConverter::formatCentsToMoney($newAmountDue),
78
-                            $newAmountDue === 0 => 'Bill will be fully paid',
79
-                            default => 'Amount exceeds bill total by ' . CurrencyConverter::formatCentsToMoney(abs($newAmountDue)),
80
-                        };
151
+                        return "Payment will be recorded as {$formattedBankAmount} in the bank account's currency ({$bankCurrency}).";
81 152
                     })
82
-                    ->rules([
83
-                        static fn (): Closure => static function (string $attribute, $value, Closure $fail) {
84
-                            if (! CurrencyConverter::isValidAmount($value)) {
85
-                                $fail('Please enter a valid amount');
86
-                            }
87
-                        },
88
-                    ]),
153
+                    ->hidden(function (Forms\Get $get, RelationManager $livewire) {
154
+                        $bankAccountId = $get('bank_account_id');
155
+                        if (empty($bankAccountId)) {
156
+                            return true;
157
+                        }
158
+
159
+                        /** @var Bill $bill */
160
+                        $bill = $livewire->getOwnerRecord();
161
+                        $billCurrency = $bill->currency_code;
162
+
163
+                        $bankAccount = BankAccount::with('account')->find($bankAccountId);
164
+                        if (! $bankAccount) {
165
+                            return true;
166
+                        }
167
+
168
+                        $bankCurrency = $bankAccount->account->currency_code ?? CurrencyAccessor::getDefaultCurrency();
169
+
170
+                        // Hide if currencies are the same
171
+                        return $billCurrency === $bankCurrency;
172
+                    }),
89 173
                 Forms\Components\Select::make('payment_method')
90 174
                     ->label('Payment method')
91 175
                     ->required()
92 176
                     ->options(PaymentMethod::class),
93
-                Forms\Components\Select::make('bank_account_id')
94
-                    ->label('Account')
95
-                    ->required()
96
-                    ->options(function () {
97
-                        return BankAccount::query()
98
-                            ->join('accounts', 'bank_accounts.account_id', '=', 'accounts.id')
99
-                            ->select(['bank_accounts.id', 'accounts.name'])
100
-                            ->pluck('accounts.name', 'bank_accounts.id')
101
-                            ->toArray();
102
-                    })
103
-                    ->searchable(),
104 177
                 Forms\Components\Textarea::make('notes')
105 178
                     ->label('Notes'),
106 179
             ]);

+ 0
- 8
app/Filament/Company/Resources/Sales/InvoiceResource.php Vedi File

@@ -12,7 +12,6 @@ use App\Enums\Accounting\InvoiceStatus;
12 12
 use App\Enums\Accounting\PaymentMethod;
13 13
 use App\Filament\Company\Resources\Sales\ClientResource\RelationManagers\InvoicesRelationManager;
14 14
 use App\Filament\Company\Resources\Sales\InvoiceResource\Pages;
15
-use App\Filament\Company\Resources\Sales\InvoiceResource\RelationManagers;
16 15
 use App\Filament\Company\Resources\Sales\InvoiceResource\Widgets;
17 16
 use App\Filament\Forms\Components\CreateAdjustmentSelect;
18 17
 use App\Filament\Forms\Components\CreateCurrencySelect;
@@ -705,13 +704,6 @@ class InvoiceResource extends Resource
705 704
             ]);
706 705
     }
707 706
 
708
-    public static function getRelations(): array
709
-    {
710
-        return [
711
-            RelationManagers\PaymentsRelationManager::class,
712
-        ];
713
-    }
714
-
715 707
     public static function getPages(): array
716 708
     {
717 709
         return [

+ 7
- 0
app/Filament/Company/Resources/Sales/InvoiceResource/Pages/ViewInvoice.php Vedi File

@@ -125,4 +125,11 @@ class ViewInvoice extends ViewRecord
125 125
                     ]),
126 126
             ]);
127 127
     }
128
+
129
+    protected function getAllRelationManagers(): array
130
+    {
131
+        return [
132
+            InvoiceResource\RelationManagers\PaymentsRelationManager::class,
133
+        ];
134
+    }
128 135
 }

+ 123
- 44
app/Filament/Company/Resources/Sales/InvoiceResource/RelationManagers/PaymentsRelationManager.php Vedi File

@@ -5,7 +5,6 @@ namespace App\Filament\Company\Resources\Sales\InvoiceResource\RelationManagers;
5 5
 use App\Enums\Accounting\InvoiceStatus;
6 6
 use App\Enums\Accounting\PaymentMethod;
7 7
 use App\Enums\Accounting\TransactionType;
8
-use App\Filament\Company\Resources\Sales\InvoiceResource\Pages\ViewInvoice;
9 8
 use App\Models\Accounting\Invoice;
10 9
 use App\Models\Accounting\Transaction;
11 10
 use App\Models\Banking\BankAccount;
@@ -41,7 +40,7 @@ class PaymentsRelationManager extends RelationManager
41 40
 
42 41
     public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
43 42
     {
44
-        return $ownerRecord->status !== InvoiceStatus::Draft && $pageClass === ViewInvoice::class;
43
+        return $ownerRecord->status !== InvoiceStatus::Draft;
45 44
     }
46 45
 
47 46
     public function form(Form $form): Form
@@ -51,63 +50,143 @@ class PaymentsRelationManager extends RelationManager
51 50
             ->schema([
52 51
                 Forms\Components\DatePicker::make('posted_at')
53 52
                     ->label('Date'),
54
-                Forms\Components\TextInput::make('amount')
55
-                    ->label('Amount')
56
-                    ->required()
57
-                    ->money()
58
-                    ->live(onBlur: true)
59
-                    ->helperText(function (RelationManager $livewire, $state, ?Transaction $record) {
60
-                        if (! CurrencyConverter::isValidAmount($state)) {
53
+                Forms\Components\Grid::make()
54
+                    ->schema([
55
+                        Forms\Components\Select::make('bank_account_id')
56
+                            ->label('Account')
57
+                            ->required()
58
+                            ->live()
59
+                            ->options(function () {
60
+                                return BankAccount::query()
61
+                                    ->join('accounts', 'bank_accounts.account_id', '=', 'accounts.id')
62
+                                    ->select(['bank_accounts.id', 'accounts.name', 'accounts.currency_code'])
63
+                                    ->get()
64
+                                    ->mapWithKeys(function ($account) {
65
+                                        $label = $account->name;
66
+                                        if ($account->currency_code) {
67
+                                            $label .= " ({$account->currency_code})";
68
+                                        }
69
+
70
+                                        return [$account->id => $label];
71
+                                    })
72
+                                    ->toArray();
73
+                            })
74
+                            ->searchable(),
75
+                        Forms\Components\TextInput::make('amount')
76
+                            ->label('Amount')
77
+                            ->required()
78
+                            ->money(function (RelationManager $livewire) {
79
+                                /** @var Invoice $invoice */
80
+                                $invoice = $livewire->getOwnerRecord();
81
+
82
+                                return $invoice->currency_code;
83
+                            })
84
+                            ->live(onBlur: true)
85
+                            ->helperText(function (RelationManager $livewire, $state, ?Transaction $record) {
86
+                                /** @var Invoice $ownerRecord */
87
+                                $ownerRecord = $livewire->getOwnerRecord();
88
+
89
+                                $invoiceCurrency = $ownerRecord->currency_code;
90
+
91
+                                if (! CurrencyConverter::isValidAmount($state, $invoiceCurrency)) {
92
+                                    return null;
93
+                                }
94
+
95
+                                $amountDue = $ownerRecord->getRawOriginal('amount_due');
96
+
97
+                                $amount = CurrencyConverter::convertToCents($state, $invoiceCurrency);
98
+
99
+                                if ($amount <= 0) {
100
+                                    return 'Please enter a valid positive amount';
101
+                                }
102
+
103
+                                $currentPaymentAmount = $record?->getRawOriginal('amount') ?? 0;
104
+
105
+                                if ($ownerRecord->status === InvoiceStatus::Overpaid) {
106
+                                    $newAmountDue = $amountDue + $amount - $currentPaymentAmount;
107
+                                } else {
108
+                                    $newAmountDue = $amountDue - $amount + $currentPaymentAmount;
109
+                                }
110
+
111
+                                return match (true) {
112
+                                    $newAmountDue > 0 => 'Amount due after payment will be ' . CurrencyConverter::formatCentsToMoney($newAmountDue, $invoiceCurrency),
113
+                                    $newAmountDue === 0 => 'Invoice will be fully paid',
114
+                                    default => 'Invoice will be overpaid by ' . CurrencyConverter::formatCentsToMoney(abs($newAmountDue), $invoiceCurrency),
115
+                                };
116
+                            })
117
+                            ->rules([
118
+                                static fn (RelationManager $livewire): Closure => static function (string $attribute, $value, Closure $fail) use ($livewire) {
119
+                                    /** @var Invoice $invoice */
120
+                                    $invoice = $livewire->getOwnerRecord();
121
+
122
+                                    if (! CurrencyConverter::isValidAmount($value, $invoice->currency_code)) {
123
+                                        $fail('Please enter a valid amount');
124
+                                    }
125
+                                },
126
+                            ]),
127
+                    ])->columns(2),
128
+                Forms\Components\Placeholder::make('currency_conversion')
129
+                    ->label('Currency Conversion')
130
+                    ->content(function (Forms\Get $get, RelationManager $livewire) {
131
+                        $amount = $get('amount');
132
+                        $bankAccountId = $get('bank_account_id');
133
+
134
+                        /** @var Invoice $invoice */
135
+                        $invoice = $livewire->getOwnerRecord();
136
+                        $invoiceCurrency = $invoice->currency_code;
137
+
138
+                        if (empty($amount) || empty($bankAccountId) || ! CurrencyConverter::isValidAmount($amount, $invoiceCurrency)) {
139
+                            return null;
140
+                        }
141
+
142
+                        $bankAccount = BankAccount::with('account')->find($bankAccountId);
143
+                        if (! $bankAccount) {
61 144
                             return null;
62 145
                         }
63 146
 
64
-                        /** @var Invoice $ownerRecord */
65
-                        $ownerRecord = $livewire->getOwnerRecord();
147
+                        $bankCurrency = $bankAccount->account->currency_code ?? CurrencyAccessor::getDefaultCurrency();
148
+
149
+                        // If currencies are the same, no conversion needed
150
+                        if ($invoiceCurrency === $bankCurrency) {
151
+                            return null;
152
+                        }
66 153
 
67
-                        $amountDue = $ownerRecord->getRawOriginal('amount_due');
154
+                        // Convert amount from invoice currency to bank currency
155
+                        $amountInInvoiceCurrencyCents = CurrencyConverter::convertToCents($amount, $invoiceCurrency);
156
+                        $amountInBankCurrencyCents = CurrencyConverter::convertBalance(
157
+                            $amountInInvoiceCurrencyCents,
158
+                            $invoiceCurrency,
159
+                            $bankCurrency
160
+                        );
68 161
 
69
-                        $amount = CurrencyConverter::convertToCents($state);
162
+                        $formattedBankAmount = CurrencyConverter::formatCentsToMoney($amountInBankCurrencyCents, $bankCurrency);
70 163
 
71
-                        if ($amount <= 0) {
72
-                            return 'Please enter a valid positive amount';
164
+                        return "Payment will be recorded as {$formattedBankAmount} in the bank account's currency ({$bankCurrency}).";
165
+                    })
166
+                    ->hidden(function (Forms\Get $get, RelationManager $livewire) {
167
+                        $bankAccountId = $get('bank_account_id');
168
+                        if (empty($bankAccountId)) {
169
+                            return true;
73 170
                         }
74 171
 
75
-                        $currentPaymentAmount = $record?->getRawOriginal('amount') ?? 0;
172
+                        /** @var Invoice $invoice */
173
+                        $invoice = $livewire->getOwnerRecord();
174
+                        $invoiceCurrency = $invoice->currency_code;
76 175
 
77
-                        if ($ownerRecord->status === InvoiceStatus::Overpaid) {
78
-                            $newAmountDue = $amountDue + $amount - $currentPaymentAmount;
79
-                        } else {
80
-                            $newAmountDue = $amountDue - $amount + $currentPaymentAmount;
176
+                        $bankAccount = BankAccount::with('account')->find($bankAccountId);
177
+                        if (! $bankAccount) {
178
+                            return true;
81 179
                         }
82 180
 
83
-                        return match (true) {
84
-                            $newAmountDue > 0 => 'Amount due after payment will be ' . CurrencyConverter::formatCentsToMoney($newAmountDue),
85
-                            $newAmountDue === 0 => 'Invoice will be fully paid',
86
-                            default => 'Invoice will be overpaid by ' . CurrencyConverter::formatCentsToMoney(abs($newAmountDue)),
87
-                        };
88
-                    })
89
-                    ->rules([
90
-                        static fn (): Closure => static function (string $attribute, $value, Closure $fail) {
91
-                            if (! CurrencyConverter::isValidAmount($value)) {
92
-                                $fail('Please enter a valid amount');
93
-                            }
94
-                        },
95
-                    ]),
181
+                        $bankCurrency = $bankAccount->account->currency_code ?? CurrencyAccessor::getDefaultCurrency();
182
+
183
+                        // Hide if currencies are the same
184
+                        return $invoiceCurrency === $bankCurrency;
185
+                    }),
96 186
                 Forms\Components\Select::make('payment_method')
97 187
                     ->label('Payment method')
98 188
                     ->required()
99 189
                     ->options(PaymentMethod::class),
100
-                Forms\Components\Select::make('bank_account_id')
101
-                    ->label('Account')
102
-                    ->required()
103
-                    ->options(function () {
104
-                        return BankAccount::query()
105
-                            ->join('accounts', 'bank_accounts.account_id', '=', 'accounts.id')
106
-                            ->select(['bank_accounts.id', 'accounts.name'])
107
-                            ->pluck('accounts.name', 'bank_accounts.id')
108
-                            ->toArray();
109
-                    })
110
-                    ->searchable(),
111 190
                 Forms\Components\Textarea::make('notes')
112 191
                     ->label('Notes'),
113 192
             ]);

Loading…
Annulla
Salva