diff --git a/addons/purchase/test/fifo_price.yml b/addons/purchase/test/fifo_price.yml index 35094de735b..f4973722d73 100644 --- a/addons/purchase/test/fifo_price.yml +++ b/addons/purchase/test/fifo_price.yml @@ -181,7 +181,7 @@ - Purchase order in usd - - I create a draft Purchase Order for 30000 g at 0.150 USD + I create a draft Purchase Order for 30000 g at 0.150 USD/g and 10 kg at 150 USD/kg - !record {model: purchase.order, id: purchase_order_fifo_usd}: partner_id: base.res_partner_3 @@ -255,10 +255,11 @@ return_id = self.create(cr, uid, {}, context={'active_model':'stock.picking', 'active_id': pick_ids[0].id}) res = self.create_returns(cr, uid, [return_id], context={'active_id': pick_ids[0].id}) return_move_id = self.pool.get("stock.move").search(cr, uid, [('move_returned_from','=', pick_ids[0].move_lines[0].id)]) - movepick_obj = self.pool.get("stock.partial.move") movepick_id = movepick_obj.create(cr, uid, {}, context={'active_model': 'stock.move', 'active_ids': return_move_id}) movepick_obj.do_partial(cr, uid, [movepick_id]) + import pdb + pdb.set_trace() - Check rounded price is 150.0 / 1.2834 - diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py index 4f5bd3d7b6d..fed0e2a351c 100644 --- a/addons/stock/report/report_stock_move.py +++ b/addons/stock/report/report_stock_move.py @@ -275,10 +275,20 @@ CREATE OR REPLACE view report_stock_valuation AS ( m.state as state, m.prodlot_id as prodlot_id, p.name as name, CASE WHEN ipcm.value_text in ('fifo','lifo') THEN coalesce(mm.price_unit_out * pu2.factor / pu.factor, 0.0) - ELSE coalesce(m.price_unit * pu2.factor / pu.factor::decimal, 0.0) END AS price_unit, + ELSE coalesce(m.price_unit * pu2.factor / pu.factor::decimal, 0.0) END AS price_unit, coalesce(sum(-ip.value_float * m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as value, - CASE WHEN ipcm.value_text in ('fifo', 'lifo') THEN coalesce(sum(-mm.price_unit_out * mm.qty)::decimal, 0.0) - ELSE coalesce(sum(-m.price_unit * mm.qty)::decimal, 0.0) END as move_value, + CASE WHEN ipcm.value_text IS NOT NULL THEN + CASE WHEN ipcm.value_text in ('fifo', 'lifo') THEN coalesce(sum(-mm.price_unit_out * mm.qty)::decimal, 0.0) + ELSE coalesce(sum(-m.price_unit * mm.qty)::decimal, 0.0) END + ELSE + CASE WHEN ipcmdef.value_text IS NOT NULL THEN + CASE WHEN ipcmdef.value_text in ('fifo', 'lifo') THEN coalesce(sum(-mm.price_unit_out * mm.qty)::decimal, 0.0) + ELSE coalesce(sum(-m.price_unit * mm.qty)::decimal, 0.0) END + ELSE + CASE WHEN ipcmdef2.value_text in ('fifo', 'lifo') THEN coalesce(sum(-mm.price_unit_out * mm.qty)::decimal, 0.0) + ELSE coalesce(sum(-m.price_unit * mm.qty)::decimal, 0.0) END + END + END as move_value, coalesce(sum(-mm.qty * pu.factor / pu2.factor)::decimal, 0.0) as product_qty, l_other.usage as location_dest_type, l.usage as location_src_type, @@ -290,16 +300,21 @@ CREATE OR REPLACE view report_stock_valuation AS ( LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id) LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',pt.id) AND ip.company_id=m.company_id) LEFT JOIN ir_property ipcm ON (ipcm.name='cost_method' and ipcm.res_id=CONCAT('product.template,',pt.id) AND ipcm.company_id=m.company_id) + LEFT JOIN ir_property ip_def ON (ip_def.name='standard_price' AND ip_def.res_id IS NULL AND ip_def.company_id=m.company_id) + LEFT JOIN ir_property ip_def2 ON (ip_def2.name='standard_price' AND ip_def2.res_id IS NULL AND ip_def2.company_id IS NULL) + LEFT JOIN ir_property ipcmdef ON (ipcmdef.name='cost_method' AND ipcmdef.res_id IS NULL AND ipcmdef.company_id=m.company_id) + LEFT JOIN ir_property ipcmdef2 ON (ipcmdef2.name='cost_method' AND ipcmdef2.res_id IS NULL AND ipcmdef2.company_id IS NULL) LEFT JOIN product_uom pu ON (pt.uom_id=pu.id) LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id) LEFT JOIN product_uom u ON (m.product_uom=u.id) LEFT JOIN stock_location l ON (m.location_id=l.id) - LEFT JOIN stock_location l_other ON (m.location_dest_id=l_other.id) + LEFT JOIN stock_location l_other ON (m.location_dest_id=l_other.id) WHERE m.state != 'cancel' and mm.move_out_id=m.id GROUP BY p.name, mm.id, mm.move_out_id, m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM'), - pu2.factor, pu.factor, ipcm.value_text, m.qty_remaining, l_other.usage + pu2.factor, pu.factor, ipcm.value_text, m.qty_remaining, l_other.usage, + ipcmdef.value_text, ipcmdef2.value_text ) UNION ALL ( SELECT -min(m.id) as id, m.date as date, @@ -322,18 +337,20 @@ CREATE OR REPLACE view report_stock_valuation AS ( LEFT JOIN stock_picking p ON (m.picking_id=p.id) LEFT JOIN product_product pp ON (m.product_id=pp.id) LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id) - LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',pt.id) AND ip.company_id=m.company_id) - LEFT JOIN ir_property ipcm ON (ipcm.name='cost_method' AND ipcm.res_id=CONCAT('product.tempalte,',pt.id) AND ipcm.company_id=m.company_id) LEFT JOIN product_uom pu ON (pt.uom_id=pu.id) LEFT JOIN product_uom pu2 ON (m.product_uom=pu2.id) LEFT JOIN product_uom u ON (m.product_uom=u.id) LEFT JOIN stock_location l ON (m.location_dest_id=l.id) - LEFT JOIN stock_location l_other ON (m.location_id=l_other.id) - WHERE m.state != 'cancel' + LEFT JOIN stock_location l_other ON (m.location_id=l_other.id), + ir_property ip, ir_property ipcm + WHERE m.state != 'cancel' and + ip.name='standard_price' AND (ip.res_id = CONCAT('product.template,',pt.id) or ip.res_id IS NULL) AND (ip.company_id=m.company_id OR ip.company_id IS NULL) and + ipcm.name='cost_method' AND (ipcm.res_id = CONCAT('product.template,',pt.id) or ipcm.res_id IS NULL) AND (ipcm.company_id=m.company_id OR ipcm.company_id IS NULL) GROUP BY p.name, m.id, m.product_id, m.product_uom, pt.categ_id, m.partner_id, m.location_id, m.location_dest_id, m.prodlot_id, m.date, m.state, l.usage, l.scrap_location, m.company_id, pt.uom_id, to_char(m.date, 'YYYY'), to_char(m.date, 'MM'), - pu2.factor, pu.factor, m.qty_remaining, l_other.usage, ipcm.value_text, ip.value_float + pu2.factor, pu.factor, m.qty_remaining, l_other.usage, ipcm.value_text, ip.value_float, ip.company_id, ipcm.company_id, ip.res_id, ipcm.res_id + order by ip.res_id ASC, ip.company_id ASC, ipcm.res_id ASC, ipcm.company_id ) ); """) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 9dd9e470299..a0aab51685a 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2705,6 +2705,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) #TODO Would be better to use price_currency_id for migration? + print tuples price_amount = 0.0 amount = 0.0 #Write stock matchings diff --git a/addons/stock/stock_fifo_lifo.py b/addons/stock/stock_fifo_lifo.py index 94d0cd00408..c8804486728 100644 --- a/addons/stock/stock_fifo_lifo.py +++ b/addons/stock/stock_fifo_lifo.py @@ -36,7 +36,7 @@ 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 + It is good to use force_company in the context ''' assert len(ids) == 1, _('Only the fifolifo stock matchings of one product can be calculated at a time.') uom_obj = self.pool.get('product.uom') @@ -64,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'), ('location_id.usage', '!=', 'internal'), ('location_dest_id.usage', '=', 'internal'), ('product_id', '=', product.id)], order = 'date desc', context=context) - tuples = [] qty_to_go = qty for move in move_obj.browse(cr, uid, move_in_ids, context=context): @@ -78,8 +77,7 @@ class product_product (osv.osv): move.price_unit, round=False) else: new_price = move.price_unit - new_price = uom_obj._compute_price(cr, uid, uom_from, new_price, - product_uom_id) + new_price = uom_obj._compute_price(cr, uid, uom_from, new_price, product_uom_id) if qty_to_go - product_qty >= 0: tuples.append((move.id, product_qty, new_price, qty_from),) qty_to_go -= product_qty @@ -125,6 +123,8 @@ class stock_move(osv.osv): if move_in: #Search all matchings matches = match_obj.search(cr, uid, [('move_in_id', '=', move.id)], context=context) + print [(x.move_in_id.product_qty, x.qty, x.move_in_id.price_unit, x.move_in_id.date) for x in match_obj.browse(cr, uid, matches, context=context)] + qty = move.product_qty for match in match_obj.browse(cr, uid, matches, context=context): qty -= uom_obj._compute_qty(cr, uid, match.move_out_id.product_uom.id, match.qty, move.product_uom.id) @@ -132,9 +132,13 @@ class stock_move(osv.osv): elif move_out: #Search all matchings, but from the other side matches = match_obj.search(cr, uid, [('move_out_id', '=', move.id)], context=context) + print [(x.move_in_id.product_qty, x.qty, x.move_in_id.price_unit, x.move_in_id.date) for x in match_obj.browse(cr, uid, matches, context=context)] qty = move.product_qty for match in match_obj.browse(cr, uid, matches, context=context): qty -= match.qty + if qty < 0: + import pdb + pdb.set_trace() res[move.id] = qty return res _inherit = 'stock.move' @@ -147,19 +151,6 @@ class stock_move(osv.osv): -# def create(self, cr, uid, vals, context=None): -# if 'product_qty' in vals: -# vals['qty_remaining'] = vals['product_qty'] -# res = super(stock_move, self).create(cr, uid, vals, context=context) -# return res -# -# def write(self, cr, uid, ids, vals, context=None): -# if 'product_qty' in vals: -# vals['qty_remaining'] = vals['product_qty'] -# res = super(stock_move, self).write(cr, uid, ids, vals, context=context) -# return res - - class stock_move_matching(osv.osv): _name = "stock.move.matching" _description = "Stock move matchings"