[WIP]stock warehouse configuration in form view, automatically create routes, picking, location and switch between them if needed. Also corrected stock_location yml test by removing invoice state which is in account_stock and not dependant from stock_location
bzr revid: csn@openerp.com-20130926153725-00gwbo2q1ok9pj21
This commit is contained in:
@@ -56,12 +56,14 @@ class procurement_rule(osv.osv):
|
||||
'route_sequence': fields.related('route_id', 'sequence', string='Route Sequence', store={'stock.location.route': (_get_rules, ['sequence'], 10)}),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type',
|
||||
help="Picking Type determines the way the picking should be shown in the view, reports, ...")
|
||||
help="Picking Type determines the way the picking should be shown in the view, reports, ..."),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the rule without removing it."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'procure_method': 'make_to_stock',
|
||||
'sequence': 20,
|
||||
'active': True,
|
||||
}
|
||||
|
||||
class procurement_order(osv.osv):
|
||||
|
||||
@@ -96,7 +96,7 @@ class stock_location(osv.osv):
|
||||
""", select = True),
|
||||
|
||||
'complete_name': fields.function(_complete_name, type='char', string="Location Name",
|
||||
store={'stock.location': (_get_sublocations, ['name', 'location_id'], 10)}),
|
||||
store={'stock.location': (_get_sublocations, ['name', 'location_id', 'active'], 10)}),
|
||||
'location_id': fields.many2one('stock.location', 'Parent Location', select=True, ondelete='cascade'),
|
||||
'child_ids': fields.one2many('stock.location', 'location_id', 'Contains'),
|
||||
|
||||
@@ -2114,6 +2114,7 @@ class stock_warehouse(osv.osv):
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Address'),
|
||||
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage', '=', 'internal')]),
|
||||
'code': fields.char('Warehouse Unique Identifier', size=5, required=True, help="Short name used to identify your warehouse"),
|
||||
}
|
||||
|
||||
def _default_stock_id(self, cr, uid, context=None):
|
||||
@@ -2124,6 +2125,10 @@ class stock_warehouse(osv.osv):
|
||||
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c),
|
||||
'lot_stock_id': _default_stock_id,
|
||||
}
|
||||
_sql_constraints = [
|
||||
('warehouse_name_uniq', 'unique (name, company_id)', 'The name of the warehouse must be unique per company!'),
|
||||
('warehouse_code_uniq', 'unique (code, company_id)', 'The code of the warehouse must be unique per company !'),
|
||||
]
|
||||
|
||||
|
||||
# -------------------------
|
||||
|
||||
@@ -503,11 +503,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Warehouse" version="7.0">
|
||||
<sheet>
|
||||
<label for="name" class="oe_edit_only" string="Warehouse Short Name"/>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
<group>
|
||||
<group>
|
||||
<field name="lot_stock_id" groups="stock.group_locations" string="Inventory Location"/>
|
||||
<field name="code"/>
|
||||
<field name="lot_stock_id" groups="stock.group_locations" string="Inventory Location" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
|
||||
@@ -19,6 +19,5 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import stock_location
|
||||
|
||||
|
||||
@@ -96,8 +96,7 @@ You can use the demo data as follow:
|
||||
'author': 'OpenERP SA',
|
||||
'images': ['images/pulled_flow.jpeg','images/pushed_flow.jpeg'],
|
||||
'depends': ['procurement','stock'],
|
||||
'data': ['wizard/configure_wh_view.xml',
|
||||
'stock_location_view.xml',
|
||||
'data': ['stock_location_view.xml',
|
||||
'stock_location_data.xml',
|
||||
'security/stock_location_security.xml',
|
||||
'security/ir.model.access.csv'],
|
||||
|
||||
@@ -33,17 +33,461 @@ class stock_location_route(osv.osv):
|
||||
'product_selectable': fields.boolean('Selectable on Product'),
|
||||
'product_categ_selectable': fields.boolean('Selectable on Product Category'),
|
||||
'warehouse_selectable': fields.boolean('Selectable on Warehouse'),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the route without removing it.")
|
||||
}
|
||||
_defaults = {
|
||||
'product_selectable': True
|
||||
'product_selectable': True,
|
||||
'active': True,
|
||||
}
|
||||
|
||||
class stock_warehouse(osv.osv):
|
||||
_inherit = 'stock.warehouse'
|
||||
_columns = {
|
||||
'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'),
|
||||
'reception_steps': fields.selection([
|
||||
('one_step', 'Receive goods directly in stock (1 step)'),
|
||||
('two_steps', 'Unload in input location then go to stock (2 steps)'),
|
||||
('three_steps', 'Unload in input location, go through a quality control before being admitted in stock (3 steps)')], 'Incoming Shipments', required=True),
|
||||
'delivery_steps': fields.selection([
|
||||
('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'),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
'reception_steps': 'one_step',
|
||||
'delivery_steps': 'ship_only',
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
if new_delivery_step == 'pick_pack_ship':
|
||||
location_obj.write(cr, uid, warehouse.wh_pack_stock_loc_id.id, {'active': True}, context=context)
|
||||
|
||||
return True#(wh_input_stock_loc, wh_output_stock_loc, wh_pack_stock_loc, wh_qc_stock_loc)
|
||||
|
||||
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
|
||||
|
||||
|
||||
keys = ('ship_only', 'pick_ship', 'pick_pack_ship')
|
||||
for delivery in keys:
|
||||
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,
|
||||
'active': active,
|
||||
})
|
||||
default_route_ids.append((4, mto_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': 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
|
||||
|
||||
#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={
|
||||
'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
|
||||
|
||||
#set defaut delivery route on warehouse according to option choosen
|
||||
self.write(cr, uid, warehouse.id, {'route_ids': default_route_ids}, context=context)
|
||||
|
||||
return default_route_ids
|
||||
|
||||
def change_route(self, cr, uid, ids, warehouse, new_reception_step=False, new_delivery_step=False, context=None):
|
||||
pull_obj = self.pool.get('procurement.rule')
|
||||
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 or route.name == delivery_name+ _(' (MTO)'):
|
||||
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
|
||||
self.set_route_active_status(cr, uid, ids, set_active_route_ids, True, context=context)
|
||||
self.set_route_active_status(cr, uid, ids, set_inactive_route_ids, False, context=context)
|
||||
return True
|
||||
|
||||
def set_route_active_status(self, cr, uid, ids, route_ids, status=True, context=None):
|
||||
route_obj = self.pool.get('stock.location.route')
|
||||
pull_obj = self.pool.get('procurement.rule')
|
||||
push_obj = self.pool.get('stock.location.path')
|
||||
if not route_ids:
|
||||
return True
|
||||
route_obj.write(cr, uid, route_ids, {'active': status}, context=context)
|
||||
pull_rules_ids = []
|
||||
push_rules_ids = []
|
||||
for route in route_obj.browse(cr, uid, route_ids, context=context):
|
||||
for pull_rule in route.pull_ids:
|
||||
pull_rules_ids.append(pull_rule.id)
|
||||
for push_rule in route.push_ids:
|
||||
push_rules_ids.append(push_rule.id)
|
||||
if pull_rules_ids:
|
||||
pull_obj.write(cr, uid, pull_rules_ids, {'active': status}, context=context)
|
||||
if push_rules_ids:
|
||||
push_obj.write(cr, uid, push_rules_ids, {'active': status}, context=context)
|
||||
return True
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if vals is None:
|
||||
vals = {}
|
||||
data_obj = self.pool.get('ir.model.data')
|
||||
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, {
|
||||
'name': _(vals.get('name')),
|
||||
'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'),
|
||||
'usage': 'internal',
|
||||
'location_id': wh_loc_id,
|
||||
'active': reception_steps != 'one_step' and True or False,
|
||||
}, 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
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
#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={
|
||||
'name': _('Receptions'),
|
||||
'warehouse_id': new_id,
|
||||
'code_id': 'incoming',
|
||||
'auto_force_assign': True,
|
||||
'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={
|
||||
'name': _('Delivery Orders'),
|
||||
'warehouse_id': new_id,
|
||||
'code_id': 'outgoing',
|
||||
'sequence_id': out_seq_id,
|
||||
'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={
|
||||
'name': _('Internal Transfers'),
|
||||
'warehouse_id': new_id,
|
||||
'code_id': 'internal',
|
||||
'sequence_id': internal_seq_id,
|
||||
'default_location_src_id': wh_stock_loc.id,
|
||||
'default_location_dest_id': wh_stock_loc.id,
|
||||
'pack': True,}, context=context)
|
||||
|
||||
#create routes and push/pull rules
|
||||
default_route_id = self.create_route(cr, uid, new_id, warehouse, context=context)
|
||||
|
||||
return new_id
|
||||
|
||||
def _format_rulename(self, cr, uid, obj, from_loc, dest_loc, context=None):
|
||||
return obj.name + ': ' + from_loc.name + ' -> ' + dest_loc.name
|
||||
|
||||
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
|
||||
#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)
|
||||
|
||||
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)]),
|
||||
}
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
seq_obj = self.pool.get('ir.sequence')
|
||||
context_with_inactive = context.copy()
|
||||
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
|
||||
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': vals.get('name', name), 'prefix': vals.get('code', warehouse.code) + '\IN\\'}, context=context)
|
||||
seq_obj.write(cr, uid, out_seq, {'name': vals.get('name', name), 'prefix': vals.get('code', warehouse.code) + '\OUT\\'}, context=context)
|
||||
seq_obj.write(cr, uid, internal_seq, {'name': vals.get('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)
|
||||
|
||||
#TODO rename routes, location, pull/push rules name if warehouse name has changed
|
||||
return super(stock_warehouse, self).write(cr, uid, ids, vals=vals, context=context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
#TODO try to delete location and route and if not possible, put them in inactive
|
||||
return super(stock_warehouse, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
class stock_location_path(osv.osv):
|
||||
_name = "stock.location.path"
|
||||
@@ -72,6 +516,7 @@ class stock_location_path(osv.osv):
|
||||
"by a worker. With 'Automatic No Step Added', the location is replaced in the original move."
|
||||
),
|
||||
'propagate': fields.boolean('Propagate cancel and split', help='If checked, when the previous move is cancelled or split, the move generated by this move will too'),
|
||||
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the rule without removing it."),
|
||||
}
|
||||
_defaults = {
|
||||
'auto': 'auto',
|
||||
@@ -79,6 +524,7 @@ class stock_location_path(osv.osv):
|
||||
'invoice_state': 'none',
|
||||
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'procurement.order', context=c),
|
||||
'propagate': True,
|
||||
'active': True,
|
||||
}
|
||||
def _apply(self, cr, uid, rule, move, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
|
||||
@@ -180,12 +180,20 @@
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="inherit_id" ref="stock.view_warehouse"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="route_ids" invisible="1"/>
|
||||
|
||||
</xpath>
|
||||
<xpath expr="//group[last()]" position="after">
|
||||
<button name="%(action_view_stock_configure_wh)d" class="oe_right oe_highlight" string="Configure this warehouse" type="action" attrs="{'invisible': [('route_id', '!=', False)]}"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Warehouse Configuration" colspan="4">
|
||||
<group colspan="4">
|
||||
<field name="reception_steps" widget='radio'/>
|
||||
<field name="delivery_steps" widget='radio'/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Routes Information" colspan="4">
|
||||
<group colspan="4">
|
||||
<field name="route_ids" nolabel="1" readonly="1"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -209,6 +217,9 @@
|
||||
<field name="model">stock.location.route</field>
|
||||
<field name="inherit_id" ref="stock.stock_location_route_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='sequence']" position="after">
|
||||
<field name="active"/>
|
||||
</xpath>
|
||||
<xpath expr="//group[@string='Pull Rules']" position="before">
|
||||
<separator string="Applicable On"/>
|
||||
<p class="oe_grey">Check these box so that the user can select this route during the following operations</p>
|
||||
|
||||
@@ -4,23 +4,20 @@
|
||||
!record {model: stock.location.route, id: stock_location_route}:
|
||||
name: 'Route from one company to the other'
|
||||
pull_ids:
|
||||
- invoice_state: none
|
||||
location_id: stock.stock_location_shop0
|
||||
- location_id: stock.stock_location_shop0
|
||||
location_src_id: stock.stock_location_intermediatelocation0
|
||||
name: E001
|
||||
procure_method: make_to_order
|
||||
picking_type_id: stock.picking_type_in
|
||||
action: move
|
||||
- invoice_state: none
|
||||
location_id: stock.stock_location_shop1
|
||||
- location_id: stock.stock_location_shop1
|
||||
procure_method: make_to_order
|
||||
location_src_id: stock.stock_location_intermediatelocation0
|
||||
name: E002
|
||||
picking_type_id: stock.picking_type_in
|
||||
procure_method: make_to_order
|
||||
action: move
|
||||
- invoice_state: none
|
||||
location_id: stock.stock_location_intermediatelocation0
|
||||
- location_id: stock.stock_location_intermediatelocation0
|
||||
location_src_id: stock.stock_location_stock
|
||||
name: E003
|
||||
action: move
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
import configure_wh
|
||||
@@ -1,274 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
class stock_configure_wh(osv.osv_memory):
|
||||
_name = "stock.configure.wh"
|
||||
_description = "Configure New WH"
|
||||
|
||||
_columns = {
|
||||
'code': fields.char('Warehouse Unique Identifier', size=5, required=True),
|
||||
'reception_steps': fields.selection([
|
||||
('one_step', 'Receive goods directly in stock (1 step)'),
|
||||
('two_steps', 'Unload in input location then go to stock (2 steps)'),
|
||||
('three_steps', 'Unload in input location, go through a quality control before being admitted in stock (3 steps)')], 'Incoming Shipments', required=True),
|
||||
'delivery_steps': fields.selection([
|
||||
('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),
|
||||
'packing': fields.boolean('Use Packing Operations', help='Whether we make packing in that warehouse while making internal transfers or not'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'reception_steps': 'one_step',
|
||||
'delivery_steps': 'ship_only',
|
||||
}
|
||||
|
||||
def onchange_delivery_steps(self, cr, uid, ids, delivery_steps, context=None):
|
||||
if delivery_steps == 'pick_pack_ship':
|
||||
return {'value': {'packing': True}}
|
||||
return {}
|
||||
|
||||
def _format_rulename(self, cr, uid, obj, from_loc, dest_loc, context=None):
|
||||
return obj.name + ': ' + from_loc.name + ' -> ' + dest_loc.name
|
||||
|
||||
def _format_routename(self, cr, uid, obj, name, context=None):
|
||||
return obj.name + ': ' + name
|
||||
|
||||
def configure_wh(self, cr, uid, ids, context=None):
|
||||
""" To Import stock inventory according to products available in the selected locations.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: the ID or list of IDs if we want more than one
|
||||
@param context: A standard dictionary
|
||||
@return:
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
if ids and isinstance(ids, list):
|
||||
ids = ids[0]
|
||||
|
||||
#TODO avoid running twice the config wizard for a given warehouse => don't create twice the same rule/route/location....
|
||||
data_obj = self.pool.get('ir.model.data')
|
||||
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')
|
||||
pull_obj = self.pool.get('procurement.rule')
|
||||
push_obj = self.pool.get('stock.location.path')
|
||||
wh_obj = self.pool.get('stock.warehouse')
|
||||
obj = self.browse(cr, uid, ids, context=context)
|
||||
|
||||
warehouse_id = context.get('active_id', context.get('active_ids') and context.get('active_ids')[0] or False)
|
||||
if not warehouse_id:
|
||||
raise osv.except_osv(_('Error!'), _('Can\'t find the warehouse to configure. The wizard cannot be used'))
|
||||
|
||||
warehouse = wh_obj.browse(cr, uid, warehouse_id, context=context)
|
||||
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
|
||||
if obj.reception_steps != 'one_step':
|
||||
wh_input_stock_loc_id = location_obj.create(cr, uid, {
|
||||
'name': _('Input'),
|
||||
'usage': 'internal',
|
||||
'location_id': wh_view_location_id
|
||||
}, context=context)
|
||||
wh_input_stock_loc = location_obj.browse(cr, uid, wh_input_stock_loc_id, context=context)
|
||||
if obj.reception_steps == 'three_steps':
|
||||
wh_qc_stock_loc_id = location_obj.create(cr, uid, {
|
||||
'name': _('Quality Control'),
|
||||
'usage': 'internal',
|
||||
'location_id': wh_view_location_id
|
||||
}, context=context)
|
||||
wh_qc_stock_loc = location_obj.browse(cr, uid, wh_qc_stock_loc_id, context=context)
|
||||
if obj.delivery_steps != 'ship_only':
|
||||
wh_output_stock_loc_id = location_obj.create(cr, uid, {
|
||||
'name': _('Output'),
|
||||
'usage': 'internal',
|
||||
'location_id': wh_view_location_id
|
||||
}, context=context)
|
||||
wh_output_stock_loc = location_obj.browse(cr, uid, wh_output_stock_loc_id, context=context)
|
||||
if obj.delivery_steps == 'pick_pack_ship':
|
||||
wh_pack_stock_loc_id = location_obj.create(cr, uid, {
|
||||
'name': _('Packing Zone'),
|
||||
'usage': 'internal',
|
||||
'location_id': wh_view_location_id
|
||||
}, context=context)
|
||||
wh_pack_stock_loc = location_obj.browse(cr, uid, wh_pack_stock_loc_id, context=context)
|
||||
|
||||
#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. The wizard cannot be used'))
|
||||
customer_loc = location_obj.browse(cr, uid, customer_loc, context=context)
|
||||
supplier_loc = location_obj.browse(cr, uid, supplier_loc, context=context)
|
||||
|
||||
#create default route for warehouse
|
||||
default_route_id = route_obj.create(cr, uid, vals={
|
||||
'name': 'to be changed later',
|
||||
'warehouse_selectable': True,
|
||||
'product_selectable': False,
|
||||
}, context=context)
|
||||
|
||||
#create warehouse
|
||||
wh_data = {
|
||||
'route_id': default_route_id,
|
||||
#TODO what about 'code' ....
|
||||
}
|
||||
wh_obj.write(cr, uid, warehouse_id, vals=wh_data, 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': obj.code + '\IN\\', 'padding': 5}, context=context)
|
||||
out_seq_id = seq_obj.create(cr, uid, values={'name': warehouse.name + _(' Picking out'), 'prefix': obj.code + '\OUT\\', 'padding': 5}, context=context)
|
||||
internal_seq_id = seq_obj.create(cr, uid, values={'name': warehouse.name + _(' Picking internal'), 'prefix': obj.code + '\INT\\', 'padding': 5}, context=context)
|
||||
#then create picking_types
|
||||
in_picking_type_id = picking_type_obj.create(cr, uid, vals={
|
||||
'name': _('Receptions'),
|
||||
'warehouse_id': warehouse_id,
|
||||
'code_id': 'incoming',
|
||||
'auto_force_assign': True,
|
||||
'sequence_id': in_seq_id,
|
||||
'default_location_src_id': supplier_loc.id,
|
||||
'default_location_dest_id': wh_input_stock_loc.id}, context=context)
|
||||
out_picking_type_id = picking_type_obj.create(cr, uid, vals={
|
||||
'name': _('Delivery Orders'),
|
||||
'warehouse_id': warehouse_id,
|
||||
'code_id': 'outgoing',
|
||||
'sequence_id': out_seq_id,
|
||||
'delivery': True,
|
||||
'default_location_src_id': wh_output_stock_loc.id,
|
||||
'default_location_dest_id': customer_loc.id}, context=context)
|
||||
internal_picking_type_id = picking_type_obj.create(cr, uid, vals={
|
||||
'name': _('Internal Transfers'),
|
||||
'warehouse_id': warehouse_id,
|
||||
'code_id': 'internal',
|
||||
'sequence_id': internal_seq_id,
|
||||
'default_location_src_id': wh_stock_loc.id,
|
||||
'default_location_dest_id': wh_stock_loc.id,
|
||||
'pack': obj.delivery_steps == 'pick_pack_ship' or obj.packing}, context=context)
|
||||
|
||||
#defining the route references for further creation
|
||||
routes_dict = {
|
||||
'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'), [(wh_input_stock_loc, wh_output_stock_loc, internal_picking_type_id), (wh_output_stock_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)]),
|
||||
}
|
||||
|
||||
#create push rules for reception and assign them to 'All products' category
|
||||
if obj.reception_steps != 'one_step':
|
||||
try:
|
||||
all_products_categ = data_obj.get_object_reference(cr, uid, 'product', 'product_category_all')[1]
|
||||
except:
|
||||
all_products_categ = self.pool.get('product.category').search(cr, uid, [('parent_id', '=', False)], context=context)
|
||||
all_products_categ = all_products_categ and all_products_categ[0] or False
|
||||
if not all_products_categ:
|
||||
raise osv.except_osv(_('Error!'), _('Can\'t find the product category for the reception in several steps. The wizard cannot be used.'))
|
||||
|
||||
route_name, values = routes_dict[obj.reception_steps]
|
||||
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,
|
||||
}, context=context)
|
||||
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,
|
||||
}
|
||||
push_obj.create(cr, uid, vals=push_data, context=context)
|
||||
|
||||
self.pool.get('product.category').write(cr, uid, all_products_categ, {'route_ids': [(4, new_route_id)]}, context=context)
|
||||
|
||||
#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[obj.delivery_steps]
|
||||
route_obj.write(cr, uid, default_route_id, {'name': self._format_routename(cr, uid, warehouse, route_name, context=context)}, context=context)
|
||||
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,
|
||||
})
|
||||
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': default_route_id,
|
||||
'action': 'move',
|
||||
'picking_type_id': pick_type_id,
|
||||
'procure_method': first_rule is True and 'make_to_stock' or 'make_to_order',
|
||||
}, 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,
|
||||
}, context=context)
|
||||
first_rule = False
|
||||
|
||||
#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={
|
||||
'name': self._format_routename(cr, uid, warehouse, route_name, context=context),
|
||||
'warehouse_selectable': False,
|
||||
'product_selectable': True,
|
||||
'product_categ_selectable': True,
|
||||
})
|
||||
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
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="stock_configure_wh" model="ir.ui.view">
|
||||
<field name="name">Configure Warehouse</field>
|
||||
<field name="model">stock.configure.wh</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Configure Warehouse" version="7.0">
|
||||
<sheet>
|
||||
<group string="Warehouse Information" colspan="4">
|
||||
<field name="code"/>
|
||||
</group>
|
||||
<group string="Logistics Information" colspan="4">
|
||||
<field name="reception_steps" widget='radio'/>
|
||||
<field name="delivery_steps" on_change="onchange_delivery_steps(delivery_steps)" widget='radio'/>
|
||||
<field name="packing" attrs="{'readonly': [('delivery_steps', '==', 'pick_pack_ship')]}"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="configure_wh" string="Configure Warehouse" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_stock_configure_wh" model="ir.actions.act_window">
|
||||
<field name="name">Configure Warehouse</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.configure.wh</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="stock_configure_wh"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user