-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] mrp_routing_workcenter_capacity: In MRP operations new fields c…
…apacity, time before production, and time after production.
- Loading branch information
1 parent
8da8770
commit 66d57bc
Showing
12 changed files
with
397 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
language: python | ||
|
||
python: | ||
- "3.5" | ||
- "3.6" | ||
|
||
sudo: false | ||
cache: pip | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
.. 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 Routing workcenter capacity | ||
=============================== | ||
|
||
* In MRP operations new fields capacity, time before production, and time after | ||
production. | ||
* When calculating the "Expected Duration" of the OF work orders, it will take | ||
the capacity defined in the operation, not the one defined in the Work | ||
Center. | ||
* The fields "Time before prod.", "Time after prod." defined in the operation | ||
also participate in the calculation, if they are informed. If they are not | ||
informed, those of the Work Center will be used. | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/avanzosc/mrp-addons/issues>`_. In case of trouble, | ||
please check there if your issue has already been reported. If you spotted | ||
it first, help us smash it by providing detailed and welcomed feedback. | ||
|
||
Do not contact contributors directly about support or help with technical issues. | ||
|
||
Credits | ||
======= | ||
|
||
Contributors | ||
------------ | ||
|
||
* Ana Juaristi <anajuaristi@avanzosc.es> | ||
* Alfredo de la Fuente <alfredodelafuente@avanzosc.es> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Copyright 2021 Alfredo de la Fuente - AvanzOSC | ||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). | ||
{ | ||
"name": "MRP Routing Workcenter Capacity", | ||
"version": '14.0.1.0.0', | ||
"author": "Avanzosc", | ||
"license": "AGPL-3", | ||
"category": "Manufacturing/Manufacturing", | ||
"depends": [ | ||
"mrp", | ||
], | ||
"data": [ | ||
'views/mrp_routing_workcenter_views.xml' | ||
], | ||
"installable": True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Translation of Odoo Server. | ||
# This file contains the translation of the following modules: | ||
# * mrp_routing_workcenter_capacity | ||
# | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: Odoo Server 14.0\n" | ||
"Report-Msgid-Bugs-To: \n" | ||
"POT-Creation-Date: 2021-07-15 14:18+0000\n" | ||
"PO-Revision-Date: 2021-07-15 14:18+0000\n" | ||
"Last-Translator: \n" | ||
"Language-Team: \n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: \n" | ||
"Plural-Forms: \n" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__capacity | ||
msgid "Capacity" | ||
msgstr "Capacidad" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__display_name | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder__display_name | ||
msgid "Display Name" | ||
msgstr "Nombre mostrado" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__id | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder__id | ||
msgid "ID" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter____last_update | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder____last_update | ||
msgid "Last Modified on" | ||
msgstr "Última modificación el" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: code:addons/mrp_routing_workcenter_capacity/models/mrp_routing_workcenter.py:0 | ||
#, python-format | ||
msgid "The capacity must be strictly positive." | ||
msgstr "La capacidad debe ser estrictamente positiva. " | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_stop | ||
msgid "Time after prod." | ||
msgstr "Tiempo después producción" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_start | ||
msgid "Time before prod." | ||
msgstr "Tiempo antes producción" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,help:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_stop | ||
msgid "Time in minutes for the cleaning." | ||
msgstr "Tiempo en minutos para la limpieza." | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,help:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_start | ||
msgid "Time in minutes for the setup." | ||
msgstr "Tiempo en minutos para la instalación." | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model,name:mrp_routing_workcenter_capacity.model_mrp_routing_workcenter | ||
msgid "Work Center Usage" | ||
msgstr "Utilización del centro de producción" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model,name:mrp_routing_workcenter_capacity.model_mrp_workorder | ||
msgid "Work Order" | ||
msgstr "Orden de trabajo" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model_terms:ir.ui.view,arch_db:mrp_routing_workcenter_capacity.mrp_routing_workcenter_form_view | ||
msgid "minutes" | ||
msgstr "minutos" | ||
|
80 changes: 80 additions & 0 deletions
80
mrp_routing_workcenter_capacity/i18n/mrp_routing_workcenter_capacity.pot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Translation of Odoo Server. | ||
# This file contains the translation of the following modules: | ||
# * mrp_routing_workcenter_capacity | ||
# | ||
msgid "" | ||
msgstr "" | ||
"Project-Id-Version: Odoo Server 14.0\n" | ||
"Report-Msgid-Bugs-To: \n" | ||
"POT-Creation-Date: 2021-07-15 14:18+0000\n" | ||
"PO-Revision-Date: 2021-07-15 14:18+0000\n" | ||
"Last-Translator: \n" | ||
"Language-Team: \n" | ||
"MIME-Version: 1.0\n" | ||
"Content-Type: text/plain; charset=UTF-8\n" | ||
"Content-Transfer-Encoding: \n" | ||
"Plural-Forms: \n" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__capacity | ||
msgid "Capacity" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__display_name | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder__display_name | ||
msgid "Display Name" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__id | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder__id | ||
msgid "ID" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter____last_update | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_workorder____last_update | ||
msgid "Last Modified on" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: code:addons/mrp_routing_workcenter_capacity/models/mrp_routing_workcenter.py:0 | ||
#, python-format | ||
msgid "The capacity must be strictly positive." | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_stop | ||
msgid "Time after prod." | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,field_description:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_start | ||
msgid "Time before prod." | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,help:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_stop | ||
msgid "Time in minutes for the cleaning." | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model.fields,help:mrp_routing_workcenter_capacity.field_mrp_routing_workcenter__time_start | ||
msgid "Time in minutes for the setup." | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model,name:mrp_routing_workcenter_capacity.model_mrp_routing_workcenter | ||
msgid "Work Center Usage" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model:ir.model,name:mrp_routing_workcenter_capacity.model_mrp_workorder | ||
msgid "Work Order" | ||
msgstr "" | ||
|
||
#. module: mrp_routing_workcenter_capacity | ||
#: model_terms:ir.ui.view,arch_db:mrp_routing_workcenter_capacity.mrp_routing_workcenter_form_view | ||
msgid "minutes" | ||
msgstr "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import mrp_routing_workcenter | ||
from . import mrp_workorder |
49 changes: 49 additions & 0 deletions
49
mrp_routing_workcenter_capacity/models/mrp_routing_workcenter.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Copyright 2021 Alfredo de la fuente - AvanzOSC | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
from odoo import models, fields, api, exceptions, _ | ||
|
||
|
||
class MrpRoutingWorkcenter(models.Model): | ||
_inherit = 'mrp.routing.workcenter' | ||
|
||
capacity = fields.Float( | ||
string='Capacity', default=1.0) | ||
time_start = fields.Float( | ||
string='Time before prod.', help="Time in minutes for the setup.") | ||
time_stop = fields.Float( | ||
string='Time after prod.', help="Time in minutes for the cleaning.") | ||
|
||
@api.depends('time_cycle_manual', 'time_mode', 'workorder_ids') | ||
def _compute_time_cycle(self): | ||
result = super(MrpRoutingWorkcenter, self)._compute_time_cycle() | ||
manual_ops = self.filtered( | ||
lambda operation: operation.time_mode == 'manual') | ||
for operation in manual_ops: | ||
operation.time_cycle = operation.time_cycle_manual | ||
operations = self - manual_ops | ||
for operation in operations.filtered(lambda x: x.capacity): | ||
data = self.env['mrp.workorder'].read_group( | ||
[('operation_id', '=', operation.id), | ||
('qty_produced', '>', 0), | ||
('state', '=', 'done') | ||
], | ||
['operation_id', 'duration', 'qty_produced'], | ||
['operation_id'], limit=operation.time_mode_batch) | ||
count_data = dict( | ||
(item['operation_id'][0], | ||
(item['duration'], | ||
item['qty_produced'])) for item in data) | ||
if count_data.get(operation.id) and count_data[operation.id][1]: | ||
operation.time_cycle = ( | ||
count_data[operation.id][0] / | ||
count_data[operation.id][1]) * (operation.capacity or 1.0) | ||
else: | ||
operation.time_cycle = operation.time_cycle_manual | ||
return result | ||
|
||
@api.constrains('capacity') | ||
def _check_capacity(self): | ||
if any(routing_workcenter.capacity < 0.0 | ||
for routing_workcenter in self): | ||
raise exceptions.UserError( | ||
_('The capacity must be strictly positive.')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Copyright 2021 Alfredo de la fuente - AvanzOSC | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
from odoo import models | ||
from odoo.tools import float_round | ||
|
||
|
||
class MrpWorkorder(models.Model): | ||
_inherit = 'mrp.workorder' | ||
|
||
def _get_duration_expected(self, alternative_workcenter=False, ratio=1): | ||
self.ensure_one() | ||
if not self.workcenter_id and not self.operation_id: | ||
return super(MrpWorkorder, self)._get_duration_expected( | ||
alternative_workcenter=alternative_workcenter, ratio=ratio) | ||
qty_production = self.production_id.product_uom_id._compute_quantity( | ||
self.qty_production, self.production_id.product_id.uom_id) | ||
capacity = ( | ||
self.operation_id.capacity if self.operation_id.capacity else | ||
self.workcenter_id.capacity) | ||
cycle_number = float_round(qty_production / capacity, | ||
precision_digits=0, rounding_method='UP') | ||
if self.operation_id.time_start or self.operation_id.time_stop: | ||
time_start = self.operation_id.time_start | ||
time_stop = self.operation_id.time_stop | ||
else: | ||
time_start = self.workcenter_id.time_start | ||
time_stop = self.workcenter_id.time_stop | ||
if alternative_workcenter: | ||
duration_expected_working = ( | ||
(self.duration_expected - time_start - time_stop) * | ||
self.workcenter_id.time_efficiency / (100.0 * cycle_number)) | ||
if duration_expected_working < 0: | ||
duration_expected_working = 0 | ||
return (alternative_workcenter.time_start + | ||
alternative_workcenter.time_stop + | ||
cycle_number * duration_expected_working * 100.0 / | ||
alternative_workcenter.time_efficiency) | ||
time_cycle = self.operation_id and self.operation_id.time_cycle or 60.0 | ||
return (time_start + time_stop + cycle_number * time_cycle * 100.0 / | ||
self.workcenter_id.time_efficiency) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_mrp_routing_workcenter_capacity |
59 changes: 59 additions & 0 deletions
59
mrp_routing_workcenter_capacity/tests/test_mrp_routing_workcenter_capacity.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Copyright 2021 Alfredo de la Fuente - AvanzOSC | ||
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html | ||
from odoo.tests import common | ||
|
||
|
||
class TestMrpRoutingWorkcenterCapacity(common.SavepointCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
super(TestMrpRoutingWorkcenterCapacity, cls).setUpClass() | ||
cls.product = cls.env.ref('mrp.product_product_computer_desk_head') | ||
cls.mrp_bom = cls.env['mrp.bom'].search( | ||
[('product_tmpl_id', '=', cls.product.product_tmpl_id.id)]) | ||
cls.operation = cls.mrp_bom.operation_ids[0] | ||
operation_vals = { | ||
'capacity': 2, | ||
'time_cycle_manual': 60} | ||
cls.operation.write(operation_vals) | ||
cls.workcenter = cls.operation.workcenter_id | ||
production_vals = { | ||
'product_id': cls.product.id, | ||
'product_uom_id': cls.product.uom_id.id, | ||
'bom_id': cls.mrp_bom.id, | ||
'product_qty': 1} | ||
cls.production = cls.env['mrp.production'].create(production_vals) | ||
cls.production._onchange_workorder_ids() | ||
cls.production._onchange_product_qty() | ||
|
||
def test_mrp_routing_workcenter_capacity(self): | ||
workorder = self.production.workorder_ids[0] | ||
self.assertEqual(workorder.duration_expected, 60.0) | ||
self.production.product_qty = 2 | ||
self.production._onchange_product_qty() | ||
self.assertEqual(workorder.duration_expected, 60.0) | ||
self.production.product_qty = 3 | ||
self.production._onchange_product_qty() | ||
self.assertEqual(workorder.duration_expected, 120.0) | ||
operation_vals = {'time_start': 10, | ||
'time_stop': 10} | ||
self.operation.write(operation_vals) | ||
self.production._onchange_product_qty() | ||
self.assertEqual(workorder.duration_expected, 140.0) | ||
workcenter_vals = {'capacity': 1, | ||
'time_start': 20, | ||
'time_stop': 20} | ||
self.workcenter.write(workcenter_vals) | ||
result = workorder._get_duration_expected( | ||
alternative_workcenter=self.workcenter, ratio=1) | ||
self.assertEqual(result, 160.0) | ||
operation_vals = {'time_mode': 'auto', | ||
'time_cycle_manual': 30} | ||
self.operation.write(operation_vals) | ||
self.operation._compute_time_cycle() | ||
self.assertEqual(self.operation.time_cycle, 30.0) | ||
workorder_vals = {'workcenter_id': False, | ||
'operation_id': False} | ||
workorder.write(workorder_vals) | ||
result = workorder._get_duration_expected() | ||
self.assertEqual(result, 140.0) |
Oops, something went wrong.