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

Regenerate invoices when a placed order is being modified by admin #103

Closed
martijnvdbrug opened this issue Feb 17, 2023 · 3 comments · Fixed by #328
Closed

Regenerate invoices when a placed order is being modified by admin #103

martijnvdbrug opened this issue Feb 17, 2023 · 3 comments · Fixed by #328

Comments

@martijnvdbrug
Copy link
Member

martijnvdbrug commented Feb 17, 2023

The problem

Invoices are only generated on order placement. When an administrator changes an order, no new invoice is generated.

In the Netherlands (and probably in more places) you are not allowed to change invoices that have been sent to the customer: You need to credit the old invoice, and create a new invoice, based on the old one.

Example:

  • First invoice #100 created with value €200
  • Order is changed to €180
  • Create credit invoice #101 with -€200. You also need to reference the original invoice on the credit invoice
  • Create new invoice #102 with value €180

Proposed solution

  • Initial invoice will always be generated on OrderPlaced event automatically
  • A button is added to the Admin UI Regenerate invoice that
      1. Creates a credit invoice for the previous invoice
      1. Generates a new invoice for the current order details
  • Invoice are only regenerated when an admin clicks the button, not automatically if the order changes.
  • An custom InvoiceCreated event is fired on every initial invoice generation. This only happens for the first invoice of an order.
InvoiceCreatedEvent {
   newInvoiceId: 123
   originalInvoiceId: undefined
   creditInvoiceId: undefined
}

When a new invoice is created for an order that already has an invoice, the event will look like this:

InvoiceCreatedEvent {
   newInvoiceId: 125
   originalInvoiceId: 123
   creditInvoiceId: 124
}

When a consumer has creditInvoices disabled, it looks like this:

InvoiceCreatedEvent {
   newInvoiceId: 124
   originalInvoiceId: 123
   creditInvoiceId: undefined
}

These events can be used to send customers the corrected version of your invoice, something like Sorry, we made a mistake We've credited invoice #123, with credit invoice #124, invoice #125 is the corrected version

Implementation

  • Orders will have a custom relation to invoice entity
  • Invoice entity will have the total amount and the tax details saved. This is needed to create credit invoices. Credit invoices will need the following data:
    • Reference to the previous invoice number
    • Inverted amount of the previous invoice, E.g -€100
    • The tax amount and rates of previous invoice
  • An negative invoiceEntity.totalAmount will mean its a credit invoice
  • Admin Graphql mutation regenerateInvoice(orderId: ID!)needs to be implemented
  • Admin UI button “re-generate invoice“ should be added. This button will require the custom AllowInvoicesPermission. The button should prompt a warning Are you sure ?
  • Invoice regeneration flow:
    • Create invoice for order. If previous invoice, create credit invoice.
    • Create new invoice
    • Emit InvoiceRecreatedEvent
  • A migration script should be written to upgrade existing plugins to this new structure, without losing any invoices/order references!
@martijnvdbrug martijnvdbrug added the Seeking input Seeking input from the community label Dec 13, 2023
@nicoes
Copy link
Contributor

nicoes commented Dec 13, 2023

I was thinking about this the other day. Some shops don't send an invoice in the mailbox straight away. They direct you to their webshop to download the invoice. And then 2. could be applied. There is still the edge case that the customer has already downloaded the invoice, and then the order was changed...

@martijnvdbrug
Copy link
Member Author

martijnvdbrug commented Dec 13, 2023

@nicoes Thanks for your input. So, the client would only download the latest (maybe re-generated) version of the invoice?

The shop owner would need to manage all the generated invoices + creditinvoices for each order change though, because they need invoices numbers to be consistent. There can be multiple invoices, if the admin changed the order multiple times.

@martijnvdbrug
Copy link
Member Author

Discussion from the Vendure discord:

Oidt — Today at 9:00 AM

is it easier to just generate a invoice when a order is shipped? at placement the order is not final so no invoice. when it is shipped make a invoice and send it to the customer.
at placement send a order received message.

Timur | Keeb.Supply — Today at 9:23 AM

Even after shipment it may not be final, maybe some item is refunded or you only do a partial fulfillment

Oidt — Today at 10:18 AM

it should be final for the invoice. when a item return you have a new scenario and credit the invoice and send a new one without returned item or only credit the returned item, it will not change the original order. at partial fulfillment you can send multiple invoices it will depend on your business i think

Martijn from Pinelab — Today at 2:24 PM

This is actually a good idea. The Vendure default order process also doesn't allow a Shipped order to be modified anymore, so the only thing that can happen is that an order is cancelled, in which case we should create a credit invoice.
Any subsequent changes will be in a new order, and thus a new invoice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants