Skip to content

Commit

Permalink
Merge pull request #784 from dpfaffenbauer/cart-item-processor-extract
Browse files Browse the repository at this point in the history
Cart item processor extract
  • Loading branch information
dpfaffenbauer authored Jan 20, 2019
2 parents 7ed6a21 + 2db5452 commit b7a8f05
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ services:
_defaults:
public: true

coreshop.cart_item.processor:
class: CoreShop\Component\Core\Order\Processor\CartItemProcessor
arguments:
- '@coreshop.product.tax_factory'
- '@coreshop.provider.store_based_default_address_provider'

coreshop.cart_processor.adjustments_clearer:
class: CoreShop\Component\Core\Order\Processor\CartAdjustmentClearer
tags:
- { name: coreshop.cart_processor, priority: 650 }

coreshop.cart_processor.items:
class: CoreShop\Component\Core\Order\Processor\CartItemProcessor
class: CoreShop\Component\Core\Order\Processor\CartItemsProcessor
arguments:
- '@coreshop.order.purchasable.calculator'
- '@coreshop.product.tax_factory'
- '@coreshop.provider.store_based_default_address_provider'
- '@coreshop.cart_item.processor'
tags:
- { name: coreshop.cart_processor, priority: 600 }

Expand Down Expand Up @@ -63,4 +68,4 @@ services:
- '@coreshop.provider.store_based_default_address_provider'
- '@coreshop.taxation.factory.tax_calculator'
tags:
- { name: coreshop.cart_processor, priority: 350 }
- { name: coreshop.cart_processor, priority: 350 }
157 changes: 61 additions & 96 deletions src/CoreShop/Component/Core/Order/Processor/CartItemProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,15 @@

namespace CoreShop\Component\Core\Order\Processor;

use CoreShop\Component\Core\Model\CartItemInterface;
use CoreShop\Component\Core\Model\StoreInterface;
use CoreShop\Component\Order\Model\CartItemInterface;
use CoreShop\Component\Core\Product\ProductTaxCalculatorFactoryInterface;
use CoreShop\Component\Core\Provider\AddressProviderInterface;
use CoreShop\Component\Order\Calculator\PurchasableCalculatorInterface;
use CoreShop\Component\Order\Model\CartInterface;
use CoreShop\Component\Order\Processor\CartProcessorInterface;
use CoreShop\Component\Order\Processor\CartItemProcessorInterface;
use CoreShop\Component\Taxation\Calculator\TaxCalculatorInterface;
use Webmozart\Assert\Assert;

final class CartItemProcessor implements CartProcessorInterface
final class CartItemProcessor implements CartItemProcessorInterface
{
/**
* @var PurchasableCalculatorInterface
*/
private $productPriceCalculator;

/**
* @var ProductTaxCalculatorFactoryInterface
*/
Expand All @@ -40,111 +32,84 @@ final class CartItemProcessor implements CartProcessorInterface
private $defaultAddressProvider;

/**
* @param PurchasableCalculatorInterface $productPriceCalculator
* @param ProductTaxCalculatorFactoryInterface $taxCalculator
* @param AddressProviderInterface $defaultAddressProvider
*/
public function __construct(
PurchasableCalculatorInterface $productPriceCalculator,
ProductTaxCalculatorFactoryInterface $taxCalculator,
AddressProviderInterface $defaultAddressProvider
) {
$this->productPriceCalculator = $productPriceCalculator;
$this->taxCalculator = $taxCalculator;
$this->defaultAddressProvider = $defaultAddressProvider;
}

/**
* {@inheritdoc}
*/
public function process(CartInterface $cart)
public function processCartItem(CartItemInterface $cartItem, int $itemPrice, int $itemRetailPrice, int $itemDiscountPrice, int $itemDiscount, array $context)
{
$store = $cart->getStore();

/**
* @var StoreInterface $store
*/
Assert::isInstanceOf($store, StoreInterface::class);

$context = [
'store' => $store,
'customer' => $cart->getCustomer() ?: null,
'currency' => $cart->getCurrency(),
'country' => $store->getBaseCountry(),
'cart' => $cart,
];

/**
* @var CartItemInterface $item
*/
foreach ($cart->getItems() as $item) {
$product = $item->getProduct();

$taxCalculator = $this->taxCalculator->getTaxCalculator($product, $cart->getShippingAddress() ?: $this->defaultAddressProvider->getAddress($cart));

$itemPrice = $this->productPriceCalculator->getPrice($product, $context, true);
$itemPriceWithoutDiscount = $this->productPriceCalculator->getPrice($product, $context);
$itemRetailPrice = $this->productPriceCalculator->getRetailPrice($product, $context);
$itemDiscountPrice = $this->productPriceCalculator->getDiscountPrice($product, $context);
$itemDiscount = $this->productPriceCalculator->getDiscount($product, $context, $itemPriceWithoutDiscount);

if ($taxCalculator instanceof TaxCalculatorInterface) {
if ($store->getUseGrossPrice()) {
$totalTaxAmount = $taxCalculator->getTaxesAmountFromGross($itemPrice * $item->getQuantity());
$itemPriceTax = $taxCalculator->getTaxesAmountFromGross($itemPrice);
$itemRetailPriceTaxAmount = $taxCalculator->getTaxesAmountFromGross($itemRetailPrice);
$itemDiscountTax = $taxCalculator->getTaxesAmountFromGross($itemDiscount);
$itemDiscountPriceTax = $taxCalculator->getTaxesAmountFromGross($itemDiscountPrice);

$item->setTotal($itemPrice * $item->getQuantity(), true);
$item->setTotal($item->getTotal(true) - $totalTaxAmount, false);

$item->setItemPrice($itemPrice, true);
$item->setItemPrice($itemPrice - $itemPriceTax, false);

$item->setItemRetailPrice($itemRetailPrice, true);
$item->setItemRetailPrice($itemRetailPrice - $itemRetailPriceTaxAmount, false);

$item->setItemDiscountPrice($itemDiscountPrice, true);
$item->setItemDiscountPrice($itemDiscountPrice - $itemDiscountTax, false);

$item->setItemDiscount($itemDiscount, true);
$item->setItemDiscount($itemDiscount - $itemDiscountPriceTax, false);
} else {
$totalTaxAmount = $taxCalculator->getTaxesAmount($itemPrice * $item->getQuantity());
$itemPriceTax = $taxCalculator->getTaxesAmount($itemPrice);
$itemRetailPriceTaxAmount = $taxCalculator->getTaxesAmount($itemRetailPrice);
$itemDiscountTax = $taxCalculator->getTaxesAmount($itemDiscount);
$itemDiscountPriceTax = $taxCalculator->getTaxesAmount($itemDiscountPrice);

$item->setTotal($itemPrice * $item->getQuantity(), false);
$item->setTotal($itemPrice * $item->getQuantity() + $totalTaxAmount, true);

$item->setItemPrice($itemPrice, false);
$item->setItemPrice($itemPrice + $itemPriceTax, true);

$item->setItemRetailPrice($itemRetailPrice, false);
$item->setItemRetailPrice($itemRetailPrice + $itemRetailPriceTaxAmount, true);

$item->setItemDiscountPrice($itemDiscountPrice, false);
$item->setItemDiscountPrice($itemDiscountPrice + $itemDiscountTax, true);

$item->setItemDiscount($itemDiscount, false);
$item->setItemDiscount($itemDiscount + $itemDiscountPriceTax, true);
}
$product = $cartItem->getProduct();
$cart = $context['cart'];
$store = $context['store'];

$taxCalculator = $this->taxCalculator->getTaxCalculator($product, $cart->getShippingAddress() ?: $this->defaultAddressProvider->getAddress($cart));

if ($taxCalculator instanceof TaxCalculatorInterface) {
if ($store->getUseGrossPrice()) {
$totalTaxAmount = $taxCalculator->getTaxesAmountFromGross($itemPrice * $cartItem->getQuantity());
$itemPriceTax = $taxCalculator->getTaxesAmountFromGross($itemPrice);
$itemRetailPriceTaxAmount = $taxCalculator->getTaxesAmountFromGross($itemRetailPrice);
$itemDiscountTax = $taxCalculator->getTaxesAmountFromGross($itemDiscount);
$itemDiscountPriceTax = $taxCalculator->getTaxesAmountFromGross($itemDiscountPrice);

$cartItem->setTotal($itemPrice * $cartItem->getQuantity(), true);
$cartItem->setTotal($cartItem->getTotal(true) - $totalTaxAmount, false);

$cartItem->setItemPrice($itemPrice, true);
$cartItem->setItemPrice($itemPrice - $itemPriceTax, false);

$cartItem->setItemRetailPrice($itemRetailPrice, true);
$cartItem->setItemRetailPrice($itemRetailPrice - $itemRetailPriceTaxAmount, false);

$cartItem->setItemDiscountPrice($itemDiscountPrice, true);
$cartItem->setItemDiscountPrice($itemDiscountPrice - $itemDiscountTax, false);

$cartItem->setItemDiscount($itemDiscount, true);
$cartItem->setItemDiscount($itemDiscount - $itemDiscountPriceTax, false);
} else {
$item->setTotal($itemPrice * $item->getQuantity(), false);
$item->setTotal($itemPrice * $item->getQuantity(), true);
$totalTaxAmount = $taxCalculator->getTaxesAmount($itemPrice * $cartItem->getQuantity());
$itemPriceTax = $taxCalculator->getTaxesAmount($itemPrice);
$itemRetailPriceTaxAmount = $taxCalculator->getTaxesAmount($itemRetailPrice);
$itemDiscountTax = $taxCalculator->getTaxesAmount($itemDiscount);
$itemDiscountPriceTax = $taxCalculator->getTaxesAmount($itemDiscountPrice);

$cartItem->setTotal($itemPrice * $cartItem->getQuantity(), false);
$cartItem->setTotal($itemPrice * $cartItem->getQuantity() + $totalTaxAmount, true);

$cartItem->setItemPrice($itemPrice, false);
$cartItem->setItemPrice($itemPrice + $itemPriceTax, true);

$item->setItemRetailPrice($itemRetailPrice, false);
$item->setItemRetailPrice($itemRetailPrice, true);
$cartItem->setItemRetailPrice($itemRetailPrice, false);
$cartItem->setItemRetailPrice($itemRetailPrice + $itemRetailPriceTaxAmount, true);

$item->setItemDiscountPrice($itemDiscountPrice, false);
$item->setItemDiscountPrice($itemDiscountPrice, true);
$cartItem->setItemDiscountPrice($itemDiscountPrice, false);
$cartItem->setItemDiscountPrice($itemDiscountPrice + $itemDiscountTax, true);

$item->setItemDiscount($itemDiscount, false);
$item->setItemDiscount($itemDiscount, true);
$cartItem->setItemDiscount($itemDiscount, false);
$cartItem->setItemDiscount($itemDiscount + $itemDiscountPriceTax, true);
}
} else {
$cartItem->setTotal($itemPrice * $cartItem->getQuantity(), false);
$cartItem->setTotal($itemPrice * $cartItem->getQuantity(), true);

$cartItem->setItemRetailPrice($itemRetailPrice, false);
$cartItem->setItemRetailPrice($itemRetailPrice, true);

$cartItem->setItemDiscountPrice($itemDiscountPrice, false);
$cartItem->setItemDiscountPrice($itemDiscountPrice, true);

$cartItem->setItemDiscount($itemDiscount, false);
$cartItem->setItemDiscount($itemDiscount, true);
}
}
}
90 changes: 90 additions & 0 deletions src/CoreShop/Component/Core/Order/Processor/CartItemsProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* CoreShop.
*
* This source file is subject to the GNU General Public License version 3 (GPLv3)
* For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
* files that are distributed with this source code.
*
* @copyright Copyright (c) 2015-2019 Dominik Pfaffenbauer (https://www.pfaffenbauer.at)
* @license https://www.coreshop.org/license GNU General Public License version 3 (GPLv3)
*/

namespace CoreShop\Component\Core\Order\Processor;

use CoreShop\Component\Core\Model\CartItemInterface;
use CoreShop\Component\Core\Model\StoreInterface;
use CoreShop\Component\Order\Calculator\PurchasableCalculatorInterface;
use CoreShop\Component\Order\Model\CartInterface;
use CoreShop\Component\Order\Processor\CartItemProcessorInterface;
use CoreShop\Component\Order\Processor\CartProcessorInterface;
use Webmozart\Assert\Assert;

final class CartItemsProcessor implements CartProcessorInterface
{
/**
* @var PurchasableCalculatorInterface
*/
private $productPriceCalculator;

/**
* @var CartItemProcessorInterface
*/
private $cartItemProcessor;

/**
* @param PurchasableCalculatorInterface $productPriceCalculator
* @param CartItemProcessorInterface $cartItemProcessor
*/
public function __construct(
PurchasableCalculatorInterface $productPriceCalculator,
CartItemProcessorInterface $cartItemProcessor
) {
$this->productPriceCalculator = $productPriceCalculator;
$this->cartItemProcessor = $cartItemProcessor;
}


/**
* {@inheritdoc}
*/
public function process(CartInterface $cart)
{
$store = $cart->getStore();

/**
* @var StoreInterface $store
*/
Assert::isInstanceOf($store, StoreInterface::class);

$context = [
'store' => $store,
'customer' => $cart->getCustomer() ?: null,
'currency' => $cart->getCurrency(),
'country' => $store->getBaseCountry(),
'cart' => $cart,
];

/**
* @var CartItemInterface $item
*/
foreach ($cart->getItems() as $item) {
$product = $item->getProduct();

$itemPrice = $this->productPriceCalculator->getPrice($product, $context, true);
$itemPriceWithoutDiscount = $this->productPriceCalculator->getPrice($product, $context);
$itemRetailPrice = $this->productPriceCalculator->getRetailPrice($product, $context);
$itemDiscountPrice = $this->productPriceCalculator->getDiscountPrice($product, $context);
$itemDiscount = $this->productPriceCalculator->getDiscount($product, $context, $itemPriceWithoutDiscount);

$this->cartItemProcessor->processCartItem(
$item,
$itemPrice,
$itemRetailPrice,
$itemDiscountPrice,
$itemDiscount,
$context
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
/**
* CoreShop.
*
* This source file is subject to the GNU General Public License version 3 (GPLv3)
* For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
* files that are distributed with this source code.
*
* @copyright Copyright (c) 2015-2019 Dominik Pfaffenbauer (https://www.pfaffenbauer.at)
* @license https://www.coreshop.org/license GNU General Public License version 3 (GPLv3)
*/

namespace CoreShop\Component\Order\Processor;

use CoreShop\Component\Order\Model\CartItemInterface;

interface CartItemProcessorInterface
{
/**
* @param CartItemInterface $cartItem
* @param int $itemPrice
* @param int $itemRetailPrice
* @param int $itemDiscountPrice
* @param int $itemDiscount
* @param array $context
*/
public function processCartItem(
CartItemInterface $cartItem,
int $itemPrice,
int $itemRetailPrice,
int $itemDiscountPrice,
int $itemDiscount,
array $context
);
}

0 comments on commit b7a8f05

Please sign in to comment.