From cb5e3a47f6d9aa6595626f1579259714d35833a9 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 08:50:37 +0100 Subject: [PATCH] fix tax handling, add functional cest for cart --- .../views/sales/orders/view.blade.php | 4 +- packages/Webkul/Checkout/src/Cart.php | 13 +- .../Core/src/Helpers/Laravel5Helper.php | 2 +- .../ProductAttributeValueFactory.php | 2 +- .../views/checkout/total/summary.blade.php | 4 +- .../emails/sales/new-admin-order.blade.php | 2 +- .../views/emails/sales/new-invoice.blade.php | 2 +- .../views/emails/sales/new-order.blade.php | 2 +- .../views/emails/sales/new-refund.blade.php | 4 +- .../views/emails/sales/order-cancel.blade.php | 2 +- .../Database/Factories/TaxCategoryFactory.php | 17 +++ .../src/Database/Factories/TaxMapFactory.php | 19 +++ .../src/Database/Factories/TaxRateFactory.php | 19 +++ .../{Checkout => Tax}/src/Helpers/Tax.php | 17 ++- .../Tax/src/Providers/TaxServiceProvider.php | 13 ++ tests/functional/Shop/CartCest.php | 114 ++++++++++++++++++ tests/functional/Shop/GuestCheckoutCest.php | 2 +- 17 files changed, 217 insertions(+), 21 deletions(-) create mode 100644 packages/Webkul/Tax/src/Database/Factories/TaxCategoryFactory.php create mode 100644 packages/Webkul/Tax/src/Database/Factories/TaxMapFactory.php create mode 100644 packages/Webkul/Tax/src/Database/Factories/TaxRateFactory.php rename packages/Webkul/{Checkout => Tax}/src/Helpers/Tax.php (61%) create mode 100644 tests/functional/Shop/CartCest.php diff --git a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php index 499fbfe74..8787b2767 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php @@ -344,12 +344,12 @@ @endif - @php ($taxRates = Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, true)) + @php ($taxRates = Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, true)) @foreach ($taxRates as $taxRate => $baseTaxAmount) last ? 'class=border' : ''}}> {{ __('admin::app.sales.orders.tax') }} {{ $taxRate }} % - - {{ core()->formatBasePrice($baseTaxAmount) }} + {{ core()->formatBasePrice($baseTaxAmount) }} @endforeach diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index c6eca6000..28021ecde 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -7,6 +7,7 @@ use Webkul\Checkout\Repositories\CartItemRepository; use Webkul\Checkout\Repositories\CartAddressRepository; use Webkul\Customer\Models\CustomerAddress; use Webkul\Product\Repositories\ProductRepository; +use Webkul\Tax\Helpers\Tax; use Webkul\Tax\Repositories\TaxCategoryRepository; use Webkul\Checkout\Models\CartItem; use Webkul\Checkout\Models\CartPayment; @@ -675,16 +676,16 @@ class Cart $cart->discount_amount += $item->discount_amount; $cart->base_discount_amount += $item->base_discount_amount; - $cart->grand_total = (float)$cart->grand_total + $item->total + $item->tax_amount - $item->discount_amount; - $cart->base_grand_total = (float)$cart->base_grand_total + $item->base_total + $item->base_tax_amount - $item->base_discount_amount; - $cart->sub_total = (float)$cart->sub_total + $item->total; $cart->base_sub_total = (float)$cart->base_sub_total + $item->base_total; - - $cart->tax_total = (float)$cart->tax_total + $item->tax_amount; - $cart->base_tax_total = (float)$cart->base_tax_total + $item->base_tax_amount; } + $cart->tax_total = Tax::getTaxTotal($cart, false); + $cart->base_tax_total = Tax::getTaxTotal($cart, true); + + $cart->grand_total = $cart->sub_total + $cart->tax_total + $cart->discount_amount; + $cart->base_grand_total = $cart->base_sub_total + $cart->base_tax_total - $cart->base_discount_amount; + if ($shipping = $cart->selected_shipping_rate) { $cart->grand_total = (float)$cart->grand_total + $shipping->price - $shipping->discount_amount; $cart->base_grand_total = (float)$cart->base_grand_total + $shipping->base_price - $shipping->base_discount_amount; diff --git a/packages/Webkul/Core/src/Helpers/Laravel5Helper.php b/packages/Webkul/Core/src/Helpers/Laravel5Helper.php index 7b8cfb7f2..1d212ab80 100644 --- a/packages/Webkul/Core/src/Helpers/Laravel5Helper.php +++ b/packages/Webkul/Core/src/Helpers/Laravel5Helper.php @@ -68,7 +68,7 @@ class Laravel5Helper extends Laravel5 ): Product { $I = $this; /** @var Product $product */ - $product = factory(Product::class)->states($productStates)->create($configs['productAttributes'] ?? []);; + $product = factory(Product::class)->states($productStates)->create($configs['productAttributes'] ?? []); $I->createAttributeValues($product->id,$configs['attributeValues'] ?? []); $I->have(ProductInventory::class, array_merge($configs['productInventory'] ?? [], [ 'product_id' => $product->id, diff --git a/packages/Webkul/Product/src/Database/Factories/ProductAttributeValueFactory.php b/packages/Webkul/Product/src/Database/Factories/ProductAttributeValueFactory.php index 4da6ddaf0..cf06abca4 100644 --- a/packages/Webkul/Product/src/Database/Factories/ProductAttributeValueFactory.php +++ b/packages/Webkul/Product/src/Database/Factories/ProductAttributeValueFactory.php @@ -42,7 +42,7 @@ $factory->defineAs(ProductAttributeValue::class, 'tax_category_id', function (Fa return factory(Product::class)->create()->id; }, 'channel' => 'default', - 'integer_value' => null, // ToDo + 'integer_value' => null, 'attribute_id' => 4, ]; }); diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php index c1feb3508..e492cb91f 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php @@ -18,10 +18,10 @@ @endif @if ($cart->base_tax_total) - @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($cart, false) as $taxRate => $taxAmount ) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($cart, true) as $taxRate => $baseTaxAmount )
- +
@endforeach @endif diff --git a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-admin-order.blade.php b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-admin-order.blade.php index a3b952743..7e077768b 100644 --- a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-admin-order.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-admin-order.blade.php @@ -161,7 +161,7 @@ - @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, true) as $taxRate => $baseTaxAmount ) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, true) as $taxRate => $baseTaxAmount )
{{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % diff --git a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-invoice.blade.php b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-invoice.blade.php index 8cba444fe..b8f70beaa 100755 --- a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-invoice.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-invoice.blade.php @@ -156,7 +156,7 @@
@endif - @foreach ($order->getTaxRatesWithAmount(false) as $taxRate => $taxAmount) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($refund, false) as $taxRate => $taxAmount)
{{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % diff --git a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-order.blade.php b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-order.blade.php index f2ca139b0..8089ce37a 100755 --- a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-order.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-order.blade.php @@ -156,7 +156,7 @@
@endif - @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount ) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount )
{{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % diff --git a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-refund.blade.php b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-refund.blade.php index 604d2f65b..8bd270795 100644 --- a/packages/Webkul/Shop/src/Resources/views/emails/sales/new-refund.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/emails/sales/new-refund.blade.php @@ -158,14 +158,16 @@
@endif -@php(//ToDo: taxes) + @if ($refund->tax_amount > 0) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($refund, false) as $taxRate => $taxAmount)
{{ __('shop::app.mail.order.tax') }} {{ core()->formatPrice($refund->tax_amount, $refund->order_currency_code) }}
+ @endforeach @endif @if ($refund->discount_amount > 0) diff --git a/packages/Webkul/Shop/src/Resources/views/emails/sales/order-cancel.blade.php b/packages/Webkul/Shop/src/Resources/views/emails/sales/order-cancel.blade.php index 19e677626..c3b007370 100644 --- a/packages/Webkul/Shop/src/Resources/views/emails/sales/order-cancel.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/emails/sales/order-cancel.blade.php @@ -157,7 +157,7 @@ - @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount ) + @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount )
{{ __('shop::app.mail.order.cancel.tax') }} {{ $taxRate }} % diff --git a/packages/Webkul/Tax/src/Database/Factories/TaxCategoryFactory.php b/packages/Webkul/Tax/src/Database/Factories/TaxCategoryFactory.php new file mode 100644 index 000000000..b704d1d84 --- /dev/null +++ b/packages/Webkul/Tax/src/Database/Factories/TaxCategoryFactory.php @@ -0,0 +1,17 @@ +define(TaxCategory::class, function (Faker $faker) { + return [ + 'channel_id' => function () { + return core()->getCurrentChannel()->id; + }, + 'code' => $faker->uuid, + 'name' => $faker->words(2, true), + 'description' => $faker->sentence(10), + ]; +}); diff --git a/packages/Webkul/Tax/src/Database/Factories/TaxMapFactory.php b/packages/Webkul/Tax/src/Database/Factories/TaxMapFactory.php new file mode 100644 index 000000000..7e7d50769 --- /dev/null +++ b/packages/Webkul/Tax/src/Database/Factories/TaxMapFactory.php @@ -0,0 +1,19 @@ +define(TaxMap::class, function (Faker $faker) { + return [ + 'tax_category_id' => function () { + return factory(TaxCategory::class)->create()->id; + }, + 'tax_rate_id' => function () { + return factory(TaxRate::class)->create()->id; + }, + ]; +}); diff --git a/packages/Webkul/Tax/src/Database/Factories/TaxRateFactory.php b/packages/Webkul/Tax/src/Database/Factories/TaxRateFactory.php new file mode 100644 index 000000000..a611bebc0 --- /dev/null +++ b/packages/Webkul/Tax/src/Database/Factories/TaxRateFactory.php @@ -0,0 +1,19 @@ +define(TaxRate::class, function (Faker $faker) { + return [ + 'identifier' => $faker->uuid, + 'is_zip' => 0, + 'zip_code' => '*', + 'zip_from' => null, + 'zip_to' => null, + 'state' => '', + 'country' => $faker->countryCode, + 'tax_rate' => $faker->randomFloat(2, 3, 25), + ]; +}); diff --git a/packages/Webkul/Checkout/src/Helpers/Tax.php b/packages/Webkul/Tax/src/Helpers/Tax.php similarity index 61% rename from packages/Webkul/Checkout/src/Helpers/Tax.php rename to packages/Webkul/Tax/src/Helpers/Tax.php index 2b4a28523..908aa8be7 100644 --- a/packages/Webkul/Checkout/src/Helpers/Tax.php +++ b/packages/Webkul/Tax/src/Helpers/Tax.php @@ -1,19 +1,19 @@ items as $item) { @@ -28,4 +28,15 @@ class Tax return $taxes; } + + public static function getTaxTotal(object $that, bool $asBase = false): float + { + $taxes = self::getTaxRatesWithAmount($that, $asBase); + + $result = 0; + foreach ($taxes as $taxRate => $taxAmount) { + $result += round($taxAmount, 2); + } + return $result; + } } \ No newline at end of file diff --git a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php index 9f67df0df..047ec84b4 100755 --- a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php +++ b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php @@ -2,6 +2,7 @@ namespace Webkul\Tax\Providers; use Illuminate\Support\ServiceProvider; +use Illuminate\Database\Eloquent\Factory as EloquentFactory; class TaxServiceProvider extends ServiceProvider { @@ -22,5 +23,17 @@ class TaxServiceProvider extends ServiceProvider */ public function register() { + $this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories'); + } + + /** + * Register factories. + * + * @param string $path + * @return void + */ + protected function registerEloquentFactoriesFrom($path): void + { + $this->app->make(EloquentFactory::class)->load($path); } } \ No newline at end of file diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php new file mode 100644 index 000000000..87f9aa131 --- /dev/null +++ b/tests/functional/Shop/CartCest.php @@ -0,0 +1,114 @@ +faker = Factory::create(); + + $this->country = 'DE'; //$this->faker->countryCode; + + $this->tax1 = $I->have(TaxRate::class, ['tax_rate' => 7.00, 'country' => $this->country]); + $taxCategorie1 = $I->have(TaxCategory::class, []); + $I->have(TaxMap::class, ['tax_rate_id' => $this->tax1->id, 'tax_category_id' => $taxCategorie1->id]); + + $this->tax2 = $I->have(TaxRate::class, ['tax_rate' => 19.00, 'country' => $this->country]); + $taxCategorie2 = $I->have(TaxCategory::class, []); + $I->have(TaxMap::class, ['tax_rate_id' => $this->tax2->id, 'tax_category_id' => $taxCategorie2->id]); + + $config1 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie1->id, + ], + ]; + $this->product1 = $I->haveProduct($config1, ['simple']); + + $config2 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie2->id, + ], + ]; + $this->product2 = $I->haveProduct($config2, ['simple']); + } + + public function checkCartWithMultipleTaxRates(FunctionalTester $I) + { + $I->setConfigData(['default_country' => $this->country]); + + $prod1Quantity = $this->faker->numberBetween(9, 30); + if ($prod1Quantity % 2 !== 0) { + $prod1Quantity -= 1; + } + + $prod2Quantity = $this->faker->numberBetween(9, 30); + if ($prod2Quantity % 2 == 0) { + $prod2Quantity -= 1; + } + + Cart::addProduct($this->product1->id, [ + '_token' => session('_token'), + 'product_id' => $this->product1->id, + 'quantity' => 1, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . $this->tax1->tax_rate); + $I->see(round($this->product1->price * $this->tax1->tax_rate / 100, 2), + '#basetaxamount-' . $this->tax1->tax_rate); + + Cart::addProduct($this->product1->id, [ + '_token' => session('_token'), + 'product_id' => $this->product1->id, + 'quantity' => $prod1Quantity, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . $this->tax1->tax_rate); + $I->see(round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2), + '#basetaxamount-' . $this->tax1->tax_rate); + + Cart::addProduct($this->product2->id, [ + '_token' => session('_token'), + 'product_id' => $this->product2->id, + 'quantity' => $prod2Quantity, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . $this->tax1->tax_rate); + $taxAmount1 = round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount1),'#basetaxamount-' . $this->tax1->tax_rate); + + $I->see('Tax ' . $this->tax2->tax_rate . ' %', '#taxrate-' . $this->tax2->tax_rate); + $taxAmount2 = round($prod2Quantity * $this->product2->price * $this->tax2->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount2),'#basetaxamount-' . $this->tax2->tax_rate); + + $cart = Cart::getCart(); + + $I->assertEquals(2, $cart->items_count); + $I->assertEquals((float)($prod1Quantity + 1 + $prod2Quantity), $cart->items_qty); + $I->assertEquals($taxAmount1 + $taxAmount2, $cart->tax_total); + + + } +} \ No newline at end of file diff --git a/tests/functional/Shop/GuestCheckoutCest.php b/tests/functional/Shop/GuestCheckoutCest.php index ea712b673..94e2e4e6e 100644 --- a/tests/functional/Shop/GuestCheckoutCest.php +++ b/tests/functional/Shop/GuestCheckoutCest.php @@ -1,6 +1,6 @@