mirror of
https://github.com/django-helpdesk/django-helpdesk.git
synced 2024-12-13 10:21:05 +01:00
DRY out email sending code and normalize behavior
This refactor removes duplicated logic for deciding whom the messages get sent to. It also normalizes behavior ensuring that all CCed addresses are sent to in all cases that CCed individuals should be notified.
This commit is contained in:
parent
9a45d28c95
commit
6c37d73d4e
@ -39,7 +39,7 @@ from django.utils.translation import ugettext as _
|
||||
from django.utils import encoding, timezone
|
||||
|
||||
from helpdesk import settings
|
||||
from helpdesk.lib import send_templated_mail, safe_template_context, process_attachments
|
||||
from helpdesk.lib import safe_template_context, process_attachments
|
||||
from helpdesk.models import Queue, Ticket, TicketCC, FollowUp, IgnoreEmail
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
@ -54,6 +54,7 @@ STRIPPED_SUBJECT_STRINGS = [
|
||||
"Automatic reply: ",
|
||||
]
|
||||
|
||||
|
||||
def process_email(quiet=False):
|
||||
for q in Queue.objects.filter(
|
||||
email_box_type__isnull=False,
|
||||
@ -463,47 +464,18 @@ def ticket_from_message(message, queue, logger):
|
||||
context = safe_template_context(t)
|
||||
|
||||
if new:
|
||||
if sender_email:
|
||||
send_templated_mail(
|
||||
'newticket_submitter',
|
||||
context,
|
||||
recipients=sender_email,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
if queue.new_ticket_cc:
|
||||
send_templated_mail(
|
||||
'newticket_cc',
|
||||
context,
|
||||
recipients=queue.new_ticket_cc,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
if queue.updated_ticket_cc and queue.updated_ticket_cc != queue.new_ticket_cc:
|
||||
send_templated_mail(
|
||||
'newticket_cc',
|
||||
context,
|
||||
recipients=queue.updated_ticket_cc,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
t.send(
|
||||
{'submitter': ('newticket_submitter', context),
|
||||
'new_ticket_cc': ('newticket_cc', context),
|
||||
'ticket_cc': ('newticket_cc', context)},
|
||||
fail_silently=True,
|
||||
)
|
||||
else:
|
||||
context.update(comment=f.comment)
|
||||
if t.assigned_to:
|
||||
send_templated_mail(
|
||||
'updated_owner',
|
||||
context,
|
||||
recipients=t.assigned_to.email,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
if queue.updated_ticket_cc:
|
||||
send_templated_mail(
|
||||
'updated_cc',
|
||||
context,
|
||||
recipients=queue.updated_ticket_cc,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
t.send(
|
||||
{'assigned_to': ('updated_owner', context),
|
||||
'ticket_cc': ('updated_cc', context)},
|
||||
fail_silently=True,
|
||||
)
|
||||
|
||||
return t
|
||||
|
@ -17,7 +17,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils import timezone
|
||||
|
||||
from helpdesk.lib import send_templated_mail, safe_template_context, process_attachments
|
||||
from helpdesk.lib import safe_template_context, process_attachments
|
||||
from helpdesk.models import (Ticket, Queue, FollowUp, Attachment, IgnoreEmail, TicketCC,
|
||||
CustomField, TicketCustomFieldValue, TicketDependency, UserSettings)
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
@ -238,56 +238,16 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form):
|
||||
context = safe_template_context(ticket)
|
||||
context['comment'] = followup.comment
|
||||
|
||||
messages_sent_to = []
|
||||
|
||||
if ticket.submitter_email:
|
||||
send_templated_mail(
|
||||
'newticket_submitter',
|
||||
context,
|
||||
recipients=ticket.submitter_email,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(ticket.submitter_email)
|
||||
|
||||
if ticket.assigned_to and \
|
||||
ticket.assigned_to != user and \
|
||||
ticket.assigned_to.usersettings_helpdesk.email_on_ticket_assign and \
|
||||
ticket.assigned_to.email and \
|
||||
ticket.assigned_to.email not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'assigned_owner',
|
||||
context,
|
||||
recipients=ticket.assigned_to.email,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(ticket.assigned_to.email)
|
||||
|
||||
if queue.new_ticket_cc and queue.new_ticket_cc not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'newticket_cc',
|
||||
context,
|
||||
recipients=queue.new_ticket_cc,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(queue.new_ticket_cc)
|
||||
|
||||
if queue.updated_ticket_cc and \
|
||||
queue.updated_ticket_cc != queue.new_ticket_cc and \
|
||||
queue.updated_ticket_cc not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'newticket_cc',
|
||||
context,
|
||||
recipients=queue.updated_ticket_cc,
|
||||
sender=queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
roles = {'submitter': ('newticket_submitter', context),
|
||||
'new_ticket_cc': ('newticket_cc', context),
|
||||
'ticket_cc': ('newticket_cc', context)}
|
||||
if ticket.assigned_to and ticket.assigned_to.usersettings_helpdesk.email_on_ticket_assign:
|
||||
roles['assigned_to'] = ('assigned_owner', context)
|
||||
ticket.send(
|
||||
roles,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
|
||||
|
||||
class TicketForm(AbstractTicketForm):
|
||||
|
124
helpdesk/lib.py
124
helpdesk/lib.py
@ -9,142 +9,22 @@ lib.py - Common functions (eg multipart e-mail)
|
||||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
from smtplib import SMTPException
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.utils import six
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from helpdesk.models import Attachment, EmailTemplate
|
||||
|
||||
import six
|
||||
|
||||
from model_utils import Choices
|
||||
|
||||
if six.PY3:
|
||||
from base64 import encodebytes as b64encode
|
||||
from base64 import decodebytes as b64decode
|
||||
else:
|
||||
from base64 import urlsafe_b64encode as b64encode
|
||||
from base64 import urlsafe_b64decode as b64decode
|
||||
from base64 import encodebytes as b64encode
|
||||
from base64 import decodebytes as b64decode
|
||||
|
||||
logger = logging.getLogger('helpdesk')
|
||||
|
||||
|
||||
def send_templated_mail(template_name,
|
||||
context,
|
||||
recipients,
|
||||
sender=None,
|
||||
bcc=None,
|
||||
fail_silently=False,
|
||||
files=None):
|
||||
"""
|
||||
send_templated_mail() is a wrapper around Django's e-mail routines that
|
||||
allows us to easily send multipart (text/plain & text/html) e-mails using
|
||||
templates that are stored in the database. This lets the admin provide
|
||||
both a text and a HTML template for each message.
|
||||
|
||||
template_name is the slug of the template to use for this message (see
|
||||
models.EmailTemplate)
|
||||
|
||||
context is a dictionary to be used when rendering the template
|
||||
|
||||
recipients can be either a string, eg 'a@b.com', or a list of strings.
|
||||
|
||||
sender should contain a string, eg 'My Site <me@z.com>'. If you leave it
|
||||
blank, it'll use settings.DEFAULT_FROM_EMAIL as a fallback.
|
||||
|
||||
bcc is an optional list of addresses that will receive this message as a
|
||||
blind carbon copy.
|
||||
|
||||
fail_silently is passed to Django's mail routine. Set to 'True' to ignore
|
||||
any errors at send time.
|
||||
|
||||
files can be a list of tuples. Each tuple should be a filename to attach,
|
||||
along with the File objects to be read. files can be blank.
|
||||
|
||||
"""
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.template import engines
|
||||
from_string = engines['django'].from_string
|
||||
|
||||
from helpdesk.models import EmailTemplate
|
||||
from helpdesk.settings import HELPDESK_EMAIL_SUBJECT_TEMPLATE, \
|
||||
HELPDESK_EMAIL_FALLBACK_LOCALE
|
||||
|
||||
locale = context['queue'].get('locale') or HELPDESK_EMAIL_FALLBACK_LOCALE
|
||||
|
||||
try:
|
||||
t = EmailTemplate.objects.get(template_name__iexact=template_name, locale=locale)
|
||||
except EmailTemplate.DoesNotExist:
|
||||
try:
|
||||
t = EmailTemplate.objects.get(template_name__iexact=template_name, locale__isnull=True)
|
||||
except EmailTemplate.DoesNotExist:
|
||||
logger.warning('template "%s" does not exist, no mail sent', template_name)
|
||||
return # just ignore if template doesn't exist
|
||||
|
||||
subject_part = from_string(
|
||||
HELPDESK_EMAIL_SUBJECT_TEMPLATE % {
|
||||
"subject": t.subject
|
||||
}).render(context).replace('\n', '').replace('\r', '')
|
||||
|
||||
footer_file = os.path.join('helpdesk', locale, 'email_text_footer.txt')
|
||||
|
||||
text_part = from_string(
|
||||
"%s{%% include '%s' %%}" % (t.plain_text, footer_file)
|
||||
).render(context)
|
||||
|
||||
email_html_base_file = os.path.join('helpdesk', locale, 'email_html_base.html')
|
||||
# keep new lines in html emails
|
||||
if 'comment' in context:
|
||||
context['comment'] = mark_safe(context['comment'].replace('\r\n', '<br>'))
|
||||
|
||||
html_part = from_string(
|
||||
"{%% extends '%s' %%}{%% block title %%}"
|
||||
"%s"
|
||||
"{%% endblock %%}{%% block content %%}%s{%% endblock %%}" %
|
||||
(email_html_base_file, t.heading, t.html)
|
||||
).render(context)
|
||||
|
||||
if isinstance(recipients, str):
|
||||
if recipients.find(','):
|
||||
recipients = recipients.split(',')
|
||||
elif type(recipients) != list:
|
||||
recipients = [recipients]
|
||||
|
||||
msg = EmailMultiAlternatives(subject_part, text_part,
|
||||
sender or settings.DEFAULT_FROM_EMAIL,
|
||||
recipients, bcc=bcc)
|
||||
msg.attach_alternative(html_part, "text/html")
|
||||
|
||||
if files:
|
||||
for filename, filefield in files:
|
||||
mime = mimetypes.guess_type(filename)
|
||||
if mime[0] is not None and mime[0] == "text/plain":
|
||||
with open(filefield.path, 'r') as attachedfile:
|
||||
content = attachedfile.read()
|
||||
msg.attach(filename, content)
|
||||
else:
|
||||
if six.PY3:
|
||||
msg.attach_file(filefield.path)
|
||||
else:
|
||||
with open(filefield.path, 'rb') as attachedfile:
|
||||
content = attachedfile.read()
|
||||
msg.attach(filename, content)
|
||||
|
||||
logger.debug('Sending email to: {!r}'.format(recipients))
|
||||
|
||||
try:
|
||||
return msg.send()
|
||||
except SMTPException as e:
|
||||
logger.exception('SMTPException raised while sending email to {}'.format(recipients))
|
||||
if not fail_silently:
|
||||
raise e
|
||||
return 0
|
||||
|
||||
|
||||
def query_to_dict(results, descriptions):
|
||||
"""
|
||||
Replacement method for cursor.dictfetchall() as that method no longer
|
||||
|
@ -24,7 +24,7 @@ except ImportError:
|
||||
from datetime import datetime as timezone
|
||||
|
||||
from helpdesk.models import Queue, Ticket, FollowUp, EscalationExclusion, TicketChange
|
||||
from helpdesk.lib import send_templated_mail, safe_template_context
|
||||
from helpdesk.lib import safe_template_context
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
@ -107,32 +107,12 @@ def escalate_tickets(queues, verbose):
|
||||
|
||||
context = safe_template_context(t)
|
||||
|
||||
if t.submitter_email:
|
||||
send_templated_mail(
|
||||
'escalated_submitter',
|
||||
context,
|
||||
recipients=t.submitter_email,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
|
||||
if t.queue.updated_ticket_cc:
|
||||
send_templated_mail(
|
||||
'escalated_cc',
|
||||
context,
|
||||
recipients=t.queue.updated_ticket_cc,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
|
||||
if t.assigned_to:
|
||||
send_templated_mail(
|
||||
'escalated_owner',
|
||||
context,
|
||||
recipients=t.assigned_to.email,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
t.send(
|
||||
{'submitter': ('escalated_submitter', context),
|
||||
'ticket_cc': ('escalated_cc', context),
|
||||
'assigned_to': ('escalated_owner', context)}
|
||||
fail_silently=True,
|
||||
)
|
||||
|
||||
if verbose:
|
||||
print(" - Esclating %s from %s>%s" % (
|
||||
|
@ -23,6 +23,8 @@ import re
|
||||
import six
|
||||
import uuid
|
||||
|
||||
from .templated_email import send_templated_mail
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Queue(models.Model):
|
||||
@ -491,6 +493,54 @@ class Ticket(models.Model):
|
||||
default=mk_secret,
|
||||
)
|
||||
|
||||
def send(self, roles, dont_send_to=None, **kwargs):
|
||||
"""
|
||||
Send notifications to everyone interested in this ticket.
|
||||
|
||||
The the roles argument is a dictionary mapping from roles to (template, context) pairs.
|
||||
If a role is not present in the dictionary, users of that type will not recieve the notification.
|
||||
|
||||
The following roles exist:
|
||||
|
||||
- 'submitter'
|
||||
- 'new_ticket_cc'
|
||||
- 'ticket_cc'
|
||||
- 'assigned_to'
|
||||
|
||||
Here is an example roles dictionary:
|
||||
|
||||
{
|
||||
'submitter': (template_name, context),
|
||||
'assigned_to': (template_name2, context),
|
||||
}
|
||||
|
||||
**kwargs are passed to send_templated_mail defined in templated_mail.py
|
||||
|
||||
returns the set of email addresses the notification was delivered to.
|
||||
|
||||
"""
|
||||
recipients = set()
|
||||
|
||||
if dont_send_to is not None:
|
||||
recipients.update(dont_send_to)
|
||||
|
||||
def should_receive(email):
|
||||
return email and email not in recipients
|
||||
|
||||
def send(role, recipient):
|
||||
if recipient and recipient not in recipients and role in roles:
|
||||
template, context = roles[role]
|
||||
send_templated_mail(template, context, recipient, sender=self.queue.from_address, **kwargs)
|
||||
recipients.add(recipient)
|
||||
send('submitter', self.submitter_email)
|
||||
send('new_ticket_cc', self.queue.new_ticket_cc)
|
||||
if self.assigned_to and self.assigned_to.usersettings_helpdesk.email_on_ticket_assign:
|
||||
send('assigned_to', self.assigned_to.email)
|
||||
send('ticket_cc', self.queue.updated_ticket_cc)
|
||||
for cc in self.ticketcc_set.all():
|
||||
send('ticket_cc', cc.email_address)
|
||||
return recipients
|
||||
|
||||
def _get_assigned_to(self):
|
||||
""" Custom property to allow us to easily print 'Unassigned' if a
|
||||
ticket has no owner, or the users name if it's assigned. If the user
|
||||
|
114
helpdesk/templated_email.py
Normal file
114
helpdesk/templated_email.py
Normal file
@ -0,0 +1,114 @@
|
||||
import os
|
||||
import mimetypes
|
||||
import logging
|
||||
from smtplib import SMTPException
|
||||
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
logger = logging.getLogger('helpdesk')
|
||||
|
||||
|
||||
def send_templated_mail(template_name,
|
||||
context,
|
||||
recipients,
|
||||
sender=None,
|
||||
bcc=None,
|
||||
fail_silently=False,
|
||||
files=None):
|
||||
"""
|
||||
send_templated_mail() is a wrapper around Django's e-mail routines that
|
||||
allows us to easily send multipart (text/plain & text/html) e-mails using
|
||||
templates that are stored in the database. This lets the admin provide
|
||||
both a text and a HTML template for each message.
|
||||
|
||||
template_name is the slug of the template to use for this message (see
|
||||
models.EmailTemplate)
|
||||
|
||||
context is a dictionary to be used when rendering the template
|
||||
|
||||
recipients can be either a string, eg 'a@b.com', or a list of strings.
|
||||
|
||||
sender should contain a string, eg 'My Site <me@z.com>'. If you leave it
|
||||
blank, it'll use settings.DEFAULT_FROM_EMAIL as a fallback.
|
||||
|
||||
bcc is an optional list of addresses that will receive this message as a
|
||||
blind carbon copy.
|
||||
|
||||
fail_silently is passed to Django's mail routine. Set to 'True' to ignore
|
||||
any errors at send time.
|
||||
|
||||
files can be a list of tuples. Each tuple should be a filename to attach,
|
||||
along with the File objects to be read. files can be blank.
|
||||
|
||||
"""
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.template import engines
|
||||
from_string = engines['django'].from_string
|
||||
|
||||
from helpdesk.models import EmailTemplate
|
||||
from helpdesk.settings import HELPDESK_EMAIL_SUBJECT_TEMPLATE, \
|
||||
HELPDESK_EMAIL_FALLBACK_LOCALE
|
||||
|
||||
locale = context['queue'].get('locale') or HELPDESK_EMAIL_FALLBACK_LOCALE
|
||||
|
||||
try:
|
||||
t = EmailTemplate.objects.get(template_name__iexact=template_name, locale=locale)
|
||||
except EmailTemplate.DoesNotExist:
|
||||
try:
|
||||
t = EmailTemplate.objects.get(template_name__iexact=template_name, locale__isnull=True)
|
||||
except EmailTemplate.DoesNotExist:
|
||||
logger.warning('template "%s" does not exist, no mail sent', template_name)
|
||||
return # just ignore if template doesn't exist
|
||||
|
||||
subject_part = from_string(
|
||||
HELPDESK_EMAIL_SUBJECT_TEMPLATE % {
|
||||
"subject": t.subject
|
||||
}).render(context).replace('\n', '').replace('\r', '')
|
||||
|
||||
footer_file = os.path.join('helpdesk', locale, 'email_text_footer.txt')
|
||||
|
||||
text_part = from_string(
|
||||
"%s{%% include '%s' %%}" % (t.plain_text, footer_file)
|
||||
).render(context)
|
||||
|
||||
email_html_base_file = os.path.join('helpdesk', locale, 'email_html_base.html')
|
||||
# keep new lines in html emails
|
||||
if 'comment' in context:
|
||||
context['comment'] = mark_safe(context['comment'].replace('\r\n', '<br>'))
|
||||
|
||||
html_part = from_string(
|
||||
"{%% extends '%s' %%}{%% block title %%}"
|
||||
"%s"
|
||||
"{%% endblock %%}{%% block content %%}%s{%% endblock %%}" %
|
||||
(email_html_base_file, t.heading, t.html)
|
||||
).render(context)
|
||||
|
||||
if isinstance(recipients, str):
|
||||
if recipients.find(','):
|
||||
recipients = recipients.split(',')
|
||||
elif type(recipients) != list:
|
||||
recipients = [recipients]
|
||||
|
||||
msg = EmailMultiAlternatives(subject_part, text_part,
|
||||
sender or settings.DEFAULT_FROM_EMAIL,
|
||||
recipients, bcc=bcc)
|
||||
msg.attach_alternative(html_part, "text/html")
|
||||
|
||||
if files:
|
||||
for filename, filefield in files:
|
||||
mime = mimetypes.guess_type(filename)
|
||||
if mime[0] is not None and mime[0] == "text/plain":
|
||||
with open(filefield.path, 'r') as attachedfile:
|
||||
content = attachedfile.read()
|
||||
msg.attach(filename, content)
|
||||
else:
|
||||
msg.attach_file(filefield.path)
|
||||
logger.debug('Sending email to: {!r}'.format(recipients))
|
||||
|
||||
try:
|
||||
return msg.send()
|
||||
except SMTPException as e:
|
||||
logger.exception('SMTPException raised while sending email to {}'.format(recipients))
|
||||
if not fail_silently:
|
||||
raise e
|
||||
return 0
|
@ -47,7 +47,7 @@ from helpdesk.forms import (
|
||||
TicketCCEmailForm, TicketCCUserForm, EditFollowUpForm, TicketDependencyForm
|
||||
)
|
||||
from helpdesk.lib import (
|
||||
send_templated_mail, query_to_dict, apply_query, safe_template_context,
|
||||
query_to_dict, apply_query, safe_template_context,
|
||||
process_attachments, queue_template_context,
|
||||
)
|
||||
from helpdesk.models import (
|
||||
@ -578,8 +578,6 @@ def update_ticket(request, ticket_id, public=False):
|
||||
if new_status == Ticket.RESOLVED_STATUS or ticket.resolution is None:
|
||||
ticket.resolution = comment
|
||||
|
||||
messages_sent_to = []
|
||||
|
||||
# ticket might have changed above, so we re-instantiate context with the
|
||||
# (possibly) updated ticket.
|
||||
context = safe_template_context(ticket)
|
||||
@ -588,6 +586,11 @@ def update_ticket(request, ticket_id, public=False):
|
||||
comment=f.comment,
|
||||
)
|
||||
|
||||
messages_sent_to = set()
|
||||
try:
|
||||
messages_sent_to.add(request.user.email)
|
||||
except AttributeError:
|
||||
pass
|
||||
if public and (f.comment or (
|
||||
f.new_status in (Ticket.RESOLVED_STATUS,
|
||||
Ticket.CLOSED_STATUS))):
|
||||
@ -598,83 +601,44 @@ def update_ticket(request, ticket_id, public=False):
|
||||
else:
|
||||
template = 'updated_'
|
||||
|
||||
template_suffix = 'submitter'
|
||||
roles = {
|
||||
'submitter': (template + 'submitter', context),
|
||||
'ticket_cc': (template + 'cc', context),
|
||||
'assigned_to': (template + 'cc', context),
|
||||
}
|
||||
messages_sent_to.update(ticket.send(roles, dont_send_to=messages_sent_to, fail_silently=True, files=files,))
|
||||
|
||||
if ticket.submitter_email:
|
||||
send_templated_mail(
|
||||
template + template_suffix,
|
||||
context,
|
||||
recipients=ticket.submitter_email,
|
||||
sender=ticket.queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(ticket.submitter_email)
|
||||
if reassigned:
|
||||
template_staff = 'assigned_owner'
|
||||
elif f.new_status == Ticket.RESOLVED_STATUS:
|
||||
template_staff = 'resolved_owner'
|
||||
elif f.new_status == Ticket.CLOSED_STATUS:
|
||||
template_staff = 'closed_owner'
|
||||
else:
|
||||
template_staff = 'updated_owner'
|
||||
|
||||
template_suffix = 'cc'
|
||||
messages_sent_to.update(ticket.send(
|
||||
{'assigned_to': (template_staff, context)},
|
||||
dont_send_to=messages_sent_to,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
))
|
||||
|
||||
for cc in ticket.ticketcc_set.all():
|
||||
if cc.email_address not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
template + template_suffix,
|
||||
context,
|
||||
recipients=cc.email_address,
|
||||
sender=ticket.queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(cc.email_address)
|
||||
if reassigned:
|
||||
template_cc = 'assigned_cc'
|
||||
elif f.new_status == Ticket.RESOLVED_STATUS:
|
||||
template_cc = 'resolved_cc'
|
||||
elif f.new_status == Ticket.CLOSED_STATUS:
|
||||
template_cc = 'closed_cc'
|
||||
else:
|
||||
template_cc = 'updated_cc'
|
||||
|
||||
if ticket.assigned_to and \
|
||||
request.user != ticket.assigned_to and \
|
||||
ticket.assigned_to.email and \
|
||||
ticket.assigned_to.email not in messages_sent_to:
|
||||
# We only send e-mails to staff members if the ticket is updated by
|
||||
# another user. The actual template varies, depending on what has been
|
||||
# changed.
|
||||
if reassigned:
|
||||
template_staff = 'assigned_owner'
|
||||
elif f.new_status == Ticket.RESOLVED_STATUS:
|
||||
template_staff = 'resolved_owner'
|
||||
elif f.new_status == Ticket.CLOSED_STATUS:
|
||||
template_staff = 'closed_owner'
|
||||
else:
|
||||
template_staff = 'updated_owner'
|
||||
|
||||
if (not reassigned or
|
||||
(reassigned and
|
||||
ticket.assigned_to.usersettings_helpdesk.email_on_ticket_assign)) or \
|
||||
(not reassigned and
|
||||
ticket.assigned_to.usersettings_helpdesk.email_on_ticket_change):
|
||||
|
||||
send_templated_mail(
|
||||
template_staff,
|
||||
context,
|
||||
recipients=ticket.assigned_to.email,
|
||||
sender=ticket.queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.append(ticket.assigned_to.email)
|
||||
|
||||
if ticket.queue.updated_ticket_cc and ticket.queue.updated_ticket_cc not in messages_sent_to:
|
||||
if reassigned:
|
||||
template_cc = 'assigned_cc'
|
||||
elif f.new_status == Ticket.RESOLVED_STATUS:
|
||||
template_cc = 'resolved_cc'
|
||||
elif f.new_status == Ticket.CLOSED_STATUS:
|
||||
template_cc = 'closed_cc'
|
||||
else:
|
||||
template_cc = 'updated_cc'
|
||||
|
||||
send_templated_mail(
|
||||
template_cc,
|
||||
context,
|
||||
recipients=ticket.queue.updated_ticket_cc,
|
||||
sender=ticket.queue.from_address,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
)
|
||||
messages_sent_to.update(ticket.send(
|
||||
{'ticket_cc': (template_cc, context)},
|
||||
dont_send_to=messages_sent_to,
|
||||
fail_silently=True,
|
||||
files=files,
|
||||
))
|
||||
|
||||
ticket.save()
|
||||
|
||||
@ -760,51 +724,19 @@ def mass_update(request):
|
||||
context.update(resolution=t.resolution,
|
||||
queue=queue_template_context(t.queue))
|
||||
|
||||
messages_sent_to = []
|
||||
messages_sent_to = set()
|
||||
try:
|
||||
messages_sent_to.add(request.user.email)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if t.submitter_email:
|
||||
send_templated_mail(
|
||||
'closed_submitter',
|
||||
context,
|
||||
recipients=t.submitter_email,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
messages_sent_to.append(t.submitter_email)
|
||||
|
||||
for cc in t.ticketcc_set.all():
|
||||
if cc.email_address not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'closed_submitter',
|
||||
context,
|
||||
recipients=cc.email_address,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
messages_sent_to.append(cc.email_address)
|
||||
|
||||
if t.assigned_to and \
|
||||
request.user != t.assigned_to and \
|
||||
t.assigned_to.email and \
|
||||
t.assigned_to.email not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'closed_owner',
|
||||
context,
|
||||
recipients=t.assigned_to.email,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
messages_sent_to.append(t.assigned_to.email)
|
||||
|
||||
if t.queue.updated_ticket_cc and \
|
||||
t.queue.updated_ticket_cc not in messages_sent_to:
|
||||
send_templated_mail(
|
||||
'closed_cc',
|
||||
context,
|
||||
recipients=t.queue.updated_ticket_cc,
|
||||
sender=t.queue.from_address,
|
||||
fail_silently=True,
|
||||
)
|
||||
messages_sent_to.update(t.send(
|
||||
{'submitter': ('closed_submitter', context),
|
||||
'ticket_cc': ('closed_cc', context),
|
||||
'assigned_to': ('closded_owner', context)},
|
||||
dont_send_to=messages_sent_to,
|
||||
fail_silently=True,
|
||||
))
|
||||
|
||||
elif action == 'delete':
|
||||
t.delete()
|
||||
|
Loading…
Reference in New Issue
Block a user