diff --git a/migrations/Version20200113091731.php b/migrations/Version20200113091731.php new file mode 100644 index 000000000..2a7109015 --- /dev/null +++ b/migrations/Version20200113091731.php @@ -0,0 +1,25 @@ +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'); + } +} diff --git a/spec/Entity/CreditMemoSpec.php b/spec/Entity/CreditMemoSpec.php index 3323933e2..7d36e1b4f 100644 --- a/spec/Entity/CreditMemoSpec.php +++ b/spec/Entity/CreditMemoSpec.php @@ -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', @@ -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'), @@ -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'); @@ -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')); diff --git a/spec/Entity/TaxItemSpec.php b/spec/Entity/TaxItemSpec.php new file mode 100644 index 000000000..652028b5c --- /dev/null +++ b/spec/Entity/TaxItemSpec.php @@ -0,0 +1,31 @@ +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); + } +} diff --git a/spec/Generator/CreditMemoGeneratorSpec.php b/spec/Generator/CreditMemoGeneratorSpec.php index 52e31eae0..f857114ca 100644 --- a/spec/Generator/CreditMemoGeneratorSpec.php +++ b/spec/Generator/CreditMemoGeneratorSpec.php @@ -14,10 +14,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; @@ -28,6 +30,7 @@ function let( OrderRepositoryInterface $orderRepository, CreditMemoUnitGeneratorInterface $orderItemUnitCreditMemoUnitGenerator, CreditMemoUnitGeneratorInterface $shipmentCreditMemoUnitGenerator, + TaxItemsGeneratorInterface $taxItemsGenerator, NumberGenerator $creditMemoNumberGenerator, CurrentDateTimeProviderInterface $currentDateTimeProvider, CreditMemoIdentifierGeneratorInterface $creditMemoIdentifierGenerator @@ -36,6 +39,7 @@ function let( $orderRepository, $orderItemUnitCreditMemoUnitGenerator, $shipmentCreditMemoUnitGenerator, + $taxItemsGenerator, $creditMemoNumberGenerator, $currentDateTimeProvider, $creditMemoIdentifierGenerator @@ -48,15 +52,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); @@ -99,6 +104,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); @@ -118,6 +126,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!'), diff --git a/spec/Generator/TaxItemsGeneratorSpec.php b/spec/Generator/TaxItemsGeneratorSpec.php new file mode 100644 index 000000000..f3263981f --- /dev/null +++ b/spec/Generator/TaxItemsGeneratorSpec.php @@ -0,0 +1,77 @@ +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)]); + } +} diff --git a/src/Entity/CreditMemo.php b/src/Entity/CreditMemo.php index 11b861245..4fd3f7a90 100644 --- a/src/Entity/CreditMemo.php +++ b/src/Entity/CreditMemo.php @@ -34,6 +34,9 @@ class CreditMemo implements CreditMemoInterface /** @var array */ protected $units; + /** @var array */ + protected $taxItems; + /** @var string */ protected $comment; @@ -55,6 +58,7 @@ public function __construct( string $localeCode, ChannelInterface $channel, array $units, + array $taxItems, string $comment, \DateTimeInterface $issuedAt, CustomerBillingDataInterface $from, @@ -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; @@ -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; @@ -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; + } } diff --git a/src/Entity/CreditMemoInterface.php b/src/Entity/CreditMemoInterface.php index e126728f3..95dba4bfa 100644 --- a/src/Entity/CreditMemoInterface.php +++ b/src/Entity/CreditMemoInterface.php @@ -24,6 +24,11 @@ public function getChannel(): ChannelInterface; public function getUnits(): array; + /** + * @return array + */ + public function getTaxItems(): array; + public function getComment(): string; public function getIssuedAt(): \DateTimeInterface; @@ -31,4 +36,6 @@ public function getIssuedAt(): \DateTimeInterface; public function getFrom(): CustomerBillingDataInterface; public function getTo(): ?ShopBillingDataInterface; + + public function getSubtotal(): int; } diff --git a/src/Entity/TaxItem.php b/src/Entity/TaxItem.php new file mode 100644 index 000000000..14c252958 --- /dev/null +++ b/src/Entity/TaxItem.php @@ -0,0 +1,49 @@ +label = $label; + $this->amount = $amount; + } + + public function getLabel(): string + { + return $this->label; + } + + public function getAmount(): int + { + return $this->amount; + } + + public function serialize(): string + { + $serialized = json_encode(['label' => $this->label, 'amount' => $this->amount]); + + if ($serialized === false) { + throw new \Exception('Tax item cannot be serialized.'); + } + + return $serialized; + } + + public static function unserialize(string $serialized): self + { + $data = json_decode($serialized, true); + + return new self($data['label'], $data['amount']); + } +} diff --git a/src/Entity/TaxItemInterface.php b/src/Entity/TaxItemInterface.php new file mode 100644 index 000000000..2671113fb --- /dev/null +++ b/src/Entity/TaxItemInterface.php @@ -0,0 +1,14 @@ +orderRepository = $orderRepository; $this->orderItemUnitCreditMemoUnitGenerator = $orderItemUnitCreditMemoUnitGenerator; $this->shipmentCreditMemoUnitGenerator = $shipmentCreditMemoUnitGenerator; + $this->taxItemsGenerator = $taxItemsGenerator; $this->creditMemoNumberGenerator = $creditMemoNumberGenerator; $this->currentDateTimeProvider = $currentDateTimeProvider; $this->uuidCreditMemoIdentifierGenerator = $uuidCreditMemoIdentifierGenerator; @@ -63,6 +69,7 @@ public function generate( $channel = $order->getChannel(); $creditMemoUnits = []; + $taxItems = []; /** @var UnitRefundInterface $unit */ foreach ($units as $unit) { @@ -80,6 +87,11 @@ public function generate( ; } + /** @var TaxItemInterface $taxItem */ + foreach ($this->taxItemsGenerator->generate($units) as $taxItem) { + $taxItems[] = $taxItem->serialize(); + } + return new CreditMemo( $this->uuidCreditMemoIdentifierGenerator->generate(), $this->creditMemoNumberGenerator->generate(), @@ -89,6 +101,7 @@ public function generate( $order->getLocaleCode(), $channel, $creditMemoUnits, + $taxItems, $comment, $this->currentDateTimeProvider->now(), $this->getFromAddress($order->getBillingAddress()), diff --git a/src/Generator/TaxItemsGenerator.php b/src/Generator/TaxItemsGenerator.php new file mode 100644 index 000000000..e62448fb2 --- /dev/null +++ b/src/Generator/TaxItemsGenerator.php @@ -0,0 +1,53 @@ +orderItemUnitRepository = $orderItemUnitRepository; + } + + public function generate(array $units): array + { + $temporaryTaxItems = []; + + /** @var UnitRefundInterface $unitRefund */ + foreach ($units as $unitRefund) { + /** @var OrderItemUnitInterface $orderItemUnit */ + $orderItemUnit = $this->orderItemUnitRepository->find($unitRefund->id()); + + $taxAdjustments = $orderItemUnit->getAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); + foreach ($taxAdjustments as $taxAdjustment) { + $taxAmount = (int) ($orderItemUnit->getTaxTotal() * ($unitRefund->total() / $orderItemUnit->getTotal())); + + if (array_key_exists($taxAdjustment->getLabel(), $temporaryTaxItems)) { + $temporaryTaxItems[$taxAdjustment->getLabel()] += $taxAmount; + + continue; + } + + $temporaryTaxItems[$taxAdjustment->getLabel()] = $taxAmount; + } + } + + $taxItems = []; + foreach ($temporaryTaxItems as $label => $amount) { + $taxItems[] = new TaxItem($label, $amount); + } + + return $taxItems; + } +} diff --git a/src/Generator/TaxItemsGeneratorInterface.php b/src/Generator/TaxItemsGeneratorInterface.php new file mode 100644 index 000000000..2f9f271f5 --- /dev/null +++ b/src/Generator/TaxItemsGeneratorInterface.php @@ -0,0 +1,18 @@ + $units + * + * @return array + */ + public function generate(array $units): array; +} diff --git a/src/Resources/config/doctrine/CreditMemo.orm.xml b/src/Resources/config/doctrine/CreditMemo.orm.xml index c1becf540..7e8a87637 100644 --- a/src/Resources/config/doctrine/CreditMemo.orm.xml +++ b/src/Resources/config/doctrine/CreditMemo.orm.xml @@ -12,6 +12,7 @@ + diff --git a/src/Resources/config/services/generator.xml b/src/Resources/config/services/generator.xml index bbac84114..526942af7 100644 --- a/src/Resources/config/services/generator.xml +++ b/src/Resources/config/services/generator.xml @@ -22,6 +22,7 @@ + @@ -36,6 +37,10 @@ @SyliusRefundPlugin/Resources/assets/sylius-logo.png + + + + diff --git a/src/Resources/views/Download/creditMemo.html.twig b/src/Resources/views/Download/creditMemo.html.twig index 6980d9ac8..f28ddf600 100644 --- a/src/Resources/views/Download/creditMemo.html.twig +++ b/src/Resources/views/Download/creditMemo.html.twig @@ -73,18 +73,32 @@ {{ 'sylius.ui.item'|trans }} - {{ 'sylius.ui.total'|trans }} {{ 'sylius.ui.tax_total'|trans }} + {{ 'sylius.ui.total'|trans }} {% for unit in creditMemo.units %} {{ unit.productName }} - {{ unit.total|sylius_format_money(creditMemo.currencyCode, creditMemo.localeCode) }} {{ unit.taxesTotal|sylius_format_money(creditMemo.currencyCode, creditMemo.localeCode) }} + {{ unit.total|sylius_format_money(creditMemo.currencyCode, creditMemo.localeCode) }} {% endfor %} + {% if creditMemo.taxItems|length > 0 %} + + {{ 'sylius.ui.tax'|trans }} + {{ 'sylius.ui.amount'|trans }} + + + {% for taxItem in creditMemo.taxItems %} + + {{ taxItem.label }} + {{ taxItem.amount|sylius_format_money(creditMemo.currencyCode, creditMemo.localeCode) }} + + {% endfor %} + {% endif %} + {% if creditMemo.comment != null %}

{{ creditMemo.comment }}

diff --git a/src/Resources/views/Order/Admin/CreditMemo/details.html.twig b/src/Resources/views/Order/Admin/CreditMemo/details.html.twig index f6fbce797..c01ef3545 100644 --- a/src/Resources/views/Order/Admin/CreditMemo/details.html.twig +++ b/src/Resources/views/Order/Admin/CreditMemo/details.html.twig @@ -89,6 +89,24 @@ {% endfor %} + + + {{ 'sylius.ui.subtotal'|trans }}: + + + {{ money.format(credit_memo.subtotal, credit_memo.currencyCode) }} + + + {% for item in credit_memo.taxItems %} + + + {{ item.label }}: + + + {{ money.format(item.amount, credit_memo.currencyCode) }} + + + {% endfor %} {{ 'sylius.ui.total'|trans }}: diff --git a/tests/Behat/Context/Application/CreditMemoContext.php b/tests/Behat/Context/Application/CreditMemoContext.php index ed8151c56..3dfb0d3f6 100644 --- a/tests/Behat/Context/Application/CreditMemoContext.php +++ b/tests/Behat/Context/Application/CreditMemoContext.php @@ -12,6 +12,7 @@ use Sylius\RefundPlugin\Entity\CreditMemoInterface; use Sylius\RefundPlugin\Entity\CustomerBillingData; use Sylius\RefundPlugin\Entity\ShopBillingData; +use Sylius\RefundPlugin\Entity\TaxItemInterface; use Sylius\RefundPlugin\Provider\CurrentDateTimeProviderInterface; use Webmozart\Assert\Assert; @@ -64,7 +65,7 @@ public function shouldHaveSequentialNumberGeneratedFromCurrentDate(): void } /** - * @Then /^this credit memo should contain (\d+) "([^"]+)" product with ("[^"]+") tax applied$/ + * @Then /^this credit memo should contain (\d+) "([^"]+)" product(?:|s) with ("[^"]+") tax applied$/ */ public function thisCreditMemoShouldContainProductWithTaxApplied( int $count, @@ -109,6 +110,32 @@ public function creditMemoTotalShouldBe(int $total): void Assert::same($this->creditMemo->getTotal(), $total); } + /** + * @Then /^its subtotal should be ("[^"]+")$/ + */ + public function creditMemoSubtotalShouldBe(int $subtotal): void + { + Assert::same($this->creditMemo->getSubtotal(), $subtotal); + } + + /** + * @Then /^it should have a tax item "([^"]+)" with amount ("[^"]+")$/ + */ + public function itShouldHaveATaxItemWithAmount(string $label, int $amount): void + { + $result = false; + /** @var TaxItemInterface $taxItem */ + foreach ($this->creditMemo->getTaxItems() as $taxItem) { + if ($taxItem->getLabel() === $label && $taxItem->getAmount() === $amount) { + $result = true; + + break; + } + } + + Assert::true($result); + } + /** * @Then it should be commented with :comment */ diff --git a/tests/Behat/Context/Ui/CreditMemoContext.php b/tests/Behat/Context/Ui/CreditMemoContext.php index 66b78c15c..8a2811d92 100644 --- a/tests/Behat/Context/Ui/CreditMemoContext.php +++ b/tests/Behat/Context/Ui/CreditMemoContext.php @@ -120,7 +120,7 @@ public function shouldHaveCountCreditMemoGeneratedForOrder(int $count, OrderInte } /** - * @Then this credit memo should contain :count :productName product with :tax tax applied + * @Then this credit memo should contain :count :productName product(s) with :tax tax applied */ public function thisCreditMemoShouldContainProductWithTaxApplied( int $count, @@ -203,6 +203,14 @@ public function creditMemoTotalShouldBe(string $total): void Assert::same($this->creditMemoDetailsPage->getTotal(), $total); } + /** + * @Then its subtotal should be :subtotal + */ + public function itsSubtotalShouldBe(string $subtotal): void + { + Assert::same($this->creditMemoDetailsPage->getSubtotal(), $subtotal); + } + /** * @Then it should be commented with :comment */ @@ -270,4 +278,12 @@ public function pdfFileShouldBeSuccessfullyDownloaded(): void { Assert::true($this->pdfDownloadElement->isPdfFileDownloaded()); } + + /** + * @Then it should have a tax item :label with amount :amount + */ + public function itShouldHaveATaxItemWithAmount(string $label, string $amount): void + { + Assert::true($this->creditMemoDetailsPage->hasTaxItem($label, $amount)); + } } diff --git a/tests/Behat/Page/Admin/CreditMemoDetailsPage.php b/tests/Behat/Page/Admin/CreditMemoDetailsPage.php index 6fdebd307..ee790528c 100644 --- a/tests/Behat/Page/Admin/CreditMemoDetailsPage.php +++ b/tests/Behat/Page/Admin/CreditMemoDetailsPage.php @@ -53,6 +53,11 @@ public function getTotal(): string return $this->getDocument()->find('css', '#credit-memo-total')->getText(); } + public function getSubtotal(): string + { + return $this->getDocument()->find('css', '#credit-memo-subtotal')->getText(); + } + public function getComment(): string { return $this->getDocument()->find('css', '#credit-memo-comment')->getText(); @@ -68,6 +73,20 @@ public function getToAddress(): string return $this->getDocument()->find('css', '#to-address')->getText(); } + public function hasTaxItem(string $label, string $amount): bool + { + $taxItemAmountElement = $this->getElement('tax_item_amount', ['%label%' => $label]); + + return $amount === $taxItemAmountElement->getText(); + } + + protected function getDefinedElements(): array + { + return array_merge(parent::getDefinedElements(), [ + 'tax_item_amount' => 'tr.tax-item:contains("%label%") .tax-item-amount', + ]); + } + /** @return array|NodeElement[] */ private function getCreditMemoUnitsWithProduct(string $productName): array { diff --git a/tests/Behat/Page/Admin/CreditMemoDetailsPageInterface.php b/tests/Behat/Page/Admin/CreditMemoDetailsPageInterface.php index ffc59da02..8fc85b96e 100644 --- a/tests/Behat/Page/Admin/CreditMemoDetailsPageInterface.php +++ b/tests/Behat/Page/Admin/CreditMemoDetailsPageInterface.php @@ -22,9 +22,13 @@ public function getChannelName(): string; public function getTotal(): string; + public function getSubtotal(): string; + public function getComment(): string; public function getFromAddress(): string; public function getToAddress(): string; + + public function hasTaxItem(string $label, string $amount): bool; }