diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py index 4cf8a4fb5bf..d6ca9d98c0b 100644 --- a/addons/product_margin/product_margin.py +++ b/addons/product_margin/product_margin.py @@ -51,39 +51,43 @@ class product_product(osv.osv): states = ('open', 'paid') elif invoice_state == 'draft_open_paid': states = ('draft', 'open', 'paid') + if "force_company" in context: + company_id = context['force_company'] + else: + company_id = self.pool.get("res.users").browse(cr, uid, uid, context=context).company_id.id #TODO: here we keep the property sqlstr="""select sum(l.price_unit * l.quantity)/sum(l.quantity) as avg_unit_price, sum(l.quantity) as num_qty, sum(l.quantity * (l.price_subtotal/l.quantity)) as total, - sum(l.quantity * pt.list_price) as sale_expected, - sum(l.quantity * ip.value_float) as normal_cost + sum(l.quantity * pt.list_price) as sale_expected from account_invoice_line l left join account_invoice i on (l.invoice_id = i.id) left join product_product product on (product.id=l.product_id) - left join product_template pt on (pt.id=product.product_tmpl_id) - left join ir_property ip - on (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',pt.id) AND ip.company_id=i.company_id) - where l.product_id = %s and i.state in %s and i.type IN %s and (i.date_invoice IS NULL or (i.date_invoice>=%s and i.date_invoice<=%s)) + left join product_template pt on (pt.id = l.product_id) + where l.product_id = %s and i.state in %s and i.type IN %s and (i.date_invoice IS NULL or (i.date_invoice>=%s and i.date_invoice<=%s and i.company_id=%s)) """ invoice_types = ('out_invoice', 'in_refund') - cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to)) + cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) result = cr.fetchall()[0] res[val.id]['sale_avg_price'] = result[0] and result[0] or 0.0 res[val.id]['sale_num_invoiced'] = result[1] and result[1] or 0.0 res[val.id]['turnover'] = result[2] and result[2] or 0.0 res[val.id]['sale_expected'] = result[3] and result[3] or 0.0 res[val.id]['sales_gap'] = res[val.id]['sale_expected']-res[val.id]['turnover'] - + prod_obj = self.pool.get("product.product") + ctx=context.copy() + ctx['force_company'] = company_id + prod = prod_obj.browse(cr, uid, val.id, context=ctx) invoice_types = ('in_invoice', 'out_refund') - cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to)) + cr.execute(sqlstr, (val.id, states, invoice_types, date_from, date_to, company_id)) result = cr.fetchall()[0] res[val.id]['purchase_avg_price'] = result[0] and result[0] or 0.0 res[val.id]['purchase_num_invoiced'] = result[1] and result[1] or 0.0 res[val.id]['total_cost'] = result[2] and result[2] or 0.0 - res[val.id]['normal_cost'] = result[4] and result[4] or 0.0 - res[val.id]['purchase_gap'] = res[val.id]['normal_cost']-res[val.id]['total_cost'] + res[val.id]['normal_cost'] = prod.standard_price * res[val.id]['purchase_num_invoiced'] + res[val.id]['purchase_gap'] = res[val.id]['normal_cost'] - res[val.id]['total_cost'] if 'total_margin' in field_names: res[val.id]['total_margin'] = res[val.id]['turnover'] - res[val.id]['total_cost'] diff --git a/addons/purchase/test/fifo_price.yml b/addons/purchase/test/fifo_price.yml index 34a8b393e85..ec07782652e 100644 --- a/addons/purchase/test/fifo_price.yml +++ b/addons/purchase/test/fifo_price.yml @@ -58,9 +58,6 @@ pick_ids = self.pool.get('purchase.order').browse(cr, uid, ref("purchase_order_fifo1")).picking_ids partial_id = self.create(cr, uid, {}, context={'active_model': 'stock.picking','active_ids': [pick_ids[0].id]}) self.do_partial(cr, uid, [partial_id]) - from datetime import * - #for move in pick_ids[0].move_lines: - # self.pool.get("stock.move").write(cr, uid, [move.id], {'date': (datetime.now()+timedelta(1)).strftime('%Y-%m-%d %H:%M:%S')}) - Check the standard price of the product (fifo icecream) - @@ -329,13 +326,6 @@ line = self.browse(cr, uid, partial_id, context=context).move_ids[0] self.pool.get("stock.partial.picking.line").write(cr, uid, [line.id], {'quantity':50}) self.do_partial(cr, uid, [partial_id]) - from datetime import * - picking_id = self.pool.get("stock.picking").browse(cr, uid, ref("outgoing_fifo_shipment_neg2")).backorder_id.id - mov_ids = self.pool.get("stock.move").search(cr, uid, [('picking_id', '=', picking_id)]) - self.pool.get("stock.move").write(cr, uid, mov_ids, {'date': (datetime.now()+timedelta(seconds=3)).strftime('%Y-%m-%d %H:%M:%S')}) - print [(x.date, x.product_qty) for x in self.pool.get("stock.move").browse(cr, uid, mov_ids)] - print self.pool.get("stock.move").browse(cr, uid, ref("outgoing_shipment_fifo_icecream_neg2")).date - print self.pool.get("stock.move").browse(cr, uid, ref("outgoing_shipment_fifo_icecream_neg")).date - Print price - diff --git a/addons/stock/report/report_stock_move.py b/addons/stock/report/report_stock_move.py index 4a5315ea887..8470ab7f8e2 100644 --- a/addons/stock/report/report_stock_move.py +++ b/addons/stock/report/report_stock_move.py @@ -92,11 +92,11 @@ class report_stock_move(osv.osv): ELSE 0.0 END AS in_qty, CASE WHEN sp.type in ('out') THEN - sum(sm.product_qty * pu.factor / pu2.factor) * ip.value_float + sum(sm.product_qty * sm.price_unit) ELSE 0.0 END AS out_value, CASE WHEN sp.type in ('in') THEN - sum(sm.product_qty * pu.factor / pu2.factor) * ip.value_float + sum(sm.product_qty * sm.price_unit) ELSE 0.0 END AS in_value, min(sm.id) as sm_id, @@ -126,7 +126,6 @@ class report_stock_move(osv.osv): LEFT JOIN product_uom pu ON (sm.product_uom=pu.id) LEFT JOIN product_uom pu2 ON (sm.product_uom=pu2.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=sm.company_id) GROUP BY sm.id,sp.type, sm.date,sm.partner_id, sm.product_id,sm.state,sm.product_uom,sm.date_expected, @@ -179,15 +178,13 @@ CREATE OR REPLACE view report_stock_inventory AS ( m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location, m.company_id, m.state as state, m.prodlot_id as prodlot_id, - - coalesce(sum(-ip.value_float * m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as value, + coalesce(sum(-m.price_unit * m.product_qty)::decimal, 0.0) as value, coalesce(sum(-m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as product_qty FROM stock_move m 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 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) @@ -205,14 +202,13 @@ CREATE OR REPLACE view report_stock_inventory AS ( m.product_id as product_id, pt.categ_id as product_categ_id, l.usage as location_type, l.scrap_location as scrap_location, m.company_id, m.state as state, m.prodlot_id as prodlot_id, - coalesce(sum(ip.value_float * m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as value, + coalesce(sum(m.price_unit * m.product_qty)::decimal, 0.0) as value, coalesce(sum(m.product_qty * pu.factor / pu2.factor)::decimal, 0.0) as product_qty FROM stock_move m 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 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) diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 502ae4a508d..1ebe99416e5 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -2701,7 +2701,6 @@ class stock_move(osv.osv): if not product.id in product_avail: product_avail[product.id] = product.qty_available - # Check if out -> do stock move matchings and if fifo/lifo -> update price if move.location_id.usage == 'internal' and move.location_dest_id.usage != 'internal': @@ -2720,14 +2719,14 @@ class stock_move(osv.osv): price_amount += match[1] * match[2] amount += match[1] #Write price on out move - if product.qty_available >= product_uom_qty and product.cost_method in ['fifo', 'lifo']: + if product_avail[product.id] >= product_uom_qty and product.cost_method in ['fifo', 'lifo']: if amount > 0: self.write(cr, uid, move.id, {'price_unit': price_amount / amount}, context=context) product_obj.write(cr, uid, product.id, {'standard_price': price_amount / product_uom_qty}, context=ctx) else: raise osv.except_osv(_('Error'), "Something went wrong finding stock moves " + str(tuples) + str(self.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', context=context)) + str(product_qty) + str(product_uom) + str(move.company_id.currency_id.id)) + order = 'date, id', context=context)) + str(product_qty) + str(product_uom) + str(move.company_id.currency_id.id)) else: new_price = uom_obj._compute_price(cr, uid, product.uom_id.id, product.standard_price, product_uom) @@ -2754,7 +2753,7 @@ class stock_move(osv.osv): if product_avail[product.id] < 0.0: #Search for most recent out moves until at least one matching has been found => order date desc moves = self.search(cr, uid, [('company_id', '=', move.company_id.id), ('state','=', 'done'), ('location_id.usage','=','internal'), ('location_dest_id.usage', '!=', 'internal'), - ('product_id', '=', move.product_id.id), ('qty_remaining', '>', 0.0)], order='date', context=ctx) + ('product_id', '=', move.product_id.id), ('qty_remaining', '>', 0.0)], order='date, id', context=ctx) qty_to_go = move.product_qty for out_mov in self.browse(cr, uid, moves, context=ctx): if qty_to_go <= 0.0: