From a533da1b11b4ab573565da4895c378c7da3c46d2 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Sat, 13 Feb 2016 14:33:14 +0100 Subject: [PATCH] [FIX] mrp_production_real_cost: Update costs when operation time lines change Up to now, you have to rely only on play/pause/stop controls, and the time passed between them for having real costs reflected, but there are manufacturing processes that reflects their times not directly, but afterwards introducing the summaries. This commit allows to reflect the changes on costs when you edit up times. --- mrp_production_real_cost/__openerp__.py | 2 +- .../models/mrp_production_workcenter_line.py | 46 +++++++++++-------- .../tests/test_mrp_production_real_cost.py | 32 +++++++++---- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/mrp_production_real_cost/__openerp__.py b/mrp_production_real_cost/__openerp__.py index 54c669a97..0587715eb 100644 --- a/mrp_production_real_cost/__openerp__.py +++ b/mrp_production_real_cost/__openerp__.py @@ -6,7 +6,7 @@ { "name": "Real costs in manufacturing orders", - "version": "8.0.1.0.0", + "version": "8.0.1.0.1", "depends": [ "project_timesheet", "mrp_project", 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 fcd8904e3..d32c6fea2 100644 --- a/mrp_production_real_cost/models/mrp_production_workcenter_line.py +++ b/mrp_production_real_cost/models/mrp_production_workcenter_line.py @@ -21,24 +21,32 @@ class MrpProductionWorkcenterLine(models.Model): task_obj = self.env['project.task'] if self.workcenter_id.costs_hour > 0.0: hour_uom = self.env.ref('product.product_uom_hour', False) - operation_line = self.operation_time_lines[-1] production = self.production_id workcenter = self.workcenter_id product = workcenter.product_id - journal_id = workcenter.costs_journal_id or self.env.ref( + journal = workcenter.costs_journal_id or self.env.ref( 'mrp.analytic_journal_machines', False) + # Delete previous uptime analytic entries + analytic_line_obj.search( + [('mrp_production_id', '=', production.id), + ('workorder', '=', self.id), + ('journal_id', '=', journal.id), + ('name', '=like', '%%%s' % _('HOUR'))] + ).unlink() + # Recreate a new entry with the total uptime name = "-".join([production.name or '', workcenter.code or '', self.routing_wc_line.routing_id.code or '', product.default_code or '', _('HOUR')]) + uptime = sum(self.mapped('operation_time_lines.uptime')) general_acc = workcenter.costs_general_account_id or False - price = -(workcenter.costs_hour * operation_line.uptime) + price = -workcenter.costs_hour * uptime if price: analytic_vals = production._prepare_real_cost_analytic_line( - journal_id, name, production, product, + journal, name, production, product, general_account=general_acc, workorder=self, - qty=operation_line.uptime, amount=price) + qty=uptime, amount=price) task = task_obj.search( [('mrp_production_id', '=', production.id), ('workorder', '=', False)]) @@ -93,22 +101,24 @@ class MrpProductionWorkcenterLine(models.Model): @api.multi def action_start_working(self): - result = super(MrpProductionWorkcenterLine, - self).action_start_working() + result = super( + MrpProductionWorkcenterLine, self).action_start_working() self._create_pre_post_cost_lines(cost_type='pre') return result @api.multi - def action_pause(self): - result = super(MrpProductionWorkcenterLine, self).action_pause() - self._create_analytic_line() - return result + def action_done(self): + self._create_pre_post_cost_lines(cost_type='post') + return super(MrpProductionWorkcenterLine, self).action_done() + + +class OperationTimeLine(models.Model): + _inherit = 'operation.time.line' @api.multi - def action_done(self): - not_paused_records = self.filtered(lambda x: x.state != 'pause') - not_paused_records._write_end_date_operation_line() - self._create_analytic_line() - self._create_pre_post_cost_lines(cost_type='post') - result = super(MrpProductionWorkcenterLine, self).action_done() - return result + def write(self, vals): + """Recreate costs when updating manually the uptime.""" + res = super(OperationTimeLine, self).write(vals) + if 'start_date' in vals or 'end_date' in vals: + self.operation_time._create_analytic_line() + return res diff --git a/mrp_production_real_cost/tests/test_mrp_production_real_cost.py b/mrp_production_real_cost/tests/test_mrp_production_real_cost.py index 444caec60..de319e0f8 100644 --- a/mrp_production_real_cost/tests/test_mrp_production_real_cost.py +++ b/mrp_production_real_cost/tests/test_mrp_production_real_cost.py @@ -6,7 +6,6 @@ from openerp.tests import common from openerp import fields from datetime import timedelta -import time class TestMrpProductionRealCost(common.TransactionCase): @@ -26,18 +25,31 @@ class TestMrpProductionRealCost(common.TransactionCase): line.pre_cost = 10 line.post_cost = 20 line.signal_workflow('button_start_working') - line.operation_time_lines[-1].start_date = self.start_date - self.assertEqual( - len(self.production.analytic_line_ids.filtered('amount')), 1) - time.sleep(1) + line.operation_time_lines[-1].start_date = ( + self.start_date - timedelta(hours=1)) + analytic_line = self.production.analytic_line_ids.filtered('amount') + # This should have the pre-operation cost + self.assertEqual(len(analytic_line), 1) line.signal_workflow('button_pause') - self.assertEqual( - len(self.production.analytic_line_ids.filtered('amount')), 2) + analytic_lines = self.production.analytic_line_ids.filtered('amount') + # This should have the pre-operation cost and uptime line + self.assertEqual(len(analytic_lines), 2) + prev_amount = analytic_lines[-1].amount line.signal_workflow('button_resume') - time.sleep(1) + line.operation_time_lines[-1].start_date = ( + self.start_date - timedelta(hours=2)) line.signal_workflow('button_done') - self.assertEqual( - len(self.production.analytic_line_ids.filtered('amount')), 3) + analytic_lines = self.production.analytic_line_ids.filtered('amount') + # This should have the pre- cost, uptime line and post- cost + self.assertEqual(len(analytic_lines), 3) + self.assertNotEqual(analytic_lines[-1].amount, prev_amount) + prev_amount = analytic_lines[-1].amount + # Change manually an uptime to see if costs change + line.operation_time_lines[-1].end_date = ( + self.start_date + (timedelta(hours=3))) + analytic_lines = self.production.analytic_line_ids.filtered('amount') + self.assertNotEqual(analytic_lines[-1].amount, prev_amount) + # Change analytic entries to see if production real_cost field changes self.production.analytic_line_ids[:1].amount = -10 self.assertTrue(self.production.real_cost)