OrderDepositTaxesApplicator   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 31
dl 0
loc 66
rs 10
c 1
b 1
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A apply() 0 26 5
A __construct() 0 8 1
A addAdjustment() 0 14 1
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\TaxRateInterface;
12
use Sylius\Component\Order\Model\OrderItemUnitInterface;
13
use Sylius\Component\Core\Taxation\Applicator\OrderTaxesApplicatorInterface;
14
use Sylius\Component\Order\Factory\AdjustmentFactoryInterface;
15
use Sylius\Component\Resource\Repository\RepositoryInterface;
16
use Sylius\Component\Taxation\Calculator\CalculatorInterface;
17
18
/**
19
 * Apply deposit tax adjustment to order item units
20
 */
21
final class OrderDepositTaxesApplicator implements OrderTaxesApplicatorInterface
22
{
23
    /** @var AdjustmentFactoryInterface */
24
    private $adjustmentFactory;
25
26
    /** @var CalculatorInterface */
27
    private $calculator;
28
29
    /** @var RepositoryInterface */
30
    private $taxRateRepository;
31
32
    public function __construct(
33
        AdjustmentFactoryInterface $adjustmentFactory,
34
        CalculatorInterface $calculator,
35
        RepositoryInterface $taxRateRepository
36
    ) {
37
        $this->adjustmentFactory = $adjustmentFactory;
38
        $this->calculator = $calculator;
39
        $this->taxRateRepository = $taxRateRepository;
40
    }
41
42
    public function apply(OrderInterface $order, ZoneInterface $zone): void
43
    {
44
        foreach ($order->getItems() as $item) {
45
            /** @var ProductVariantInterface $variant */
46
            $variant = $item->getVariant();
47
48
            $taxCategory = $variant->getDepositTaxCategory();
49
50
            /** @var TaxRateInterface|null $taxRate */
51
            $taxRate = $this->taxRateRepository->findOneBy(['category' => $taxCategory, 'zone' => $zone]);
52
            if (null == $taxRate) {
53
                continue;
54
            }
55
56
            foreach ($item->getUnits() as $unit) {
57
                $depositPrice = $unit->getAdjustmentsTotal('deposit');
58
59
                $taxAmount = $this->calculator->calculate((float) $depositPrice, $taxRate);
60
                if (0.00 === $taxAmount) {
61
                    continue;
62
                }
63
64
                $this->addAdjustment(
65
                    $unit,
66
                    $taxRate,
67
                    (int) $taxAmount
68
                );
69
            }
70
        }
71
    }
72
73
    private function addAdjustment(OrderItemUnitInterface $unit, TaxRateInterface $taxRate, int $taxAmount): void
74
    {
75
        $unitTaxAdjustment = $this->adjustmentFactory->createWithData(
76
            AdjustmentInterface::TAX_ADJUSTMENT,
77
            (string) $taxRate->getLabel(),
78
            $taxAmount,
79
            $taxRate->isIncludedInPrice(),
80
            [
81
                'taxRateCode' => $taxRate->getCode(),
82
                'taxRateName' => $taxRate->getName(),
83
                'taxRateAmount' => $taxRate->getAmount(),
84
            ]
85
        );
86
        $unit->addAdjustment($unitTaxAdjustment);
87
    }
88
}
89