Passed
Push — master ( 9d9530...9d60e1 )
by G
07:54
created

OrderDepositTaxesApplicator::apply()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 21
nc 5
nop 2
dl 0
loc 37
rs 8.6506
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewebe\SyliusProductDepositPlugin\Taxation;
6
7
use Gewebe\SyliusProductDepositPlugin\Entity\ProductVariantInterface;
8
use Sylius\Component\Addressing\Model\ZoneInterface;
9
use Sylius\Component\Core\Model\AdjustmentInterface;
10
use Sylius\Component\Core\Model\OrderInterface;
11
use Sylius\Component\Core\Model\TaxRate;
12
use Sylius\Component\Core\Model\OrderItemInterface;
13
use Sylius\Component\Order\Model\OrderItemUnitInterface;
14
use Sylius\Component\Core\Taxation\Applicator\OrderTaxesApplicatorInterface;
15
use Sylius\Component\Order\Factory\AdjustmentFactoryInterface;
16
use Sylius\Component\Resource\Repository\RepositoryInterface;
17
use Sylius\Component\Taxation\Calculator\CalculatorInterface;
18
19
/**
20
 * Apply deposit tax to order item units
21
 */
22
final class OrderDepositTaxesApplicator implements OrderTaxesApplicatorInterface
23
{
24
    /**
25
     * @var CalculatorInterface
26
     */
27
    private $calculator;
28
29
    /**
30
     * @var AdjustmentFactoryInterface
31
     */
32
    private $adjustmentFactory;
33
34
    /**
35
     * @var RepositoryInterface
36
     */
37
    private $taxRateRepository;
38
39
    /**
40
     * @param CalculatorInterface $calculator
41
     * @param AdjustmentFactoryInterface $adjustmentFactory
42
     * @param RepositoryInterface $taxRateRepository
43
     */
44
    public function __construct(
45
        CalculatorInterface $calculator,
46
        AdjustmentFactoryInterface $adjustmentFactory,
47
        RepositoryInterface $taxRateRepository
48
    ) {
49
        $this->calculator = $calculator;
50
        $this->adjustmentFactory = $adjustmentFactory;
51
        $this->taxRateRepository = $taxRateRepository;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function apply(OrderInterface $order, ZoneInterface $zone): void
58
    {
59
        /** @var OrderItemInterface $item */
60
        foreach ($order->getItems() as $item) {
61
62
            /** @var ProductVariantInterface $variant */
63
            $variant = $item->getVariant();
64
65
            $channel = $order->getChannel();
66
            if (null == $channel) {
67
                continue;
68
            }
69
70
            $channelDeposit = $variant->getChannelDepositForChannel($channel);
71
            if (null == $channelDeposit) {
72
                continue;
73
            }
74
75
            $taxCategory = $variant->getDepositTaxCategory();
76
77
            /** @var TaxRate|null $taxRate */
78
            $taxRate = $this->taxRateRepository->findOneBy(['category' => $taxCategory, 'zone' => $zone]);
79
            if (null == $taxRate) {
80
                continue;
81
            }
82
83
            foreach ($item->getUnits() as $unit) {
84
                $taxAmount = $this->calculator->calculate((float) $channelDeposit->getPrice(), $taxRate);
85
                if (0.00 === $taxAmount) {
86
                    continue;
87
                }
88
89
                $this->addTaxAdjustment(
90
                    $unit,
91
                    (int) $taxAmount,
92
                    (string) $taxRate->getLabel(),
93
                    $taxRate->isIncludedInPrice()
94
                );
95
            }
96
        }
97
    }
98
99
    /**
100
     * @param OrderItemUnitInterface $unit
101
     * @param int $taxAmount
102
     * @param string $label
103
     * @param bool $included
104
     */
105
    private function addTaxAdjustment(OrderItemUnitInterface $unit, int $taxAmount, string $label, bool $included): void
106
    {
107
        $unitTaxAdjustment = $this->adjustmentFactory->createWithData(
108
            AdjustmentInterface::TAX_ADJUSTMENT,
109
            $label,
110
            $taxAmount,
111
            $included
112
        );
113
        $unit->addAdjustment($unitTaxAdjustment);
114
    }
115
}
116