diff --git a/helpdesk_mgmt_activity/__manifest__.py b/helpdesk_mgmt_activity/__manifest__.py index 8a10d4ebd8..f61aa4eebf 100644 --- a/helpdesk_mgmt_activity/__manifest__.py +++ b/helpdesk_mgmt_activity/__manifest__.py @@ -12,6 +12,7 @@ "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, diff --git a/helpdesk_mgmt_activity/models/helpdesk_ticket.py b/helpdesk_mgmt_activity/models/helpdesk_ticket.py index a6b6afe83c..51d8212440 100644 --- a/helpdesk_mgmt_activity/models/helpdesk_ticket.py +++ b/helpdesk_mgmt_activity/models/helpdesk_ticket.py @@ -9,21 +9,27 @@ class HelpdeskTicket(models.Model): _inherit = "helpdesk.ticket" - can_create_activity = fields.Boolean(related="team_id.is_set_activity") + 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="_referenceable_models", + 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.context_today) + next_stage_id = fields.Many2one( + comodel_name="helpdesk.ticket.stage", + compute="_compute_next_stage_id", + store=True, + index=True, + ) @api.model - def _referenceable_models(self): + def _selection_record_ref(self): """Select target model for source document""" model_ids_str = ( self.env["ir.config_parameter"] @@ -43,31 +49,62 @@ def _referenceable_models(self): 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} + + @api.depends("stage_id") + def _compute_next_stage_id(self): + """Compute next stage for ticket""" + team_stages = self._get_team_stages(self.team_id) + for record in self: + current_stage = record.stage_id + stages = team_stages.get( + record.team_id.id, self.env["helpdesk.ticket.stage"] + ) + 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 rec.res_model and rec.res_id: - 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 - else: + 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 def _inverse_record_ref(self): """Set Source Document Reference""" for record in self: - if record.record_ref: - res_id = record.record_ref.id - res_model = record.record_ref._name - else: - res_id, res_model = False, False - record.write({"res_id": res_id, "res_model": res_model}) + 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""" @@ -94,7 +131,6 @@ def perform_action(self): "default_res_id": self.res_id, "default_activity_type_id": self.source_activity_type_id.id, "default_date_deadline": self.date_deadline, - "default_note": self.description, "default_ticket_id": self.id, "default_summary": self.name, "default_user_id": self.user_id.id, diff --git a/helpdesk_mgmt_activity/models/helpdesk_ticket_team.py b/helpdesk_mgmt_activity/models/helpdesk_ticket_team.py index bc4a2acc41..ecb27dd23c 100644 --- a/helpdesk_mgmt_activity/models/helpdesk_ticket_team.py +++ b/helpdesk_mgmt_activity/models/helpdesk_ticket_team.py @@ -4,7 +4,7 @@ class HelpdeskTicketTeam(models.Model): _inherit = "helpdesk.ticket.team" - is_set_activity = fields.Boolean( + allow_set_activity = fields.Boolean( string="Set Activities", help="Available to set activity on source record from ticket", ) diff --git a/helpdesk_mgmt_activity/models/mail_activity.py b/helpdesk_mgmt_activity/models/mail_activity.py index 150186786e..a73d0b545c 100644 --- a/helpdesk_mgmt_activity/models/mail_activity.py +++ b/helpdesk_mgmt_activity/models/mail_activity.py @@ -1,4 +1,4 @@ -from odoo import fields, models +from odoo import api, fields, models class MailActivity(models.Model): @@ -12,8 +12,25 @@ class MailActivity(models.Model): def _action_done(self, feedback=False, attachment_ids=None): # Get closed stage for ticket - for ticket in self.mapped("ticket_id"): + 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) + + @api.onchange("activity_type_id") + def _onchange_activity_type_id(self): + result = super()._onchange_activity_type_id() + if self.ticket_id: + # Add ticket description to action note + self.note = (self.note or "") + "
{}".format( + self.ticket_id.description + ) + return result + + @api.model_create_multi + def create(self, vals_list): + records = super().create(vals_list) + # Set next stage for helpdesk ticket's + records.ticket_id.set_next_stage() + return records diff --git a/helpdesk_mgmt_activity/tests/test_helpdesk_ticket.py b/helpdesk_mgmt_activity/tests/test_helpdesk_ticket.py index 52596007b1..2c02c2b93d 100644 --- a/helpdesk_mgmt_activity/tests/test_helpdesk_ticket.py +++ b/helpdesk_mgmt_activity/tests/test_helpdesk_ticket.py @@ -19,6 +19,12 @@ def setUpClass(cls): "helpdesk_mgmt_activity.helpdesk_available_model_ids", cls.partner_model.ids ) + # Stages + cls.progress_stage = cls.env.ref( + "helpdesk_mgmt.helpdesk_ticket_stage_in_progress" + ) + cls.awaiting_stage = cls.env.ref("helpdesk_mgmt.helpdesk_ticket_stage_awaiting") + def create_ticket_and_activity(self): """Create ticket and activity for record""" ticket = self._create_ticket(self.team_a, self.user) @@ -39,6 +45,47 @@ def create_ticket_and_activity(self): ) return ticket, activity + def test_ticket_next_stage(self): + """Test flow check stage for ticket""" + # Set team config + self.team_a.write( + { + "allow_set_activity": True, + "activity_stage_id": self.stage_closed.id, + } + ) + # Create ticket + ticket = self._create_ticket(self.team_a, self.user) + + self.assertEqual(ticket.stage_id, self.new_stage) + self.assertEqual(ticket.next_stage_id, self.progress_stage) + + # Set activity configuration for ticket + ticket.write( + { + "record_ref": f"res.partner,{self.test_partner.id}", + "source_activity_type_id": self.activity_type_meeting.id, + "date_deadline": Date.today(), + } + ) + + # Create activity for source record + action = ticket.perform_action() + activity = ticket.record_ref.with_context( + **action.get("context", {}) + ).activity_schedule( + summary=ticket.name, + note=ticket.description, + date_deadline=ticket.date_deadline, + ) + + self.assertEqual(ticket.stage_id, self.progress_stage) + + # Activity set done + activity.action_done() + + self.assertEqual(ticket.stage_id, self.stage_closed) + def test_ticket_available_model_ids(self): """Test flow when available model for ticket is updated""" settings = self.env["res.config.settings"].create({}) @@ -78,7 +125,7 @@ def test_perform_action(self): ticket.perform_action() self.assertEqual(error.exception.args[0], "You cannot create activity!") - ticket.team_id.is_set_activity = True + ticket.team_id.allow_set_activity = True with self.assertRaises(UserError) as error: ticket.perform_action() @@ -114,7 +161,6 @@ def test_perform_action(self): "default_res_id": ticket.res_id, "default_activity_type_id": ticket.source_activity_type_id.id, "default_date_deadline": ticket.date_deadline, - "default_note": ticket.description, "default_ticket_id": ticket.id, "default_summary": ticket.name, "default_user_id": ticket.user_id.id, @@ -130,7 +176,7 @@ def test_helpdesk_activity_with_team_stage(self): """ self.team_a.write( { - "is_set_activity": True, + "allow_set_activity": True, "activity_stage_id": self.stage_closed.id, } ) @@ -154,7 +200,7 @@ def test_helpdesk_activity_without_team_stage(self): Test flow when create activity from helpdesk ticket and done it without activity_stage_id field value from ticket team """ - self.team_a.is_set_activity = True + self.team_a.allow_set_activity = True ticket, activity = self.create_ticket_and_activity() ticket_stage_id = ticket.stage_id.id self.assertEqual( diff --git a/helpdesk_mgmt_activity/views/helpdesk_ticket_team_views.xml b/helpdesk_mgmt_activity/views/helpdesk_ticket_team_views.xml index 6b9115a8bb..d795f984c5 100644 --- a/helpdesk_mgmt_activity/views/helpdesk_ticket_team_views.xml +++ b/helpdesk_mgmt_activity/views/helpdesk_ticket_team_views.xml @@ -7,10 +7,11 @@ 99 - + diff --git a/helpdesk_mgmt_activity/views/helpdesk_ticket_view.xml b/helpdesk_mgmt_activity/views/helpdesk_ticket_view.xml index 1b302ec718..33f3b0e78b 100644 --- a/helpdesk_mgmt_activity/views/helpdesk_ticket_view.xml +++ b/helpdesk_mgmt_activity/views/helpdesk_ticket_view.xml @@ -10,13 +10,14 @@