[IMP] Clean print, clean unused methods, price update according to currency in stock move adjustment

bzr revid: jco@openerp.com-20130515124457-irka898ynrgxt279
This commit is contained in:
Josse Colpaert
2013-05-15 14:44:57 +02:00
parent 6d0289e7b7
commit ffde17a603
6 changed files with 28 additions and 209 deletions
+4 -2
View File
@@ -128,8 +128,10 @@ class stock_partial_picking(osv.osv_memory):
# incoming pickings.
def _product_cost_for_average_update(self, cr, uid, move):
if move.picking_id.purchase_id:
return {'cost': move.purchase_line_id.price_unit,
'currency': move.picking_id.purchase_id.pricelist_id.currency_id.id}
currency_obj = self.pool.get("res.currency")
new_price = currency_obj.compute(cr, uid, move.picking_id.purchase_id.pricelist_id.currency_id.id, move.company_id.currency_id.id,
move.purchase_line_id.price_unit, round=False)
return {'cost': new_price}
return super(stock_partial_picking, self)._product_cost_for_average_update(cr, uid, move)
# Redefinition of the new field in order to update the model stock.picking.in in the orm
+4 -3
View File
@@ -172,7 +172,7 @@
version_id:
- name: v1.0
items_id:
- name: 20% Discount given by my supplier
- name: First version
sequence: 1
price_min_margin: 2
price_max_margin: 5
@@ -186,16 +186,17 @@
!record {model: purchase.order, id: purchase_order_fifo_usd}:
partner_id: base.res_partner_3
location_id: stock.stock_location_stock
pricelist_id: supplier_pricelist_usd
order_line:
- product_id: product_fifo_icecream
product_qty: 30.0
product_uom: product.product_uom_kgm
price_unit: 116.88
price_unit: 150.0
name: 'FIFO Ice Cream'
- product_id: product_fifo_icecream
product_qty: 10.0
product_uom: product.product_uom_kgm
price_unit: 116.877045348
price_unit: 150.0
-
I confirm the purchase order in USD
-
-2
View File
@@ -52,8 +52,6 @@ class report_stock_move(osv.osv):
'day_diff1':fields.float('Planned Lead Time (Days)',readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"),
'day_diff':fields.float('Execution Lead Time (Days)',readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"),
'stock_journal': fields.many2one('stock.journal','Stock Journal', select=True),
}
+7 -95
View File
@@ -675,6 +675,7 @@ class stock_picking(osv.osv):
('name_uniq', 'unique(name, company_id)', 'Reference must be unique per Company!'),
]
def action_process(self, cr, uid, ids, context=None):
if context is None:
context = {}
@@ -1225,10 +1226,8 @@ class stock_picking(osv.osv):
for pick in self.browse(cr, uid, ids, context=context):
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)
move_product_qty, prodlot_ids, partial_qty, product_uoms = {}, {}, {}, {}
for move in pick.move_lines:
if move.state in ('done', 'cancel'):
@@ -1238,7 +1237,6 @@ class stock_picking(osv.osv):
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_id = partial_data.get('prodlot_id')
prodlot_ids[move.id] = prodlot_id
product_uoms[move.id] = product_uom
@@ -1272,7 +1270,7 @@ class stock_picking(osv.osv):
'picking_id' : new_picking,
'state': 'assigned',
'move_dest_id': False,
'price_unit': move.price_unit,
'price_unit': product_price,
'product_uom': product_uoms[move.id]
}
prodlot_id = prodlot_ids[move.id]
@@ -2687,7 +2685,7 @@ class stock_move(osv.osv):
fifo = (cost_method != 'lifo')
tuples = product_obj.get_stock_matchings_fifolifo(cr, uid, [product.id], product_qty, fifo,
product_uom, move.company_id.currency_id.id, context=ctx)
product_uom, move.company_id.currency_id.id, context=ctx) #TODO Would be better to use price_currency_id for migration?
price_amount = 0.0
amount = 0.0
#Write stock matchings
@@ -2740,89 +2738,6 @@ class stock_move(osv.osv):
product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price}, context=ctx)
product_avail[product.id] -= product_uom_qty
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)
#Check we are using the right company
company_id = move.company_id.id
ctx = context.copy()
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
if company_id != user.company_id.id:
ctx['force_company'] = move.company_id.id
product = product_obj.browse(cr, uid, move.product_id.id, context=ctx)
cost_method = product.cost_method
#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:
# If no price from picking, use cost price from product
if product_price == 0.0:
product_price = product.price_get('standard_price', context=ctx)[product.id]
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)
if not product.id in product_avail:
product_avail[product.id] = product.qty_available
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)
#Adjust product available with the right amount
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):
@@ -2841,11 +2756,8 @@ class stock_move(osv.osv):
context = {}
complete, too_many, too_few = [], [], []
move_product_qty, prodlot_ids, product_avail, partial_qty, product_uoms = {}, {}, {}, {}, {}
move_product_qty, prodlot_ids, partial_qty, product_uoms = {}, {}, {}, {}
#Let us do the price calculation
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'):
@@ -2876,7 +2788,7 @@ class stock_move(osv.osv):
'picking_id' : move.picking_id.id,
'state': 'assigned',
'move_dest_id': False,
'price_unit': move.price_unit,
'price_unit': product_price,
}
prodlot_id = prodlot_ids[move.id]
if prodlot_id:
+1 -92
View File
@@ -36,9 +36,9 @@ class product_product (osv.osv):
(move_in_id, qty in uom of move out, price (converted to move out), qty in uom of move in
This should be called for only one product at a time
UoMs and currencies from the corresponding moves are converted towards that given in the params
It is good to use force_company in the header
'''
assert len(ids) == 1, _('Only the fifolifo stock matchings of one product can be calculated at a time.')
print uid, ids, qty, fifo, product_uom_id, currency_id, context
uom_obj = self.pool.get('product.uom')
currency_obj = self.pool.get('res.currency')
@@ -56,8 +56,6 @@ class product_product (osv.osv):
if not currency_id:
currency_id = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.id
print fifo
print company_id, product.id
if fifo:
move_in_ids = move_obj.search(cr, uid, [('company_id','=', company_id), ('qty_remaining', '>', 0), ('state', '=', 'done'),
('type', '=', 'in'), ('product_id', '=', product.id)],
@@ -66,7 +64,6 @@ class product_product (osv.osv):
move_in_ids = move_obj.search(cr, uid, [('company_id','=', company_id), ('qty_remaining', '>', 0), ('state', '=', 'done'),
('type', '=', 'in'), ('product_id', '=', product.id)],
order = 'date desc', context=context)
print move_in_ids
tuples = []
qty_to_go = qty
for move in move_obj.browse(cr, uid, move_in_ids, context=context):
@@ -110,94 +107,6 @@ class stock_move(osv.osv):
return res
#Overwrites method for FIFO computation
def price_computation(self, cr, uid, ids, partial_datas, context=None):
super(stock_move, self).price_computation(cr, uid, ids, partial_datas, context=context)
product_obj = self.pool.get('product.product')
matching_obj = self.pool.get('stock.move.matching')
currency_obj = self.pool.get('res.currency')
uom_obj = self.pool.get('product.uom')
#Find stock moves working in fifo/lifo price -> find stock moves out
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)
#Check we are using the right company
company_id = move.company_id.id
ctx = context.copy()
ctx['force_company'] = company_id
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
if company_id != user.company_id.id:
product = product_obj.browse(cr, uid, move.product_id.id, context=ctx)
cost_method = product.cost_method
uom_id = product.uom_id.id
if move.picking_id.type == 'out' and cost_method in ['fifo', 'lifo']:
#This price has to be put as the new standard price for the product, but needs to be converted to product UoM and currency
#convert uom of qty
product_uom_qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, uom_id)
#get_stock_matchings will convert to currency and UoM of this stock move
tuples = product_obj.get_stock_matchings_fifolifo(cr, uid, [product.id], product_qty, cost_method == 'fifo',
product_uom, move.company_id.currency_id.id, context=ctx) #Always currency of the company
print "TUPLES:", tuples
price_amount = 0.0
amount = 0.0
move_currency_id = move.company_id.currency_id.id
ctx['currency_id'] = move_currency_id
for match in tuples:
matchvals = {'move_in_id': match[0], 'qty': match[1],
'move_out_id': move.id, 'price_unit_out': match[2]}
match_id = matching_obj.create(cr, uid, matchvals, context=context)
move_in = self.browse(cr, uid, match[0], context=context)
#Reduce remaining quantity
self.write(cr, uid, match[0], { 'qty_remaining': move_in.qty_remaining - match[3]}, context=context)
price_amount += match[1] * match[2]
amount += match[1]
if product.qty_available >= product_uom_qty:
self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context)
else:
standard_price = product.standard_price
self.write(cr, uid, move.id, {'price_unit': standard_price}, context=context)
#convert price, no need of UoM conversion as it is the total price
currency_id = move.company_id.currency_id.id
currency_from = move.price_currency_id
if move.price_currency_id and (move.price_currency_id.id != currency_id):
new_price = currency_obj.compute(cr, uid, move.price_currency_id, currency_id,
price_amount)
else:
new_price = price_amount
if product.qty_available >= product_uom_qty:
product_obj.write(cr, uid, product.id, {'standard_price': new_price / product_uom_qty}, context=ctx)
# When the move is products returned to supplier or return products from customer,
# it should be treated as a normal in or out, so for every in
elif cost_method in ['fifo', 'lifo']:
#The currency in the stock move should be the currency of the company
if product_price > 0.0:
if product_currency != move.company_id.currency_id.id:
new_price = currency_obj.compute(cr, uid, product_currency, move.company_id.currency_id.id,
product_price, round=False)
else:
new_price = product_price
else:
if product_uom != uom_id:
new_price = uom_obj._compute_price(cr, uid, uom_id, new_price, product_uom)
else:
new_price = product.standard_price
self.write(cr, uid, [move.id],
{'price_unit': new_price,
'price_currency_id': move.company_id.currency_id.id})
return True
class stock_move_matching(osv.osv):
_name = "stock.move.matching"
_description = "Stock move matchings"
+12 -15
View File
@@ -127,19 +127,21 @@ class stock_partial_picking(osv.osv_memory):
def _product_cost_for_average_update(self, cr, uid, move):
"""Returns product cost and currency ID for the given move, suited for re-computing
the average product cost.
:return: map of the form::
{'cost': 123.34,
'currency': 42}
"""
# Currently, the cost on the product form is supposed to be expressed in the currency
# of the company owning the product. If not set, we fall back to the picking's company,
# which should work in simple cases.
product_currency_id = move.product_id.company_id.currency_id and move.product_id.company_id.currency_id.id
picking_currency_id = move.picking_id.company_id.currency_id and move.picking_id.company_id.currency_id.id
return {'cost': move.product_id.standard_price,
'currency': product_currency_id or picking_currency_id or False}
# need to take the standard_price from the correct company
move2 = self.pool.get("stock.move").browse(cr, uid, move.id, context={'force_company': move.company_id.id})
return {'cost': move2.product_id.standard_price,
'currency': False}
def _partial_move_for(self, cr, uid, move):
partial_move = {
@@ -169,7 +171,7 @@ class stock_partial_picking(osv.osv_memory):
line_uom = wizard_line.product_uom
move_id = wizard_line.move_id.id
#Quantiny must be Positive
#Quantity must be Positive
if wizard_line.quantity < 0:
raise osv.except_osv(_('Warning!'), _('Please provide proper Quantity.'))
@@ -190,6 +192,7 @@ class stock_partial_picking(osv.osv_memory):
without_rounding_qty = (wizard_line.quantity / line_uom.factor) * initial_uom.factor
if float_compare(qty_in_initial_uom, without_rounding_qty, precision_rounding=initial_uom.rounding) != 0:
raise osv.except_osv(_('Warning!'), _('The rounding of the initial uom does not allow you to ship "%s %s", as it would let a quantity of "%s %s" to ship and only roundings of "%s %s" is accepted by the uom.') % (wizard_line.quantity, line_uom.name, wizard_line.move_id.product_qty - without_rounding_qty, initial_uom.name, initial_uom.rounding, initial_uom.name))
stock_move.write(cr, uid, [move_id], {'price_unit': wizard_line.cost, 'price_currency_id': False})
else:
seq_obj_name = 'stock.picking.' + picking_type
move_id = stock_move.create(cr,uid,{'name' : self.pool.get('ir.sequence').get(cr, uid, seq_obj_name),
@@ -200,6 +203,7 @@ class stock_partial_picking(osv.osv_memory):
'location_id' : wizard_line.location_id.id,
'location_dest_id' : wizard_line.location_dest_id.id,
'picking_id': partial.picking_id.id,
'price_unit': wizard_line.cost,
},context=context)
stock_move.action_confirm(cr, uid, [move_id], context)
partial_data['move%s' % (move_id)] = {
@@ -211,14 +215,7 @@ class stock_partial_picking(osv.osv_memory):
if (picking_type == 'in') and (wizard_line.product_id.cost_method != 'standard'):
#TODO Maybe better ways to get company or main currency
#TODO Should not this currency be calculated at the date of the purchase order? (not the case now?)
if wizard_line.location_id.company_id:
company = wizard_line.location_id.company_id
else:
company = wizard_line.location_dest_id.company_id
currency_obj = self.pool.get("res.currency")
new_price = currency_obj.compute(cr, uid, wizard_line.currency.id, company.currency_id.id,
wizard_line.cost, round=False)
partial_data['move%s' % (wizard_line.move_id.id)].update(product_price=new_price,)
partial_data['move%s' % (wizard_line.move_id.id)].update(product_price=wizard_line.cost,)
stock_picking.do_partial(cr, uid, [partial.picking_id.id], partial_data, context=context)
return {'type': 'ir.actions.act_window_close'}