[FIX] fix orderpoint compute with purchase multiple

This commit is contained in:
Cédric Pigeon
2017-10-02 22:34:17 +02:00
committed by Thomas Binsfeld
parent 5d2c71c85f
commit 98e451917b
2 changed files with 150 additions and 0 deletions

View File

@@ -2,6 +2,7 @@
# Copyright 2015-2017 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools import float_compare
class ProcurementOrder(models.Model):
@@ -28,3 +29,38 @@ class ProcurementOrder(models.Model):
self.product_qty, new_uom_id)
res['product_qty'] = max(qty, seller.min_qty)
return res
class Orderpoint(models.Model):
_inherit = 'stock.warehouse.orderpoint'
@api.multi
def subtract_procurements_from_orderpoints(self):
# In this method we need to access the purchase order line quantity
# to correctly evaluate the forecast.
# Imagine a product with a minimum rule of 4 units and a purchase
# multiple of 12. The first run will generate a procurement for 4 Pc
# but a purchase for 12 units.
# Let's change the minimum rule to 5 units.
# The standard subtract_procurements_from_orderpoints will return 4
# and Odoo will create a procurement for 1 unit which will trigger a
# purchase of 12 due to the multiple. So the original purchase will
# be increased to 24 units which is wrong.
# This override will return 12 and no additionnal procurement will be
# created
res = super(Orderpoint, self).subtract_procurements_from_orderpoints()
for orderpoint in self:
procs = self.env['procurement.order'].search(
[('orderpoint_id', '=', orderpoint.id),
('state', 'not in', ['cancel', 'done'])])
if procs:
po_lines = procs.mapped('purchase_line_id').filtered(
lambda x: x.state == 'draft')
if po_lines:
qty = sum([line.product_qty for line in po_lines])
precision = orderpoint.product_uom.rounding
if float_compare(
qty, res[orderpoint.id],
precision_rounding=precision) >= 0:
res[orderpoint.id] = qty
return res

View File

@@ -259,3 +259,117 @@ class TestProcurementOrder(common.TransactionCase):
proc1.purchase_line_id.product_uom)
self.assertEqual(36, proc1.purchase_line_id.price_unit)
proc1.purchase_id.button_confirm()
def test_procurement_from_orderpoint_draft_po(self):
# Define a multiple of 12 on supplier info
# Trigger a stock minimum rule of 10 PC
# A purchase line with 12 PC should be generated
# Change the stock minimum to 11 PC
# The purchase quantity should remains 12
# Change the stock minimum to 13 PC
# The purchase quantity should increase up to 24
warehouse = self.env.ref('stock.warehouse0')
product = self.env.ref('product.product_product_3')
product.route_ids = [(
4, self.env.ref("purchase.route_warehouse0_buy").id)]
self.env.ref('product.product_uom_dozen').rounding = 1
procurement_obj = self.env['procurement.order']
self.sp_30.min_qty = 1
self.sp_30.min_qty_uom_id = self.env.ref('product.product_uom_dozen')
orderpoint = self.env['stock.warehouse.orderpoint'].create({
'warehouse_id': warehouse.id,
'location_id': warehouse.lot_stock_id.id,
'product_id': product.id,
'product_min_qty': 10,
'product_max_qty': 10,
})
procurement_obj.run_scheduler()
proc = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertEqual(len(proc), 1)
self.assertTrue(proc.purchase_line_id)
self.assertEqual(proc.purchase_line_id.product_qty, 12)
# change order_point level and rerun
orderpoint.product_min_qty = 11
orderpoint.product_max_qty = 11
procurement_obj.run_scheduler()
procs = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertTrue(procs)
self.assertEqual(len(procs), 1)
# change order_point level and rerun
orderpoint.product_min_qty = 13
orderpoint.product_max_qty = 13
procurement_obj.run_scheduler()
procs = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertTrue(procs)
self.assertEqual(len(procs), 2)
for proc in procs:
self.assertTrue(proc.purchase_line_id)
self.assertEqual(proc.purchase_line_id.product_qty, 24)
def test_procurement_from_orderpoint_confirmed_po(self):
# Define a multiple of 12 on supplier info
# Trigger a stock minimum rule of 10 PC
# A purchase line with 12 PC should be generated
# Confirm the purchase order
# Change the stock minimum to 11 PC
# No new purchase should be generated
# Change the stock minimum to 13 PC
# A new purchase should be generated
warehouse = self.env.ref('stock.warehouse0')
product = self.env.ref('product.product_product_3')
product.route_ids = [(
4, self.env.ref("purchase.route_warehouse0_buy").id)]
self.env.ref('product.product_uom_dozen').rounding = 1
procurement_obj = self.env['procurement.order']
self.sp_30.min_qty = 1
self.sp_30.min_qty_uom_id = self.env.ref('product.product_uom_dozen')
orderpoint = self.env['stock.warehouse.orderpoint'].create({
'warehouse_id': warehouse.id,
'location_id': warehouse.lot_stock_id.id,
'product_id': product.id,
'product_min_qty': 10,
'product_max_qty': 10,
})
procurement_obj.run_scheduler()
proc = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertEqual(len(proc), 1)
self.assertTrue(proc.purchase_line_id)
self.assertEqual(proc.purchase_line_id.product_qty, 12)
proc.purchase_line_id.order_id.button_confirm()
# change order_point level and rerun
orderpoint.product_min_qty = 11
orderpoint.product_max_qty = 11
procurement_obj.run_scheduler()
proc = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertTrue(proc)
self.assertEqual(len(proc), 1)
self.assertEqual(proc.purchase_line_id.product_qty, 12)
# change order_point level and rerun
orderpoint.product_min_qty = 13
orderpoint.product_max_qty = 13
procurement_obj.run_scheduler()
procs = procurement_obj.search([('orderpoint_id', '=', orderpoint.id)])
self.assertTrue(procs)
self.assertEqual(len(procs), 2)
for proc in procs:
self.assertTrue(proc.purchase_line_id)
self.assertEqual(proc.purchase_line_id.product_qty, 12)