diff --git a/README.md b/README.md index 8ffea9fbec..cacdaee40e 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ addon | version | maintainers | summary [project_task_code](project_task_code/) | 14.0.1.0.2 | | Sequential Code for Tasks [project_task_default_stage](project_task_default_stage/) | 14.0.1.1.0 | | Recovery default task stages for projects from v8 [project_task_dependency](project_task_dependency/) | 14.0.1.1.0 | [![astirpe](https://github.com/astirpe.png?size=30px)](https://github.com/astirpe) | Enables to define dependencies (other tasks) of a task +[project_task_description_template](project_task_description_template/) | 14.0.1.0.0 | [![aleuffre](https://github.com/aleuffre.png?size=30px)](https://github.com/aleuffre) [![renda-dev](https://github.com/renda-dev.png?size=30px)](https://github.com/renda-dev) | Module for Task Templates [project_task_digitized_signature](project_task_digitized_signature/) | 14.0.1.0.0 | | Project Task Digitized Signature [project_task_material](project_task_material/) | 14.0.1.0.1 | | Record products spent in a Task [project_task_project_required](project_task_project_required/) | 14.0.1.0.0 | | Set project on task as a mandatory field diff --git a/project_task_description_template/README.rst b/project_task_description_template/README.rst new file mode 100644 index 0000000000..71e3d2f880 --- /dev/null +++ b/project_task_description_template/README.rst @@ -0,0 +1,115 @@ +====================== +Project Task Templates +====================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7fa1f9f57e535d5cc7bc336e9f0169353824dafa1ee4bdd72bc80894835343e5 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproject-lightgray.png?logo=github + :target: https://github.com/OCA/project/tree/14.0/project_task_description_template + :alt: OCA/project +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/project-14-0/project-14-0-project_task_description_template + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/project&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +The goal of this module is to allow templates for task descriptions. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Follow these steps to use the module: + +**Create task template** + +- Go to **Project -> Configuration -> Task Template**. +- Create desired task templates and configure them according to your + project needs. + +**Assign Templates to Projects** + +- Go to the specific project to which a template should be assigned. + Open the Settings tab. +- In the Task Template dropdown, select created templates. +- In the field Available in, select the product stages where this + templates will be available + +**Create task** + +- Create a new task within the project. +- The task template will be available to set up in the stage configured + for the task template. +- Select the desired template from the Task Template field. +- Fields will automatically be populated with values from the selected + template. + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Cetmix + +Contributors +------------ + +- Cetmix + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +.. |maintainer-aleuffre| image:: https://github.com/aleuffre.png?size=40px + :target: https://github.com/aleuffre + :alt: aleuffre +.. |maintainer-renda-dev| image:: https://github.com/renda-dev.png?size=40px + :target: https://github.com/renda-dev + :alt: renda-dev + +Current `maintainers `__: + +|maintainer-aleuffre| |maintainer-renda-dev| + +This module is part of the `OCA/project `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/project_task_description_template/__init__.py b/project_task_description_template/__init__.py new file mode 100644 index 0000000000..ea1a62d9a0 --- /dev/null +++ b/project_task_description_template/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from . import models diff --git a/project_task_description_template/__manifest__.py b/project_task_description_template/__manifest__.py new file mode 100644 index 0000000000..219aa2edc9 --- /dev/null +++ b/project_task_description_template/__manifest__.py @@ -0,0 +1,24 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +{ + "name": "Project Task Templates", + "version": "14.0.1.0.0", + "summary": "Module for Task Templates", + "author": "Cetmix, Odoo Community Association (OCA)", + "category": "Project", + "maintainers": ["aleuffre", "renda-dev"], + "website": "https://github.com/OCA/project", + "license": "AGPL-3", + "depends": ["project"], + "demo": [ + "data/demo.xml", + ], + "data": [ + "security/ir.model.access.csv", + "views/project_task_template_views.xml", + "views/project_views.xml", + "views/assets.xml", + ], + "application": False, +} diff --git a/project_task_description_template/data/demo.xml b/project_task_description_template/data/demo.xml new file mode 100644 index 0000000000..44bde996d3 --- /dev/null +++ b/project_task_description_template/data/demo.xml @@ -0,0 +1,25 @@ + + + + Template demo 1 + + + Template 1 Description! + + + + Template demo 2 + + + Template 2 Description! + + + diff --git a/project_task_description_template/i18n/project_task_description_template.pot b/project_task_description_template/i18n/project_task_description_template.pot new file mode 100644 index 0000000000..423afdb8bc --- /dev/null +++ b/project_task_description_template/i18n/project_task_description_template.pot @@ -0,0 +1,152 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_task_description_template +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \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: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__user_id +#: model_terms:ir.ui.view,arch_db:project_task_description_template.view_task_template_form +msgid "Assigned to" +msgstr "" + +#. module: project_task_description_template +#. openerp-web +#: code:addons/project_task_description_template/static/src/js/onchange_confirm_widget.js:0 +#, python-format +msgid "Confirmation" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__create_uid +msgid "Created by" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__create_date +msgid "Created on" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__default_task_template_id +msgid "Default Task Template" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__description +#: model_terms:ir.ui.view,arch_db:project_task_description_template.view_task_template_form +msgid "Description" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__display_name +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task__display_name +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__display_name +msgid "Display Name" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__id +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task__id +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__id +msgid "ID" +msgstr "" + +#. module: project_task_description_template +#: model_terms:ir.ui.view,arch_db:project_task_description_template.view_task_template_form +msgid "Information" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project____last_update +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task____last_update +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template____last_update +msgid "Last Modified on" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__write_date +msgid "Last Updated on" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__name +msgid "Name" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__project_ids +msgid "Project" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model,name:project_task_description_template.model_project_task_template +msgid "Project Task Template" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__is_restrict_template_by_stages +msgid "Restrict template by stages" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task_template__tag_ids +msgid "Tag" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model,name:project_task_description_template.model_project_task +msgid "Task" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task__task_template_id +#: model_terms:ir.ui.view,arch_db:project_task_description_template.view_task_form2 +#: model_terms:ir.ui.view,arch_db:project_task_description_template.view_task_template_form +msgid "Task Template" +msgstr "" + +#. module: project_task_description_template +#: model:ir.actions.act_window,name:project_task_description_template.open_view_task_templates_all +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__task_template_ids +#: model:ir.ui.menu,name:project_task_description_template.menu_projects_config_task_templates +msgid "Task Templates" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_task__template_visible +msgid "Template Visible" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model.fields,field_description:project_task_description_template.field_project_project__template_task_type_ids +msgid "Templates allowed in stages" +msgstr "" + +#. module: project_task_description_template +#. openerp-web +#: code:addons/project_task_description_template/static/src/js/onchange_confirm_widget.js:0 +#, python-format +msgid "" +"The record has been modified, your changes will be discarded. Do you want to" +" proceed?" +msgstr "" + +#. module: project_task_description_template +#: model:ir.model,name:project_task_description_template.model_project_project +msgid "WBS element" +msgstr "" diff --git a/project_task_description_template/models/__init__.py b/project_task_description_template/models/__init__.py new file mode 100644 index 0000000000..2904acf92f --- /dev/null +++ b/project_task_description_template/models/__init__.py @@ -0,0 +1,6 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from . import project_task_template +from . import project_project +from . import project_task diff --git a/project_task_description_template/models/project_project.py b/project_task_description_template/models/project_project.py new file mode 100644 index 0000000000..f45d51cd3e --- /dev/null +++ b/project_task_description_template/models/project_project.py @@ -0,0 +1,27 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from odoo import api, fields, models + + +class ProjectProject(models.Model): + _inherit = "project.project" + + default_task_template_id = fields.Many2one(comodel_name="project.task.template") + task_template_ids = fields.Many2many( + comodel_name="project.task.template", string="Task Templates" + ) + template_task_type_ids = fields.Many2many( + string="Templates allowed in stages", comodel_name="project.task.type" + ) + is_restrict_template_by_stages = fields.Boolean( + string="Restrict template by stages" + ) + + @api.onchange("task_template_ids") + def _onchange_task_template_ids(self): + for record in self: + if record.default_task_template_id and ( + record.default_task_template_id not in record.task_template_ids + ): + record.default_task_template_id = False diff --git a/project_task_description_template/models/project_task.py b/project_task_description_template/models/project_task.py new file mode 100644 index 0000000000..67a9fa3ed5 --- /dev/null +++ b/project_task_description_template/models/project_task.py @@ -0,0 +1,45 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from odoo import api, fields, models + + +class ProjectTask(models.Model): + _inherit = "project.task" + + task_template_id = fields.Many2one( + comodel_name="project.task.template", + compute="_compute_template_visible", + store=True, + readonly=False, + ) + template_visible = fields.Boolean(compute="_compute_template_visible", store=True) + + @api.depends("project_id", "stage_id") + def _compute_template_visible(self): + for rec in self: + visible = not rec.project_id.is_restrict_template_by_stages or ( + rec.stage_id + and rec.project_id + and rec.project_id.template_task_type_ids + and rec.stage_id in rec.project_id.template_task_type_ids + ) + rec.template_visible = visible + if ( + visible + and rec.project_id.default_task_template_id + and not rec.task_template_id + ): + rec.task_template_id = rec.project_id.default_task_template_id + self._onchange_task_template_id() + + @api.onchange("task_template_id") + def _onchange_task_template_id(self): + if self.task_template_id: + self.update( + { + "user_id": self.task_template_id.user_id.id, + "tag_ids": self.task_template_id.tag_ids.ids, + "description": self.task_template_id.description, + } + ) diff --git a/project_task_description_template/models/project_task_template.py b/project_task_description_template/models/project_task_template.py new file mode 100644 index 0000000000..956bd47d7f --- /dev/null +++ b/project_task_description_template/models/project_task_template.py @@ -0,0 +1,15 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from odoo import fields, models + + +class ProjectTaskTemplate(models.Model): + _name = "project.task.template" + _description = "Project Task Template" + + name = fields.Char() + tag_ids = fields.Many2many(comodel_name="project.tags") + user_id = fields.Many2one(string="Assigned to", comodel_name="res.users") + description = fields.Html() + project_ids = fields.Many2many(comodel_name="project.project") diff --git a/project_task_description_template/readme/CONTRIBUTORS.md b/project_task_description_template/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..ad0cc5a403 --- /dev/null +++ b/project_task_description_template/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Cetmix diff --git a/project_task_description_template/readme/DESCRIPTION.md b/project_task_description_template/readme/DESCRIPTION.md new file mode 100644 index 0000000000..9e4111bd8e --- /dev/null +++ b/project_task_description_template/readme/DESCRIPTION.md @@ -0,0 +1 @@ +The goal of this module is to allow templates for task descriptions. diff --git a/project_task_description_template/readme/USAGE.md b/project_task_description_template/readme/USAGE.md new file mode 100644 index 0000000000..bb4cfe19b7 --- /dev/null +++ b/project_task_description_template/readme/USAGE.md @@ -0,0 +1,22 @@ +Follow these steps to use the module: + +**Create task template** + +- Go to **Project -> Configuration -> Task Template**. +- Create desired task templates and configure them according to your project needs. + +**Assign Templates to Projects** + +- Go to the specific project to which a template should be assigned. Open the Settings + tab. +- In the Task Template dropdown, select created templates. +- In the field Available in, select the product stages where this templates will be + available + +**Create task** + +- Create a new task within the project. +- The task template will be available to set up in the stage configured for the task + template. +- Select the desired template from the Task Template field. +- Fields will automatically be populated with values from the selected template. diff --git a/project_task_description_template/security/ir.model.access.csv b/project_task_description_template/security/ir.model.access.csv new file mode 100644 index 0000000000..29a6fcc93c --- /dev/null +++ b/project_task_description_template/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_project_task_employees,project.task.template,model_project_task_template,base.group_user,1,0,0,0 +access_project_task_manager,project.task.template,model_project_task_template,project.group_project_manager,1,1,1,1 diff --git a/project_task_description_template/static/description/icon.png b/project_task_description_template/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/project_task_description_template/static/description/icon.png differ diff --git a/project_task_description_template/static/description/index.html b/project_task_description_template/static/description/index.html new file mode 100644 index 0000000000..21f4b10e0c --- /dev/null +++ b/project_task_description_template/static/description/index.html @@ -0,0 +1,451 @@ + + + + + + +Project Task Templates + + + +
+

Project Task Templates

+ + +

Beta License: AGPL-3 OCA/project Translate me on Weblate Try me on Runboat

+

The goal of this module is to allow templates for task descriptions.

+

Table of contents

+ +
+

Usage

+

Follow these steps to use the module:

+

Create task template

+
    +
  • Go to Project -> Configuration -> Task Template.
  • +
  • Create desired task templates and configure them according to your +project needs.
  • +
+

Assign Templates to Projects

+
    +
  • Go to the specific project to which a template should be assigned. +Open the Settings tab.
  • +
  • In the Task Template dropdown, select created templates.
  • +
  • In the field Available in, select the product stages where this +templates will be available
  • +
+

Create task

+
    +
  • Create a new task within the project.
  • +
  • The task template will be available to set up in the stage configured +for the task template.
  • +
  • Select the desired template from the Task Template field.
  • +
  • Fields will automatically be populated with values from the selected +template.
  • +
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Cetmix
  • +
+
+
+

Contributors

+
    +
  • Cetmix <cetmix.com/>
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainers:

+

aleuffre renda-dev

+

This module is part of the OCA/project project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/project_task_description_template/static/src/js/onchange_confirm_widget.js b/project_task_description_template/static/src/js/onchange_confirm_widget.js new file mode 100644 index 0000000000..8f3ada3409 --- /dev/null +++ b/project_task_description_template/static/src/js/onchange_confirm_widget.js @@ -0,0 +1,57 @@ +odoo.define("project_task_description_template.onchange_confirm_widget", function ( + require +) { + "use strict"; + + var field_registry = require("web.field_registry"); + var relational_fields = require("web.relational_fields"); + var FieldMany2One = relational_fields.FieldMany2One; + + var core = require("web.core"); + var Dialog = require("web.Dialog"); + + var _t = core._t; + + var OnchangeConfirm = FieldMany2One.extend({ + init: function () { + this._super.apply(this, arguments); + }, + + _change_template: function (ev) { + this.trigger_up("field_changed", { + dataPointID: ev.data.dataPointID, + changes: ev.data.changes, + skip: true, + }); + }, + + _onFieldChanged: function (ev) { + var self = this; + if (ev.data && !ev.data.skip) { + ev.stopPropagation(); + var message = _t( + "The record has been modified, your changes will be discarded. Do you want to proceed?" + ); + self.result = new Promise(function (resolve, reject) { + var dialog = Dialog.confirm(self, message, { + title: _t("Confirmation"), + confirm_callback: () => { + resolve(true); + self._change_template(ev); + self.result = undefined; + }, + cancel_callback: () => { + reject(false); + self.result = undefined; + }, + }); + dialog.on("closed", self.result, reject); + }); + } else { + this._super.apply(this, arguments); + } + }, + }); + field_registry.add("onchange_confirm", OnchangeConfirm); + return OnchangeConfirm; +}); diff --git a/project_task_description_template/tests/__init__.py b/project_task_description_template/tests/__init__.py new file mode 100644 index 0000000000..7c12cfebdd --- /dev/null +++ b/project_task_description_template/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from . import test_task_template diff --git a/project_task_description_template/tests/test_task_template.py b/project_task_description_template/tests/test_task_template.py new file mode 100644 index 0000000000..a9c22bae62 --- /dev/null +++ b/project_task_description_template/tests/test_task_template.py @@ -0,0 +1,254 @@ +# Copyright (C) 2023 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl) + +from odoo.tests.common import SavepointCase + + +class TestProjectTaskTemplate(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # create tag model + tag_model = cls.env["project.tags"] + # creating tags: Red, Green, Blue, White, Yellow + cls.tag_red = tag_model.create({"name": "Red"}) + cls.tag_green = tag_model.create({"name": "Green"}) + cls.tag_blue = tag_model.create({"name": "Blue"}) + cls.tag_white = tag_model.create({"name": "White"}) + cls.tag_yellow = tag_model.create({"name": "Yellow"}) + cls.stage_1 = cls.env["project.task.type"].create({"name": "Stage 1"}) + cls.stage_2 = cls.env["project.task.type"].create({"name": "Stage 2"}) + # create res users model + res_users_model = cls.env["res.users"] + # create users: Bob, Mike, Kate + cls.user_bob = res_users_model.create( + {"name": "Bob", "email": "bob@example.com", "login": "bob"} + ) + cls.user_mike = res_users_model.create( + {"name": "Mike", "email": "mike@example.com", "login": "mike"} + ) + cls.user_kate = res_users_model.create( + {"name": "Kate", "email": "kate@example.com", "login": "kate"} + ) + # create task template model + task_template_model = cls.env["project.task.template"] + # create task templates: + + cls.template_1 = task_template_model.create( + { + "name": "Template1", + "tag_ids": [ + cls.tag_red.id, + cls.tag_green.id, + ], + "user_id": cls.user_bob.id, + "description": "This is template 1", + } + ) + cls.template_2 = task_template_model.create( + { + "name": "Template2", + "tag_ids": [ + cls.tag_blue.id, + cls.tag_white.id, + ], + "user_id": cls.user_mike.id, + "description": "This is template 2", + } + ) + # create project model + project_model = cls.env["project.project"] + # create projects : "Project 1" and add templates 1-2 + cls.project_1 = project_model.create( + { + "name": "Project 1", + "task_template_ids": [cls.template_1.id, cls.template_2.id], + } + ) + + cls.project_2 = project_model.create( + { + "name": "Project 1", + "task_template_ids": [cls.template_1.id, cls.template_2.id], + "default_task_template_id": cls.template_2.id, + "template_task_type_ids": [cls.stage_1.id, cls.stage_2.id], + "is_restrict_template_by_stages": True, + } + ) + # create task model + cls.project_task_model = cls.env["project.task"] + cls.test_task_1 = cls.project_task_model.create( + { + "name": "Test task 1", + "user_id": cls.user_kate.id, + "tag_ids": [ + cls.tag_yellow.id, + ], + "description": "This is task1", + "task_template_id": False, + } + ) + + cls.test_project_2_task_1 = cls.project_task_model.create( + { + "name": "Test Project #2 Task #1", + "user_id": cls.user_kate.id, + "tag_ids": [ + cls.tag_yellow.id, + ], + "description": "This is task1", + "project_id": cls.project_2.id, + "stage_id": cls.stage_1.id, + } + ) + + def test_task_1_template_1(self): + """Test the behavior when choosing a template.""" + # Set the task_template_id of test_task_1 to template_1.id + self.test_task_1.task_template_id = self.template_1.id + + # Trigger the _onchange_task_template_id method + self.test_task_1._onchange_task_template_id() + + # Verify that the user_id of test_task_1 is equal to the user_id of template_1 + self.assertEqual( + self.test_task_1.user_id.id, + self.template_1.user_id.id, + msg="The task 1 user #id must be equal to the template 1 user ID#%s" + % self.template_1.user_id.id, + ) + + # Verify that the tag_ids of test_task_1 are equal to the tag_ids of template_1 + self.assertEqual( + self.test_task_1.tag_ids.ids, + self.template_1.tag_ids.ids, + msg="The task 1 tag IDs must be equal to the template 1 tag IDs", + ) + + # Verify that the description of test_task_1 is + # equal to the description of template_1 + self.assertEqual( + self.test_task_1.description, + self.template_1.description, + msg="The task 1 description must be equal to the template 1 description", + ) + + def test_task_1_template_2(self): + """Test the behavior when choosing a different template (template_2).""" + # Set the task_template_id of test_task_1 to template_2.id + self.test_task_1.task_template_id = self.template_2.id + + # Trigger the _onchange_task_template_id method + self.test_task_1._onchange_task_template_id() + + # Verify that the user_id of test_task_1 is equal to the user_id of template_2 + self.assertEqual( + self.test_task_1.user_id.id, + self.template_2.user_id.id, + msg="The task 1 user #id must be equal to the template 2 user ID# %s" + % self.template_2.user_id.id, + ) + + # Verify that the tag_ids of test_task_1 are equal to the tag_ids of template_2 + self.assertEqual( + self.test_task_1.tag_ids.ids, + self.template_2.tag_ids.ids, + msg="The task 1 tag IDs must be equal to the template 2 tag IDs", + ) + + # Verify that the description of test_task_1 is + # equal to the description of template_2 + self.assertEqual( + self.test_task_1.description, + self.template_2.description, + msg="The task 1 description must be equal to the template 2 description", + ) + + def test_task_1_template_false(self): + """Test the behavior when setting task_template_id to False + after choosing a template. + """ + # Set the task_template_id of test_task_1 to template_2.id + self.test_task_1.task_template_id = self.template_2.id + + # Trigger the _onchange_task_template_id method + self.test_task_1._onchange_task_template_id() + + # Set the task_template_id of test_task_1 to False + self.test_task_1.task_template_id = False + + # Trigger the _onchange_task_template_id method + self.test_task_1._onchange_task_template_id() + + # Verify that the user_id of test_task_1 is + # equal to the user_id of template_2 + self.assertEqual( + self.test_task_1.user_id.id, + self.template_2.user_id.id, + msg="The task 1 user #id must be equal to the template 2 user ID#%s" + % self.template_2.user_id.id, + ) + + # Verify that the tag_ids of test_task_1 are equal to the tag_ids of template_2 + self.assertEqual( + self.test_task_1.tag_ids.ids, + self.template_2.tag_ids.ids, + msg="The task 1 tag IDs must be equal to the template 2 tag IDs", + ) + + # Verify that the description of test_task_1 is + # equal to the description of template_2 + self.assertEqual( + self.test_task_1.description, + self.template_2.description, + msg="The task 1 description must be equal to the template 2 description", + ) + + def test_task_2_template_2(self): + """Test the behavior when choosing a default template in project settings.""" + + self.assertTrue( + self.test_project_2_task_1.task_template_id, + msg=f"The task template ID #{self.template_2.id} must be set", + ) + + self.assertEqual( + self.test_project_2_task_1.task_template_id.id, + self.project_2.default_task_template_id.id, + msg=( + "The task template ID must be equal" + "to the default template ID in project settings" + ), + ) + + self.project_2.task_template_ids = [self.template_1.id] + self.project_2._onchange_task_template_ids() + self.assertFalse(self.project_2.default_task_template_id, msg="Must be empty") + + def test_change_stage(self): + """Test the behavior when changing the stage of a task.""" + + self.assertTrue( + self.test_project_2_task_1.task_template_id, + msg=f"The task template ID #{self.template_2.id} must be set", + ) + + self.assertEqual( + self.test_project_2_task_1.task_template_id.id, + self.project_2.default_task_template_id.id, + msg=( + "The task template ID must be equal" + "to the default template ID in project settings" + ), + ) + + self.test_project_2_task_1.stage_id = self.stage_2.id + self.test_project_2_task_1._compute_template_visible() + self.assertEqual( + self.test_project_2_task_1.task_template_id.id, + self.project_2.default_task_template_id.id, + msg=( + "The task template ID must be equal" + "to the default template ID in project settings" + ), + ) diff --git a/project_task_description_template/views/assets.xml b/project_task_description_template/views/assets.xml new file mode 100644 index 0000000000..c6dbd16c6f --- /dev/null +++ b/project_task_description_template/views/assets.xml @@ -0,0 +1,12 @@ + + +