OBPIH-6502 Add API endpoints to edit prepaid invoice items#4800
OBPIH-6502 Add API endpoints to edit prepaid invoice items#4800awalkowiak merged 3 commits intofeature/OBPIH-6398-partial-invoices-for-prepaid-pofrom
Conversation
| Integer quantityAvailableToInverse = inverseItem.quantity + getQuantityAvailableToInverse(orderItem, prepaymentItem) | ||
| Integer quantityToInverse = quantity > quantityAvailableToInverse ? quantityAvailableToInverse : quantity | ||
| inverseItem.quantity = quantityToInverse | ||
| inverseItem.amount = quantityToInverse * prepaymentItem.unitPrice * orderItem.order.prepaymentPercent * (-1) |
There was a problem hiding this comment.
@ewaterman I still remember you wanted to move it to separate method but I was not sure how to actually do it. Is something like that what you'd expect here:
BigDecimal calculateAmount(Integer quantity, BigDecimal unitPrice, BigDecimal percentage = 1, Integer inverse = 1) {
return quantity * unitPrice * percentage * inverse
}and then just passing what we have available or need to use in calculation, or do you see here something a bit more complex in this method?
There was a problem hiding this comment.
I think the thing I'm mainly worried about is that we calculate amount all over the place and it'd be nice to have a calculateAmountForPrepaymentItem(), calculateAmountForRegularItem() and calculateAmountForInverseItem() methods just to have it unified.
I haven't thought it through fully so this might not be the best idea, but they could maybe just take in the invoice item itself and do all the lookups they need so that the caller doesn't need to know what to do.
The logic here is just a bit tough to navigate with all the transients and chained calls so it'd be great if there was a simple method of calculating it that brought it all together
There was a problem hiding this comment.
Ok, I think I am going to leave it as is for now, but I'll think about this as a standalone improvement in separate ticket/pr
| action = [POST: "validateInvoiceItem"] | ||
| } | ||
|
|
||
| "/api/prepaymentInvoices/$id/invoiceItems" { |
There was a problem hiding this comment.
I'm not generally a fan of the camelcase URIs. I usually try to stick to a feature/sub-feature/entity-based system with something like: /api/invoices/prepayment/$id/items or /api/prepayment-invoices/$id/invoice-items. Up to you though
There was a problem hiding this comment.
We don't have a written convention for these yet (camel vs kebab case), hence I am following for now what we have in other cases (ex. stockMovements, partialReceiving, etc)
|
|
||
| class PrepaymentInvoiceApiController { | ||
|
|
||
| def prepaymentInvoiceService |
There was a problem hiding this comment.
in my opinion we should use proper types unless it's absolutely necessary to use def
There was a problem hiding this comment.
I am also always trying to catch all of the unnecessary defs in review 🫶
| "/api/prepaymentInvoiceItems/$id/" { | ||
| controller = "prepaymentInvoiceItemApi" | ||
| action = [DELETE: "delete"] | ||
| action = [POST: "update", DELETE: "delete"] |
There was a problem hiding this comment.
If I'm doing an update only on the provided fields I usually use PATCH over POST (I think that's the generally accepted convention) but I'm not really bothered either way.
You do have a trailing slash in the URI which is probably best to remove for consistency's sake but up to you.
| * change quantity on the corresponding inverse item. | ||
| * | ||
| * */ | ||
| void updateItemsQuantity(String invoiceId, List items) { |
There was a problem hiding this comment.
It might be best to make this method more generic (ie call it updateItems instead of updateItemsQuantity). Right now we only allow you to update the quantity field but that could change in the future.
| Integer quantityAvailableToInvoice = invoiceItem.shipmentItem.quantityToInvoice | ||
| if (quantity > quantityAvailableToInvoice + invoiceItem.quantity) { | ||
| throw new IllegalArgumentException("Cannot update quantity to higher value than available to invoice") | ||
| } |
There was a problem hiding this comment.
I asked a similar question in the other PR, but what about cancelled items? You shouldn't be able to update the invoice quantity right? Is that already handled by the quantityToInvoice field? Would it just be 0 in that case?
There was a problem hiding this comment.
Canceled items don't have shipment items, so these are already ruled out and we don't allow to change the quantity on them
|
|
||
| // If there is a case that we did not found inverse item, but it was made available to inverse now after | ||
| // editing or removing invoice items on invoices, lets try to create it here | ||
| inverseItem = createInverseItemForShipmentItem(invoiceItem?.shipmentItem, invoiceItem) |
There was a problem hiding this comment.
nitpick: I'd put this case in the if block (and change the condition to if (!inverseItem)) since it's much simpler and so the big block above doesn't need to be nested inside an if block.
| def update() { | ||
| JSONObject jsonObject = request.JSON | ||
| Integer quantity = jsonObject.get('quantity') | ||
| prepaymentInvoiceService.updateInvoiceItemQuantity(params.id, quantity) | ||
| render status: 200 | ||
| } |
There was a problem hiding this comment.
btw, from the frontend perspective, update/post methods should return the newly updated state, because we always have to refetch the new data. It's not a change request, because in this one case, on the frontend it's not necessary to fetch the data again, but in most cases, we should.
There was a problem hiding this comment.
I agree, but here we have a bit more complex update, where we are passing one invoice item, but in reality we are updating two, so should we return both here or only the one that was sent in requests? Due to this, I decided to keep it simple and return only status, at least for now.
| Invoice invoice = Invoice.get(invoiceId) | ||
| if (!invoice) { | ||
| String defaultMessage = "Cannot find invoice with id: ${invoiceId}" | ||
| throw new IllegalArgumentException(g.message(code: "invoice.cannotFind.label", args: [invoiceId], default: defaultMessage)) |
There was a problem hiding this comment.
we don't typically bother setting a default value for localization strings do we?
There was a problem hiding this comment.
I think we don't have clear convention
0778a20
into
feature/OBPIH-6398-partial-invoices-for-prepaid-po
✨ Description of Change
Link to GitHub issue or Jira ticket:
https://pihemr.atlassian.net/browse/OBPIH-6502
Description:
Add API endpoints to edit prepaid invoice items
📈 Test Plan
Description of test plan (if applicable):
Will be tested with frontend changes
✅ Quality Checks
[OBS-123]for Jira,[#0000]for GitHub, or[OBS-123, OBPIH-123]if there are multiple), or with[N/A]if not applicable