Skip to content
Snippets Groups Projects
Commit 05de60cb authored by Mart Raudsepp's avatar Mart Raudsepp Committed by Josse Colpaert
Browse files

[FIX] Correct floating number handling for _procure_orderpoint_confirm

Fixes comparison with min_quantity orderpoint in scheduler - basic floating
point math issue in procurement scheduler when comparing current quantity
with orderpoint minimum quantity. In certain cases floating point comparison
could result in e.g 400.0 < 400.0 == True due to typical floating point
comparison issues, as Odoo doesn't use Decimal types where the issue
doesn't exist.

Fixes early exiting out of the loop cycle, in case qty is already near zero.
Fixes the new procurement creation check, to not do that if it's close
enough to zero already, to be considered a floating point math error, not
really non-zero.

These combined (or at least the last one) avoid each supply_method == buy
pending in draft PO's getting a zero quantity extra procurement order each
time the scheduler runs. Otherwise there could be hundreds of zero quantity
procurement orders pending, which makes the confirming of the PO take hours,
due to creating hundreds of stock moves for each order line.

Use float_compare helper to solve all these with floating point type for now,
instead of the more evasion possibility of converting to Decimal module.
Two potential bad comparisons remain, add FIXME notes for now until further
analysis.

Also: Float rounding on reste when comparing and on the procurement qty
parent a300b6e3
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_compare, float_round
from openerp import SUPERUSER_ID
from dateutil.relativedelta import relativedelta
from datetime import datetime
......@@ -352,21 +352,21 @@ class procurement_order(osv.osv):
prods = self._product_virtual_get(cr, uid, op)
if prods is None:
continue
if prods < op.product_min_qty:
if float_compare(prods, op.product_min_qty, precision_rounding=op.product_uom.rounding) < 0:
qty = max(op.product_min_qty, op.product_max_qty) - prods
reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0
if reste > 0:
if float_compare(reste, 0.0, precision_rounding=op.product_uom.rounding) > 0:
qty += op.qty_multiple - reste
if qty <= 0:
if float_compare(qty, 0.0, precision_rounding=op.product_uom.rounding) <= 0:
continue
qty -= orderpoint_obj.subtract_procurements(cr, uid, op, context=context)
if qty > 0:
qty_rounded = float_round(qty, precision_rounding=op.product_uom.rounding)
if qty_rounded > 0:
proc_id = procurement_obj.create(cr, uid,
self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context),
self._prepare_orderpoint_procurement(cr, uid, op, qty_rounded, context=context),
context=context)
self.check(cr, uid, [proc_id])
self.run(cr, uid, [proc_id])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment