Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CreditMemo] Add tax items to credit memo #173

Merged
merged 2 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Zales0123 marked this conversation as resolved.
Show resolved Hide resolved
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