Skip to content

Commit

Permalink
feature #173 [CreditMemo] Add tax items to credit memo (GSadee)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.

Discussion
----------

Fixes #129

<img width="1677" alt="Zrzut ekranu 2020-01-13 o 11 22 49" src="https://user-images.githubusercontent.com/6140884/72323856-f8d06000-36a9-11ea-9e71-a5f1f62853ae.png">
<img width="789" alt="Zrzut ekranu 2020-01-13 o 11 48 56" src="https://user-images.githubusercontent.com/6140884/72323857-f968f680-36a9-11ea-8447-ab71c0a73aa5.png">


Commits
-------

34156fd [Behat][CreditMemo] Update credit memo scenarios by adding tax items
765bed7 [CreditMemo] Add tax items to credit memo
  • Loading branch information
Zales0123 authored Jan 15, 2020
2 parents 3f2640a + 765bed7 commit bd17ace
Show file tree
Hide file tree
Showing 21 changed files with 471 additions and 11 deletions.
10 changes: 7 additions & 3 deletions features/having_credit_memo_generated.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ Feature: Having credit memo generated

@ui @application
Scenario: Seeing the details of generated credit memo
Given 1st "Mr. Meeseeks T-Shirt" product from order "#00000022" has already been refunded with "Space money" payment
Given all units from the order "#00000022" are refunded with "Space money" payment
And I browse the details of the only credit memo generated for order "#00000022"
And it should have sequential number generated from current date
Then this credit memo should contain 1 "Mr. Meeseeks T-Shirt" product with "$0.90" tax applied
Then this credit memo should contain 2 "Mr. Meeseeks T-Shirt" products with "$0.90" tax applied
And it should be issued in "United States" channel
And it should be issued from "Rick Sanchez", "Seaside Fwy", "90802" "Los Angeles" in the "United States"
And it should be issued to "Haas & Milan", "Pacific Coast Hwy", "90003" "Los Angeles" in the "United States" with "1100110011" tax ID
And its total should be "$9.90"
And its subtotal should be "$18.00"
And it should have a tax item "US VAT (10%)" with amount "$1.80"
And its total should be "$19.80"

@ui @application
Scenario: Seeing the details of generated credit memo with partial price
Expand All @@ -52,6 +54,8 @@ Feature: Having credit memo generated
And it should have sequential number generated from current date
Then this credit memo should contain 1 "Mr. Meeseeks T-Shirt" product with "$0.50" tax applied
And it should be issued in "United States" channel
And its subtotal should be "$5.00"
And it should have a tax item "US VAT (10%)" with amount "$0.50"
And its total should be "$5.50"

@ui @application
Expand Down
25 changes: 25 additions & 0 deletions migrations/Version20200113091731.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20200113091731 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('ALTER TABLE sylius_refund_credit_memo ADD tax_items LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\'');
}

public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');

$this->addSql('ALTER TABLE sylius_refund_credit_memo DROP tax_items');
}
}
13 changes: 13 additions & 0 deletions spec/Entity/CreditMemoSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
use Sylius\RefundPlugin\Entity\CreditMemoUnit;
use Sylius\RefundPlugin\Entity\CustomerBillingData;
use Sylius\RefundPlugin\Entity\ShopBillingData;
use Sylius\RefundPlugin\Entity\TaxItem;

final class CreditMemoSpec extends ObjectBehavior
{
function let(ChannelInterface $channel, OrderInterface $order): void
{
$creditMemoUnit = new CreditMemoUnit('Portal gun', 1000, 50);
$taxItem = new TaxItem('VAT', 50);

$this->beConstructedWith(
'7903c83a-4c5e-4bcf-81d8-9dc304c6a353',
Expand All @@ -27,6 +29,7 @@ function let(ChannelInterface $channel, OrderInterface $order): void
'en_US',
$channel,
[$creditMemoUnit->serialize()],
[$taxItem->serialize()],
'Comment',
new \DateTime('01-01-2020 10:10:10'),
new CustomerBillingData('Rick Sanchez', 'Main St. 3322', '90802', 'US', 'Curse Purge Plus!', 'Los Angeles', 'Baldwin Hills', '323'),
Expand Down Expand Up @@ -59,6 +62,11 @@ function it_has_total(): void
$this->getTotal()->shouldReturn(1000);
}

function it_has_a_subtotal(): void
{
$this->getSubtotal()->shouldReturn(950);
}

function it_has_currency_code(): void
{
$this->getCurrencyCode()->shouldReturn('USD');
Expand All @@ -79,6 +87,11 @@ function it_has_units(): void
$this->getUnits()->shouldBeLike([new CreditMemoUnit('Portal gun', 1000, 50)]);
}

function it_has_tax_items(): void
{
$this->getTaxItems()->shouldBeLike([new TaxItem('VAT', 50)]);
}

function it_has_date_of_creation(): void
{
$this->getIssuedAt()->shouldBeLike(new \DateTime('01-01-2020 10:10:10'));
Expand Down
31 changes: 31 additions & 0 deletions spec/Entity/TaxItemSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Entity;

use PhpSpec\ObjectBehavior;
use Sylius\RefundPlugin\Entity\TaxItemInterface;

final class TaxItemSpec extends ObjectBehavior
{
function let(): void
{
$this->beConstructedWith('VAT', 100);
}

function it_implements_tax_item_interface(): void
{
$this->shouldImplement(TaxItemInterface::class);
}

function it_has_a_label(): void
{
$this->getLabel()->shouldReturn('VAT');
}

function it_has_an_amount(): void
{
$this->getAmount()->shouldReturn(100);
}
}
17 changes: 13 additions & 4 deletions spec/Generator/CreditMemoGeneratorSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
use Sylius\RefundPlugin\Entity\CreditMemoUnit;
use Sylius\RefundPlugin\Entity\CustomerBillingData;
use Sylius\RefundPlugin\Entity\ShopBillingData;
use Sylius\RefundPlugin\Entity\TaxItem;
use Sylius\RefundPlugin\Generator\CreditMemoGeneratorInterface;
use Sylius\RefundPlugin\Generator\CreditMemoIdentifierGeneratorInterface;
use Sylius\RefundPlugin\Generator\CreditMemoUnitGeneratorInterface;
use Sylius\RefundPlugin\Generator\NumberGenerator;
use Sylius\RefundPlugin\Generator\TaxItemsGeneratorInterface;
use Sylius\RefundPlugin\Model\OrderItemUnitRefund;
use Sylius\RefundPlugin\Model\ShipmentRefund;
use Sylius\RefundPlugin\Provider\CurrentDateTimeProviderInterface;
Expand All @@ -26,13 +28,15 @@ final class CreditMemoGeneratorSpec extends ObjectBehavior
function let(
CreditMemoUnitGeneratorInterface $orderItemUnitCreditMemoUnitGenerator,
CreditMemoUnitGeneratorInterface $shipmentCreditMemoUnitGenerator,
TaxItemsGeneratorInterface $taxItemsGenerator,
NumberGenerator $creditMemoNumberGenerator,
CurrentDateTimeProviderInterface $currentDateTimeProvider,
CreditMemoIdentifierGeneratorInterface $creditMemoIdentifierGenerator
): void {
$this->beConstructedWith(
$orderItemUnitCreditMemoUnitGenerator,
$shipmentCreditMemoUnitGenerator,
$taxItemsGenerator,
$creditMemoNumberGenerator,
$currentDateTimeProvider,
$creditMemoIdentifierGenerator
Expand All @@ -45,15 +49,16 @@ function it_implements_credit_memo_generator_interface(): void
}

function it_generates_credit_memo_basing_on_event_data(
CreditMemoUnitGeneratorInterface $orderItemUnitCreditMemoUnitGenerator,
CreditMemoUnitGeneratorInterface $shipmentCreditMemoUnitGenerator,
TaxItemsGeneratorInterface $taxItemsGenerator,
NumberGenerator $creditMemoNumberGenerator,
CurrentDateTimeProviderInterface $currentDateTimeProvider,
CreditMemoIdentifierGeneratorInterface $creditMemoIdentifierGenerator,
OrderInterface $order,
ChannelInterface $channel,
ShopBillingDataInterface $shopBillingData,
AddressInterface $customerBillingAddress,
CreditMemoUnitGeneratorInterface $orderItemUnitCreditMemoUnitGenerator,
CreditMemoUnitGeneratorInterface $shipmentCreditMemoUnitGenerator,
CurrentDateTimeProviderInterface $currentDateTimeProvider,
CreditMemoIdentifierGeneratorInterface $creditMemoIdentifierGenerator,
\DateTime $dateTime
): void {
$firstUnitRefund = new OrderItemUnitRefund(1, 500);
Expand Down Expand Up @@ -96,6 +101,9 @@ function it_generates_credit_memo_basing_on_event_data(
$shipmentCreditMemoUnit = new CreditMemoUnit('Galaxy post', 400, 0);
$shipmentCreditMemoUnitGenerator->generate(3, 400)->willReturn($shipmentCreditMemoUnit);

$taxItem = new TaxItem('VAT', 100);
$taxItemsGenerator->generate([$firstUnitRefund, $secondUnitRefund])->willReturn([$taxItem]);

$creditMemoNumberGenerator->generate()->willReturn('2018/07/00001111');

$currentDateTimeProvider->now()->willReturn($dateTime);
Expand All @@ -115,6 +123,7 @@ function it_generates_credit_memo_basing_on_event_data(
$secondCreditMemoUnit->serialize(),
$shipmentCreditMemoUnit->serialize(),
],
[$taxItem->serialize()],
'Comment',
$dateTime->getWrappedObject(),
new CustomerBillingData('Rick Sanchez', 'Universe St. 444', '000333', 'US', 'Los Angeles', 'Curse Purge Plus!'),
Expand Down
77 changes: 77 additions & 0 deletions spec/Generator/TaxItemsGeneratorSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\RefundPlugin\Generator;

use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\AdjustmentInterface;
use Sylius\Component\Core\Model\OrderItemUnitInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\RefundPlugin\Entity\TaxItem;
use Sylius\RefundPlugin\Generator\TaxItemsGeneratorInterface;
use Sylius\RefundPlugin\Model\OrderItemUnitRefund;

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

function it_implements_tax_items_generator_interface(): void
{
$this->shouldImplement(TaxItemsGeneratorInterface::class);
}

function it_generates_tax_items(
RepositoryInterface $orderItemUnitRepository,
OrderItemUnitInterface $firstOrderItemUnit,
OrderItemUnitInterface $secondOrderItemUnit,
AdjustmentInterface $firstAdjustment,
AdjustmentInterface $secondAdjustment
): void {
$firstUnitRefund = new OrderItemUnitRefund(1, 500);
$secondUnitRefund = new OrderItemUnitRefund(3, 200);

$orderItemUnitRepository->find(1)->willReturn($firstOrderItemUnit);
$firstOrderItemUnit->getTotal()->willReturn(500);
$firstOrderItemUnit->getTaxTotal()->willReturn(50);
$firstOrderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$firstAdjustment->getWrappedObject()]))
;
$firstAdjustment->getLabel()->willReturn('VAT');

$orderItemUnitRepository->find(3)->willReturn($secondOrderItemUnit);
$secondOrderItemUnit->getTotal()->willReturn(200);
$secondOrderItemUnit->getTaxTotal()->willReturn(20);
$secondOrderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$secondAdjustment->getWrappedObject()]))
;
$secondAdjustment->getLabel()->willReturn('VAT');

$this->generate([$firstUnitRefund, $secondUnitRefund])->shouldBeLike([new TaxItem('VAT', 70)]);
}

function it_generates_tax_items_with_partial_amount(
RepositoryInterface $orderItemUnitRepository,
OrderItemUnitInterface $orderItemUnit,
AdjustmentInterface $adjustment
): void {
$unitRefund = new OrderItemUnitRefund(1, 250);

$orderItemUnitRepository->find(1)->willReturn($orderItemUnit);
$orderItemUnit->getTotal()->willReturn(500);
$orderItemUnit->getTaxTotal()->willReturn(50);
$orderItemUnit
->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT)
->willReturn(new ArrayCollection([$adjustment->getWrappedObject()]))
;
$adjustment->getLabel()->willReturn('VAT');

$this->generate([$unitRefund])->shouldBeLike([new TaxItem('VAT', 25)]);
}
}
27 changes: 27 additions & 0 deletions src/Entity/CreditMemo.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class CreditMemo implements CreditMemoInterface
/** @var array */
protected $units;

/** @var array */
protected $taxItems;

/** @var string */
protected $comment;

Expand All @@ -55,6 +58,7 @@ public function __construct(
string $localeCode,
ChannelInterface $channel,
array $units,
array $taxItems,
string $comment,
\DateTimeInterface $issuedAt,
CustomerBillingDataInterface $from,
Expand All @@ -68,6 +72,7 @@ public function __construct(
$this->localeCode = $localeCode;
$this->channel = $channel;
$this->units = $units;
$this->taxItems = $taxItems;
$this->comment = $comment;
$this->issuedAt = $issuedAt;
$this->from = $from;
Expand Down Expand Up @@ -119,6 +124,16 @@ public function getUnits(): array
return $units;
}

public function getTaxItems(): array
{
$taxItems = [];
foreach ($this->taxItems as $taxItem) {
$taxItems[] = TaxItem::unserialize($taxItem);
}

return $taxItems;
}

public function getComment(): string
{
return $this->comment;
Expand All @@ -138,4 +153,16 @@ public function getTo(): ?ShopBillingDataInterface
{
return $this->to;
}

public function getSubtotal(): int
{
$subtotal = 0;

/** @var CreditMemoUnit $unit */
foreach ($this->getUnits() as $unit) {
$subtotal += $unit->getTotal() - $unit->getTaxesTotal();
}

return $subtotal;
}
}
7 changes: 7 additions & 0 deletions src/Entity/CreditMemoInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ public function getChannel(): ChannelInterface;

public function getUnits(): array;

/**
* @return array<TaxItemInterface>
*/
public function getTaxItems(): array;

public function getComment(): string;

public function getIssuedAt(): \DateTimeInterface;

public function getFrom(): CustomerBillingDataInterface;

public function getTo(): ?ShopBillingDataInterface;

public function getSubtotal(): int;
}
Loading

0 comments on commit bd17ace

Please sign in to comment.