Skip to content

Commit

Permalink
[ADD] helpdesk_mgmt_activity: Add module
Browse files Browse the repository at this point in the history
The module adds the following features:

- Set the list of models available for a Helpdesk
- Refer the Odoo model record to the Helpdesk Ticket
- Create an activity for the referring record right from the Helpdesk and move the ticket to the next state automatically
- Move the Ticket to a pre-defined stage automatically when the referred activity created from the Helpdesk is marked as Done

To streamline your helpdesk operations you can set activities to the pre-configured odoo modules records right from the Helpdesk. The ticket will be moved to the pre-defined stage when the activity is marked as done.
For instance:
A customer reached out to the support team regarding a delayed shipment.

- Assign Activity: The helpdesk support team user opens a ticket for the relevant Inventory picking record with specific instructions to check the shipment status and actions that must be taken.
- Warehouse Action: The assigned warehouse user sees the new activity in their Odoo dashboard, follows the prescribed steps to investigate, and updates the activity status accordingly.
- Automated Updates: Once the warehouse user marks the activity as done, the ticket automatically moves to the "Awaiting" stage to be checked by the support team use
  • Loading branch information
dessanhemrayev authored and geomer198 committed Dec 10, 2024
1 parent f371905 commit 1ef073b
Show file tree
Hide file tree
Showing 26 changed files with 1,358 additions and 0 deletions.
152 changes: 152 additions & 0 deletions helpdesk_mgmt_activity/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
============================
Helpdesk Management Activity
============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:c77bb124906154be8648020f75af1b6c2dca2c419551445c18e60b86488fe429
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fhelpdesk-lightgray.png?logo=github
:target: https://github.com/OCA/helpdesk/tree/16.0/helpdesk_mgmt_activity
:alt: OCA/helpdesk
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/helpdesk-16-0/helpdesk-16-0-helpdesk_mgmt_activity
: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/helpdesk&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

The module adds the following features:

* Link a ticket to an Odoo model record
* Set the list of available models for a Helpdesk team
* Pre-configure ticket description template based on it's category
* Create an activity for the linked record right from the Ticket
* Change the Ticket's stage based on the activity state



**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

To streamline your helpdesk operations you can set activities to the pre-configured odoo modules records right from the Helpdesk.

The ticket will be moved to the pre-defined stage when the activity is marked as done.

For instance:

A customer reaches the support team regarding a delayed shipment. 
- Assign Activity: The helpdesk support team user opens a ticket for the relevant Inventory picking record with specific instructions to check the shipment status and actions that must be taken.
- Warehouse Action: The assigned warehouse user sees the new activity in their Odoo dashboard, follows the prescribed steps to investigate, and updates the activity status accordingly.
- Automated Updates: Once the warehouse user marks the activity as done, the ticket automatically moves to the "Awaiting" stage to be checked by the support team user.

Configuration
=============

**To Configure Available Odoo Models**
======================================

- Go to Helpdesk-->Configuration-->Settings
- In the Available Models field add models available for a Helpdesk

.. figure:: https://raw.githubusercontent.com/OCA/helpdesk/16.0/helpdesk_mgmt_activity/static/img/settings.png
:alt: Settings view
:width: 600 px

To Configure Ticket's Stage on Activity State**
===============================================

- Go to Helpdesk-->Configuration-->Teams
- Create a new team or select an existing record
- Enable the "Set Activities" checkbox to enable the feature
- Select the "Done Activity Stage" to move the ticket when the activity is done

.. figure:: https://raw.githubusercontent.com/OCA/helpdesk/16.0/helpdesk_mgmt_activity/static/img/team.png
:alt: Team view
:width: 600 px


Usage
=====

**Go to Helpdesk module**
=========================

- Select a Team
- Open a Ticket
- Create a new Ticket
- In the "Assign Activity" group

- Select a related model and record in the Source field
- Select Activity type and due date

.. image:: https://raw.githubusercontent.com/OCA/helpdesk/16.0/helpdesk_mgmt_activity/static/img/helpdesk_activity_fields.png
:width: 400
:alt: Helpdesk Activity Fields

- Enter the Description
- Click the "Perform Action" button
- Ticket will be moved to the next preset state and activity will be created in the related model
- If an activity is Done, the Ticket moves to the pre-defined stage

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/helpdesk/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 <https://github.com/OCA/helpdesk/issues/new?body=module:%20helpdesk_mgmt_activity%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
~~~~~~~

* Cetmix OÜ

Contributors
~~~~~~~~~~~~

* `Cetmix OÜ <https://cetmix.com>`_:

* Ivan Sokolov
* Mikhail Lapin
* Dessan Hemrayev
* Maksim Shurupov

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.

This module is part of the `OCA/helpdesk <https://github.com/OCA/helpdesk/tree/16.0/helpdesk_mgmt_activity>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 4 additions & 0 deletions helpdesk_mgmt_activity/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
19 changes: 19 additions & 0 deletions helpdesk_mgmt_activity/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Helpdesk Management Activity",
"summary": "Create Activities for Odoo records from the Helpdesk",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "Cetmix OÜ, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/helpdesk",
"depends": ["helpdesk_mgmt"],
"data": [
"views/res_config_settings_views.xml",
"views/helpdesk_ticket_view.xml",
"views/mail_activity_views.xml",
"views/helpdesk_ticket_team_views.xml",
],
"application": False,
}
7 changes: 7 additions & 0 deletions helpdesk_mgmt_activity/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import res_config_settings
from . import helpdesk_ticket
from . import helpdesk_ticket_team
from . import mail_activity
155 changes: 155 additions & 0 deletions helpdesk_mgmt_activity/models/helpdesk_ticket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import ast

from odoo import _, api, fields, models


class HelpdeskTicket(models.Model):
_inherit = "helpdesk.ticket"

can_create_activity = fields.Boolean(related="team_id.allow_set_activity")
res_model = fields.Char(string="Source Document Model", index=True)
res_id = fields.Integer(string="Source Document", index=True)

record_ref = fields.Reference(
selection="_selection_record_ref",
compute="_compute_record_ref",
inverse="_inverse_record_ref",
string="Source Record",
)
source_activity_type_id = fields.Many2one(comodel_name="mail.activity.type")
date_deadline = fields.Date(string="Due Date", default=fields.Date.today)
next_stage_id = fields.Many2one(
comodel_name="helpdesk.ticket.stage",
compute="_compute_next_stage_id",
store=True,
index=True,
)
assigned_user_id = fields.Many2one(
comodel_name="res.users",
)
is_new_stage = fields.Boolean(compute="_compute_is_new_stage")

@api.model
def _selection_record_ref(self):
"""Select target model for source document"""
model_ids_str = (
self.env["ir.config_parameter"]
.sudo()
.get_param("helpdesk_mgmt_activity.helpdesk_available_model_ids", "[]")
)
model_ids = ast.literal_eval(model_ids_str)
if not model_ids:
return []
IrModelAccess = self.env["ir.model.access"].with_user(self.env.user.id)
available_models = self.env["ir.model"].search_read(
[("id", "in", model_ids)], fields=["model", "name"]
)
return [
(model.get("model"), model.get("name"))
for model in available_models
if IrModelAccess.check(model.get("model"), "read", False)
]

@api.model
def _get_team_stages(self, teams):
"""
Get grouping stages by team id
:param teams: helpdesk.ticket.team record set
:return: dict {team_id: team stages recordset}
"""
return {team.id: team._get_applicable_stages() for team in teams}

def _compute_is_new_stage(self):
for ticket in self:
new_stage = ticket.team_id._get_applicable_stages()[:1]
ticket.is_new_stage = ticket.stage_id == new_stage

Check warning on line 69 in helpdesk_mgmt_activity/models/helpdesk_ticket.py

View check run for this annotation

Codecov / codecov/patch

helpdesk_mgmt_activity/models/helpdesk_ticket.py#L68-L69

Added lines #L68 - L69 were not covered by tests

@api.depends("stage_id")
def _compute_next_stage_id(self):
"""Compute next stage for ticket"""
team_stages = self._get_team_stages(self.team_id)
helpdesk_ticket_stage_obj = self.env["helpdesk.ticket.stage"]
for record in self:
current_stage = record.stage_id
stages = team_stages.get(record.team_id.id, helpdesk_ticket_stage_obj)
next_stage = (
stages.filtered(
lambda stage, _cur_stage=current_stage: stage.sequence
> current_stage.sequence
)[:1]
or current_stage
)
record.next_stage_id = next_stage

@api.depends("res_model", "res_id")
def _compute_record_ref(self):
"""Compute Source Document Reference"""
for rec in self:
if not rec.res_model or not rec.res_id:
rec.record_ref = None
continue
try:
self.env[rec.res_model].browse(rec.res_id).check_access_rule("read")
rec.record_ref = "%s,%s" % (rec.res_model, rec.res_id)
except Exception:
rec.record_ref = None

Check warning on line 99 in helpdesk_mgmt_activity/models/helpdesk_ticket.py

View check run for this annotation

Codecov / codecov/patch

helpdesk_mgmt_activity/models/helpdesk_ticket.py#L98-L99

Added lines #L98 - L99 were not covered by tests

def _inverse_record_ref(self):
"""Set Source Document Reference"""
for record in self:
record_ref = record.record_ref
record.write(
{
"res_id": record_ref and record_ref.id or False,
"res_model": record_ref and record_ref._name or False,
}
)

def set_next_stage(self):
"""Set next ticket stage"""
for record in self:
record.stage_id = record.next_stage_id

def _check_activity_values(self):
"""Check activity values for helpdesk ticket"""
if not self.can_create_activity:
raise models.UserError(_("You cannot create activity!"))
if not (self.res_id and self.res_model):
raise models.UserError(_("Source Record is not set!"))
if not self.source_activity_type_id:
raise models.UserError(_("Activity Type is not set!"))
if not self.date_deadline:
raise models.UserError(_("Date Deadline is not set!"))
if not self.assigned_user_id:
raise models.UserError(_("Assigned User is not set!"))

def perform_action(self):
"""Perform action for ticket"""
self.ensure_one()
# Check values for create activity
self._check_activity_values()
try:
# Create activity for source record
self.record_ref.activity_schedule(
summary=self.name,
note=self.description,
date_deadline=self.date_deadline,
activity_type_id=self.source_activity_type_id.id,
ticket_id=self.id,
)
self.set_next_stage()
except Exception as e:
raise models.UserError from e

Check warning on line 146 in helpdesk_mgmt_activity/models/helpdesk_ticket.py

View check run for this annotation

Codecov / codecov/patch

helpdesk_mgmt_activity/models/helpdesk_ticket.py#L145-L146

Added lines #L145 - L146 were not covered by tests
return {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {
"type": "success",
"message": _("Activity has been created!"),
"next": {"type": "ir.actions.act_window_close"},
},
}
19 changes: 19 additions & 0 deletions helpdesk_mgmt_activity/models/helpdesk_ticket_team.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class HelpdeskTicketTeam(models.Model):
_inherit = "helpdesk.ticket.team"

allow_set_activity = fields.Boolean(
string="Set Activities",
help="Available to set activity on source record from ticket",
)
activity_stage_id = fields.Many2one(
comodel_name="helpdesk.ticket.stage",
string="Done Activity Stage",
domain="['|', ('team_ids', 'in, []'), ('team_ids', 'in', [id])]",
help="Move the ticket when the activity in source record is done",
)
22 changes: 22 additions & 0 deletions helpdesk_mgmt_activity/models/mail_activity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright (C) 2024 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import fields, models


class MailActivity(models.Model):
_inherit = "mail.activity"

ticket_id = fields.Many2one(
comodel_name="helpdesk.ticket",
help="Activity created from helpdesk ticket"
"After closing this activity, ticket is moved to done stage",
)

def _action_done(self, feedback=False, attachment_ids=None):
# Get closed stage for ticket
for ticket in self.ticket_id:
if ticket.team_id and ticket.team_id.activity_stage_id:
# Change ticket stage
ticket.stage_id = ticket.team_id.activity_stage_id.id
return super()._action_done(feedback, attachment_ids)
Loading

0 comments on commit 1ef073b

Please sign in to comment.