From 48185f01247f80031317765baeb32f0f0a87a785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Sainl=C3=A9ger?= Date: Tue, 17 Mar 2026 21:41:37 +0100 Subject: [PATCH] [MIG] helpdesk_convert_ticket_to_task: migrate to 18.0 --- helpdesk_convert_ticket_to_task/.gitignore | 2 + helpdesk_convert_ticket_to_task/README.md | 73 ++++++++++++ helpdesk_convert_ticket_to_task/__init__.py | 1 + .../__manifest__.py | 27 +++++ helpdesk_convert_ticket_to_task/i18n/fr.po | 63 +++++++++++ .../models/__init__.py | 1 + .../models/helpdesk_ticket.py | 106 ++++++++++++++++++ .../views/helpdesk_convert_ticket_to_task.xml | 21 ++++ 8 files changed, 294 insertions(+) create mode 100644 helpdesk_convert_ticket_to_task/.gitignore create mode 100644 helpdesk_convert_ticket_to_task/README.md create mode 100644 helpdesk_convert_ticket_to_task/__init__.py create mode 100644 helpdesk_convert_ticket_to_task/__manifest__.py create mode 100644 helpdesk_convert_ticket_to_task/i18n/fr.po create mode 100644 helpdesk_convert_ticket_to_task/models/__init__.py create mode 100644 helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py create mode 100644 helpdesk_convert_ticket_to_task/views/helpdesk_convert_ticket_to_task.xml diff --git a/helpdesk_convert_ticket_to_task/.gitignore b/helpdesk_convert_ticket_to_task/.gitignore new file mode 100644 index 0000000..6da5887 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/.gitignore @@ -0,0 +1,2 @@ +*.*~ +*pyc diff --git a/helpdesk_convert_ticket_to_task/README.md b/helpdesk_convert_ticket_to_task/README.md new file mode 100644 index 0000000..1eb5c44 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/README.md @@ -0,0 +1,73 @@ +=============================== +helpdesk_convert_ticket_to_task +=============================== + +This module aims to convert a ticket into a task. + +It adds a "Convert to task" button in the ticket form view (in the button box). +When clicked, a confirmation dialog appears, then the conversion process: + +* Creates a new task with the following fields copied from the ticket: + + * Name + * Description + * Project + * Assigned user + * Partner + * Priority + +* Matches the task's service and request type based on the ticket's category + and request type (by name matching). +* Copies all chatter messages and their attachments to the new task. +* Copies all attachments from the ticket to the task. +* Copies all followers (subscribers) to the new task. +* Posts a message in the new task's chatter with a link to the original ticket. +* Posts a message in the ticket's chatter with a link to the new task. +* Archives the ticket and links it to the new task. +* Transfers all timesheets from the ticket to the task. +* Redirects the user to the newly created task form. + +# Installation + +Use Odoo normal module installation procedure to install +`helpdesk_convert_ticket_to_task`. + +This module depends on: + +* `helpdesk_mgmt`: provides the base helpdesk ticket functionality. +* `helpdesk_mgmt_project`: provides the link between tickets and projects. +* `helpdesk_request_type`: provides the request type field on tickets. +* `project_request_data`: provides the service and request type fields on tasks. +* `project_task_add_very_high`: provides extended priority values (2 and 3) on + tasks to match ticket priorities. +* `helpdesk_transfer_timesheet_to_task`: provides the timesheet transfer + functionality from ticket to task. + +# Known issues / Roadmap + +A current limitation is that one task can be linked to many tickets. +Thus, the above task fields are filled up at the creation of the task from a ticket form +but are not updated when the linked tickets are updated. + +# Bug Tracker + +Bugs are tracked on [our issues website](https://git.elabore.coop/Elabore/helpdesk-tools/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. + +# Credits + +## Contributors + +- Quentin Mondot + +## Funders + +The development of this module has been financially supported by: + +- Elabore (https://elabore.coop) + +## Maintainer + +This module is maintained by Elabore. diff --git a/helpdesk_convert_ticket_to_task/__init__.py b/helpdesk_convert_ticket_to_task/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/helpdesk_convert_ticket_to_task/__manifest__.py b/helpdesk_convert_ticket_to_task/__manifest__.py new file mode 100644 index 0000000..64e3284 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/__manifest__.py @@ -0,0 +1,27 @@ +# Copyright 2024 Quentin Mondot +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "helpdesk_convert_ticket_to_task", + "version": "18.0.1.0.0", + "author": "Elabore", + "website": "https://elabore.coop", + "maintainer": "Quentin Mondot", + "license": "AGPL-3", + "category": "Tools", + "summary": "This module adds a button to convert a ticket into a task.", + "depends": [ + "base", + "helpdesk_mgmt", + "helpdesk_mgmt_project", + "helpdesk_request_type", # to create the helpdesk.request.type model and have the field request_type_id in the helpdesk.ticket model + "project_request_data", # to have the fields service_id and request_type_id in the project.task model + "project_task_add_very_high", # to have priority values 2 and 3 on tasks + "helpdesk_transfer_timesheet_to_task" # to copy timesheets from ticket to task + ], + "data": [ + "views/helpdesk_convert_ticket_to_task.xml", + ], + "installable": True, + "auto_install": False, + "application": False, +} diff --git a/helpdesk_convert_ticket_to_task/i18n/fr.po b/helpdesk_convert_ticket_to_task/i18n/fr.po new file mode 100644 index 0000000..cb22619 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/i18n/fr.po @@ -0,0 +1,63 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * helpdesk_convert_ticket_to_task +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-08-04 15:26+0000\n" +"PO-Revision-Date: 2025-08-04 15:26+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: helpdesk_convert_ticket_to_task +#: model_terms:ir.ui.view,arch_db:helpdesk_convert_ticket_to_task.convert_to_task_helpdesk_ticket_view_form +msgid "" +"Are you sure you want to convert this ticket into a task ? You'll be " +"redirected to the newly created task and this ticket will be archived." +msgstr "" +"Êtes-vous sûr de vouloir convertir ce ticket en tâche ? Vous allez être " +"redirigé vers la tâche créée et ce ticket sera archivé." + +#. module: helpdesk_convert_ticket_to_task +#: model_terms:ir.ui.view,arch_db:helpdesk_convert_ticket_to_task.convert_to_task_helpdesk_ticket_view_form +msgid "Convert to task" +msgstr "Convertir en tâche" + +#. module: helpdesk_convert_ticket_to_task +#: model:ir.model,name:helpdesk_convert_ticket_to_task.model_helpdesk_ticket +msgid "Helpdesk Ticket" +msgstr "Ticket d'Assistance" + +#. module: helpdesk_convert_ticket_to_task +#: model:ir.model.fields,field_description:helpdesk_convert_ticket_to_task.field_helpdesk_ticket__smart_search +msgid "Smart Search" +msgstr "" + +#. module: helpdesk_convert_ticket_to_task +#. odoo-python +#: code:addons/helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py:0 +#, python-format +msgid "" +"This task has been converted from a ticket. You can find the original ticket" +" on this link." +msgstr "" +"Cette tâche a été convertie depuis un ticket. Vous trouverez le ticket " +"original en cliquant sur ce " +"lien." + +#. module: helpdesk_convert_ticket_to_task +#. odoo-python +#: code:addons/helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py:0 +#, python-format +msgid "" +"This ticket has been converted into a task. You can find it on this link." +msgstr "" +"Ce ticket a été convertie en tâche. Vous trouverez la tâche en cliquant sur ce lien." diff --git a/helpdesk_convert_ticket_to_task/models/__init__.py b/helpdesk_convert_ticket_to_task/models/__init__.py new file mode 100644 index 0000000..8e082e7 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/models/__init__.py @@ -0,0 +1 @@ +from . import helpdesk_ticket diff --git a/helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py b/helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py new file mode 100644 index 0000000..ffda182 --- /dev/null +++ b/helpdesk_convert_ticket_to_task/models/helpdesk_ticket.py @@ -0,0 +1,106 @@ +from markupsafe import Markup + +from odoo import _, api, models + + +class HelpdeskTicket(models.Model): + _inherit = "helpdesk.ticket" + + def button_convert_to_task(self): + user_ids = [self.user_id.id] + task_service_id, request_type_id = self._match_task_service_and_request_type( + ticket_category_id=self.category_id.id, + ticket_request_type_id=self.request_type_id.id, + ) + + task = self.env["project.task"].create( + { + "name": self.name, + "description": self.description, + "project_id": self.project_id.id, + "user_ids": user_ids, + "partner_id": self.partner_id.id, + "service_id": task_service_id, + "request_type_id": request_type_id, + "priority": self.priority, + } + ) + + # copy chatter + for msg in reversed(self.message_ids): + msg.copy({"model": "project.task", "res_id": task.id}) + + # copy attachments inserted in the messages + for attach in msg.attachment_ids: + attach.copy( + { + "res_model": "project.task", + "res_id": task.id, + "res_name": task.name, + } + ) + + # copy attachments not added in a message + for attachment in self.attachment_ids: + attachment.copy( + {"res_model": "project.task", "res_id": task.id, "res_name": task.name} + ) + + # copy subscribers + task.message_subscribe(partner_ids=self.message_partner_ids.ids) + + # warn (in the chatter) that the task is a copy + base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url") + ticket_url = f"{base_url}/web#id={self.id}&model=helpdesk.ticket&view_type=form" + task_message = Markup( + _( + "This task has been converted from a ticket. You can find the " + "original ticket on this link." + ) + ) % {"ticket_url": ticket_url} + task.message_post(body=task_message) + + # warn (in the chatter) that the ticket has been converted + task_url = f"{base_url}/web#id={task.id}&model=project.task&view_type=form" + ticket_message = Markup( + _( + "This ticket has been converted into a task. You can find it " + "on this link." + ) + ) % {"task_url": task_url} + self.message_post(body=ticket_message) + + # archive the ticket + self.write({"active": False, "task_id": task.id}) + # transfer timesheets from ticket to task + self._onchange_task_id() + + return { + "type": "ir.actions.act_window", + "view_mode": "form", + "target": "current", + "res_model": "project.task", + "res_id": task.id, + } + + def _match_task_service_and_request_type( + self, ticket_category_id: int, ticket_request_type_id: int + ) -> tuple[int, int]: + """ + This function permits to match the task service_id and request_type from the ticket category and request type + """ + helpdesk_ticket_category = self.env["helpdesk.ticket.category"].search( + [("id", "=", ticket_category_id)], limit=1 + ) + task_service = self.env["task.service"].search( + [("name", "=", helpdesk_ticket_category.name)] + ) + + helpdesk_ticket_request_type = self.env["helpdesk.request.type"].search( + [("id", "=", ticket_request_type_id)], limit=1 + ) + task_request_type = self.env["request.type"].search( + [("name", "=", helpdesk_ticket_request_type.name)] + ) + + return task_service.id, task_request_type.id diff --git a/helpdesk_convert_ticket_to_task/views/helpdesk_convert_ticket_to_task.xml b/helpdesk_convert_ticket_to_task/views/helpdesk_convert_ticket_to_task.xml new file mode 100644 index 0000000..7d5adce --- /dev/null +++ b/helpdesk_convert_ticket_to_task/views/helpdesk_convert_ticket_to_task.xml @@ -0,0 +1,21 @@ + + + + timesheet.helpdesk.ticket.form.view + helpdesk.ticket + + + +
+
+
+
+