[WIP] stock: partial re-implementation of action_assign do_rereserve...
bzr revid: qdp-launchpad@openerp.com-20131115175505-8x75o2xcxxm58g0z
This commit is contained in:
parent
3e21ab83e8
commit
9a3da0db2b
|
@ -259,12 +259,25 @@ class stock_quant(osv.osv):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def quants_reserve(self, cr, uid, quants, move, context=None):
|
def quants_reserve(self, cr, uid, quants, move, context=None):
|
||||||
|
'''This function reserves quants for the given move. If the total of quantity reserved is enough, the move's state is also set to 'assigned'
|
||||||
|
:param quants: list of tuple(quant browse record or None, qty to reserve). If None is given as first tuple element, the item will be ignored
|
||||||
|
:param move: browse record
|
||||||
|
'''
|
||||||
toreserve = []
|
toreserve = []
|
||||||
for quant,qty in quants:
|
#split quants if needed
|
||||||
if not quant: continue
|
for quant, qty in quants:
|
||||||
|
if not quant:
|
||||||
|
continue
|
||||||
self._quant_split(cr, uid, quant, qty, context=context)
|
self._quant_split(cr, uid, quant, qty, context=context)
|
||||||
toreserve.append(quant.id)
|
toreserve.append(quant.id)
|
||||||
return self.write(cr, SUPERUSER_ID, toreserve, {'reservation_id': move.id}, context=context)
|
#reserve quants
|
||||||
|
if toreserve:
|
||||||
|
self.write(cr, SUPERUSER_ID, toreserve, {'reservation_id': move.id}, context=context)
|
||||||
|
#check if move'state needs to be set as 'assigned'
|
||||||
|
move.refresh()
|
||||||
|
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)
|
# 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):
|
def quants_move(self, cr, uid, quants, move, lot_id=False, owner_id=False, package_id=False, context=None):
|
||||||
|
@ -325,7 +338,7 @@ class stock_quant(osv.osv):
|
||||||
Use the removal strategies of product to search for the correct quants
|
Use the removal strategies of product to search for the correct quants
|
||||||
If you inherit, put the super at the end of your method.
|
If you inherit, put the super at the end of your method.
|
||||||
|
|
||||||
:location: browse record of the parent location in which the quants have to be found
|
:location: browse record of the parent location where the quants have to be found
|
||||||
:product: browse record of the product to find
|
:product: browse record of the product to find
|
||||||
:qty in UoM of product
|
:qty in UoM of product
|
||||||
"""
|
"""
|
||||||
|
@ -750,17 +763,50 @@ class stock_picking(osv.osv):
|
||||||
|
|
||||||
def action_assign(self, cr, uid, ids, context=None):
|
def action_assign(self, cr, uid, ids, context=None):
|
||||||
""" Check availability of picking moves.
|
""" Check availability of picking moves.
|
||||||
This has the effect of changing the state and reserved quants of available moves, and may
|
This has the effect of changing the state and reserve quants on available moves, and may
|
||||||
also impact the state of the picking as it is computed based on move's states.
|
also impact the state of the picking as it is computed based on move's states.
|
||||||
@return: True
|
@return: True
|
||||||
"""
|
"""
|
||||||
|
def build_domain(record):
|
||||||
|
op = record.operation_id
|
||||||
|
move = record.move_id
|
||||||
|
domain = [('product_id', '=', move.produc_id.id)]
|
||||||
|
if op.package_id:
|
||||||
|
domain.append(('id', 'in', package_obj. _get_content_package(cr, uid, [op.package_id.id, context=context]))
|
||||||
|
elif op.quant_id:
|
||||||
|
domain.append(('id', '=', op.quant_id.id))
|
||||||
|
elif op.lot_id:
|
||||||
|
domain.append(('lot_id', '=', op.lot_id.id))
|
||||||
|
else:
|
||||||
|
#fallback on the default behavior
|
||||||
|
return []
|
||||||
|
return domain
|
||||||
|
|
||||||
|
package_obj = self.pool.get('stock.quant.package')
|
||||||
|
quant_obj = self.pool.get('stock.quant')
|
||||||
|
deferred_move_ids = []
|
||||||
for pick in self.browse(cr, uid, ids, context=context):
|
for pick in self.browse(cr, uid, ids, context=context):
|
||||||
if pick.state == 'draft':
|
if pick.state == 'draft':
|
||||||
self.action_confirm(cr, uid, [pick.id], context=context)
|
self.action_confirm(cr, uid, [pick.id], context=context)
|
||||||
move_ids = [x.id for x in pick.move_lines if x.state == 'confirmed']
|
move_ids = [x.id for x in pick.move_lines if x.state not in ('draft', 'cancel', 'done')]
|
||||||
if not move_ids:
|
if not move_ids:
|
||||||
raise osv.except_osv(_('Warning!'), _('No product available.'))
|
raise osv.except_osv(_('Warning!'), _('Nothing to check the availability for.'))
|
||||||
self.pool.get('stock.move').action_assign(cr, uid, move_ids, context=context)
|
for move in pick.move_lines:
|
||||||
|
#skip the move that doesn't need to be checked
|
||||||
|
if move.state in ('draft', 'cancel', 'done'):
|
||||||
|
continue
|
||||||
|
#assign quants based on the pack operations of the picking
|
||||||
|
for record in move.linked_move_operation_ids:
|
||||||
|
domain = build_domain(record)
|
||||||
|
if domain:
|
||||||
|
quants = quant_obj.quants_get(cr, uid, move.location_id, move.product_id, record.qty, domain=domain)
|
||||||
|
quants_obj.quants_reserve(cr, uid, quants, move, context=context)
|
||||||
|
#if the move is still not totally available (not possible to reserve everything based on the pack operations),
|
||||||
|
#queue this move in the list to recompute based on generic action_assign of the move.
|
||||||
|
if move.state != 'assigned':
|
||||||
|
deferred_move_ids.append(move.id)
|
||||||
|
if deferred_move_ids:
|
||||||
|
self.pool.get('stock.move').action_assign(cr, uid, deferred_move_ids, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def force_assign(self, cr, uid, ids, context=None):
|
def force_assign(self, cr, uid, ids, context=None):
|
||||||
|
@ -913,12 +959,19 @@ class stock_picking(osv.osv):
|
||||||
'cost': move.product_id.standard_price,
|
'cost': move.product_id.standard_price,
|
||||||
}, context=context)
|
}, context=context)
|
||||||
|
|
||||||
|
def available_quants_assign(self, cr, uid, picking_ids, context=None):
|
||||||
|
'''Recompute the availability of quants for the given picking and assign them on the stock moves'''
|
||||||
|
#first unreserve the quants of related picking, because this function could be used to unreserve
|
||||||
|
#quants on several pickings in order to group the available ones on a single picking.
|
||||||
|
self.do_unreserve(cr, uid, picking_ids, context=context)
|
||||||
|
return self.action_assign(cr, uid picking_ids, context=context)
|
||||||
|
|
||||||
def do_rereserve(self, cr, uid, picking_ids, context=None):
|
|
||||||
'''
|
#def do_rereserve(self, cr, uid, picking_ids, context=None):
|
||||||
Needed for parameter create
|
# '''
|
||||||
'''
|
# Needed for parameter create
|
||||||
self.rereserve(cr, uid, picking_ids, context=context)
|
# '''
|
||||||
|
# self.rereserve(cr, uid, picking_ids, context=context)
|
||||||
|
|
||||||
def do_unreserve(self, cr, uid, picking_ids, context=None):
|
def do_unreserve(self, cr, uid, picking_ids, context=None):
|
||||||
"""
|
"""
|
||||||
|
@ -955,48 +1008,9 @@ class stock_picking(osv.osv):
|
||||||
# quant_obj.write(cr, SUPERUSER_ID, [x[0].id for x in quants if x[0]], {'reservation_op_id': ops.id}, 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
|
# return res_qty
|
||||||
|
|
||||||
def do_recompute_remaining_quantities(self, cr, uid, ids, context=None):
|
|
||||||
'''This function simply calls recompute_remaining_quantities but is needed in order to pass the context in the righ argument'''
|
|
||||||
return self.recompute_remaining_quantities(cr, uid, ids, product_ids=[], context=context)
|
|
||||||
|
|
||||||
def _get_total_from_pack_operations(self, cr, picking, ids, product_ids=[], context=None):
|
|
||||||
def _update_quantity(product, quantity, uom_id):
|
|
||||||
quantity_in_move_uom = uom_obj._compute_qty(cr, uid, uom_id, quantity, product.uom_id.id, round=False)
|
|
||||||
self._create_link_move_op(cr, uid, op
|
|
||||||
|
|
||||||
res = {}
|
|
||||||
#if product_ids is not given, we'll recompute the remaining quantity for all move lines
|
|
||||||
if not product_ids:
|
|
||||||
tocheck_product_ids = [m.product_id.id for m in picking.move_lines]
|
|
||||||
else:
|
|
||||||
tocheck_product_ids = product_ids
|
|
||||||
#loop on the operations to compute the total of each product
|
|
||||||
for op in picking.pack_operation_ids:
|
|
||||||
quant_ids = []
|
|
||||||
if op.product_id and op.product_id.id in tocheck_product_ids:
|
|
||||||
_update_quantity(op.product_id, op.product_qty, op.product_uom_id.id)
|
|
||||||
elif op.quant_id:
|
|
||||||
quant_ids = [op.quant_id.id]
|
|
||||||
elif op.package_id:
|
|
||||||
quant_ids = self.pool.get('stock.quant.package').get_content_package(cr, uid, ids, context=context)
|
|
||||||
if quant_ids:
|
|
||||||
for quant in self.pool.get('stock.quant').browse(cr, uid, quant_ids, context=context):
|
|
||||||
if quant.product_id.id in tocheck_product_ids:
|
|
||||||
_update_quantity(quant.product_id, quant.qty, quant.product_id.uom_id.id)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def _set_remaining_on_lines(self, cr, uid, picking, product_dict, context=None):
|
|
||||||
#loop on the move lines to write the remaining quantity
|
|
||||||
for move in picking.move_lines:
|
|
||||||
if product_dict.get(move.product_id.id):
|
|
||||||
qty_to_write = min(move.product_qty, product_dict[move.product_id.id])
|
|
||||||
product_dict[move.product_id.id] -= qty_to_write
|
|
||||||
qty_to_write = uom_obj._compute_qty(cr, uid, move.product_id.uom_id.id, qty_to_write, move.product_uom.id)
|
|
||||||
self.pool.get('stock.move').write(cr, uid, [move.id], {'remaining_qty': move.product_uom_qty - qty_to_write}, context=context)
|
|
||||||
#loop on the product_dict items to set the remaining_qty on the pack operations if needed
|
|
||||||
for product_id, remaining_qty in product_dict.items:
|
|
||||||
if remaining_qty > 0:
|
|
||||||
#there was more in pack operations than in move lines
|
|
||||||
### MEMO
|
### 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)
|
###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)
|
###check_availability() (pas sur du nom)
|
||||||
|
@ -1028,17 +1042,23 @@ class stock_picking(osv.osv):
|
||||||
###3) action_done du move: base sur les quants assigned (semble ok pour l'instant)
|
###3) action_done du move: base sur les quants assigned (semble ok pour l'instant)
|
||||||
###4) packaging (donc hors du action_done du move)
|
###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 recompute_remaining_quantities(self, cr, uid, ids, product_ids=[], context=None):
|
|
||||||
""" This will recompute the remaining qty on all move lines on the given picking 'ids'
|
|
||||||
based on the pack operations of the picking. An optionnal product_ids may be given in
|
|
||||||
order to restrict the recomputation on stock moves having a product_id in 'product_ids' only.
|
|
||||||
"""
|
|
||||||
uom_obj = self.pool.get('product.uom')
|
|
||||||
for picking in self.browse(cr, uid, ids, context=context):
|
|
||||||
product_dict = self._get_total_from_pack_operations(cr, uid, picking, product_ids=product_ids, context=context)
|
|
||||||
self._set_remaining_on_lines(cr, uid, picking, product_dict, context=context)
|
|
||||||
|
|
||||||
#def rereserve(self, cr, uid, picking_ids, create=False, context=None):
|
#def rereserve(self, cr, uid, picking_ids, create=False, context=None):
|
||||||
# """
|
# """
|
||||||
|
@ -1116,11 +1136,21 @@ class stock_picking(osv.osv):
|
||||||
# res[ops.id][quant.product_id.id] += qty_to_do
|
# res[ops.id][quant.product_id.id] += qty_to_do
|
||||||
# return (res, res2, resneg)
|
# return (res, res2, resneg)
|
||||||
|
|
||||||
def _create_extra_moves(self, cr, uid, picking, remaining_dict, context=None):
|
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)
|
'''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
|
||||||
'''
|
'''
|
||||||
for
|
move_obj = self.pool.get('stock.move')
|
||||||
pass
|
for op in picking.pack_operation_ids:
|
||||||
|
for op_remaining_product_id, op_remaing_qty in package_obj._get_remaining_prod_quantities().items():
|
||||||
|
#TODO continue MEMO
|
||||||
|
if op_remaining_qty > 0:
|
||||||
|
vals = {
|
||||||
|
'picking_id': picking.id,
|
||||||
|
'location_id': picking.location_id.id,
|
||||||
|
'location_dest_id': picking.location_dest_id.id,
|
||||||
|
'product_id': op.
|
||||||
|
}
|
||||||
|
move_obj.create(cr, uid, vals, context=context)
|
||||||
|
|
||||||
def rereserve_quants(self, cr, uid, picking, move_ids=[], context=None):
|
def rereserve_quants(self, cr, uid, picking, move_ids=[], context=None):
|
||||||
stock_move_obj = self.pool.get('stock.move')
|
stock_move_obj = self.pool.get('stock.move')
|
||||||
|
@ -1144,10 +1174,8 @@ class stock_picking(osv.osv):
|
||||||
self.action_done(cr, uid, [picking.id], context=context)
|
self.action_done(cr, uid, [picking.id], context=context)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
#recompute remaining quantities on stock move
|
|
||||||
remaining_dict = self.recompute_remaining_quantities(cr, uid, [picking.id], product_ids=[], context=context)
|
|
||||||
#create extra moves in the picking (unexpected product moves coming from pack operations)
|
#create extra moves in the picking (unexpected product moves coming from pack operations)
|
||||||
self._create_extra_moves(cr, uid, picking, remaining_dict, context=context)
|
self._create_extra_moves(cr, uid, picking, context=context)
|
||||||
picking.refresh()
|
picking.refresh()
|
||||||
#split move lines eventually
|
#split move lines eventually
|
||||||
todo_move_ids = []
|
todo_move_ids = []
|
||||||
|
@ -1350,9 +1378,11 @@ class stock_move(osv.osv):
|
||||||
def _get_remaining_qty(self, cr, uid, ids, field_name, args, context=None):
|
def _get_remaining_qty(self, cr, uid, ids, field_name, args, context=None):
|
||||||
res = {}
|
res = {}
|
||||||
for move in self.browse(cr, uid, ids, context=context):
|
for move in self.browse(cr, uid, ids, context=context):
|
||||||
res[move.id] = move.product_qty
|
qty = move.product_qty
|
||||||
for quant in move.reserved_quant_ids:
|
for record in move.linked_move_operation_ids:
|
||||||
res[move.id] -= quant.qty
|
qty -= record.qty
|
||||||
|
#converting the remaining quantity in the move UoM
|
||||||
|
res[move.id] = uom_obj._compute_qty(cr, uid, move.product_id.uom_id.id, qty, move.product_uom.id)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_lot_ids(self, cr, uid, ids, field_name, args, context=None):
|
def _get_lot_ids(self, cr, uid, ids, field_name, args, context=None):
|
||||||
|
@ -1451,11 +1481,11 @@ class stock_move(osv.osv):
|
||||||
|
|
||||||
'quant_ids': fields.many2many('stock.quant', 'stock_quant_move_rel', 'move_id', 'quant_id', 'Moved Quants'),
|
'quant_ids': fields.many2many('stock.quant', 'stock_quant_move_rel', 'move_id', 'quant_id', 'Moved Quants'),
|
||||||
'reserved_quant_ids': fields.one2many('stock.quant', 'reservation_id', 'Reserved quants'),
|
'reserved_quant_ids': fields.one2many('stock.quant', 'reservation_id', 'Reserved quants'),
|
||||||
'remaining_qty': fields.float('Remaining Quantity'),
|
'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',
|
'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)]},
|
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),
|
#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)}),
|
# 'stock.quant': (_get_move, ['reservation_id'], 10)}),
|
||||||
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
||||||
'group_id': fields.many2one('procurement.group', 'Procurement Group'),
|
'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'),
|
'rule_id': fields.many2one('procurement.rule', 'Procurement Rule', help='The pull rule that created this stock move'),
|
||||||
|
@ -1817,9 +1847,9 @@ class stock_move(osv.osv):
|
||||||
done.append(move.id)
|
done.append(move.id)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
qty_already_assigned = ...
|
qty_already_assigned = sum([q.qty for q in move.reserved_quant_ids])
|
||||||
qty = move.product_qty - qty_already_assigned
|
qty = move.product_qty - qty_already_assigned
|
||||||
#we keep the quants already assigned and try to find the remaining qauntity on quants not assigned only
|
#we keep the quants already assigned and try to find the remaining quantity on quants not assigned only
|
||||||
domain = [('reservation_id', '=', False), ('qty', '>', 0)]
|
domain = [('reservation_id', '=', False), ('qty', '>', 0)]
|
||||||
#build the prefered domain based on quants that moved in previous linked done move
|
#build the prefered domain based on quants that moved in previous linked done move
|
||||||
prev_quant_ids = []
|
prev_quant_ids = []
|
||||||
|
@ -3260,19 +3290,49 @@ class stock_package(osv.osv):
|
||||||
total += quant.qty
|
total += quant.qty
|
||||||
return total
|
return total
|
||||||
|
|
||||||
|
def _get_all_products_quantities(cr, uid, package_id, context=None):
|
||||||
|
'''This function computes the different product quantities for the given package
|
||||||
|
'''
|
||||||
|
quant_obj = self.pool.get('stock.quant')
|
||||||
|
res = {}
|
||||||
|
for quant in quant_obj.browse(cr, uid, self._get_content_package(cr, uid, package_id, context=context))
|
||||||
|
if quant.product_id.id not in res:
|
||||||
|
res[quant.product_id.id] = 0
|
||||||
|
res[quant.product_id.id] += quant.qty
|
||||||
|
return res
|
||||||
|
|
||||||
class stock_pack_operation(osv.osv):
|
class stock_pack_operation(osv.osv):
|
||||||
_name = "stock.pack.operation"
|
_name = "stock.pack.operation"
|
||||||
_description = "Packing Operation"
|
_description = "Packing Operation"
|
||||||
|
|
||||||
#def _get_remaining_qty(self, cr, uid, ids, name, args, context=None):
|
def _get_remaining_prod_quantities(cr, uid, operation, context=None):
|
||||||
# res = {}
|
res = {}
|
||||||
# for ops in self.browse(cr, uid, ids, context=context):
|
#total found per product included in the operation
|
||||||
# qty = ops.product_qty
|
for record in operation.linked_move_operation_ids:
|
||||||
# for quant in ops.reserved_quant_ids:
|
if record.product_id.id not in res:
|
||||||
# qty -= quant.qty
|
res[record.product_id.id] = 0
|
||||||
# res[ops.id] = qty
|
res[record.product_id.id] += record.qty
|
||||||
# return res
|
#if the operation concerns a package (this function could work only for this case => TODO: decide
|
||||||
|
if operation.package_id:
|
||||||
|
reference_dict = self.pool.get('stock.quant.package')._get_all_products_quantities(cr, uid operation.package_id.id, context=context)
|
||||||
|
#compare the 2 dicts to know what's the difference
|
||||||
|
|
||||||
|
def _get_remaining_qty(self, cr, uid, ids, name, args, context=None):
|
||||||
|
res = {}
|
||||||
|
for ops in self.browse(cr, uid, ids, context=context):
|
||||||
|
if ops.package_id or ops.quant_id:
|
||||||
|
#dont try to compute the remaining quantity for packages because it's not relevant (a package could include different products).
|
||||||
|
#should use
|
||||||
|
res[ops.id] = 0
|
||||||
|
continue
|
||||||
|
qty = ops.product_qty
|
||||||
|
for record in ops.linked_move_operation_ids:
|
||||||
|
qty -= record.qty
|
||||||
|
if ops.product_id and ops.product_uom_id:
|
||||||
|
#converting the remaining quantity in the pack operation UoM
|
||||||
|
qty = uom_obj._compute_qty(cr, uid, ops.product_id.uom_id.id, qty, ops.product_uom_id.id)
|
||||||
|
res[ops.id] = qty
|
||||||
|
return res
|
||||||
|
|
||||||
def product_id_change(self, cr, uid, ids, product_id, product_uom_id, product_qty, context=None):
|
def product_id_change(self, cr, uid, ids, product_id, product_uom_id, product_qty, context=None):
|
||||||
res = self.on_change_tests(cr, uid, ids, product_id, product_uom_id, product_qty, context=context)
|
res = self.on_change_tests(cr, uid, ids, product_id, product_uom_id, product_qty, context=context)
|
||||||
|
@ -3316,9 +3376,8 @@ class stock_pack_operation(osv.osv):
|
||||||
#'update_cost': fields.boolean('Need cost update'),
|
#'update_cost': fields.boolean('Need cost update'),
|
||||||
'cost': fields.float("Cost", help="Unit Cost for this product line"),
|
'cost': fields.float("Cost", help="Unit Cost for this product line"),
|
||||||
'currency': fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
'currency': fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", ondelete='CASCADE'),
|
||||||
'reserved_quant_ids': fields.one2many('stock.quant', 'reservation_op_id', string='Reserved Quants', readonly=True, help='Quants reserved for this operation'),
|
'linked_move_operation_ids': fields.one2many('stock.move.operation.link', 'operation_id', string='Linked Moves', readonly=True, help='Moves impacted by this operation for the computation of the remaining quantities'),
|
||||||
#'remaining_qty': fields.function(_get_remaining_qty, type='float', string='Remaining Qty'),
|
'remaining_qty': fields.function(_get_remaining_qty, type='float', string='Remaining Qty'),
|
||||||
'remaining_qty': fields.float('Remaining Qty'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaults = {
|
_defaults = {
|
||||||
|
@ -3384,6 +3443,20 @@ class stock_pack_operation(osv.osv):
|
||||||
values.update({'id': operation_id})
|
values.update({'id': operation_id})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class stock_move_operation_link(osv.osv):
|
||||||
|
"""
|
||||||
|
Table making the link between stock.moves and stock.pack.operations to compute the remaining quantities on each of these objects
|
||||||
|
"""
|
||||||
|
_name = "stock.move.operation.link"
|
||||||
|
_description = "Link between stock moves and pack operations"
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'qty': fields.float('Quantity', help="Quantity of products to consider when talking about the contribution of this pack operation towards the remaining quantity of the move (and inverse). Given in the product main uom."),
|
||||||
|
'operation_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
|
||||||
|
'move_id': fields.many2one('stock.move', 'Move', required=True, ondelete="cascade"),
|
||||||
|
}
|
||||||
|
|
||||||
class stock_warehouse_orderpoint(osv.osv):
|
class stock_warehouse_orderpoint(osv.osv):
|
||||||
"""
|
"""
|
||||||
Defines Minimum stock rules.
|
Defines Minimum stock rules.
|
||||||
|
|
|
@ -747,7 +747,7 @@
|
||||||
<form string="Transfer" version="7.0">
|
<form string="Transfer" version="7.0">
|
||||||
<header>
|
<header>
|
||||||
<button name="action_confirm" states="draft" string="Mark as Todo" type="object" class="oe_highlight" groups="base.group_user"/>
|
<button name="action_confirm" states="draft" string="Mark as Todo" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||||
<button name="do_rereserve" states="confirmed" string="Check Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
<button name="action_assign" states="confirmed" string="Check Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||||
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||||
<button name="do_transfer" states="assigned" string="Transfer Done" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
|
<button name="do_transfer" states="assigned" string="Transfer Done" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
|
||||||
<button name="do_prepare_partial" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', True),('state','!=','assigned')]}"/>
|
<button name="do_prepare_partial" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': ['|',('pack_operation_exist', '=', True),('state','!=','assigned')]}"/>
|
||||||
|
|
Loading…
Reference in New Issue