From fbf89d48762b2f318454e16c49e32d236714c93f Mon Sep 17 00:00:00 2001 From: kououken Date: Thu, 21 Feb 2019 16:18:39 -0800 Subject: [PATCH 1/6] Implemented email sending code. --- back/Pipfile | 1 + back/Pipfile.lock | 15 +++++-- back/backend/templates/backend/email.html | 21 +++++++++ back/backend/templates/backend/email.txt | 12 +++++ back/backend/views.py | 51 +++++++++++++++++++++- back/db.sqlite3 | Bin 105472 -> 197632 bytes back/reimbursinator/settings.py | 11 +++-- 7 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 back/backend/templates/backend/email.html create mode 100644 back/backend/templates/backend/email.txt diff --git a/back/Pipfile b/back/Pipfile index c985465..5ad300d 100644 --- a/back/Pipfile +++ b/back/Pipfile @@ -12,6 +12,7 @@ djangorestframework = "==3.8.2" django-rest-auth = "==0.9.3" django-allauth = "==0.37.1" gunicorn = "==19.6.0" +python-decouple = "==3.1" [requires] python_version = "3.5" diff --git a/back/Pipfile.lock b/back/Pipfile.lock index a6ed173..eb9c181 100644 --- a/back/Pipfile.lock +++ b/back/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "b1fc6b06ec8daa4efd9573865bc6c1732ae9354309e036bfe3ce0ab76b1a3bcd" + "sha256": "b8697c2d821e12f9f3e7bbad8a765782fc8a89df3f4260bc5f2b6f2e3d454510" }, "pipfile-spec": 6, "requires": { @@ -39,11 +39,11 @@ }, "django": { "hashes": [ - "sha256:a32c22af23634e1d11425574dce756098e015a165be02e4690179889b207c7a8", - "sha256:d6393918da830530a9516bbbcbf7f1214c3d733738779f06b0f649f49cc698c3" + "sha256:275bec66fd2588dd517ada59b8bfb23d4a9abc5a362349139ddda3c7ff6f5ade", + "sha256:939652e9d34d7d53d74d5d8ef82a19e5f8bb2de75618f7e5360691b6e9667963" ], "index": "pypi", - "version": "==2.1.5" + "version": "==2.1.7" }, "django-allauth": { "hashes": [ @@ -97,6 +97,13 @@ ], "version": "==3.0.1" }, + "python-decouple": { + "hashes": [ + "sha256:1317df14b43efee4337a4aa02914bf004f010cd56d6c4bd894e6474ec8c4fe2d" + ], + "index": "pypi", + "version": "==3.1" + }, "python3-openid": { "hashes": [ "sha256:0086da6b6ef3161cfe50fb1ee5cceaf2cda1700019fda03c2c5c440ca6abe4fa", diff --git a/back/backend/templates/backend/email.html b/back/backend/templates/backend/email.html new file mode 100644 index 0000000..cf7deb1 --- /dev/null +++ b/back/backend/templates/backend/email.html @@ -0,0 +1,21 @@ + + + + + +

Title: {{ title }}

+ {% for section in sections %} + {% if section.completed %} +

{{section.title}}

+ + {% for field in section.fields %} + + + + + {% endfor %} +
{{field.label}}{{field.value|default:""}}
+ {% endif %} + {% endfor %} + + diff --git a/back/backend/templates/backend/email.txt b/back/backend/templates/backend/email.txt new file mode 100644 index 0000000..64d4e13 --- /dev/null +++ b/back/backend/templates/backend/email.txt @@ -0,0 +1,12 @@ +***Deprecated: + Replaced by converting html template to plaintext + using the html2text library +*** + +Title: {{title}} +{% for section in sections %} + {{section.title}} + {% for field in section.fields %} + {{field.label}}: {{field.value|default:"empty"}} + {% endfor %} +{% endfor %} diff --git a/back/backend/views.py b/back/backend/views.py index bd4a9ec..eb18992 100644 --- a/back/backend/views.py +++ b/back/backend/views.py @@ -5,6 +5,9 @@ from .policy import pol import os from rest_framework.exceptions import ParseError from rest_framework.parsers import FileUploadParser, MultiPartParser +from django.core.mail import EmailMultiAlternatives +from django.template.loader import render_to_string +from decouple import config def get_report(report_pk): """ @@ -204,8 +207,8 @@ def report_detail(request, report_pk): return JsonResponse({"message": "Cannot submit a report that has already been submitted."}, status=409) rep.submitted = True; rep.save() - # Send email here - ################# + # Send email + send_report_to_admin(request, report_pk) return JsonResponse({"message": "Report submitted."}) # DELETE: Deletes a report from the user's account. @@ -370,3 +373,47 @@ def section_complete(section_pk): if i.completed: return True return False + +def send_report_to_admin(request, report_pk): + """ + Sends an email message to admin with html/txt version of report, + along with file attachments. Cc sent to user. + + request -- Request object with user info inside + report_pk -- ID of the report to submit + """ + params = get_report(report_pk) + subject = 'Report: {}'.format(params['title']), + to_email = config('SUBMIT_REPORT_DESTINATION_EMAIL') + from_email = config('SUBMIT_REPORT_FROM_EMAIL') + cc = request.user.email + msg_html = render_to_string('backend/email.html', params) + msg_plain = render_to_string('backend/email.txt', params) + message = EmailMultiAlternatives( + subject, + msg_plain, + from_email, + [to_email], + cc=[request.user.email], + ) + message.attach_alternative(msg_html, "text/html") + for f in get_files(report_pk): + message.attach_file(f) + message.send() + +def get_files(report_pk): + """ + collects all the files in a particular report and returns them + in an array. + + report_pk -- ID of the report to collect files for + """ + sections = Section.objects.filter(report_id=report_pk) + files = [] + for section in sections: + fields = Field.objects.filter(section_id=section.id, completed=True) + for field in fields: + if field.field_type == "file": + print("appending {}".format(field.data_file.name)) + files.append(field.data_file.name) + return files diff --git a/back/db.sqlite3 b/back/db.sqlite3 index b0936b92192c4608e786589b5bcca9f75278d50c..63e34f6e142b4ff799e17967459f21cfe40f98d2 100644 GIT binary patch literal 197632 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 MnJ+Z+ys^0WzdJ<^J^%m! diff --git a/back/reimbursinator/settings.py b/back/reimbursinator/settings.py index c306f32..5b074f3 100644 --- a/back/reimbursinator/settings.py +++ b/back/reimbursinator/settings.py @@ -11,12 +11,11 @@ https://docs.djangoproject.com/en/2.1/ref/settings/ """ import os -#from reimbursinator.custom_auth import BearerAuthentication +from decouple import config # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ @@ -28,7 +27,6 @@ DEBUG = True ALLOWED_HOSTS = ['localhost','192.168.99.100', '127.0.0.1'] - # Application definition INSTALLED_APPS = [ @@ -157,7 +155,12 @@ STATIC_URL = 'https://192.168.99.100:8445/' # Email Config -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_USE_TLS = True +EMAIL_HOST = 'smtp.gmail.com' +EMAIL_HOST_USER = config('EMAIL_HOST_USER') +EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD') +EMAIL_PORT = 587 SITE_ID = 1 From d876852e7ebaad6d89bc7428ffcf0f1810e45559 Mon Sep 17 00:00:00 2001 From: kououken Date: Thu, 21 Feb 2019 16:43:39 -0800 Subject: [PATCH 2/6] Added rule violations to emails. --- back/backend/templates/backend/email.html | 5 +++++ back/backend/templates/backend/email.txt | 3 +++ back/db.sqlite3 | Bin 197632 -> 197632 bytes 3 files changed, 8 insertions(+) diff --git a/back/backend/templates/backend/email.html b/back/backend/templates/backend/email.html index cf7deb1..b985302 100644 --- a/back/backend/templates/backend/email.html +++ b/back/backend/templates/backend/email.html @@ -14,6 +14,11 @@ {{field.value|default:""}} {% endfor %} + {% for rule in section.rule_violations %} + + {{rule.label}}
{{rule.rule_break_text}} + + {% endfor %} {% endif %} {% endfor %} diff --git a/back/backend/templates/backend/email.txt b/back/backend/templates/backend/email.txt index 64d4e13..43f9df7 100644 --- a/back/backend/templates/backend/email.txt +++ b/back/backend/templates/backend/email.txt @@ -9,4 +9,7 @@ Title: {{title}} {% for field in section.fields %} {{field.label}}: {{field.value|default:"empty"}} {% endfor %} + {% for rule in section.rule_violations %} + [RULE] {{rule.label}}: {{rule.rule_break_text}} + {% endfor %} {% endfor %} diff --git a/back/db.sqlite3 b/back/db.sqlite3 index 63e34f6e142b4ff799e17967459f21cfe40f98d2..e1d41596d7922b7a3494ee4a62a36f8929456c47 100644 GIT binary patch delta 6045 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 Fe*oU4BVPaj From b23fcaa4a2ba760d9e8c7b6c5b754200b6fd581d Mon Sep 17 00:00:00 2001 From: kououken Date: Thu, 21 Feb 2019 19:41:26 -0800 Subject: [PATCH 3/6] Fixed bug in subject line formatting. --- back/backend/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/back/backend/views.py b/back/backend/views.py index eb18992..e855f78 100644 --- a/back/backend/views.py +++ b/back/backend/views.py @@ -383,14 +383,13 @@ def send_report_to_admin(request, report_pk): report_pk -- ID of the report to submit """ params = get_report(report_pk) - subject = 'Report: {}'.format(params['title']), to_email = config('SUBMIT_REPORT_DESTINATION_EMAIL') from_email = config('SUBMIT_REPORT_FROM_EMAIL') cc = request.user.email msg_html = render_to_string('backend/email.html', params) msg_plain = render_to_string('backend/email.txt', params) message = EmailMultiAlternatives( - subject, + "Reimbursinator - {}".format(params['title']), msg_plain, from_email, [to_email], From b28a73d97fe0220e56d29dfd9947eb57af074b05 Mon Sep 17 00:00:00 2001 From: Daniel Dupriest Date: Fri, 22 Feb 2019 12:42:54 -0800 Subject: [PATCH 4/6] Create placeholder config file for server settings --- back/.env | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 back/.env diff --git a/back/.env b/back/.env new file mode 100644 index 0000000..b47f7a4 --- /dev/null +++ b/back/.env @@ -0,0 +1,4 @@ +EMAIL_HOST_USER=accountemail@yourmail.com +EMAIL_HOST_PASSWORD=accountpasswordhere +SUBMIT_REPORT_DESTINATION_EMAIL=to-address@yourmail.com +SUBMIT_REPORT_FROM_EMAIL=from-address@yourmail.com From b19cd21b411fdb2001a06376f281f50c83faf760 Mon Sep 17 00:00:00 2001 From: kououken Date: Fri, 22 Feb 2019 19:22:32 -0800 Subject: [PATCH 5/6] Repaired all the broken field references. --- back/backend/policy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/back/backend/policy.py b/back/backend/policy.py index 6366018..01566e0 100644 --- a/back/backend/policy.py +++ b/back/backend/policy.py @@ -114,8 +114,8 @@ def fare_limit_rule(report, fields): planning_section.add_rule(title="Fare limits", rule=fare_limit_rule) def lowest_fare_rule(report, fields): - diff = field['lowest_fare_duration'] - field['preferred_flight_duration'] - lowest_Fare = field['lowest_fare'] + diff = fields['lowest_fare_duration'] - fields['preferred_flight_duration'] + lowest_Fare = fields['lowest_fare'] maximum = 0 if diff <= 0: maximum = lowest_fare + 100 @@ -127,14 +127,14 @@ def lowest_fare_rule(report, fields): maximum = lowest_fare + 350 else: maximum = lowest_fare + 600 - if field['preferred_fare'] > maximum: + if fields['preferred_fare'] > maximum: return "For the lowest fare you have provided, your maximum in-policy fare amount is {} USD.".format(maximum) return None planning_section.add_rule(title="Lowest fare check", rule=lowest_fare_rule) def departure_date_limit_rule(report, fields): - days_to_departure = date(field['departure_date']) - date(field['screenshot_date']) + days_to_departure = date(fields['departure_date']) - date(fields['screenshot_date']) if days_to_departure < 14: return "Flights must be booked at least 14 days in advance." if days_to_departure > 365: @@ -174,7 +174,7 @@ flight_section.add_rule(title="Fare limits", rule=actual_fare_limit_rule) def request_date_rule(report, fields): now = date.today() - last_travel = date(field['return_date']) + last_travel = date(fields['return_date']) if now - last_travel > 90: return "Reimbursement requests must be made within 90 days of the last day of travel." return None From 1c8eb17e857caf6fb60c78bfda52912d5e8188b9 Mon Sep 17 00:00:00 2001 From: kououken Date: Sat, 23 Feb 2019 12:59:27 -0800 Subject: [PATCH 6/6] Fixed 'lowest_fare' rule bug. --- back/backend/policy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/backend/policy.py b/back/backend/policy.py index 01566e0..41f8b73 100644 --- a/back/backend/policy.py +++ b/back/backend/policy.py @@ -115,7 +115,7 @@ planning_section.add_rule(title="Fare limits", rule=fare_limit_rule) def lowest_fare_rule(report, fields): diff = fields['lowest_fare_duration'] - fields['preferred_flight_duration'] - lowest_Fare = fields['lowest_fare'] + lowest_fare = fields['lowest_fare'] maximum = 0 if diff <= 0: maximum = lowest_fare + 100