Skip to content

OBPIH-6497 [backend] Determine encumbered and invoiceable items or adjustments#4772

Merged
awalkowiak merged 8 commits intodevelopfrom
OBPIH-6497
Jul 31, 2024
Merged

OBPIH-6497 [backend] Determine encumbered and invoiceable items or adjustments#4772
awalkowiak merged 8 commits intodevelopfrom
OBPIH-6497

Conversation

@alannadolny
Copy link
Collaborator

No description provided.

Boolean getIsEncumbered() {
return !isInvoiced && hasPrepaymentInvoice
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

I know we've done that in some places, but I don't like the naming like getIs.
Booleans should be named as isSomething.
Moreover, those don't have to be marked transients anymore, so you could just have a method isInvoicable().

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, but the naming convention with get, allows us to use the .getIsEncumbered() in this way: .isEncumbered, so I prefer this groovy syntactic sugar

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see anything bad in using .isEncumbered() vs forcing to access a property via the field name (isEncumbered). I feel like naming booleans using getIs, getHas is an anti-pattern we should avoid.
https://rules.sonarsource.com/java/tag/convention/RSPEC-2047/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is groovy, not Java 😄
The rule that you send is another case. They say that we should use hasBar, not getBar

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, and why should we use getBar for a boolean field?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not getBar, but getIsBar, and then we can use it isBar

Copy link
Collaborator

Choose a reason for hiding this comment

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

I will repeat it again, and you will do whatever you want - getIs feels like antipattern, and I don't see anything wrong in using isBar() in this case.

Copy link
Member

Choose a reason for hiding this comment

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

I'm used to seeing fields like:

invoiceable
encumbered

with getters and setters like

isInvoiceable
setInvoiceable
isEncumbered
setEncumbered

From the groovy docs: https://groovy-lang.org/objectorientation.html#_property_naming_conventions

...generated getters and setters will have a name formed by capitalizing the property name and adding a get or set prefix (or optionally "is" for a boolean getter)... isEmpty might be the getter method name for a property named empty.

So with that setup in Groovy we could do boolean isOrderInvoiceable = order.isInvoiceable() as Kacper says. That's my personal preference but if you disagree Alan feel free to do as you wish.

Copy link
Member

@jmiranda jmiranda Jul 29, 2024

Choose a reason for hiding this comment

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

Java beans use the same convention.

So since we keep having this conversation

#4266 (review)

... let's just use the java/groovy convention from now one.

So no more "is" prefix in the property name.


Aside: All I really care about is that I want to use Groovy's implicit getter method

if (order.invoiceable)

over the explicit getter methods

if(order.getInvoiceable())

or

if(order.isInvoiceable())

Copy link
Collaborator

Choose a reason for hiding this comment

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

The problem with getIs is that the property itself would be named with the is prefix, e.g. isInvoiceable instead of invoiceable.
https://stackoverflow.com/a/5322730

Your field should not be called isCurrent in the first place. Is is a verb and verbs are inappropriate to represent an Object's state. Use an adjective instead, and suddenly your getter / setter names will make more sense:


Boolean getHasNotInvoicedAdjustment() {
return orderAdjustments.any { !it.isInvoiced }
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

same as above

return !hasInvoice && isPrepaymentRequired && hasActiveItemsOrAdjustments
}

/*
Copy link
Member

Choose a reason for hiding this comment

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

I think you need javadocs to start with /** (two asterisks) to have them work correctly in IDEs and other tools. Good job with the documentation here though!

Copy link
Collaborator

@awalkowiak awalkowiak left a comment

Choose a reason for hiding this comment

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

First comment is a request change, second one is just a question

}

return orderItems.any {
it.hasNotInvoicedAdjustment || // condition related to first point
Copy link
Collaborator

Choose a reason for hiding this comment

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

What if the order adjustment is not tied to any order item? This is possible too

}

Boolean getIsEncumbered() {
return !isInvoiced && hasPrepaymentInvoice
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be also order.isPlaced() to be considered encumbered or not?

Set<OrderItem> orderItems = [
Mock(OrderItem),
orderItem,
Mock(OrderItem)
Copy link
Member

Choose a reason for hiding this comment

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

what do these mock order items give us?

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 added those mocked order items, because we have to have at least one order item fulfilling the tested case, so I am testing if one item of those three matches the tested condition.

Copy link
Member

@ewaterman ewaterman Jul 30, 2024

Choose a reason for hiding this comment

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

I guess my question was more what kind of values do these mocks return? Do they have quantity 0?

hasPrepaymentInvoice | orderItemStatusCode | isEncumbered || canGenerateInvoice
false | OrderItemStatusCode.CANCELED | false || false
true | OrderItemStatusCode.CANCELED | false || false
true | OrderItemStatusCode.PENDING | true || false
Copy link
Member

Choose a reason for hiding this comment

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

what about testing the scenario where Order.stats == PLACED? then you would be able to generate an invoice right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Order status cannot be placed. The available options are:

[PENDING, COMPLETED, CANCELED, BACKORDER]

Copy link
Member

Choose a reason for hiding this comment

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

that's OrderItemStatusCode right? I meant OrderStatus

@github-actions github-actions bot added the domain: backend Changes or discussions relating to the backend server label Jul 30, 2024
@alannadolny alannadolny requested a review from awalkowiak July 30, 2024 11:39
where:
hasPrepaymentInvoice || canGenerateInvoice
false || false
true || false
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this condition return true? You have an un-invoiced adjustment that has no associated order items

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

that's interesting, why this test doesn't fail

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, got the reason, I didn't take order status into account (orderAdjustment.isInvoiceable takes into account the fact if order is placed)

/**
Should return true if at least one PO item is invoiceable.
A PO item is invoiceable if the order has a prepayment invoice and at least one of those requirements are fulfilled:
1. There is an order adjustment on that item that hasn’t already been invoiced
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the first point is misleading.

What is an invoiceable item?
a shipped item or a placed adjustment; any placed adjustment is pulled as invoiceable on the partial final invoice generated (but it can be removed or edited) or a canceled line

Order adjustment should be invoiceable if the order has a prepayment invoice and is placed.
Order item should be invoiceable if it has prepayment invoice and:

  1. is partially shipped (only this partial quantity not yet invoiced is invoiceable)
  2. items canceled that are not yet invoiced

Imho there is no need to check in order item is invoiceable if it has NotInvoicedAdjustment, I think the order adjustments should be separated from order items and checked as it is written above.

(to be confirmed)

@awalkowiak awalkowiak merged commit c5cc782 into develop Jul 31, 2024
@awalkowiak awalkowiak deleted the OBPIH-6497 branch July 31, 2024 13:39
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.

6 participants