Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rejection mail template #1553

Merged
merged 6 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changelog

**Added**

- #1553 Allow to modify the email template for rejection notification
- #1549 Added registry profile for jQuery UI settings
- #1544 Progress indicator for Batch listing
- #1536 Integrated Setup and Profiles from senaite.lims
Expand Down
1 change: 1 addition & 0 deletions bika/lims/api/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import mimetypes
import os
import re
import six
import socket
from email import encoders
from email.header import Header
Expand Down
40 changes: 8 additions & 32 deletions bika/lims/browser/analysisrequest/reject.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile


class AnalysisRequestRejectBase(object):
class AnalysisRequestRejectPdfView(BrowserView):
"""
Provides helper methods that ease the work with rejection reasons
View that renders the template to be used for the generation of a pdf to
be attached in the email for the notification of an Analysis Request
rejection action.
"""
template = ViewPageTemplateFile("templates/analysisrequest_retract_pdf.pt")

def __call__(self):
return self.template()

def get_rejection_reasons(self, keyword=None):
"""
Expand All @@ -49,33 +55,3 @@ def get_rejection_reasons(self, keyword=None):
return rejection_reasons.get(keyword, '') and [rejection_reasons.get(keyword, '')] or []
return rejection_reasons.get(keyword, [])


class AnalysisRequestRejectEmailView(BrowserView, AnalysisRequestRejectBase):
"""
View that renders the template to be attached in the body of the email
for the notification of an Analysis Request rejection action.
"""

template = ViewPageTemplateFile("templates/analysisrequest_retract_mail.pt")

def __init__(self, context, request):
super(AnalysisRequestRejectEmailView, self).__init__(context, request)

def __call__(self):
return self.template()


class AnalysisRequestRejectPdfView(BrowserView, AnalysisRequestRejectBase):
"""
View that renders the template to be used for the generation of a pdf to
be attached in the email for the notification of an Analysis Request
rejection action.
"""

template = ViewPageTemplateFile("templates/analysisrequest_retract_pdf.pt")

def __init__(self, context, request):
super(AnalysisRequestRejectPdfView, self).__init__(context, request)

def __call__(self):
return self.template()

This file was deleted.

27 changes: 26 additions & 1 deletion bika/lims/content/bikasetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,31 @@ def getCounterTypes(self, instance=None):
"via email to the Client when a Sample is rejected.")
),
),
TextField(
"EmailBodySampleRejection",
default_content_type='text/html',
default_output_type='text/x-html-safe',
schemata="Notifications",
label=_("Email body for Sample Rejection notifications"),
default="The sample $sample_link has been rejected because of the "
"following reasons:"
"<br/><br/>$reasons<br/><br/>"
"For further information, please contact us under the "
"following address.<br/><br/>"
"$lab_address",
widget=RichWidget(
label=_("Email body for Sample Rejection notifications"),
description=_(
"Set the text for the body of the email to be sent to the "
"Sample's client contact if the option 'Email notification on "
"Sample rejection' is enabled. You can use reserved keywords: "
"$sample_id, $sample_link, $reasons, $lab_address"),
default_mime_type='text/x-rst',
output_mime_type='text/x-html',
allow_file_upload=False,
rows=15,
),
),
BooleanField(
'NotifyOnSampleInvalidation',
schemata="Notifications",
Expand Down Expand Up @@ -640,7 +665,7 @@ def getCounterTypes(self, instance=None):
default_mime_type='text/x-rst',
output_mime_type='text/x-html',
allow_file_upload=False,
rows=10,
rows=15,
),
),
StringField(
Expand Down
22 changes: 17 additions & 5 deletions bika/lims/utils/analysisrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# Some rights reserved, see README and LICENSE.

import itertools
from string import Template

import six
from Products.Archetypes.config import UID_CATALOG
Expand All @@ -45,6 +46,7 @@
from bika.lims.utils import changeWorkflowState
from bika.lims.utils import copy_field_values
from bika.lims.utils import createPdf
from bika.lims.utils import get_link
from bika.lims.utils import tmpID
from bika.lims.workflow import ActionHandlerPool
from bika.lims.workflow import doActionFor
Expand Down Expand Up @@ -520,13 +522,23 @@ def get_rejection_pdf(sample):
def get_rejection_mail(sample, rejection_pdf=None):
"""Generates an email to sample contacts with rejection reasons
"""
# Avoid circular dependencies
from bika.lims.browser.analysisrequest.reject import \
AnalysisRequestRejectEmailView
# Get the reasons
reasons = sample.getRejectionReasons()
reasons = reasons and reasons[0] or {}
reasons = reasons.get("selected", []) + [reasons.get("other")]
reasons = filter(None, reasons)
reasons = "<br/>- ".join(reasons)

# Render the email body
tpl = AnalysisRequestRejectEmailView(sample, api.get_request())
email_body = tpl.template()
setup = api.get_setup()
lab_address = setup.laboratory.getPrintAddress()
email_body = Template(setup.getEmailBodySampleRejection())
email_body = email_body.safe_substitute({
"lab_address": "<br/>".join(lab_address),
"reasons": reasons and "<br/>-{}".format(reasons) or "",
"sample_id": api.get_id(sample),
"sample_link": get_link(api.get_url(sample), api.get_id(sample))
})

def to_valid_email_address(contact):
if not contact:
Expand Down