[MERGE] trunk-wms up to revision 9598

bzr revid: qdp-launchpad@openerp.com-20140317105915-7gl53kvduilf3fup
This commit is contained in:
Quentin (OpenERP) 2014-03-17 11:59:15 +01:00
commit 5b8bbb161b
2 changed files with 64 additions and 12 deletions

View File

@ -236,8 +236,8 @@ 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),
'location_id': fields.many2one('stock.location', 'Location', required=True),
'product_id': fields.many2one('product.product', 'Product', required=True, ondelete="restrict"),
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="restrict"),
'qty': fields.float('Quantity', required=True, help="Quantity of products in this quant, in the default unit of measure of the product"),
'package_id': fields.many2one('stock.quant.package', string='Package', help="The package containing this quant"),
'packaging_type_id': fields.related('package_id', 'packaging_id', type='many2one', relation='product.packaging', string='Type of packaging', store=True),
@ -587,6 +587,40 @@ class stock_quant(osv.osv):
raise osv.except_osv(_('Error'), _('You cannot move to a location of type view %s.') % (location.name))
return True
def _check_open_inventory_location(self, cr, uid, ids, context=None):
""" Check if there is an inventory running for the locations implied
"""
inventory_obj = self.pool.get('stock.inventory')
for quant in self.browse(cr, uid, ids, context=context):
loc = quant.location_id
parent_location_ids = []
while loc:
parent_location_ids.append(loc.id)
loc = loc.location_id
domain = [('state', '=', 'confirm'), ('location_id', 'in', parent_location_ids), '|', ('product_id', '=', False), ('product_id', '=', quant.product_id.id)]
domain += ['|', ('lot_id', '=', False), ('lot_id', '=', quant.lot_id.id)]
domain += ['|', ('partner_id', '=', False), ('partner_id', '=', quant.owner_id.id)]
domain += ['|', ('package_id', '=', False), ('package_id', '=', quant.package_id.id)]
inventory_ids = inventory_obj.search(cr, uid, domain, context=context)
if inventory_ids:
inventory = inventory_obj.browse(cr, uid, inventory_ids[0], context=context)
raise osv.except_osv(_('Error! Location on inventory'),
_('There exists an inventory conflicting with your operation :\n%s') % inventory.name)
return True
_constraints = [
(_check_open_inventory_location,
"A Physical Inventory is being conducted at this location", ['location_id']),
]
def write(self, cr, uid, ids, vals, context=None):
#check the inventory constraint before the write
if isinstance(ids, (int, long)):
ids = [ids]
if 'owner_id' in vals or 'lot_id' in vals or 'package_id' in vals or 'location_id' in vals or 'product_id' in vals:
self._check_open_inventory_location(cr, uid, ids, context=context)
return super(stock_quant, self).write(cr, uid, ids, vals, context=context)
#----------------------------------------------------------
# Stock Picking
@ -1648,7 +1682,6 @@ class stock_move(osv.osv):
'propagate': True,
}
def copy_data(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
@ -2111,8 +2144,8 @@ class stock_move(osv.osv):
if move.propagate:
self.action_cancel(cr, uid, [move.move_dest_id.id], context=context)
elif move.move_dest_id.state == 'waiting':
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'})
return self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'}, context=context)
return self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False}, context=context)
def _check_package_from_moves(self, cr, uid, moves, context=None):
pack_obj = self.pool.get("stock.quant.package")
@ -2195,7 +2228,8 @@ class stock_move(osv.osv):
# Check the packages have been placed in the correct locations
self._check_package_from_moves(cr, uid, self.browse(cr, uid, ids, context=context), context=context)
# Apply on picking
self.write(cr, uid, ids, {'state': 'done', 'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
done_date = context.get('force_date', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT))
self.write(cr, uid, ids, {'state': 'done', 'date': done_date}, context=context)
self.pool.get('procurement.order').check(cr, uid, procurement_ids, context=context)
#check picking state to set the date_done is needed
done_picking = []
@ -2352,7 +2386,6 @@ class stock_inventory(osv.osv):
_columns = {
'name': fields.char('Inventory Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Name."),
'date': fields.datetime('Inventory Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Create Date."),
'date_done': fields.datetime('Date done', help="Inventory Validation Date."),
'line_ids': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', readonly=False, states={'done': [('readonly', True)]}, help="Inventory Lines."),
'move_ids': fields.one2many('stock.move', 'inventory_id', 'Created Moves', help="Inventory Moves.", states={'done': [('readonly', True)]}),
'state': fields.selection([('draft', 'Draft'), ('cancel', 'Cancelled'), ('confirm', 'In Progress'), ('done', 'Validated')], 'Status', readonly=True, select=True),
@ -2390,7 +2423,7 @@ class stock_inventory(osv.osv):
if default is None:
default = {}
default = default.copy()
default.update({'move_ids': [], 'date_done': False})
default.update({'move_ids': []})
return super(stock_inventory, self).copy(cr, uid, id, default, context=context)
def _inventory_line_hook(self, cr, uid, inventory_line, move_vals):
@ -2415,11 +2448,13 @@ class stock_inventory(osv.osv):
if not inv.move_ids:
self.action_check(cr, uid, [inv.id], context=context)
inv.refresh()
self.write(cr, uid, [inv.id], {'state': 'done'}, context=context)
#The inventory is posted as a single step which means quants cannot be moved from an internal location to another using an inventory
#as they will be moved to inventory loss, and other quants will be created to the encoded quant location. This is a normal behavior
#as quants cannot be reuse from inventory location (users can still manually move the products before/after the inventory if they want).
move_obj.action_done(cr, uid, [x.id for x in inv.move_ids], context=context)
self.write(cr, uid, [inv.id], {'state': 'done', 'date_done': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context)
ctx = context.copy()
ctx['force_date'] = inv.date
move_obj.action_done(cr, uid, [x.id for x in inv.move_ids], context=ctx)
return True
def _create_stock_move(self, cr, uid, inventory, todo_line, context=None):
@ -2482,9 +2517,24 @@ class stock_inventory(osv.osv):
def action_cancel_inventory(self, cr, uid, ids, context=None):
self.action_cancel_draft(cr, uid, ids, context=context)
def check_inventory_date(self, cr, uid, inventory, context=None):
domain = ['|', ('location_id', 'child_of', [inventory.location_id.id]), ('location_dest_id', 'child_of', [inventory.location_id.id]), ('date', '>', inventory.date), ('state', '!=', 'cancel')]
if inventory.product_id:
domain += [('product_id', '=', inventory.product_id.id)]
return self.pool.get('stock.move').search(cr, uid, domain, context=context)
def prepare_inventory(self, cr, uid, ids, context=None):
inventory_line_obj = self.pool.get('stock.inventory.line')
for inventory in self.browse(cr, uid, ids, context=context):
#check inventory start date is allowed
if inventory.date > time.strftime(DEFAULT_SERVER_DATETIME_FORMAT):
raise osv.except_osv(_('Error!'), _('It\'s impossible to confirm an inventory in the future. Please change the inventory date to proceed further.'))
conflicting_move_ids = self.check_inventory_date(cr, uid, inventory, context=context)
error_message = ""
for move in self.pool.get('stock.move').browse(cr, uid, conflicting_move_ids, context=context):
error_message += _("\n * Date: %s - %s %s - From: %s To: %s") % (move.date, move.product_uom_qty, move.product_uom.name, move.location_id.name, move.location_dest_id.name)
if conflicting_move_ids:
raise osv.except_osv(_('Error!'), _('There exists stock moves made/scheduled after the inventory date which are conflicting with its settings. Please cancel them or change the inventory date to proceed further.\n\n%s') % (error_message))
#clean the existing inventory lines before redoing an inventory proposal
line_ids = [line.id for line in inventory.line_ids]
inventory_line_obj.unlink(cr, uid, line_ids, context=context)

View File

@ -197,7 +197,7 @@ class stock_quant(osv.osv):
'quantity': qty,
'product_uom_id': move.product_id.uom_id.id,
'ref': move.picking_id and move.picking_id.name or False,
'date': time.strftime('%Y-%m-%d'),
'date': move.date,
'partner_id': partner_id,
'debit': valuation_amount > 0 and valuation_amount or 0,
'credit': valuation_amount < 0 and -valuation_amount or 0,
@ -209,7 +209,7 @@ class stock_quant(osv.osv):
'quantity': qty,
'product_uom_id': move.product_id.uom_id.id,
'ref': move.picking_id and move.picking_id.name or False,
'date': time.strftime('%Y-%m-%d'),
'date': move.date,
'partner_id': partner_id,
'credit': valuation_amount > 0 and valuation_amount or 0,
'debit': valuation_amount < 0 and -valuation_amount or 0,
@ -232,6 +232,8 @@ class stock_quant(osv.osv):
move_lines = self._prepare_account_move_line(cr, uid, move, quant_cost_qty[cost], cost, credit_account_id, debit_account_id, context=context)
return move_obj.create(cr, uid, {'journal_id': journal_id,
'line_id': move_lines,
'perdiod_id': self.pool.get('account.period').find(cr, uid, move.date, context=context)[0],
'date': move.date,
'ref': move.picking_id and move.picking_id.name}, context=context)
#def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):