Skip to content

Commit abbafb3

Browse files
[7.x] Correct tax calculations when "Prices include tax" is false (standard tax engine) (#1234)
* Fix Tax Calculation with $taxRate->includeInPrice true Tax calculation was not correct when $taxRate->includeInPrice set to true. * fix style * fix style, added test On my shop I show all prices without VAT because it is a B2B Site and the Tax is added at checkout. A Product costs 100 Euro (without Tax) and the cart should show 119 Euro total (with 19 % Tax) Previously the StandardTaxEngine calculates a total of 116 Euro which is wrong. I added a Test for this Issue, in 5 of the older tests with 'price_includes_tax' => false the expected numbers are not right. * Update test to reflect actual numbers * Fix shipping tax calculation * Correct assertions in tests --------- Co-authored-by: Duncan McClean <duncan@duncanmcclean.com>
1 parent 025bb36 commit abbafb3

2 files changed

Lines changed: 90 additions & 12 deletions

File tree

src/Tax/Standard/TaxEngine.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ public function calculateForLineItem(Order $order, LineItem $lineItem): TaxCalcu
3838
}
3939
}
4040

41-
$taxAmount = ($lineItem->total() / 100) * ($taxRate->rate() / (100 + $taxRate->rate()));
41+
if ($taxRate->includeInPrice()) {
42+
$taxAmount = ($lineItem->total() / 100) * ($taxRate->rate() / (100 + $taxRate->rate()));
43+
} else {
44+
$taxAmount = ($lineItem->total() / 100) * ($taxRate->rate() / 100);
45+
}
46+
4247
$itemTax = (int) round($taxAmount * 100);
4348

4449
return new TaxCalculation($itemTax, $taxRate->rate(), $taxRate->includeInPrice());
@@ -115,7 +120,12 @@ public function calculateForShipping(Order $order, ShippingMethod $shippingMetho
115120
}
116121
}
117122

118-
$taxAmount = ($order->shippingTotal() / 100) * ($taxRate->rate() / (100 + $taxRate->rate()));
123+
if ($taxRate->includeInPrice()) {
124+
$taxAmount = ($order->shippingTotal() / 100) * ($taxRate->rate() / (100 + $taxRate->rate()));
125+
} else {
126+
$taxAmount = ($order->shippingTotal() / 100) * ($taxRate->rate() / 100);
127+
}
128+
119129
$itemTax = (int) round($taxAmount * 100);
120130

121131
return new TaxCalculation($itemTax, $taxRate->rate(), $taxRate->includeInPrice());

tests/Tax/StandardTaxEngineTest.php

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@
9595

9696
// Ensure tax on line items are right
9797
$this->assertSame($recalculate->lineItems()->first()->tax(), [
98-
'amount' => 167,
98+
'amount' => 200,
9999
'rate' => 20,
100100
'price_includes_tax' => false,
101101
]);
102102

103103
// Ensure global order tax is right
104-
expect(167)->toBe($recalculate->taxTotal());
104+
expect(200)->toBe($recalculate->taxTotal());
105105
});
106106

107107
test('can correctly calculate line item tax rate based on region', function () {
@@ -164,13 +164,13 @@
164164

165165
// Ensure tax on line items are right
166166
$this->assertSame($recalculate->lineItems()->first()->tax(), [
167-
'amount' => 130,
167+
'amount' => 150,
168168
'rate' => 15,
169169
'price_includes_tax' => false,
170170
]);
171171

172172
// Ensure global order tax is right
173-
expect(130)->toBe($recalculate->taxTotal());
173+
expect(150)->toBe($recalculate->taxTotal());
174174
});
175175

176176
test('can correctly calculate line item tax rate when address has region but no addresses have a region', function () {
@@ -237,13 +237,13 @@
237237

238238
// Ensure tax on line items are right
239239
$this->assertSame($recalculate->lineItems()->first()->tax(), [
240-
'amount' => 130,
240+
'amount' => 150,
241241
'rate' => 15,
242242
'price_includes_tax' => false,
243243
]);
244244

245245
// Ensure global order tax is right
246-
expect(130)->toBe($recalculate->taxTotal());
246+
expect(150)->toBe($recalculate->taxTotal());
247247
});
248248

249249
test('can correctly calculate line item tax zones when tax rates exists both with and without region', function () {
@@ -328,13 +328,13 @@
328328

329329
// Ensure tax on line items are right
330330
$this->assertSame($recalculate->lineItems()->first()->tax(), [
331-
'amount' => 130,
331+
'amount' => 150,
332332
'rate' => 15,
333333
'price_includes_tax' => false,
334334
]);
335335

336336
// Ensure global order tax is right
337-
expect(130)->toBe($recalculate->taxTotal());
337+
expect(150)->toBe($recalculate->taxTotal());
338338
});
339339

340340
test('can calculate line item tax rate when included in price', function () {
@@ -756,11 +756,79 @@
756756

757757
// Ensure tax on line items are right
758758
$this->assertSame($recalculate->lineItems()->first()->tax(), [
759-
'amount' => 170,
759+
'amount' => 205,
760760
'rate' => 20.5,
761761
'price_includes_tax' => false,
762762
]);
763763

764764
// Ensure global order tax is right
765-
expect(170)->toBe($recalculate->taxTotal());
765+
expect(205)->toBe($recalculate->taxTotal());
766+
});
767+
768+
// https://github.com/duncanmcclean/simple-commerce/issues/1234
769+
test('can calculate line item tax rate when excluded in price', function () {
770+
Config::set('simple-commerce.tax_engine', StandardTaxEngine::class);
771+
772+
Config::set('simple-commerce.tax_engine_config', [
773+
'address' => 'billing',
774+
]);
775+
776+
$taxCategory = TaxCategory::make()
777+
->id('vat')
778+
->name('VAT');
779+
780+
$taxCategory->save();
781+
782+
$taxZone = TaxZone::make()
783+
->id('germany')
784+
->name('Germany')
785+
->country('DE');
786+
787+
$taxZone->save();
788+
789+
$taxRate = TaxRate::make()
790+
->id('vat')
791+
->name('VAT')
792+
->rate(19)
793+
->category($taxCategory->id())
794+
->zone($taxZone->id())
795+
->includeInPrice(false);
796+
797+
$taxRate->save();
798+
799+
$product = Product::make()
800+
->price(10000)
801+
->taxCategory($taxCategory->id())
802+
->data([
803+
'title' => 'Cat Food',
804+
]);
805+
806+
$product->save();
807+
808+
$order = Order::make()->lineItems([
809+
[
810+
'id' => app('stache')->generateId(),
811+
'product' => $product->id,
812+
'quantity' => 1,
813+
'total' => 1000,
814+
],
815+
])->merge([
816+
'billing_address' => '1 Test Street',
817+
'billing_country' => 'DE',
818+
'use_shipping_address_for_billing' => false,
819+
]);
820+
821+
$order->save();
822+
823+
$recalculate = $order->recalculate();
824+
825+
// Ensure tax on line items are right
826+
$this->assertSame($recalculate->lineItems()->first()->tax(), [
827+
'amount' => 1900,
828+
'rate' => 19,
829+
'price_includes_tax' => false,
830+
]);
831+
832+
// Ensure global order tax is right
833+
expect(1900)->toBe($recalculate->taxTotal());
766834
});

0 commit comments

Comments
 (0)