[FIX] stock, sale_stock: changed the way the procurements look for a suitable rule => Added a m2o field warehouse_id on procurement.order, procurement.rule and stock.move. There was a problem with MTO products because they weren't following the route of the chosen warehouse at all (since all warehouse were creating their rule in the same route, there was no garantee that the route chosen was included in the warehouse selected on the SO)

bzr revid: qdp-launchpad@openerp.com-20131022120605-3dj65nm5yc96sj5r
This commit is contained in:
Quentin (OpenERP) 2013-10-22 14:06:05 +02:00
parent 52cfccf2ce
commit 441d0bc009
4 changed files with 32 additions and 21 deletions

View File

@ -85,15 +85,14 @@ class sale_order(osv.osv):
res[sale.id] = list(picking_ids)
return res
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id = False, context=None):
def _prepare_order_line_procurement(self, cr, uid, order, line, group_id=False, context=None):
vals = super(sale_order, self)._prepare_order_line_procurement(cr, uid, order, line, group_id=group_id, context=context)
location_id = order.partner_shipping_id.property_stock_customer.id
vals['location_id'] = location_id
routes = []
routes += order.warehouse_id and [(4, x.id) for x in order.warehouse_id.route_ids] or [] #route_ids
routes += line.route_id and [(4, line.route_id.id)] or [] #route_id
vals['route_ids'] = routes
routes = line.route_id and [(4, line.route_id.id)] or []
vals['route_ids'] = routes
vals['warehouse_id'] = order.warehouse_id and order.warehouse_id.id or False
return vals
_columns = {

View File

@ -82,6 +82,7 @@ class procurement_rule(osv.osv):
'delay': fields.integer('Number of Days'),
'partner_address_id': fields.many2one('res.partner', 'Partner Address'),
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when the previous move of the move (which was generated by a next procurement) is cancelled or split, the move generated by this move will too'),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
}
_defaults = {
@ -99,7 +100,7 @@ class procurement_order(osv.osv):
'move_ids': fields.one2many('stock.move', 'procurement_id', 'Moves', help="Moves created by the procurement"),
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Move which caused (created) the procurement"),
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_procurement', 'procurement_id', 'route_id', 'Followed Route', help="Preferred route to be followed by the procurement order"),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', help="Warehouse to consider for the route selection"),
}
def propagate_cancel(self, cr, uid, procurement, context=None):
@ -125,10 +126,18 @@ class procurement_order(osv.osv):
res.append(location.id)
return res
def change_warehouse_id(self, cr, uid, ids, warehouse_id, context=None):
if warehouse_id:
warehouse = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context=context)
return {'value': {'location_id': warehouse.lot_stock_id.id}}
return {}
def _search_suitable_rule(self, cr, uid, procurement, domain, context=None):
'''we try to first find a rule among the ones defined on the procurement order group and if none is found, we try on the routes defined for the product, and finally we fallback on the default behavior'''
if procurement.warehouse_id:
domain += [('warehouse_id', '=', procurement.warehouse_id.id)]
product_route_ids = [x.id for x in procurement.product_id.route_ids + procurement.product_id.categ_id.total_route_ids]
procurement_route_ids = [x.id for x in procurement.route_ids]
procurement_route_ids = [x.id for x in procurement.route_ids] + [x.id for x in procurement.warehouse_id.route_ids]
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', product_route_ids)], order = 'route_sequence, sequence', context=context)
if not res:
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', procurement_route_ids)], order = 'route_sequence, sequence', context=context)
@ -171,6 +180,7 @@ class procurement_order(osv.osv):
'picking_type_id': procurement.rule_id.picking_type_id.id,
'group_id': procurement.group_id and procurement.group_id.id or False,
'route_ids': [(4, x.id) for x in procurement.route_ids],
'warehouse_id': procurement.rule_id.warehouse_id.id,
}
if procurement.rule_id:
newdate = (datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.rule_id.delay or 0)).strftime('%Y-%m-%d %H:%M:%S')

View File

@ -1356,6 +1356,7 @@ class stock_move(osv.osv):
'restrict_partner_id': fields.many2one('res.partner', 'Owner ', help="Technical field used to depict a restriction on the ownership of quants to consider when marking this move as 'done'"),
'putaway_ids': fields.one2many('stock.move.putaway', 'move_id', 'Put Away Suggestions'),
'route_ids': fields.many2many('stock.location.route', 'stock_location_route_move', 'move_id', 'route_id', 'Destination route', help="Preferred route to be followed by the procurement order"),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', help="Technical field depicting the warehouse to consider for the route selection on the next procurement (if any)."),
}
def copy(self, cr, uid, id, default=None, context=None):
@ -1420,6 +1421,7 @@ class stock_move(osv.osv):
'move_dest_id': move.id,
'group_id': move.group_id and move.group_id.id or False,
'route_ids' : [(4, x.id) for x in move.route_ids],
'warehouse_id': move.warehouse_id and move.warehouse_id.id or False,
}
def _push_apply(self, cr, uid, moves, context):
@ -1429,7 +1431,10 @@ class stock_move(osv.osv):
routes = [x.id for x in move.product_id.route_ids + move.product_id.categ_id.total_route_ids]
routes = routes or [x.id for x in move.route_ids]
if routes:
rules = push_obj.search(cr, uid, [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)], context=context)
domain = [('route_id', 'in', routes), ('location_from_id', '=', move.location_dest_id.id)]
if move.warehouse_id:
domain += [('warehouse_id', '=', move.warehouse_id.id)]
rules = push_obj.search(cr, uid, domain, context=context)
if rules:
rule = push_obj.browse(cr, uid, rules[0], context=context)
push_obj._apply(cr, uid, rule, move, context=context)
@ -2225,6 +2230,7 @@ class stock_warehouse(osv.osv):
'name': fields.char('Name', size=128, required=True, select=True),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
'partner_id': fields.many2one('res.partner', 'Address'),
'view_location_id': fields.many2one('stock.location', 'View Location', required=True, domain=[('usage', '=', 'view')]),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]),
'code': fields.char('Short Name', size=5, required=True, help="Short name used to identify your warehouse"),
'route_ids': fields.many2many('stock.location.route', 'stock_route_warehouse', 'warehouse_id', 'route_id', 'Routes', domain="[('warehouse_selectable', '=', True)]", help='Defaults routes through the warehouse'),
@ -2382,6 +2388,7 @@ class stock_warehouse(osv.osv):
'auto': 'manual',
'picking_type_id': pick_type_id,
'active': active,
'warehouse_id': warehouse.id,
})
pull_rules_list.append({
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
@ -2392,6 +2399,7 @@ class stock_warehouse(osv.osv):
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'active': active,
'warehouse_id': warehouse.id,
})
first_rule = False
return push_rules_list, pull_rules_list
@ -2416,6 +2424,7 @@ class stock_warehouse(osv.osv):
'picking_type_id': pick_type_id,
'procure_method': 'make_to_order',
'active': True,
'warehouse_id': warehouse.id,
}
def _get_crossdock_route(self, cr, uid, warehouse, route_name, context=None):
@ -2546,6 +2555,7 @@ class stock_warehouse(osv.osv):
'usage': 'view',
'location_id': data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_locations')[1]
}, context=context)
vals['view_location_id'] = wh_loc_id
#create all location
reception_steps = vals.get('reception_steps', False)
delivery_steps = vals.get('delivery_steps', False)
@ -2834,6 +2844,7 @@ class stock_location_path(osv.osv):
'stock.location.route': (_get_route, ['active'], 20),
'stock.location.path': (lambda self, cr, uid, ids, c={}: ids, ['route_id'], 20),},
help="If the active field is set to False, it will allow you to hide the rule without removing it." ),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
}
_defaults = {
'auto': 'auto',
@ -2865,6 +2876,7 @@ class stock_location_path(osv.osv):
'picking_type_id': rule.picking_type_id and rule.picking_type_id.id or False,
'rule_id': rule.id,
'propagate': rule.propagate,
'warehouse_id': rule.warehouse_id and rule.warehouse_id.id or False,
})
move_obj.write(cr, uid, [move.id], {
'move_dest_id': move_id,

View File

@ -1667,7 +1667,8 @@
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='origin']" position="after">
<field name="location_id"/>
<field name="warehouse_id" on_change="change_warehouse_id(warehouse_id, context)"/>
<field name="location_id" domain="[('usage', '=', 'internal')]"/>
</xpath>
<xpath expr="//field[@name='rule_id']" position="after">
<field name="route_ids" widget="many2many_tags"/>
@ -2128,17 +2129,6 @@
<menuitem action="action_routes_form" id="menu_stock_routes"
parent="stock.menu_stock_configuration" sequence="11" />
<record id="procurement_form_view_inherit" model="ir.ui.view">
<field name="name">procurement.order.form.view.inherit</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="model">procurement.order</field>
<field name="arch" type="xml">
<xpath expr="//field[@name='rule_id']" position="after">
<field name="route_ids" widget="many2many_tags" />
</xpath>
</field>
</record>
<record id="view_product_procurement_rule_form" model="ir.ui.view">
<field name="name">product.template.procurement.rule.inherit</field>