[REF] Refactor of trunk
bzr revid: jco@openerp.com-20130423151308-cplq5o4hhh1boglr
This commit is contained in:
parent
f7cb978b8f
commit
042e47c5d4
|
@ -275,7 +275,7 @@ class product_product(osv.osv):
|
|||
if not ids:
|
||||
return res
|
||||
#set_context: refactor code here
|
||||
location_ids = self._getlocations_from_context(cr, uid, ids, context=context)
|
||||
location_ids = self._get_locations_from_context(cr, uid, ids, context=context)
|
||||
if not location_ids: #in case of no locations, query will be empty anyways
|
||||
return res
|
||||
|
||||
|
|
|
@ -1201,6 +1201,9 @@ class stock_picking(osv.osv):
|
|||
|
||||
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
|
||||
|
||||
|
||||
# FIXME: needs refactoring, this code is partially duplicated in stock_move.do_partial()!
|
||||
def do_partial(self, cr, uid, ids, partial_datas, context=None):
|
||||
""" Makes partial picking and moves done.
|
||||
|
@ -1224,6 +1227,10 @@ class stock_picking(osv.osv):
|
|||
new_picking = None
|
||||
complete, too_many, too_few = [], [], []
|
||||
move_product_qty, prodlot_ids, product_avail, partial_qty, product_uoms = {}, {}, {}, {}, {}
|
||||
|
||||
move_ids = [x.id for x in pick.move_lines]
|
||||
move_obj.price_computation(cr, uid, move_ids, partial_datas, context=context)
|
||||
|
||||
for move in pick.move_lines:
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
|
@ -1243,89 +1250,7 @@ class stock_picking(osv.osv):
|
|||
too_few.append(move)
|
||||
else:
|
||||
too_many.append(move)
|
||||
|
||||
#Change cost price according to company
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
product = product_obj.browse(cr, uid, move.product_id.id, context=context)
|
||||
company_id = move.company_id.id
|
||||
ctx = context.copy()
|
||||
if company_id != user.company_id.id:
|
||||
#test if I could do this with a read instead
|
||||
ctx['force_company'] = move.company_id.id
|
||||
product = product_obj.browse(cr, uid, move.product_id.id, context=ctx)
|
||||
cost_method = product.cost_method
|
||||
product_price = product.standard_price
|
||||
else:
|
||||
cost_method = move.product_id.cost_method
|
||||
|
||||
# Average price computation
|
||||
if (pick.type == 'in') and (cost_method == 'average'):
|
||||
|
||||
move_currency_id = move.company_id.currency_id.id
|
||||
context['currency_id'] = move_currency_id
|
||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||
|
||||
if product.id in product_avail:
|
||||
product_avail[product.id] += qty
|
||||
else:
|
||||
product_avail[product.id] = product.qty_available
|
||||
|
||||
if qty > 0:
|
||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||
move_currency_id, product_price)
|
||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||
product.uom_id.id)
|
||||
if product.qty_available <= 0:
|
||||
new_std_price = new_price
|
||||
else:
|
||||
# Get the standard price -> This should be company_dependent
|
||||
amount_unit = product.price_get('standard_price', context=context)[product.id]
|
||||
new_std_price = ((amount_unit * product_avail[product.id])\
|
||||
+ (new_price * qty))/(product_avail[product.id] + qty)
|
||||
# Write the field according to price type field, company dependence in ctx
|
||||
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price}, context=ctx)
|
||||
|
||||
# Record the values that were chosen in the wizard, so they can be
|
||||
# used for inventory valuation if real-time valuation is enabled.
|
||||
move_obj.write(cr, uid, [move.id],
|
||||
{'price_unit': product_price,
|
||||
'price_currency_id': product_currency})
|
||||
|
||||
#Average price computation when returning products
|
||||
if (pick.type == 'out') and (cost_method == 'average'):
|
||||
orig_move_id = move_obj.search(cr, uid, [('move_history_ids2', 'in', [move.id])], context=context)
|
||||
if len(orig_move_id) == 1:
|
||||
#Is it ok to repeat code here?
|
||||
move_orig = move_obj.browse(cr, uid, orig_move_id[0], context=context)
|
||||
product = product_obj.browse(cr, uid, move.product_id.id)
|
||||
move_currency_id = move.company_id.currency_id.id
|
||||
context['currency_id'] = move_currency_id
|
||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||
|
||||
if product.id in product_avail:
|
||||
product_avail[product.id] += qty
|
||||
else:
|
||||
product_avail[product.id] = product.qty_available
|
||||
|
||||
if qty > 0:
|
||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||
move_currency_id, move_orig.price_unit)
|
||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||
product.uom_id.id)
|
||||
# Get the standard price
|
||||
amount_unit = product.price_get('standard_price', context=context)[product.id]
|
||||
#Check new stock is not zero or negative:
|
||||
if (product_avail[product.id]- qty) > 0:
|
||||
new_std_price = ((amount_unit * product_avail[product.id])\
|
||||
- (new_price * qty))/(product_avail[product.id] - qty)
|
||||
# Write the field according to price type field
|
||||
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price})
|
||||
|
||||
# Record the values that were chosen in the wizard, so they can be
|
||||
# used for inventory valuation if real-time valuation is enabled.
|
||||
move_obj.write(cr, uid, [move.id],
|
||||
{'price_unit': move_orig.price_unit,
|
||||
'price_currency_id': product_currency})
|
||||
|
||||
for move in too_few:
|
||||
product_qty = move_product_qty[move.id]
|
||||
|
@ -1671,6 +1596,7 @@ class stock_move(osv.osv):
|
|||
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Optional: next stock move when chaining them", select=True),
|
||||
'move_history_ids': fields.many2many('stock.move', 'stock_move_history_ids', 'parent_id', 'child_id', 'Move History (child moves)'),
|
||||
'move_history_ids2': fields.many2many('stock.move', 'stock_move_history_ids', 'child_id', 'parent_id', 'Move History (parent moves)'),
|
||||
'move_returned_from': fields.many2one('stock.move', 'Move this move was returned from'),
|
||||
'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
|
||||
'note': fields.text('Notes'),
|
||||
'state': fields.selection([('draft', 'New'),
|
||||
|
@ -2664,6 +2590,89 @@ class stock_move(osv.osv):
|
|||
|
||||
return res
|
||||
|
||||
|
||||
|
||||
def price_computation(self, cr, uid, ids, partial_datas, context=None):
|
||||
'''
|
||||
This method will update the price of the products according to the stock moves
|
||||
If multiple stock moves have the same product, it will take into account
|
||||
the fact that the other was already processed with the product_avail list
|
||||
'''
|
||||
product_obj = self.pool.get('product.product')
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
|
||||
product_avail = {}
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
partial_data = partial_datas.get('move%s'%(move.id), {})
|
||||
product_qty = partial_data.get('product_qty',0.0)
|
||||
product_uom = partial_data.get('product_uom',False)
|
||||
product_price = partial_data.get('product_price',0.0)
|
||||
product_currency = partial_data.get('product_currency',False)
|
||||
product = product_obj.browse(cr, uid, move.product_id.id, context=context)
|
||||
ctx = context.copy()
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
company_id = move.company_id.id
|
||||
if company_id != user.company_id.id:
|
||||
#test if I could do this with a read instead
|
||||
ctx['force_company'] = move.company_id.id
|
||||
product = product_obj.browse(cr, uid, move.product_id.id, context=ctx)
|
||||
cost_method = product.cost_method
|
||||
product_price = move.price_unit
|
||||
#Check if cost_method used needs update
|
||||
avg_in_update = (move.picking_id.type == 'in') and (cost_method == 'average')
|
||||
avg_out_update = (move.picking_id.type == 'out') and (cost_method == 'average') and (move.move_returned_from)
|
||||
if avg_in_update or avg_out_update:
|
||||
move_currency_id = move.company_id.currency_id.id
|
||||
ctx['currency_id'] = move_currency_id
|
||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||
first_avail = False
|
||||
if not product.id in product_avail:
|
||||
product_avail[product.id] = product.qty_available
|
||||
first_avail = True
|
||||
if qty > 0:
|
||||
if avg_in_update:
|
||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||
move_currency_id, product_price)
|
||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||
product.uom_id.id)
|
||||
if product.qty_available <= 0:
|
||||
new_std_price = new_price
|
||||
else:
|
||||
amount_unit = product.price_get('standard_price', context=ctx)[product.id]
|
||||
new_std_price = ((amount_unit * product_avail[product.id])\
|
||||
+ (new_price * qty))/(product_avail[product.id] + qty)
|
||||
elif avg_out_update:
|
||||
move_orig = move.move_returned_from
|
||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||
move_currency_id, move_orig.price_unit)
|
||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||
product.uom_id.id)
|
||||
if (product_avail[product.id]- qty) > 0:
|
||||
amount_unit = product.price_get('standard_price', context=ctx)[product.id]
|
||||
new_std_price = ((amount_unit * product_avail[product.id])\
|
||||
- (new_price * qty))/(product_avail[product.id] - qty)
|
||||
# Write the field according to price type field
|
||||
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price})
|
||||
|
||||
#Adjust product available with the right amount
|
||||
if not first_avail:
|
||||
if avg_out_update:
|
||||
product_avail[product.id] -= qty
|
||||
else:
|
||||
product_avail[product.id] += qty
|
||||
|
||||
# Write the field according to price type field, company dependence in ctx
|
||||
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price}, context=ctx)
|
||||
|
||||
# Record the values that were chosen in the wizard, so they can be
|
||||
# used for inventory valuation if real-time valuation is enabled.
|
||||
self.write(cr, uid, [move.id],
|
||||
{'price_unit': product_price,
|
||||
'price_currency_id': product_currency})
|
||||
return True
|
||||
|
||||
|
||||
# FIXME: needs refactoring, this code is partially duplicated in stock_picking.do_partial()!
|
||||
def do_partial(self, cr, uid, ids, partial_datas, context=None):
|
||||
""" Makes partial pickings and moves done.
|
||||
|
@ -2681,54 +2690,34 @@ class stock_move(osv.osv):
|
|||
context = {}
|
||||
|
||||
complete, too_many, too_few = [], [], []
|
||||
move_product_qty = {}
|
||||
prodlot_ids = {}
|
||||
move_product_qty, prodlot_ids, product_avail, partial_qty, product_uoms = {}, {}, {}, {}, {}
|
||||
|
||||
|
||||
#Should trigger price_calculation here:
|
||||
move_ids = [x.id for x in self.browse(cr, uid, ids, context=context)]
|
||||
self.price_computation(cr, uid, move_ids, partial_datas, context=context)
|
||||
|
||||
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
partial_data = partial_datas.get('move%s'%(move.id), False)
|
||||
assert partial_data, _('Missing partial picking data for move #%s.') % (move.id)
|
||||
partial_data = partial_datas.get('move%s'%(move.id), {})
|
||||
product_qty = partial_data.get('product_qty',0.0)
|
||||
move_product_qty[move.id] = product_qty
|
||||
product_uom = partial_data.get('product_uom',False)
|
||||
product_price = partial_data.get('product_price',0.0)
|
||||
product_currency = partial_data.get('product_currency',False)
|
||||
prodlot_ids[move.id] = partial_data.get('prodlot_id')
|
||||
if move.product_qty == product_qty:
|
||||
prodlot_id = partial_data.get('prodlot_id')
|
||||
prodlot_ids[move.id] = prodlot_id
|
||||
product_uoms[move.id] = product_uom
|
||||
partial_qty[move.id] = uom_obj._compute_qty(cr, uid, product_uoms[move.id], product_qty, move.product_uom.id)
|
||||
if move.product_qty == partial_qty[move.id]:
|
||||
complete.append(move)
|
||||
elif move.product_qty > product_qty:
|
||||
elif move.product_qty > partial_qty[move.id]:
|
||||
too_few.append(move)
|
||||
else:
|
||||
too_many.append(move)
|
||||
|
||||
# Average price computation
|
||||
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
product = product_obj.browse(cr, uid, move.product_id.id)
|
||||
move_currency_id = move.company_id.currency_id.id
|
||||
context['currency_id'] = move_currency_id
|
||||
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
|
||||
if qty > 0:
|
||||
new_price = currency_obj.compute(cr, uid, product_currency,
|
||||
move_currency_id, product_price)
|
||||
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
|
||||
product.uom_id.id)
|
||||
if product.qty_available <= 0:
|
||||
new_std_price = new_price
|
||||
else:
|
||||
# Get the standard price
|
||||
amount_unit = product.price_get('standard_price', context=context)[product.id]
|
||||
new_std_price = ((amount_unit * product.qty_available)\
|
||||
+ (new_price * qty))/(product.qty_available + qty)
|
||||
|
||||
product_obj.write(cr, uid, [product.id],{'standard_price': new_std_price})
|
||||
|
||||
# Record the values that were chosen in the wizard, so they can be
|
||||
# used for inventory valuation if real-time valuation is enabled.
|
||||
self.write(cr, uid, [move.id],
|
||||
{'price_unit': product_price,
|
||||
'price_currency_id': product_currency,
|
||||
})
|
||||
|
||||
for move in too_few:
|
||||
product_qty = move_product_qty[move.id]
|
||||
if product_qty != 0:
|
||||
|
|
|
@ -199,6 +199,7 @@ class stock_return_picking(osv.osv_memory):
|
|||
'location_id': new_location,
|
||||
'location_dest_id': move.location_id.id,
|
||||
'date': date_cur,
|
||||
'move_returned_from': move.id,
|
||||
})
|
||||
move_obj.write(cr, uid, [move.id], {'move_history_ids2':[(4,new_move)]}, context=context)
|
||||
if not returned_lines:
|
||||
|
|
Loading…
Reference in New Issue