diff --git a/maintenance_request_tags/README.rst b/maintenance_request_tags/README.rst
new file mode 100644
index 000000000..b855121ea
--- /dev/null
+++ b/maintenance_request_tags/README.rst
@@ -0,0 +1 @@
+Adds tags to Maintenance Requests
diff --git a/maintenance_request_tags/__init__.py b/maintenance_request_tags/__init__.py
new file mode 100644
index 000000000..0650744f6
--- /dev/null
+++ b/maintenance_request_tags/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/maintenance_request_tags/__manifest__.py b/maintenance_request_tags/__manifest__.py
new file mode 100644
index 000000000..29670b704
--- /dev/null
+++ b/maintenance_request_tags/__manifest__.py
@@ -0,0 +1,21 @@
+# Copyright 2019 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ "name": "Maintenance Request Tags",
+ "summary": """
+ Adds tags to Maintenance Requests""",
+ "version": "14.0.1.0.0",
+ "license": "AGPL-3",
+ "author": "CreuBlanca,Odoo Community Association (OCA)",
+ "website": "https://github.com/tegin/cb-maintenance",
+ "depends": ["maintenance_plan", "maintenance_team_hierarchy"],
+ "data": [
+ "security/ir.model.access.csv",
+ "views/maintenance_equipment.xml",
+ "views/maintenance_plan.xml",
+ "views/maintenance_request_tag.xml",
+ "views/maintenance_request.xml",
+ "views/maintenance_team.xml",
+ ],
+}
diff --git a/maintenance_request_tags/i18n/es.po b/maintenance_request_tags/i18n/es.po
new file mode 100644
index 000000000..12f42c862
--- /dev/null
+++ b/maintenance_request_tags/i18n/es.po
@@ -0,0 +1,116 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * maintenance_request_tags
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 11.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-12-12 11:47+0000\n"
+"PO-Revision-Date: 2019-12-12 12:50+0100\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: \n"
+"Language: es\n"
+"X-Generator: Poedit 2.0.6\n"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_color
+msgid "Color Index (0-15)"
+msgstr "Número del Color (0-15)"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_create_uid
+msgid "Created by"
+msgstr "Creado por"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_create_date
+msgid "Created on"
+msgstr "Creado en"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_display_name
+msgid "Display Name"
+msgstr "Nombre mostrado"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_id
+msgid "ID"
+msgstr "ID (identificación)"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag___last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_write_uid
+msgid "Last Updated by"
+msgstr "Última actualización de"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_write_date
+msgid "Last Updated on"
+msgstr "Última actualización en"
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_request_tag
+msgid "Maintenance Request Tag"
+msgstr "Etiqueta de Peticiones"
+
+#. module: maintenance_request_tags
+#: model:ir.actions.act_window,name:maintenance_request_tags.maintenance_request_tag_act_window
+#: model:ir.ui.menu,name:maintenance_request_tags.maintenance_request_tag_menu
+msgid "Maintenance Request Tags"
+msgstr "Etiquetas de Peticiones"
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_request
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_request_ids
+msgid "Maintenance Requests"
+msgstr "Peticiones de mantenimiento"
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_team
+msgid "Maintenance Teams"
+msgstr "Equipos de mantenimiento"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_name
+msgid "Request Tag"
+msgstr "Etiqueta de Peticiones"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_selectable_tags_ids
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_team_selectable_tags_ids
+msgid "Selectable Tags"
+msgstr "Etiquetas Seleccionables"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_selectable_team_count
+msgid "Selectable Team Count"
+msgstr "Número de Etiquetas Seleccionables"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_selectable_team_ids
+msgid "Selectable Teams"
+msgstr "Equipos"
+
+#. module: maintenance_request_tags
+#: sql_constraint:maintenance.request.tag:0
+msgid "Tag name already exists !"
+msgstr "Esta etiqueta ya existe!"
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_ids
+msgid "Tags"
+msgstr "Etiquetas"
+
+#. module: maintenance_request_tags
+#: model:ir.ui.view,arch_db:maintenance_request_tags.hr_equipment_request_view_form
+msgid "e.g. Computers"
+msgstr "p.e Ordenadores"
diff --git a/maintenance_request_tags/i18n/maintenance_request_tags.pot b/maintenance_request_tags/i18n/maintenance_request_tags.pot
new file mode 100644
index 000000000..b4055d96f
--- /dev/null
+++ b/maintenance_request_tags/i18n/maintenance_request_tags.pot
@@ -0,0 +1,115 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * maintenance_request_tags
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 11.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-12-12 11:46+0000\n"
+"PO-Revision-Date: 2019-12-12 11:46+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: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_color
+msgid "Color Index (0-15)"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_create_date
+msgid "Created on"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_id
+msgid "ID"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag___last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_request_tag
+msgid "Maintenance Request Tag"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.actions.act_window,name:maintenance_request_tags.maintenance_request_tag_act_window
+#: model:ir.ui.menu,name:maintenance_request_tags.maintenance_request_tag_menu
+msgid "Maintenance Request Tags"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_request
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_request_ids
+msgid "Maintenance Requests"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model,name:maintenance_request_tags.model_maintenance_team
+msgid "Maintenance Teams"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_name
+msgid "Request Tag"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_selectable_tags_ids
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_team_selectable_tags_ids
+msgid "Selectable Tags"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_selectable_team_count
+msgid "Selectable Team Count"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_selectable_team_ids
+msgid "Selectable Teams"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: sql_constraint:maintenance.request.tag:0
+msgid "Tag name already exists !"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.model.fields,field_description:maintenance_request_tags.field_maintenance_request_tag_ids
+msgid "Tags"
+msgstr ""
+
+#. module: maintenance_request_tags
+#: model:ir.ui.view,arch_db:maintenance_request_tags.hr_equipment_request_view_form
+msgid "e.g. Computers"
+msgstr ""
+
diff --git a/maintenance_request_tags/models/__init__.py b/maintenance_request_tags/models/__init__.py
new file mode 100644
index 000000000..5a0552bcb
--- /dev/null
+++ b/maintenance_request_tags/models/__init__.py
@@ -0,0 +1,5 @@
+from . import maintenance_team
+from . import maintenance_request
+from . import maintenance_request_tag
+from . import maintenance_plan
+from . import maintenance_equipment
diff --git a/maintenance_request_tags/models/maintenance_equipment.py b/maintenance_request_tags/models/maintenance_equipment.py
new file mode 100644
index 000000000..6a9ec00dc
--- /dev/null
+++ b/maintenance_request_tags/models/maintenance_equipment.py
@@ -0,0 +1,16 @@
+# Copyright 2020 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import models
+
+
+class MaintenanceEquipment(models.Model):
+
+ _inherit = "maintenance.equipment"
+
+ def _prepare_request_from_plan(self, maintenance_plan, next_maintenance_date):
+ res = super()._prepare_request_from_plan(
+ maintenance_plan, next_maintenance_date
+ )
+ res.update({"tag_ids": [(6, 0, maintenance_plan.tag_ids.ids)]})
+ return res
diff --git a/maintenance_request_tags/models/maintenance_plan.py b/maintenance_request_tags/models/maintenance_plan.py
new file mode 100644
index 000000000..975352149
--- /dev/null
+++ b/maintenance_request_tags/models/maintenance_plan.py
@@ -0,0 +1,11 @@
+# Copyright 2020 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class MaintenancePlan(models.Model):
+
+ _inherit = "maintenance.plan"
+
+ tag_ids = fields.Many2many("maintenance.request.tag", string="Tags")
diff --git a/maintenance_request_tags/models/maintenance_request.py b/maintenance_request_tags/models/maintenance_request.py
new file mode 100644
index 000000000..7a5fedebf
--- /dev/null
+++ b/maintenance_request_tags/models/maintenance_request.py
@@ -0,0 +1,35 @@
+# Copyright 2019 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class MaintenanceRequest(models.Model):
+
+ _inherit = "maintenance.request"
+
+ selectable_tags_ids = fields.Many2many(
+ "maintenance.request.tag",
+ compute="_compute_selectable_tags_ids",
+ readonly=True,
+ )
+
+ tag_ids = fields.Many2many(
+ "maintenance.request.tag",
+ "request_tag_rel",
+ "request_id",
+ "tag_id",
+ string="Tags",
+ )
+
+ @api.depends("maintenance_team_id")
+ def _compute_selectable_tags_ids(self):
+ for record in self:
+ record.selectable_tags_ids = [
+ (6, 0, record.maintenance_team_id.selectable_tags_ids.ids)
+ ]
+ team_id = record.maintenance_team_id
+ while team_id.parent_id:
+ team_id = team_id.parent_id
+ tags = [(4, tag) for tag in team_id.selectable_tags_ids.ids]
+ record.selectable_tags_ids = tags
diff --git a/maintenance_request_tags/models/maintenance_request_tag.py b/maintenance_request_tags/models/maintenance_request_tag.py
new file mode 100644
index 000000000..7c8eb8c91
--- /dev/null
+++ b/maintenance_request_tags/models/maintenance_request_tag.py
@@ -0,0 +1,37 @@
+# Copyright 2019 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from random import randint
+
+from odoo import api, fields, models
+
+
+class MaintenanceRequestTag(models.Model):
+
+ _name = "maintenance.request.tag"
+ _description = "Maintenance Request Tag"
+
+ name = fields.Char(string="Request Tag", required=True)
+ color = fields.Integer(string="Color Index (0-15)", default=randint(1, 15))
+ request_ids = fields.Many2many(
+ "maintenance.request",
+ "request_tag_rel",
+ "tag_id",
+ "request_id",
+ string="Maintenance Requests",
+ )
+
+ selectable_team_ids = fields.Many2many(
+ "maintenance.team", string="Selectable Teams"
+ )
+
+ selectable_team_count = fields.Integer(
+ compute="_compute_selectable_team_count", store=True, readonly=True
+ )
+
+ @api.depends("selectable_team_ids")
+ def _compute_selectable_team_count(self):
+ for record in self:
+ record.selectable_team_count = len(record.selectable_team_ids)
+
+ _sql_constraints = [("name_uniq", "unique (name)", "Tag name already exists !")]
diff --git a/maintenance_request_tags/models/maintenance_team.py b/maintenance_request_tags/models/maintenance_team.py
new file mode 100644
index 000000000..84b97a50d
--- /dev/null
+++ b/maintenance_request_tags/models/maintenance_team.py
@@ -0,0 +1,13 @@
+# Copyright 2019 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class MaintenanceTeam(models.Model):
+
+ _inherit = "maintenance.team"
+
+ selectable_tags_ids = fields.Many2many(
+ "maintenance.request.tag", string="Selectable Tags"
+ )
diff --git a/maintenance_request_tags/security/ir.model.access.csv b/maintenance_request_tags/security/ir.model.access.csv
new file mode 100644
index 000000000..0b12c78b2
--- /dev/null
+++ b/maintenance_request_tags/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_maintenance_request_tag,access_maintenance_request_tag,model_maintenance_request_tag,base.group_user,1,0,0,0
+access_maintenance_request_tag_admin,access_maintenance_request_tag_admin,model_maintenance_request_tag,maintenance.group_equipment_manager,1,1,1,1
diff --git a/maintenance_request_tags/static/description/icon.png b/maintenance_request_tags/static/description/icon.png
new file mode 100644
index 000000000..3a0328b51
Binary files /dev/null and b/maintenance_request_tags/static/description/icon.png differ
diff --git a/maintenance_request_tags/tests/__init__.py b/maintenance_request_tags/tests/__init__.py
new file mode 100644
index 000000000..ad723f61c
--- /dev/null
+++ b/maintenance_request_tags/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_request_tags
diff --git a/maintenance_request_tags/tests/test_request_tags.py b/maintenance_request_tags/tests/test_request_tags.py
new file mode 100644
index 000000000..7866893d8
--- /dev/null
+++ b/maintenance_request_tags/tests/test_request_tags.py
@@ -0,0 +1,48 @@
+# Copyright 2019 Creu Blanca
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo.tests.common import SavepointCase
+
+
+class TestRequestTags(SavepointCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ self = cls
+ self.tag_1 = self.env["maintenance.request.tag"].create({"name": "Test Tag 1"})
+ self.tag_2 = self.env["maintenance.request.tag"].create({"name": "Test Tag 2"})
+ self.team_1 = self.env["maintenance.team"].create(
+ {"name": "T1", "selectable_tags_ids": [(4, self.tag_1.id)]}
+ )
+ self.team_2 = self.env["maintenance.team"].create(
+ {
+ "name": "T2",
+ "selectable_tags_ids": [(4, self.tag_2.id)],
+ "parent_id": self.team_1.id,
+ }
+ )
+ self.equipment = self.env["maintenance.equipment"].create({"name": "Laptop"})
+
+ self.plan = self.env["maintenance.plan"].create(
+ {
+ "equipment_id": self.equipment.id,
+ "interval": 1,
+ "interval_step": "month",
+ "maintenance_plan_horizon": 2,
+ "planning_step": "month",
+ "maintenance_team_id": self.team_2.id,
+ "tag_ids": [(4, self.tag_2.id)],
+ }
+ )
+
+ def test_request_tags(self):
+ request = self.env["maintenance.request"].create(
+ {"name": "Request", "maintenance_team_id": self.team_2.id}
+ )
+ self.assertEqual(len(request.selectable_tags_ids), 2)
+
+ def test_request_creation(self):
+ request = self.equipment._create_new_request(self.plan)
+ self.assertTrue(request)
+ for r in request:
+ self.assertTrue(r.tag_ids)
diff --git a/maintenance_request_tags/views/maintenance_equipment.xml b/maintenance_request_tags/views/maintenance_equipment.xml
new file mode 100644
index 000000000..de4b4a796
--- /dev/null
+++ b/maintenance_request_tags/views/maintenance_equipment.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ maintenance.equipment.form (in maintenance_request_tags)
+ maintenance.equipment
+
+
+
+
+
+
+
+
diff --git a/maintenance_request_tags/views/maintenance_plan.xml b/maintenance_request_tags/views/maintenance_plan.xml
new file mode 100644
index 000000000..4d35f6d6c
--- /dev/null
+++ b/maintenance_request_tags/views/maintenance_plan.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ maintenance.plan.form (in maintenance_request_tags)
+ maintenance.plan
+
+
+
+
+
+
+
+
+ maintenance.plan.search (in maintenance_request_tags)
+ maintenance.plan
+
+
+
+
+
+
+
+
+ maintenance.plan.tree (in maintenance_request_tags)
+ maintenance.plan
+
+
+
+
+
+
+
+
diff --git a/maintenance_request_tags/views/maintenance_request.xml b/maintenance_request_tags/views/maintenance_request.xml
new file mode 100644
index 000000000..8dbdca778
--- /dev/null
+++ b/maintenance_request_tags/views/maintenance_request.xml
@@ -0,0 +1,69 @@
+
+
+
+
+ maintenance.request.form (in maintenance_request_tags)
+ maintenance.request
+
+
+
+
+
+
+
+
+
+ maintenance.request.kanban (in maintenance_request_tags)
+ maintenance.request
+
+
+
+
+
+
+
+
+ maintenance.request.tree (in maintenance_request_tags)
+ maintenance.request
+
+
+
+
+
+
+
+
+ maintenance.request.search (in maintenance_request_tags)
+ maintenance.request
+
+
+
+
+
+
+
+
+
diff --git a/maintenance_request_tags/views/maintenance_request_tag.xml b/maintenance_request_tags/views/maintenance_request_tag.xml
new file mode 100644
index 000000000..ac630086c
--- /dev/null
+++ b/maintenance_request_tags/views/maintenance_request_tag.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ maintenance.request.tag.form (in maintenance_request_tags)
+ maintenance.request.tag
+
+
+
+
+
+ maintenance.request.tag.search (in maintenance_request_tags)
+ maintenance.request.tag
+
+
+
+
+
+
+
+ maintenance.request.tag.tree (in maintenance_request_tags)
+ maintenance.request.tag
+
+
+
+
+
+
+
+ Maintenance Request Tags
+ maintenance.request.tag
+ tree,form
+ []
+ {}
+
+
+ Maintenance Request Tags
+
+
+
+
+
diff --git a/maintenance_request_tags/views/maintenance_team.xml b/maintenance_request_tags/views/maintenance_team.xml
new file mode 100644
index 000000000..850900624
--- /dev/null
+++ b/maintenance_request_tags/views/maintenance_team.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ maintenance.team.form (in maintenance_request_tags)
+ maintenance.team
+
+
+
+
+
+
+
+
+ maintenance.team.tree (in maintenance_request_tags)
+ maintenance.team
+
+
+
+
+
+
+
+