From 5d30b9317ef38cc7a5b6d193c5acf75a074dcfc8 Mon Sep 17 00:00:00 2001 From: agaldona Date: Wed, 20 May 2015 15:31:46 +0200 Subject: [PATCH] [IMP] mrp_production_real_cost: Use variant cost price --- .../models/mrp_production.py | 19 ++- .../models/mrp_production_workcenter_line.py | 52 ++---- mrp_production_real_cost/models/stock_move.py | 151 ++++++------------ 3 files changed, 79 insertions(+), 143 deletions(-) diff --git a/mrp_production_real_cost/models/mrp_production.py b/mrp_production_real_cost/models/mrp_production.py index 984ac116b..bfe7c544c 100644 --- a/mrp_production_real_cost/models/mrp_production.py +++ b/mrp_production_real_cost/models/mrp_production.py @@ -23,12 +23,17 @@ class MrpProduction(models.Model): _inherit = 'mrp.production' + @api.multi + def calc_mrp_real_cost(self): + self.ensure_one() + return sum([-line.amount for line in + self.analytic_line_ids.filtered(lambda l: l.amount < 0)]) + @api.one @api.depends('analytic_line_ids', 'analytic_line_ids.amount', 'product_qty') def get_real_cost(self): - self.real_cost = sum([-line.amount for line in - self.analytic_line_ids]) + self.real_cost = self.calc_mrp_real_cost() self.unit_real_cost = self.real_cost / self.product_qty real_cost = fields.Float("Total Real Cost", compute="get_real_cost", @@ -39,9 +44,11 @@ class MrpProduction(models.Model): @api.multi def action_production_end(self): res = super(MrpProduction, self).action_production_end() - analytic_line_obj = self.env['account.analytic.line'] for record in self: - cost_lines = analytic_line_obj.search([('mrp_production_id', '=', - record.id)]) - record.real_cost = sum([-line.amount for line in cost_lines]) + mrp_cost = record.calc_mrp_real_cost() + done_lines = record.move_created_ids2.filtered(lambda l: + l.state == 'done') + done_lines.create_produce_cost_line(mrp_cost) + record.real_cost = mrp_cost + done_lines.product_price_update_production_done() return res diff --git a/mrp_production_real_cost/models/mrp_production_workcenter_line.py b/mrp_production_real_cost/models/mrp_production_workcenter_line.py index c58d3f0b9..356e98890 100644 --- a/mrp_production_real_cost/models/mrp_production_workcenter_line.py +++ b/mrp_production_real_cost/models/mrp_production_workcenter_line.py @@ -17,7 +17,6 @@ ############################################################################## from openerp import models, api -from datetime import datetime class MrpProductionWorkcenterLine(models.Model): @@ -28,7 +27,6 @@ class MrpProductionWorkcenterLine(models.Model): def _create_analytic_line(self): self.ensure_one() analytic_line_obj = self.env['account.analytic.line'] - property_obj = self.env['ir.property'] task_obj = self.env['project.task'] if self.workcenter_id.costs_hour > 0.0: hour_uom = self.env.ref('product.product_uom_hour', False) @@ -36,46 +34,22 @@ class MrpProductionWorkcenterLine(models.Model): production = self.production_id workcenter = self.workcenter_id product = workcenter.product_id - journal_id = workcenter.costs_journal_id or False - if not journal_id: - journal_id = self.env.ref( - 'mrp_production_project_estimated_cost.analytic_journal_' - 'machines', False) - analytic_account_id = production.analytic_account_id.id or False - task_id = False - if production: - task = task_obj.search([('mrp_production_id', '=', - production.id), - ('wk_order', '=', False)]) - if task: - task_id = task[0].id + journal_id = workcenter.costs_journal_id or self.env.ref( + 'mrp_production_project_estimated_cost.analytic_journal_' + 'machines', False) name = ((production.name or '') + '-' + (self.routing_wc_line.operation.code or '') + '-' + (product.default_code or '')) - general_acc = ( - workcenter.costs_general_account_id.id or - product.property_account_expense.id or - product.categ_id.property_account_expense_categ.id or - property_obj.get('property_account_expense_categ', - 'product.category')) - price = workcenter.costs_hour - analytic_vals = {'name': name, - 'ref': name, - 'date': datetime.now().strftime('%Y-%m-%d'), - 'user_id': self.env.uid, - 'product_id': product.id, - 'product_uom_id': hour_uom.id, - 'amount': -(price * operation_line.uptime), - 'unit_amount': operation_line.uptime, - 'journal_id': journal_id.id, - 'account_id': analytic_account_id, - 'general_account_id': general_acc, - 'task_id': task_id, - 'mrp_production_id': production.id or False, - 'workorder': self.id, - 'estim_avg_cost': 0.0, - 'estim_std_cost': 0.0 - } + general_acc = workcenter.costs_general_account_id or False + price = -(workcenter.costs_hour * operation_line.uptime) + analytic_vals = production._prepare_cost_analytic_line( + journal_id, name, production, product, + general_account=general_acc, workorder=self, + qty=operation_line.uptime, amount=price) + task = task_obj.search([('mrp_production_id', '=', production.id), + ('wk_order', '=', False)]) + analytic_vals['task_id'] = task and task[0].id or False + analytic_vals['product_uom_id'] = hour_uom.id analytic_line = analytic_line_obj.create(analytic_vals) return analytic_line diff --git a/mrp_production_real_cost/models/stock_move.py b/mrp_production_real_cost/models/stock_move.py index ee907b771..0c5d55f70 100644 --- a/mrp_production_real_cost/models/stock_move.py +++ b/mrp_production_real_cost/models/stock_move.py @@ -17,139 +17,94 @@ ############################################################################## from openerp import models, api -from datetime import datetime -import math class StockMove(models.Model): _inherit = 'stock.move' + @api.multi + def create_produce_cost_line(self, amount): + task_obj = self.env['project.task'] + analytic_line_obj = self.env['account.analytic.line'] + for record in self: + if amount > 0.0: + if record.production_id: + product = record.product_id + production = record.production_id + journal_id = self.env.ref( + 'mrp_production_project_estimated_cost.analytic_' + 'journal_materials', False) + name = ('Final product - ' + (production.name or '') + + '-' + (product.default_code or '')) + vals = production._prepare_cost_analytic_line( + journal_id, name, production, product, + qty=record.product_qty, amount=amount) + task = task_obj.search( + [('mrp_production_id', '=', production.id), + ('wk_order', '=', False)]) + vals['task_id'] = task and task[0].id or False + analytic_line_obj.create(vals) + @api.multi def action_consume(self, product_qty, location_id=False, restrict_lot_id=False, restrict_partner_id=False, consumed_for=False): task_obj = self.env['project.task'] - property_obj = self.env['ir.property'] analytic_line_obj = self.env['account.analytic.line'] result = super(StockMove, self).action_consume( product_qty, location_id=location_id, restrict_lot_id=restrict_lot_id, restrict_partner_id=restrict_partner_id, consumed_for=consumed_for) for record in self: - price = record.product_id.standard_price + price = record.product_id.cost_price if price > 0.0: - if record.production_id or record.raw_material_production_id: + if record.raw_material_production_id: product = record.product_id journal_id = self.env.ref( 'mrp_production_project_estimated_cost.analytic_' 'journal_materials', False) - production_id = False - analytic_account_id = False - task_id = False - if record.production_id: - production = record.production_id - elif record.raw_material_production_id: - production = record.raw_material_production_id - if production: - production_id = production.id - analytic_account_id = production.analytic_account_id.id - task = task_obj.search( - [('mrp_production_id', '=', production_id), - ('wk_order', '=', False)]) - if task: - task_id = task[0].id + production = record.raw_material_production_id name = ( (production.name or '') + '-' + (record.work_order.routing_wc_line.operation.code or '') + '-' + (product.default_code or '')) - general_account = ( - product.property_account_expense.id or - product.categ_id.property_account_expense_categ.id or - property_obj.get('property_account_expense_categ', - 'product.category')) - date = datetime.now().strftime('%Y-%m-%d') - uom_id = record.product_id.uom_id.id - if record.raw_material_production_id: - analytic_vals = {'name': name, - 'ref': name, - 'date': date, - 'user_id': self.env.uid, - 'product_id': product.id, - 'product_uom_id': uom_id, - 'amount': -(price * product_qty), - 'unit_amount': product_qty, - 'journal_id': journal_id.id, - 'account_id': analytic_account_id, - 'general_account_id': general_account, - 'task_id': task_id, - 'mrp_production_id': production_id, - 'workorder': record.work_order.id, - 'estim_avg_cost': 0.0, - 'estim_std_cost': 0.0 - } - analytic_line_obj.create(analytic_vals) - elif record.production_id: - amount = 0.0 - unit_amount = 0.0 - for wc in production.workcenter_lines: - cycle_cost = wc.workcenter_id.costs_cycle - cycle_units = wc.workcenter_id.capacity_per_cycle - cycle = int(math.ceil(product_qty / cycle_units)) - amount += cycle * cycle_cost - unit_amount += cycle - analytic_vals = {'name': name, - 'ref': name, - 'date': date, - 'user_id': self.env.uid, - 'product_id': product.id, - 'product_uom_id': uom_id, - 'amount': amount, - 'unit_amount': unit_amount, - 'journal_id': journal_id.id, - 'account_id': analytic_account_id, - 'general_account_id': general_account, - 'task_id': task_id, - 'mrp_production_id': production_id, - 'workorder': record.work_order.id, - 'estim_avg_cost': 0.0, - 'estim_std_cost': 0.0 - } - analytic_line_obj.create(analytic_vals) + analytic_vals = production._prepare_cost_analytic_line( + journal_id, name, production, product, + workorder=record.work_order, qty=record.product_qty, + amount=(-price * record.product_qty)) + task = task_obj.search( + [('mrp_production_id', '=', production.id), + ('wk_order', '=', False)]) + analytic_vals['task_id'] = task and task[0].id or False + analytic_line_obj.create(analytic_vals) return result @api.multi - def product_price_update_before_done(self): - analytic_line_obj = self.env['account.analytic.line'] - super(StockMove, self).product_price_update_before_done() + def product_price_update_production_done(self): for move in self: - # adapt standard price on production final moves if the - # product cost_method is 'average' if (move.production_id) and (move.product_id.cost_method == 'average'): - analytic_lines = analytic_line_obj.search( - [('mrp_production_id', '=', move.production_id.id)]) - prod_total_cost = sum([-line.amount for line in - analytic_lines]) + prod_total_cost = move.production_id.calc_mrp_real_cost() product = move.product_id product_avail = product.qty_available - amount_unit = product.standard_price - new_std_price = ((amount_unit * product_avail + + amount_unit = product.cost_price + template_avail = product.product_tmpl_id.qty_available + template_price = product.standard_price + new_cost_price = ((amount_unit * product_avail + prod_total_cost) / - ((product_avail >= 0.0 and product_avail or + ((product_avail >= 0.0 and product_avail or + 0.0) + move.product_qty)) + new_std_price = ((template_price * template_avail + + prod_total_cost) / + ((template_avail >= 0.0 and template_avail or 0.0) + move.product_qty)) - # Write the standard price, as SUPERUSER_ID because a warehouse - # manager may not have the right to write on products - product.sudo().write({'standard_price': new_std_price}) + product.sudo().write({'cost_price': new_cost_price, + 'standard_price': new_std_price}) - @api.multi - def get_price_unit(self): - self.ensure_one() - if self.production_id: - analytic_line_obj = self.env['account.analytic.line'] - analytic_lines = analytic_line_obj.search( - [('mrp_production_id', '=', self.production_id.id)]) - return (sum([-line.amount for line in analytic_lines]) / - self.product_qty) + @api.model + def get_price_unit(self, move): + if move.production_id: + return move.production_id.calc_mrp_real_cost() / move.product_qty else: - return super(StockMove, self).get_price_unit() + return super(StockMove, self).get_price_unit(move)