Repository navigation
[FIX] purchase_stock_ux: cancel remaining must not leave a pending vendor receipt nor a counter-delivery - #365
fw-bot-adhoc wants to merge 1 commit into
Conversation
|
@jcadhoc @les-adhoc cherrypicking of pull request #358 failed. stdout: Either perform the forward-port manually (and push to this branch, proceeding as usual) or close this PR (maybe?).
More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port |
|
@jcadhoc @les-adhoc this forward port of #358 is awaiting action (not merged or closed). |
3 similar comments
|
@jcadhoc @les-adhoc this forward port of #358 is awaiting action (not merged or closed). |
|
@jcadhoc @les-adhoc this forward port of #358 is awaiting action (not merged or closed). |
|
@jcadhoc @les-adhoc this forward port of #358 is awaiting action (not merged or closed). |
c217076 to
0f652f3
Compare
|
@jcadhoc @les-adhoc this forward port of #358 is awaiting action (not merged or closed). |
…ndor receipt nor a counter-delivery When cancelling the remaining qty, lowering product_qty does not always cancel the pending receipt: with a refund return (ticket 124773) a live pending IN remains and inflates the forecast of units to receive, and when the negative move does not net against the pending one (different price/final location) a counter-delivery to the vendor is generated (ticket 124957). We now explicitly cancel the line's open remaining move. In 1, 2 or 3 step receptions the pending qty to receive always lives in the first-step move (vendor->input), which hangs off move_ids and has no downstream; core (_action_cancel) propagates to later moves if needed, so there is no need to walk the chain. The cancel is scoped to genuine forward vendor receipts: exchange-return replacements (a legitimate expected receipt) and open, not-yet-validated vendor returns (origin_returned_move_id, which also hang off move_ids and are not part of the remainder) are excluded. product_qty is not touched, so invoicing (qty_to_invoice) stays intact. Forward port note: in 19.0 purchase exchanges are not flagged with the sale_stock_ux is_exchange_move field (that wizard override does not exist here); they are detected from the return picking, as _should_count_for_quantity_received already did. We extract that criterion into _is_exchange_receipt() and use it for the guard, so the exclusion is real in this version instead of dead code. Tests (test_cancel_remaining.py, over 1/2/3 steps): partial receipt, refund return (124773), preservation of goods in transit, and an open vendor return that must survive cancel remaining (RED without the origin_returned_move_id guard). X-original-commit: 44a1146
0f652f3 to
4126a63
Compare
|
@roboadhoc r+ nobump |
…ndor receipt nor a counter-delivery When cancelling the remaining qty, lowering product_qty does not always cancel the pending receipt: with a refund return (ticket 124773) a live pending IN remains and inflates the forecast of units to receive, and when the negative move does not net against the pending one (different price/final location) a counter-delivery to the vendor is generated (ticket 124957). We now explicitly cancel the line's open remaining move. In 1, 2 or 3 step receptions the pending qty to receive always lives in the first-step move (vendor->input), which hangs off move_ids and has no downstream; core (_action_cancel) propagates to later moves if needed, so there is no need to walk the chain. The cancel is scoped to genuine forward vendor receipts: exchange-return replacements (a legitimate expected receipt) and open, not-yet-validated vendor returns (origin_returned_move_id, which also hang off move_ids and are not part of the remainder) are excluded. product_qty is not touched, so invoicing (qty_to_invoice) stays intact. Forward port note: in 19.0 purchase exchanges are not flagged with the sale_stock_ux is_exchange_move field (that wizard override does not exist here); they are detected from the return picking, as _should_count_for_quantity_received already did. We extract that criterion into _is_exchange_receipt() and use it for the guard, so the exclusion is real in this version instead of dead code. Tests (test_cancel_remaining.py, over 1/2/3 steps): partial receipt, refund return (124773), preservation of goods in transit, and an open vendor return that must survive cancel remaining (RED without the origin_returned_move_id guard). closes #365 X-original-commit: 44a1146 Signed-off-by: Luciano Esperlazza <les@adhoc.inc> Signed-off-by: ced-adhoc <ced@adhoc.com.ar>
…ndor receipt nor a counter-delivery When cancelling the remaining qty, lowering product_qty does not always cancel the pending receipt: with a refund return (ticket 124773) a live pending IN remains and inflates the forecast of units to receive, and when the negative move does not net against the pending one (different price/final location) a counter-delivery to the vendor is generated (ticket 124957). We now explicitly cancel the line's open remaining move. In 1, 2 or 3 step receptions the pending qty to receive always lives in the first-step move (vendor->input), which hangs off move_ids and has no downstream; core (_action_cancel) propagates to later moves if needed, so there is no need to walk the chain. The cancel is scoped to genuine forward vendor receipts: exchange-return replacements (a legitimate expected receipt) and open, not-yet-validated vendor returns (origin_returned_move_id, which also hang off move_ids and are not part of the remainder) are excluded. product_qty is not touched, so invoicing (qty_to_invoice) stays intact. Forward port note: in 19.0 purchase exchanges are not flagged with the sale_stock_ux is_exchange_move field (that wizard override does not exist here); they are detected from the return picking, as _should_count_for_quantity_received already did. We extract that criterion into _is_exchange_receipt() and use it for the guard, so the exclusion is real in this version instead of dead code. Tests (test_cancel_remaining.py, over 1/2/3 steps): partial receipt, refund return (124773), preservation of goods in transit, and an open vendor return that must survive cancel remaining (RED without the origin_returned_move_id guard). closes #365 X-original-commit: 44a1146 Signed-off-by: Luciano Esperlazza <les@adhoc.inc> Signed-off-by: ced-adhoc <ced@adhoc.com.ar>

Problem
When cancelling the remaining qty on a purchase order line (
button_cancel_remaining), loweringproduct_qtydoes not always cancel the pending receipt:Fix
After setting
product_qty, explicitly cancel the line's open remaining move, scoped to genuine forward vendor receipts:In 1/2/3-step receptions the pending qty always lives in the first-step move (vendor→input), which hangs off
move_idsand has no downstream; core_action_cancelpropagates to later moves if needed (and never todoneones), so there's no need to walk the chain.product_qtyis not touched, so invoicing (qty_to_invoice) stays intact.The two exclusions matter because returns and exchange replacements also carry
purchase_line_idand thus land inmove_ids; without the guards, an open (not-yet-validated) vendor return would be cancelled along with the remainder.Also replaced the expensive
fields_get()probe in_is_exchange_move_helperwith a plain'is_exchange_move' in self._fieldscheck (O(1), no full field-descriptor build).Tests
test_cancel_remaining.py, parametrized over one/two/three steps:origin_returned_move_idguard; reproduces the over-cancel reported on the client base)All green on a v18 test DB (
0 failed, 0 error of 4 tests).Forward-Port-Of: #358