Skip to content

Commit 5932bce

Browse files
committed
fix zero pdf invoice
1 parent ff9e615 commit 5932bce

File tree

2 files changed

+15
-20
lines changed

2 files changed

+15
-20
lines changed

src/Pdf/PdfInvoice.php

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,50 +133,41 @@ public function subTotalDiscountedAmount(): Money
133133
*/
134134
public function totalTaxAmount(): Money
135135
{
136-
if (empty($this->items)) {
137-
return Money::of(0, $this->getCurrency());
138-
}
139-
140136
$totalDiscount = $this->totalDiscountAmount();
141137

142138
/**
143-
* Taxes must be calculated on the discounted subtotal.
144-
* Since discounts apply at the invoice level and taxes at the item level,
145-
* we allocate the discount across items before computing taxes.
139+
* Taxes must be calculated based on the discounted subtotal.
140+
* Since discounts are applied at the invoice level, but taxes are calculated at the item level,
141+
* we allocate the total discount proportionally across individual items before computing taxes.
146142
*/
147143
$ratios = array_map(
148144
fn ($item) => $item->subTotalAmount()->abs()->getMinorAmount()->toInt(),
149145
$this->items
150146
);
151-
// Check if all ratios are zero
152-
$hasNonZeroRatios = collect($ratios)->filter(fn($ratio) => $ratio > 0)->isNotEmpty();
153-
154-
if ($hasNonZeroRatios) {
155-
// Normal allocation when we have non-zero ratios
156-
$allocatedDiscounts = $totalDiscount->allocate(...$ratios);
157-
} else {
158-
// All items have zero price - return zero amounts for each item
159-
$allocatedDiscounts = collect($ratios)->map(function() use ($totalDiscount) {
160-
return Money::of('0.00', $totalDiscount->getCurrency());
161-
})->toArray();
147+
148+
if (array_sum($ratios) === 0) {
149+
return Money::of(0, $this->getCurrency());
162150
}
163151

152+
$allocatedDiscounts = $totalDiscount->allocate(...$ratios);
153+
164154
$totalTaxAmount = Money::of(0, $this->getCurrency());
165155

166156
foreach ($this->items as $index => $item) {
167157

168158
if ($item->unit_tax) {
169159
/**
170-
* When unit_tax is defined, the amount is considered right
171-
* and the discount is not apply
160+
* When unit_tax is defined, the amount is considered correct
172161
*/
173162
$itemTaxAmount = $item->unit_tax->multipliedBy($item->quantity);
174163
} elseif ($item->tax_percentage) {
164+
175165
$itemDiscount = $allocatedDiscounts[$index];
176166

177167
$itemTaxAmount = $item->subTotalAmount()
178168
->minus($itemDiscount)
179169
->multipliedBy($item->tax_percentage / 100.0, roundingMode: RoundingMode::HALF_EVEN);
170+
180171
} else {
181172
$itemTaxAmount = Money::of(0, $totalTaxAmount->getCurrency());
182173
}

tests/Feature/PdfInvoiceTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
expect($pdfInvoice->totalTaxAmount()->getAmount()->toFloat())->toEqual($totalTaxAmount);
4646
expect($pdfInvoice->totalAmount()->getAmount()->toFloat())->toEqual($totalAmount);
4747
})->with([
48+
[[], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
49+
[[['unit_price' => 0.0]], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
50+
[[['unit_price' => 0.0]], 10.0, 0.0, 0.0, 0.0, 0.0, 0.0],
51+
[[['unit_price' => 0.0]], 10.0, 10.0, 0.0, 0.0, 0.0, 0.0],
4852
[[['unit_price' => 100.0]], 0.0, 0.0, 100.0, 0.0, 0.0, 100.0],
4953
[[['unit_price' => 100.0, 'quantity' => 2]], 0.0, 0.0, 200.0, 0.0, 0.0, 200.0],
5054
[[['unit_price' => 100.0, 'quantity' => 0.1]], 0.0, 0.0, 10.0, 0.0, 0.0, 10.0],

0 commit comments

Comments
 (0)