Completed
Push — master ( bf2eb3...b959e3 )
by Paweł
215:08 queued 200:46
created

applyAdjustmentsOnItemUnits()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 0
loc 14
rs 9.4285
cc 3
eloc 8
nc 3
nop 3
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Component\Core\Promotion\Applicator;
13
14
use Sylius\Component\Core\Distributor\IntegerDistributorInterface;
15
use Sylius\Component\Core\Model\AdjustmentInterface;
16
use Sylius\Component\Core\Model\OrderInterface;
17
use Sylius\Component\Core\Model\OrderItemInterface;
18
use Sylius\Component\Order\Factory\AdjustmentFactoryInterface;
19
use Sylius\Component\Order\Model\OrderItemUnitInterface;
20
use Sylius\Component\Originator\Originator\OriginatorInterface;
21
use Sylius\Component\Promotion\Model\PromotionInterface;
22
use Webmozart\Assert\Assert;
23
24
/**
25
 * @author Mateusz Zalewski <[email protected]>
26
 */
27
class UnitsPromotionAdjustmentsApplicator implements UnitsPromotionAdjustmentsApplicatorInterface
28
{
29
    /**
30
     * @var AdjustmentFactoryInterface
31
     */
32
    private $adjustmentFactory;
33
34
    /**
35
     * @var IntegerDistributorInterface
36
     */
37
    private $distributor;
38
39
    /**
40
     * @var OriginatorInterface
41
     */
42
    private $originator;
43
44
    /**
45
     * @param AdjustmentFactoryInterface $adjustmentFactory
46
     * @param IntegerDistributorInterface $distributor
47
     * @param OriginatorInterface $originator
48
     */
49
    public function __construct(
50
        AdjustmentFactoryInterface $adjustmentFactory,
51
        IntegerDistributorInterface $distributor,
52
        OriginatorInterface $originator
53
    ) {
54
        $this->adjustmentFactory = $adjustmentFactory;
55
        $this->distributor = $distributor;
56
        $this->originator = $originator;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function apply(OrderInterface $order, PromotionInterface $promotion, array $adjustmentsAmounts)
63
    {
64
        Assert::eq($order->countItems(), count($adjustmentsAmounts));
65
66
        $i = 0;
67
        foreach ($order->getItems() as $item) {
68
            $adjustmentAmount = $adjustmentsAmounts[$i++];
69
            if (0 === $adjustmentAmount) {
70
                continue;
71
            }
72
73
            $this->applyAdjustmentsOnItemUnits($item, $promotion, $adjustmentAmount);
74
        }
75
    }
76
77
    /**
78
     * @param OrderItemInterface $item
79
     * @param PromotionInterface $promotion
80
     * @param int $itemPromotionAmount
81
     */
82
    private function applyAdjustmentsOnItemUnits(OrderItemInterface $item, PromotionInterface $promotion, $itemPromotionAmount)
83
    {
84
        $splitPromotionAmount = $this->distributor->distribute($itemPromotionAmount, $item->getQuantity());
85
86
        $i = 0;
87
        foreach ($item->getUnits() as $unit) {
88
            $promotionAmount = $splitPromotionAmount[$i++];
89
            if (0 === $promotionAmount) {
90
                continue;
91
            }
92
93
            $this->addAdjustment($promotion, $unit, $promotionAmount);
94
        }
95
    }
96
97
    /**
98
     * @param PromotionInterface $promotion
99
     * @param OrderItemUnitInterface $unit
100
     * @param int $amount
101
     */
102
    private function addAdjustment(PromotionInterface $promotion, OrderItemUnitInterface $unit, $amount)
103
    {
104
        $adjustment = $this->adjustmentFactory
105
            ->createWithData(AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT, $promotion->getName(), $amount)
106
        ;
107
108
        $this->originator->setOrigin($adjustment, $promotion);
109
110
        $unit->addAdjustment($adjustment);
111
    }
112
}
113