[REF] Refactor of trunk

bzr revid: jco@openerp.com-20130423151308-cplq5o4hhh1boglr
This commit is contained in:
Josse Colpaert 2013-04-23 17:13:08 +02:00
parent f7cb978b8f
commit 042e47c5d4
3 changed files with 108 additions and 118 deletions

View File

@ -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

View File

@ -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:

View File

@ -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: