[FIX] stock: let resupply from warehouse work

If you set WH B to be resupplied from WH A, then the scheduler will
generate a procurement with warehouse_id = B and location_id = B.stock.
Running the procurement will find the resupply rule, and this will
create another procurement with warehouse_id = A and location_id =
transit location.

However, without this patch, the resupply route is not part of the
route_ids of warehouse A, and so the 2nd procurement goes in exception
because if cannot find a rule (the search will force a rule linked to a
route which is part of A.route_ids).

Closes #7956
This commit is contained in:
Alexandre Fayolle 2015-08-07 16:01:36 +02:00 committed by Nicolas Martinelli
parent 3cc7f9fc86
commit 74b7b97209
3 changed files with 54 additions and 2 deletions

View File

@ -3039,7 +3039,7 @@ class stock_warehouse(osv.osv):
'crossdock_route_id': fields.many2one('stock.location.route', 'Crossdock Route'),
'reception_route_id': fields.many2one('stock.location.route', 'Receipt Route'),
'delivery_route_id': fields.many2one('stock.location.route', 'Delivery Route'),
'resupply_from_wh': fields.boolean('Resupply From Other Warehouses'),
'resupply_from_wh': fields.boolean('Resupply From Other Warehouses', help='Unused field'),
'resupply_wh_ids': fields.many2many('stock.warehouse', 'stock_wh_resupply_table', 'supplied_wh_id', 'supplier_wh_id', 'Resupply Warehouses'),
'resupply_route_ids': fields.one2many('stock.location.route', 'supplied_wh_id', 'Resupply Routes',
help="Routes will be created for these resupply warehouses and you can select them on products and product categories"),
@ -3099,7 +3099,7 @@ class stock_warehouse(osv.osv):
pull_obj.create(cr, uid, vals=pull_rule, context=context)
#if the warehouse is also set as default resupply method, assign this route automatically to the warehouse
if default_resupply_wh and default_resupply_wh.id == wh.id:
self.write(cr, uid, [warehouse.id], {'route_ids': [(4, inter_wh_route_id)]}, context=context)
self.write(cr, uid, [warehouse.id, wh.id], {'route_ids': [(4, inter_wh_route_id)]}, context=context)
_defaults = {
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c),

View File

@ -2,3 +2,4 @@
from . import test_stock_flow
from . import test_owner_available
from . import test_resupply

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
from openerp.addons.stock.tests.common import TestStockCommon
from openerp.tools import mute_logger, float_round
class TestResupply(TestStockCommon):
def setUp(self):
super(TestResupply, self).setUp()
self.Warehouse = self.env['stock.warehouse']
# create 2 WH, BIG and SMALL
# SMALL resupplies from BIG
self.bigwh = self.Warehouse.create({'name': 'BIG', 'code': 'B'})
self.smallwh = self.Warehouse.create({'name': 'SMALL', 'code': 'S',
'default_resupply_wh_id': self.bigwh.id,
'resupply_wh_ids': [(6, 0, [self.bigwh.id])],
})
# minimum stock rule for Product A on SMALL
Orderpoint = self.env['stock.warehouse.orderpoint']
Orderpoint.create({'warehouse_id': self.smallwh.id,
'location_id': self.smallwh.lot_stock_id.id,
'product_id': self.productA.id,
'product_min_qty': 100,
'product_max_qty': 200,
'product_uom': self.uom_unit.id,
})
# create some stock on BIG
Wiz = self.env['stock.change.product.qty']
wiz = Wiz.create({'product_id': self.productA.id,
'new_quantity': 1000,
'location_id': self.bigwh.lot_stock_id.id,
})
wiz.change_product_qty()
def test_resupply_from_wh(self):
sched = self.env['procurement.order']
sched.run_scheduler()
# we generated 2 procurements for product A: one on small wh and the
# other one on the transit location
procs = sched.search([('product_id', '=', self.productA.id)])
self.assertEqual(len(procs), 2)
proc1 = sched.search([('product_id', '=', self.productA.id),
('warehouse_id', '=', self.smallwh.id)])
self.assertEqual(proc1.state, 'running')
proc2 = sched.search([('product_id', '=', self.productA.id),
('warehouse_id', '=', self.bigwh.id)])
self.assertEqual(proc2.location_id.usage, 'transit')
self.assertNotEqual(proc2.state, 'exception')
proc2.run()
self.assertEqual(proc2.state, 'running')
self.assertTrue(proc2.rule_id)