From 8abce3302a54848494142011075cbb44f9dd9013 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Fri, 31 Jan 2020 16:08:01 +0100 Subject: [PATCH 01/16] tax helper introduced, views changed to display multiple tax rates --- config/app.php | 2 +- .../views/sales/orders/view.blade.php | 11 +- packages/Webkul/Checkout/src/Cart.php | 375 ++++++++++-------- packages/Webkul/Checkout/src/Helpers/Tax.php | 31 ++ .../views/checkout/total/summary.blade.php | 6 +- .../emails/sales/new-admin-order.blade.php | 10 +- .../views/emails/sales/new-invoice.blade.php | 18 +- .../views/emails/sales/new-order.blade.php | 12 +- .../views/emails/sales/new-refund.blade.php | 6 +- .../views/emails/sales/order-cancel.blade.php | 14 +- 10 files changed, 297 insertions(+), 188 deletions(-) create mode 100644 packages/Webkul/Checkout/src/Helpers/Tax.php diff --git a/config/app.php b/config/app.php index a3cf7f964..1f0b07847 100755 --- a/config/app.php +++ b/config/app.php @@ -104,7 +104,7 @@ return [ | */ - 'default_country' => null, + 'default_country' => 'DE', /* |-------------------------------------------------------------------------- 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 a1b28cbd0..499fbfe74 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 @@ -266,7 +266,7 @@ @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -344,11 +344,14 @@ @endif - - {{ __('admin::app.sales.orders.tax') }} + @php ($taxRates = Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, true)) + @foreach ($taxRates as $taxRate => $baseTaxAmount) + last ? 'class=border' : ''}}> + {{ __('admin::app.sales.orders.tax') }} {{ $taxRate }} % - - {{ core()->formatBasePrice($order->base_tax_amount) }} + {{ core()->formatBasePrice($baseTaxAmount) }} + @endforeach {{ __('admin::app.sales.orders.grand-total') }} diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 9157dc392..c6eca6000 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -5,6 +5,7 @@ namespace Webkul\Checkout; use Webkul\Checkout\Repositories\CartRepository; use Webkul\Checkout\Repositories\CartItemRepository; use Webkul\Checkout\Repositories\CartAddressRepository; +use Webkul\Customer\Models\CustomerAddress; use Webkul\Product\Repositories\ProductRepository; use Webkul\Tax\Repositories\TaxCategoryRepository; use Webkul\Checkout\Models\CartItem; @@ -14,6 +15,17 @@ use Webkul\Customer\Repositories\CustomerAddressRepository; use Illuminate\Support\Facades\Event; use Illuminate\Support\Arr; +class addressHelper +{ + public $country; + public $postcode; + + function __construct() + { + $this->country = config('app.default_country'); + } +} + /** * Facades handler for all the methods to be implemented in Cart. * @@ -21,7 +33,8 @@ use Illuminate\Support\Arr; * @author Jitendra Singh * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) */ -class Cart { +class Cart +{ /** * CartRepository instance @@ -75,15 +88,16 @@ class Cart { /** * Create a new controller instance. * - * @param Webkul\Checkout\Repositories\CartRepository $cart - * @param Webkul\Checkout\Repositories\CartItemRepository $cartItem - * @param Webkul\Checkout\Repositories\CartAddressRepository $cartAddress - * @param Webkul\Product\Repositories\ProductRepository $product - * @param Webkul\Product\Repositories\TaxCategoryRepository $taxCategory - * @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress - * @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress - * @param Webkul\Discount\Repositories\CartRuleRepository $cartRule - * @param Webkul\Helpers\Discount $discount + * @param Webkul\Checkout\Repositories\CartRepository $cart + * @param Webkul\Checkout\Repositories\CartItemRepository $cartItem + * @param Webkul\Checkout\Repositories\CartAddressRepository $cartAddress + * @param Webkul\Product\Repositories\ProductRepository $product + * @param Webkul\Product\Repositories\TaxCategoryRepository $taxCategory + * @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress + * @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress + * @param Webkul\Discount\Repositories\CartRuleRepository $cartRule + * @param Webkul\Helpers\Discount $discount + * * @return void */ public function __construct( @@ -94,8 +108,7 @@ class Cart { TaxCategoryRepository $taxCategoryRepository, WishlistRepository $wishlistRepository, CustomerAddressRepository $customerAddressRepository - ) - { + ) { $this->cartRepository = $cartRepository; $this->cartItemRepository = $cartItemRepository; @@ -128,6 +141,7 @@ class Cart { * * @param integer $productId * @param array $data + * * @return Cart */ public function addProduct($productId, $data) @@ -136,8 +150,9 @@ class Cart { $cart = $this->getCart(); - if (! $cart && ! $cart = $this->create($data)) + if (!$cart && !$cart = $this->create($data)) { return; + } $product = $this->productRepository->findOneByField('id', $productId); @@ -146,7 +161,7 @@ class Cart { if (is_string($cartProducts)) { $this->collectTotals(); - if (! count($cart->all_items) > 0) { + if (!count($cart->all_items) > 0) { session()->forget('cart'); } @@ -157,21 +172,24 @@ class Cart { foreach ($cartProducts as $cartProduct) { $cartItem = $this->getItemByProduct($cartProduct); - if (isset($cartProduct['parent_id'])) + if (isset($cartProduct['parent_id'])) { $cartProduct['parent_id'] = $parentCartItem->id; + } - if (! $cartItem) { + if (!$cartItem) { $cartItem = $this->cartItemRepository->create(array_merge($cartProduct, ['cart_id' => $cart->id])); } else { if (isset($cartProduct['parent_id']) && $cartItem->parent_id != $parentCartItem->id) { - $cartItem = $this->cartItemRepository->create(array_merge($cartProduct, ['cart_id' => $cart->id])); + $cartItem = $this->cartItemRepository->create(array_merge($cartProduct, + ['cart_id' => $cart->id])); } else { $cartItem = $this->cartItemRepository->update($cartProduct, $cartItem->id); } } - if (! $parentCartItem) + if (!$parentCartItem) { $parentCartItem = $cartItem; + } } } @@ -186,17 +204,18 @@ class Cart { * Create new cart instance. * * @param array $data + * * @return Cart|null */ public function create($data) { $cartData = [ - 'channel_id' => core()->getCurrentChannel()->id, - 'global_currency_code' => core()->getBaseCurrencyCode(), - 'base_currency_code' => core()->getBaseCurrencyCode(), + 'channel_id' => core()->getCurrentChannel()->id, + 'global_currency_code' => core()->getBaseCurrencyCode(), + 'base_currency_code' => core()->getBaseCurrencyCode(), 'channel_currency_code' => core()->getChannelBaseCurrencyCode(), - 'cart_currency_code' => core()->getCurrentCurrencyCode(), - 'items_count' => 1 + 'cart_currency_code' => core()->getCurrentCurrencyCode(), + 'items_count' => 1, ]; //Authentication details @@ -212,7 +231,7 @@ class Cart { $cart = $this->cartRepository->create($cartData); - if (! $cart) { + if (!$cart) { session()->flash('error', trans('shop::app.checkout.cart.create-error')); return; @@ -235,8 +254,9 @@ class Cart { foreach ($data['qty'] as $itemId => $quantity) { $item = $this->cartItemRepository->findOneByField('id', $itemId); - if (! $item) + if (!$item) { continue; + } if ($quantity <= 0) { $this->removeItem($itemId); @@ -246,18 +266,19 @@ class Cart { $item->quantity = $quantity; - if (! $this->isItemHaveQuantity($item)) + if (!$this->isItemHaveQuantity($item)) { throw new \Exception(trans('shop::app.checkout.cart.quantity.inventory_warning')); + } Event::dispatch('checkout.cart.update.before', $item); $this->cartItemRepository->update([ - 'quantity' => $quantity, - 'total' => core()->convertPrice($item->price * $quantity), - 'base_total' => $item->price * $quantity, - 'total_weight' => $item->weight * $quantity, - 'base_total_weight' => $item->weight * $quantity - ], $itemId); + 'quantity' => $quantity, + 'total' => core()->convertPrice($item->price * $quantity), + 'base_total' => $item->price * $quantity, + 'total_weight' => $item->weight * $quantity, + 'base_total_weight' => $item->weight * $quantity, + ], $itemId); Event::dispatch('checkout.cart.update.after', $item); } @@ -271,6 +292,7 @@ class Cart { * Get cart item by product * * @param array $data + * * @return CartItem|void */ public function getItemByProduct($data) @@ -280,8 +302,10 @@ class Cart { foreach ($items as $item) { if ($item->product->getTypeInstance()->compareOptions($item->additional, $data['additional'])) { if (isset($data['additional']['parent_id'])) { - if ($item->parent->product->getTypeInstance()->compareOptions($item->parent->additional, request()->all())) + if ($item->parent->product->getTypeInstance()->compareOptions($item->parent->additional, + request()->all())) { return $item; + } } else { return $item; } @@ -293,14 +317,16 @@ class Cart { * Remove the item from the cart * * @param integer $itemId + * * @return boolean */ public function removeItem($itemId) { Event::dispatch('checkout.cart.delete.before', $itemId); - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } $this->cartItemRepository->delete($itemId); @@ -328,18 +354,21 @@ class Cart { public function mergeCart() { if (session()->has('cart')) { - $cart = $this->cartRepository->findOneWhere(['customer_id' => $this->getCurrentCustomer()->user()->id, 'is_active' => 1]); + $cart = $this->cartRepository->findOneWhere([ + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'is_active' => 1, + ]); $guestCart = session()->get('cart'); //when the logged in customer is not having any of the cart instance previously and are active. - if (! $cart) { + if (!$cart) { $this->cartRepository->update([ - 'customer_id' => $this->getCurrentCustomer()->user()->id, - 'is_guest' => 0, + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'is_guest' => 0, 'customer_first_name' => $this->getCurrentCustomer()->user()->first_name, - 'customer_last_name' => $this->getCurrentCustomer()->user()->last_name, - 'customer_email' => $this->getCurrentCustomer()->user()->email + 'customer_last_name' => $this->getCurrentCustomer()->user()->last_name, + 'customer_email' => $this->getCurrentCustomer()->user()->email, ], $guestCart->id); session()->forget('cart'); @@ -352,23 +381,25 @@ class Cart { $found = false; foreach ($cart->items as $cartItem) { - if (! $cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, $guestCartItem->additional)) + if (!$cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, + $guestCartItem->additional)) { continue; + } $cartItem->quantity = $newQuantity = $cartItem->quantity + $guestCartItem->quantity; - if (! $this->isItemHaveQuantity($cartItem)) { + if (!$this->isItemHaveQuantity($cartItem)) { $this->cartItemRepository->delete($guestCartItem->id); continue; } $this->cartItemRepository->update([ - 'quantity' => $newQuantity, - 'total' => core()->convertPrice($cartItem->price * $newQuantity), - 'base_total' => $cartItem->price * $newQuantity, - 'total_weight' => $cartItem->weight * $newQuantity, - 'base_total_weight' => $cartItem->weight * $newQuantity + 'quantity' => $newQuantity, + 'total' => core()->convertPrice($cartItem->price * $newQuantity), + 'base_total' => $cartItem->price * $newQuantity, + 'total_weight' => $cartItem->weight * $newQuantity, + 'base_total_weight' => $cartItem->weight * $newQuantity, ], $cartItem->id); $guestCart->items->forget($key); @@ -378,14 +409,14 @@ class Cart { $found = true; } - if (! $found) { + if (!$found) { $this->cartItemRepository->update([ - 'cart_id' => $cart->id + 'cart_id' => $cart->id, ], $guestCartItem->id); foreach ($guestCartItem->children as $child) { $this->cartItemRepository->update([ - 'cart_id' => $cart->id + 'cart_id' => $cart->id, ], $child->id); } } @@ -405,11 +436,12 @@ class Cart { * Save cart * * @param Cart $cart + * * @return void */ public function putCart($cart) { - if (! $this->getCurrentCustomer()->check()) { + if (!$this->getCurrentCustomer()->check()) { session()->put('cart', $cart); } } @@ -426,7 +458,7 @@ class Cart { if ($this->getCurrentCustomer()->check()) { $cart = $this->cartRepository->findOneWhere([ 'customer_id' => $this->getCurrentCustomer()->user()->id, - 'is_active' => 1 + 'is_active' => 1, ]); } elseif (session()->has('cart')) { $cart = $this->cartRepository->find(session()->get('cart')->id); @@ -465,18 +497,20 @@ class Cart { * Save customer address * * @param array $data + * * @return boolean */ public function saveCustomerAddress($data) { - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } $billingAddress = $data['billing']; $billingAddress['cart_id'] = $cart->id; if (isset($data['billing']['address_id']) && $data['billing']['address_id']) { - $address = $this->customerAddressRepository->findOneWhere(['id'=> $data['billing']['address_id']])->toArray(); + $address = $this->customerAddressRepository->findOneWhere(['id' => $data['billing']['address_id']])->toArray(); $billingAddress['first_name'] = $this->getCurrentCustomer()->user()->first_name; $billingAddress['last_name'] = $this->getCurrentCustomer()->user()->last_name; @@ -490,7 +524,7 @@ class Cart { } if (isset($data['billing']['save_as_address']) && $data['billing']['save_as_address']) { - $billingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id; + $billingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id; $this->customerAddressRepository->create($billingAddress); } @@ -499,7 +533,7 @@ class Cart { $shippingAddress['cart_id'] = $cart->id; if (isset($data['shipping']['address_id']) && $data['shipping']['address_id']) { - $address = $this->customerAddressRepository->findOneWhere(['id'=> $data['shipping']['address_id']])->toArray(); + $address = $this->customerAddressRepository->findOneWhere(['id' => $data['shipping']['address_id']])->toArray(); $shippingAddress['first_name'] = $this->getCurrentCustomer()->user()->first_name; $shippingAddress['last_name'] = $this->getCurrentCustomer()->user()->last_name; @@ -513,7 +547,7 @@ class Cart { } if (isset($data['shipping']['save_as_address']) && $data['shipping']['save_as_address']) { - $shippingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id; + $shippingAddress['customer_id'] = $this->getCurrentCustomer()->user()->id; $this->customerAddressRepository->create($shippingAddress); } @@ -531,9 +565,11 @@ class Cart { } } else { if (isset($billingAddress['use_for_shipping']) && $billingAddress['use_for_shipping']) { - $this->cartAddressRepository->create(array_merge($billingAddress, ['address_type' => 'shipping'])); + $this->cartAddressRepository->create(array_merge($billingAddress, + ['address_type' => 'shipping'])); } else { - $this->cartAddressRepository->create(array_merge($shippingAddress, ['address_type' => 'shipping'])); + $this->cartAddressRepository->create(array_merge($shippingAddress, + ['address_type' => 'shipping'])); } } } @@ -568,12 +604,14 @@ class Cart { * Save shipping method for cart * * @param string $shippingMethodCode + * * @return boolean */ public function saveShippingMethod($shippingMethodCode) { - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } $cart->shipping_method = $shippingMethodCode; $cart->save(); @@ -585,15 +623,18 @@ class Cart { * Save payment method for cart * * @param string $payment + * * @return CartPayment */ public function savePaymentMethod($payment) { - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } - if ($cartPayment = $cart->payment) + if ($cartPayment = $cart->payment) { $cartPayment->delete(); + } $cartPayment = new CartPayment; @@ -613,11 +654,13 @@ class Cart { { $validated = $this->validateItems(); - if (! $validated) + if (!$validated) { return false; + } - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } Event::dispatch('checkout.cart.collect.totals.before', $cart); @@ -632,19 +675,19 @@ 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->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->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 = (float)$cart->tax_total + $item->tax_amount; + $cart->base_tax_total = (float)$cart->base_tax_total + $item->base_tax_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; + $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; $cart->discount_amount += $shipping->discount_amount; $cart->base_discount_amount += $shipping->base_discount_amount; @@ -673,8 +716,9 @@ class Cart { */ public function validateItems() { - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return; + } //rare case of accident-->used when there are no items. if (count($cart->items) == 0) { @@ -685,12 +729,12 @@ class Cart { foreach ($cart->items as $item) { $item->product->getTypeInstance()->validateCartItem($item); - $price = ! is_null($item->custom_price) ? $item->custom_price : $item->base_price; + $price = !is_null($item->custom_price) ? $item->custom_price : $item->base_price; $this->cartItemRepository->update([ - 'price' => core()->convertPrice($price), + 'price' => core()->convertPrice($price), 'base_price' => $price, - 'total' => core()->convertPrice($price * $item->quantity), + 'total' => core()->convertPrice($price * $item->quantity), 'base_total' => $price * $item->quantity, ], $item->id); } @@ -706,17 +750,19 @@ class Cart { */ public function calculateItemsTax() { - if (! $cart = $this->getCart()) + if (!$cart = $this->getCart()) { return false; + } - if (! $cart->shipping_address && ! $cart->billing_address) - return; +// if (! $cart->shipping_address && ! $cart->billing_address) +// return; foreach ($cart->items()->get() as $item) { $taxCategory = $this->taxCategoryRepository->find($item->product->tax_category_id); - if (! $taxCategory) + if (!$taxCategory) { continue; + } if ($item->product->getTypeInstance()->isStockable()) { $address = $cart->shipping_address; @@ -724,25 +770,30 @@ class Cart { $address = $cart->billing_address; } + if ($address === null) { + $address = new addressHelper(); + } + $taxRates = $taxCategory->tax_rates()->where([ - 'country' => $address->country, - ])->orderBy('tax_rate', 'desc')->get(); + 'country' => $address->country, + ])->orderBy('tax_rate', 'desc')->get(); if ($taxRates->count()) { foreach ($taxRates as $rate) { $haveTaxRate = false; - if ($rate->state != '' && $rate->state != $address->state) + if ($rate->state != '' && $rate->state != $address->state) { continue; - - if (! $rate->is_zip) { - if ($rate->zip_code == '*' || $rate->zip_code == $address->postcode) - $haveTaxRate = true; - } else { - if ($address->postcode >= $rate->zip_from && $address->postcode <= $rate->zip_to) - $haveTaxRate = true; } - + if (!$rate->is_zip) { + if ($rate->zip_code == '*' || $rate->zip_code == $address->postcode) { + $haveTaxRate = true; + } + } else { + if ($address->postcode >= $rate->zip_from && $address->postcode <= $rate->zip_to) { + $haveTaxRate = true; + } + } if ($haveTaxRate) { $item->tax_percent = $rate->tax_rate; $item->tax_amount = ($item->total * $rate->tax_rate) / 100; @@ -769,11 +820,13 @@ class Cart { */ public function hasError() { - if (! $this->getCart()) + if (!$this->getCart()) { return true; + } - if (! $this->isItemsHaveSufficientQuantity()) + if (!$this->isItemsHaveSufficientQuantity()) { return true; + } return false; } @@ -786,8 +839,9 @@ class Cart { public function isItemsHaveSufficientQuantity() { foreach ($this->getCart()->items as $item) { - if (! $this->isItemHaveQuantity($item)) + if (!$this->isItemHaveQuantity($item)) { return false; + } } return true; @@ -797,6 +851,7 @@ class Cart { * Checks if all cart items have sufficient quantity. * * @param CartItem $item + * * @return boolean */ public function isItemHaveQuantity($item) @@ -830,42 +885,42 @@ class Cart { $data = $this->toArray(); $finalData = [ - 'cart_id' => $this->getCart()->id, - 'customer_id' => $data['customer_id'], - 'is_guest' => $data['is_guest'], - 'customer_email' => $data['customer_email'], - 'customer_first_name' => $data['customer_first_name'], - 'customer_last_name' => $data['customer_last_name'], - 'customer' => $this->getCurrentCustomer()->check() ? $this->getCurrentCustomer()->user() : null, - 'total_item_count' => $data['items_count'], - 'total_qty_ordered' => $data['items_qty'], - 'base_currency_code' => $data['base_currency_code'], + 'cart_id' => $this->getCart()->id, + 'customer_id' => $data['customer_id'], + 'is_guest' => $data['is_guest'], + 'customer_email' => $data['customer_email'], + 'customer_first_name' => $data['customer_first_name'], + 'customer_last_name' => $data['customer_last_name'], + 'customer' => $this->getCurrentCustomer()->check() ? $this->getCurrentCustomer()->user() : null, + 'total_item_count' => $data['items_count'], + 'total_qty_ordered' => $data['items_qty'], + 'base_currency_code' => $data['base_currency_code'], 'channel_currency_code' => $data['channel_currency_code'], - 'order_currency_code' => $data['cart_currency_code'], - 'grand_total' => $data['grand_total'], - 'base_grand_total' => $data['base_grand_total'], - 'sub_total' => $data['sub_total'], - 'base_sub_total' => $data['base_sub_total'], - 'tax_amount' => $data['tax_total'], - 'base_tax_amount' => $data['base_tax_total'], - 'coupon_code' => $data['coupon_code'], + 'order_currency_code' => $data['cart_currency_code'], + 'grand_total' => $data['grand_total'], + 'base_grand_total' => $data['base_grand_total'], + 'sub_total' => $data['sub_total'], + 'base_sub_total' => $data['base_sub_total'], + 'tax_amount' => $data['tax_total'], + 'base_tax_amount' => $data['base_tax_total'], + 'coupon_code' => $data['coupon_code'], 'applied_cart_rule_ids' => $data['applied_cart_rule_ids'], - 'discount_amount' => $data['discount_amount'], - 'base_discount_amount' => $data['base_discount_amount'], - 'billing_address' => Arr::except($data['billing_address'], ['id', 'cart_id']), - 'payment' => Arr::except($data['payment'], ['id', 'cart_id']), - 'channel' => core()->getCurrentChannel(), + 'discount_amount' => $data['discount_amount'], + 'base_discount_amount' => $data['base_discount_amount'], + 'billing_address' => Arr::except($data['billing_address'], ['id', 'cart_id']), + 'payment' => Arr::except($data['payment'], ['id', 'cart_id']), + 'channel' => core()->getCurrentChannel(), ]; if ($this->getCart()->haveStockableItems()) { $finalData = array_merge($finalData, [ - 'shipping_method' => $data['selected_shipping_rate']['method'], - 'shipping_title' => $data['selected_shipping_rate']['carrier_title'] . ' - ' . $data['selected_shipping_rate']['method_title'], - 'shipping_description' => $data['selected_shipping_rate']['method_description'], - 'shipping_amount' => $data['selected_shipping_rate']['price'], - 'base_shipping_amount' => $data['selected_shipping_rate']['base_price'], - 'shipping_address' => Arr::except($data['shipping_address'], ['id', 'cart_id']), - 'shipping_discount_amount' => $data['selected_shipping_rate']['discount_amount'], + 'shipping_method' => $data['selected_shipping_rate']['method'], + 'shipping_title' => $data['selected_shipping_rate']['carrier_title'] . ' - ' . $data['selected_shipping_rate']['method_title'], + 'shipping_description' => $data['selected_shipping_rate']['method_description'], + 'shipping_amount' => $data['selected_shipping_rate']['price'], + 'base_shipping_amount' => $data['selected_shipping_rate']['base_price'], + 'shipping_address' => Arr::except($data['shipping_address'], ['id', 'cart_id']), + 'shipping_discount_amount' => $data['selected_shipping_rate']['discount_amount'], 'base_shipping_discount_amount' => $data['selected_shipping_rate']['base_discount_amount'], ]); } @@ -881,29 +936,30 @@ class Cart { * Prepares data for order item * * @param array $data + * * @return array */ public function prepareDataForOrderItem($data) { $finalData = [ - 'product' => $this->productRepository->find($data['product_id']), - 'sku' => $data['sku'], - 'type' => $data['type'], - 'name' => $data['name'], - 'weight' => $data['weight'], - 'total_weight' => $data['total_weight'], - 'qty_ordered' => $data['quantity'], - 'price' => $data['price'], - 'base_price' => $data['base_price'], - 'total' => $data['total'], - 'base_total' => $data['base_total'], - 'tax_percent' => $data['tax_percent'], - 'tax_amount' => $data['tax_amount'], - 'base_tax_amount' => $data['base_tax_amount'], - 'discount_percent' => $data['discount_percent'], - 'discount_amount' => $data['discount_amount'], + 'product' => $this->productRepository->find($data['product_id']), + 'sku' => $data['sku'], + 'type' => $data['type'], + 'name' => $data['name'], + 'weight' => $data['weight'], + 'total_weight' => $data['total_weight'], + 'qty_ordered' => $data['quantity'], + 'price' => $data['price'], + 'base_price' => $data['base_price'], + 'total' => $data['total'], + 'base_total' => $data['base_total'], + 'tax_percent' => $data['tax_percent'], + 'tax_amount' => $data['tax_amount'], + 'base_tax_amount' => $data['base_tax_amount'], + 'discount_percent' => $data['discount_percent'], + 'discount_amount' => $data['discount_amount'], 'base_discount_amount' => $data['base_discount_amount'], - 'additional' => $data['additional'], + 'additional' => $data['additional'], ]; if (isset($data['children']) && $data['children']) { @@ -921,15 +977,18 @@ class Cart { * Move a wishlist item to cart * * @param WishlistItem $wishlistItem + * * @return boolean */ public function moveToCart($wishlistItem) { - if (! $wishlistItem->product->getTypeInstance()->canBeMovedFromWishlistToCart($wishlistItem)) + if (!$wishlistItem->product->getTypeInstance()->canBeMovedFromWishlistToCart($wishlistItem)) { return false; + } - if (! $wishlistItem->additional) + if (!$wishlistItem->additional) { $wishlistItem->additional = ['product_id' => $wishlistItem->product_id]; + } request()->merge($wishlistItem->additional); @@ -948,6 +1007,7 @@ class Cart { * Function to move a already added product to wishlist will run only on customer authentication. * * @param integer $itemId + * * @return boolean|void */ public function moveToWishlist($itemId) @@ -956,34 +1016,38 @@ class Cart { $cartItem = $cart->items()->find($itemId); - if (! $cartItem) + if (!$cartItem) { return false; + } $wishlistItems = $this->wishlistRepository->findWhere([ - 'customer_id' => $this->getCurrentCustomer()->user()->id, - 'product_id' => $cartItem->product_id - ]); + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'product_id' => $cartItem->product_id, + ]); $found = false; foreach ($wishlistItems as $wishlistItem) { - if ($cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, $wishlistItem->item_options)) + if ($cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, + $wishlistItem->item_options)) { $found = true; + } } - if (! $found) { + if (!$found) { $this->wishlistRepository->create([ - 'channel_id' => $cart->channel_id, - 'customer_id' => $this->getCurrentCustomer()->user()->id, - 'product_id' => $cartItem->product_id, - 'additional' => $cartItem->additional - ]); + 'channel_id' => $cart->channel_id, + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'product_id' => $cartItem->product_id, + 'additional' => $cartItem->additional, + ]); } $result = $this->cartItemRepository->delete($itemId); - if (! $cart->items()->count()) + if (!$cart->items()->count()) { $this->cartRepository->delete($cart->id); + } $this->collectTotals(); @@ -994,6 +1058,7 @@ class Cart { * Set coupon code to the cart * * @param string $code + * * @return Cart */ public function setCouponCode($code) diff --git a/packages/Webkul/Checkout/src/Helpers/Tax.php b/packages/Webkul/Checkout/src/Helpers/Tax.php new file mode 100644 index 000000000..2b4a28523 --- /dev/null +++ b/packages/Webkul/Checkout/src/Helpers/Tax.php @@ -0,0 +1,31 @@ +items as $item) { + $taxRate = (string)round((float)$item->tax_percent, self::TAX_PRECISION); + + if (array_key_exists($taxRate, $taxes)) { + $taxes[$taxRate] += $asBase ? $item->base_tax_amount : $item->tax_amount; + } else { + $taxes += [$taxRate => $asBase ? $item->base_tax_amount : $item->tax_amount]; + } + } + + return $taxes; + } +} \ No newline at end of file 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 70d5d87d6..c1feb3508 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,12 @@ @endif @if ($cart->base_tax_total) + @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($cart, false) as $taxRate => $taxAmount )
- - + +
+ @endforeach @endif
base_discount_amount && $cart->base_discount_amount > 0) style="display: block;" @else style="display: none;" @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 9e913b50b..a3b952743 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 @@ -123,7 +123,7 @@ @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -161,12 +161,14 @@
+ @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, true) as $taxRate => $baseTaxAmount )
- {{ __('shop::app.mail.order.tax') }} - - {{ core()->formatBasePrice($order->base_tax_amount) }} + {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + + {{ core()->formatBasePrice($baseTaxAmount) }}
+ @endforeach @if ($order->discount_amount > 0)
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 55b0d5264..8cba444fe 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 @@ -115,10 +115,10 @@ {{ $item->name }} - + @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -146,7 +146,7 @@ {{ core()->formatPrice($invoice->sub_total, $invoice->order_currency_code) }}
- + @if ($order->shipping_address)
{{ __('shop::app.mail.order.shipping-handling') }} @@ -156,12 +156,14 @@
@endif -
- {{ __('shop::app.mail.order.tax') }} - - {{ core()->formatPrice($invoice->tax_amount, $invoice->order_currency_code) }} + @foreach ($order->getTaxRatesWithAmount(false) as $taxRate => $taxAmount) +
+ {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }} -
+
+ @endforeach @if ($invoice->discount_amount > 0)
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 2d848b5ca..f2ca139b0 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 @@ -116,10 +116,10 @@ {{ $item->name }} - + @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -156,12 +156,14 @@
@endif + @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount )
- {{ __('shop::app.mail.order.tax') }} - - {{ core()->formatPrice($order->tax_amount, $order->order_currency_code) }} + {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }}
+ @endforeach @if ($order->discount_amount > 0)
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 d80d9937d..604d2f65b 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 @@ -115,10 +115,10 @@ {{ $item->name }} - + @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -158,7 +158,7 @@
@endif - +@php(//ToDo: taxes) @if ($refund->tax_amount > 0)
{{ __('shop::app.mail.order.tax') }} 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 cd6b9600e..19e677626 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 @@ -119,7 +119,7 @@ @if (isset($item->additional['attributes']))
- + @foreach ($item->additional['attributes'] as $attribute) {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach @@ -157,12 +157,14 @@
-
- {{ __('shop::app.mail.order.cancel.tax') }} - - {{ core()->formatPrice($order->tax_amount, $order->order_currency_code) }} + @foreach (Webkul\Checkout\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount ) +
+ {{ __('shop::app.mail.order.cancel.tax') }} {{ $taxRate }} % + + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }} -
+
+ @endforeach @if ($order->discount_amount > 0)
From cb5e3a47f6d9aa6595626f1579259714d35833a9 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 08:50:37 +0100 Subject: [PATCH 02/16] 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 @@ Date: Tue, 4 Feb 2020 11:18:40 +0100 Subject: [PATCH 03/16] add unit tests, refactoring --- .../views/sales/orders/view.blade.php | 4 +- packages/Webkul/Core/src/Core.php | 11 ++++ .../views/checkout/total/summary.blade.php | 4 +- .../emails/sales/new-admin-order.blade.php | 4 +- .../views/emails/sales/new-invoice.blade.php | 4 +- .../views/emails/sales/new-order.blade.php | 4 +- .../views/emails/sales/order-cancel.blade.php | 4 +- packages/Webkul/Tax/src/Helpers/Tax.php | 7 +++ tests/_support/UnitTester.php | 59 +++++++++++++++++-- tests/functional/Shop/CartCest.php | 46 +++++++++------ tests/unit/Core/CoreCest.php | 34 +++++++++++ tests/unit/Tax/Helpers/TaxCest.php | 18 ++++++ 12 files changed, 164 insertions(+), 35 deletions(-) create mode 100644 tests/unit/Core/CoreCest.php create mode 100644 tests/unit/Tax/Helpers/TaxCest.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 8787b2767..dcf5d8872 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 @@ -347,9 +347,9 @@ @php ($taxRates = Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, true)) @foreach ($taxRates as $taxRate => $baseTaxAmount) last ? 'class=border' : ''}}> - {{ __('admin::app.sales.orders.tax') }} {{ $taxRate }} % + {{ __('admin::app.sales.orders.tax') }} {{ $taxRate }} % - - {{ core()->formatBasePrice($baseTaxAmount) }} + {{ core()->formatBasePrice($baseTaxAmount) }} @endforeach diff --git a/packages/Webkul/Core/src/Core.php b/packages/Webkul/Core/src/Core.php index 963af1b00..832e3c178 100755 --- a/packages/Webkul/Core/src/Core.php +++ b/packages/Webkul/Core/src/Core.php @@ -933,4 +933,15 @@ class Core return $instance[$className] = app($className); } + + /** + * Returns a string as selector part for identifying elements in views + * @param float $taxRate + * + * @return string + */ + public static function taxRateAsIdentifier(float $taxRate): string + { + return str_replace('.', '_', (string)$taxRate); + } } \ No newline at end of file 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 e492cb91f..76a6b238b 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 @@ -20,8 +20,8 @@ @if ($cart->base_tax_total) @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 7e077768b..ec6933735 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 @@ -163,8 +163,8 @@ @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, true) as $taxRate => $baseTaxAmount )
- {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % - + {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + {{ core()->formatBasePrice($baseTaxAmount) }}
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 b8f70beaa..32a35705f 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 @@ -158,8 +158,8 @@ @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($refund, false) as $taxRate => $taxAmount)
- {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % - + {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }}
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 8089ce37a..a1b58f641 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 @@ -158,8 +158,8 @@ @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount )
- {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % - + {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }}
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 c3b007370..2b0139e1c 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 @@ -159,8 +159,8 @@ @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($order, false) as $taxRate => $taxAmount )
- {{ __('shop::app.mail.order.cancel.tax') }} {{ $taxRate }} % - + {{ __('shop::app.mail.order.cancel.tax') }} {{ $taxRate }} % + {{ core()->formatPrice($taxAmount, $order->order_currency_code) }}
diff --git a/packages/Webkul/Tax/src/Helpers/Tax.php b/packages/Webkul/Tax/src/Helpers/Tax.php index 908aa8be7..cc10b2baf 100644 --- a/packages/Webkul/Tax/src/Helpers/Tax.php +++ b/packages/Webkul/Tax/src/Helpers/Tax.php @@ -29,6 +29,13 @@ class Tax return $taxes; } + /** + * Returns the total tax amount + * @param object $that + * @param bool $asBase + * + * @return float + */ public static function getTaxTotal(object $that, bool $asBase = false): float { $taxes = self::getTaxRatesWithAmount($that, $asBase); diff --git a/tests/_support/UnitTester.php b/tests/_support/UnitTester.php index e19544a51..b056dc732 100644 --- a/tests/_support/UnitTester.php +++ b/tests/_support/UnitTester.php @@ -1,5 +1,6 @@ comment('I execute function "' + . $functionName + . '" of class "' + . (is_object($className) ? get_class($className) : $className) + . '" with ' + . count($methodParams) + . ' method-params, ' + . count($constructParams) + . ' constuctor-params and ' + . count($mocks) + . ' mocked class-methods/params' + ); + $class = new \ReflectionClass($className); + $method = $class->getMethod($functionName); + $method->setAccessible(true); + if (is_object($className)) { + $reflectedClass = $className; + } elseif (empty($constructParams)) { + $reflectedClass = Stub::make($className, $mocks); + } else { + $reflectedClass = Stub::construct($className, $constructParams, $mocks); + } + + return $method->invokeArgs($reflectedClass, $methodParams); + } +} \ No newline at end of file diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php index 87f9aa131..8381defa2 100644 --- a/tests/functional/Shop/CartCest.php +++ b/tests/functional/Shop/CartCest.php @@ -4,6 +4,7 @@ namespace Tests\Functional\Cart; use FunctionalTester; use Faker\Factory; +use Illuminate\Support\Facades\Config; use Webkul\Tax\Models\TaxMap; use Webkul\Tax\Models\TaxRate; use Webkul\Tax\Models\TaxCategory; @@ -21,15 +22,27 @@ class CartCest { $this->faker = Factory::create(); - $this->country = 'DE'; //$this->faker->countryCode; + $this->country = Config::get('app.default_country'); - $this->tax1 = $I->have(TaxRate::class, ['tax_rate' => 7.00, 'country' => $this->country]); + $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]); + $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]); + $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]); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $this->tax2->id, + 'tax_category_id' => $taxCategorie2->id + ]); $config1 = [ 'productInventory' => ['qty' => 100], @@ -54,7 +67,6 @@ class CartCest public function checkCartWithMultipleTaxRates(FunctionalTester $I) { - $I->setConfigData(['default_country' => $this->country]); $prod1Quantity = $this->faker->numberBetween(9, 30); if ($prod1Quantity % 2 !== 0) { @@ -73,9 +85,9 @@ class CartCest ]); $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); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); + $I->see(core()->currency(round($this->product1->price * $this->tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); Cart::addProduct($this->product1->id, [ '_token' => session('_token'), @@ -84,9 +96,9 @@ class CartCest ]); $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); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); + $I->see(core()->currency(round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); Cart::addProduct($this->product2->id, [ '_token' => session('_token'), @@ -95,20 +107,18 @@ class CartCest ]); $I->amOnPage('/checkout/cart'); - $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . $this->tax1->tax_rate); + $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($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(core()->currency($taxAmount1),'#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $I->see('Tax ' . $this->tax2->tax_rate . ' %', '#taxrate-' . $this->tax2->tax_rate); + $I->see('Tax ' . $this->tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($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); + $I->see(core()->currency($taxAmount2),'#basetaxamount-' . core()->taxRateAsIdentifier($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/unit/Core/CoreCest.php b/tests/unit/Core/CoreCest.php new file mode 100644 index 000000000..25189b907 --- /dev/null +++ b/tests/unit/Core/CoreCest.php @@ -0,0 +1,34 @@ + 0, + 'expected' => '0', + ], + [ + 'input' => 0.01, + 'expected' => '0_01', + ], + [ + 'input' => .12, + 'expected' => '0_12', + ], + [ + 'input' => 1234.5678, + 'expected' => '1234_5678', + ], + ]; + + foreach ($scenarios as $scenario) { + $I->assertEquals($scenario['expected'], $I->executeFunction(\Webkul\Core\Core::class, 'taxRateAsIdentifier', [$scenario['input']])); + } + } +} diff --git a/tests/unit/Tax/Helpers/TaxCest.php b/tests/unit/Tax/Helpers/TaxCest.php new file mode 100644 index 000000000..9b8caa20f --- /dev/null +++ b/tests/unit/Tax/Helpers/TaxCest.php @@ -0,0 +1,18 @@ +assertTrue(false); + } + + public function testGetTaxTotal(UnitTester $I) + { + $I->assertTrue(false); + } +} From 721091cf3228b147dd7e12ec644d4ff02bf9a7b6 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 13:27:47 +0100 Subject: [PATCH 04/16] unit test --- packages/Webkul/Tax/src/Helpers/Tax.php | 2 +- tests/unit.suite.yml | 2 +- tests/unit/Tax/Helpers/TaxCest.php | 95 ++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/packages/Webkul/Tax/src/Helpers/Tax.php b/packages/Webkul/Tax/src/Helpers/Tax.php index cc10b2baf..e7bd81eee 100644 --- a/packages/Webkul/Tax/src/Helpers/Tax.php +++ b/packages/Webkul/Tax/src/Helpers/Tax.php @@ -4,7 +4,7 @@ namespace Webkul\Tax\Helpers; class Tax { - private const TAX_PRECISION = 4; + public const TAX_PRECISION = 4; /** * Returns an array with tax rates and tax amount diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml index 53b2aa210..ba6191f9a 100644 --- a/tests/unit.suite.yml +++ b/tests/unit.suite.yml @@ -8,7 +8,7 @@ modules: - Asserts - Filesystem - \Helper\Unit - - Laravel5: + - Webkul\Core\Helpers\Laravel5Helper: environment_file: .env.testing run_database_migrations: true run_database_seeder: true diff --git a/tests/unit/Tax/Helpers/TaxCest.php b/tests/unit/Tax/Helpers/TaxCest.php index 9b8caa20f..5d987aacf 100644 --- a/tests/unit/Tax/Helpers/TaxCest.php +++ b/tests/unit/Tax/Helpers/TaxCest.php @@ -2,17 +2,108 @@ namespace Tests\Unit\Tax\Helpers; +use Faker\Factory; +use Illuminate\Support\Facades\Config; use UnitTester; +use Webkul\Tax\Models\TaxCategory; +use Webkul\Tax\Models\TaxMap; +use Webkul\Tax\Models\TaxRate; +use Cart; class TaxCest { + public $scenario; + + public function _before(UnitTester $I) + { + $faker = Factory::create(); + + $country = Config::get('app.default_country'); + + $tax1 = $I->have(TaxRate::class, [ + 'country' => $country, + ]); + $taxCategorie1 = $I->have(TaxCategory::class, []); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax1->id, + 'tax_category_id' => $taxCategorie1->id, + ]); + + $tax2 = $I->have(TaxRate::class, [ + 'country' => $country, + ]); + $taxCategorie2 = $I->have(TaxCategory::class, []); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax2->id, + 'tax_category_id' => $taxCategorie2->id, + ]); + + $config1 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie1->id, + ], + ]; + $product1 = $I->haveProduct($config1, ['simple']); + + $config2 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie2->id, + ], + ]; + $product2 = $I->haveProduct($config2, ['simple']); + + Cart::addProduct($product1->id, [ + '_token' => session('_token'), + 'product_id' => $product1->id, + 'quantity' => 11, + ]); + + Cart::addProduct($product2->id, [ + '_token' => session('_token'), + 'product_id' => $product2->id, + 'quantity' => 7, + ]); + + + $this->scenario = [ + 'object' => Cart::getCart(), + 'expectedTaxRates' => [ + (string)round((float)$tax1->tax_rate, \Webkul\Tax\Helpers\Tax::TAX_PRECISION) + => round(11 * $product1->price * $tax1->tax_rate / 100, 4), + + (string)round((float)$tax2->tax_rate, \Webkul\Tax\Helpers\Tax::TAX_PRECISION) + => round(7 * $product2->price * $tax2->tax_rate / 100, 4), + ], + 'expectedTaxTotal' => + round( + round(11 * $product1->price * $tax1->tax_rate / 100, 2) + + round(7 * $product2->price * $tax2->tax_rate / 100, 2) + , 2), + ]; + } + public function testGetTaxRatesWithAmount(UnitTester $I) { - $I->assertTrue(false); + $result = $I->executeFunction(\Webkul\Tax\Helpers\Tax::class, 'getTaxRatesWithAmount', + [$this->scenario['object'], false]); + + foreach ($result as $taxRate => $taxAmount) { + $I->assertTrue(array_key_exists($taxRate, $result)); + $I->assertEquals($this->scenario['expectedTaxRates'][$taxRate], $taxAmount); + } } public function testGetTaxTotal(UnitTester $I) { - $I->assertTrue(false); + $result = $I->executeFunction(\Webkul\Tax\Helpers\Tax::class, 'getTaxTotal', + [$this->scenario['object'], false]); + + $I->assertEquals($this->scenario['expectedTaxTotal'], $result); } } From a61446f1aa174ce9d2dad111f12798c378edd7ac Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 14:31:18 +0100 Subject: [PATCH 05/16] refactoring --- packages/Webkul/Checkout/src/Cart.php | 24 ++++++--------- packages/Webkul/Tax/src/Helpers/Tax.php | 7 ++--- .../Tax/src/Providers/TaxServiceProvider.php | 13 +------- tests/functional/Shop/CartCest.php | 27 +++++++++-------- tests/unit/Core/CoreCest.php | 30 ++++++++++++++----- tests/unit/Tax/Helpers/TaxCest.php | 20 ++++++++----- 6 files changed, 62 insertions(+), 59 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 28021ecde..5da54ae3b 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -16,17 +16,6 @@ use Webkul\Customer\Repositories\CustomerAddressRepository; use Illuminate\Support\Facades\Event; use Illuminate\Support\Arr; -class addressHelper -{ - public $country; - public $postcode; - - function __construct() - { - $this->country = config('app.default_country'); - } -} - /** * Facades handler for all the methods to be implemented in Cart. * @@ -755,9 +744,6 @@ class Cart return false; } -// if (! $cart->shipping_address && ! $cart->billing_address) -// return; - foreach ($cart->items()->get() as $item) { $taxCategory = $this->taxCategoryRepository->find($item->product->tax_category_id); @@ -772,7 +758,15 @@ class Cart } if ($address === null) { - $address = new addressHelper(); + $address = new class() { + public $country; + public $postcode; + + function __construct() + { + $this->country = config('app.default_country'); + } + }; } $taxRates = $taxCategory->tax_rates()->where([ diff --git a/packages/Webkul/Tax/src/Helpers/Tax.php b/packages/Webkul/Tax/src/Helpers/Tax.php index e7bd81eee..fac5dc7ca 100644 --- a/packages/Webkul/Tax/src/Helpers/Tax.php +++ b/packages/Webkul/Tax/src/Helpers/Tax.php @@ -19,11 +19,10 @@ class Tax foreach ($that->items as $item) { $taxRate = (string)round((float)$item->tax_percent, self::TAX_PRECISION); - if (array_key_exists($taxRate, $taxes)) { - $taxes[$taxRate] += $asBase ? $item->base_tax_amount : $item->tax_amount; - } else { - $taxes += [$taxRate => $asBase ? $item->base_tax_amount : $item->tax_amount]; + if (!array_key_exists($taxRate, $taxes)) { + $taxes[$taxRate] = 0; } + $taxes[$taxRate] += $asBase ? $item->base_tax_amount : $item->tax_amount; } return $taxes; diff --git a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php index 047ec84b4..886962155 100755 --- a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php +++ b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php @@ -23,17 +23,6 @@ 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); + $this->loadFactoriesFrom(__DIR__ . '/../Database/Factories'); } } \ No newline at end of file diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php index 8381defa2..2a6ab3a7b 100644 --- a/tests/functional/Shop/CartCest.php +++ b/tests/functional/Shop/CartCest.php @@ -20,25 +20,23 @@ class CartCest function _before(FunctionalTester $I) { - $this->faker = Factory::create(); + $this->country = Config::get('app.default_country'); $this->tax1 = $I->have(TaxRate::class, [ - //'tax_rate' => 7.00, 'country' => $this->country ]); - $taxCategorie1 = $I->have(TaxCategory::class, []); + $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, []); + $taxCategorie2 = $I->have(TaxCategory::class); $I->have(TaxMap::class, [ 'tax_rate_id' => $this->tax2->id, 'tax_category_id' => $taxCategorie2->id @@ -67,13 +65,14 @@ class CartCest public function checkCartWithMultipleTaxRates(FunctionalTester $I) { - - $prod1Quantity = $this->faker->numberBetween(9, 30); + $prod1Quantity = $I->fake()->numberBetween(9, 30); + // quantity of product1 should be not even if ($prod1Quantity % 2 !== 0) { $prod1Quantity -= 1; } - $prod2Quantity = $this->faker->numberBetween(9, 30); + $prod2Quantity = $I->fake()->numberBetween(9, 30); + // quantity of product2 should be even if ($prod2Quantity % 2 == 0) { $prod2Quantity -= 1; } @@ -86,8 +85,10 @@ class CartCest $I->amOnPage('/checkout/cart'); $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $I->see(core()->currency(round($this->product1->price * $this->tax1->tax_rate / 100, 2)), - '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); + $I->see( + core()->currency(round($this->product1->price * $this->tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate) + ); Cart::addProduct($this->product1->id, [ '_token' => session('_token'), @@ -97,8 +98,10 @@ class CartCest $I->amOnPage('/checkout/cart'); $I->see('Tax ' . $this->tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $I->see(core()->currency(round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2)), - '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); + $I->see( + core()->currency(round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate) + ); Cart::addProduct($this->product2->id, [ '_token' => session('_token'), diff --git a/tests/unit/Core/CoreCest.php b/tests/unit/Core/CoreCest.php index 25189b907..acb996f79 100644 --- a/tests/unit/Core/CoreCest.php +++ b/tests/unit/Core/CoreCest.php @@ -2,13 +2,31 @@ namespace Tests\Unit\Core; +use Codeception\Example; use UnitTester; class CoreCest { - public function testTaxRateAsIdentifier(UnitTester $I) + /** + * @param \UnitTester $I + * + * @param \Codeception\Example $scenario + * + * @throws \Exception + * @dataProvider getTaxRateScenarios + * + */ + public function testTaxRateAsIdentifier(UnitTester $I, Example $scenario): void { - $scenarios = [ + $I->assertEquals( + $scenario['expected'], + $I->executeFunction(\Webkul\Core\Core::class, 'taxRateAsIdentifier', [$scenario['input']]) + ); + } + + protected function getTaxRateScenarios(): array + { + return [ [ 'input' => 0, 'expected' => '0', @@ -18,17 +36,13 @@ class CoreCest 'expected' => '0_01', ], [ - 'input' => .12, + 'input' => .12, 'expected' => '0_12', ], [ - 'input' => 1234.5678, + 'input' => 1234.5678, 'expected' => '1234_5678', ], ]; - - foreach ($scenarios as $scenario) { - $I->assertEquals($scenario['expected'], $I->executeFunction(\Webkul\Core\Core::class, 'taxRateAsIdentifier', [$scenario['input']])); - } } } diff --git a/tests/unit/Tax/Helpers/TaxCest.php b/tests/unit/Tax/Helpers/TaxCest.php index 5d987aacf..e1d7d1461 100644 --- a/tests/unit/Tax/Helpers/TaxCest.php +++ b/tests/unit/Tax/Helpers/TaxCest.php @@ -16,14 +16,12 @@ class TaxCest public function _before(UnitTester $I) { - $faker = Factory::create(); - $country = Config::get('app.default_country'); $tax1 = $I->have(TaxRate::class, [ 'country' => $country, ]); - $taxCategorie1 = $I->have(TaxCategory::class, []); + $taxCategorie1 = $I->have(TaxCategory::class); $I->have(TaxMap::class, [ 'tax_rate_id' => $tax1->id, 'tax_category_id' => $taxCategorie1->id, @@ -32,7 +30,7 @@ class TaxCest $tax2 = $I->have(TaxRate::class, [ 'country' => $country, ]); - $taxCategorie2 = $I->have(TaxCategory::class, []); + $taxCategorie2 = $I->have(TaxCategory::class); $I->have(TaxMap::class, [ 'tax_rate_id' => $tax2->id, 'tax_category_id' => $taxCategorie2->id, @@ -90,8 +88,11 @@ class TaxCest public function testGetTaxRatesWithAmount(UnitTester $I) { - $result = $I->executeFunction(\Webkul\Tax\Helpers\Tax::class, 'getTaxRatesWithAmount', - [$this->scenario['object'], false]); + $result = $I->executeFunction( + \Webkul\Tax\Helpers\Tax::class, + 'getTaxRatesWithAmount', + [$this->scenario['object'], false] + ); foreach ($result as $taxRate => $taxAmount) { $I->assertTrue(array_key_exists($taxRate, $result)); @@ -101,8 +102,11 @@ class TaxCest public function testGetTaxTotal(UnitTester $I) { - $result = $I->executeFunction(\Webkul\Tax\Helpers\Tax::class, 'getTaxTotal', - [$this->scenario['object'], false]); + $result = $I->executeFunction( + \Webkul\Tax\Helpers\Tax::class, + 'getTaxTotal', + [$this->scenario['object'], false] + ); $I->assertEquals($this->scenario['expectedTaxTotal'], $result); } From 763ccf3af9a32a02eb3a169d1c525aa16e62399a Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 14:33:25 +0100 Subject: [PATCH 06/16] set default_country to EN --- config/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app.php b/config/app.php index 1f0b07847..818d39fa8 100755 --- a/config/app.php +++ b/config/app.php @@ -104,7 +104,7 @@ return [ | */ - 'default_country' => 'DE', + 'default_country' => 'EN', /* |-------------------------------------------------------------------------- From 01010db842f8e57f76eb7270da7857b5509f3bce Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 14:38:52 +0100 Subject: [PATCH 07/16] set default_country to null, add fallback for test --- config/app.php | 2 +- tests/functional/Shop/CartCest.php | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/config/app.php b/config/app.php index 818d39fa8..a3cf7f964 100755 --- a/config/app.php +++ b/config/app.php @@ -104,7 +104,7 @@ return [ | */ - 'default_country' => 'EN', + 'default_country' => null, /* |-------------------------------------------------------------------------- diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php index 2a6ab3a7b..3a486e536 100644 --- a/tests/functional/Shop/CartCest.php +++ b/tests/functional/Shop/CartCest.php @@ -14,15 +14,12 @@ use Cart; class CartCest { private $country; - private $faker; private $product1, $product2; private $tax1, $tax2; function _before(FunctionalTester $I) { - - - $this->country = Config::get('app.default_country'); + $this->country = Config::get('app.default_country') ?? 'DE'; $this->tax1 = $I->have(TaxRate::class, [ 'country' => $this->country From dd8f653df4096d8050530b055ccc8ebbc4310443 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 14:48:15 +0100 Subject: [PATCH 08/16] minor improvements --- config/app.php | 2 ++ packages/Webkul/Checkout/src/Cart.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/app.php b/config/app.php index a3cf7f964..4efe78849 100755 --- a/config/app.php +++ b/config/app.php @@ -102,6 +102,8 @@ return [ | Ensure it is uppercase and reflects the 'code' column of the | countries table. | + | for example: DE EN FR + | (use capital letters!) */ 'default_country' => null, diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 5da54ae3b..3f69fbe1d 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -764,7 +764,7 @@ class Cart function __construct() { - $this->country = config('app.default_country'); + $this->country = strtoupper(config('app.default_country')); } }; } From cdd61fa77eb24e53aba6655ed856100c9fc4a257 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 17:21:18 +0100 Subject: [PATCH 09/16] fix test for misconfigured config/app.php --- tests/unit/Tax/Helpers/TaxCest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/Tax/Helpers/TaxCest.php b/tests/unit/Tax/Helpers/TaxCest.php index e1d7d1461..741fcf75c 100644 --- a/tests/unit/Tax/Helpers/TaxCest.php +++ b/tests/unit/Tax/Helpers/TaxCest.php @@ -17,6 +17,9 @@ class TaxCest public function _before(UnitTester $I) { $country = Config::get('app.default_country'); + if ($country === null) { + $country = 'DE'; + } $tax1 = $I->have(TaxRate::class, [ 'country' => $country, From ec89d9781661e673d9440fef091846717ccef576 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Tue, 4 Feb 2020 17:41:05 +0100 Subject: [PATCH 10/16] refactoring --- tests/functional/Shop/CartCest.php | 2 +- tests/unit/Tax/Helpers/TaxCest.php | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php index 3a486e536..47505945c 100644 --- a/tests/functional/Shop/CartCest.php +++ b/tests/functional/Shop/CartCest.php @@ -19,7 +19,7 @@ class CartCest function _before(FunctionalTester $I) { - $this->country = Config::get('app.default_country') ?? 'DE'; + $this->country = strtoupper(Config::get('app.default_country')) ?? 'DE'; $this->tax1 = $I->have(TaxRate::class, [ 'country' => $this->country diff --git a/tests/unit/Tax/Helpers/TaxCest.php b/tests/unit/Tax/Helpers/TaxCest.php index 741fcf75c..0712352f3 100644 --- a/tests/unit/Tax/Helpers/TaxCest.php +++ b/tests/unit/Tax/Helpers/TaxCest.php @@ -16,10 +16,7 @@ class TaxCest public function _before(UnitTester $I) { - $country = Config::get('app.default_country'); - if ($country === null) { - $country = 'DE'; - } + $country = strtoupper(Config::get('app.default_country')) ?? 'DE'; $tax1 = $I->have(TaxRate::class, [ 'country' => $country, From e678a467fc058506e5678a096a945c2a1e9f5b2b Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Wed, 5 Feb 2020 11:18:21 +0100 Subject: [PATCH 11/16] call collectTotals in saveCustomerAddress --- packages/Webkul/Checkout/src/Cart.php | 2 ++ packages/Webkul/Core/src/Helpers/Laravel5Helper.php | 1 + tests/functional/Shop/CartCest.php | 2 -- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index d2c3ec78a..6102d582a 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -590,6 +590,8 @@ class Cart $cart->save(); + $this->collectTotals(); + return true; } diff --git a/packages/Webkul/Core/src/Helpers/Laravel5Helper.php b/packages/Webkul/Core/src/Helpers/Laravel5Helper.php index b15b3d89f..baa7a650c 100644 --- a/packages/Webkul/Core/src/Helpers/Laravel5Helper.php +++ b/packages/Webkul/Core/src/Helpers/Laravel5Helper.php @@ -72,6 +72,7 @@ class Laravel5Helper extends Laravel5 * @param array $productStates * * @return \Webkul\Product\Models\Product + * @part ORM */ public function haveProduct(int $productType, array $configs = [], array $productStates = []): Product { diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php index dc61c5384..eeddd3eaa 100644 --- a/tests/functional/Shop/CartCest.php +++ b/tests/functional/Shop/CartCest.php @@ -3,12 +3,10 @@ namespace Tests\Functional\Cart; use FunctionalTester; -use Faker\Factory; use Illuminate\Support\Facades\Config; use Webkul\Tax\Models\TaxMap; use Webkul\Tax\Models\TaxRate; use Webkul\Tax\Models\TaxCategory; -use Webkul\Checkout\Models\Cart as CartModel; use Cart; class CartCest From 1d08f8a1f59f3cc24f85009f929469145b8eb0c6 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Fri, 7 Feb 2020 19:09:41 +0100 Subject: [PATCH 12/16] extend API endpoint for Cart by taxes --- .../API/Http/Resources/Checkout/Cart.php | 31 +++++++++++++++++++ packages/Webkul/Checkout/src/Cart.php | 6 ++++ 2 files changed, 37 insertions(+) diff --git a/packages/Webkul/API/Http/Resources/Checkout/Cart.php b/packages/Webkul/API/Http/Resources/Checkout/Cart.php index 2a6401b9e..028d42f43 100644 --- a/packages/Webkul/API/Http/Resources/Checkout/Cart.php +++ b/packages/Webkul/API/Http/Resources/Checkout/Cart.php @@ -16,6 +16,12 @@ class Cart extends JsonResource */ public function toArray($request) { + $taxes = \Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($this, false); + $baseTaxes = \Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($this, true); + + $formatedTaxes = $this->formatTaxAmounts($taxes, false); + $formatedBaseTaxes = $this->formatTaxAmounts($baseTaxes, true); + return [ 'id' => $this->id, 'customer_email' => $this->customer_email, @@ -60,6 +66,31 @@ class Cart extends JsonResource 'shipping_address' => new CartAddress($this->shipping_address), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, + 'taxes' => json_encode($taxes, JSON_FORCE_OBJECT), + 'formated_taxes' => json_encode($formatedTaxes, JSON_FORCE_OBJECT), + 'base_taxes' => json_encode($baseTaxes, JSON_FORCE_OBJECT), + 'formated_base_taxes' => json_encode($formatedBaseTaxes, JSON_FORCE_OBJECT), ]; } + + /** + * @param array $taxes + * @param bool $isBase + * + * @return array + */ + private function formatTaxAmounts(array $taxes, bool $isBase = false): array + { + $result = []; + + foreach ($taxes as $taxRate => $taxAmount) { + if ($isBase === true) { + $result[$taxRate] = core()->formatBasePrice($taxAmount); + } else { + $result[$taxRate] = core()->formatPrice($taxAmount, $this->cart_currency_code); + } + } + + return $result; + } } \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 1539fab12..5fd8aae46 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -762,6 +762,12 @@ class Cart $address = $cart->billing_address; } + + if ($address === null && auth()->guard('customer')->check()) { + $address = auth()->guard('customer')->user()->addresses() + ->where('default_address',1)->first(); + } + if ($address === null) { $address = new class() { public $country; From 00c43e21de6c035a72e71d4707a7b332e905ccdd Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Fri, 7 Feb 2020 19:23:15 +0100 Subject: [PATCH 13/16] cleanup --- packages/Webkul/Checkout/src/Cart.php | 1 - packages/Webkul/Tax/src/Providers/TaxServiceProvider.php | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 5fd8aae46..eae2a9ee3 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -762,7 +762,6 @@ class Cart $address = $cart->billing_address; } - if ($address === null && auth()->guard('customer')->check()) { $address = auth()->guard('customer')->user()->addresses() ->where('default_address',1)->first(); diff --git a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php index 886962155..181258405 100755 --- a/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php +++ b/packages/Webkul/Tax/src/Providers/TaxServiceProvider.php @@ -2,7 +2,6 @@ namespace Webkul\Tax\Providers; use Illuminate\Support\ServiceProvider; -use Illuminate\Database\Eloquent\Factory as EloquentFactory; class TaxServiceProvider extends ServiceProvider { From 7dff220da9f78d34597b175d7beaaa03c6ee10ab Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Sat, 8 Feb 2020 20:42:32 +0100 Subject: [PATCH 14/16] fix issue with zip based taxes, added functional test --- packages/Webkul/Checkout/src/Cart.php | 17 +- tests/functional/Shop/CartCest.php | 122 ------- tests/functional/Shop/CartTaxesCest.php | 436 ++++++++++++++++++++++++ 3 files changed, 444 insertions(+), 131 deletions(-) delete mode 100644 tests/functional/Shop/CartCest.php create mode 100644 tests/functional/Shop/CartTaxesCest.php diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index eae2a9ee3..a076cbea2 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -743,10 +743,10 @@ class Cart * * @return void */ - public function calculateItemsTax() + public function calculateItemsTax(): void { if (!$cart = $this->getCart()) { - return false; + return; } foreach ($cart->items()->get() as $item) { @@ -783,6 +783,10 @@ class Cart 'country' => $address->country, ])->orderBy('tax_rate', 'desc')->get(); + $item->tax_percent = 0; + $item->tax_amount = 0; + $item->base_tax_amount = 0; + if ($taxRates->count()) { foreach ($taxRates as $rate) { $haveTaxRate = false; @@ -804,17 +808,12 @@ class Cart $item->tax_amount = ($item->total * $rate->tax_rate) / 100; $item->base_tax_amount = ($item->base_total * $rate->tax_rate) / 100; - $item->save(); break; } } - } else { - $item->tax_percent = 0; - $item->tax_amount = 0; - $item->base_tax_amount = 0; - - $item->save(); } + + $item->save(); } } diff --git a/tests/functional/Shop/CartCest.php b/tests/functional/Shop/CartCest.php deleted file mode 100644 index eeddd3eaa..000000000 --- a/tests/functional/Shop/CartCest.php +++ /dev/null @@ -1,122 +0,0 @@ -country = strtoupper(Config::get('app.default_country')) ?? 'DE'; - - $this->tax1 = $I->have(TaxRate::class, [ - '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, [ - '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(\Webkul\Core\Helpers\Laravel5Helper::SIMPLE_PRODUCT, $config1); - - $config2 = [ - 'productInventory' => ['qty' => 100], - 'attributeValues' => [ - 'status' => true, - 'new' => 1, - 'tax_category_id' => $taxCategorie2->id, - ], - ]; - $this->product2 = $I->haveProduct(\Webkul\Core\Helpers\Laravel5Helper::SIMPLE_PRODUCT, $config2); - } - - public function checkCartWithMultipleTaxRates(FunctionalTester $I) - { - $prod1Quantity = $I->fake()->numberBetween(9, 30); - // quantity of product1 should be not even - if ($prod1Quantity % 2 !== 0) { - $prod1Quantity -= 1; - } - - $prod2Quantity = $I->fake()->numberBetween(9, 30); - // quantity of product2 should be even - 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-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $I->see( - core()->currency(round($this->product1->price * $this->tax1->tax_rate / 100, 2)), - '#basetaxamount-' . core()->taxRateAsIdentifier($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-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $I->see( - core()->currency(round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2)), - '#basetaxamount-' . core()->taxRateAsIdentifier($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-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - $taxAmount1 = round(($prod1Quantity + 1) * $this->product1->price * $this->tax1->tax_rate / 100, 2); - $I->see(core()->currency($taxAmount1),'#basetaxamount-' . core()->taxRateAsIdentifier($this->tax1->tax_rate)); - - $I->see('Tax ' . $this->tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($this->tax2->tax_rate)); - $taxAmount2 = round($prod2Quantity * $this->product2->price * $this->tax2->tax_rate / 100, 2); - $I->see(core()->currency($taxAmount2),'#basetaxamount-' . core()->taxRateAsIdentifier($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/CartTaxesCest.php b/tests/functional/Shop/CartTaxesCest.php new file mode 100644 index 000000000..6e474fe16 --- /dev/null +++ b/tests/functional/Shop/CartTaxesCest.php @@ -0,0 +1,436 @@ +country = strtoupper(Config::get('app.default_country')) ?? 'DE'; + } + + public function checkCartWithMultipleTaxRates(FunctionalTester $I): void + { + $tax1 = $I->have(TaxRate::class, [ + 'country' => $this->country, + ]); + $taxCategorie1 = $I->have(TaxCategory::class); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax1->id, + 'tax_category_id' => $taxCategorie1->id, + ]); + + $tax2 = $I->have(TaxRate::class, [ + 'country' => $this->country, + ]); + $taxCategorie2 = $I->have(TaxCategory::class); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax2->id, + 'tax_category_id' => $taxCategorie2->id, + ]); + + $config1 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie1->id, + ], + ]; + $product1 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config1); + + $config2 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie2->id, + ], + ]; + $product2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config2); + + $prod1Quantity = $I->fake()->numberBetween(9, 30); + // quantity of product1 should be not even + if ($prod1Quantity % 2 !== 0) { + $prod1Quantity -= 1; + } + + $prod2Quantity = $I->fake()->numberBetween(9, 30); + // quantity of product2 should be even + if ($prod2Quantity % 2 == 0) { + $prod2Quantity -= 1; + } + + Cart::addProduct($product1->id, [ + '_token' => session('_token'), + 'product_id' => $product1->id, + 'quantity' => 1, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + $I->see( + core()->currency(round($product1->price * $tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate) + ); + + Cart::addProduct($product1->id, [ + '_token' => session('_token'), + 'product_id' => $product1->id, + 'quantity' => $prod1Quantity, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + $I->see( + core()->currency(round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate) + ); + + Cart::addProduct($product2->id, [ + '_token' => session('_token'), + 'product_id' => $product2->id, + 'quantity' => $prod2Quantity, + ]); + + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + $taxAmount1 = round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + + $I->see('Tax ' . $tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax2->tax_rate)); + $taxAmount2 = round($prod2Quantity * $product2->price * $tax2->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($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); + + Cart::removeItem($cart->items[1]->id); + + $I->amOnPage('/checkout/cart'); + $I->amOnPage('/checkout/cart'); + $I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + $taxAmount1 = round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate)); + + $I->dontSee('Tax ' . $tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax2->tax_rate)); + $taxAmount2 = round($prod2Quantity * $product2->price * $tax2->tax_rate / 100, 2); + $I->dontSee(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax2->tax_rate)); + + $cart = Cart::getCart(); + + $I->assertEquals(1, $cart->items_count); + $I->assertEquals((float)($prod1Quantity + 1), $cart->items_qty); + $I->assertEquals($taxAmount1, $cart->tax_total); + } + + public function checkCartWithMultipleZipRangeBasedTaxes(FunctionalTester $I): void + { + $tax11 = $I->have(TaxRate::class, [ + 'country' => $this->country, + 'is_zip' => 1, + 'zip_code' => null, + 'zip_from' => '00000', + 'zip_to' => '49999', + 'tax_rate' => $I->fake()->randomFloat(2, 3, 8), + ]); + $tax12 = $I->have(TaxRate::class, [ + 'country' => $this->country, + 'is_zip' => 1, + 'zip_code' => null, + 'zip_from' => '50000', + 'zip_to' => '89999', + 'tax_rate' => $I->fake()->randomFloat(2, 3, 8), + ]); + + $taxCategorie1 = $I->have(TaxCategory::class); + + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax11->id, + 'tax_category_id' => $taxCategorie1->id, + ]); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax12->id, + 'tax_category_id' => $taxCategorie1->id, + ]); + + $tax21 = $I->have(TaxRate::class, [ + 'country' => $this->country, + 'is_zip' => 1, + 'zip_code' => null, + 'zip_from' => '00000', + 'zip_to' => '49999', + 'tax_rate' => $I->fake()->randomFloat(2, 14, 25), + ]); + $tax22 = $I->have(TaxRate::class, [ + 'country' => $this->country, + 'is_zip' => 1, + 'zip_code' => null, + 'zip_from' => '50000', + 'zip_to' => '89999', + 'tax_rate' => $I->fake()->randomFloat(2, 14, 25), + ]); + + $taxCategorie2 = $I->have(TaxCategory::class); + + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax21->id, + 'tax_category_id' => $taxCategorie2->id, + ]); + $I->have(TaxMap::class, [ + 'tax_rate_id' => $tax22->id, + 'tax_category_id' => $taxCategorie2->id, + ]); + + $config1 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie1->id, + ], + ]; + $product1 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config1); + + $config2 = [ + 'productInventory' => ['qty' => 100], + 'attributeValues' => [ + 'status' => true, + 'new' => 1, + 'tax_category_id' => $taxCategorie2->id, + ], + ]; + $product2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config2); + + $customer = $I->have(Customer::class); + + $addressZip012345 = $I->have(CustomerAddress::class, [ + 'customer_id' => $customer->id, + 'postcode' => '012345', + 'vat_id' => 'DE123456789', + 'country' => $this->country, + 'default_address' => 1, + ]); + + Cart::addProduct($product1->id, [ + '_token' => session('_token'), + 'product_id' => $product1->id, + 'quantity' => 1, + ]); + + Cart::saveCustomerAddress( + [ + 'billing' => [ + 'address1' => $addressZip012345->address1, + 'use_for_shipping' => 1, + 'email' => $customer->email, + 'company_name' => $addressZip012345->company_name, + 'first_name' => $addressZip012345->first_name, + 'last_name' => $addressZip012345->last_name, + 'city' => $addressZip012345->city, + 'state' => $addressZip012345->state, + 'postcode' => $addressZip012345->postcode, + 'country' => $addressZip012345->country, + ], + 'shipping' => [ + 'address1' => '', + ], + ]); + + $I->wantToTest('customer address with postcode in range of 00000 - 49999'); + $I->amOnPage('/checkout/cart'); + + $I->see('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate)); + $I->see( + core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate) + ); + + $I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate)); + $I->dontSee( + core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate) + ); + + $I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate) + ); + + $I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate) + ); + + Cart::addProduct($product2->id, [ + '_token' => session('_token'), + 'product_id' => $product2->id, + 'quantity' => 1, + ]); + + $I->amOnPage('/checkout/cart'); + + $I->see('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate)); + $I->see( + core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate) + ); + + $I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate)); + $I->dontSee( + core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate) + ); + + $I->see('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate)); + $I->see( + core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate) + ); + + $I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate) + ); + + $taxAmount1 = round($product1->price * $tax11->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate)); + + $taxAmount2 = round($product2->price * $tax21->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate)); + + + $I->wantToTest('customer address with postcode in range of 50000 - 89999'); + $addressZip67890 = $I->have(CustomerAddress::class, [ + 'customer_id' => $customer->id, + 'postcode' => '67890', + 'vat_id' => 'DE123456789', + 'country' => $this->country, + 'default_address' => 1, + ]); + + Cart::saveCustomerAddress( + [ + 'billing' => [ + 'address1' => $addressZip67890->address1, + 'use_for_shipping' => 1, + 'email' => $customer->email, + 'company_name' => $addressZip67890->company_name, + 'first_name' => $addressZip67890->first_name, + 'last_name' => $addressZip67890->last_name, + 'city' => $addressZip67890->city, + 'state' => $addressZip67890->state, + 'postcode' => $addressZip67890->postcode, + 'country' => $addressZip67890->country, + ], + 'shipping' => [ + 'address1' => '', + ], + ]); + + $I->amOnPage('/checkout/cart'); + + $I->dontSee('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate)); + $I->dontSee( + core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate) + ); + + $I->see('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate)); + $I->see( + core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate) + ); + + $I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate) + ); + + $I->see('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate)); + $I->see( + core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate) + ); + + $taxAmount1 = round($product1->price * $tax12->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate)); + + $taxAmount2 = round($product2->price * $tax22->tax_rate / 100, 2); + $I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate)); + + $I->wantToTest('customer address with postcode in range of 90000 - 99000'); + $I->wanttoTest('as we dont have any taxes in this zip range'); + $addressZip98765 = $I->have(CustomerAddress::class, [ + 'customer_id' => $customer->id, + 'postcode' => '98765', + 'vat_id' => 'DE123456789', + 'country' => $this->country, + 'default_address' => 1, + ]); + + Cart::saveCustomerAddress( + [ + 'billing' => [ + 'address1' => $addressZip98765->address1, + 'use_for_shipping' => 1, + 'email' => $customer->email, + 'company_name' => $addressZip98765->company_name, + 'first_name' => $addressZip98765->first_name, + 'last_name' => $addressZip98765->last_name, + 'city' => $addressZip98765->city, + 'state' => $addressZip98765->state, + 'postcode' => $addressZip98765->postcode, + 'country' => $addressZip98765->country, + ], + 'shipping' => [ + 'address1' => '', + ], + ]); + + $I->amOnPage('/checkout/cart'); + + $I->dontSee('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate)); + $I->dontSee( + core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate) + ); + + $I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate)); + $I->dontSee( + core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate) + ); + + $I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate) + ); + + $I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate)); + $I->dontSee( + core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)), + '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate) + ); + } +} \ No newline at end of file From 623b7893a26dedf9165341f70989be53317228db Mon Sep 17 00:00:00 2001 From: Annika Wolff <57894757+AnnikaWolff@users.noreply.github.com> Date: Thu, 20 Feb 2020 19:23:01 +0100 Subject: [PATCH 15/16] resolve merge conflicts --- packages/Webkul/Checkout/src/Cart.php | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 771845934..74e75be04 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -784,18 +784,17 @@ class Cart 'country' => $address->country, ])->orderBy('tax_rate', 'desc')->get(); + $item = $this->setItemTaxToZero($item); + if ($taxRates->count()) { foreach ($taxRates as $rate) { $haveTaxRate = false; if ($rate->state != '' && $rate->state != $address->state) { - $this->setItemTaxToZero($item); - continue; } - - if (! $rate->is_zip) { - if ($rate->zip_code == '*' || $rate->zip_code == $address->postcode) + if (!$rate->is_zip) { + if ($rate->zip_code == '*' || $rate->zip_code == $address->postcode) { $haveTaxRate = true; } } else { @@ -808,15 +807,9 @@ class Cart $item->tax_amount = ($item->total * $rate->tax_rate) / 100; $item->base_tax_amount = ($item->base_total * $rate->tax_rate) / 100; - break; - } else { - $this->setItemTaxToZero($item); - break; } } - } else { - $this->setItemTaxToZero($item); } $item->save(); @@ -826,14 +819,15 @@ class Cart /** * Set Item tax to zero. * - * @return void + * @param CartItem $item + * @return CartItem */ protected function setItemTaxToZero($item) { $item->tax_percent = 0; $item->tax_amount = 0; $item->base_tax_amount = 0; - - $item->save(); + + return $item; } /** @@ -1113,4 +1107,4 @@ class Cart return $this; } -} \ No newline at end of file +} From d50510a626732bf890edff1b33b16e6ba2ed30d3 Mon Sep 17 00:00:00 2001 From: Annika Wolff Date: Fri, 21 Feb 2020 08:36:52 +0100 Subject: [PATCH 16/16] resolve merge issue, add type hints in Cart helper function --- packages/Webkul/Checkout/src/Cart.php | 6 +- .../views/emails/sales/new-invoice.blade.php | 66 ++++++++++--------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 74e75be04..7b125b01a 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -785,7 +785,7 @@ class Cart ])->orderBy('tax_rate', 'desc')->get(); $item = $this->setItemTaxToZero($item); - + if ($taxRates->count()) { foreach ($taxRates as $rate) { $haveTaxRate = false; @@ -822,11 +822,11 @@ class Cart * @param CartItem $item * @return CartItem */ - protected function setItemTaxToZero($item) { + protected function setItemTaxToZero(CartItem $item): CartItem { $item->tax_percent = 0; $item->tax_amount = 0; $item->base_tax_amount = 0; - + return $item; } 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 32a35705f..5c24a70fd 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 @@ -30,7 +30,8 @@ {{ __('shop::app.mail.invoice.summary') }}
-
+
@if ($order->shipping_address)
@@ -103,37 +104,41 @@ - - - - - + + + + + - @foreach ($invoice->items as $item) - - + + + @endif + - + - - + + - @endforeach + @endforeach
{{ __('shop::app.customer.account.order.view.product-name') }}{{ __('shop::app.customer.account.order.view.price') }}{{ __('shop::app.customer.account.order.view.qty') }}
{{ __('shop::app.customer.account.order.view.product-name') }}{{ __('shop::app.customer.account.order.view.price') }}{{ __('shop::app.customer.account.order.view.qty') }}
- {{ $item->name }} + @foreach ($invoice->items as $item) +
+ {{ $item->name }} - @if (isset($item->additional['attributes'])) -
+ @if (isset($item->additional['attributes'])) +
- @foreach ($item->additional['attributes'] as $attribute) - {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
- @endforeach + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} + : {{ $attribute['option_label'] }}
+ @endforeach -
- @endif -
{{ core()->formatPrice($item->price, $order->order_currency_code) }} - {{ core()->formatPrice($item->price, $order->order_currency_code) }} + {{ $item->qty }}
{{ $item->qty }}
@@ -156,14 +161,12 @@
@endif - @foreach (Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($refund, false) as $taxRate => $taxAmount) -
- {{ __('shop::app.mail.order.tax') }} {{ $taxRate }} % - - {{ core()->formatPrice($taxAmount, $order->order_currency_code) }} +
+ {{ __('shop::app.mail.order.tax') }} + + {{ core()->formatPrice($invoice->tax_amount, $order->order_currency_code) }} -
- @endforeach +
@if ($invoice->discount_amount > 0)
@@ -182,7 +185,8 @@
-
+

{!! __('shop::app.mail.order.help', [