X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Fstock%2Fstock.py;h=ef6d0f3f8dc075fe77ec985455f613186d80d2f5;hb=411d6d931de034c29c07dfa1e46619b78e76182b;hp=fb1e4afd5b35aaaa6116b504508f870de7a70354;hpb=fb87569289b505ba4dc7b7e45ff7756e98e0480c;p=odoo%2Fodoo.git diff --git a/addons/stock/stock.py b/addons/stock/stock.py index fb1e4af..ef6d0f3 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -243,7 +243,7 @@ class stock_location(osv.osv): elif location.chained_location_type == 'fixed': result = location.chained_location_id if result: - return result, location.chained_auto_packing, location.chained_delay, location.chained_journal_id and location.chained_journal_id.id or False, location.chained_company_id and location.chained_company_id.id or False, location.chained_picking_type + return result, location.chained_auto_packing, location.chained_delay, location.chained_journal_id and location.chained_journal_id.id or False, location.chained_company_id and location.chained_company_id.id or False, location.chained_picking_type, False return result def picking_type_get(self, cr, uid, from_location, to_location, context=None): @@ -425,7 +425,7 @@ class stock_location(osv.osv): # so we ROLLBACK to the SAVEPOINT to restore the transaction to its earlier # state, we return False as if the products were not available, and log it: cr.execute("ROLLBACK TO stock_location_product_reserve") - _logger.warn("Failed attempt to reserve %s x product %s, likely due to another transaction already in progress. Next attempt is likely to work. Detailed error available at DEBUG level.", product_qty, product_id) + _logger.warning("Failed attempt to reserve %s x product %s, likely due to another transaction already in progress. Next attempt is likely to work. Detailed error available at DEBUG level.", product_qty, product_id) _logger.debug("Trace of the failed product reservation attempt: ", exc_info=True) return False @@ -618,7 +618,7 @@ class stock_picking(osv.osv): def create(self, cr, user, vals, context=None): if ('name' not in vals) or (vals.get('name')=='/'): - seq_obj_name = 'stock.picking.' + vals['type'] + seq_obj_name = self._name vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name) new_id = super(stock_picking, self).create(cr, user, vals, context) if new_id: @@ -629,7 +629,7 @@ class stock_picking(osv.osv): 'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'origin': fields.char('Source Document', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True), 'backorder_id': fields.many2one('stock.picking', '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), - 'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, readonly=True, help="Shipping type specify, goods coming in or going out."), + 'type': fields.selection([('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."), 'note': fields.text('Notes', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'stock_journal_id': fields.many2one('stock.journal','Stock Journal', select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'location_id': fields.many2one('stock.location', 'Location', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Keep empty if you produce at the location where the finished products are needed." \ @@ -653,9 +653,9 @@ class stock_picking(osv.osv): * Cancelled: has been cancelled, can't be confirmed anymore""" ), 'min_date': fields.function(get_min_max_date, fnct_inv=_set_minimum_date, multi="min_max_date", - store=True, type='datetime', string='Scheduled Date', select=1, help="Scheduled date for the shipment to be processed"), - 'date': fields.datetime('Date', help="Creation date, usually the date of the order.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), - 'date_done': fields.datetime('Date Done', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), + store=True, type='datetime', string='Scheduled Time', select=1, help="Scheduled time for the shipment to be processed"), + 'date': fields.datetime('Time', help="Creation time, usually the time of the order.", select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), + 'date_done': fields.datetime('Date of Transfer', help="Date of Completion", states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}), 'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date", store=True, type='datetime', string='Max. Expected Date', select=2), 'move_lines': fields.one2many('stock.move', 'picking_id', 'Internal Moves', states={'done': [('readonly', True)], 'cancel': [('readonly', True)]}), @@ -712,7 +712,7 @@ class stock_picking(osv.osv): default['name'] = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name) default['origin'] = '' default['backorder_id'] = False - if picking_obj.invoice_state == 'invoiced': + if 'invoice_state' not in default and picking_obj.invoice_state == 'invoiced': default['invoice_state'] = '2binvoiced' res=super(stock_picking, self).copy(cr, uid, id, default, context) if res: @@ -730,7 +730,7 @@ class stock_picking(osv.osv): 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): + def onchange_partner_in(self, cr, uid, ids, partner_id=None, context=None): return {} def action_explode(self, cr, uid, moves, context=None): @@ -1023,8 +1023,10 @@ class stock_picking(osv.osv): partner = self.pool.get('res.partner').browse(cr, uid, partner, context=context) if inv_type in ('out_invoice', 'out_refund'): account_id = partner.property_account_receivable.id + payment_term = partner.property_payment_term.id or False else: account_id = partner.property_account_payable.id + payment_term = partner.property_supplier_payment_term.id or False comment = self._get_comment_invoice(cr, uid, picking) invoice_vals = { 'name': picking.name, @@ -1033,7 +1035,7 @@ class stock_picking(osv.osv): 'account_id': account_id, 'partner_id': partner.id, 'comment': comment, - 'payment_term': partner.property_payment_term and partner.property_payment_term.id or False, + 'payment_term': payment_term, 'fiscal_position': partner.property_account_position.id, 'date_invoice': context.get('date_inv', False), 'company_id': picking.company_id.id, @@ -1142,6 +1144,9 @@ class stock_picking(osv.osv): for move_line in picking.move_lines: if move_line.state == 'cancel': continue + if move_line.scrapped: + # do no invoice scrapped products + continue vals = self._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context) if vals: @@ -1351,14 +1356,14 @@ class stock_picking(osv.osv): wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr) # Then we finish the good picking self.write(cr, uid, [pick.id], {'backorder_id': new_picking}) - self.action_move(cr, uid, [new_picking]) + self.action_move(cr, uid, [new_picking], context=context) wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_done', cr) wf_service.trg_write(uid, 'stock.picking', pick.id, cr) delivered_pack_id = new_picking back_order_name = self.browse(cr, uid, delivered_pack_id, context=context).name self.back_order_send_note(cr, uid, ids, back_order_name, context) else: - self.action_move(cr, uid, [pick.id]) + self.action_move(cr, uid, [pick.id], context=context) wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_done', cr) delivered_pack_id = pick.id self.ship_done_send_note(cr, uid, ids, context) @@ -1393,6 +1398,14 @@ class stock_picking(osv.osv): """ if context is None: context = {} + lang_obj = self.pool.get('res.lang') + user_lang = self.pool.get('res.users').browse(cr, uid, uid, context=context).context_lang + lang_ids = lang_obj.search(cr, uid, [('code','like',user_lang)]) + if lang_ids: + date_format = lang_obj.browse(cr, uid, lang_ids[0], context=context).date_format + else: + date_format = '%m/%d/%Y' + for pick in self.browse(cr, uid, ids, context=context): msg='' if pick.auto_picking: @@ -1404,7 +1417,7 @@ class stock_picking(osv.osv): } message = type_list.get(pick.type, _('Document')) + " '" + (pick.name or '?') + "' " if pick.min_date: - msg= _(' for the ')+ datetime.strptime(pick.min_date, '%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y') + msg= _(' for the ')+ datetime.strptime(pick.min_date, '%Y-%m-%d %H:%M:%S').strftime(date_format) state_list = { 'confirmed': _('is scheduled %s.') % msg, 'assigned': _('is ready to process.'), @@ -1553,7 +1566,7 @@ class stock_production_lot(osv.osv): 'product_id': lambda x, y, z, c: c.get('product_id', False), } _sql_constraints = [ - ('name_ref_uniq', 'unique (name, ref)', 'The combination of serial number and internal reference must be unique !'), + ('name_ref_uniq', 'unique (name, ref)', 'The combination of Serial Number and internal reference must be unique !'), ] def action_traceability(self, cr, uid, ids, context=None): """ It traces the information of a product @@ -1566,6 +1579,13 @@ class stock_production_lot(osv.osv): """ value=self.pool.get('action.traceability').action_traceability(cr,uid,ids,context) return value + + def copy(self, cr, uid, id, default=None, context=None): + context = context or {} + default = default and default.copy() or {} + default.update(date=time.strftime('%Y-%m-%d %H:%M:%S'), move_ids=[]) + return super(stock_production_lot, self).copy(cr, uid, id, default=default, context=context) + stock_production_lot() class stock_production_lot_revision(osv.osv): @@ -1669,7 +1689,7 @@ class stock_move(osv.osv): return True _columns = { - 'name': fields.char('Name', size=250, required=True, select=True), + 'name': fields.char('Description', required=True, select=True), 'priority': fields.selection([('0', 'Not urgent'), ('1', 'Urgent')], 'Priority'), 'create_date': fields.datetime('Creation Date', readonly=True, select=True), 'date': fields.datetime('Date', required=True, select=True, help="Move date: scheduled date until move is done, then date of actual move processing", states={'done': [('readonly', True)]}), @@ -1845,7 +1865,7 @@ class stock_move(osv.osv): if move.state == 'done': if frozen_fields.intersection(vals): raise osv.except_osv(_('Operation forbidden !'), - _('Quantities, Unit of Measures, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).')) + _('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).')) return super(stock_move, self).write(cr, uid, ids, vals, context=context) def copy(self, cr, uid, id, default=None, context=None): @@ -2123,19 +2143,19 @@ class stock_move(osv.osv): old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id) if old_ptype != picking.type: old_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + old_ptype) - self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name}, context=context) + self.pool.get('stock.picking').write(cr, uid, [picking.id], {'name': old_pick_name, 'type': old_ptype}, context=context) else: pickid = False - for move, (loc, dummy, delay, dummy, company_id, ptype) in todo: + for move, (loc, dummy, delay, dummy, company_id, ptype, invoice_state) in todo: new_id = move_obj.copy(cr, uid, move.id, { 'location_id': move.location_dest_id.id, 'location_dest_id': loc.id, - 'date_moved': time.strftime('%Y-%m-%d'), + 'date': time.strftime('%Y-%m-%d'), 'picking_id': pickid, 'state': 'waiting', 'company_id': company_id or res_obj._company_default_get(cr, uid, 'stock.company', context=context) , 'move_history_ids': [], - 'date': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'), + 'date_expected': (datetime.strptime(move.date, '%Y-%m-%d %H:%M:%S') + relativedelta(days=delay or 0)).strftime('%Y-%m-%d'), 'move_history_ids2': []} ) move_obj.write(cr, uid, [move.id], { @@ -2433,14 +2453,17 @@ class stock_move(osv.osv): if move.picking_id: picking_ids.append(move.picking_id.id) if move.move_dest_id.id and (move.state != 'done'): - self.write(cr, uid, [move.id], {'move_history_ids': [(4, move.move_dest_id.id)]}) - #cr.execute('insert into stock_move_history_ids (parent_id,child_id) values (%s,%s)', (move.id, move.move_dest_id.id)) - if move.move_dest_id.state in ('waiting', 'confirmed'): - self.force_assign(cr, uid, [move.move_dest_id.id], context=context) - if move.move_dest_id.picking_id: - wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr) - if move.move_dest_id.auto_validate: - self.action_done(cr, uid, [move.move_dest_id.id], context=context) + # Downstream move should only be triggered if this move is the last pending upstream move + other_upstream_move_ids = self.search(cr, uid, [('id','!=',move.id),('state','not in',['done','cancel']), + ('move_dest_id','=',move.move_dest_id.id)], context=context) + if not other_upstream_move_ids: + self.write(cr, uid, [move.id], {'move_history_ids': [(4, move.move_dest_id.id)]}) + if move.move_dest_id.state in ('waiting', 'confirmed'): + self.force_assign(cr, uid, [move.move_dest_id.id], context=context) + if move.move_dest_id.picking_id: + wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr) + if move.move_dest_id.auto_validate: + self.action_done(cr, uid, [move.move_dest_id.id], context=context) self._create_product_valuation_moves(cr, uid, move, context=context) if move.state not in ('confirmed','done','assigned'): @@ -2868,14 +2891,14 @@ class stock_inventory(osv.osv): move_ids = [] for line in inv.inventory_line_id: pid = line.product_id.id - product_context.update(uom=line.product_uom.id, date=inv.date, prodlot_id=line.prod_lot_id.id) + product_context.update(uom=line.product_uom.id, to_date=inv.date, date=inv.date, prodlot_id=line.prod_lot_id.id) amount = location_obj._product_get(cr, uid, line.location_id.id, [pid], product_context)[pid] change = line.product_qty - amount lot_id = line.prod_lot_id.id if change: location_id = line.product_id.product_tmpl_id.property_stock_inventory.id value = { - 'name': 'INV:' + str(line.inventory_id.id) + ':' + line.inventory_id.name, + 'name': _('INV:') + (line.inventory_id.name or ''), 'product_id': line.product_id.id, 'product_uom': line.product_uom.id, 'prodlot_id': lot_id, @@ -3039,7 +3062,7 @@ class stock_picking_in(osv.osv): ('assigned', 'Ready to Receive'), ('done', 'Received'), ('cancel', 'Cancelled'),], - 'State', readonly=True, select=True, + 'Status', readonly=True, select=True, help="""* Draft: not confirmed yet and will not be scheduled until confirmed\n * Waiting Another Operation: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n * Waiting Availability: still waiting for the availability of products\n @@ -3084,7 +3107,7 @@ class stock_picking_out(osv.osv): ('assigned', 'Ready to Deliver'), ('done', 'Delivered'), ('cancel', 'Cancelled'),], - 'State', readonly=True, select=True, + 'Status', readonly=True, select=True, help="""* Draft: not confirmed yet and will not be scheduled until confirmed\n * Waiting Another Operation: waiting for another move to proceed before it becomes automatically available (e.g. in Make-To-Order flows)\n * Waiting Availability: still waiting for the availability of products\n