-
-
Notifications
You must be signed in to change notification settings - Fork 723
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
[14.0][IMP] stock_reserve_rule: add full lot strategy #1834
Conversation
3e791e2
to
edd4fdc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
functional ok!
@OCA/logistics-maintainers good for merge?
This PR has the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what you try to achieve ? What are your real use cases ?
I have the impression that you try to minimize the amount of locations from which you reserve
Hi @jbaudoux thanks for review! |
Please also drop a review on #1831 :) |
@francesco-ooops @geomer198 looks tolerance doesn’t work :( |
Yes, I only added fields without functional. |
@jbaudoux please take a look :) |
f8c45ef
to
9352c9d
Compare
Done, fixed it! |
@jbaudoux feedback? |
@jbaudoux gentle reminder! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still issues to be addressed. Main concern is the group by location which does not seems inline with the intention of the module.
Also use float_compare and make a plain compare method.
Could you check my changes? Is now ok? |
781bd70
to
9a62218
Compare
@jbaudoux gentle reminder :) |
if computation == "percentage": | ||
# need + rounding < product_qty <= need * (100 + tolerance) / 100 | ||
return ( | ||
float_compare(need, product_qty, rounding) == -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you accept exact value when you give a tolerance? It should be in the limit defined by the tolerance but if the quantity is exactly the need, it should also be valid, isn't it?
float_compare(need, product_qty, rounding) == -1 | |
float_compare(need, product_qty, rounding) <= 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some unit tests on _compare_with_tolerance
with real figures would be helpful. Just the call to the method without picking.
Tests with inside tolerance, at the lower limit of tolerance, at the upper limit of the tolerance, below tolerance, above tolerance
- no tolerance
- upper_limit, percentage
- upper_limit, absolute
- lower_limit, percentage
- lower_limit, absolute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elvise This still needs to be fixed or answered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@francesco-ooops @geomer198 please take care
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Done! Please check tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Done! Please check tests.
@geomer198 can you add tests with decimals (qty)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Done! Please check tests.
@geomer198 can you add tests with decimals (qty)?
Yes) Done!
need = ( | ||
yield fields.first(lot_quants).location_id, | ||
lot_quantity, | ||
need, | ||
lot, | ||
None, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have selected a lot and it can have multiple quants. I think you need to yield each quant one by one by looping on the quants (they should be already sorted by fifo/fefo) decreasing the need until need is 0 or all quants are consumed.
Can you add a test with this?
Example:
- Loc1, Lot A, 10 units
- Loc2, Lot A, 5 units
Need for 15 units. Lot A is selected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Thank you for your solution! I updated function implementation. Now the strategy looks better!
Thanks for the work. The code is so much cleaner, easy to read and simple :) |
@jbaudoux Please check my changes. |
@jbaudoux gentle reminder :) |
1 similar comment
@jbaudoux gentle reminder :) |
for lot_quant in lot_quants: | ||
product_qty = sum(lot_quant.mapped("quantity")) | ||
lot_quantity = sum(lot_quant.mapped("quantity")) - sum( | ||
lot_quant.mapped("reserved_quantity") | ||
) | ||
if ( | ||
lot | ||
and self._compare_with_tolerance(need, product_qty, rounding) | ||
and lot_quantity > 0 | ||
): | ||
need = ( | ||
yield lot_quant.location_id, | ||
lot_quantity, | ||
need, | ||
lot, | ||
None, | ||
) # noqa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about lots that are partially reserved? I think you want to skip them.
product_qty
can be computed outside loop.
for lot_quant in lot_quants: | |
product_qty = sum(lot_quant.mapped("quantity")) | |
lot_quantity = sum(lot_quant.mapped("quantity")) - sum( | |
lot_quant.mapped("reserved_quantity") | |
) | |
if ( | |
lot | |
and self._compare_with_tolerance(need, product_qty, rounding) | |
and lot_quantity > 0 | |
): | |
need = ( | |
yield lot_quant.location_id, | |
lot_quantity, | |
need, | |
lot, | |
None, | |
) # noqa | |
if not lot: | |
continue | |
if any(quant.reserved_quantity in lot_quants): | |
# skip lots that are partially reserved | |
continue | |
product_qty = sum(lot_quants.mapped("quantity")) | |
if not self._compare_with_tolerance(need, product_qty, rounding): | |
continue | |
for lot_quant in lot_quants: | |
lot_quantity = lot_quant.quantity - lot_quant.reserved_quantity | |
need = yield ( | |
lot_quant.location_id, | |
lot_quantity, | |
need, | |
lot, | |
None, | |
) # noqa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Could you check my proposed version of the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux Your code has an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if any(quant.reserved_quantity for quant in lot_quants):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geomer198 was this addressed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geomer198 was this addressed?
Yes, I added this code.
for lot, lot_quants in quants.filtered( | ||
lambda quant: quant.product_id.id == product.id | ||
and quant.lot_id | ||
and not quant.reserved_quantity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cannot exclude quant with reserved quantities before the group by. If the lot is on 2 locations and has a reservation only on one location, you will not end-up with the right result
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbaudoux I fixed it. I hope now is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we lost the exclusion. See my proposed solution above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we lost the exclusion. See my proposed solution above
I didn't understand this line:
if any(quant.reserved_quantity in lot_quants):
# skip lots that are partially reserved
continue
In this function only quants
variable. And why float must be contain in quant's record set?
@jbaudoux good now ? :) |
@elvise @francesco-ooops Write unit tests for the tolerance. See #1834 (comment) |
There hasn't been any activity on this pull request in the past 4 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 30 days. |
New removal strategy is added.