X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fstock%2Fstock.py;h=dd04132303374329a86f4dca770314f0d3e8bad5;hb=abff9e1a2577ace9ae38426defd911732c9b7c12;hp=96cabbf1cce90c6caae60401fee0a10d929fda3a;hpb=21f2f7c1128668fb6d2a15b054340bea66d71668;p=odoo%2Fodoo.git diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 96cabbf..dd04132 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -510,9 +510,13 @@ class stock_tracking(osv.osv): return self.name_get(cr, user, ids, context) def name_get(self, cr, uid, ids, context=None): + """Append the serial to the name""" if not len(ids): return [] - res = [(r['id'], r['name']+' ['+(r['serial'] or '')+']') for r in self.read(cr, uid, ids, ['name', 'serial'], context)] + res = [ (r['id'], r['serial'] and '%s [%s]' % (r['name'], r['serial']) + or r['name'] ) + for r in self.read(cr, uid, ids, ['name', 'serial'], + context=context) ] return res def unlink(self, cr, uid, ids, context=None): @@ -709,6 +713,15 @@ class stock_picking(osv.osv): for move in picking_obj.move_lines: move_obj.write(cr, uid, [move.id], {'tracking_id': False,'prodlot_id':False, 'move_history_ids2': [(6, 0, [])], 'move_history_ids': [(6, 0, [])]}) return res + + def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False): + if view_type == 'form' and not view_id: + mod_obj = self.pool.get('ir.model.data') + if self._name == "stock.picking.in": + model,view_id = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_in_form') + if self._name == "stock.picking.out": + model,view_id = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_out_form') + return super(stock_picking,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) def onchange_partner_in(self, cr, uid, context=None, partner_id=None): return {} @@ -720,16 +733,16 @@ class stock_picking(osv.osv): """ Confirms picking. @return: True """ + pickings = self.browse(cr, uid, ids, context=context) + for picking in pickings: + if picking.state <> 'confirmed': + self.confirm_send_note(cr, uid, [picking.id], context=context) self.write(cr, uid, ids, {'state': 'confirmed'}) todo = [] - for picking in self.browse(cr, uid, ids, context=context): - if picking.state == 'confirmed': - self.confirm_send_note(cr, uid, ids, context=context) + for picking in pickings: for r in picking.move_lines: if r.state == 'draft': todo.append(r.id) - - todo = self.action_explode(cr, uid, todo, context) if len(todo): self.pool.get('stock.move').action_confirm(cr, uid, todo, context=context) @@ -1163,8 +1176,9 @@ class stock_picking(osv.osv): return True for move in pick.move_lines: if move.state == 'done': - raise osv.except_osv(_('Error!'), _('You cannot cancel picking because stock move is in done state!')) + raise osv.except_osv(_('Error!'), _('You cannot cancel the picking as some moves have been done. You should cancel the picking lines.')) return True + def unlink(self, cr, uid, ids, context=None): move_obj = self.pool.get('stock.move') if context is None: @@ -1264,9 +1278,14 @@ class stock_picking(osv.osv): for move in too_few: product_qty = move_product_qty[move.id] if not new_picking: + new_picking_name = pick.name + self.write(cr, uid, [pick.id], + {'name': sequence_obj.get(cr, uid, + 'stock.picking.%s'%(pick.type)), + }) new_picking = self.copy(cr, uid, pick.id, { - 'name': sequence_obj.get(cr, uid, 'stock.picking.%s'%(pick.type)), + 'name': new_picking_name, 'move_lines' : [], 'state':'draft', }) @@ -1286,9 +1305,10 @@ class stock_picking(osv.osv): move_obj.copy(cr, uid, move.id, defaults) move_obj.write(cr, uid, [move.id], { - 'product_qty' : move.product_qty - partial_qty[move.id], + 'product_qty': move.product_qty - partial_qty[move.id], 'product_uos_qty': move.product_qty - partial_qty[move.id], #TODO: put correct uos_qty - + 'prodlot_id': False, + 'tracking_id': False, }) if new_picking: @@ -1378,64 +1398,40 @@ class stock_picking(osv.osv): # OpenChatter methods and notifications # ----------------------------------------- - def _get_thread_model(self, cr, uid, ids, context=None): - for obj in self.browse(cr, uid, ids, context=context): - if obj.type in ('out', 'in'): - context.update({'thread_model': 'stock.picking.' + obj.type}) - return True - - def _get_document_type(self, type): + def _get_document_type(self, cr, uid, obj, context=None): type_dict = { - 'out': 'Delivery order', - 'in': 'Shipment', - 'internal': 'Internal picking', + 'out': _('Delivery order'), + 'in': _('Shipment'), + 'internal': _('Internal picking'), } - return type_dict.get(type, 'Stock picking') + return type_dict.get(obj.type, _('Picking')) def create_send_note(self, cr, uid, ids, context=None): - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(obj.type)), context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been created.") % (self._get_document_type(cr, uid, obj, context=context)), context=context) def confirm_send_note(self, cr, uid, ids, context=None): - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been confirmed.") % (self._get_document_type(obj.type)), context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been confirmed.") % (self._get_document_type(cr, uid, obj, context=context)), context=context) def scrap_send_note(self, cr, uid, ids, quantity, uom, name, context=None): - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) return self.message_post(cr, uid, ids, body= _("%s %s %s has been moved to scrap.") % (quantity, uom, name), context=context) def back_order_send_note(self, cr, uid, ids, back_name, context=None): - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) return self.message_post(cr, uid, ids, body=_("Back order %s has been created.") % (back_name), context=context) def ship_done_send_note(self, cr, uid, ids, context=None): type_dict = { - 'out': 'delivered', - 'in': 'received', - 'internal': 'moved', + 'out': _("Products have been delivered."), + 'in': _("Products have been received."), + 'internal': _("Products have been moved."), } - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("Products have been %s.") % (type_dict.get(obj.type, 'move done')), context=context) + self.message_post(cr, uid, [obj.id], body=type_dict.get(obj.type, _('Products have been moved.')), context=context) def ship_cancel_send_note(self, cr, uid, ids, context=None): - if context is None: - context = {} - self._get_thread_model(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(obj.type)), context=context) + self.message_post(cr, uid, [obj.id], body=_("%s has been cancelled.") % (self._get_document_type(cr, uid, obj, context=context)), context=context) stock_picking() @@ -1522,7 +1518,7 @@ class stock_production_lot(osv.osv): 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]), 'date': fields.datetime('Creation Date', required=True), 'stock_available': fields.function(_get_stock, fnct_search=_stock_search, type="float", string="Available", select=True, - help="Current quantity of products with this Production Lot Number available in company warehouses", + help="Current quantity of products with this Serial Number available in company warehouses", digits_compute=dp.get_precision('Product Unit of Measure')), 'revisions': fields.one2many('stock.production.lot.revision', 'lot_id', 'Revisions'), 'company_id': fields.many2one('res.company', 'Company', select=True), @@ -1698,10 +1694,13 @@ class stock_move(osv.osv): 'scrapped': fields.related('location_dest_id','scrap_location',type='boolean',relation='stock.location',string='Scrapped', readonly=True), 'type': fields.related('picking_id', 'type', type='selection', selection=[('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], string='Shipping Type'), } + def _check_location(self, cr, uid, ids, context=None): for record in self.browse(cr, uid, ids, context=context): - if (record.state=='done') and (record.location_dest_id.usage == 'view' or record.location_id.usage == 'view'): - return False + if (record.state=='done') and (record.location_id.usage == 'view'): + raise osv.except_osv(_('Error'), _('You cannot move product %s from a location of type view %s.')% (record.product_id.name, record.location_id.name)) + if (record.state=='done') and (record.location_dest_id.usage == 'view' ): + raise osv.except_osv(_('Error'), _('You cannot move product %s to a location of type view %s.')% (record.product_id.name, record.location_dest_id.name)) return True _constraints = [ @@ -1777,7 +1776,7 @@ class stock_move(osv.osv): return user.company_id.partner_id.id def _default_move_type(self, cr, uid, context=None): - """ Gets default type of move + """ Gets default type of move @return: type """ if context is None: @@ -1857,8 +1856,8 @@ class stock_move(osv.osv): warning = {} if (location.usage == 'internal') and (product_qty > (amount_actual or 0.0)): warning = { - 'title': _('Insufficient Stock in Lot !'), - 'message': _('You are moving %.2f %s products but only %.2f %s available in this lot.') % (product_qty, uom.name, amount_actual, uom.name) + 'title': _('Insufficient Stock for Serial Number !'), + 'message': _('You are moving %.2f %s but only %.2f %s available for this serial number.') % (product_qty, uom.name, amount_actual, uom.name) } return {'warning': warning} @@ -1938,7 +1937,8 @@ class stock_move(osv.osv): 'product_uom': product.uom_id.id, 'product_uos': uos_id, 'product_qty': 1.00, - 'product_uos_qty' : self.pool.get('stock.move').onchange_quantity(cr, uid, ids, prod_id, 1.00, product.uom_id.id, uos_id)['value']['product_uos_qty'] + 'product_uos_qty' : self.pool.get('stock.move').onchange_quantity(cr, uid, ids, prod_id, 1.00, product.uom_id.id, uos_id)['value']['product_uos_qty'], + 'prodlot_id' : False, } if not ids: result['name'] = product.partner_ref @@ -1958,9 +1958,9 @@ class stock_move(osv.osv): location_dest_id = False if type == 'in': location_source_id = 'stock_location_suppliers' - location_dest_id = 'stock_location_stock' + location_dest_id = 'stock_location_stock' elif type == 'out': - location_source_id = 'stock_location_stock' + location_source_id = 'stock_location_stock' location_dest_id = 'stock_location_customers' if location_source_id: try: @@ -2327,7 +2327,11 @@ class stock_move(osv.osv): or move.location_id.company_id != move.location_dest_id.company_id): journal_id, acc_src, acc_dest, acc_valuation = self._get_accounting_data_for_valuation(cr, uid, move, src_company_ctx) reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, src_company_ctx) - account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_dest, reference_amount, reference_currency_id, context))] + #returning goods to supplier + if move.location_dest_id.usage == 'supplier': + account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_src, reference_amount, reference_currency_id, context))] + else: + account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_valuation, acc_dest, reference_amount, reference_currency_id, context))] # Incoming moves (or cross-company input part) if move.location_dest_id.company_id \ @@ -2335,7 +2339,11 @@ class stock_move(osv.osv): or move.location_id.company_id != move.location_dest_id.company_id): journal_id, acc_src, acc_dest, acc_valuation = self._get_accounting_data_for_valuation(cr, uid, move, dest_company_ctx) reference_amount, reference_currency_id = self._get_reference_accounting_values_for_valuation(cr, uid, move, src_company_ctx) - account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_src, acc_valuation, reference_amount, reference_currency_id, context))] + #goods return from customer + if move.location_id.usage == 'customer': + account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_dest, acc_valuation, reference_amount, reference_currency_id, context))] + else: + account_moves += [(journal_id, self._create_account_move_line(cr, uid, move, acc_src, acc_valuation, reference_amount, reference_currency_id, context))] move_obj = self.pool.get('account.move') for j_id, move_lines in account_moves: @@ -2712,8 +2720,10 @@ class stock_move(osv.osv): complete.append(self.browse(cr, uid, new_move)) self.write(cr, uid, [move.id], { - 'product_qty' : move.product_qty - product_qty, - 'product_uos_qty':move.product_qty - product_qty, + 'product_qty': move.product_qty - product_qty, + 'product_uos_qty': move.product_qty - product_qty, + 'prodlot_id': False, + 'tracking_id': False, }) @@ -2899,11 +2909,11 @@ class stock_inventory_line(osv.osv): @return: Dictionary of changed values """ if not product: - return {'value': {'product_qty': 0.0, 'product_uom': False}} + return {'value': {'product_qty': 0.0, 'product_uom': False, 'prod_lot_id': False}} obj_product = self.pool.get('product.product').browse(cr, uid, product) uom = uom or obj_product.uom_id.id amount = self.pool.get('stock.location')._product_get(cr, uid, location_id, [product], {'uom': uom, 'to_date': to_date, 'compute_child': False})[product] - result = {'product_qty': amount, 'product_uom': uom} + result = {'product_qty': amount, 'product_uom': uom, 'prod_lot_id': False} return {'value': result} stock_inventory_line() @@ -2963,7 +2973,13 @@ class stock_picking_in(osv.osv): #instead of it's own workflow (which is not existing) return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context) + def _workflow_signal(self, cr, uid, ids, signal, context=None): + #override in order to fire the workflow signal on given stock.picking workflow instance + #instead of it's own workflow (which is not existing) + return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context) + _columns = { + 'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True), 'state': fields.selection( [('draft', 'Draft'), ('auto', 'Waiting Another Operation'), @@ -3002,7 +3018,13 @@ class stock_picking_out(osv.osv): #instead of it's own workflow (which is not existing) return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context) + def _workflow_signal(self, cr, uid, ids, signal, context=None): + #override in order to fire the workflow signal on given stock.picking workflow instance + #instead of it's own workflow (which is not existing) + return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context) + _columns = { + 'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True), 'state': fields.selection( [('draft', 'Draft'), ('auto', 'Waiting Another Operation'),