[MERGE] from upstream

bzr revid: fva@openerp.com-20131003095917-dv6a4ek197wggy4a
This commit is contained in:
Frédéric van der Essen
2013-10-03 11:59:17 +02:00
11 changed files with 397 additions and 598 deletions
-8
View File
@@ -40,14 +40,6 @@ class procurement_order(osv.osv):
'production_id': fields.many2one('mrp.production', 'Manufacturing Order'),
}
def _find_suitable_rule(self, cr, uid, procurement, context=None):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
#if there isn't any specific procurement.rule defined for the product, we try to directly supply it from a supplier
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'manufacture'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
return rule_id
def _run(self, cr, uid, procurement, context=None):
if procurement.rule_id and procurement.rule_id.action == 'manufacture':
#make a manufacturing order for the procurement
+8 -8
View File
@@ -1126,16 +1126,16 @@ class procurement_order(osv.osv):
'purchase_line_id': fields.many2one('purchase.order.line', 'Purchase Order'),
}
def _find_suitable_rule(self, cr, uid, procurement, context=None):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
#if there isn't any specific procurement.rule defined for the product, we try to directly supply it from a supplier
rule_id = self._search_suitable_rule(cr, uid, procurement, [('action', '=', 'buy'), ('location_id', '=', procurement.location_id.id)], context=context)
rule_id = rule_id and rule_id[0] or False
return rule_id
def _run(self, cr, uid, procurement, context=None):
print "dans le run de purchase"
print procurement
print procurement.rule_id
if procurement.rule_id:
print procurement.rule_id.action
#a = procurement.rule_id and procurement.rule_id.name or 'pas de rule'
#print a
if procurement.rule_id and procurement.rule_id.action == 'buy':
print "go pour make_po"
#make a purchase order for the procurement
return self.make_po(cr, uid, [procurement.id], context=context)[procurement.id]
return super(procurement_order, self)._run(cr, uid, procurement, context=context)
@@ -40,6 +40,7 @@ class sale_order(osv.osv):
routes += route_ids
route_id = line.route_id and [(4, line.route_id.id)] or []
routes += route_id
print 'toutes les routes sur le procurement', routes
res.update({
'route_ids': routes
})
+3
View File
@@ -47,6 +47,9 @@ class procurement_rule(osv.osv):
return res
def _get_route(self, cr, uid, ids, context=None):
#WARNING TODO route_id is not required, so a field related seems a bad idea >-<
if context is None:
context = {}
result = {}
if context is None:
context = {}
+5 -3
View File
@@ -147,7 +147,7 @@ class stock_location_route(osv.osv):
}
_defaults = {
'sequence': lambda self,cr,uid,ctx: 0,
'sequence': lambda self, cr, uid, ctx: 0,
'active': True,
}
@@ -1006,8 +1006,8 @@ class stock_picking(osv.osv):
# Methods for the barcode UI
def get_picking_for_packing_ui(self, cr, uid, context={}):
return self.search(cr, uid, [('state', 'in', ('confirmed', 'assigned')),('picking_type_id','=', context.get('default_picking_type_id'))], context=context)
def get_picking_for_packing_ui(self, cr, uid, context=None):
return self.search(cr, uid, [('state', 'in', ('confirmed', 'assigned')), ('picking_type_id', '=', context.get('default_picking_type_id'))], context=context)
def action_done_from_packing_ui(self, cr, uid, picking_id, only_split_lines=False, context=None):
self.do_partial(cr, uid, picking_id, only_split_lines, context=context)
@@ -2653,6 +2653,7 @@ class stock_picking_type(osv.osv):
'code_id': fields.selection([('incoming', 'Suppliers'), ('outgoing', 'Customers'), ('internal', 'Internal')], 'Picking type code', required=True),
'return_picking_type_id': fields.many2one('stock.picking.type', 'Picking Type for Returns'),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
'active': fields.boolean('Active'),
# Statistics for the kanban view
'weekly_picking': fields.function(_get_picking_data,
@@ -2687,5 +2688,6 @@ class stock_picking_type(osv.osv):
}
_defaults = {
'warehouse_id': _default_warehouse,
'active': True,
}
+7 -7
View File
@@ -80,22 +80,22 @@
<!-- Sequences for picking types -->
<record id="seq_picking_type_in" model="ir.sequence">
<field name="name">Picking in</field>
<field name="prefix">IN</field>
<field name="name">WH Picking in</field>
<field name="prefix">WH\IN</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
<record id="seq_picking_type_out" model="ir.sequence">
<field name="name">Picking out</field>
<field name="prefix">OUT</field>
<field name="name">WH Picking out</field>
<field name="prefix">WH\OUT</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
<record id="seq_picking_type_internal" model="ir.sequence">
<field name="name">Picking internal</field>
<field name="prefix">INT</field>
<field name="name">WH Picking internal</field>
<field name="prefix">WH\INT</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
@@ -228,7 +228,7 @@ watch your stock valuation, and track production lots upstream and downstream (b
<record id="warehouse0" model="stock.warehouse">
<field model="res.company" name="name" search="[]" use="name"/>
<field name="lot_stock_id" ref="stock_location_stock"/>
<field name="code">Main</field>
<field name="code">WH</field>
</record>
<record id="sequence_mrp_op_type" model="ir.sequence.type">
@@ -42,6 +42,11 @@
!python {model: procurement.group}: |
sale_record = self.pool.get("sale.order").browse(cr, uid, ref('sale_order_drp_shpng'))
assert self.browse(cr, uid, sale_record.procurement_group_id.id).procurement_ids[0].product_qty == 200
-
I run scheduler.
-
!python {model: procurement.order}: |
self.run_scheduler(cr, uid)
-
Check a quotation was created to a certain supplier and confirm so it becomes a confirmed purchase order
-
@@ -50,6 +55,13 @@
sale_record = self.pool.get("sale.order").browse(cr, uid, ref('sale_order_drp_shpng'))
procurement_order = self.pool.get("procurement.group").browse(cr, uid, sale_record.procurement_group_id.id).procurement_ids[0]
print 'procurement_order', procurement_order.state
print 'test', procurement_order.purchase_line_id.order_id
print 'test rule', procurement_order.rule_id.action
print 'test route sequence', [(r.name, r.sequence) for r in procurement_order.route_ids]
rule_seq = []
for route in procurement_order.route_ids:
rule_seq += [(ru.name, ru.route_sequence, ru.sequence) for ru in route.pull_ids]
print '####RULES SEQ####', rule_seq
purchase_id = procurement_order.purchase_line_id.order_id.id
wf_service = netsvc.LocalService('workflow')
+294 -336
View File
@@ -50,228 +50,225 @@ class stock_warehouse(osv.osv):
('ship_only', 'Ship directly from stock (Ship only)'),
('pick_ship', 'Bring goods to output location before shipping (Pick + Ship)'),
('pick_pack_ship', 'Make packages into a dedicated location, then bring them to the output location for shipping (Pick + Pack + Ship)')], 'Outgoing Shippings', required=True),
'wh_input_stock_loc_id': fields.many2one('stock.location', 'Input Location'),
'wh_qc_stock_loc_id': fields.many2one('stock.location', 'Quality Control Location'),
'wh_output_stock_loc_id': fields.many2one('stock.location', 'Output Location'),
'wh_pack_stock_loc_id': fields.many2one('stock.location', 'Packing Location'),
'ship_route_mto': fields.many2one('stock.location.route', 'ship MTO route'),
'pick_ship_route_mto': fields.many2one('stock.location.route', 'pick-ship MTO route'),
'pick_pack_ship_route_mto': fields.many2one('stock.location.route', 'pick-pack-ship MTO route'),
'mto_pull_id': fields.many2one('procurement.rule', 'MTO rule'),
'pick_type_id': fields.many2one('stock.picking.type', 'Pick Type'),
'pack_type_id': fields.many2one('stock.picking.type', 'Pack Type'),
'out_type_id': fields.many2one('stock.picking.type', 'Out Type'),
'in_type_id': fields.many2one('stock.picking.type', 'In Type'),
'int_type_id': fields.many2one('stock.picking.type', 'Internal Type'),
'crossdock_route_id': fields.many2one('stock.location.route', 'Crossdock Route'),
'reception_route_id': fields.many2one('stock.location.route', 'Reception Route'),
'delivery_route_id': fields.many2one('stock.location.route', 'Delivery Route'),
}
_defaults = {
'reception_steps': 'one_step',
'delivery_steps': 'ship_only',
}
def _get_partner_locations(self, cr, uid, ids, context=None):
''' returns a tuple made of the browse record of customer location and the browse record of supplier location'''
data_obj = self.pool.get('ir.model.data')
location_obj = self.pool.get('stock.location')
try:
customer_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_customers')[1]
supplier_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_suppliers')[1]
except:
customer_loc = location_obj.search(cr, uid, [('usage', '=', 'customer')], context=context)
customer_loc = customer_loc and customer_loc[0] or False
supplier_loc = location_obj.search(cr, uid, [('usage', '=', 'supplier')], context=context)
supplier_loc = supplier_loc and supplier_loc[0] or False
if not (customer_loc and supplier_loc):
raise osv.except_osv(_('Error!'), _('Can\'t find any customer or supplier location.'))
return location_obj.browse(cr, uid, [customer_loc, supplier_loc], context=context)
def switch_location(self, cr, uid, ids, warehouse, new_reception_step=False, new_delivery_step=False, context=None):
location_obj = self.pool.get('stock.location')
wh_view_location_id = warehouse.lot_stock_id.location_id.id
wh_stock_loc = warehouse.lot_stock_id
wh_input_stock_loc = wh_output_stock_loc = wh_pack_stock_loc = wh_qc_stock_loc = wh_stock_loc
new_reception_step = new_reception_step or warehouse.reception_steps
new_delivery_step = new_delivery_step or warehouse.delivery_steps
if warehouse.reception_steps != new_reception_step:
location_obj.write(cr, uid, [warehouse.wh_input_stock_loc_id.id, warehouse.wh_qc_stock_loc_id.id], {'active': False}, context=context)
if new_reception_step != 'one_step':
location_obj.write(cr, uid, warehouse.wh_input_stock_loc_id.id, {'active': True}, context=context)
location_obj.write(cr, uid, warehouse.wh_input_stock_loc_id.id, {'active': True}, context=context)
if new_reception_step == 'three_steps':
location_obj.write(cr, uid, warehouse.wh_qc_stock_loc_id.id, {'active': True}, context=context)
if warehouse.delivery_steps != new_delivery_step:
location_obj.write(cr, uid, [warehouse.wh_output_stock_loc_id.id, warehouse.wh_pack_stock_loc_id.id], {'active': False}, context=context)
if new_delivery_step != 'ship_only':
location_obj.write(cr, uid, warehouse.wh_output_stock_loc_id.id, {'active': True}, context=context)
location_obj.write(cr, uid, warehouse.wh_output_stock_loc_id.id, {'active': True}, context=context)
if new_delivery_step == 'pick_pack_ship':
location_obj.write(cr, uid, warehouse.wh_pack_stock_loc_id.id, {'active': True}, context=context)
location_obj.write(cr, uid, warehouse.wh_pack_stock_loc_id.id, {'active': True}, context=context)
return True
def create_route(self, cr, uid, ids, warehouse, context=None):
default_route_ids = []
data_obj = self.pool.get('ir.model.data')
route_obj = self.pool.get('stock.location.route')
pull_obj = self.pool.get('procurement.rule')
push_obj = self.pool.get('stock.location.path')
keys = ('two_steps', 'three_steps')
routes_dict = self.get_routes_dict(cr, uid, ids, warehouse, warehouse.reception_steps, warehouse.delivery_steps, write=False, context=context)
for reception in keys:
active = False
route_name, values = routes_dict[reception]
if reception == warehouse.reception_steps:
active = True
new_route_id = route_obj.create(cr, uid, vals={
'name': self._format_routename(cr, uid, warehouse, route_name, context=context),
'product_categ_selectable': True,
'product_selectable': False,
'active': active
}, context=context)
default_route_ids.append((4, new_route_id))
first_rule = True
for from_loc, dest_loc, pick_type_id in values:
push_data = {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_from_id': from_loc.id,
'location_dest_id': dest_loc.id,
'route_id': new_route_id,
'auto': 'manual',
'picking_type_id': pick_type_id,
'active': active,
}
push_obj.create(cr, uid, vals=push_data, context=context)
pull_obj.create(cr, uid, {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': new_route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'active': active,
}, context=context)
first_rule = False
def _get_reception_delivery_route(self, cr, uid, warehouse, route_name, context=None):
return {
'name': self._format_routename(cr, uid, warehouse, route_name, context=context),
'product_categ_selectable': True,
'product_selectable': False,
}
keys = {'ship_only': 'ship_route_mto', 'pick_ship': 'pick_ship_route_mto', 'pick_pack_ship': 'pick_pack_ship_route_mto'}
for delivery, field in keys.items():
active = False
#create pull rules for delivery, which include all routes in MTS on the warehouse and a specific route MTO to be set on the product
route_name, values = routes_dict[delivery]
if delivery == warehouse.delivery_steps:
active = True
route_id = route_obj.create(cr, uid, vals={
'name': self._format_routename(cr, uid, warehouse, route_name, context=context),
'warehouse_selectable': True,
'product_selectable': False,
'active': active,
}, context=context)
default_route_ids.append((4, route_id))
mto_route_id = route_obj.create(cr, uid, vals={
'name': self._format_routename(cr, uid, warehouse, route_name, context=context) + _(' (MTO)'),
'warehouse_selectable': False,
'product_selectable': True,
def _get_push_pull_rules(self, cr, uid, warehouse, active, values, new_route_id, context=None):
first_rule = True
push_rules_list = []
pull_rules_list = []
for from_loc, dest_loc, pick_type_id in values:
push_rules_list.append({
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_from_id': from_loc.id,
'location_dest_id': dest_loc.id,
'route_id': new_route_id,
'auto': 'manual',
'picking_type_id': pick_type_id,
'active': active,
})
self.write(cr, uid, warehouse.id, {field: mto_route_id}, context=context)
first_rule = True
for from_loc, dest_loc, pick_type_id in values:
pull_obj.create(cr, uid, {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'active': active,
}, context=context)
if first_rule:
pull_obj.create(cr, uid, {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': mto_route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': 'make_to_order',
'sequence': 10,
'active': active,
}, context=context)
first_rule = False
pull_rules_list.append({
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': new_route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'active': active,
})
first_rule = False
return push_rules_list, pull_rules_list
#create a route for cross dock operations, that can be set on products and product categories
route_name, values = routes_dict['crossdock']
crossdock_route_id = route_obj.create(cr, uid, vals={
def _get_mto_pull_rule(self, cr, uid, warehouse, values, context=None):
data_obj = self.pool.get('ir.model.data')
try:
mto_route_id = data_obj.get_object_reference(cr, uid, 'stock', 'route_warehouse0_mto')[1]
except:
mto_route_id = route_obj.search(cr, uid, [('name', 'like', _('MTO'))], context=context)
mto_route_id = mto_route_id and mto_route_id[0] or False
if not mto_route_id:
raise osv.except_osv(_('Error!'), _('Can\'t find any generic MTO route.'))
from_loc, dest_loc, pick_type_id = values[0]
return {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context) + _(' MTO'),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': mto_route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': 'make_to_order',
'active': True,
}
def _get_crossdock_route(self, cr, uid, warehouse, route_name, context=None):
return {
'name': self._format_routename(cr, uid, warehouse, route_name, context=context),
'warehouse_selectable': False,
'product_selectable': True,
'product_categ_selectable': True,
})
default_route_ids.append((4, crossdock_route_id))
first_rule = True
for from_loc, dest_loc, pick_type_id in values:
pull_obj.create(cr, uid, {
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': crossdock_route_id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'sequence': 10,
}, context=context)
first_rule = False
'active': warehouse.delivery_steps != 'ship_only' and warehouse.reception_steps != 'one_step',
}
#set defaut delivery route on warehouse according to option choosen
self.write(cr, uid, warehouse.id, {'route_ids': default_route_ids}, context=context)
def create_routes(self, cr, uid, ids, warehouse, context=None):
wh_route_ids = []
route_obj = self.pool.get('stock.location.route')
pull_obj = self.pool.get('procurement.rule')
push_obj = self.pool.get('stock.location.path')
routes_dict = self.get_routes_dict(cr, uid, ids, warehouse, context=context)
#create reception route and rules
route_name, values = routes_dict[warehouse.reception_steps]
route_vals = self._get_reception_delivery_route(cr, uid, warehouse, route_name, context=context)
reception_route_id = route_obj.create(cr, uid, route_vals, context=context)
wh_route_ids.append((4, reception_route_id))
push_rules_list, pull_rules_list = self._get_push_pull_rules(cr, uid, warehouse, True, values, reception_route_id, context=context)
#create the push/pull rules
for push_rule in push_rules_list:
push_obj.create(cr, uid, vals=push_rule, context=context)
for pull_rule in pull_rules_list:
pull_obj.create(cr, uid, vals=pull_rule, context=context)
return default_route_ids
#create MTS route and pull rules for delivery a specific route MTO to be set on the product
route_name, values = routes_dict[warehouse.delivery_steps]
route_vals = self._get_reception_delivery_route(cr, uid, warehouse, route_name, context=context)
#create the route and its pull rules
delivery_route_id = route_obj.create(cr, uid, route_vals, context=context)
wh_route_ids.append((4, delivery_route_id))
dummy, pull_rules_list = self._get_push_pull_rules(cr, uid, warehouse, True, values, delivery_route_id, context=context)
for pull_rule in pull_rules_list:
pull_obj.create(cr, uid, vals=pull_rule, context=context)
#create MTO pull rule and link it to the generic MTO route
mto_pull_vals = self._get_mto_pull_rule(cr, uid, warehouse, values, context=context)
mto_pull_id = pull_obj.create(cr, uid, mto_pull_vals, context=context)
#create a route for cross dock operations, that can be set on products and product categories
route_name, values = routes_dict['crossdock']
crossdock_route_vals = self._get_crossdock_route(cr, uid, warehouse, route_name, context=context)
crossdock_route_id = route_obj.create(cr, uid, vals=crossdock_route_vals, context=context)
wh_route_ids.append((4, crossdock_route_id))
dummy, pull_rules_list = self._get_push_pull_rules(cr, uid, warehouse, warehouse.delivery_steps != 'ship_only' and warehouse.reception_steps != 'one_step', values, crossdock_route_id, context=context)
for pull_rule in pull_rules_list:
pull_obj.create(cr, uid, vals=pull_rule, context=context)
#set routes and mto pull rule on warehouse
return self.write(cr, uid, warehouse.id, {
'route_ids': wh_route_ids,
'mto_pull_id': mto_pull_id,
'reception_route_id': reception_route_id,
'delivery_route_id': delivery_route_id,
'crossdock_route_id': crossdock_route_id,
}, context=context)
def change_route(self, cr, uid, ids, warehouse, new_reception_step=False, new_delivery_step=False, context=None):
picking_type_obj = self.pool.get('stock.picking.type')
pull_obj = self.pool.get('procurement.rule')
push_obj = self.pool.get('stock.location.path')
route_obj = self.pool.get('stock.location.route')
new_reception_step = new_reception_step or warehouse.reception_steps
new_delivery_step = new_delivery_step or warehouse.delivery_steps
reception_name = False
routes_dict = self.get_routes_dict(cr, uid, ids, warehouse, new_reception_step, new_delivery_step, write=True, context=context)
delivery_name, values = routes_dict[new_delivery_step]
delivery_name = self._format_routename(cr, uid, warehouse, delivery_name, context=context)
crossdock_name, values = routes_dict['crossdock']
crossdock_name = self._format_routename(cr, uid, warehouse, crossdock_name, context=context)
if new_reception_step != 'one_step':
reception_name, values = routes_dict[new_reception_step]
reception_name = self._format_routename(cr, uid, warehouse, reception_name, context=context)
set_active_route_ids = []
set_inactive_route_ids = []
for route in warehouse.route_ids:
#put active route that are associated to reception and delivery method choosen if it's not already the case
if route.name == reception_name or route.name == delivery_name:
if not route.active:
set_active_route_ids.append(route.id)
#put previous active route that are no longer needed to active=False
elif route.active and route.name != crossdock_name:
set_inactive_route_ids.append(route.id)
#change pull rules input/output destination on crossdock route
elif route.name == crossdock_name:
route_name, values = routes_dict['crossdock']
first_rule = True
i=0
if len(route.pull_ids) == len(values):
for from_loc, dest_loc, pick_type_id in values:
pull_obj.write(cr, uid, route.pull_ids[i].id, vals={
'name': self._format_rulename(cr, uid, warehouse, from_loc, dest_loc, context=context),
'location_src_id': from_loc.id,
'location_id': dest_loc.id,
'route_id': route.id,
'action': 'move',
'picking_type_id': pick_type_id,
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
'sequence': 10,
}, context=context)
first_rule = False
i+=1
continue
#deactivate previous mto route
if warehouse.ship_route_mto.active:
set_inactive_route_ids.append(warehouse.ship_route_mto.id)
if warehouse.pick_ship_route_mto.active:
set_inactive_route_ids.append(warehouse.pick_ship_route_mto.id)
if warehouse.pick_pack_ship_route_mto.active:
set_inactive_route_ids.append(warehouse.pick_pack_ship_route_mto.id)
#activate new mto route
#change the default source and destination location and (de)activate picking types
input_loc = warehouse.wh_input_stock_loc_id
if new_reception_step == 'one_step':
input_loc = warehouse.lot_stock_id
output_loc = warehouse.wh_output_stock_loc_id
if new_delivery_step == 'ship_only':
set_active_route_ids.append(warehouse.ship_route_mto.id)
elif new_delivery_step == 'pick_ship':
set_active_route_ids.append(warehouse.pick_ship_route_mto.id)
elif new_delivery_step == 'pick_pack_ship':
set_active_route_ids.append(warehouse.pick_pack_ship_route_mto.id)
route_obj.write(cr, uid, set_inactive_route_ids, {'active': False}, context=context)
route_obj.write(cr, uid, set_active_route_ids, {'active': True}, context=context)
output_loc = warehouse.lot_stock_id
picking_type_obj.write(cr, uid, warehouse.in_type_id.id, {'default_location_dest_id': input_loc.id}, context=context)
picking_type_obj.write(cr, uid, warehouse.out_type_id.id, {'default_location_src_id': output_loc.id}, context=context)
picking_type_obj.write(cr, uid, warehouse.int_type_id.id, {'active': new_reception_step != 'one_step'}, context=context)
picking_type_obj.write(cr, uid, warehouse.pick_type_id.id, {'active': new_delivery_step != 'ship_only'}, context=context)
picking_type_obj.write(cr, uid, warehouse.pack_type_id.id, {'active': new_delivery_step == 'pick_pack_ship'}, context=context)
routes_dict = self.get_routes_dict(cr, uid, ids, warehouse, context=context)
#update delivery route and rules: unlink the existing rules of the warehouse delivery route and recreate it
pull_obj.unlink(cr, uid, [pu.id for pu in warehouse.delivery_route_id.pull_ids], context=context)
route_name, values = routes_dict[new_delivery_step]
route_obj.write(cr, uid, warehouse.delivery_route_id.id, {'name': self._format_routename(cr, uid, warehouse, route_name, context=context)}, context=context)
dummy, pull_rules_list = self._get_push_pull_rules(cr, uid, warehouse, True, values, warehouse.delivery_route_id.id, context=context)
#create the pull rules
for pull_rule in pull_rules_list:
pull_obj.create(cr, uid, vals=pull_rule, context=context)
#update reception route and rules: unlink the existing rules of the warehouse reception route and recreate it
pull_obj.unlink(cr, uid, [pu.id for pu in warehouse.reception_route_id.pull_ids], context=context)
push_obj.unlink(cr, uid, [pu.id for pu in warehouse.reception_route_id.push_ids], context=context)
route_name, values = routes_dict[new_reception_step]
route_obj.write(cr, uid, warehouse.reception_route_id.id, {'name': self._format_routename(cr, uid, warehouse, route_name, context=context)}, context=context)
push_rules_list, pull_rules_list = self._get_push_pull_rules(cr, uid, warehouse, True, values, warehouse.reception_route_id.id, context=context)
#create the push/pull rules
for push_rule in push_rules_list:
push_obj.create(cr, uid, vals=push_rule, context=context)
for pull_rule in pull_rules_list:
pull_obj.create(cr, uid, vals=pull_rule, context=context)
route_obj.write(cr, uid, warehouse.crossdock_route_id.id, {'active': new_reception_step != 'one_step' and new_delivery_step != 'ship_only'}, context=context)
#change MTO rule
dummy, values = routes_dict[new_delivery_step]
mto_pull_vals = self._get_mto_pull_rule(cr, uid, warehouse, values, context=context)
pull_obj.write(cr, uid, warehouse.mto_pull_id.id, mto_pull_vals, context=context)
return True
def create(self, cr, uid, vals, context=None):
@@ -283,7 +280,6 @@ class stock_warehouse(osv.osv):
seq_obj = self.pool.get('ir.sequence')
picking_type_obj = self.pool.get('stock.picking.type')
location_obj = self.pool.get('stock.location')
route_obj = self.pool.get('stock.location.route')
#create view location for warehouse
wh_loc_id = location_obj.create(cr, uid, {
@@ -291,84 +287,54 @@ class stock_warehouse(osv.osv):
'usage': 'view',
'location_id': data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_locations')[1]
}, context=context)
wh_stock_loc_id = location_obj.create(cr, uid, {
'name': _('Stock'),
'usage': 'internal',
'location_id': wh_loc_id
}, context=context)
vals['lot_stock_id'] = wh_stock_loc_id
context_with_inactive = context.copy()
context_with_inactive['active_test']=False
#create all location
reception_steps = vals.get('reception_steps', False)
delivery_steps = vals.get('delivery_steps', False)
wh_input_stock_loc_id = location_obj.create(cr, uid, {
'name': _('Input'),
context_with_inactive = context.copy()
context_with_inactive['active_test'] = False
sub_locations = [
{'name': _('Stock'), 'active': True, 'field': 'lot_stock_id'},
{'name': _('Input'), 'active': reception_steps != 'one_step', 'field': 'wh_input_stock_loc_id'},
{'name': _('Quality Control'), 'active': reception_steps == 'three_steps', 'field': 'wh_qc_stock_loc_id'},
{'name': _('Output'), 'active': delivery_steps != 'ship_only', 'field': 'wh_output_stock_loc_id'},
{'name': _('Packing Zone'), 'active': delivery_steps == 'pick_pack_ship', 'field': 'wh_pack_stock_loc_id'},
]
for values in sub_locations:
location_id = location_obj.create(cr, uid, {
'name': values['name'],
'usage': 'internal',
'location_id': wh_loc_id,
'active': reception_steps != 'one_step' and True or False,
'active': values['active'],
}, context=context_with_inactive)
vals['wh_input_stock_loc_id'] = wh_input_stock_loc_id
wh_qc_stock_loc_id = location_obj.create(cr, uid, {
'name': _('Quality Control'),
'usage': 'internal',
'location_id': wh_loc_id,
'active': reception_steps == 'three_steps' and True or False,
}, context=context_with_inactive)
vals['wh_qc_stock_loc_id'] = wh_qc_stock_loc_id
wh_output_stock_loc_id = location_obj.create(cr, uid, {
'name': _('Output'),
'usage': 'internal',
'location_id': wh_loc_id,
'active': delivery_steps != 'ship_only' and True or False,
}, context=context_with_inactive)
vals['wh_output_stock_loc_id'] = wh_output_stock_loc_id
wh_pack_stock_loc_id = location_obj.create(cr, uid, {
'name': _('Packing Zone'),
'usage': 'internal',
'location_id': wh_loc_id,
'active': delivery_steps == 'pick_pack_ship' and True or False,
}, context=context_with_inactive)
vals['wh_pack_stock_loc_id'] = wh_pack_stock_loc_id
vals[values['field']] = location_id
#create new sequences
in_seq_id = seq_obj.create(cr, uid, values={'name': vals.get('name', '') + _(' Sequence in'), 'prefix': vals.get('code', '') + '\IN\\', 'padding': 5}, context=context)
out_seq_id = seq_obj.create(cr, uid, values={'name': vals.get('name', '') + _(' Sequence out'), 'prefix': vals.get('code', '') + '\OUT\\', 'padding': 5}, context=context)
pack_seq_id = seq_obj.create(cr, uid, values={'name': vals.get('name', '') + _(' Sequence packing'), 'prefix': vals.get('code', '') + '\PACK\\', 'padding': 5}, context=context)
pick_seq_id = seq_obj.create(cr, uid, values={'name': vals.get('name', '') + _(' Sequence picking'), 'prefix': vals.get('code', '') + '\PICK\\', 'padding': 5}, context=context)
int_seq_id = seq_obj.create(cr, uid, values={'name': vals.get('name', '') + _(' Sequence internal'), 'prefix': vals.get('code', '') + '\INT\\', 'padding': 5}, context=context)
#create WH
new_id = super(stock_warehouse, self).create(cr, uid, vals=vals, context=context)
#create sequences and picking type
warehouse = self.browse(cr, uid, new_id, context=context)
wh_stock_loc = warehouse.lot_stock_id
wh_input_stock_loc = location_obj.browse(cr, uid, wh_input_stock_loc_id, context=context)
wh_qc_stock_loc = location_obj.browse(cr, uid, wh_qc_stock_loc_id, context=context)
wh_output_stock_loc = location_obj.browse(cr, uid, wh_output_stock_loc_id, context=context)
wh_pack_stock_loc = location_obj.browse(cr, uid, wh_pack_stock_loc_id, context=context)
wh_input_stock_loc = warehouse.wh_input_stock_loc_id
wh_output_stock_loc = warehouse.wh_output_stock_loc_id
wh_pack_stock_loc = warehouse.wh_pack_stock_loc_id
#fetch customer and supplier locations, for references
try:
customer_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_customers')[1]
supplier_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_suppliers')[1]
except:
customer_loc = location_obj.search(cr, uid, [('usage', '=', 'customer')], context=context)
customer_loc = customer_loc and customer_loc[0] or False
supplier_loc = location_obj.search(cr, uid, [('usage', '=', 'supplier')], context=context)
supplier_loc = supplier_loc and supplier_loc[0] or False
if not (customer_loc and supplier_loc):
raise osv.except_osv(_('Error!'), _('Can\'t find any customer or supplier location.'))
customer_loc = location_obj.browse(cr, uid, customer_loc, context=context)
supplier_loc = location_obj.browse(cr, uid, supplier_loc, context=context)
customer_loc, supplier_loc = self._get_partner_locations(cr, uid, new_id, context=context)
#create in, out, internal picking types for warehouse
#First create new sequence
in_seq_id = seq_obj.create(cr, uid, values={'name': warehouse.name + _(' Picking in'), 'prefix': warehouse.code + '\IN\\', 'padding': 5}, context=context)
out_seq_id = seq_obj.create(cr, uid, values={'name': warehouse.name + _(' Picking out'), 'prefix': warehouse.code + '\OUT\\', 'padding': 5}, context=context)
internal_seq_id = seq_obj.create(cr, uid, values={'name': warehouse.name + _(' Picking internal'), 'prefix': warehouse.code + '\INT\\', 'padding': 5}, context=context)
#then create picking_types
input_loc = wh_input_stock_loc
if warehouse.reception_steps == 'one_step':
input_loc = wh_stock_loc
output_loc = wh_output_stock_loc
if warehouse.delivery_steps == 'ship_only':
output_loc = wh_stock_loc
in_picking_type_id = picking_type_obj.create(cr, uid, vals={
in_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Receptions'),
'warehouse_id': new_id,
'code_id': 'incoming',
@@ -376,7 +342,7 @@ class stock_warehouse(osv.osv):
'sequence_id': in_seq_id,
'default_location_src_id': supplier_loc.id,
'default_location_dest_id': input_loc.id}, context=context)
out_picking_type_id = picking_type_obj.create(cr, uid, vals={
out_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Delivery Orders'),
'warehouse_id': new_id,
'code_id': 'outgoing',
@@ -384,18 +350,47 @@ class stock_warehouse(osv.osv):
'delivery': True,
'default_location_src_id': output_loc.id,
'default_location_dest_id': customer_loc.id}, context=context)
internal_picking_type_id = picking_type_obj.create(cr, uid, vals={
int_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Internal Transfers'),
'warehouse_id': new_id,
'code_id': 'internal',
'sequence_id': internal_seq_id,
'sequence_id': int_seq_id,
'default_location_src_id': wh_stock_loc.id,
'default_location_dest_id': wh_stock_loc.id,
'pack': True,}, context=context)
'active': reception_steps != 'one_step',
'pack': False}, context=context)
pack_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Pack'),
'warehouse_id': new_id,
'code_id': 'internal',
'sequence_id': pack_seq_id,
'default_location_src_id': wh_pack_stock_loc.id,
'default_location_dest_id': output_loc.id,
'active': delivery_steps == 'pick_pack_ship',
'pack': True}, context=context)
pick_type_id = picking_type_obj.create(cr, uid, vals={
'name': _('Pick'),
'warehouse_id': new_id,
'code_id': 'internal',
'sequence_id': pick_seq_id,
'default_location_src_id': wh_stock_loc.id,
'default_location_dest_id': wh_pack_stock_loc.id,
'active': delivery_steps != 'ship_only',
'pack': False}, context=context)
#write picking types on WH
vals = {
'in_type_id': in_type_id,
'out_type_id': out_type_id,
'pack_type_id': pack_type_id,
'pick_type_id': pick_type_id,
'int_type_id': int_type_id,
}
super(stock_warehouse, self).write(cr, uid, new_id, vals=vals, context=context)
warehouse.refresh()
#create routes and push/pull rules
default_route_id = self.create_route(cr, uid, new_id, warehouse, context=context)
self.create_routes(cr, uid, new_id, warehouse, context=context)
return new_id
def _format_rulename(self, cr, uid, obj, from_loc, dest_loc, context=None):
@@ -404,54 +399,23 @@ class stock_warehouse(osv.osv):
def _format_routename(self, cr, uid, obj, name, context=None):
return obj.name + ': ' + name
def get_routes_dict(self, cr, uid, ids, warehouse, reception_steps=False, delivery_steps=False, write=False, context=None):
picking_type_obj = self.pool.get('stock.picking.type')
data_obj = self.pool.get('ir.model.data')
location_obj = self.pool.get('stock.location')
#fetch various location
wh_input_stock_loc = warehouse.wh_input_stock_loc_id
wh_qc_stock_loc = warehouse.wh_qc_stock_loc_id
wh_output_stock_loc = warehouse.wh_output_stock_loc_id
wh_pack_stock_loc = warehouse.wh_pack_stock_loc_id
wh_stock_loc = warehouse.lot_stock_id
def get_routes_dict(self, cr, uid, ids, warehouse, context=None):
#fetch customer and supplier locations, for references
try:
customer_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_customers')[1]
supplier_loc = data_obj.get_object_reference(cr, uid, 'stock', 'stock_location_suppliers')[1]
except:
customer_loc = location_obj.search(cr, uid, [('usage', '=', 'customer')], context=context)
customer_loc = customer_loc and customer_loc[0] or False
supplier_loc = location_obj.search(cr, uid, [('usage', '=', 'supplier')], context=context)
supplier_loc = supplier_loc and supplier_loc[0] or False
if not (customer_loc and supplier_loc):
raise osv.except_osv(_('Error!'), _('Can\'t find any customer or supplier location.'))
customer_loc = location_obj.browse(cr, uid, customer_loc, context=context)
supplier_loc = location_obj.browse(cr, uid, supplier_loc, context=context)
#update route on picking type
input_loc = wh_input_stock_loc
if reception_steps == 'one_step':
input_loc = wh_stock_loc
output_loc = wh_output_stock_loc
if delivery_steps == 'ship_only':
output_loc = wh_stock_loc
in_picking_type_id = picking_type_obj.search(cr, uid, [('warehouse_id', '=', warehouse.id), ('code_id', '=', 'incoming')], context=context)[0]
out_picking_type_id = picking_type_obj.search(cr, uid, [('warehouse_id', '=', warehouse.id), ('code_id', '=', 'outgoing')], context=context)[0]
internal_picking_type_id = picking_type_obj.search(cr, uid, [('warehouse_id', '=', warehouse.id), ('code_id', '=', 'internal')], context=context)[0]
#in case we need to update picking location
if write:
picking_type_obj.write(cr, uid, in_picking_type_id, {'default_location_dest_id': input_loc.id}, context=context)
picking_type_obj.write(cr, uid, out_picking_type_id, {'default_location_src_id': output_loc.id}, context=context)
customer_loc, supplier_loc = self._get_partner_locations(cr, uid, ids, context=context)
return {
'two_steps': (_('Reception in 2 steps'), [(wh_input_stock_loc, wh_stock_loc, internal_picking_type_id)]),
'three_steps': (_('Reception in 3 steps'), [(wh_input_stock_loc, wh_qc_stock_loc, internal_picking_type_id), (wh_qc_stock_loc, wh_stock_loc, internal_picking_type_id)]),
'crossdock': (_('Cross-Dock'), [(input_loc, output_loc, internal_picking_type_id), (output_loc, customer_loc, out_picking_type_id)]),
'ship_only': (_('Ship Only'), [(wh_stock_loc, customer_loc, out_picking_type_id)]),
'pick_ship': (_('Pick + Ship'), [(wh_stock_loc, wh_output_stock_loc, internal_picking_type_id), (wh_output_stock_loc, customer_loc, out_picking_type_id)]),
'pick_pack_ship': (_('Pick + Pack + Ship'), [(wh_stock_loc, wh_pack_stock_loc, internal_picking_type_id), (wh_pack_stock_loc, wh_output_stock_loc, internal_picking_type_id), (wh_output_stock_loc, customer_loc, out_picking_type_id)]),
'one_step': (_('Reception in 1 step'), []),
'two_steps': (_('Reception in 2 steps'), [(warehouse.wh_input_stock_loc_id, warehouse.lot_stock_id, warehouse.int_type_id.id)]),
'three_steps': (_('Reception in 3 steps'), [(warehouse.wh_input_stock_loc_id, warehouse.wh_qc_stock_loc_id, warehouse.int_type_id.id), (warehouse.wh_qc_stock_loc_id, warehouse.lot_stock_id, warehouse.int_type_id.id)]),
'crossdock': (_('Cross-Dock'), [(warehouse.wh_input_stock_loc_id, warehouse.wh_output_stock_loc_id, warehouse.int_type_id.id), (warehouse.wh_output_stock_loc_id, customer_loc, warehouse.out_type_id.id)]),
'ship_only': (_('Ship Only'), [(warehouse.lot_stock_id, customer_loc, warehouse.out_type_id.id)]),
'pick_ship': (_('Pick + Ship'), [(warehouse.lot_stock_id, warehouse.wh_output_stock_loc_id, warehouse.pick_type_id.id), (warehouse.wh_output_stock_loc_id, customer_loc, warehouse.out_type_id.id)]),
'pick_pack_ship': (_('Pick + Pack + Ship'), [(warehouse.lot_stock_id, warehouse.wh_pack_stock_loc_id, warehouse.int_type_id.id), (warehouse.wh_pack_stock_loc_id, warehouse.wh_output_stock_loc_id, warehouse.pack_type_id.id), (warehouse.wh_output_stock_loc_id, customer_loc, warehouse.out_type_id.id)]),
}
def write(self, cr, uid, ids, vals, context=None):
if context is None:
context = {}
if isinstance(ids, (int, long)):
ids = [ids]
if context is None:
@@ -463,50 +427,36 @@ class stock_warehouse(osv.osv):
push_obj = self.pool.get('stock.location.path')
context_with_inactive = context.copy()
context_with_inactive['active_test']=False
context_with_inactive['active_test'] = False
for warehouse in self.browse(cr, uid, ids, context=context_with_inactive):
name = warehouse.name
rename = False
if vals.get('code') or vals.get('name'):
#use previous name to find informations
#rename sequence
if vals.get('name'):
rename = True
name = vals.get('name')
in_seq = seq_obj.search(cr, uid, [('name', '=', name + _(' Picking in'))], context=context)
out_seq = seq_obj.search(cr, uid, [('name', '=', name + _(' Picking out'))], context=context)
internal_seq = seq_obj.search(cr, uid, [('name', '=', name + _(' Picking internal'))], context=context)
seq_obj.write(cr, uid, in_seq, {'name': name, 'prefix': vals.get('code', warehouse.code) + '\IN\\'}, context=context)
seq_obj.write(cr, uid, out_seq, {'name': name, 'prefix': vals.get('code', warehouse.code) + '\OUT\\'}, context=context)
seq_obj.write(cr, uid, internal_seq, {'name': name, 'prefix': vals.get('code', warehouse.code) + '\INT\\'}, context=context)
#first of all, check if we need to delete and recreate route
if vals.get('reception_steps') or vals.get('delivery_steps'):
#activate and deactivate location according to reception and delivery option
self.switch_location(cr, uid, warehouse.id, warehouse, vals.get('reception_steps', False), vals.get('delivery_steps', False), context=context)
# switch between route
self.change_route(cr, uid, ids, warehouse, vals.get('reception_steps', False), vals.get('delivery_steps', False), context=context_with_inactive)
if rename:
#rename location
location_id = warehouse.lot_stock_id.location_id.id
location_obj.write(cr, uid, location_id, {'name': name}, context=context_with_inactive)
#rename route and push-pull rules
for route in warehouse.route_ids:
route_obj.write(cr, uid, route.id, {'name': route.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for pull in route.pull_ids:
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for push in route.push_ids:
push_obj.write(cr, uid, push.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
#change the 3 mto route name
route_obj.write(cr, uid, warehouse.ship_route_mto.id, {'name': warehouse.ship_route_mto.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for pull in warehouse.ship_route_mto.pull_ids:
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
route_obj.write(cr, uid, warehouse.pick_ship_route_mto.id, {'name': warehouse.pick_ship_route_mto.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for pull in warehouse.pick_ship_route_mto.pull_ids:
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
route_obj.write(cr, uid, warehouse.pick_pack_ship_route_mto.id, {'name': warehouse.pick_pack_ship_route_mto.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for pull in warehouse.pick_pack_ship_route_mto.pull_ids:
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
if vals.get('code') or vals.get('name'):
name = warehouse.name
#rename sequence
if vals.get('name'):
name = vals.get('name')
#rename location
location_id = warehouse.lot_stock_id.location_id.id
location_obj.write(cr, uid, location_id, {'name': name}, context=context_with_inactive)
#rename route and push-pull rules
for route in warehouse.route_ids:
route_obj.write(cr, uid, route.id, {'name': route.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for pull in route.pull_ids:
pull_obj.write(cr, uid, pull.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
for push in route.push_ids:
push_obj.write(cr, uid, push.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
#change the mto pull rule name
pull_obj.write(cr, uid, warehouse.mto_pull_id.id, {'name': warehouse.mto_pull_id.name.replace(warehouse.name, name, 1)}, context=context_with_inactive)
seq_obj.write(cr, uid, warehouse.in_type_id.sequence_id.id, {'name': name + _(' Sequence in'), 'prefix': vals.get('code', warehouse.code) + '\IN\\'}, context=context)
seq_obj.write(cr, uid, warehouse.out_type_id.sequence_id.id, {'name': name + _(' Sequence out'), 'prefix': vals.get('code', warehouse.code) + '\OUT\\'}, context=context)
seq_obj.write(cr, uid, warehouse.pack_type_id.sequence_id.id, {'name': name + _(' Sequence packing'), 'prefix': vals.get('code', warehouse.code) + '\PACK\\'}, context=context)
seq_obj.write(cr, uid, warehouse.pick_type_id.sequence_id.id, {'name': name + _(' Sequence picking'), 'prefix': vals.get('code', warehouse.code) + '\PICK\\'}, context=context)
seq_obj.write(cr, uid, warehouse.int_type_id.sequence_id.id, {'name': name + _(' Sequence internal'), 'prefix': vals.get('code', warehouse.code) + '\INT\\'}, context=context)
return super(stock_warehouse, self).write(cr, uid, ids, vals=vals, context=context)
def unlink(self, cr, uid, ids, context=None):
@@ -519,6 +469,9 @@ class stock_location_path(osv.osv):
_order = "name"
def _get_route(self, cr, uid, ids, context=None):
#WARNING TODO route_id is not required, so a field related seems a bad idea >-<
if context is None:
context = {}
result = {}
if context is None:
context = {}
@@ -628,27 +581,34 @@ class procurement_order(osv.osv):
})
return d
def _find_parent_locations(self, cr, uid, procurement, context=None):
location = procurement.location_id
res = [location.id]
while location.location_id:
location = location.location_id
res.append(location.id)
return res
def _find_suitable_rule(self, cr, uid, procurement, context=None):
rule_id = super(procurement_order, self)._find_suitable_rule(cr, uid, procurement, context=context)
if not rule_id:
rule_id = self._search_suitable_rule(cr, uid, procurement, [('location_id', '=', procurement.location_id.id)], context=context) #action=move
#a rule defined on 'Stock' is suitable for a procurement in 'Stock\Bin A'
all_parent_location_ids = self._find_parent_locations(cr, uid, procurement, context=context)
rule_id = self._search_suitable_rule(cr, uid, procurement, [('location_id', 'in', all_parent_location_ids)], context=context)
rule_id = rule_id and rule_id[0] or False
return rule_id
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'''
categ_obj = self.pool.get("product.category")
categ_id = procurement.product_id.categ_id.id
route_ids1 = [x.id for x in procurement.product_id.route_ids + procurement.product_id.categ_id.total_route_ids]
route_ids2 = [x.id for x in procurement.route_ids]
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', route_ids1)], order = 'route_sequence, sequence', context=context)
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]
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', route_ids2)], order = 'route_sequence, sequence', context=context)
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', 'in', procurement_route_ids)], order = 'route_sequence, sequence', context=context)
if not res:
res = self.pool.get('procurement.rule').search(cr, uid, domain + [('route_id', '=', False)], order='sequence', context=context)
return res
class product_putaway_strategy(osv.osv):
_name = 'product.putaway'
_description = 'Put Away Strategy'
@@ -672,16 +632,17 @@ class product_removal_strategy(osv.osv):
'location_id': fields.many2one('stock.location', 'Locations', required=True),
}
class product_product(osv.osv):
_inherit = 'product.product'
_columns = {
'route_ids': fields.many2many('stock.location.route', 'stock_route_product', 'product_id', 'route_id', 'Routes', domain="[('product_selectable', '=', True)]"), #Adds domain
}
class product_category(osv.osv):
_inherit = 'product.category'
def calculate_total_routes(self, cr, uid, ids, name, args, context=None):
res = {}
route_obj = self.pool.get("stock.location.route")
@@ -700,7 +661,6 @@ class product_category(osv.osv):
'putaway_strategy_ids': fields.one2many('product.putaway', 'product_categ_id', 'Put Away Strategies'),
'total_route_ids': fields.function(calculate_total_routes, relation='stock.location.route', type='many2many', string='Total routes', readonly=True),
}
class stock_move_putaway(osv.osv):
@@ -716,13 +676,12 @@ class stock_move_putaway(osv.osv):
class stock_quant(osv.osv):
_inherit = "stock.quant"
def check_preferred_location(self, cr, uid, move, context=None):
# moveputaway_obj = self.pool.get('stock.move.putaway')
if move.putaway_ids and move.putaway_ids[0]:
#Take only first suggestion for the moment
return move.putaway_ids[0].location_id
else:
return super(stock_quant, self).check_preferred_location(cr, uid, move, context=context)
return super(stock_quant, self).check_preferred_location(cr, uid, move, context=context)
class stock_move(osv.osv):
@@ -818,5 +777,4 @@ class stock_location(osv.osv):
return pr.browse(cr, uid, result[0], context=context).method
return super(stock_location, self).get_removal_strategy(cr, uid, location, product, context=context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+61 -230
View File
@@ -4,7 +4,6 @@
<!--Pick / Pack / Input location
-->
<record id="location_pack_zone" model="stock.location">
<field name="name">Packing zone</field>
<field name="location_id" ref="stock.stock_location_company"/>
@@ -18,20 +17,50 @@
<field name="usage">internal</field>
<field name="active" eval="False"/>
</record>
<record id="stock_location_qualitytest0" model="stock.location">
<field name="location_id" ref="stock.stock_location_company"/>
<field eval="0" name="scrap_location"/>
<field name="company_id" ref="base.main_company"/>
<field name="usage">internal</field>
<field name="name">Quality Control</field>
<field name="active" eval="False"/>
<record id="stock_location_quality" model="stock.location">
<field name="name">Quality Control</field>
<field name="location_id" ref="stock.stock_location_company"/>
<field name="usage">internal</field>
<field name="active" eval="False"/>
</record>
<!-- Sequences and picking types -->
<record id="seq_picking_type_pack" model="ir.sequence">
<field name="name">Main warehouse: Pack</field>
<field name="prefix">WH\PACK</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
<record id="picking_type_pack" model="stock.picking.type">
<field name="name">Pack Operations</field>
<field name="sequence_id" ref="seq_picking_type_pack"/>
<field name="default_location_src_id" ref="location_pack_zone"/>
<field name="default_location_dest_id" ref="stock.stock_location_output"/>
<field name="code_id">internal</field>
<field name="active" eval="False"/>
</record>
<record id="seq_picking_type_pick" model="ir.sequence">
<field name="name">Main warehouse: Pick</field>
<field name="prefix">WH\PICK</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
<record id="picking_type_pick" model="stock.picking.type">
<field name="name">Pick Operations</field>
<field name="sequence_id" ref="seq_picking_type_pick"/>
<field name="default_location_src_id" ref="stock.stock_location_stock"/>
<field name="default_location_dest_id" ref="location_pack_zone"/>
<field name="code_id">internal</field>
<field name="active" eval="False"/>
</record>
<!--
Procurement rules
-->
<record id="route_warehouse0_mts" model='stock.location.route'>
<field name="name">Your Company: Ship only</field>
<field name="sequence">20</field>
@@ -39,7 +68,6 @@
<field name="product_selectable" eval="False"/>
</record>
<record id="procurement_rule_customer0_mts" model="procurement.rule">
<field name="name">Your Company: Stock → Customers</field>
<field name="action">move</field>
@@ -50,259 +78,62 @@
<field name="picking_type_id" ref="stock.picking_type_out"/>
</record>
<!-- Override from stock-->
<!--<record id="procurement_rule_customer_mto" model="procurement.rule">
<field name="name">Stock → Customer</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="stock.route_warehouse0_mto"/>
<field name="product_categ_selectable" eval="True"/>
</record>-->
<record id="stock.route_warehouse0_mto" model='stock.location.route'>
<field name="name">Your company: Ship only (MTO)</field>
<field name="sequence">10</field>
<field name="product_categ_selectable" eval="True"/>
</record>
<record id="procurement_rule_customer0_mto" model="procurement.rule">
<field name="name">Your Company: Stock → Customers</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="stock.route_warehouse0_mto"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
</record>
<record id="route_warehouse0_crossdock" model='stock.location.route'>
<field name="name">Your Company: Cross-Dock</field>
<field name="sequence">9</field>
<field name="product_categ_selectable" eval="True"/>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_xdock" model="procurement.rule">
<field name="name">Your Company: Stock → Customers</field>
<field name="name">Your Company: Output → Customers</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="location_src_id" ref="stock.stock_location_output"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_crossdock"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_xdock_start" model="procurement.rule">
<field name="name">Your Company: Stock → Stock</field>
<field name="name">Your Company: Input → Output</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="stock_location_input"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_crossdock"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="route_warehouse0_pack" model='stock.location.route'>
<field name="name">Your Company: Pick + Ship</field>
<field name="sequence">15</field>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="active" eval="False"/>
</record>
<record id="route_warehouse0_mto_pack" model='stock.location.route'>
<field name="name">Your Company: Pick + Ship (MTO)</field>
<field name="sequence">10</field>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_pack" model="procurement.rule">
<field name="name">Your Company: Stock → Output</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_pack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer1_pack" model="procurement.rule">
<field name="name">Your Company: Output → Customers</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_output"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_pack"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_mto_pack" model="procurement.rule">
<field name="name">Your Company: Stock → Output</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto_pack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<!-- Pick + pack + ship -->
<record id="route_warehouse0_pickpack" model='stock.location.route'>
<field name="name">Your Company: Pick + Pack + Ship</field>
<field name="sequence">20</field>
<field name="warehouse_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="active" eval="False"/>
</record>
<record id="route_warehouse0_mto_pickpack" model='stock.location.route'>
<field name="name">Your Company: Pick + Pack + Ship (MTO)</field>
<field name="sequence">12</field>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_pickpack" model="procurement.rule">
<field name="name">Your Company: Stock → Packing Zone</field>
<field name="action">move</field>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_warehouse0_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer1_pickpack" model="procurement.rule">
<field name="name">Your Company: Output → Customers</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_customers"/>
<field name="location_src_id" ref="stock.stock_location_output"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_out"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer2_pickpack" model="procurement.rule">
<field name="name">Your Company: Packing Zone → Output</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_output"/>
<field name="location_src_id" ref="location_pack_zone"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_customer0_mto_pickpack" model="procurement.rule">
<field name="name">Your Company: Stock → Packing Zone</field>
<field name="action">move</field>
<field name="location_id" ref="location_pack_zone"/>
<field name="location_src_id" ref="stock.stock_location_stock"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_warehouse0_mto_pickpack"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<!-- 2-step reception route -->
<record id="route_2_push" model='stock.location.route'>
<field name="name">Your Company: Reception in 2 steps</field>
<!-- reception route -->
<record id="route_1_push" model='stock.location.route'>
<field name="name">1-step Receival</field>
<field name="sequence">20</field>
<field name="product_categ_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="active" eval="False"/>
</record>
<record id="push" model='stock.location.path'>
<field name="name">Your Company: Input → Stock</field>
<field name="location_from_id" ref="stock_location_input"/>
<field name="location_dest_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="route_id" ref="route_2_push"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_2_push" model="procurement.rule">
<field name="name">Your Company: Input → Stock</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_src_id" ref="stock_location_input"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_2_push"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<!-- 3step reception route -->
<record id="route_3_push" model='stock.location.route'>
<field name="name">Your Company: Reception in 3 steps</field>
<field name="sequence">22</field>
<field name="product_categ_selectable" eval="True"/>
<field name="product_selectable" eval="False"/>
<field name="active" eval="False"/>
</record>
<record id="push3" model='stock.location.path'>
<field name="name">Your Company: Input → Quality Control</field>
<field name="location_from_id" ref="stock_location_input"/>
<field name="location_dest_id" ref="stock_location_qualitytest0"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="route_id" ref="route_3_push"/>
<field name="active" eval="False"/>
</record>
<record id="push3_next" model='stock.location.path'>
<field name="name">Your Company: Quality Control → Stock</field>
<field name="location_from_id" ref="stock_location_qualitytest0"/>
<field name="location_dest_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="route_id" ref="route_3_push"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_3_push" model="procurement.rule">
<field name="name">Your Company: Quality Control → Stock</field>
<field name="action">move</field>
<field name="location_id" ref="stock.stock_location_stock"/>
<field name="location_src_id" ref="stock_location_qualitytest0"/>
<field name="procure_method">make_to_order</field>
<field name="route_id" ref="route_3_push"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<record id="procurement_rule_3_push_next" model="procurement.rule">
<field name="name">Your Company: Input → Quality Control</field>
<field name="action">move</field>
<field name="location_id" ref="stock_location_qualitytest0"/>
<field name="location_src_id" ref="stock_location_input"/>
<field name="procure_method">make_to_stock</field>
<field name="route_id" ref="route_3_push"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
<field name="active" eval="False"/>
</record>
<!-- Set location and route information on main warehouse -->
<record id="stock.warehouse0" model="stock.warehouse">
<field name="route_ids" eval="[(6, 0, [ref('route_warehouse0_crossdock'), ref('route_warehouse0_mts'), ref('route_1_push')])]"/>
<field name="mto_pull_id" ref="stock.procurement_rule_customer_mto"/>
<field name="wh_input_stock_loc_id" ref="stock_location_input"/>
<field name="wh_qc_stock_loc_id" ref="stock_location_qualitytest0"/>
<field name="wh_output_stock_loc_id" ref="stock.stock_location_output"/>
<field name="wh_qc_stock_loc_id" ref="stock_location_quality"/>
<field name="wh_pack_stock_loc_id" ref="location_pack_zone"/>
<field name="ship_route_mto" ref="stock.route_warehouse0_mto"/>
<field name="pick_ship_route_mto" ref="route_warehouse0_mto_pack"/>
<field name="pick_pack_ship_route_mto" ref="route_warehouse0_mto_pickpack"/>
<field name="route_ids" eval="[(4, ref('route_warehouse0_mts')), (4, ref('route_warehouse0_pack')), (4, ref('route_warehouse0_pickpack')), (4, ref('route_2_push')), (4, ref('route_3_push')), (4, ref('route_warehouse0_crossdock'))]"/>
<field name="pick_type_id" ref="picking_type_pick"/>
<field name="pack_type_id" ref="picking_type_pack"/>
<field name="in_type_id" ref="stock.picking_type_in"/>
<field name="out_type_id" ref="stock.picking_type_out"/>
<field name="int_type_id" ref="stock.picking_type_internal"/>
<field name="reception_route_id" ref="route_1_push"/>
<field name="delivery_route_id" ref="route_warehouse0_mts"/>
<field name="crossdock_route_id" ref="route_warehouse0_crossdock"/>
</record>
</data>
</openerp>
@@ -4,7 +4,7 @@
<field name="description">This product is configured with example of push/pull flows</field>
</record>
<record id="stock_location_qualitytest0" model="stock.location">
<record id="stock_location_quality" model="stock.location">
<field name="active">True</field>
</record>
<record id="stock_location_path_4" model="stock.location.path">
@@ -14,12 +14,12 @@
<field name="invoice_state">none</field>
<field eval="1" name="delay"/>
<field name="name">Receptions to Quality Control</field>
<field name="location_dest_id" ref="stock_location_qualitytest0"/>
<field name="location_dest_id" ref="stock_location_quality"/>
<field name="location_from_id" ref="stock.stock_location_stock"/>
<field name="picking_type_id" ref="stock.picking_type_internal"/>
</record>
<record id="stock_location_path_5" model="stock.location.path">
<field name="location_from_id" ref="stock_location_qualitytest0"/>
<field name="location_from_id" ref="stock_location_quality"/>
<field name="product_id" ref="product.product_product_10"/>
<field name="auto">manual</field>
<field name="invoice_state">none</field>
@@ -67,4 +67,4 @@
</record>
</data>
</openerp>
</openerp>
@@ -31,13 +31,13 @@
push_ids:
- name: 'stock -> quality test'
invoice_state: none
location_dest_id: stock_location.stock_location_qualitytest0
location_dest_id: stock_location.stock_location_quality
location_from_id: stock.stock_location_stock
picking_type_id: stock.picking_type_internal
- name: 'quality test -> components'
invoice_state: none
location_dest_id: stock.stock_location_components
location_from_id: stock_location.stock_location_qualitytest0
location_from_id: stock_location.stock_location_quality
picking_type_id: stock.picking_type_internal
-
!record {model: product.product, id: product_product_hpcdwriters01}: