Skip to content

Commit

Permalink
refactor #226 Relate Invoice with Order (Zales0123)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.0-dev branch.

Discussion
----------

Similar to Sylius/RefundPlugin#306 and Sylius/RefundPlugin#307.

Should be easier to operate on the Invoice with a proper relation rather than just an order number

Commits
-------

081b080 Add Order relation on Invoice (and remove order number field)
e480edc Use order instead of order number in invoice repository
0ab7fed Final fixes
ce949d3 Mention changes in the UPGRADE file
8411c18 Remove unneeded point in UPGRADE file
  • Loading branch information
GSadee authored Jun 14, 2021
2 parents dea611b + 8411c18 commit 1015a34
Show file tree
Hide file tree
Showing 24 changed files with 157 additions and 53 deletions.
10 changes: 10 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
### UPGRADE FROM 0.15.0 TO 0.16.0

1. `orderNumber` field on `Sylius\InvoicingPlugin\Entity\Invoice` has been removed and replaced with relation to `Order` entity.
1. `Sylius\InvoicingPlugin\Entity\InvoiceInterface::orderNumber` function is left due to easier and smoother upgrades,
but is also deprecated and will be removed in the `v1.0.0` release. Use `Sylius\InvoicingPlugin\Entity\InvoiceInterface::order` instead.
1. `Sylius\InvoicingPlugin\Doctrine\ORM\InvoiceRepositoryInterface::findOneByOrderNumber` method has been replaced by
`Sylius\InvoicingPlugin\Doctrine\ORM\InvoiceRepositoryInterface::findOneByOrder`.
1. `Sylius\InvoicingPlugin\Factory\InvoiceFactoryInterface::createForData` takes `OrderInterface $order` as the 3rd argument instead
of `string $orderNumber`.

### UPGRADE FROM 0.14.0 TO 0.15.0

1. Command bus `sylius_invoicing_plugin.command_bus` has been replaced with `sylius.command_bus`.
Expand Down
6 changes: 3 additions & 3 deletions spec/CommandHandler/SendInvoiceEmailHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public function it_requests_an_email_with_an_invoice_to_be_sent(
OrderInterface $order,
CustomerInterface $customer
): void {
$invoiceRepository->findOneByOrderNumber('0000001')->willReturn($invoice);

$orderRepository->findOneByNumber('0000001')->willReturn($order);

$invoiceRepository->findOneByOrder($order)->willReturn($invoice);

$order->getCustomer()->willReturn($customer);

$customer->getEmail()->willReturn('[email protected]');
Expand All @@ -60,8 +60,8 @@ public function it_does_not_request_an_email_to_be_sent_if_invoice_was_not_found
OrderInterface $order,
CustomerInterface $customer
): void {
$invoiceRepository->findOneByOrderNumber('0000001')->willReturn(null);
$orderRepository->findOneByNumber('0000001')->willReturn($order);
$invoiceRepository->findOneByOrder($order)->willReturn(null);

$order->getCustomer()->shouldNotBeCalled();
$customer->getEmail()->shouldNotBeCalled();
Expand Down
12 changes: 7 additions & 5 deletions spec/Creator/InvoiceCreatorSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public function it_creates_invoice_for_order(
OrderInterface $order,
InvoiceInterface $invoice
): void {
$invoiceRepository->findOneByOrderNumber('0000001')->willReturn(null);

$orderRepository->findOneByNumber('0000001')->willReturn($order);

$invoiceRepository->findOneByOrder($order)->willReturn(null);

$invoiceDateTime = new \DateTimeImmutable('2019-02-25');

$invoiceGenerator->generateForOrder($order, $invoiceDateTime)->willReturn($invoice);
Expand All @@ -62,17 +62,19 @@ public function it_throws_an_exception_when_invoice_was_already_created_for_give
InvoiceRepositoryInterface $invoiceRepository,
OrderRepositoryInterface $orderRepository,
InvoiceGeneratorInterface $invoiceGenerator,
OrderInterface $order,
InvoiceInterface $invoice
): void {
$invoiceRepository->findOneByOrderNumber('0000001')->willReturn($invoice);
$orderRepository->findOneByNumber('0000001')->willReturn($order);
$invoiceRepository->findOneByOrder($order)->willReturn($invoice);

$invoiceDateTime = new \DateTimeImmutable('2019-02-25');

$orderRepository->findOneByNumber(Argument::any())->shouldNotBeCalled();
$invoiceGenerator->generateForOrder(Argument::any(), Argument::any())->shouldNotBeCalled();
$invoiceRepository->add(Argument::any())->shouldNotBeCalled();

$this->shouldThrow(InvoiceAlreadyGenerated::withOrderNumber('0000001'))
$this
->shouldThrow(InvoiceAlreadyGenerated::withOrderNumber('0000001'))
->during('__invoke', ['0000001', $invoiceDateTime])
;
}
Expand Down
13 changes: 8 additions & 5 deletions spec/Entity/InvoiceSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\InvoicingPlugin\Entity\BillingDataInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;
Expand All @@ -30,14 +31,15 @@ public function let(
LineItemInterface $lineItem,
TaxItemInterface $taxItem,
ChannelInterface $channel,
InvoiceShopBillingDataInterface $shopBillingData
InvoiceShopBillingDataInterface $shopBillingData,
OrderInterface $order
): void {
$issuedAt = \DateTimeImmutable::createFromFormat('Y-m', '2019-01');

$this->beConstructedWith(
'7903c83a-4c5e-4bcf-81d8-9dc304c6a353',
$issuedAt->format('Y/m') . '/000000001',
'007',
$order,
$issuedAt,
$billingData,
'USD',
Expand All @@ -60,16 +62,17 @@ public function it_implements_resource_interface(): void
$this->shouldImplement(ResourceInterface::class);
}

public function it_has_an_id(
public function it_has_data(
BillingDataInterface $billingData,
LineItemInterface $lineItem,
TaxItemInterface $taxItem,
ChannelInterface $channel,
InvoiceShopBillingDataInterface $shopBillingData
InvoiceShopBillingDataInterface $shopBillingData,
OrderInterface $order
): void {
$this->id()->shouldReturn('7903c83a-4c5e-4bcf-81d8-9dc304c6a353');
$this->number()->shouldReturn('2019/01/000000001');
$this->orderNumber()->shouldReturn('007');
$this->order()->shouldReturn($order);
$this->billingData()->shouldReturn($billingData);
$this->currencyCode()->shouldReturn('USD');
$this->localeCode()->shouldReturn('en_US');
Expand Down
4 changes: 2 additions & 2 deletions spec/EventProducer/OrderPaymentPaidProducerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function it_dispatches_order_payment_paid_event_for_payment(

$event = new OrderPaymentPaid('0000001', $dateTime);

$invoiceRepository->findOneByOrderNumber('0000001')->willReturn($invoice);
$invoiceRepository->findOneByOrder($order)->willReturn($invoice);

$eventBus->dispatch($event)->shouldBeCalled()->willReturn(new Envelope($event));

Expand Down Expand Up @@ -80,7 +80,7 @@ public function it_does_not_dispatch_event_when_there_is_no_invoice_related_to_o
): void {
$payment->getOrder()->willReturn($order);
$order->getNumber()->willReturn('0000001');
$invoiceRepository->findOneByOrderNumber('0000001')->willReturn(null);
$invoiceRepository->findOneByOrder($order)->willReturn(null);

$eventBus->dispatch(Argument::any())->shouldNotBeCalled();
$dateTimeProvider->__invoke()->shouldNotBeCalled();
Expand Down
11 changes: 7 additions & 4 deletions spec/Factory/InvoiceFactorySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\InvoicingPlugin\Entity\BillingDataInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceShopBillingDataInterface;
Expand All @@ -31,14 +32,15 @@ public function it_implements_invoice_factory_interface(): void
public function it_creates_an_invoice_for_given_data(
BillingDataInterface $billingData,
ChannelInterface $channel,
InvoiceShopBillingDataInterface $invoiceShopBillingData
InvoiceShopBillingDataInterface $invoiceShopBillingData,
OrderInterface $order
): void {
$date = new \DateTimeImmutable('2019-03-06');

$this->createForData(
'7903c83a-4c5e-4bcf-81d8-9dc304c6a353',
'2019/03/0000001',
'007',
$order,
$date,
$billingData,
'USD',
Expand All @@ -53,14 +55,15 @@ public function it_creates_an_invoice_for_given_data(

public function it_allows_for_nullable_shop_billing_data(
BillingDataInterface $billingData,
ChannelInterface $channel
ChannelInterface $channel,
OrderInterface $order
): void {
$date = new \DateTimeImmutable('2019-03-06');

$this->createForData(
'7903c83a-4c5e-4bcf-81d8-9dc304c6a353',
'2019/03/0000001',
'007',
$order,
$date,
$billingData,
'USD',
Expand Down
3 changes: 1 addition & 2 deletions spec/Generator/InvoiceGeneratorSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public function it_generates_an_invoice_for_a_given_order(
$uuidInvoiceIdentifierGenerator->generate()->willReturn('7903c83a-4c5e-4bcf-81d8-9dc304c6a353');
$sequentialInvoiceNumberGenerator->generate()->willReturn($date->format('Y/m') . '/0000001');

$order->getNumber()->willReturn('007');
$order->getCurrencyCode()->willReturn('USD');
$order->getLocaleCode()->willReturn('en_US');
$order->getTotal()->willReturn(10300);
Expand All @@ -95,7 +94,7 @@ public function it_generates_an_invoice_for_a_given_order(
$invoiceFactory->createForData(
'7903c83a-4c5e-4bcf-81d8-9dc304c6a353',
'2019/03/0000001',
'007',
$order,
$date,
$billingData,
'USD',
Expand Down
8 changes: 4 additions & 4 deletions src/CommandHandler/SendInvoiceEmailHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ public function __construct(

public function __invoke(SendInvoiceEmail $command): void
{
/** @var OrderInterface $order */
$order = $this->orderRepository->findOneByNumber($command->orderNumber());

/** @var InvoiceInterface|null $invoice */
$invoice = $this->invoiceRepository->findOneByOrderNumber($command->orderNumber());
$invoice = $this->invoiceRepository->findOneByOrder($order);

if (null === $invoice) {
return;
}

/** @var OrderInterface $order */
$order = $this->orderRepository->findOneByNumber($command->orderNumber());

if (null === $order->getCustomer()) {
return;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Creator/InvoiceCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ public function __construct(

public function __invoke(string $orderNumber, \DateTimeInterface $dateTime): void
{
/** @var OrderInterface $order */
$order = $this->orderRepository->findOneByNumber($orderNumber);

/** @var InvoiceInterface|null $invoice */
$invoice = $this->invoiceRepository->findOneByOrderNumber($orderNumber);
$invoice = $this->invoiceRepository->findOneByOrder($order);

if (null !== $invoice) {
throw InvoiceAlreadyGenerated::withOrderNumber($orderNumber);
}

/** @var OrderInterface $order */
$order = $this->orderRepository->findOneByNumber($orderNumber);

$invoice = $this->invoiceGenerator->generateForOrder($order, $dateTime);

$this->invoiceRepository->add($invoice);
Expand Down
17 changes: 15 additions & 2 deletions src/Doctrine/ORM/InvoiceRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,28 @@
namespace Sylius\InvoicingPlugin\Doctrine\ORM;

use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;

class InvoiceRepository extends EntityRepository implements InvoiceRepositoryInterface
{
public function findOneByOrderNumber(string $orderNumber): ?InvoiceInterface
public function findOneByOrder(OrderInterface $order): ?InvoiceInterface
{
/** @var InvoiceInterface|null $invoice */
$invoice = $this->findOneBy(['orderNumber' => $orderNumber]);
$invoice = $this->findOneBy(['order' => $order]);

return $invoice;
}

public function findByOrderNumber(string $orderNumber): array
{
return $this
->createQueryBuilder('invoice')
->innerJoin('invoice.order', 'o')
->where('o.number = :orderNumber')
->setParameter('orderNumber', $orderNumber)
->getQuery()
->getResult()
;
}
}
5 changes: 4 additions & 1 deletion src/Doctrine/ORM/InvoiceRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@

namespace Sylius\InvoicingPlugin\Doctrine\ORM;

use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;

interface InvoiceRepositoryInterface extends RepositoryInterface
{
public function findOneByOrderNumber(string $orderNumber): ?InvoiceInterface;
public function findOneByOrder(OrderInterface $order): ?InvoiceInterface;

public function findByOrderNumber(string $orderNumber): array;
}
16 changes: 11 additions & 5 deletions src/Entity/Invoice.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;

/** @final */
class Invoice implements InvoiceInterface
Expand All @@ -25,8 +26,8 @@ class Invoice implements InvoiceInterface
/** @var string */
protected $number;

/** @var string */
protected $orderNumber;
/** @var OrderInterface */
protected $order;

/** @var \DateTimeInterface */
protected $issuedAt;
Expand Down Expand Up @@ -58,7 +59,7 @@ class Invoice implements InvoiceInterface
public function __construct(
string $id,
string $number,
string $orderNumber,
OrderInterface $order,
\DateTimeInterface $issuedAt,
BillingDataInterface $billingData,
string $currencyCode,
Expand All @@ -71,7 +72,7 @@ public function __construct(
) {
$this->id = $id;
$this->number = $number;
$this->orderNumber = $orderNumber;
$this->order = $order;
$this->issuedAt = clone $issuedAt;
$this->billingData = $billingData;
$this->currencyCode = $currencyCode;
Expand Down Expand Up @@ -108,9 +109,14 @@ public function number(): string
return $this->number;
}

public function order(): OrderInterface
{
return $this->order;
}

public function orderNumber(): string
{
return $this->orderNumber;
return (string) $this->order->getNumber();
}

public function issuedAt(): \DateTimeInterface
Expand Down
4 changes: 4 additions & 0 deletions src/Entity/InvoiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Resource\Model\ResourceInterface;

interface InvoiceInterface extends ResourceInterface
Expand All @@ -23,6 +24,9 @@ public function id(): string;

public function number(): string;

public function order(): OrderInterface;

/** @deprecated this method is deprecated an will be remove in v1.0 - use InvoiceInterface::order() instead */
public function orderNumber(): string;

public function issuedAt(): \DateTimeInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/EventProducer/OrderPaymentPaidProducer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ private function shouldEventBeDispatched(PaymentInterface $payment): bool
/** @var OrderInterface $order */
$order = $payment->getOrder();

return null !== $order && null !== $this->invoiceRepository->findOneByOrderNumber($order->getNumber());
return null !== $order && null !== $this->invoiceRepository->findOneByOrder($order);
}
}
5 changes: 3 additions & 2 deletions src/Factory/InvoiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\Common\Collections\Collection;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\InvoicingPlugin\Entity\BillingDataInterface;
use Sylius\InvoicingPlugin\Entity\Invoice;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;
Expand All @@ -26,7 +27,7 @@ final class InvoiceFactory implements InvoiceFactoryInterface
public function createForData(
string $id,
string $number,
string $orderNumber,
OrderInterface $order,
\DateTimeInterface $issuedAt,
BillingDataInterface $billingData,
string $currencyCode,
Expand All @@ -40,7 +41,7 @@ public function createForData(
return new Invoice(
$id,
$number,
$orderNumber,
$order,
$issuedAt,
$billingData,
$currencyCode,
Expand Down
Loading

0 comments on commit 1015a34

Please sign in to comment.