[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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
-
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user