[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.
This commit is contained in:
Pedro M. Baeza
2015-12-04 19:28:26 +01:00
parent 56769b0dc2
commit 21000de524
13 changed files with 770 additions and 0 deletions

View File

@@ -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
<https://github.com/OCA/manufacture/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
<https://github.com/OCA/
manufacture/issues/new?body=module:%20
mrp_operations_project%0Aversion:%20
8.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Daniel Campos <danielcampos@avanzosc.es>
* Pedro M. Baeza <pedro.baeza@serviciosbaeza.com>
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.

View File

@@ -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

View File

@@ -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,
}

View File

@@ -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 <pedro.baeza@gmail.com>\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 ""

View File

@@ -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

View File

@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
# (c) 2014 Daniel Campos <danielcampos@avanzosc.es>
# (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

View File

@@ -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')

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,56 @@
<openerp>
<data>
<record model="ir.ui.view" id="project_task_work_mrp">
<field name="name">Project task work view for MRP</field>
<field name="model">project.task.work</field>
<field name="priority" eval="999"/>
<field name="arch" type="xml">
<tree editable="top">
<field name="task_id"
context="{'name_show_user': True}"
domain="[('id', 'in', parent.task_m2m[0][2])]"
on_change="onchange_task_id(task_id)"
/>
<field name="user_id"/>
<field name="date"/>
<field name="hours" widget="float_time"/>
<button name="button_end_work"
string="Stop"
type="object"
icon="STOCK_STOP"
attrs="{'invisible': [('hours', '>', 0)]}"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="mrp_production_workcenter_form_view_inherit">
<field name="name">Workorder form view (task works)</field>
<field name="model">mrp.production.workcenter.line</field>
<field name="groups_id" eval="[(6, 0, [ref('project.group_tasks_work_on_tasks')])]"/>
<field name="inherit_id" ref="mrp_operations.mrp_production_workcenter_form_view_inherit" />
<field name="arch" type="xml">
<page string="Information" position="after">
<page string="Operators time">
<field name="task_m2m" invisible="1"/>
<field name="work_ids" context="{'name_show_user': True, 'tree_view_ref': 'mrp_project.project_task_work_mrp'}"/>
</page>
</page>
</field>
</record>
<record model="ir.ui.view" id="mrp_production_project_form_view">
<field name="name">mrp.production.project.inh.form</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view" />
<field name="arch" type="xml">
<xpath expr="//field[@name='workcenter_lines']/form//page[@string='Information']" position="after">
<page string="Operators time">
<field name="task_m2m" invisible="1"/>
<field name="work_ids" context="{'name_show_user': True, 'tree_view_ref': 'mrp_project.project_task_work_mrp'}"/>
</page>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@@ -0,0 +1,23 @@
<openerp>
<data>
<record model="ir.ui.view" id="project_task_mrp_form_view">
<field name="name">project.task.mrp.inh.form</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="mrp_project.project_task_mrp_form_view"/>
<field name="arch" type="xml">
<field name="production_scheduled_products" position="after">
<field name="workorder_scheduled_products"
colspan="4"
nolabel="1"
attrs="{'invisible': [('workorder', '=', False)]}"
/>
</field>
<label for="production_scheduled_products" position="attributes">
<attribute name="invisible">1</attribute>
</label>
</field>
</record>
</data>
</openerp>