Skip to content

Commit

Permalink
Extract tax rate provider from line items converter
Browse files Browse the repository at this point in the history
  • Loading branch information
GSadee committed Jan 31, 2020
1 parent 757c53f commit 1aca927
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 49 deletions.
37 changes: 13 additions & 24 deletions spec/Converter/LineItemsConverterSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@

namespace spec\Sylius\RefundPlugin\Converter;

use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\RefundPlugin\Converter\LineItemsConverterInterface;
use Sylius\RefundPlugin\Entity\LineItem;
use Sylius\RefundPlugin\Model\OrderItemUnitRefund;
use Sylius\RefundPlugin\Provider\TaxRateProviderInterface;

final class LineItemsConverterSpec extends ObjectBehavior
{
function let(RepositoryInterface $orderItemUnitRepository): void
function let(RepositoryInterface $orderItemUnitRepository, TaxRateProviderInterface $taxRateProvider): void
{
$this->beConstructedWith($orderItemUnitRepository);
$this->beConstructedWith($orderItemUnitRepository, $taxRateProvider);
}

function it_implements_line_items_converter_interface(): void
Expand All @@ -28,9 +27,9 @@ function it_implements_line_items_converter_interface(): void

function it_converts_unit_refunds_to_line_items(
RepositoryInterface $orderItemUnitRepository,
TaxRateProviderInterface $taxRateProvider,
OrderItemUnitInterface $orderItemUnit,
OrderItemInterface $orderItem,
AdjustmentInterface $adjustment
OrderItemInterface $orderItem
): void {
$unitRefund = new OrderItemUnitRefund(1, 500);

Expand All @@ -39,13 +38,10 @@ function it_converts_unit_refunds_to_line_items(
$orderItemUnit->getOrderItem()->willReturn($orderItem);
$orderItemUnit->getTotal()->willReturn(1500);
$orderItemUnit->getTaxTotal()->willReturn(300);
$orderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$adjustment->getWrappedObject()]))
;

$taxRateProvider->provide($orderItemUnit)->willReturn('25%');

$orderItem->getProductName()->willReturn('Portal gun');
$adjustment->getLabel()->willReturn('25%');

$this->convert([$unitRefund])->shouldBeLike([new LineItem(
'Portal gun',
Expand All @@ -61,12 +57,11 @@ function it_converts_unit_refunds_to_line_items(

function it_groups_the_same_line_items_during_converting(
RepositoryInterface $orderItemUnitRepository,
TaxRateProviderInterface $taxRateProvider,
OrderItemUnitInterface $firstOrderItemUnit,
OrderItemUnitInterface $secondOrderItemUnit,
OrderItemInterface $firstOrderItem,
OrderItemInterface $secondOrderItem,
AdjustmentInterface $firstAdjustment,
AdjustmentInterface $secondAdjustment
OrderItemInterface $secondOrderItem
): void {
$firstUnitRefund = new OrderItemUnitRefund(1, 500);
$secondUnitRefund = new OrderItemUnitRefund(2, 960);
Expand All @@ -77,26 +72,20 @@ function it_groups_the_same_line_items_during_converting(
$firstOrderItemUnit->getOrderItem()->willReturn($firstOrderItem);
$firstOrderItemUnit->getTotal()->willReturn(1500);
$firstOrderItemUnit->getTaxTotal()->willReturn(300);
$firstOrderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$firstAdjustment->getWrappedObject()]))
;

$taxRateProvider->provide($firstOrderItemUnit)->willReturn('25%');

$firstOrderItem->getProductName()->willReturn('Portal gun');
$firstAdjustment->getLabel()->willReturn('25%');

$orderItemUnitRepository->find(2)->willReturn($secondOrderItemUnit);

$secondOrderItemUnit->getOrderItem()->willReturn($secondOrderItem);
$secondOrderItemUnit->getTotal()->willReturn(960);
$secondOrderItemUnit->getTaxTotal()->willReturn(160);
$secondOrderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$secondAdjustment->getWrappedObject()]))
;

$taxRateProvider->provide($secondOrderItemUnit)->willReturn('20%');

$secondOrderItem->getProductName()->willReturn('Space gun');
$secondAdjustment->getLabel()->willReturn('20%');

$this->convert([$firstUnitRefund, $secondUnitRefund, $thirdUnitRefund])->shouldBeLike([
new LineItem(
Expand Down
57 changes: 57 additions & 0 deletions spec/Provider/TaxRateProviderSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Provider;

use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\RefundPlugin\Provider\TaxRateProviderInterface;

final class TaxRateProviderSpec extends ObjectBehavior
{
function it_implements_tax_rate_provider_interface(): void
{
$this->shouldImplement(TaxRateProviderInterface::class);
}

function it_provides_a_tax_rate_from_tax_adjustment_label(
OrderItemUnitInterface $orderItemUnit,
AdjustmentInterface $taxAdjustment
): void {
$orderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$taxAdjustment->getWrappedObject()]))
;

$taxAdjustment->getLabel()->willReturn('VAT (20%)');

$this->provide($orderItemUnit)->shouldReturn('20%');
}

function it_provides_a_tax_adjustment_label_if_the_value_does_not_match_the_pattern(
OrderItemUnitInterface $orderItemUnit,
AdjustmentInterface $taxAdjustment
): void {
$orderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$taxAdjustment->getWrappedObject()]))
;

$taxAdjustment->getLabel()->willReturn('20%');

$this->provide($orderItemUnit)->shouldReturn('20%');
}

function it_returns_null_if_there_is_no_tax_adjustment(OrderItemUnitInterface $orderItemUnit): void
{
$orderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([]))
;

$this->provide($orderItemUnit)->shouldReturn(null);
}
}
32 changes: 7 additions & 25 deletions src/Converter/LineItemsConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@

namespace Sylius\RefundPlugin\Converter;

use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\RefundPlugin\Entity\LineItem;
use Sylius\RefundPlugin\Entity\LineItemInterface;
use Sylius\RefundPlugin\Model\UnitRefundInterface;
use Sylius\RefundPlugin\Provider\TaxRateProviderInterface;
use Webmozart\Assert\Assert;

final class LineItemsConverter implements LineItemsConverterInterface
{
/** @var RepositoryInterface */
private $orderItemUnitRepository;

public function __construct(RepositoryInterface $orderItemUnitRepository)
/** @var TaxRateProviderInterface */
private $taxRateProvider;

public function __construct(RepositoryInterface $orderItemUnitRepository, TaxRateProviderInterface $taxRateProvider)
{
$this->orderItemUnitRepository = $orderItemUnitRepository;
$this->taxRateProvider = $taxRateProvider;
}

public function convert(array $units): array
Expand Down Expand Up @@ -50,9 +53,6 @@ private function convertUnitRefundToLineItem(UnitRefundInterface $unitRefund): L
$taxAmount = (int) ($grossValue * $orderItemUnit->getTaxTotal() / $orderItemUnit->getTotal());
$netValue = $grossValue - $taxAmount;

/** @var Collection|AdjustmentInterface[] $taxAdjustments */
$taxAdjustments = $orderItemUnit->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);

return new LineItem(
$orderItem->getProductName(),
1,
Expand All @@ -61,7 +61,7 @@ private function convertUnitRefundToLineItem(UnitRefundInterface $unitRefund): L
$netValue,
$grossValue,
$taxAmount,
$this->getTaxRate($taxAdjustments)
$this->taxRateProvider->provide($orderItemUnit)
);
}

Expand All @@ -85,22 +85,4 @@ private function addLineItem(LineItemInterface $newLineItem, array $lineItems):

return $lineItems;
}

/**
* @param Collection|AdjustmentInterface[] $taxAdjustments
*/
private function getTaxRate(Collection $taxAdjustments): ?string
{
if ($taxAdjustments->isEmpty()) {
return null;
}

$label = $taxAdjustments->first()->getLabel();

if (preg_match('/\((.*?)\)/', $label, $matches)) {
return end($matches); // returns percent tax rate from tax adjustment label
}

return $label;
}
}
30 changes: 30 additions & 0 deletions src/Provider/TaxRateProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Sylius\RefundPlugin\Provider;

use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;

final class TaxRateProvider implements TaxRateProviderInterface
{
public function provide(OrderItemUnitInterface $orderItemUnit): ?string
{
/** @var Collection|AdjustmentInterface[] $taxAdjustments */
$taxAdjustments = $orderItemUnit->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);

if ($taxAdjustments->isEmpty()) {
return null;
}

$label = $taxAdjustments->first()->getLabel();

if (preg_match('/\((.*?)\)/', $label, $matches)) {
return end($matches); // returns percent tax rate from tax adjustment label
}

return $label;
}
}
12 changes: 12 additions & 0 deletions src/Provider/TaxRateProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Sylius\RefundPlugin\Provider;

use Sylius\Component\Core\Model\OrderItemUnitInterface;

interface TaxRateProviderInterface
{
public function provide(OrderItemUnitInterface $orderItemUnit): ?string;
}
1 change: 1 addition & 0 deletions src/Resources/config/services/converter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<service id="Sylius\RefundPlugin\Converter\LineItemsConverterInterface" class="Sylius\RefundPlugin\Converter\LineItemsConverter">
<argument type="service" id="sylius.repository.order_item_unit" />
<argument type="service" id="Sylius\RefundPlugin\Provider\TaxRateProviderInterface" />
</service>

<service id="Sylius\RefundPlugin\Converter\ShipmentLineItemsConverterInterface" class="Sylius\RefundPlugin\Converter\ShipmentLineItemsConverter">
Expand Down
5 changes: 5 additions & 0 deletions src/Resources/config/services/provider.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,10 @@
<argument type="service" id="sylius.repository.payment_method" />
<argument>%sylius_refund.supported_gateways%</argument>
</service>

<service
id="Sylius\RefundPlugin\Provider\TaxRateProviderInterface"
class="Sylius\RefundPlugin\Provider\TaxRateProvider"
/>
</services>
</container>

0 comments on commit 1aca927

Please sign in to comment.