Skip to content

Commit

Permalink
[IMP] helpdesk_mgmt: Use email layout to simplify all templates
Browse files Browse the repository at this point in the history
- Avoid email_cc (error "message without recipients")
- Use coherent partner/user reference
- Access button from e-mail notifications

Semi-forward port of 98e5ef7

Please note that the commit a5041c2 (An e-mail is sent to the ticket after each create/edit) has not been forward ported because the assignment notify is done internally by odoo in `_message_auto_subscribe_followers` from `mail.thread`
  • Loading branch information
eLBati authored and PicchiSeba committed Nov 26, 2024
1 parent 0226a96 commit 99e6237
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 197 deletions.
4 changes: 4 additions & 0 deletions helpdesk_mgmt/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ Contributors
* Marcel Savegnago
* Eduardo Aparício

* `TAKOBI <https://takobi.online>`_:

* Lorenzo Battistini

* `Obertix <https://www.obertix.net>`_:

* Vicent Cubells
Expand Down
1 change: 1 addition & 0 deletions helpdesk_mgmt/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"depends": ["mail", "portal"],
"data": [
"data/helpdesk_data.xml",
"data/ir_config_parameter.xml",
"security/helpdesk_security.xml",
"security/ir.model.access.csv",
"views/res_partner_views.xml",
Expand Down
216 changes: 29 additions & 187 deletions helpdesk_mgmt/data/helpdesk_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,105 +32,33 @@
<field name="model_id" ref="helpdesk_mgmt.model_helpdesk_ticket" />
<field name="email_from">{{object.company_id.partner_id.email}}</field>
<field
name="email_cc"
name="email_to"
>{{not object.partner_id and object.partner_email or ''}},</field>
<field name="subject">The ticket {{object.number}} has been closed.</field>
<field name="partner_to">{{object.partner_id.id}}</field>
<field name="auto_delete" eval="False" />
<field name="lang">{{object.partner_id.lang}}</field>
<field name="body_html" type="html">
<table
border="0"
width="100%"
cellpadding="0"
bgcolor="#ededed"
style="padding: 20px; background-color: #ededed; border-collapse:separate;"
>
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#875A7B"
style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;"
>
<tr>
<td valign="middle" align="right">
<img
t-att-src="'/logo.png?company=%s' % object.company_id.id"
style="padding: 0px; margin: 0px; height: auto; width: 80px;"
t-att-alt="'%s' % object.company_id.name"
/>
</td>
</tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#ffffff"
style="min-width: 590px; background-color: rgb(255, 255, 255); padding: 20px; border-collapse:separate;"
>
<tbody>
<td
valign="top"
style="font-family:Arial,Helvetica,sans-serif; color: #555; font-size: 14px;"
>
<p>Hello <t t-out="object.user_id.name" />,</p>
<p>The ticket "<t
t-out="object.display_name"
/>" has been closed.</p>
</td>
</tbody>
</table>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#875A7B"
style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;"
>
<tr>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.phone" />
</td>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.email" />
</td>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.website" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div>
<p>Hello <t
t-out="object.partner_id.name or object.partner_name or ''"
/>,</p>
<p>The ticket "<t
t-out="object.display_name or 'n/a'"
/>" has been closed.</p>
<t t-if="object.partner_can_access()">
<div style="margin: 16px 0px 16px 0px;">
<a
t-attf-href="{{object.get_access_link()}}"
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;"
>
View Ticket
</a>
</div>
</t>
Thank you,<br /><br />
<t t-out="user.signature or ''" /><br />
</div>
</field>
</record>
<record id="changed_stage_template" model="mail.template">
Expand All @@ -147,100 +75,14 @@
<field name="auto_delete" eval="False" />
<field name="lang">{{object.partner_id.lang}}</field>
<field name="body_html" type="html">
<table
border="0"
width="100%"
cellpadding="0"
bgcolor="#ededed"
style="padding: 20px; background-color: #ededed; border-collapse:separate;"
>
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#875A7B"
style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;"
>
<tr>
<td valign="middle" align="right">
<img
t-att-src="'/logo.png?company=%s' % object.company_id.id"
style="padding: 0px; margin: 0px; height: auto; width: 80px;"
t-att-alt="'%s' % object.company_id.name"
/>
</td>
</tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#ffffff"
style="min-width: 590px; background-color: rgb(255, 255, 255); padding: 20px; border-collapse:separate;"
>
<tbody>
<td
valign="top"
style="font-family:Arial,Helvetica,sans-serif; color: #555; font-size: 14px;"
>
<p>Hello <t t-out="object.user_id.name" />,</p>
<p>The ticket "<t
t-out="object.display_name"
/>" stage has changed to <t
t-out="object.stage_id.name"
/>.</p>
</td>
</tbody>
</table>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table
width="590"
border="0"
cellpadding="0"
bgcolor="#875A7B"
style="min-width: 590px; background-color: rgb(135,90,123); padding: 20px; border-collapse:separate;"
>
<tr>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.phone" />
</td>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.email" />
</td>
<td
valign="middle"
align="left"
style="color: #fff; padding-top: 10px; padding-bottom: 10px; font-size: 12px;"
>
<t t-out="object.company_id.website" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div>
<p>Hello <t
t-out="object.partner_id.name or object.partner_name or ''"
/>,</p>
<p>The ticket "<t
t.out="object.display_name"
/>" stage has changed to <t t-out="object.stage_id.name" />.</p>
</div>
</field>
</record>
<!-- Sequence -->
Expand Down
9 changes: 9 additions & 0 deletions helpdesk_mgmt/data/ir_config_parameter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">

<record model="ir.config_parameter" id="created_ticket_template_name">
<field name="key">helpdesk_mgmt.created_ticket_template_name</field>
<field name="value">helpdesk_mgmt.created_ticket_template</field>
</record>

</odoo>
86 changes: 76 additions & 10 deletions helpdesk_mgmt/models/helpdesk_ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,28 @@ def _read_group_stage_ids(self, stages, domain, order):
)
active = fields.Boolean(default=True)

def _send_mail_to_partner(self, template_name):
"""Send a feedback message to the contact linked to this newly created ticket
(whatever it is a real partner or just its e-mail).
Note: The purpose of this function is to replace the stage's `mail_template_id`
role (that just doesn't work when the ticket is created from the portal or when
`partner_id` is set)"""
created_ticket_template = self.env.ref(template_name, raise_if_not_found=False)
if created_ticket_template:
created_ticket_template.send_mail(
self.id,
force_send=True,
email_layout_xmlid="mail.mail_notification_light",
)

@api.model
def _get_created_ticket_template_name(self):
return (
self.env["ir.config_parameter"]
.sudo()
.get_param("helpdesk_mgmt.created_ticket_template_name")
)

def name_get(self):
res = []
for rec in self:
Expand All @@ -154,6 +176,15 @@ def _onchange_partner_id(self):
def _creation_subtype(self):
return self.env.ref("helpdesk_mgmt.hlp_tck_created")

def _message_auto_subscribe_followers(self, updated_values, default_subtype_ids):
"""Auto-subscribe ticket partner."""
result = super()._message_auto_subscribe_followers(
updated_values, default_subtype_ids
)
if updated_values.get("partner_id"):
result.append((self.partner_id.id, default_subtype_ids, False))
return result

@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
Expand All @@ -176,7 +207,13 @@ def create(self, vals_list):
)
if channel_email_id:
vals["channel_id"] = channel_email_id.id
return super().create(vals_list)
res = super().create(vals_list)
created_ticket_template_name = self._get_created_ticket_template_name()
if created_ticket_template_name:
for rec in res:
if rec.partner_id or rec.partner_email:
rec._send_mail_to_partner(created_ticket_template_name)
return res

def copy(self, default=None):
self.ensure_one()
Expand Down Expand Up @@ -209,12 +246,6 @@ def _prepare_ticket_number(self, values):
seq = seq.with_company(values["company_id"])
return seq.next_by_code("helpdesk.ticket.sequence") or "/"

def _compute_access_url(self):
res = super()._compute_access_url()
for item in self:
item.access_url = "/my/ticket/%s" % (item.id)
return res

# ---------------------------------------------------
# Mail gateway
# ---------------------------------------------------
Expand Down Expand Up @@ -251,10 +282,8 @@ def message_new(self, msg, custom_values=None):
"partner_id": msg.get("author_id"),
}
defaults.update(custom_values)

# Write default values coming from msg
ticket = super().message_new(msg, custom_values=defaults)

# Use mail gateway tools to search for partners to subscribe
email_list = tools.email_split(
(msg.get("to") or "") + "," + (msg.get("cc") or "")
Expand All @@ -267,7 +296,6 @@ def message_new(self, msg, custom_values=None):
if p
]
ticket.message_subscribe(partner_ids)

return ticket

def message_update(self, msg, update_vals=None):
Expand Down Expand Up @@ -315,3 +343,41 @@ def _notify_get_reply_to(self, default=None):
super(HelpdeskTicket, leftover)._notify_get_reply_to(default=default)
)
return res

# ---------------------------------------------------
# Portal
# ---------------------------------------------------

def _compute_access_url(self):
res = super(HelpdeskTicket, self)._compute_access_url()
for ticket in self:
ticket.access_url = "/my/ticket/%s" % (ticket.id)
return res

def _notify_get_recipients_groups(self, msg_vals=None):
groups = super(HelpdeskTicket, self)._notify_get_recipients_groups(
msg_vals=msg_vals
)
self.ensure_one()
for group_name, _group_method, group_data in groups:
if group_name == "portal":
group_data["has_button_access"] = True
return groups

def partner_can_access(self):
if not self.partner_id:
return False
user = (
self.env["res.users"]
.sudo()
.search([("partner_id", "=", self.partner_id.id)])
)
if not user or not self.with_user(user).check_access_rights(
"read", raise_exception=False
):
return False
return True

def get_access_link(self):
# _notify_get_action_link is not callable from email template
return self._notify_get_action_link("view")
Loading

0 comments on commit 99e6237

Please sign in to comment.