Skip to content

OBPIH-6536 [backend] Create partial invoice for prepay PO#4776

Merged
awalkowiak merged 6 commits intodevelopfrom
OBPIH-6536
Aug 5, 2024
Merged

OBPIH-6536 [backend] Create partial invoice for prepay PO#4776
awalkowiak merged 6 commits intodevelopfrom
OBPIH-6536

Conversation

@alannadolny
Copy link
Collaborator

✨ Description of Change

A concise summary of what is being changed. Please provide enough context for reviewers to be able to understand the change and why it is necessary.

Link to GitHub issue or Jira ticket: https://pihemr.atlassian.net/browse/OBPIH-6536

Description:


📷 Screenshots & Recordings (optional)


📈 Test Plan

We require that all code changes come paired with a method of testing them. Please select which of the following testing approaches you've included with this change:

  • Frontend automation tests (unit)
  • Backend automation tests (unit, API, smoke)
  • End-to-end tests (Playwright)
  • Manual tests (please describe below)
  • Not Applicable

Description of test plan (if applicable):
Check whether only not invoiced items/adjustments are visible on the Create Invoice page


✅ Quality Checks

Please confirm and check each of the following to ensure that your change conforms to the coding standards of the project:

  • The pull request title is prefixed with the issue/ticket number (Ex: [OBS-123] for Jira, [#0000] for GitHub, or [OBS-123, OBPIH-123] if there are multiple), or with [N/A] if not applicable
  • The pull request description has enough information for someone without context to be able to understand the change and why it is needed
  • The change has tests that prove the issue is fixed / the feature works as intended

2nd condition is met - the context is available in the ticket

@alannadolny alannadolny self-assigned this Aug 2, 2024
@github-actions github-actions bot added the domain: backend Changes or discussions relating to the backend server label Aug 2, 2024
}

Invoice invoice = invoiceService.generateInvoice(order)
Invoice invoice = prepaymentInvoiceService.generateInvoice(order)
Copy link
Member

Choose a reason for hiding this comment

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

What method is getting called when generating an invoice for a PO that wasn't pre-paid? If this API is used in non-prepay related flows we don't want to have it use the prepaymentInvoiceService

Copy link
Member

Choose a reason for hiding this comment

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

nvm I see the first line in the method checks that it has a prepayment invoice already.

Have you considered moving these methods to a PrepaymentInvoiceController since you're also doing that for the service methods?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it's not worth it, to be honest. Later we will add PrepaymentInvoiceApiController, so this one will have only one endpoint.

class InvoiceServiceSpec extends Specification implements ServiceUnitTest<InvoiceService>, DataTest {

@Override
Class<?>[] getDomainClassesToMock() {
Copy link
Member

Choose a reason for hiding this comment

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

why is this needed? You can't just call mockDomains in setup?

OrderItem orderItem = shipmentItem.orderItems?.find { it }
InvoiceItem invoiceItem = new InvoiceItem(
quantity: shipmentItem.quantity ? shipmentItem.quantity/orderItem.quantityPerUom : 0,
quantity: shipmentItem.quantityToInvoice ? (shipmentItem.quantityToInvoice / orderItem?.quantityPerUom) : 0,
Copy link
Member

Choose a reason for hiding this comment

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

is this not going to affect non-prepayment invoices? Or is the assumption that quantityInvoiced is always 0 for that because we don't support partial invoicing?

}

Integer getQuantityToInvoice() {
return quantity - quantityInvoiced
Copy link
Member

@ewaterman ewaterman Aug 2, 2024

Choose a reason for hiding this comment

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

What's your plan for eventually handling cancellations/returns/reductions of quantity?

quantityInvoiced loops through all the invoices and sums the quantity, which works fine for the case where there are no quantity adjustments but... if a shipment item has quantity 3 and we cancelled or returned the shipment, we generate an invoice with quantity 0. In that scenario quantityInvoiced for the shipment item is 0, and isInvoiceable will be true (which is incorrect). We'll need some way to note that even if we invoice for less than the quantity shipped for that shipment item, we've still "fully invoiced" it.

Same thought for reducing quantity (shipment has quantity 3 but in reality they shipped 2 so we only want to invoice for quantity 2 (or whatever that case looks like))

Side note: I remember chatting with Manon about whether we need to be able to split a single shipment item up into multiple invoices (Ex: we have a shipment item with quantity 3 which has an invoice item with quantity 1 and another invoice item with quantity 2) and I thiiiiink she said we don't need the ability to do that (probably worth confirming).

So maybe it'd just be a matter of changing the getQuantityInvoiced method to return 0 for shipment items without an invoice and shipmentItem.quantity for shipment items that do have an invoice. So we ignore the quantity in the invoiceItem for the purpose of determining if the shipment item has been fully invoiced. (Which we can do because we can safely assume that each shipmentItem will only ever have a single invoiceItem so if it was invoiced at all, it's done.)

I know the work to implement cancellations isn't covered by this ticket, I just want to make sure it'll eventually be able to work within this system.

@Transactional
class PrepaymentInvoiceService {

InvoiceService invoiceService
Copy link
Member

@ewaterman ewaterman Aug 2, 2024

Choose a reason for hiding this comment

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

Generally my preference would be to not have services call other services but instead move common code to shared util classes (Ex: InvoiceNumberGenerator, InvoiceItemGenerator (or whatever names)). It breaks the code up into more manageable units (easier testing too).

I don't expect you to make any kind of change like that here though. Just noting down my thoughts.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ewaterman could you expand on that? I am a bit surprised you suggest not to inject services in services. It's a known practice throughout spring community.
Even if for example we wanted to just fetch a product and used productService.findProduct (or anything like this).
How would you move such method then? If it were supposed to be a util class, anyway it would have to be a bean, so it would evaluate to a "service" anyway.

return orderItems.findAll { it.invoiceable }
}

Set<OrderAdjustment> getInvoiceableAdjustment() {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Set<OrderAdjustment> getInvoiceableAdjustment() {
Set<OrderAdjustment> getInvoiceableAdjustments() {

@awalkowiak awalkowiak merged commit 67ad18e into develop Aug 5, 2024
@awalkowiak awalkowiak deleted the OBPIH-6536 branch August 5, 2024 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: backend Changes or discussions relating to the backend server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants