Mails for approval process

This commit is contained in:
Carlos Lopez 2020-06-04 00:35:59 -06:00
parent 299ad4fc8b
commit f581bd9f2b
15 changed files with 192 additions and 16 deletions

View File

@ -39,6 +39,7 @@ ldap3 = "*"
gunicorn = "*"
werkzeug = "*"
sentry-sdk = {extras = ["flask"],version = "==0.14.4"}
flask-mail = "*"
[requires]
python_version = "3.7"

39
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "54d9d51360f54762138a3acc7696badd1d711e7b1dde9e2d82aa706e40c17102"
"sha256": "6c89585086260ebcb41918b8ef3b1d9e189e1b492208d3ff000a138bc2f2fcee"
},
"pipfile-spec": 6,
"requires": {
@ -104,10 +104,10 @@
},
"celery": {
"hashes": [
"sha256:5147662e23dc6bc39c17a2cbc9a148debe08ecfb128b0eded14a0d9c81fc5742",
"sha256:df2937b7536a2a9b18024776a3a46fd281721813636c03a5177fa02fe66078f6"
"sha256:9ae2e73b93cc7d6b48b56aaf49a68c91752d0ffd7dfdcc47f842ca79a6f13eae",
"sha256:c2037b6a8463da43b19969a0fc13f9023ceca6352b4dd51be01c66fbbb13647e"
],
"version": "==4.4.3"
"version": "==4.4.4"
},
"certifi": {
"hashes": [
@ -276,6 +276,13 @@
"index": "pypi",
"version": "==3.0.8"
},
"flask-mail": {
"hashes": [
"sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41"
],
"index": "pypi",
"version": "==0.9.1"
},
"flask-marshmallow": {
"hashes": [
"sha256:6e6aec171b8e092e0eafaf035ff5b8637bf3a58ab46f568c4c1bab02f2a3c196",
@ -387,10 +394,10 @@
},
"kombu": {
"hashes": [
"sha256:ab0afaa5388dd2979cbc439d3623b86a4f7a58d41f621096bef7767c37bc2505",
"sha256:aece08f48706743aaa1b9d607fee300559481eafcc5ee56451aa0ef867a3be07"
"sha256:437b9cdea193cc2ed0b8044c85fd0f126bb3615ca2f4d4a35b39de7cacfa3c1a",
"sha256:dc282bb277197d723bccda1a9ba30a27a28c9672d0ab93e9e51bb05a37bd29c3"
],
"version": "==4.6.9"
"version": "==4.6.10"
},
"ldap3": {
"hashes": [
@ -479,11 +486,11 @@
},
"marshmallow": {
"hashes": [
"sha256:c2673233aa21dde264b84349dc2fd1dce5f30ed724a0a00e75426734de5b84ab",
"sha256:f88fe96434b1f0f476d54224d59333eba8ca1a203a2695683c1855675c4049a7"
"sha256:35ee2fb188f0bd9fc1cf9ac35e45fd394bd1c153cee430745a465ea435514bd5",
"sha256:9aa20f9b71c992b4782dad07c51d92884fd0f7c5cb9d3c737bea17ec1bad765f"
],
"index": "pypi",
"version": "==3.6.0"
"version": "==3.6.1"
},
"marshmallow-enum": {
"hashes": [
@ -968,11 +975,11 @@
},
"pytest": {
"hashes": [
"sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3",
"sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"
"sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1",
"sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"
],
"index": "pypi",
"version": "==5.4.2"
"version": "==5.4.3"
},
"six": {
"hashes": [
@ -983,10 +990,10 @@
},
"wcwidth": {
"hashes": [
"sha256:3de2e41158cb650b91f9654cbf9a3e053cee0719c9df4ddc11e4b568669e9829",
"sha256:b651b6b081476420e4e9ae61239ac4c1b49d0c5ace42b2e81dc2ff49ed50c566"
"sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6",
"sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830"
],
"version": "==0.2.2"
"version": "==0.2.3"
},
"zipp": {
"hashes": [

View File

@ -3,6 +3,7 @@ import os
import sentry_sdk
import connexion
from jinja2 import Environment, FileSystemLoader
from flask_cors import CORS
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate
@ -48,6 +49,10 @@ if app.config['ENABLE_SENTRY']:
integrations=[FlaskIntegration()]
)
# Jinja environment definition, used to render mail templates
template_dir = os.getcwd() + '/crc/static/templates/mails'
env = Environment(loader=FileSystemLoader(template_dir))
print('=== USING THESE CONFIG SETTINGS: ===')
print('DB_HOST = ', )
print('CORS_ALLOW_ORIGINS = ', app.config['CORS_ALLOW_ORIGINS'])

99
crc/services/mails.py Normal file
View File

@ -0,0 +1,99 @@
import os
from crc import app, env
from jinja2 import Environment, FileSystemLoader
from flask import render_template, render_template_string
from flask_mail import Mail, Message
# TODO: Extract common mailing code into its own function
def send_ramp_up_submission_email(sender, recipients, approver_1, approver_2=None):
with app.app_context():
try:
msg = Message('Research Ramp-up Plan Submitted',
sender=sender,
recipients=recipients)
template = env.get_template('ramp_up_submission.txt')
template_vars = {'approver_1': approver_1, 'approver_2': approver_2}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_submission.html')
msg.html = template.render(template_vars)
mail = Mail(app)
mail.send(msg)
except Exception as e:
app.logger.error(str(e))
def send_ramp_up_approval_request_email(sender, recipients, primary_investigator):
with app.app_context():
try:
msg = Message('Research Ramp-up Plan Approval Request',
sender=sender,
recipients=recipients)
template = env.get_template('ramp_up_approval_request.txt')
template_vars = {'primary_investigator': primary_investigator}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approval_request.html')
msg.html = template.render(template_vars)
mail = Mail(app)
mail.send(msg)
except Exception as e:
app.logger.error(str(e))
def send_ramp_up_approval_request_first_review_email(sender, recipients, primary_investigator, approver):
with app.app_context():
try:
msg = Message('Research Ramp-up Plan Approval Request',
sender=sender,
recipients=recipients)
template = env.get_template('ramp_up_approval_request_first_review.txt')
template_vars = {'primary_investigator': primary_investigator, 'approver': approver}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approval_request_first_review.html')
msg.html = template.render(template_vars)
mail = Mail(app)
mail.send(msg)
except Exception as e:
app.logger.error(str(e))
def send_ramp_up_approved_email(sender, recipients, approver_1, approver_2=None):
with app.app_context():
try:
msg = Message('Research Ramp-up Plan Approved',
sender=sender,
recipients=recipients)
template = env.get_template('ramp_up_approved.txt')
template_vars = {'approver_1': approver_1, 'approver_2': approver_2}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approved.html')
msg.html = template.render(template_vars)
mail = Mail(app)
mail.send(msg)
except Exception as e:
app.logger.error(str(e))
def send_ramp_up_denied_email(sender, recipients, approver):
with app.app_context():
try:
msg = Message('Research Ramp-up Plan Denied',
sender=sender,
recipients=recipients)
template = env.get_template('ramp_up_denied.txt')
template_vars = {'approver': approver}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_denied.html')
msg.html = template.render(template_vars)
mail = Mail(app)
mail.send(msg)
except Exception as e:
app.logger.error(str(e))

View File

@ -0,0 +1 @@
<p>A Research Ramp-up approval request from {{ primary_investigator }} is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).</p>

View File

@ -0,0 +1 @@
A Research Ramp-up approval request from {{ primary_investigator }} is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).

View File

@ -0,0 +1 @@
<p>A Research Ramp-up approval request from {{ primary_investigator }} has been approve by {{ approver }} and is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).</p>

View File

@ -0,0 +1 @@
A Research Ramp-up approval request from {{ primary_investigator }} has been approve by {{ approver }} and is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).

View File

@ -0,0 +1 @@
<p>Your Research Ramp-up Plan has been approved by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}</p>

View File

@ -0,0 +1 @@
Your Research Ramp-up Plan has been approved by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}

View File

@ -0,0 +1,5 @@
<p>Your Research Ramp-up Plan (RRP) has been submitted for review by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}. After completion of the review step you will receive email notification of its approval or if additional information and/or modifications are required, along with instructions on how to proceed. Return to the Research Ramp-up Plan application to proceed as instructed.</p>
<p>In the meantime, please make sure all required training has been completed and needed supplies secured. You will be asked to confirm that both of these requirements have been met before reopening the research space approved in your RRP.</p>
<p>Additionally, if there are any unknown Area Monitors for the spaces listed in your RRP, please contact your approvers to determine either who they are or how you can find out. Missing Area Monitors will need to be entered before proceeding as well.</p>

View File

@ -0,0 +1,5 @@
Your Research Ramp-up Plan (RRP) has been submitted for review by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}. After completion of the review step you will receive email notification of its approval or if additional information and/or modifications are required, along with instructions on how to proceed. Return to the Research Ramp-up Plan application to proceed as instructed.
In the meantime, please make sure all required training has been completed and needed supplies secured. You will be asked to confirm that both of these requirements have been met before reopening the research space approved in your RRP.
Additionally, if there are any unknown Area Monitors for the spaces listed in your RRP, please contact your approvers to determine either who they are or how you can find out. Missing Area Monitors will need to be entered before proceeding as well.

48
tests/test_mails.py Normal file
View File

@ -0,0 +1,48 @@
from tests.base_test import BaseTest
from crc.services.mails import (
send_ramp_up_submission_email,
send_ramp_up_approval_request_email,
send_ramp_up_approval_request_first_review_email,
send_ramp_up_approved_email,
send_ramp_up_denied_email
)
class TestMails(BaseTest):
def setUp(self):
self.sender = 'sender@sartography.com'
self.recipients = ['recipient@sartography.com']
self.primary_investigator = 'Dr. Bartlett'
self.approver_1 = 'Max Approver'
self.approver_2 = 'Close Reviewer'
def test_send_ramp_up_submission_email(self):
send_ramp_up_submission_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
send_ramp_up_submission_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
def test_send_ramp_up_approval_request_email(self):
send_ramp_up_approval_request_email(self.sender, self.recipients, self.primary_investigator)
self.assertTrue(True)
def test_send_ramp_up_approval_request_first_review_email(self):
send_ramp_up_approval_request_first_review_email(
self.sender, self.recipients, self.primary_investigator, self.approver_1
)
self.assertTrue(True)
def test_send_ramp_up_approved_email(self):
send_ramp_up_approved_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
send_ramp_up_approved_email(self.sender, self.recipients, self.approver_1, self.approver_2)
self.assertTrue(True)
def test_send_ramp_up_denied_email(self):
send_ramp_up_denied_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)