mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-11 05:31:48 +00:00
fix: repost read stale sibling SLE rate for moving average returns
During repost, a return line with recalculate_rate resolved its moving average rate through get_incoming_rate -> get_previous_sle, which matches posting_datetime <= and orders by creation desc. For a multi-line return of the same item, every line shares one posting_datetime, so the query landed on a sibling line of the same voucher whose stored valuation_rate was still the previous repost run's output, not the rate before the voucher. Each repost run therefore re-seeded the voucher from its own prior output. The error gain per run is (qty returned at the stale rate) / (qty remaining after the return), so whenever a return removes most of the stock the loop diverges instead of converging, alternating sign and growing until stock_value overflows decimal(21,9) and the repost dies with 'Out of range value for column stock_value'. Use the in-memory running valuation rate that update_entries_after already tracks for the warehouse at this point in the repost. It is the authoritative pre-entry state, is immune to sibling rows, and makes the repost idempotent. The database lookup is kept only as a fallback for a zero in-memory rate, preserving the existing zero-rate fallback chain.
This commit is contained in:
@@ -1301,23 +1301,25 @@ class update_entries_after:
|
||||
and not sle.get("batch_no")
|
||||
and not sle.get("serial_and_batch_bundle")
|
||||
):
|
||||
rate = get_incoming_rate(
|
||||
{
|
||||
"item_code": sle.item_code,
|
||||
"warehouse": sle.warehouse,
|
||||
"posting_date": sle.posting_date,
|
||||
"posting_time": sle.posting_time,
|
||||
"qty": sle.actual_qty,
|
||||
"serial_no": sle.get("serial_no"),
|
||||
"batch_no": sle.get("batch_no"),
|
||||
"serial_and_batch_bundle": sle.get("serial_and_batch_bundle"),
|
||||
"company": sle.company,
|
||||
"voucher_type": sle.voucher_type,
|
||||
"voucher_no": sle.voucher_no,
|
||||
"allow_zero_valuation": self.allow_zero_rate,
|
||||
"sle": sle.name,
|
||||
}
|
||||
)
|
||||
rate = flt(self.wh_data.valuation_rate)
|
||||
if not rate:
|
||||
rate = get_incoming_rate(
|
||||
{
|
||||
"item_code": sle.item_code,
|
||||
"warehouse": sle.warehouse,
|
||||
"posting_date": sle.posting_date,
|
||||
"posting_time": sle.posting_time,
|
||||
"qty": sle.actual_qty,
|
||||
"serial_no": sle.get("serial_no"),
|
||||
"batch_no": sle.get("batch_no"),
|
||||
"serial_and_batch_bundle": sle.get("serial_and_batch_bundle"),
|
||||
"company": sle.company,
|
||||
"voucher_type": sle.voucher_type,
|
||||
"voucher_no": sle.voucher_no,
|
||||
"allow_zero_valuation": self.allow_zero_rate,
|
||||
"sle": sle.name,
|
||||
}
|
||||
)
|
||||
|
||||
if not rate and sle.voucher_type in ["Delivery Note", "Sales Invoice"]:
|
||||
rate = get_rate_for_return(
|
||||
|
||||
Reference in New Issue
Block a user