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
+
+
+
+