|
@@ -2,19 +2,14 @@
|
2
|
2
|
|
3
|
3
|
namespace App\View\Models;
|
4
|
4
|
|
5
|
|
-use App\Enums\Accounting\AdjustmentComputation;
|
6
|
|
-use App\Enums\Accounting\DocumentDiscountMethod;
|
7
|
5
|
use App\Enums\Accounting\DocumentType;
|
8
|
|
-use App\Models\Accounting\Adjustment;
|
9
|
6
|
use App\Models\Accounting\DocumentLineItem;
|
10
|
7
|
use App\Models\Common\Client;
|
11
|
8
|
use App\Models\Company;
|
12
|
9
|
use App\Models\Setting\DocumentDefault;
|
13
|
10
|
use App\Utilities\Currency\CurrencyAccessor;
|
14
|
11
|
use App\Utilities\Currency\CurrencyConverter;
|
15
|
|
-use App\Utilities\RateCalculator;
|
16
|
12
|
use Illuminate\Database\Eloquent\Model;
|
17
|
|
-use Illuminate\Support\Number;
|
18
|
13
|
|
19
|
14
|
class DocumentPreviewViewModel
|
20
|
15
|
{
|
|
@@ -120,85 +115,4 @@ class DocumentPreviewViewModel
|
120
|
115
|
'show_logo' => $settings->show_logo ?? false,
|
121
|
116
|
];
|
122
|
117
|
}
|
123
|
|
-
|
124
|
|
- private function calculateLineSubtotalInCents(array $item, string $currencyCode): int
|
125
|
|
- {
|
126
|
|
- $quantity = max((float) ($item['quantity'] ?? 0), 0);
|
127
|
|
- $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
|
128
|
|
-
|
129
|
|
- $subtotal = $quantity * $unitPrice;
|
130
|
|
-
|
131
|
|
- return CurrencyConverter::convertToCents($subtotal, $currencyCode);
|
132
|
|
- }
|
133
|
|
-
|
134
|
|
- private function calculateAdjustmentsTotalInCents($lineItems, string $key, string $currencyCode): int
|
135
|
|
- {
|
136
|
|
- return $lineItems->reduce(function ($carry, $item) use ($key, $currencyCode) {
|
137
|
|
- $quantity = max((float) ($item['quantity'] ?? 0), 0);
|
138
|
|
- $unitPrice = max((float) ($item['unit_price'] ?? 0), 0);
|
139
|
|
- $adjustmentIds = $item[$key] ?? [];
|
140
|
|
- $lineTotal = $quantity * $unitPrice;
|
141
|
|
-
|
142
|
|
- $lineTotalInCents = CurrencyConverter::convertToCents($lineTotal, $currencyCode);
|
143
|
|
-
|
144
|
|
- $adjustmentTotal = Adjustment::whereIn('id', $adjustmentIds)
|
145
|
|
- ->get()
|
146
|
|
- ->sum(function (Adjustment $adjustment) use ($lineTotalInCents) {
|
147
|
|
- if ($adjustment->computation->isPercentage()) {
|
148
|
|
- return RateCalculator::calculatePercentage($lineTotalInCents, $adjustment->getRawOriginal('rate'));
|
149
|
|
- } else {
|
150
|
|
- return $adjustment->getRawOriginal('rate');
|
151
|
|
- }
|
152
|
|
- });
|
153
|
|
-
|
154
|
|
- return $carry + $adjustmentTotal;
|
155
|
|
- }, 0);
|
156
|
|
- }
|
157
|
|
-
|
158
|
|
- private function calculateDiscountTotalInCents($lineItems, int $subtotalInCents, string $currencyCode): int
|
159
|
|
- {
|
160
|
|
- $discountMethod = DocumentDiscountMethod::parse($this->data['discount_method']) ?? DocumentDiscountMethod::PerLineItem;
|
161
|
|
-
|
162
|
|
- if ($discountMethod->isPerLineItem()) {
|
163
|
|
- return $this->calculateAdjustmentsTotalInCents($lineItems, $this->documentType->getDiscountKey(), $currencyCode);
|
164
|
|
- }
|
165
|
|
-
|
166
|
|
- $discountComputation = AdjustmentComputation::parse($this->data['discount_computation']) ?? AdjustmentComputation::Percentage;
|
167
|
|
- $discountRate = blank($this->data['discount_rate']) ? '0' : $this->data['discount_rate'];
|
168
|
|
-
|
169
|
|
- if ($discountComputation->isPercentage()) {
|
170
|
|
- $scaledDiscountRate = RateCalculator::parseLocalizedRate($discountRate);
|
171
|
|
-
|
172
|
|
- return RateCalculator::calculatePercentage($subtotalInCents, $scaledDiscountRate);
|
173
|
|
- }
|
174
|
|
-
|
175
|
|
- if (! CurrencyConverter::isValidAmount($discountRate)) {
|
176
|
|
- $discountRate = '0';
|
177
|
|
- }
|
178
|
|
-
|
179
|
|
- return CurrencyConverter::convertToCents($discountRate, $currencyCode);
|
180
|
|
- }
|
181
|
|
-
|
182
|
|
- private function buildConversionMessage(int $grandTotalInCents, string $currencyCode, string $defaultCurrencyCode): ?string
|
183
|
|
- {
|
184
|
|
- if ($currencyCode === $defaultCurrencyCode) {
|
185
|
|
- return null;
|
186
|
|
- }
|
187
|
|
-
|
188
|
|
- $rate = currency($currencyCode)->getRate();
|
189
|
|
- $indirectRate = 1 / $rate;
|
190
|
|
-
|
191
|
|
- $convertedTotalInCents = CurrencyConverter::convertBalance($grandTotalInCents, $currencyCode, $defaultCurrencyCode);
|
192
|
|
-
|
193
|
|
- $formattedRate = Number::format($indirectRate, maxPrecision: 10);
|
194
|
|
-
|
195
|
|
- return sprintf(
|
196
|
|
- 'Currency conversion: %s (%s) at an exchange rate of 1 %s = %s %s',
|
197
|
|
- CurrencyConverter::formatCentsToMoney($convertedTotalInCents, $defaultCurrencyCode),
|
198
|
|
- $defaultCurrencyCode,
|
199
|
|
- $currencyCode,
|
200
|
|
- $formattedRate,
|
201
|
|
- $defaultCurrencyCode
|
202
|
|
- );
|
203
|
|
- }
|
204
|
118
|
}
|