diff --git a/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml b/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml index 31a464fa760..9f9c0d03dde 100644 --- a/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml +++ b/src/Sylius/Bundle/CoreBundle/Resources/config/services.xml @@ -40,6 +40,8 @@ Sylius\Component\Core\OrderProcessing\PricesRecalculator Sylius\Component\Core\OrderProcessing\OrderRecalculator + Sylius\Component\Core\Remover\AdjustmentsRemover + Sylius\Component\Core\Taxation\Applicator\OrderShipmentTaxesApplicator Sylius\Component\Core\Taxation\Applicator\OrderItemsTaxesApplicator Sylius\Component\Core\Taxation\Applicator\OrderItemUnitsTaxesApplicator @@ -314,6 +316,7 @@ + @@ -332,6 +335,8 @@ + + diff --git a/src/Sylius/Component/Core/OrderProcessing/OrderRecalculator.php b/src/Sylius/Component/Core/OrderProcessing/OrderRecalculator.php index 969b5140c7c..4bb782d7dde 100644 --- a/src/Sylius/Component/Core/OrderProcessing/OrderRecalculator.php +++ b/src/Sylius/Component/Core/OrderProcessing/OrderRecalculator.php @@ -12,14 +12,21 @@ namespace Sylius\Component\Core\OrderProcessing; use Sylius\Component\Core\Model\OrderInterface; +use Sylius\Component\Core\Remover\AdjustmentsRemoverInterface; use Sylius\Component\Core\Taxation\Processor\OrderTaxesProcessorInterface; use Sylius\Component\Promotion\Processor\PromotionProcessorInterface; /** * @author Jan Góralski + * @author Mateusz Zalewski */ class OrderRecalculator implements OrderRecalculatorInterface { + /** + * @var AdjustmentsRemoverInterface + */ + private $adjustmentsRemover; + /** * @var OrderTaxesProcessorInterface */ @@ -41,17 +48,20 @@ class OrderRecalculator implements OrderRecalculatorInterface private $shippingChargesProcessor; /** + * @param AdjustmentsRemoverInterface $adjustmentsRemover * @param OrderTaxesProcessorInterface $taxesProcessor * @param PricesRecalculatorInterface $pricesRecalculator * @param PromotionProcessorInterface $promotionProcessor * @param ShippingChargesProcessorInterface $shippingChargesProcessor */ public function __construct( + AdjustmentsRemoverInterface $adjustmentsRemover, OrderTaxesProcessorInterface $taxesProcessor, PricesRecalculatorInterface $pricesRecalculator, PromotionProcessorInterface $promotionProcessor, ShippingChargesProcessorInterface $shippingChargesProcessor ) { + $this->adjustmentsRemover = $adjustmentsRemover; $this->taxesProcessor = $taxesProcessor; $this->pricesRecalculator = $pricesRecalculator; $this->promotionProcessor = $promotionProcessor; @@ -65,6 +75,7 @@ public function __construct( */ public function recalculate(OrderInterface $order) { + $this->adjustmentsRemover->removeFrom($order); $this->pricesRecalculator->recalculate($order); $this->shippingChargesProcessor->applyShippingCharges($order); $this->promotionProcessor->process($order); diff --git a/src/Sylius/Component/Core/Remover/AdjustmentsRemover.php b/src/Sylius/Component/Core/Remover/AdjustmentsRemover.php new file mode 100644 index 00000000000..a4f9a33ba52 --- /dev/null +++ b/src/Sylius/Component/Core/Remover/AdjustmentsRemover.php @@ -0,0 +1,38 @@ + + */ +class AdjustmentsRemover implements AdjustmentsRemoverInterface +{ + /** + * {@inheritdoc} + */ + public function removeFrom(OrderInterface $order) + { + $adjustmentsToRemove = [ + AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT, + AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT, + AdjustmentInterface::TAX_ADJUSTMENT + ]; + + foreach ($adjustmentsToRemove as $type) { + $order->removeAdjustmentsRecursively($type); + } + } +} diff --git a/src/Sylius/Component/Core/Remover/AdjustmentsRemoverInterface.php b/src/Sylius/Component/Core/Remover/AdjustmentsRemoverInterface.php new file mode 100644 index 00000000000..4ed259a1244 --- /dev/null +++ b/src/Sylius/Component/Core/Remover/AdjustmentsRemoverInterface.php @@ -0,0 +1,25 @@ + + */ +interface AdjustmentsRemoverInterface +{ + /** + * @param OrderInterface $order + */ + public function removeFrom(OrderInterface $order); +} diff --git a/src/Sylius/Component/Core/spec/OrderProcessing/OrderRecalculatorSpec.php b/src/Sylius/Component/Core/spec/OrderProcessing/OrderRecalculatorSpec.php index 1c2d6b89b33..b95b323ba78 100644 --- a/src/Sylius/Component/Core/spec/OrderProcessing/OrderRecalculatorSpec.php +++ b/src/Sylius/Component/Core/spec/OrderProcessing/OrderRecalculatorSpec.php @@ -17,6 +17,7 @@ use Sylius\Component\Core\OrderProcessing\OrderRecalculatorInterface; use Sylius\Component\Core\OrderProcessing\PricesRecalculatorInterface; use Sylius\Component\Core\OrderProcessing\ShippingChargesProcessorInterface; +use Sylius\Component\Core\Remover\AdjustmentsRemoverInterface; use Sylius\Component\Core\Taxation\Processor\OrderTaxesProcessorInterface; use Sylius\Component\Promotion\Processor\PromotionProcessorInterface; @@ -28,12 +29,19 @@ class OrderRecalculatorSpec extends ObjectBehavior { function let( + AdjustmentsRemoverInterface $adjustmentsRemover, OrderTaxesProcessorInterface $taxesProcessor, PricesRecalculatorInterface $pricesRecalculator, PromotionProcessorInterface $promotionProcessor, ShippingChargesProcessorInterface $shippingChargesProcessor ) { - $this->beConstructedWith($taxesProcessor, $pricesRecalculator, $promotionProcessor, $shippingChargesProcessor); + $this->beConstructedWith( + $adjustmentsRemover, + $taxesProcessor, + $pricesRecalculator, + $promotionProcessor, + $shippingChargesProcessor + ); } function it_is_initializable() @@ -47,13 +55,15 @@ function it_implements_order_recalculator_interface() } function it_recalculates_order_promotions_taxes_and_shipping_charges( + AdjustmentsRemoverInterface $adjustmentsRemover, PromotionProcessorInterface $promotionProcessor, PricesRecalculatorInterface $pricesRecalculator, OrderTaxesProcessorInterface $taxesProcessor, ShippingChargesProcessorInterface $shippingChargesProcessor, OrderInterface $order ) { - $pricesRecalculator->recalculate($order); + $adjustmentsRemover->removeFrom($order)->shouldBeCalled(); + $pricesRecalculator->recalculate($order)->shouldBeCalled(); $promotionProcessor->process($order)->shouldBeCalled(); $taxesProcessor->process($order)->shouldBeCalled(); $shippingChargesProcessor->applyShippingCharges($order)->shouldBeCalled(); diff --git a/src/Sylius/Component/Core/spec/Remover/AdjustmentsRemoverSpec.php b/src/Sylius/Component/Core/spec/Remover/AdjustmentsRemoverSpec.php new file mode 100644 index 00000000000..a522c5872ec --- /dev/null +++ b/src/Sylius/Component/Core/spec/Remover/AdjustmentsRemoverSpec.php @@ -0,0 +1,46 @@ + + */ +class AdjustmentsRemoverSpec extends ObjectBehavior +{ + function it_is_initializable() + { + $this->shouldHaveType('Sylius\Component\Core\Remover\AdjustmentsRemover'); + } + + function it_implements_adjustments_remover_interface() + { + $this->shouldImplement(AdjustmentsRemoverInterface::class); + } + + function it_removes_adjustments_from_order_recursively(OrderInterface $order) + { + $order->removeAdjustmentsRecursively(AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT)->shouldBeCalled(); + $order->removeAdjustmentsRecursively(AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT)->shouldBeCalled(); + $order->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT)->shouldBeCalled(); + + $this->removeFrom($order); + } +} diff --git a/src/Sylius/Component/Order/Model/Order.php b/src/Sylius/Component/Order/Model/Order.php index aed4d2a2d6a..53d4851529f 100644 --- a/src/Sylius/Component/Order/Model/Order.php +++ b/src/Sylius/Component/Order/Model/Order.php @@ -460,6 +460,17 @@ public function removeAdjustments($type) } } + /** + * {@inheritdoc} + */ + public function removeAdjustmentsRecursively($type = null) + { + $this->removeAdjustments($type); + foreach ($this->items as $item) { + $item->removeAdjustmentsRecursively($type); + } + } + /** * {@inheritdoc} */ diff --git a/src/Sylius/Component/Order/Model/OrderInterface.php b/src/Sylius/Component/Order/Model/OrderInterface.php index 5b117d94387..62246a5f92f 100644 --- a/src/Sylius/Component/Order/Model/OrderInterface.php +++ b/src/Sylius/Component/Order/Model/OrderInterface.php @@ -158,4 +158,9 @@ public function getAdjustmentsRecursively($type = null); * @return int */ public function getAdjustmentsTotalRecursively($type = null); + + /** + * @param string|null $type + */ + public function removeAdjustmentsRecursively($type = null); } diff --git a/src/Sylius/Component/Order/spec/Model/OrderSpec.php b/src/Sylius/Component/Order/spec/Model/OrderSpec.php index 1a7f4a7591f..1b4bd187b7a 100644 --- a/src/Sylius/Component/Order/spec/Model/OrderSpec.php +++ b/src/Sylius/Component/Order/spec/Model/OrderSpec.php @@ -201,6 +201,48 @@ function it_removes_adjustments_properly(AdjustmentInterface $adjustment) $this->hasAdjustment($adjustment)->shouldReturn(false); } + function it_removes_adjustments_recursively_properly( + AdjustmentInterface $orderAdjustment, + OrderItemInterface $item + ) { + $this->addAdjustment($orderAdjustment); + $this->addItem($item); + + $item->removeAdjustmentsRecursively(null)->shouldBeCalled(); + + $this->removeAdjustmentsRecursively(); + + $this->hasAdjustment($orderAdjustment)->shouldReturn(false); + } + + function it_removes_adjustments_recursively_by_type_properly( + AdjustmentInterface $orderPromotionAdjustment, + AdjustmentInterface $orderTaxAdjustment, + OrderItemInterface $item + ) { + $orderPromotionAdjustment->getType()->willReturn('promotion'); + $orderPromotionAdjustment->isNeutral()->willReturn(true); + $orderPromotionAdjustment->setAdjustable($this)->shouldBeCalled(); + $orderPromotionAdjustment->isLocked()->willReturn(false); + + $orderTaxAdjustment->getType()->willReturn('tax'); + $orderTaxAdjustment->isNeutral()->willReturn(true); + $orderTaxAdjustment->setAdjustable($this)->shouldBeCalled(); + $orderTaxAdjustment->isLocked()->willReturn(false); + + $this->addAdjustment($orderPromotionAdjustment); + $this->addAdjustment($orderTaxAdjustment); + $this->addItem($item); + + $item->removeAdjustmentsRecursively('tax')->shouldBeCalled(); + $orderTaxAdjustment->setAdjustable(null)->shouldBeCalled(); + + $this->removeAdjustmentsRecursively('tax'); + + $this->hasAdjustment($orderPromotionAdjustment)->shouldReturn(true); + $this->hasAdjustment($orderTaxAdjustment)->shouldReturn(false); + } + function it_returns_adjustments_recursively( AdjustmentInterface $orderAdjustment, AdjustmentInterface $itemAdjustment1,