Merge pull request #60 from pedrobaeza/8.0-mrp_operations_project

[8.0] mrp_operations_project
This commit is contained in:
Pedro M. Baeza
2015-12-10 01:19:02 +01:00
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>