-
-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathOrderItemsTaxesApplicator.php
106 lines (90 loc) · 3.58 KB
/
OrderItemsTaxesApplicator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\RefundPlugin\TaxesApplicator;
use Sylius\Component\Addressing\Model\ZoneInterface;
use Sylius\Component\Core\Distributor\IntegerDistributorInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\Component\Core\Model\TaxRateInterface;
use Sylius\Component\Core\Taxation\Applicator\OrderTaxesApplicatorInterface;
use Sylius\Component\Order\Factory\AdjustmentFactoryInterface;
use Sylius\Component\Taxation\Calculator\CalculatorInterface;
use Sylius\Component\Taxation\Resolver\TaxRateResolverInterface;
use Sylius\RefundPlugin\Entity\AdjustmentInterface;
use Webmozart\Assert\Assert;
/**
* @internal
*
* This class is not covered by the backward compatibility promise and it will be removed after update Sylius to 1.9.
* It is a duplication of a logic from Sylius to provide proper adjustments handling.
*/
final class OrderItemsTaxesApplicator implements OrderTaxesApplicatorInterface
{
/** @var CalculatorInterface */
private $calculator;
/** @var AdjustmentFactoryInterface */
private $adjustmentFactory;
/** @var IntegerDistributorInterface */
private $distributor;
/** @var TaxRateResolverInterface */
private $taxRateResolver;
public function __construct(
CalculatorInterface $calculator,
AdjustmentFactoryInterface $adjustmentFactory,
IntegerDistributorInterface $distributor,
TaxRateResolverInterface $taxRateResolver
) {
$this->calculator = $calculator;
$this->adjustmentFactory = $adjustmentFactory;
$this->distributor = $distributor;
$this->taxRateResolver = $taxRateResolver;
}
/**
* @throws \InvalidArgumentException
*/
public function apply(OrderInterface $order, ZoneInterface $zone): void
{
foreach ($order->getItems() as $item) {
$quantity = $item->getQuantity();
Assert::notSame($quantity, 0, 'Cannot apply tax to order item with 0 quantity.');
/** @var TaxRateInterface|null $taxRate */
$taxRate = $this->taxRateResolver->resolve($item->getVariant(), ['zone' => $zone]);
if (null === $taxRate) {
continue;
}
$totalTaxAmount = $this->calculator->calculate($item->getTotal(), $taxRate);
$splitTaxes = $this->distributor->distribute($totalTaxAmount, $quantity);
/** @var OrderItemUnitInterface $unit */
foreach ($item->getUnits() as $index => $unit) {
if (0 === $splitTaxes[$index]) {
continue;
}
$this->addAdjustment($unit, $splitTaxes[$index], $taxRate);
}
}
}
private function addAdjustment(OrderItemUnitInterface $unit, int $taxAmount, TaxRateInterface $taxRate): void
{
/** @var AdjustmentInterface $unitTaxAdjustment */
$unitTaxAdjustment = $this->adjustmentFactory->createWithData(
AdjustmentInterface::TAX_ADJUSTMENT,
$taxRate->getLabel(),
$taxAmount,
$taxRate->isIncludedInPrice()
);
$unitTaxAdjustment->setDetails([
'taxRateCode' => $taxRate->getCode(),
'taxRateName' => $taxRate->getName(),
'taxRateAmount' => $taxRate->getAmount(),
]);
$unit->addAdjustment($unitTaxAdjustment);
}
}