Completed
Push — master ( 0f74a6...eca3e7 )
by Kamil
20:39
created

OrderTaxesProcessor::process()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 23
rs 8.5906
nc 5
cc 5
eloc 12
nop 1
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\Taxation\Processor;
13
14
use Sylius\Component\Addressing\Matcher\ZoneMatcherInterface;
15
use Sylius\Component\Addressing\Model\AddressInterface;
16
use Sylius\Component\Addressing\Model\ZoneInterface;
17
use Sylius\Component\Core\Model\AdjustmentInterface;
18
use Sylius\Component\Core\Model\OrderInterface;
19
use Sylius\Component\Core\Provider\ZoneProviderInterface;
20
use Sylius\Component\Core\Taxation\Exception\UnsupportedTaxCalculationStrategyException;
21
use Sylius\Component\Core\Taxation\Strategy\TaxCalculationStrategyInterface;
22
use Sylius\Component\Registry\PrioritizedServiceRegistryInterface;
23
24
/**
25
 * @author Paweł Jędrzejewski <[email protected]>
26
 * @author Mateusz Zalewski <[email protected]>
27
 * @author Mark McKelvie <[email protected]>
28
 */
29
class OrderTaxesProcessor implements OrderTaxesProcessorInterface
30
{
31
    /**
32
     * @var ZoneProviderInterface
33
     */
34
    protected $defaultTaxZoneProvider;
35
36
    /**
37
     * @var ZoneMatcherInterface
38
     */
39
    protected $zoneMatcher;
40
41
    /**
42
     * @var PrioritizedServiceRegistryInterface
43
     */
44
    protected $strategyRegistry;
45
46
    /**
47
     * @param ZoneProviderInterface $defaultTaxZoneProvider
48
     * @param ZoneMatcherInterface $zoneMatcher
49
     * @param PrioritizedServiceRegistryInterface $strategyRegistry
50
     */
51
    public function __construct(
52
        ZoneProviderInterface $defaultTaxZoneProvider,
53
        ZoneMatcherInterface $zoneMatcher,
54
        PrioritizedServiceRegistryInterface $strategyRegistry
55
    ) {
56
        $this->defaultTaxZoneProvider = $defaultTaxZoneProvider;
57
        $this->zoneMatcher = $zoneMatcher;
58
        $this->strategyRegistry = $strategyRegistry;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function process(OrderInterface $order)
65
    {
66
        $this->clearTaxes($order);
67
        if ($order->isEmpty()) {
68
            return;
69
        }
70
71
        $zone = $this->getTaxZone($order->getShippingAddress());
72
73
        if (null === $zone) {
74
            return;
75
        }
76
77
        /** @var TaxCalculationStrategyInterface $strategy */
78
        foreach ($this->strategyRegistry->all() as $strategy) {
79
            if ($strategy->supports($order, $zone)) {
80
                $strategy->applyTaxes($order, $zone);
81
                return;
82
            }
83
        }
84
85
        throw new UnsupportedTaxCalculationStrategyException();
86
    }
87
88
    /**
89
     * @param AddressInterface|null $shippingAddress
90
     *
91
     * @return ZoneInterface|null
92
     */
93
    private function getTaxZone(AddressInterface $shippingAddress = null)
94
    {
95
        $zone = null;
96
        if (null !== $shippingAddress) {
97
            $zone = $this->zoneMatcher->match($shippingAddress);
98
        }
99
100
        return $zone ?: $this->defaultTaxZoneProvider->getZone();
101
    }
102
103
    /**
104
     * @param OrderInterface $order
105
     */
106
    private function clearTaxes(OrderInterface $order)
107
    {
108
        $order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
109
        foreach ($order->getItems() as $item) {
110
            $item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
111
        }
112
    }
113
}
114