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

[Invoice] Add payment status #246

Merged
merged 4 commits into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
61 changes: 61 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
### UPGRADE FROM 0.17.0 TO 0.18.0

Now on invoice admin and shop user can check if related order was paid before invoice generated.

1. `src/Entity/Invoice.php` model has new field (`paymentState`), and updated constructor arguments:

```dif
public function __construct(
string $id,
string $number,
OrderInterface $order,
\DateTimeInterface $issuedAt,
BillingDataInterface $billingData,
string $currencyCode,
string $localeCode,
int $total,
Collection $lineItems,
Collection $taxItems,
ChannelInterface $channel,
+ string $paymentState,
InvoiceShopBillingDataInterface $shopBillingData
) {
$this->id = $id;
$this->number = $number;
$this->order = $order;
$this->issuedAt = clone $issuedAt;
$this->billingData = $billingData;
$this->currencyCode = $currencyCode;
$this->localeCode = $localeCode;
$this->total = $total;
$this->lineItems = $lineItems;
$this->taxItems = $taxItems;
$this->channel = $channel;
+ $this->paymentState = $paymentState;
$this->shopBillingData = $shopBillingData;
```

1. New field on `src/Entity/Invoice.php` implies a database update

1. Method `createForData` from `src/Factory/InvoiceFactory.php` service was updated:

```dif
public function createForData(
string $id,
string $number,
OrderInterface $order,
\DateTimeInterface $issuedAt,
BillingDataInterface $billingData,
string $currencyCode,
string $localeCode,
int $total,
Collection $lineItems,
Collection $taxItems,
ChannelInterface $channel,
+ bool $isPaid,
arti0090 marked this conversation as resolved.
Show resolved Hide resolved
InvoiceShopBillingDataInterface $shopBillingData = null
): InvoiceInterface {
// ...
}
```

### UPGRADE FROM 0.16.1 TO 0.17.0

Invoices are now saved on the server during their generation (by default, when the order is paid).
Expand Down
32 changes: 32 additions & 0 deletions features/managing_invoices/seeing_payment_state_on_invoice.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@managing_invoices
Feature: Seeing payment state of an invoice
In order to see if customer paid order
As an Administrator
I want to be able to view payment state of invoice

Background:
Given the store operates on a single channel in "United States"
And the store has "VAT" tax rate of 10% for "Clothes" within the "US" zone
And the store has a product "Angel T-Shirt" priced at "$60.00"
And it belongs to "Clothes" tax category
And the store has "UPS" shipping method with "$10.00" fee
And the store allows paying with "Cash on Delivery"
And the store allows paying with "Quick Payments"
And I am logged in as an administrator
And I set shop billing data for channel "United States" as "Ragnarok", "1100110011", "Pacific Coast Hwy", "90806" "Los Angeles", "United States"
And there is a customer "[email protected]" that placed an order "#00000666"
And the customer bought 2 "Angel T-Shirt" products
And the customer "Lucifer Morningstar" addressed it to "Seaside Fwy", "90802" "Los Angeles" in the "United States"
And for the billing address of "Mazikeen Lilim" in the "Pacific Coast Hwy", "90806" "Los Angeles", "United States"
Given the customer chose "UPS" shipping method with "Cash on Delivery" payment
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

@ui
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to make also an @api for this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we don't have API implemented on this plugin

Scenario: Seeing unpaid invoice details
When I view the summary of the invoice for order "#00000666"
And it should be unpaid
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

@ui
Scenario: Seeing invoice details after payment made
Given this order is already paid
When I view the summary of the invoice for order "#00000666"
And it should be unpaid
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions spec/Entity/InvoiceSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function let(
new ArrayCollection([$lineItem->getWrappedObject()]),
new ArrayCollection([$taxItem->getWrappedObject()]),
$channel,
InvoiceInterface::PAYMENT_STATE_COMPLETED,
$shopBillingData
);
}
Expand Down
2 changes: 2 additions & 0 deletions spec/Factory/InvoiceFactorySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function it_creates_an_invoice_for_given_data(
new ArrayCollection(),
new ArrayCollection(),
$channel,
InvoiceInterface::PAYMENT_STATE_COMPLETED,
$invoiceShopBillingData
)->shouldReturnAnInstanceOf(InvoiceInterface::class);
}
Expand All @@ -72,6 +73,7 @@ function it_allows_for_nullable_shop_billing_data(
new ArrayCollection(),
new ArrayCollection(),
$channel,
InvoiceInterface::PAYMENT_STATE_COMPLETED,
null
)->shouldReturnAnInstanceOf(InvoiceInterface::class);
}
Expand Down
3 changes: 3 additions & 0 deletions spec/Generator/InvoiceGeneratorSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Sylius\Component\Core\Model\AddressInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Payment\Model\PaymentInterface;
use Sylius\InvoicingPlugin\Converter\BillingDataConverterInterface;
use Sylius\InvoicingPlugin\Converter\InvoiceShopBillingDataConverterInterface;
use Sylius\InvoicingPlugin\Converter\LineItemsConverterInterface;
Expand Down Expand Up @@ -89,6 +90,7 @@ function it_generates_an_invoice_for_a_given_order(
$order->getLocaleCode()->willReturn('en_US');
$order->getTotal()->willReturn(10300);
$order->getChannel()->willReturn($channel);
$order->getPaymentState()->willReturn(PaymentInterface::STATE_COMPLETED);
$order->getBillingAddress()->willReturn($billingAddress);

$billingDataConverter->convert($billingAddress)->willReturn($billingData);
Expand All @@ -110,6 +112,7 @@ function it_generates_an_invoice_for_a_given_order(
new ArrayCollection([$unitLineItem->getWrappedObject(), $shippingLineItem->getWrappedObject()]),
new ArrayCollection([$taxItem->getWrappedObject()]),
$channel,
InvoiceInterface::PAYMENT_STATE_COMPLETED,
$invoiceShopBillingData
)->willReturn($invoice);

Expand Down
10 changes: 10 additions & 0 deletions src/Entity/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class Invoice implements InvoiceInterface
/** @var ChannelInterface */
protected $channel;

/** @var string */
protected $paymentState;
GSadee marked this conversation as resolved.
Show resolved Hide resolved

/** @var InvoiceShopBillingDataInterface */
protected $shopBillingData;

Expand All @@ -68,6 +71,7 @@ public function __construct(
Collection $lineItems,
Collection $taxItems,
ChannelInterface $channel,
string $paymentState,
InvoiceShopBillingDataInterface $shopBillingData
) {
$this->id = $id;
Expand All @@ -81,6 +85,7 @@ public function __construct(
$this->lineItems = $lineItems;
$this->taxItems = $taxItems;
$this->channel = $channel;
$this->paymentState = $paymentState;
$this->shopBillingData = $shopBillingData;

/** @var LineItemInterface $lineItem */
Expand Down Expand Up @@ -187,4 +192,9 @@ public function shopBillingData(): InvoiceShopBillingDataInterface
{
return $this->shopBillingData;
}

public function paymentState(): string
{
return $this->paymentState;
}
}
6 changes: 6 additions & 0 deletions src/Entity/InvoiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

interface InvoiceInterface extends ResourceInterface
{
public const PAYMENT_STATE_COMPLETED = 'Completed';
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

Tomanhez marked this conversation as resolved.
Show resolved Hide resolved
public const PAYMENT_STATE_PENDING = 'Pending';
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

public function id(): string;

public function number(): string;
Expand Down Expand Up @@ -50,4 +54,6 @@ public function taxesTotal(): int;
public function channel(): ChannelInterface;

public function shopBillingData(): InvoiceShopBillingDataInterface;

public function paymentState(): string;
}
2 changes: 2 additions & 0 deletions src/Factory/InvoiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function createForData(
Collection $lineItems,
Collection $taxItems,
ChannelInterface $channel,
string $paymentState,
InvoiceShopBillingDataInterface $shopBillingData = null
): InvoiceInterface {
return new Invoice(
Expand All @@ -50,6 +51,7 @@ public function createForData(
$lineItems,
$taxItems,
$channel,
$paymentState,
$shopBillingData ?? new InvoiceShopBillingData()
);
}
Expand Down
1 change: 1 addition & 0 deletions src/Factory/InvoiceFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function createForData(
Collection $lineItems,
Collection $taxItems,
ChannelInterface $channel,
string $paymentState,
InvoiceShopBillingDataInterface $shopBillingData = null
): InvoiceInterface;
}
5 changes: 5 additions & 0 deletions src/Generator/InvoiceGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Sylius\Component\Core\Model\AddressInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Payment\Model\PaymentInterface;
use Sylius\InvoicingPlugin\Converter\BillingDataConverterInterface;
use Sylius\InvoicingPlugin\Converter\InvoiceShopBillingDataConverterInterface;
use Sylius\InvoicingPlugin\Converter\LineItemsConverterInterface;
Expand Down Expand Up @@ -78,6 +79,9 @@ public function generateForOrder(OrderInterface $order, \DateTimeInterface $date
/** @var ChannelInterface $channel */
$channel = $order->getChannel();

$paymentState = $order->getPaymentState() === PaymentInterface::STATE_COMPLETED ?
InvoiceInterface::PAYMENT_STATE_COMPLETED : InvoiceInterface::PAYMENT_STATE_PENDING;
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

return $this->invoiceFactory->createForData(
$this->uuidInvoiceIdentifierGenerator->generate(),
$this->sequentialInvoiceNumberGenerator->generate(),
Expand All @@ -93,6 +97,7 @@ public function generateForOrder(OrderInterface $order, \DateTimeInterface $date
)),
$this->taxItemsConverter->convert($order),
$channel,
$paymentState,
$this->invoiceShopBillingDataConverter->convert($channel)
);
}
Expand Down
40 changes: 40 additions & 0 deletions src/Migrations/Version20210812125029.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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\InvoicingPlugin\Migrations;

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

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20210812125029 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add payment_state to invoice';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE sylius_invoicing_plugin_invoice ADD payment_state VARCHAR(255) NOT NULL');
AdamKasp marked this conversation as resolved.
Show resolved Hide resolved
AdamKasp marked this conversation as resolved.
Show resolved Hide resolved
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE sylius_invoicing_plugin_invoice DROP payment_state');
}
}
1 change: 1 addition & 0 deletions src/Resources/config/doctrine/Invoice.orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<field name="currencyCode" column="currency_code" length="3" />
<field name="localeCode" column="locale_code" />
<field name="total" column="total" type="integer" />
<field name="paymentState" column="payment_state" type="string" />
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved

<one-to-one field="billingData" target-entity="Sylius\InvoicingPlugin\Entity\BillingDataInterface">
<cascade>
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/translations/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ sylius_invoicing_plugin:
net_value: 'Net value'
no: 'No.'
order_number: 'Order number'
payment:
paid: 'Paid'
yes: 'Yes'
no: 'No'
resend_invoice: 'Resend'
seller: 'Seller'
tax_amount: 'Tax amount'
Expand Down
11 changes: 11 additions & 0 deletions src/Resources/views/Invoice/Download/pdf.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@
<td>{{ '%0.2f'|format(invoice.total/100) }}</td>
<td>{{ invoice.currencyCode }}</td>
</tr>
<tr class="paid">
<td colspan="5"></td>
<td colspan="2" class="bold">{{ 'sylius_invoicing_plugin.ui.payment.paid'|trans }}:</td>
<td>
{% if invoice.paymentState() is constant('Sylius\\InvoicingPlugin\\Entity\\InvoiceInterface::PAYMENT_STATE_COMPLETED') %}
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved
{{ 'sylius_invoicing_plugin.ui.payment.yes'|trans }}
{% else %}
{{ 'sylius_invoicing_plugin.ui.payment.no'|trans }}
{% endif %}
</td>
</tr>

{% if invoice.taxItems.count() > 0 %}
<tr>
Expand Down
12 changes: 12 additions & 0 deletions src/Resources/views/Invoice/show.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,17 @@
</tfoot>
</table>
</div>
<div class="right floated left aligned four wide column">
<div class="ui segment" {{ sylius_test_html_attribute('invoice-is-paid') }}>
<strong>{{ 'sylius_invoicing_plugin.ui.payment.paid'|trans }}: </strong>
<span>
{% if invoice.paymentState() is constant('Sylius\\InvoicingPlugin\\Entity\\InvoiceInterface::PAYMENT_STATE_COMPLETED') %}
Tomanhez marked this conversation as resolved.
Show resolved Hide resolved
{{ 'sylius_invoicing_plugin.ui.payment.yes'|trans }}
{% else %}
{{ 'sylius_invoicing_plugin.ui.payment.no'|trans }}
{% endif %}
</span>
</div>
</div>
</div>
{% endblock %}
8 changes: 8 additions & 0 deletions tests/Behat/Context/Ui/Admin/ManagingInvoicesContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -332,4 +332,12 @@ public function itShouldHaveItemsWithUnitPriceNetValueTaxTotalAndTotalInCurrency
): void {
Assert::true($this->showPage->hasItemWithData($name, $unitPrice, $quantity, $taxTotal, $total, $currencyCode, $netValue));
}

/**
* @Then it should be unpaid
*/
public function itShouldBeUnpaid(): void
{
Assert::false($this->showPage->isPaid());
}
}
6 changes: 6 additions & 0 deletions tests/Behat/Page/Admin/Invoice/ShowPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ public function goBack(): void
$this->getElement('back')->click();
}

public function isPaid(): bool
{
return str_contains($this->getElement('paid')->getHtml(), 'Yes');
}

protected function getDefinedElements(): array
{
return array_merge(parent::getDefinedElements(), [
Expand All @@ -170,6 +175,7 @@ protected function getDefinedElements(): array
'invoice_total' => '[data-test-invoice-total]',
'invoice_total_currency_code' => '[data-test-invoice-total-currency-code]',
'issued_at' => '#invoice-issued-at',
'paid' => '[data-test-invoice-is-paid]',
'shop_billing_data' => '#shop-billing-data',
'table' => '.table',
]);
Expand Down
2 changes: 2 additions & 0 deletions tests/Behat/Page/Admin/Invoice/ShowPageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,6 @@ public function download(): void;
public function resend(): void;

public function goBack(): void;

public function isPaid(): bool;
}