[WIP] stock: partial transfer and rereserve reimplementation
bzr revid: qdp-launchpad@openerp.com-20131118133650-gd5jx6tkjjrzha05
This commit is contained in:
parent
dde7550152
commit
436b46bf77
|
@ -134,10 +134,7 @@ class stock_location(osv.osv):
|
|||
categ = categ.parent_id
|
||||
categs.append(categ.id)
|
||||
|
||||
result = pa.search(cr,uid, [
|
||||
('location_id', '=', location.id),
|
||||
('product_categ_id', 'in', categs)
|
||||
], context=context)
|
||||
result = pa.search(cr, uid, [('location_id', '=', location.id), ('product_categ_id', 'in', categs)], context=context)
|
||||
if result:
|
||||
return pa.browse(cr, uid, result[0], context=context)
|
||||
|
||||
|
@ -149,10 +146,7 @@ class stock_location(osv.osv):
|
|||
categ = categ.parent_id
|
||||
categs.append(categ.id)
|
||||
|
||||
result = pr.search(cr,uid, [
|
||||
('location_id', '=', location.id),
|
||||
('product_categ_id', 'in', categs)
|
||||
], context=context)
|
||||
result = pr.search(cr, uid, [('location_id', '=', location.id), ('product_categ_id', 'in', categs)], context=context)
|
||||
if result:
|
||||
return pr.browse(cr, uid, result[0], context=context).method
|
||||
|
||||
|
@ -186,7 +180,6 @@ class stock_location_route(osv.osv):
|
|||
}
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Quants
|
||||
#----------------------------------------------------------
|
||||
|
@ -219,7 +212,6 @@ class stock_quant(osv.osv):
|
|||
'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),
|
||||
'reservation_id': fields.many2one('stock.move', 'Reserved for Move', help="The move the quant is reserved for"),
|
||||
'reservation_op_id': fields.many2one('stock.pack.operation', 'Reserved for Pack Operation', help="The operation the quant is reserved for"),
|
||||
'lot_id': fields.many2one('stock.production.lot', 'Lot'),
|
||||
'cost': fields.float('Unit Cost'),
|
||||
'owner_id': fields.many2one('res.partner', 'Owner', help="This is the owner of the quant"),
|
||||
|
@ -278,34 +270,65 @@ class stock_quant(osv.osv):
|
|||
if sum([q.qty for q in move.reserved_quant_ids]) == move.product_qty and move.state == 'confirmed':
|
||||
self.pool.get('stock.move').write(cr, uid, [move.id], {'state': 'assigned'}, context=context)
|
||||
|
||||
|
||||
# add location_dest_id in parameters (False=use the destination of the move)
|
||||
def quants_move(self, cr, uid, quants, move, lot_id=False, owner_id=False, package_id=False, context=None):
|
||||
"""Moves all given stock.quant in the destination location of the given move.
|
||||
:param quants: list of tuple(browse record(stock.quant) or None, quantity to move)
|
||||
:param move: browse record (stock.move)
|
||||
:param lot_id: ID of the lot that mus be set on the quants to move
|
||||
:param owner_id: ID of the partner that must own the quants to move
|
||||
:param package_id: ID of the package that must contains the quants to move
|
||||
"""
|
||||
for quant, qty in quants:
|
||||
#quant may be a browse record or None
|
||||
quant_record = self.move_single_quant(cr, uid, quant, qty, move, lot_id=lot_id, package_id=package_id, context=context)
|
||||
#quant_record is the quant newly created or already split
|
||||
self._quant_reconcile_negative(cr, uid, quant_record, context=context)
|
||||
|
||||
def check_preferred_location(self, cr, uid, move, context=None):
|
||||
if move.putaway_ids and move.putaway_ids[0]:
|
||||
#Take only first suggestion for the moment
|
||||
return move.putaway_ids[0].location_id
|
||||
return move.location_dest_id
|
||||
|
||||
def move_single_quant(self, cr, uid, quant, qty, move, lot_id=False, owner_id=False, package_id=False, context=None):
|
||||
if not quant:
|
||||
#If quant is None, we will create a quant to move (and potentially a negative counterpart too)
|
||||
quant = self._quant_create(cr, uid, qty, move, lot_id=lot_id, owner_id=owner_id, package_id=package_id, context=context)
|
||||
else:
|
||||
self._quant_split(cr, uid, quant, qty, context=context)
|
||||
# FP Note: improve this using preferred locations
|
||||
location_to = self.check_preferred_location(cr, uid, move, context=context)
|
||||
self.move_single_quant_tuple(cr, uid, quant, qty, move, context=context)
|
||||
|
||||
def check_preferred_location(self, cr, uid, move, qty, context=None):
|
||||
'''Checks the preferred location on the move, if any returned by a putaway strategy, and returns a list of
|
||||
tuple(location, qty) where the quant have to be moved
|
||||
|
||||
:param move: browse record (stock.move)
|
||||
:param qty: float
|
||||
:returns: list of tuple build as [(browe record (stock.move), float)]
|
||||
'''
|
||||
if move.putaway_ids:
|
||||
res = []
|
||||
for record in move.putaway_ids:
|
||||
res.append((record.location_id, record.quantity))
|
||||
return res
|
||||
return [(move.location_dest_id, qty)]
|
||||
|
||||
def move_single_quant(self, cr, uid, quant, location_to, qty, move, context=None):
|
||||
'''Moves the given 'quant' in 'location_to' for the given 'qty', and logs the stock.move that triggered this move in the quant history.
|
||||
If needed, the quant may be split if it's not totally moved.
|
||||
|
||||
:param quant: browse record (stock.quant)
|
||||
:param location_to: browse record (stock.location)
|
||||
:param qty: float
|
||||
:param move: browse record (stock.move)
|
||||
'''
|
||||
new_quant = self._quant_split(cr, uid, quant, qty, context=context)
|
||||
self.write(cr, SUPERUSER_ID, [quant.id], {
|
||||
'location_id': location_to.id,
|
||||
'history_ids': [(4, move.id)]
|
||||
})
|
||||
quant.refresh()
|
||||
return quant
|
||||
return new_quant
|
||||
|
||||
def move_single_quant_tuple(self, cr, uid, quant, qty, move, context=None):
|
||||
'''Effectively process the move of a tuple (quant record, qty to move). This may result in several quants moved
|
||||
if the preferred locations on the move say so but by default it will only move the quant record given as argument
|
||||
:param quant: browse record (stock.quant)
|
||||
:param qty: float
|
||||
:param move: browse record (stock.move)
|
||||
'''
|
||||
for location_to, qty in self.check_preferred_location(cr, uid, move, qty, context=context):
|
||||
if not quant:
|
||||
break
|
||||
new_quant = self.move_single_quant(cr, uid, quant, location_to, qty, move, context=context)
|
||||
self._quant_reconcile_negative(cr, uid, quant, context=context)
|
||||
quant = new_quant
|
||||
|
||||
def quants_get_prefered_domain(self, cr, uid, location, product, qty, domain=None, prefered_domain=False, fallback_domain=False, restrict_lot_id=False, restrict_partner_id=False, context=None):
|
||||
''' This function tries to find quants in the given location for the given domain, by trying to first limit
|
||||
|
@ -409,23 +432,6 @@ class stock_quant(osv.osv):
|
|||
move = m
|
||||
return move
|
||||
|
||||
#def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
|
||||
# move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
|
||||
# remaining_solving_quant = self._quant_split(cr, uid, quant, qty, context=context)
|
||||
# remaining_to_solve_quant = self._quant_split(cr, uid, to_solve_quant, qty, context=context)
|
||||
# remaining_neg_quant = self._quant_split(cr, uid, quant_neg, -qty, context=context)
|
||||
# #if the reconciliation was not complete, we need to link together the remaining parts
|
||||
# if remaining_to_solve_quant and remaining_neg_quant:
|
||||
# self.write(cr, uid, remaining_to_solve_quant.id, {'propagated_from_id': remaining_neg_quant.id}, context=context)
|
||||
# #delete the reconciled quants, as it is replaced by the solving quant
|
||||
# if remaining_neg_quant:
|
||||
# otherquant_ids = self.search(cr, uid, [('propagated_from_id', '=', quant_neg.id)], context=context)
|
||||
# self.write(cr, uid, otherquant_ids, {'propagated_from_id': remaining_neg_quant.id}, context=context)
|
||||
# self.unlink(cr, SUPERUSER_ID, [quant_neg.id, to_solve_quant.id], context=context)
|
||||
# #call move_single_quant to ensure recursivity if necessary and do the stock valuation
|
||||
# self.move_single_quant(cr, uid, quant, qty, move, context=context)
|
||||
# return remaining_solving_quant, remaining_to_solve_quant
|
||||
|
||||
def _quants_merge(self, cr, uid, solved_quant_ids, solving_quant, context=None):
|
||||
path = []
|
||||
for move in solving_quant.history_ids:
|
||||
|
@ -476,8 +482,6 @@ class stock_quant(osv.osv):
|
|||
self.unlink(cr, SUPERUSER_ID, [solving_quant.id], context=context)
|
||||
solving_quant = remaining_solving_quant
|
||||
|
||||
#solving_quant, dummy = self._reconcile_single_negative_quant(cr, uid, to_solve_quant, solving_quant, quant_neg, qty, context=context)
|
||||
|
||||
def _price_update(self, cr, uid, ids, newprice, context=None):
|
||||
self.write(cr, SUPERUSER_ID, ids, {'cost': newprice}, context=context)
|
||||
|
||||
|
@ -494,7 +498,7 @@ class stock_quant(osv.osv):
|
|||
|
||||
def quants_unreserve(self, cr, uid, move, context=None):
|
||||
related_quants = [x.id for x in move.reserved_quant_ids]
|
||||
return self.write(cr, SUPERUSER_ID, related_quants, {'reservation_id': False, 'reservation_op_id': False}, context=context)
|
||||
return self.write(cr, SUPERUSER_ID, related_quants, {'reservation_id': False}, context=context)
|
||||
|
||||
def _quants_get_order(self, cr, uid, location, product, quantity, domain=[], orderby='in_date', context=None):
|
||||
''' Implementation of removal strategies
|
||||
|
@ -608,7 +612,6 @@ class stock_picking(osv.osv):
|
|||
ptype_id = vals.get('picking_type_id', context.get('default_picking_type_id', False))
|
||||
sequence_id = self.pool.get('stock.picking.type').browse(cr, user, ptype_id, context=context).sequence_id.id
|
||||
vals['name'] = self.pool.get('ir.sequence').get_id(cr, user, sequence_id, 'id', context=context)
|
||||
|
||||
return super(stock_picking, self).create(cr, user, vals, context)
|
||||
|
||||
def _state_get(self, cr, uid, ids, field_name, arg, context=None):
|
||||
|
@ -708,7 +711,7 @@ class stock_picking(osv.osv):
|
|||
|
||||
'owner_id': fields.many2one('res.partner', 'Owner', help="Default Owner"),
|
||||
# Used to search on pickings
|
||||
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),#?
|
||||
'product_id': fields.related('move_lines', 'product_id', type='many2one', relation='product.product', string='Product'),
|
||||
'location_id': fields.related('move_lines', 'location_id', type='many2one', relation='stock.location', string='Location', readonly=True),
|
||||
'location_dest_id': fields.related('move_lines', 'location_dest_id', type='many2one', relation='stock.location', string='Destination Location', readonly=True),
|
||||
'group_id': fields.related('move_lines', 'group_id', type='many2one', relation='procurement.group', string='Procurement Group', readonly=True,
|
||||
|
@ -745,7 +748,6 @@ class stock_picking(osv.osv):
|
|||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
todo = []
|
||||
todo_force_assign = []
|
||||
|
||||
for picking in self.browse(cr, uid, ids, context=context):
|
||||
if picking.picking_type_id.auto_force_assign:
|
||||
todo_force_assign.append(picking.id)
|
||||
|
@ -859,8 +861,6 @@ class stock_picking(osv.osv):
|
|||
move_obj.unlink(cr, uid, ids2, context=context)
|
||||
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
# Methods for partial pickings
|
||||
|
||||
def _create_backorder(self, cr, uid, picking, backorder_moves=[], context=None):
|
||||
"""
|
||||
Move all non-done lines into a new backorder picking. If the key 'do_only_split' is given in the context, then move all lines not in context.get('split', []) instead of all non-done lines.
|
||||
|
@ -895,7 +895,8 @@ class stock_picking(osv.osv):
|
|||
quant_obj = self.pool.get("stock.quant")
|
||||
for picking in self.browse(cr, uid, picking_ids, context=context):
|
||||
for move in picking.move_lines:
|
||||
if move.state != 'assigned': continue
|
||||
if move.state != 'assigned':
|
||||
continue
|
||||
#Check which of the reserved quants are entirely in packages (can be in separate method)
|
||||
packages = list(set([x.package_id for x in move.reserved_quant_ids if x.package_id]))
|
||||
done_packages = []
|
||||
|
@ -1000,160 +1001,6 @@ class stock_picking(osv.osv):
|
|||
normalized_qty = uom_obj._compute_qty(cr, uid, op.product_uom_id.id, op.product_qty, op.product_id.uom_id.id)
|
||||
_create_link_for_product(op.product_id.id, normalized_qty)
|
||||
|
||||
|
||||
#def _reserve_quants_ops_move(self, cr, uid, ops, move, qty, create=False, context=None):
|
||||
# """
|
||||
# Will return the quantity that could not be reserved
|
||||
# """
|
||||
# quant_obj = self.pool.get("stock.quant")
|
||||
# op_obj = self.pool.get("stock.pack.operation")
|
||||
# if create and move.location_id.usage != 'internal':
|
||||
# # Create quants
|
||||
# quant = quant_obj._quant_create(cr, uid, qty, move, lot_id=ops.lot_id and ops.lot_id.id or False, owner_id=ops.owner_id and ops.owner_id.id or False, context=context)
|
||||
# quant.write({'reservation_op_id': ops.id, 'location_id': move.location_id.id})
|
||||
# quant_obj.quants_reserve(cr, uid, [(quant, qty)], move, context=context)
|
||||
# return 0
|
||||
# else:
|
||||
# #Quants get
|
||||
# dom = op_obj._get_domain(cr, uid, ops, context=context)
|
||||
# dom = dom + [('reservation_id', 'not in', [x.id for x in move.picking_id.move_lines])]
|
||||
# quants = quant_obj.quants_get_prefered_domain(cr, uid, move.location_id, move.product_id, qty, domain=dom, prefered_domain=[('reservation_id', '=', False)], fallback_domain=[('reservation_id', '!=', False)], context=context)
|
||||
# res_qty = qty
|
||||
# for quant in quants:
|
||||
# if quant[0]: # If quant can be reserved
|
||||
# res_qty -= quant[1]
|
||||
# quant_obj.quants_reserve(cr, uid, quants, move, context=context)
|
||||
# quant_obj.write(cr, SUPERUSER_ID, [x[0].id for x in quants if x[0]], {'reservation_op_id': ops.id}, context=context)
|
||||
# return res_qty
|
||||
|
||||
|
||||
|
||||
|
||||
### MEMO
|
||||
###remaining_qty sur move et pack sont des champ calculés grace à des one2many vers une nouvelle table(move_id, pack_id, qty_in_move_uom)
|
||||
###check_availability() (pas sur du nom)
|
||||
###1) unreserve
|
||||
###2) action_assign
|
||||
###
|
||||
###build_domain()
|
||||
###if op.package_id: return [('product_id', '=', move.produc_id), ('id', 'in', _get_all_quants)]
|
||||
###elif op.quant_id: return [('product_id', '=', move.produc_id), ('id', '=', op.quant_id)]
|
||||
###elif op.lot_id: return [('product_id', '=', move.producT_id), ('lot_id', '=', op.lot_id)]
|
||||
###else: return [] #fallback on the default behavior
|
||||
###
|
||||
###
|
||||
###do_transfer:
|
||||
###1) create extra moves based on remaining_qty of pack_operations
|
||||
###2) check_availability
|
||||
###2) a) unreserve
|
||||
###2) b) assign quants: loop on move_lines,
|
||||
### for record in move.newtablelink:
|
||||
### domain = buil_domain(record)
|
||||
### if domain:
|
||||
### quants = quant_get(domain, record.qty)
|
||||
### for quant, qtty in quants:
|
||||
### if quant:
|
||||
### reserve quant for move (split)
|
||||
### else: rien
|
||||
### if move pas totallement available:
|
||||
### action_assign(move) #mieux de faire action_assign car ca va checker le move précedent pyus faure un fallback (/!\ qty?)
|
||||
###3) action_done du move: base sur les quants assigned (semble ok pour l'instant)
|
||||
###4) packaging (donc hors du action_done du move)
|
||||
|
||||
### package_obj._get_remaining_prod_quantities(operation):
|
||||
###res = {}
|
||||
####total found per product included in the operation
|
||||
###for record in operation.linked_move_operation_ids:
|
||||
### if record.product_id.id not in res:
|
||||
### res[record.product_id.id] = 0
|
||||
### res[record.product_id.id] += record.qty
|
||||
####total per product included int the package
|
||||
###res2 = {}
|
||||
###for quant in quant_obj.browse(cr, uid, package_obj._get_content_package(cr, uid, op.package_id, context=context))
|
||||
### if quant.product_id.id not in res2:
|
||||
### res2[quant.product_id.id] = 0
|
||||
### res2[quant.product_id.id] += quant.qty
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#def rereserve(self, cr, uid, picking_ids, create=False, context=None):
|
||||
# """
|
||||
# This will unreserve all products and reserve the quants from the operations again
|
||||
# :return: Tuple (res, res2, resneg)
|
||||
# res: dictionary of ops with quantity that could not be processed matching ops and moves
|
||||
# res2: dictionary of moves with quantity that could not be processed matching ops and moves
|
||||
# resneg: the negative quants to be created: resneg[move][ops] gives negative quant to be created
|
||||
# tuple of dictionary with quantities of quant operation and product that can not be matched between ops and moves
|
||||
# and dictionary with remaining values on moves
|
||||
# """
|
||||
# quant_obj = self.pool.get("stock.quant")
|
||||
# pack_obj = self.pool.get("stock.quant.package")
|
||||
# uom_obj = self.pool.get('product.uom')
|
||||
# res = {} # Qty still to do from ops
|
||||
# res2 = {} #what is left from moves
|
||||
# resneg= {} #Number of negative quants to create for move/op
|
||||
# for picking in self.browse(cr, uid, picking_ids, context=context):
|
||||
# products_moves = {}
|
||||
# # unreserve everything and initialize res2
|
||||
# for move in picking.move_lines:
|
||||
# quant_obj.quants_unreserve(cr, uid, move, context=context)
|
||||
# res2[move.id] = move.product_qty
|
||||
# resneg[move.id] = {}
|
||||
# if move.state in ('confirmed', 'assigned'):
|
||||
# products_moves.setdefault(move.product_id.id, []).append(move)
|
||||
#
|
||||
#
|
||||
# # Resort pack_operation_ids such that package transfers happen first and then the most specific operations from the product
|
||||
#
|
||||
# orderedpackops = picking.pack_operation_ids
|
||||
# orderedpackops.sort(key = lambda x: ((x.package_id and not x.product_id) and -3 or 0) + (x.package_id and -1 or 0) + (x.lot_id and -1 or 0))
|
||||
|
||||
# for ops in orderedpackops:
|
||||
# #If a product is specified in the ops, search for appropriate quants
|
||||
# if ops.product_id:
|
||||
# # Match with moves
|
||||
# move_ids = ops.product_id.id in products_moves and filter(lambda x: res2[x.id] > 0, products_moves[ops.product_id.id]) or []
|
||||
# qty_to_do = uom_obj._compute_qty(cr, uid, ops.product_uom_id.id, ops.product_qty, to_uom_id=ops.product_id.uom_id.id)
|
||||
# while qty_to_do > 0 and move_ids:
|
||||
# move = move_ids.pop()
|
||||
# if res2[move.id] > qty_to_do:
|
||||
# qty = qty_to_do
|
||||
# qty_to_do = 0
|
||||
# else:
|
||||
# qty = res2[move.id]
|
||||
# qty_to_do -= res2[move.id]
|
||||
# neg_qty = self._reserve_quants_ops_move(cr, uid, ops, move, qty, create=create, context=context)
|
||||
# if neg_qty > 0:
|
||||
# resneg[move.id].setdefault(ops.id, 0)
|
||||
# resneg [move.id][ops.id] += neg_qty
|
||||
# res2[move.id] -= qty
|
||||
# res[ops.id] = {}
|
||||
# res[ops.id][ops.product_id.id] = qty_to_do
|
||||
# # In case only a package is specified, take all the quants from the package
|
||||
# elif ops.package_id:
|
||||
# quants = quant_obj.browse(cr, uid, pack_obj.get_content(cr, uid, [ops.package_id.id], context=context))
|
||||
# quants = [x for x in quants if x.qty > 0] #Negative quants should not be moved
|
||||
# for quant in quants:
|
||||
# # Match with moves
|
||||
# move_ids = quant.product_id.id in products_moves and filter(lambda x: res2[x.id] > 0, products_moves[quant.product_id.id]) or []
|
||||
# qty_to_do = quant.qty
|
||||
# while qty_to_do > 0 and move_ids:
|
||||
# move = move_ids.pop()
|
||||
# if res2[move.id] > qty_to_do:
|
||||
# qty = qty_to_do
|
||||
# qty_to_do = 0.0
|
||||
# else:
|
||||
# qty = res2[move.id]
|
||||
# qty_to_do -= res2[move.id]
|
||||
# quant_obj.quants_reserve(cr, uid, [(quant, qty)], move, context=context)
|
||||
# quant_obj.write(cr, uid, [quant.id], {'reservation_op_id': ops.id}, context=context)
|
||||
# res2[move.id] -= qty
|
||||
# res.setdefault(ops.id, {}).setdefault(quant.product_id.id, 0.0)
|
||||
# res[ops.id][quant.product_id.id] += qty_to_do
|
||||
# return (res, res2, resneg)
|
||||
|
||||
def _create_extra_moves(self, cr, uid, picking, context=None):
|
||||
'''This function creates move lines on a picking, at the time of do_transfer, based on unexpected product transfers (or exceeding quantities) found in the pack operations
|
||||
'''
|
||||
|
@ -1237,49 +1084,6 @@ class stock_picking(osv.osv):
|
|||
if toassign_move_ids:
|
||||
stock_move_obj.action_assign(cr, uid, toassign_move_ids, context=context)
|
||||
return True
|
||||
## Rereserve quants
|
||||
## TODO: quants could have been created already in Supplier, so create parameter could disappear
|
||||
#res = self.rereserve(cr, uid, [picking.id], create = True, context = context) #This time, quants need to be created
|
||||
#resneg = res[2]
|
||||
#orig_moves = picking.move_lines
|
||||
#orig_qtys = {}
|
||||
#for orig in orig_moves:
|
||||
# orig_qtys[orig.id] = orig.product_qty
|
||||
##Add moves that operations need extra
|
||||
#extra_moves = []
|
||||
#for ops in res[0].keys():
|
||||
# for prod in res[0][ops].keys():
|
||||
# product = self.pool.get('product.product').browse(cr, uid, prod, context=context)
|
||||
# qty = res[0][ops][prod]
|
||||
# if qty > 0:
|
||||
# #Create moves for products too many on operation
|
||||
# move_id = stock_move_obj.create(cr, uid, {
|
||||
# 'name': product.name,
|
||||
# 'product_id': product.id,
|
||||
# 'product_uom_qty': qty,
|
||||
# 'product_uom': product.uom_id.id,
|
||||
# 'location_id': picking.location_id.id,
|
||||
# 'location_dest_id': picking.location_dest_id.id,
|
||||
# 'picking_id': picking.id,
|
||||
# 'picking_type_id': picking.picking_type_id.id,
|
||||
# 'group_id': picking.group_id.id,
|
||||
# }, context=context)
|
||||
# stock_move_obj.action_confirm(cr, uid, [move_id], context=context)
|
||||
# move = stock_move_obj.browse(cr, uid, move_id, context=context)
|
||||
# ops_rec = self.pool.get("stock.pack.operation").browse(cr, uid, ops, context=context)
|
||||
# resneg[move_id] = {}
|
||||
# resneg[move_id][ops] = self._reserve_quants_ops_move(cr, uid, ops_rec, move, qty, create=True, context=context)
|
||||
# extra_moves.append(move_id)
|
||||
#res2 = res[1]
|
||||
##Backorder
|
||||
#for move in res2.keys():
|
||||
# if res2[move] > 0:
|
||||
# mov = stock_move_obj.browse(cr, uid, move, context=context)
|
||||
# new_move = stock_move_obj.split(cr, uid, mov, res2[move], context=context)
|
||||
# #Assign move as it was assigned before
|
||||
# stock_move_obj.action_assign(cr, uid, [new_move], context=context)
|
||||
#todo = []
|
||||
#orig_moves = [x for x in orig_moves if res[1][x.id] < orig_qtys[x.id]]
|
||||
|
||||
def do_split(self, cr, uid, picking_ids, context=None):
|
||||
"""
|
||||
|
@ -1293,7 +1097,6 @@ class stock_picking(osv.osv):
|
|||
return True
|
||||
|
||||
# Methods for the barcode UI
|
||||
|
||||
def get_picking_for_packing_ui(self, cr, uid, context=None):
|
||||
return self.search(cr, uid, [('state', 'in', ('confirmed', 'assigned')), ('picking_type_id', '=', context.get('default_picking_type_id'))], context=context)
|
||||
|
||||
|
@ -1519,8 +1322,6 @@ class stock_move(osv.osv):
|
|||
'linked_move_operation_ids': fields.one2many('stock.move.operation.link', 'move_id', string='Linked Operations', readonly=True, help='Operations that impact this move for the computation of the remaining quantities'),
|
||||
'remaining_qty': fields.function(_get_remaining_qty, type='float', string='Remaining Quantity',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'), states={'done': [('readonly', True)]},),
|
||||
#store = {'stock.move': (lambda self, cr, uid, ids, c={}: ids , ['product_uom_qty', 'product_uom', 'reserved_quant_ids'], 20),
|
||||
# 'stock.quant': (_get_move, ['reservation_id'], 10)}),
|
||||
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
||||
'rule_id': fields.many2one('procurement.rule', 'Procurement Rule', help='The pull rule that created this stock move'),
|
||||
|
@ -1602,7 +1403,7 @@ class stock_move(osv.osv):
|
|||
for move in self.browse(cr, uid, move_ids, context=context):
|
||||
ids_to_free += [quant.id for quant in move.reserved_quant_ids]
|
||||
if ids_to_free:
|
||||
quant_obj.write(cr, SUPERUSER_ID, ids_to_free, {'reservation_id': False, 'reservation_op_id': False}, context=context)
|
||||
quant_obj.write(cr, SUPERUSER_ID, ids_to_free, {'reservation_id': False}, context=context)
|
||||
|
||||
def _prepare_procurement_from_move(self, cr, uid, move, context=None):
|
||||
origin = (move.group_id and (move.group_id.name + ":") or "") + (move.rule_id and move.rule_id.name or "/")
|
||||
|
@ -1656,15 +1457,12 @@ class stock_move(osv.osv):
|
|||
if putaway.method == 'fixed' and putaway.location_spec_id:
|
||||
moveputaway_obj.create(cr, SUPERUSER_ID, {'move_id': move.id,
|
||||
'location_id': putaway.location_spec_id.id,
|
||||
'quantity': move.product_uom_qty}, context=context)
|
||||
'quantity': move.product_qty}, context=context)
|
||||
return True
|
||||
|
||||
def _create_procurement(self, cr, uid, move, context=None):
|
||||
"""
|
||||
This will create a procurement order
|
||||
"""
|
||||
proc_obj = self.pool.get("procurement.order")
|
||||
return proc_obj.create(cr, uid, self._prepare_procurement_from_move(cr, uid, move, context=context))
|
||||
""" This will create a procurement order """
|
||||
return self.pool.get("procurement.order").create(cr, uid, self._prepare_procurement_from_move(cr, uid, move, context=context))
|
||||
|
||||
# Check that we do not modify a stock.move which is done
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
|
@ -1676,11 +1474,9 @@ class stock_move(osv.osv):
|
|||
if frozen_fields.intersection(vals):
|
||||
raise osv.except_osv(_('Operation Forbidden!'),
|
||||
_('Quantities, Units of Measure, Products and Locations cannot be modified on stock moves that have already been processed (except by the Administrator).'))
|
||||
result = super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||
return result
|
||||
return super(stock_move, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def onchange_quantity(self, cr, uid, ids, product_id, product_qty,
|
||||
product_uom, product_uos):
|
||||
def onchange_quantity(self, cr, uid, ids, product_id, product_qty, product_uom, product_uos):
|
||||
""" On change of product quantity finds UoM and UoS quantities
|
||||
@param product_id: Product id
|
||||
@param product_qty: Changed Quantity of product
|
||||
|
@ -1755,8 +1551,7 @@ class stock_move(osv.osv):
|
|||
result['product_uom_qty'] = product_uos_qty
|
||||
return {'value': result, 'warning': warning}
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False,
|
||||
loc_dest_id=False, partner_id=False):
|
||||
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False, partner_id=False):
|
||||
""" On change of product id, if finds UoM, UoS, quantity and UoS quantity.
|
||||
@param prod_id: Changed Product id
|
||||
@param loc_id: Source location id
|
||||
|
@ -1862,7 +1657,6 @@ class stock_move(osv.osv):
|
|||
self.write(cr, uid, list(set(ids) - set(done)), {'state': 'assigned'})
|
||||
return True
|
||||
|
||||
|
||||
def cancel_assign(self, cr, uid, ids, context=None):
|
||||
""" Changes the state to confirmed.
|
||||
@return: True
|
||||
|
@ -1904,9 +1698,6 @@ class stock_move(osv.osv):
|
|||
self._putaway_apply(cr, uid, ids, context=context)
|
||||
return done
|
||||
|
||||
#
|
||||
# Cancel move => cancel others move and pickings
|
||||
#
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
""" Cancels the moves and if all moves are cancelled it cancels the picking.
|
||||
@return: True
|
||||
|
@ -1939,8 +1730,6 @@ class stock_move(osv.osv):
|
|||
"""
|
||||
context = context or {}
|
||||
quant_obj = self.pool.get("stock.quant")
|
||||
ops_obj = self.pool.get("stock.pack.operation")
|
||||
pack_obj = self.pool.get("stock.quant.package")
|
||||
todo = [move.id for move in self.browse(cr, uid, ids, context=context) if move.state == "draft"]
|
||||
if todo:
|
||||
self.action_confirm(cr, uid, todo, context=context)
|
||||
|
@ -1952,10 +1741,6 @@ class stock_move(osv.osv):
|
|||
pickings.add(move.picking_id.id)
|
||||
qty = move.product_qty
|
||||
|
||||
# for qty, location_id in move_id.prefered_location_ids:
|
||||
# quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, qty, context=context)
|
||||
# quant_obj.quants_move(cr, uid, quants, move, location_dest_id, context=context)
|
||||
# should replace the above 2 lines
|
||||
dom = [('qty', '>', 0)]
|
||||
prefered_domain = [('reservation_id', '=', move.id)]
|
||||
fallback_domain = [('reservation_id', '=', False)]
|
||||
|
@ -1994,7 +1779,7 @@ class stock_move(osv.osv):
|
|||
@param context: context arguments
|
||||
@return: Scraped lines
|
||||
"""
|
||||
#quantity should in MOVE UOM
|
||||
#quantity should be given in MOVE UOM
|
||||
if quantity <= 0:
|
||||
raise osv.except_osv(_('Warning!'), _('Please provide a positive quantity to scrap.'))
|
||||
res = []
|
||||
|
@ -2041,7 +1826,7 @@ class stock_move(osv.osv):
|
|||
@param context: context arguments
|
||||
@return: Consumed lines
|
||||
"""
|
||||
#quantity should in MOVE UOM
|
||||
#quantity should be given in MOVE UOM
|
||||
if context is None:
|
||||
context = {}
|
||||
if quantity <= 0:
|
||||
|
@ -2088,12 +1873,8 @@ class stock_move(osv.osv):
|
|||
self.action_done(cr, uid, res, context=context)
|
||||
return res
|
||||
|
||||
|
||||
|
||||
def split(self, cr, uid, move, qty, context=None):
|
||||
"""
|
||||
Splits qty from move move into a new move
|
||||
"""
|
||||
""" Splits qty from move move into a new move """
|
||||
if move.product_qty == qty:
|
||||
return move.id
|
||||
if (move.product_qty < qty) or (qty == 0):
|
||||
|
@ -2159,12 +1940,12 @@ class stock_inventory(osv.osv):
|
|||
|
||||
stock_settings = settings_obj.browse(cr, uid, config_ids[0], context=context)
|
||||
if stock_settings.group_stock_tracking_owner:
|
||||
res_filter.append(('owner', 'One owner only'))
|
||||
res_filter.append(('product_owner', 'One product for a specific owner'))
|
||||
res_filter.append(('owner', _('One owner only')))
|
||||
res_filter.append(('product_owner', _('One product for a specific owner')))
|
||||
if stock_settings.group_stock_production_lot:
|
||||
res_filter.append(('lot', 'One Lot/Serial Number'))
|
||||
res_filter.append(('lot', _('One Lot/Serial Number')))
|
||||
if stock_settings.group_stock_tracking_lot:
|
||||
res_filter.append(('pack', 'A Pack'))
|
||||
res_filter.append(('pack', _('A Pack')))
|
||||
return res_filter
|
||||
|
||||
_columns = {
|
||||
|
|
|
@ -85,7 +85,7 @@ class stock_quant(osv.osv):
|
|||
"""
|
||||
def _account_entry_move(self, cr, uid, quant, move, context=None):
|
||||
location_from = move.location_id
|
||||
location_to = move.location_dest_id
|
||||
location_to = quant.location_id
|
||||
if context is None:
|
||||
context = {}
|
||||
if quant.product_id.valuation != 'real_time':
|
||||
|
@ -126,9 +126,9 @@ class stock_quant(osv.osv):
|
|||
self._create_account_move_line(cr, uid, quant, move, acc_valuation, acc_dest, journal_id, context=ctx)
|
||||
|
||||
|
||||
def move_single_quant(self, cr, uid, quant, qty, move, lot_id=False, owner_id=False, package_id= False, context=None):
|
||||
quant_record = super(stock_quant, self).move_single_quant(cr, uid, quant, qty, move, lot_id = lot_id, owner_id = owner_id, package_id = package_id, context=context)
|
||||
self._account_entry_move(cr, uid, quant_record, move, context=context)
|
||||
def move_single_quant(self, cr, uid, quant, location_to, qty, move, context=None):
|
||||
quant_record = super(stock_quant, self).move_single_quant(cr, uid, quant, location_to, qty, move, context=context)
|
||||
self._account_entry_move(cr, uid, quant, move, context=context)
|
||||
return quant_record
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue