From 21000de5242308e89666b622dd8694b9e59782e9 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 4 Dec 2015 19:28:26 +0100 Subject: [PATCH] [ADD] mrp_operations_project ================================== MRP Project Link (with operations) ================================== This module links manufacturing operations with projects. It performs the following actions: * Auto-create tasks for work orders with assigned operators. * Add a tab where to encode task for the work order. * Add a link on task for the work order scheduled product. Installation ============ This modules is auto-installed when you install *mrp_operations_extension* and *mrp_project*. Usage ===== In a manufacturing order (MO) containing work orders with at least one operator assigned, when a work order is started, a task is created and assigned to the operator. In the work order form, a new tab "Operators time" is added to input the the work log. Besides, in the related tasks, the products scheduled in the work order are listed. --- mrp_operations_project/README.rst | 80 ++++++ mrp_operations_project/__init__.py | 5 + mrp_operations_project/__openerp__.py | 26 ++ mrp_operations_project/i18n/es.po | 168 +++++++++++ mrp_operations_project/models/__init__.py | 6 + .../models/mrp_production.py | 80 ++++++ mrp_operations_project/models/project_task.py | 14 + .../static/description/icon.png | Bin 0 -> 13268 bytes .../static/description/icon.svg | 260 ++++++++++++++++++ mrp_operations_project/tests/__init__.py | 5 + .../tests/test_mrp_operations_project.py | 47 ++++ .../views/mrp_production_view.xml | 56 ++++ .../views/project_task_view.xml | 23 ++ 13 files changed, 770 insertions(+) create mode 100644 mrp_operations_project/README.rst create mode 100644 mrp_operations_project/__init__.py create mode 100644 mrp_operations_project/__openerp__.py create mode 100644 mrp_operations_project/i18n/es.po create mode 100644 mrp_operations_project/models/__init__.py create mode 100644 mrp_operations_project/models/mrp_production.py create mode 100644 mrp_operations_project/models/project_task.py create mode 100644 mrp_operations_project/static/description/icon.png create mode 100644 mrp_operations_project/static/description/icon.svg create mode 100644 mrp_operations_project/tests/__init__.py create mode 100644 mrp_operations_project/tests/test_mrp_operations_project.py create mode 100644 mrp_operations_project/views/mrp_production_view.xml create mode 100644 mrp_operations_project/views/project_task_view.xml diff --git a/mrp_operations_project/README.rst b/mrp_operations_project/README.rst new file mode 100644 index 000000000..0b249fc98 --- /dev/null +++ b/mrp_operations_project/README.rst @@ -0,0 +1,80 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================================== +MRP Project Link (with operations) +================================== + +This module links manufacturing operations with projects. It performs the +following actions: + +* Auto-create tasks for work orders with assigned operators. +* Add a tab where to encode task for the work order. +* Add a link on task for the work order scheduled product. + +Installation +============ + +This modules is auto-installed when you install *mrp_operations_extension* and +*mrp_project*. + +Usage +===== + +In a manufacturing order (MO) containing work orders with at least one operator +assigned, when a work order is started, a task is created and assigned to the +operator. + +In the work order form, a new tab "Operators time" is added to input the the +work log. + +Besides, in the related tasks, the products scheduled in the work order are +listed. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/129/8.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed `feedback +`_. + +Credits +======= + +Contributors +------------ + +* Daniel Campos +* Pedro M. Baeza + +Images +------ + +* Original Odoo icons. +* Thanks to https://openclipart.org/detail/15193/Arrow%20set%20%28Comic%29 +* Thanks to https://openclipart.org/detail/151831/work-bench + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/mrp_operations_project/__init__.py b/mrp_operations_project/__init__.py new file mode 100644 index 000000000..ba6a70dfa --- /dev/null +++ b/mrp_operations_project/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import models diff --git a/mrp_operations_project/__openerp__.py b/mrp_operations_project/__openerp__.py new file mode 100644 index 000000000..7f919e4dd --- /dev/null +++ b/mrp_operations_project/__openerp__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +{ + "name": "MRP Project Link (with operations)", + "summary": "Create task for work orders with operators", + "version": "8.0.1.0.0", + "depends": [ + "mrp_project", + "mrp_operations_extension", + ], + 'license': 'AGPL-3', + "author": "OdooMRP team," + "AvanzOSC," + "Serv. Tecnol. Avanzados - Pedro M. Baeza," + "Antiun Ingeniería," + "Odoo Community Association (OCA)", + "category": "Manufacturing", + 'data': [ + "views/mrp_production_view.xml", + "views/project_task_view.xml", + ], + 'installable': True, + 'auto_install': True, +} diff --git a/mrp_operations_project/i18n/es.po b/mrp_operations_project/i18n/es.po new file mode 100644 index 000000000..c1b8a0495 --- /dev/null +++ b/mrp_operations_project/i18n/es.po @@ -0,0 +1,168 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mrp_project +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: odoomrp-wip (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-10-07 10:44+0000\n" +"PO-Revision-Date: 2015-10-09 10:50+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/odoomrp-wip-8-0/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mrp_project +#: code:addons/mrp_project/models/mrp_production.py:51 +#, python-format +msgid "" +"\n" +" Manufacturing Order: %s\n" +" Product to Produce: [%s]%s\n" +" Quantity to Produce: %s\n" +" Bill of Material: %s\n" +" Planned Date: %s\n" +" " +msgstr "\n Orden de fabricación: %s\n Producto a producir: [%s]%s\n Cantidad a producir: %s\n Lista de materiales: %s\n Fecha planificada: %s\n " + +#. module: mrp_project +#: code:addons/mrp_project/models/mrp_production.py:103 +#, python-format +msgid "" +"\n" +" Manufacturing Order: %s\n" +" Work Order: %s\n" +" Workcenter: %s\n" +" Cycle: %s\n" +" Hour: %s\n" +" " +msgstr "\n Orden de fabricación: %s\n Orden de trabajo: %s\n Centro de producción: %s\n Ciclo: %s\n Hora: %s\n " + +#. module: mrp_project +#: code:addons/mrp_project/models/mrp_production.py:129 +#, python-format +msgid "%s:: WO%s-%s:: %s" +msgstr "%s:: OT%s-%s:: %s" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_search_view +#: field:mrp.production,analytic_account_id:0 +msgid "Analytic Account" +msgstr "Cuenta analítica" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_account_analytic_line +msgid "Analytic Line" +msgstr "Línea analítica" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_form_view +msgid "General Accounting" +msgstr "Contabilidad general" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_form_view +#: view:project.task:mrp_project.project_task_mrp_form_view +msgid "MRP Data" +msgstr "Información de fabricación" + +#. module: mrp_project +#: field:procurement.order,main_project_id:0 +#: field:stock.move,main_project_id:0 +msgid "Main Project" +msgstr "Proyecto principal" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_search_view +#: view:project.project:mrp_project.project_mrp_procurement_shortcut_form_view +#: view:project.task:mrp_project.project_task_mrp_inh_search_view +msgid "Manufacturing" +msgstr "Fabricación" + +#. module: mrp_project +#: field:account.analytic.line,mrp_production_id:0 +#: model:ir.model,name:mrp_project.model_mrp_production +#: field:project.task,mrp_production_id:0 +msgid "Manufacturing Order" +msgstr "Orden de fabricación" + +#. module: mrp_project +#: model:ir.actions.act_window,name:mrp_project.act_project_2_production_all +msgid "Manufacturing Orders" +msgstr "Órdenes de fabricación" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_procurement_order +msgid "Procurement" +msgstr "Abastecimiento" + +#. module: mrp_project +#: model:ir.actions.act_window,name:mrp_project.act_project_2_procurement_all +#: view:project.project:mrp_project.project_mrp_procurement_shortcut_form_view +msgid "Procurements" +msgstr "Abastecimientos" + +#. module: mrp_project +#: view:project.task:mrp_project.project_task_mrp_form_view +#: view:project.task:mrp_project.project_task_mrp_inh_tree_view +msgid "Product to Produce" +msgstr "Producto a producir" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_mrp_production_product_line +msgid "Production Scheduled Product" +msgstr "Producto planificado de la fabricación" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_project_project +#: field:mrp.production,project_id:0 +msgid "Project" +msgstr "Proyecto" + +#. module: mrp_project +#: field:account.analytic.line,task_id:0 +msgid "Project Task" +msgstr "Tarea de proyecto" + +#. module: mrp_project +#: view:project.task:mrp_project.project_task_mrp_form_view +msgid "Scheduled Products" +msgstr "Productos planificados" + +#. module: mrp_project +#: view:project.task:mrp_project.project_task_mrp_inh_search_view +msgid "Stage" +msgstr "Etapa" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_stock_move +msgid "Stock Move" +msgstr "Movimiento de stock" + +#. module: mrp_project +#: model:ir.model,name:mrp_project.model_project_task +#: field:mrp.production.product.line,task_id:0 +msgid "Task" +msgstr "Tarea" + +#. module: mrp_project +#: field:account.analytic.line,workorder:0 +#: model:ir.model,name:mrp_project.model_mrp_production_workcenter_line +msgid "Work Order" +msgstr "Orden de trabajo" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_search_view +#: view:project.task:mrp_project.project_task_mrp_inh_search_view +msgid "Workorder" +msgstr "Orden de trabajo" + +#. module: mrp_project +#: view:account.analytic.line:mrp_project.account_analytic_line_mrp_search_view +msgid "group_analytic_account" +msgstr "" diff --git a/mrp_operations_project/models/__init__.py b/mrp_operations_project/models/__init__.py new file mode 100644 index 000000000..2c2ef74ce --- /dev/null +++ b/mrp_operations_project/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import mrp_production +from . import project_task diff --git a/mrp_operations_project/models/mrp_production.py b/mrp_operations_project/models/mrp_production.py new file mode 100644 index 000000000..428c02100 --- /dev/null +++ b/mrp_operations_project/models/mrp_production.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# (c) 2014 Daniel Campos +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import api, fields, models, _ + + +class MrpProductionWorkcenterLine(models.Model): + _inherit = 'mrp.production.workcenter.line' + + @api.multi + def _compute_task_m2m(self): + for record in self: + record.task_m2m = record.task_ids + + # needed because the one2many can't be part of a domain directly + task_m2m = fields.Many2many( + comodel_name="project.task", compute="_compute_task_m2m") + + @api.model + def _prepare_workorder_task(self, workorder): + task_domain = [ + ('mrp_production_id', '=', workorder.production_id.id), + ('workorder', '=', False)] + production_tasks = self.env['project.task'].search(task_domain) + task_descr = _(""" + Manufacturing Order: %s + Work Order: %s + Workcenter: %s + Cycle: %s + Hour: %s + """) % (workorder.production_id.name, workorder.name, + workorder.workcenter_id.name, workorder.cycle, + workorder.hour) + return { + 'mrp_production_id': workorder.production_id.id, + 'workorder': workorder.id, + 'reviewer_id': workorder.production_id.user_id.id, + 'description': task_descr, + 'project_id': workorder.production_id.project_id.id, + 'parent_ids': [(6, 0, production_tasks.ids)] + } + + @api.model + def _prepare_tasks_vals(self, workorder, task_vals): + """Method to be inheritable for having the possibility of creating + multiple tasks from one work order. + :param workorder: Work order + :param task_vals: Template task values + :return: List of dictionaries with each of the task values to create. + """ + tasks_vals = [] + wk_operation = workorder.routing_wc_line.op_wc_lines.filtered( + lambda r: r.workcenter == workorder.workcenter_id)[:1] + count = (wk_operation.op_number or + workorder.workcenter_id.op_number) + op_list = workorder.workcenter_id.operators + for i in range(count): + # Create a task for each employee + if len(op_list) > i: + task_vals['user_id'] = op_list[i].id + task_name = (_("%s:: WO%s-%s:: %s") % + (workorder.production_id.name, + str(workorder.sequence).zfill(3), + str(i).zfill(3), workorder.name)) + task_vals['name'] = task_name + tasks_vals.append(task_vals) + return tasks_vals + + @api.multi + def action_start_working(self): + res = super(MrpProductionWorkcenterLine, self).action_start_working() + task_obj = self.env['project.task'] + for workorder in self: + task_vals = self._prepare_workorder_task(workorder) + tasks_vals = self._prepare_tasks_vals(workorder, task_vals) + for task_vals in tasks_vals: + task_obj.create(task_vals) + return res diff --git a/mrp_operations_project/models/project_task.py b/mrp_operations_project/models/project_task.py new file mode 100644 index 000000000..e152ac382 --- /dev/null +++ b/mrp_operations_project/models/project_task.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# (c) 2014 Daniel Campos (danielcampos@avanzosc.es) +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp import fields, models + + +class ProjectTask(models.Model): + _inherit = 'project.task' + + workorder_scheduled_products = fields.One2many( + comodel_name="mrp.production.product.line", inverse_name='task_id', + related='workorder.product_line', store=False, + string='Scheduled Products') diff --git a/mrp_operations_project/static/description/icon.png b/mrp_operations_project/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..450d2183c6354e400919d72f817a9a80c684518a GIT binary patch literal 13268 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 + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mrp_operations_project/tests/__init__.py b/mrp_operations_project/tests/__init__.py new file mode 100644 index 000000000..6db718e98 --- /dev/null +++ b/mrp_operations_project/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from . import test_mrp_operations_project diff --git a/mrp_operations_project/tests/test_mrp_operations_project.py b/mrp_operations_project/tests/test_mrp_operations_project.py new file mode 100644 index 000000000..472e90ded --- /dev/null +++ b/mrp_operations_project/tests/test_mrp_operations_project.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Pedro M. Baeza - Serv. Tecnol. Avanzados +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp.addons.mrp_project.tests import test_mrp_project + + +class TestMrpOperationsProject(test_mrp_project.TestMrpProject): + def setUp(self): + super(TestMrpOperationsProject, self).setUp() + self.workcenter = self.env['mrp.workcenter'].create( + {'name': 'Test work center'}) + self.routing = self.env['mrp.routing'].create( + { + 'name': 'Test routing', + 'workcenter_lines': [ + (0, 0, {'name': 'Test workcenter line', + 'do_production': True, + 'workcenter_id': self.workcenter.id})], + }) + self.production.routing_id = self.routing.id + + def test_workcenter_tasks(self): + self.workcenter.op_number = 1 + self.production.signal_workflow('button_confirm') + self.production.force_production() + # start the MO (and this starts the first WO) + self.assertFalse(self.production.project_id.task_ids) + self.production.signal_workflow('button_produce') + self.assertEqual(len(self.production.workcenter_lines[0].task_m2m), 1) + self.assertEqual(len(self.production.project_id.task_ids), 2) + + def test_project_full(self): + """Don't repeat this test.""" + pass + + def test_preservation_project_with_works(self): + """Don't repeat this test.""" + pass + + def test_onchange_task(self): + """Don't repeat this test.""" + pass + + def test_button_end_work(self): + """Don't repeat this test.""" + pass diff --git a/mrp_operations_project/views/mrp_production_view.xml b/mrp_operations_project/views/mrp_production_view.xml new file mode 100644 index 000000000..710d16f1d --- /dev/null +++ b/mrp_operations_project/views/mrp_production_view.xml @@ -0,0 +1,56 @@ + + + + Project task work view for MRP + project.task.work + + + + + + + +