From 0171fba1ceffae1dbbb4834e4c66c89dbf17a704 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Wed, 18 Jun 2014 12:23:02 +0200 Subject: [PATCH 1/6] [IMP] Make it possible to create sequences in a separate function + change names when some types are not created yet --- addons/stock/stock.py | 217 ++++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 105 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9c5310dcd6b..c678b27f4a6 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -3114,6 +3114,109 @@ class stock_warehouse(osv.osv): pull_obj.write(cr, uid, warehouse.mto_pull_id.id, mto_pull_vals, context=context) return True + def create_sequences_and_picking_types(self, cr, uid, warehouse, context=None): + seq_obj = self.pool.get('ir.sequence') + picking_type_obj = self.pool.get('stock.picking.type') + #create new sequences + in_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence in'), 'prefix': warehouse.code + '/IN/', 'padding': 5}, context=context) + out_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence out'), 'prefix': warehouse.code + '/OUT/', 'padding': 5}, context=context) + pack_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence packing'), 'prefix': warehouse.code + '/PACK/', 'padding': 5}, context=context) + pick_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence picking'), 'prefix': warehouse.code + '/PICK/', 'padding': 5}, context=context) + int_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': warehouse.name + _(' Sequence internal'), 'prefix': warehouse.code + '/INT/', 'padding': 5}, context=context) + + wh_stock_loc = warehouse.lot_stock_id + 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 + customer_loc, supplier_loc = self._get_partner_locations(cr, uid, warehouse.id, context=context) + + #create in, out, internal picking types for warehouse + 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 + + #choose the next available color for the picking types of this warehouse + color = 0 + available_colors = [c%9 for c in range(3, 12)] # put flashy colors first + all_used_colors = self.pool.get('stock.picking.type').search_read(cr, uid, [('warehouse_id', '!=', False), ('color', '!=', False)], ['color'], order='color') + #don't use sets to preserve the list order + for x in all_used_colors: + if x['color'] in available_colors: + available_colors.remove(x['color']) + if available_colors: + color = available_colors[0] + + #order the picking types with a sequence allowing to have the following suit for each warehouse: reception, internal, pick, pack, ship. + max_sequence = self.pool.get('stock.picking.type').search_read(cr, uid, [], ['sequence'], order='sequence desc') + max_sequence = max_sequence and max_sequence[0]['sequence'] or 0 + + in_type_id = picking_type_obj.create(cr, uid, vals={ + 'name': _('Receptions'), + 'warehouse_id': warehouse.id, + 'code': 'incoming', + 'sequence_id': in_seq_id, + 'default_location_src_id': supplier_loc.id, + 'default_location_dest_id': input_loc.id, + 'sequence': max_sequence + 1, + 'color': color}, context=context) + out_type_id = picking_type_obj.create(cr, uid, vals={ + 'name': _('Delivery Orders'), + 'warehouse_id': warehouse.id, + 'code': 'outgoing', + 'sequence_id': out_seq_id, + 'return_picking_type_id': in_type_id, + 'default_location_src_id': output_loc.id, + 'default_location_dest_id': customer_loc.id, + 'sequence': max_sequence + 4, + 'color': color}, context=context) + picking_type_obj.write(cr, uid, [in_type_id], {'return_picking_type_id': out_type_id}, context=context) + int_type_id = picking_type_obj.create(cr, uid, vals={ + 'name': _('Internal Transfers'), + 'warehouse_id': warehouse.id, + 'code': 'internal', + 'sequence_id': int_seq_id, + 'default_location_src_id': wh_stock_loc.id, + 'default_location_dest_id': wh_stock_loc.id, + 'active': True, + 'sequence': max_sequence + 2, + 'color': color}, context=context) + pack_type_id = picking_type_obj.create(cr, uid, vals={ + 'name': _('Pack'), + 'warehouse_id': warehouse.id, + 'code': 'internal', + 'sequence_id': pack_seq_id, + 'default_location_src_id': wh_pack_stock_loc.id, + 'default_location_dest_id': output_loc.id, + 'active': warehouse.delivery_steps == 'pick_pack_ship', + 'sequence': max_sequence + 3, + 'color': color}, context=context) + pick_type_id = picking_type_obj.create(cr, uid, vals={ + 'name': _('Pick'), + 'warehouse_id': warehouse.id, + 'code': 'internal', + 'sequence_id': pick_seq_id, + 'default_location_src_id': wh_stock_loc.id, + 'default_location_dest_id': wh_pack_stock_loc.id, + 'active': warehouse.delivery_steps != 'ship_only', + 'sequence': max_sequence + 2, + 'color': color}, 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, warehouse.id, vals=vals, context=context) + + def create(self, cr, uid, vals, context=None): if context is None: context = {} @@ -3153,108 +3256,10 @@ class stock_warehouse(osv.osv): }, context=context_with_inactive) vals[values['field']] = location_id - #create new sequences - in_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': vals.get('name', '') + _(' Sequence in'), 'prefix': vals.get('code', '') + '/IN/', 'padding': 5}, context=context) - out_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': vals.get('name', '') + _(' Sequence out'), 'prefix': vals.get('code', '') + '/OUT/', 'padding': 5}, context=context) - pack_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': vals.get('name', '') + _(' Sequence packing'), 'prefix': vals.get('code', '') + '/PACK/', 'padding': 5}, context=context) - pick_seq_id = seq_obj.create(cr, SUPERUSER_ID, values={'name': vals.get('name', '') + _(' Sequence picking'), 'prefix': vals.get('code', '') + '/PICK/', 'padding': 5}, context=context) - int_seq_id = seq_obj.create(cr, SUPERUSER_ID, 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) - warehouse = self.browse(cr, uid, new_id, context=context) - wh_stock_loc = warehouse.lot_stock_id - 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 - customer_loc, supplier_loc = self._get_partner_locations(cr, uid, new_id, context=context) - - #create in, out, internal picking types for warehouse - 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 - - #choose the next available color for the picking types of this warehouse - color = 0 - available_colors = [c%9 for c in range(3, 12)] # put flashy colors first - all_used_colors = self.pool.get('stock.picking.type').search_read(cr, uid, [('warehouse_id', '!=', False), ('color', '!=', False)], ['color'], order='color') - #don't use sets to preserve the list order - for x in all_used_colors: - if x['color'] in available_colors: - available_colors.remove(x['color']) - if available_colors: - color = available_colors[0] - - #order the picking types with a sequence allowing to have the following suit for each warehouse: reception, internal, pick, pack, ship. - max_sequence = self.pool.get('stock.picking.type').search_read(cr, uid, [], ['sequence'], order='sequence desc') - max_sequence = max_sequence and max_sequence[0]['sequence'] or 0 - - in_type_id = picking_type_obj.create(cr, uid, vals={ - 'name': _('Receptions'), - 'warehouse_id': new_id, - 'code': 'incoming', - 'sequence_id': in_seq_id, - 'default_location_src_id': supplier_loc.id, - 'default_location_dest_id': input_loc.id, - 'sequence': max_sequence + 1, - 'color': color}, context=context) - out_type_id = picking_type_obj.create(cr, uid, vals={ - 'name': _('Delivery Orders'), - 'warehouse_id': new_id, - 'code': 'outgoing', - 'sequence_id': out_seq_id, - 'return_picking_type_id': in_type_id, - 'default_location_src_id': output_loc.id, - 'default_location_dest_id': customer_loc.id, - 'sequence': max_sequence + 4, - 'color': color}, context=context) - picking_type_obj.write(cr, uid, [in_type_id], {'return_picking_type_id': out_type_id}, context=context) - int_type_id = picking_type_obj.create(cr, uid, vals={ - 'name': _('Internal Transfers'), - 'warehouse_id': new_id, - 'code': 'internal', - 'sequence_id': int_seq_id, - 'default_location_src_id': wh_stock_loc.id, - 'default_location_dest_id': wh_stock_loc.id, - 'active': True, - 'sequence': max_sequence + 2, - 'color': color}, context=context) - pack_type_id = picking_type_obj.create(cr, uid, vals={ - 'name': _('Pack'), - 'warehouse_id': new_id, - 'code': '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', - 'sequence': max_sequence + 3, - 'color': color}, context=context) - pick_type_id = picking_type_obj.create(cr, uid, vals={ - 'name': _('Pick'), - 'warehouse_id': new_id, - 'code': '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', - 'sequence': max_sequence + 2, - 'color': color}, 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) + self.create_sequences_and_picking_types(cr, uid, warehouse, context=context) warehouse.refresh() #create routes and push/pull rules @@ -3298,7 +3303,8 @@ class stock_warehouse(osv.osv): for push in route.push_ids: push_obj.write(cr, uid, push.id, {'name': pull.name.replace(warehouse.name, name, 1)}, context=context) #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) + if warehouse.mto_pull_id.id: + pull_obj.write(cr, uid, warehouse.mto_pull_id.id, {'name': warehouse.mto_pull_id.name.replace(warehouse.name, name, 1)}, context=context) def _check_delivery_resupply(self, cr, uid, warehouse, new_location, change_to_multiple, context=None): """ Will check if the resupply routes from this warehouse follow the changes of number of delivery steps """ @@ -3380,11 +3386,12 @@ class stock_warehouse(osv.osv): if vals.get('name'): name = vals.get('name', warehouse.name) self._handle_renaming(cr, uid, warehouse, name, vals.get('code', warehouse.code), 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) + if warehouse.in_type_id: + 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) if vals.get('resupply_wh_ids') and not vals.get('resupply_route_ids'): for cmd in vals.get('resupply_wh_ids'): if cmd[0] == 6: From 403fefc25204fb547e66082ce7611bebe37d629b Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 23 Jun 2014 09:30:42 +0200 Subject: [PATCH 2/6] [IMP] default priority if no moves in picking --- addons/stock/stock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index c678b27f4a6..8f9cdff8165 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -635,7 +635,7 @@ class stock_picking(osv.osv): """ res = {} for id in ids: - res[id] = {'min_date': False, 'max_date': False} + res[id] = {'min_date': False, 'max_date': False, 'priority': '1'} if not ids: return res cr.execute("""select From c9f247daeacd79df2ce5e686211613e23cf61002 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 23 Jun 2014 10:03:56 +0200 Subject: [PATCH 3/6] [IMP] Check inventory valuation fields --- addons/stock/product.py | 6 ------ addons/stock_account/product.py | 16 +++++++++------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/addons/stock/product.py b/addons/stock/product.py index 1cd677706f6..a173647bed9 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -324,11 +324,6 @@ class product_template(osv.osv): return res _columns = { - 'valuation':fields.selection([('manual_periodic', 'Periodical (manual)'), - ('real_time','Real Time (automated)'),], 'Inventory Valuation', - help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves." \ - "The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products." - , required=True), 'type': fields.selection([('product', 'Stockable Product'), ('consu', 'Consumable'), ('service', 'Service')], 'Product Type', required=True, help="Consumable: Will not imply stock management for this product. \nStockable product: Will imply stock management for this product."), 'property_stock_procurement': fields.property( type='many2one', @@ -376,7 +371,6 @@ class product_template(osv.osv): _defaults = { 'sale_delay': 7, - 'valuation': 'manual_periodic', } def action_view_routes(self, cr, uid, ids, context=None): diff --git a/addons/stock_account/product.py b/addons/stock_account/product.py index b043fc4094b..807c5bc08fc 100644 --- a/addons/stock_account/product.py +++ b/addons/stock_account/product.py @@ -114,19 +114,16 @@ class product_product(osv.osv): self.write(cr, uid, rec_id, {'standard_price': new_price}) return True + +class product_template(osv.osv): + _name = 'product.template' + _inherit = 'product.template' _columns = { 'valuation': fields.property(type='selection', selection=[('manual_periodic', 'Periodical (manual)'), ('real_time', 'Real Time (automated)')], string='Inventory Valuation', help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves, with product price as specified by the 'Costing Method'" \ "The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products." , required=True), - } - - -class product_template(osv.osv): - _name = 'product.template' - _inherit = 'product.template' - _columns = { 'cost_method': fields.property(type='selection', selection=[('standard', 'Standard Price'), ('average', 'Average Price'), ('real', 'Real Price')], help="""Standard Price: The cost price is manually updated at the end of a specific period (usually every year). Average Price: The cost price is recomputed at each incoming shipment and used for the product valuation. @@ -145,6 +142,11 @@ class product_template(osv.osv): help="When doing real-time inventory valuation, counterpart journal items for all outgoing stock moves will be posted in this account, unless " "there is a specific valuation account set on the destination location. When not set on the product, the one from the product category is used."), } + + _defaults = { + 'valuation': 'manual_periodic', + 'cost_method': 'standard', + } class product_category(osv.osv): From 56c669b9b37a9d08b3dfd35b611cf06e6fa21e7a Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 23 Jun 2014 10:25:49 +0200 Subject: [PATCH 4/6] [FIX] Default valuation has to be on product template --- addons/stock_account/product.py | 5 ----- addons/stock_account/stock_account_data.xml | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/addons/stock_account/product.py b/addons/stock_account/product.py index 807c5bc08fc..cdab10af624 100644 --- a/addons/stock_account/product.py +++ b/addons/stock_account/product.py @@ -142,11 +142,6 @@ class product_template(osv.osv): help="When doing real-time inventory valuation, counterpart journal items for all outgoing stock moves will be posted in this account, unless " "there is a specific valuation account set on the destination location. When not set on the product, the one from the product category is used."), } - - _defaults = { - 'valuation': 'manual_periodic', - 'cost_method': 'standard', - } class product_category(osv.osv): diff --git a/addons/stock_account/stock_account_data.xml b/addons/stock_account/stock_account_data.xml index 4dea1742498..8723d11c9d3 100644 --- a/addons/stock_account/stock_account_data.xml +++ b/addons/stock_account/stock_account_data.xml @@ -22,7 +22,7 @@ Valuation Property - + manual_periodic selection From 6416fee88d8e9dbba0f78733f15bfb9932105398 Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 23 Jun 2014 11:17:10 +0200 Subject: [PATCH 5/6] [IMP] Put indices on quant and package --- addons/stock/stock.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 1679cf88a67..0bc0f92f1af 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -272,25 +272,25 @@ class stock_quant(osv.osv): _columns = { 'name': fields.function(_get_quant_name, type='char', string='Identifier'), - 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete="restrict", readonly=True), - 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="restrict", readonly=True), - 'qty': fields.float('Quantity', required=True, help="Quantity of products in this quant, in the default unit of measure of the product", readonly=True), - 'package_id': fields.many2one('stock.quant.package', string='Package', help="The package containing this quant", readonly=True), + 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete="restrict", readonly=True, select=True), + 'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="restrict", readonly=True, select=True), + 'qty': fields.float('Quantity', required=True, help="Quantity of products in this quant, in the default unit of measure of the product", readonly=True, select=True), + 'package_id': fields.many2one('stock.quant.package', string='Package', help="The package containing this quant", readonly=True, select=True), 'packaging_type_id': fields.related('package_id', 'packaging_id', type='many2one', relation='product.packaging', string='Type of packaging', readonly=True, store=True), - 'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="The move the quant is reserved for", readonly=True), - 'lot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True), + 'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="The move the quant is reserved for", readonly=True, select=True), + 'lot_id': fields.many2one('stock.production.lot', 'Lot', readonly=True, select=True), 'cost': fields.float('Unit Cost'), - 'owner_id': fields.many2one('res.partner', 'Owner', help="This is the owner of the quant", readonly=True), + 'owner_id': fields.many2one('res.partner', 'Owner', help="This is the owner of the quant", readonly=True, select=True), 'create_date': fields.datetime('Creation Date', readonly=True), - 'in_date': fields.datetime('Incoming Date', readonly=True), + 'in_date': fields.datetime('Incoming Date', readonly=True, select=True), 'history_ids': fields.many2many('stock.move', 'stock_quant_move_rel', 'quant_id', 'move_id', 'Moves', help='Moves that operate(d) on this quant'), - 'company_id': fields.many2one('res.company', 'Company', help="The company to which the quants belong", required=True, readonly=True), + 'company_id': fields.many2one('res.company', 'Company', help="The company to which the quants belong", required=True, readonly=True, select=True), 'inventory_value': fields.function(_calc_inventory_value, string="Inventory Value", type='float', readonly=True), # Used for negative quants to reconcile after compensated by a new positive one - 'propagated_from_id': fields.many2one('stock.quant', 'Linked Quant', help='The negative quant this is coming from', readonly=True), + 'propagated_from_id': fields.many2one('stock.quant', 'Linked Quant', help='The negative quant this is coming from', readonly=True, select=True), 'negative_move_id': fields.many2one('stock.move', 'Move Negative Quant', help='If this is a negative quant, this will be the move that caused this negative quant.', readonly=True), 'negative_dest_location_id': fields.related('negative_move_id', 'location_dest_id', type='many2one', relation='stock.location', string="Negative Destination Location", readonly=True, help="Technical field used to record the destination location of a move that created a negative quant"), @@ -3598,13 +3598,13 @@ class stock_package(osv.osv): 'complete_name': fields.function(_complete_name, type='char', string="Package Name",), 'parent_left': fields.integer('Left Parent', select=1), 'parent_right': fields.integer('Right Parent', select=1), - 'packaging_id': fields.many2one('product.packaging', 'Packaging', help="This field should be completed only if everything inside the package share the same product, otherwise it doesn't really makes sense."), + 'packaging_id': fields.many2one('product.packaging', 'Packaging', help="This field should be completed only if everything inside the package share the same product, otherwise it doesn't really makes sense.", select=True), 'ul_id': fields.many2one('product.ul', 'Logistic Unit'), 'location_id': fields.function(_get_package_info, type='many2one', relation='stock.location', string='Location', multi="package", store={ 'stock.quant': (_get_packages, ['location_id'], 10), 'stock.quant.package': (_get_packages_to_relocate, ['quant_ids', 'children_ids', 'parent_id'], 10), - }, readonly=True), + }, readonly=True, select=True), 'quant_ids': fields.one2many('stock.quant', 'package_id', 'Bulk Content', readonly=True), 'parent_id': fields.many2one('stock.quant.package', 'Parent Package', help="The package containing this item", ondelete='restrict', readonly=True), 'children_ids': fields.one2many('stock.quant.package', 'parent_id', 'Contained Packages', readonly=True), @@ -3612,12 +3612,12 @@ class stock_package(osv.osv): store={ 'stock.quant': (_get_packages, ['company_id'], 10), 'stock.quant.package': (_get_packages_to_relocate, ['quant_ids', 'children_ids', 'parent_id'], 10), - }, readonly=True), + }, readonly=True, select=True), 'owner_id': fields.function(_get_package_info, type='many2one', relation='res.partner', string='Owner', multi="package", store={ 'stock.quant': (_get_packages, ['owner_id'], 10), 'stock.quant.package': (_get_packages_to_relocate, ['quant_ids', 'children_ids', 'parent_id'], 10), - }, readonly=True), + }, readonly=True, select=True), } _defaults = { 'name': lambda self, cr, uid, context: self.pool.get('ir.sequence').get(cr, uid, 'stock.quant.package') or _('Unknown Pack') From 5ecde0fa265e7f130adafcaf39400dcfe414d7dc Mon Sep 17 00:00:00 2001 From: Josse Colpaert Date: Mon, 23 Jun 2014 15:23:20 +0200 Subject: [PATCH 6/6] [IMP] Tristates should be working even if the picking has no name --- addons/calendar/calendar.py | 1 - addons/stock/stock.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index b6473a7f1a7..7108a2d1d73 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -762,7 +762,6 @@ class calendar_event(osv.Model): res[meeting_id][field] = meeting.start_date if meeting.allday else meeting.start_datetime elif field == 'stop': res[meeting_id][field] = meeting.stop_date if meeting.allday else meeting.stop_datetime - return res def _get_rulestring(self, cr, uid, ids, name, arg, context=None): diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 0bc0f92f1af..ed8c946d78a 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -4094,11 +4094,11 @@ class stock_picking_type(osv.osv): tristates = [] for picking in picking_obj.browse(cr, uid, picking_ids, context=context): if picking.date_done > picking.date: - tristates.insert(0, {'tooltip': picking.name + _(': Late'), 'value': -1}) + tristates.insert(0, {'tooltip': picking.name or '' + _(': Late'), 'value': -1}) elif picking.backorder_id: - tristates.insert(0, {'tooltip': picking.name + _(': Backorder exists'), 'value': 0}) + tristates.insert(0, {'tooltip': picking.name or '' + _(': Backorder exists'), 'value': 0}) else: - tristates.insert(0, {'tooltip': picking.name + _(': OK'), 'value': 1}) + tristates.insert(0, {'tooltip': picking.name or '' + _(': OK'), 'value': 1}) res[picking_type_id] = tristates return res