From d852ecb678c872b80dd3779d6e366fc75ce535ac Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Mon, 6 Nov 2023 05:37:16 -0800 Subject: [PATCH 01/17] Adding account_restored_nsf email processor --- .../email_processors/account_restored_nsf.py | 95 +++++++++++++++++++ .../account_restored_email.html | 14 +-- .../src/account_mailer/enums.py | 2 +- .../src/account_mailer/version.py | 2 +- .../src/account_mailer/worker.py | 20 +++- 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py new file mode 100644 index 0000000000..3dc4a8f59a --- /dev/null +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -0,0 +1,95 @@ +# Copyright © 2019 Province of British Columbia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""A Template for the Account Restored NSF Email.""" + +import base64 +import datetime + +from auth_api.models import User as UserModel +from auth_api.services.org import Org as OrgService +from auth_api.services.rest_service import RestService +from auth_api.utils.enums import AuthHeaderType, ContentType +from entity_queue_common.service_utils import logger +from flask import current_app +from jinja2 import Template + +from account_mailer.email_processors import generate_template +from account_mailer.services import minio_service + +def process(email_msg: dict, token: str) -> dict: + """Build the email for Account Restored NSF notification.""" + logger.debug('email_msg notification: %s', email_msg) + pdf_attachment = _get_account_restored_nsf_pdf(email_msg, token) + html_body = _get_account_restored_nsf_email(email_msg) + return { + 'recipients': email_msg.get('admin_coordinator_emails'), + 'content': { + 'subject': email_msg.get('subject'), + 'body': f'{html_body}', + 'attachments': [ + { + 'fileName': 'NSF_Fee_Receipt.pdf', + 'fileBytes': pdf_attachment.decode('utf-8'), + 'fileUrl': '', + 'attachOrder': '1' + } + ] + } + } + +def _get_account_restored_nsf_email(email_msg): + filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), email_msg.get('template_name')) + jnja_template = Template(filled_template, autoescape=True) + html_out = jnja_template.render( + account_name=email_msg.get('account_name'), + logo_url=email_msg.get('logo_url') + ) + return html_out + +def _get_account_restored_nsf_pdf(email_msg, token): + current_time = datetime.datetime.now() + template_vars = { + **email_msg, + 'corpName': email_msg.get('account_name'), + 'receiptNumber': email_msg.get('receipt_number'), + 'filingDate': current_time.strftime('%Y-%m-%d'), + 'effectiveDateTime': current_time.strftime('%Y-%m-%d %H:%M:%S'), + 'invoiceNumber': email_msg.get('invoice_number'), + 'paymentMethodDescription': email_msg.get('payment_method_description'), + 'filingIdentifier': email_msg.get('filing_identifier'), + 'invoice': email_msg.get('invoice'), + + } + + pdf_payload = { + 'reportName': 'NSF_Fee_Receipt', + 'templateVars': template_vars, + 'populatePageNumber': True, + 'templateName': 'payment_receipt', + } + + report_response = RestService.post(endpoint=current_app.config.get('REPORT_API_BASE_URL'), + token=token, + auth_header_type=AuthHeaderType.BEARER, + content_type=ContentType.JSON, + data=pdf_payload, + raise_for_status=True, + additional_headers={'Accept': 'application/pdf'}) + pdf_attachment = None + if report_response.status_code != 200: + logger.error('Failed to get pdf') + else: + pdf_attachment = base64.b64encode(report_response.content) + + return pdf_attachment \ No newline at end of file diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html b/queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html index 15e2f082f1..094e0132d4 100644 --- a/queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html +++ b/queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html @@ -1,9 +1,11 @@ -# Your BC Registries and Online Services account has been reactivated. +# Account Unlocked -The following account has been reactivated and is now accessible. +Your account **{{ account_name }}** has been unlocked. Team members can now log in and access this account. -{{ account_name }} +Your receipt is attached to this email: -Log in to BC Registries and Online Services to access your account. - -[Log in]({{ url }}) +**Business Registry** +BC Registries and Online Services +Toll Free: [1-877-370-1033](1-877-370-1033) +Victoria Office: [250-370-1033](250-370-1033) +Email: [BCRegistries@gov.bc.ca](BCRegistries@gov.bc.ca) diff --git a/queue_services/account-mailer/src/account_mailer/enums.py b/queue_services/account-mailer/src/account_mailer/enums.py index bd5aed7d0e..491f365221 100644 --- a/queue_services/account-mailer/src/account_mailer/enums.py +++ b/queue_services/account-mailer/src/account_mailer/enums.py @@ -70,7 +70,7 @@ class SubjectType(Enum): """Event Types.""" NSF_LOCK_ACCOUNT_SUBJECT = '[BC Registries and Online Services] Your account has been suspended' - NSF_UNLOCK_ACCOUNT_SUBJECT = '[BC Registries and Online Services] Your account has been reactivated' + NSF_UNLOCK_ACCOUNT_SUBJECT = 'Your Account Was Successfully Restored' ACCOUNT_CONF_OVER_SUBJECT = '[BC Registries and Online Services] Your account is now active' PAD_INVOICE_CREATED = '[BC Registries and Online Services] Your accounts PAD transaction details' ADMIN_REMOVED_SUBJECT = '[BC Registries and Online Services] You have been removed as an administrator' diff --git a/queue_services/account-mailer/src/account_mailer/version.py b/queue_services/account-mailer/src/account_mailer/version.py index e084225b3c..dc116fa97a 100644 --- a/queue_services/account-mailer/src/account_mailer/version.py +++ b/queue_services/account-mailer/src/account_mailer/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '2.18.3' # pylint: disable=invalid-name +__version__ = '2.18.4' # pylint: disable=invalid-name diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 80e08d8f0d..385079750a 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -41,7 +41,7 @@ from account_mailer import config from account_mailer.auth_utils import get_login_url, get_member_emails from account_mailer.email_processors import ( - common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, refund_requested) + account_restored_nsf, common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, refund_requested) from account_mailer.enums import Constants, MessageType, SubjectType, TemplateType, TitleType from account_mailer.services import minio_service, notification_service from account_mailer.utils import format_currency, format_day_with_suffix, get_local_formatted_date @@ -93,14 +93,26 @@ async def process_event(event_message: dict, flask_app): email_dict = common_mailer.process(org_id, admin_coordinator_emails, template_name, subject, logo_url=logo_url) elif message_type == MessageType.NSF_UNLOCK_ACCOUNT.value: - logger.debug('unlock account message recieved') + logger.debug('unlock account message received') template_name = TemplateType.NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME.value org_id = email_msg.get('accountId') admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') - email_dict = common_mailer.process(org_id, admin_coordinator_emails, - template_name, subject, logo_url=logo_url) + account_name = email_msg.get('toOrgName'), + + email_dict = common_mailer.process( + **{ + 'account_name': account_name, + 'logo_url': logo_url, + 'template_name': template_name, + 'subject': subject, + 'org_id': org_id, + 'admin_coordinator_emails': admin_coordinator_emails, + }) + + email_dict = account_restored_nsf.process(email_dict, token=token) + elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value org_id = email_msg.get('accountId') From 82a394e8c519212c7eac1c49bddac9baa9971f57 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Thu, 9 Nov 2023 08:02:38 -0800 Subject: [PATCH 02/17] Fixing typo --- .../src/account_mailer/email_processors/account_restored_nsf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index 3dc4a8f59a..bb961572e9 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -61,7 +61,7 @@ def _get_account_restored_nsf_pdf(email_msg, token): current_time = datetime.datetime.now() template_vars = { **email_msg, - 'corpName': email_msg.get('account_name'), + 'corpName': email_msg.get('accountName'), 'receiptNumber': email_msg.get('receipt_number'), 'filingDate': current_time.strftime('%Y-%m-%d'), 'effectiveDateTime': current_time.strftime('%Y-%m-%d %H:%M:%S'), From 8ab4e45e5eaf3350790b63355044852a25ed64b5 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Wed, 15 Nov 2023 08:34:58 -0800 Subject: [PATCH 03/17] Cleaning up linting --- .../account_mailer/email_processors/account_restored_nsf.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index bb961572e9..a8c9fb085d 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -16,8 +16,6 @@ import base64 import datetime -from auth_api.models import User as UserModel -from auth_api.services.org import Org as OrgService from auth_api.services.rest_service import RestService from auth_api.utils.enums import AuthHeaderType, ContentType from entity_queue_common.service_utils import logger @@ -25,7 +23,6 @@ from jinja2 import Template from account_mailer.email_processors import generate_template -from account_mailer.services import minio_service def process(email_msg: dict, token: str) -> dict: """Build the email for Account Restored NSF notification.""" @@ -92,4 +89,4 @@ def _get_account_restored_nsf_pdf(email_msg, token): else: pdf_attachment = base64.b64encode(report_response.content) - return pdf_attachment \ No newline at end of file + return pdf_attachment From ee3253dccf7601ae89398f62c8f44717ee10ec32 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Wed, 15 Nov 2023 08:39:53 -0800 Subject: [PATCH 04/17] Lint fixes --- queue_services/account-mailer/src/account_mailer/worker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 385079750a..4d6b63c7f7 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -99,7 +99,7 @@ async def process_event(event_message: dict, flask_app): admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') - account_name = email_msg.get('toOrgName'), + account_name = email_msg.get('toOrgName') email_dict = common_mailer.process( **{ @@ -112,7 +112,7 @@ async def process_event(event_message: dict, flask_app): }) email_dict = account_restored_nsf.process(email_dict, token=token) - + elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value org_id = email_msg.get('accountId') From b7f7fb8cead0d4d07506063a322fc9d106441a4b Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Wed, 15 Nov 2023 09:02:22 -0800 Subject: [PATCH 05/17] lint fixes --- .../account_mailer/email_processors/account_restored_nsf.py | 3 +-- queue_services/account-mailer/src/account_mailer/worker.py | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index a8c9fb085d..3f53c0b13b 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -16,14 +16,13 @@ import base64 import datetime +from account_mailer.email_processors import generate_template from auth_api.services.rest_service import RestService from auth_api.utils.enums import AuthHeaderType, ContentType from entity_queue_common.service_utils import logger from flask import current_app from jinja2 import Template -from account_mailer.email_processors import generate_template - def process(email_msg: dict, token: str) -> dict: """Build the email for Account Restored NSF notification.""" logger.debug('email_msg notification: %s', email_msg) diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 4d6b63c7f7..0123abb604 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -41,7 +41,8 @@ from account_mailer import config from account_mailer.auth_utils import get_login_url, get_member_emails from account_mailer.email_processors import ( - account_restored_nsf, common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, refund_requested) + account_restored_nsf, common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, + refund_requested) from account_mailer.enums import Constants, MessageType, SubjectType, TemplateType, TitleType from account_mailer.services import minio_service, notification_service from account_mailer.utils import format_currency, format_day_with_suffix, get_local_formatted_date From 556abba8cba938631e42efd7472244beffbd5376 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Wed, 15 Nov 2023 09:08:19 -0800 Subject: [PATCH 06/17] Import order --- .../src/account_mailer/email_processors/account_restored_nsf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index 3f53c0b13b..6214aec689 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -16,12 +16,12 @@ import base64 import datetime -from account_mailer.email_processors import generate_template from auth_api.services.rest_service import RestService from auth_api.utils.enums import AuthHeaderType, ContentType from entity_queue_common.service_utils import logger from flask import current_app from jinja2 import Template +from account_mailer.email_processors import generate_template def process(email_msg: dict, token: str) -> dict: """Build the email for Account Restored NSF notification.""" From d05d1fe74e105ead4ace07766b7febc63a72b44b Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Wed, 15 Nov 2023 09:29:26 -0800 Subject: [PATCH 07/17] Linting fixes --- .../account_mailer/email_processors/account_restored_nsf.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index 6214aec689..1876de5582 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -21,8 +21,10 @@ from entity_queue_common.service_utils import logger from flask import current_app from jinja2 import Template + from account_mailer.email_processors import generate_template + def process(email_msg: dict, token: str) -> dict: """Build the email for Account Restored NSF notification.""" logger.debug('email_msg notification: %s', email_msg) @@ -44,6 +46,7 @@ def process(email_msg: dict, token: str) -> dict: } } + def _get_account_restored_nsf_email(email_msg): filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), email_msg.get('template_name')) jnja_template = Template(filled_template, autoescape=True) @@ -53,6 +56,7 @@ def _get_account_restored_nsf_email(email_msg): ) return html_out + def _get_account_restored_nsf_pdf(email_msg, token): current_time = datetime.datetime.now() template_vars = { From 9092520fd5cfce64320af5b265cafb967bcb68bb Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Mon, 11 Dec 2023 00:21:10 -0800 Subject: [PATCH 08/17] Cleanup --- .../email_processors/account_restored_nsf.py | 16 ++++++++-------- .../account-mailer/src/account_mailer/worker.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py index 1876de5582..06d718fc3f 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py @@ -28,8 +28,8 @@ def process(email_msg: dict, token: str) -> dict: """Build the email for Account Restored NSF notification.""" logger.debug('email_msg notification: %s', email_msg) - pdf_attachment = _get_account_restored_nsf_pdf(email_msg, token) - html_body = _get_account_restored_nsf_email(email_msg) + pdf_attachment = _get_account_restored_pdf(email_msg, token) + html_body = _get_account_restored_email(email_msg) return { 'recipients': email_msg.get('admin_coordinator_emails'), 'content': { @@ -47,7 +47,7 @@ def process(email_msg: dict, token: str) -> dict: } -def _get_account_restored_nsf_email(email_msg): +def _get_account_restored_email(email_msg): filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), email_msg.get('template_name')) jnja_template = Template(filled_template, autoescape=True) html_out = jnja_template.render( @@ -57,18 +57,18 @@ def _get_account_restored_nsf_email(email_msg): return html_out -def _get_account_restored_nsf_pdf(email_msg, token): +def _get_account_restored_pdf(email_msg, token): current_time = datetime.datetime.now() template_vars = { **email_msg, - 'corpName': email_msg.get('accountName'), + 'corpName': email_msg.get('account_name'), 'receiptNumber': email_msg.get('receipt_number'), 'filingDate': current_time.strftime('%Y-%m-%d'), 'effectiveDateTime': current_time.strftime('%Y-%m-%d %H:%M:%S'), - 'invoiceNumber': email_msg.get('invoice_number'), - 'paymentMethodDescription': email_msg.get('payment_method_description'), 'filingIdentifier': email_msg.get('filing_identifier'), - 'invoice': email_msg.get('invoice'), + 'paymentMethodDescription': email_msg.get('payment_method_description'), # THIS TOO? + 'invoiceNumber': email_msg.get('invoice_number'), # NEED THIS + 'invoice': email_msg.get('invoice'), # THIS AS WELL? } diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index ade0bfcadc..171cb6b243 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -112,7 +112,7 @@ async def process_event(event_message: dict, flask_app): 'admin_coordinator_emails': admin_coordinator_emails, }) - email_dict = account_restored_nsf.process(email_dict, token=token) + email_dict = account_restored_nsf.process(email_msg=email_dict, token=token) elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value From 50adb698f7cdcc68f4d53ab3e3dd41a55068f939 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Mon, 11 Dec 2023 09:40:40 -0800 Subject: [PATCH 09/17] Cleanup --- ...ount_restored_nsf.py => account_unlock.py} | 15 ++++--- ...email.html => account_unlocked_email.html} | 0 .../src/account_mailer/worker.py | 40 +++++++++++++------ 3 files changed, 35 insertions(+), 20 deletions(-) rename queue_services/account-mailer/src/account_mailer/email_processors/{account_restored_nsf.py => account_unlock.py} (89%) rename queue_services/account-mailer/src/account_mailer/email_templates/{account_restored_email.html => account_unlocked_email.html} (100%) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py similarity index 89% rename from queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py rename to queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py index 06d718fc3f..5be984ce76 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_restored_nsf.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""A Template for the Account Restored NSF Email.""" +"""A Template for the Account Unlocked Email.""" import base64 import datetime @@ -26,10 +26,10 @@ def process(email_msg: dict, token: str) -> dict: - """Build the email for Account Restored NSF notification.""" + """Build the email for Account Unlocked notification.""" logger.debug('email_msg notification: %s', email_msg) - pdf_attachment = _get_account_restored_pdf(email_msg, token) - html_body = _get_account_restored_email(email_msg) + pdf_attachment = _get_account_unlock_pdf(email_msg, token) + html_body = _get_account_unlock_email(email_msg) return { 'recipients': email_msg.get('admin_coordinator_emails'), 'content': { @@ -37,7 +37,7 @@ def process(email_msg: dict, token: str) -> dict: 'body': f'{html_body}', 'attachments': [ { - 'fileName': 'NSF_Fee_Receipt.pdf', + 'fileName': 'Account_Unlock_Receipt.pdf', 'fileBytes': pdf_attachment.decode('utf-8'), 'fileUrl': '', 'attachOrder': '1' @@ -47,7 +47,7 @@ def process(email_msg: dict, token: str) -> dict: } -def _get_account_restored_email(email_msg): +def _get_account_unlock_email(email_msg): filled_template = generate_template(current_app.config.get('TEMPLATE_PATH'), email_msg.get('template_name')) jnja_template = Template(filled_template, autoescape=True) html_out = jnja_template.render( @@ -57,7 +57,7 @@ def _get_account_restored_email(email_msg): return html_out -def _get_account_restored_pdf(email_msg, token): +def _get_account_unlock_pdf(email_msg, token): current_time = datetime.datetime.now() template_vars = { **email_msg, @@ -69,7 +69,6 @@ def _get_account_restored_pdf(email_msg, token): 'paymentMethodDescription': email_msg.get('payment_method_description'), # THIS TOO? 'invoiceNumber': email_msg.get('invoice_number'), # NEED THIS 'invoice': email_msg.get('invoice'), # THIS AS WELL? - } pdf_payload = { diff --git a/queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html b/queue_services/account-mailer/src/account_mailer/email_templates/account_unlocked_email.html similarity index 100% rename from queue_services/account-mailer/src/account_mailer/email_templates/account_restored_email.html rename to queue_services/account-mailer/src/account_mailer/email_templates/account_unlocked_email.html diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 171cb6b243..2ddd909a5a 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -41,7 +41,7 @@ from account_mailer import config from account_mailer.auth_utils import get_login_url, get_member_emails from account_mailer.email_processors import ( - account_restored_nsf, common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, + account_unlock, common_mailer, ejv_failures, pad_confirmation, payment_completed, product_confirmation, refund_requested) from account_mailer.enums import Constants, MessageType, SubjectType, TemplateType, TitleType from account_mailer.services import minio_service, notification_service @@ -100,19 +100,35 @@ async def process_event(event_message: dict, flask_app): admin_coordinator_emails = get_member_emails(org_id, (ADMIN, COORDINATOR)) subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') - account_name = email_msg.get('toOrgName') - email_dict = common_mailer.process( - **{ - 'account_name': account_name, - 'logo_url': logo_url, - 'template_name': template_name, - 'subject': subject, - 'org_id': org_id, - 'admin_coordinator_emails': admin_coordinator_emails, - }) + + + # email_dict = common_mailer.process( + # **{ + # 'org_id': None, + # 'recipients': email_msg.get('emailAddresses'), + # 'template_name': TemplateType[f'{MessageType(message_type).name}_TEMPLATE_NAME'].value, + # 'subject': SubjectType[MessageType(message_type).name].value.format(business_name=business_name), + # 'logo_url': logo_url, + # 'business_name': business_name, + # 'requesting_account': requesting_account, + # 'account': account, + # 'is_authorized': email_msg.get('isAuthorized', None), + # 'additional_message': email_msg.get('additionalMessage', None) + # }) + + email_dict = { + 'account_name': email_msg.get('toOrgName'), + 'logo_url': logo_url, + 'template_name': template_name, + 'subject': subject, + 'org_id': org_id, + 'admin_coordinator_emails': admin_coordinator_emails, + 'filing_identifier': email_msg.get('filing_identifier'), + } + - email_dict = account_restored_nsf.process(email_msg=email_dict, token=token) + email_dict = account_unlock.process(email_msg=email_dict, token=token) elif message_type == MessageType.ACCOUNT_CONFIRMATION_PERIOD_OVER.value: template_name = TemplateType.ACCOUNT_CONF_OVER_TEMPLATE_NAME.value From 05015296490d99fabc5a3e52289c8271c4866f39 Mon Sep 17 00:00:00 2001 From: Rodrigo Barraza Date: Mon, 22 Jan 2024 08:10:12 -0800 Subject: [PATCH 10/17] Cleanup --- .../email_processors/account_unlock.py | 6 +++--- .../account-mailer/src/account_mailer/worker.py | 17 ----------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py index 5be984ce76..de878e3e9d 100644 --- a/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py +++ b/queue_services/account-mailer/src/account_mailer/email_processors/account_unlock.py @@ -66,9 +66,9 @@ def _get_account_unlock_pdf(email_msg, token): 'filingDate': current_time.strftime('%Y-%m-%d'), 'effectiveDateTime': current_time.strftime('%Y-%m-%d %H:%M:%S'), 'filingIdentifier': email_msg.get('filing_identifier'), - 'paymentMethodDescription': email_msg.get('payment_method_description'), # THIS TOO? - 'invoiceNumber': email_msg.get('invoice_number'), # NEED THIS - 'invoice': email_msg.get('invoice'), # THIS AS WELL? + 'paymentMethodDescription': email_msg.get('payment_method_description'), + 'invoiceNumber': email_msg.get('invoice_number'), + 'invoice': email_msg.get('invoice') } pdf_payload = { diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 2ddd909a5a..35099838c3 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -101,22 +101,6 @@ async def process_event(event_message: dict, flask_app): subject = SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value logo_url = email_msg.get('logo_url') - - - # email_dict = common_mailer.process( - # **{ - # 'org_id': None, - # 'recipients': email_msg.get('emailAddresses'), - # 'template_name': TemplateType[f'{MessageType(message_type).name}_TEMPLATE_NAME'].value, - # 'subject': SubjectType[MessageType(message_type).name].value.format(business_name=business_name), - # 'logo_url': logo_url, - # 'business_name': business_name, - # 'requesting_account': requesting_account, - # 'account': account, - # 'is_authorized': email_msg.get('isAuthorized', None), - # 'additional_message': email_msg.get('additionalMessage', None) - # }) - email_dict = { 'account_name': email_msg.get('toOrgName'), 'logo_url': logo_url, @@ -126,7 +110,6 @@ async def process_event(event_message: dict, flask_app): 'admin_coordinator_emails': admin_coordinator_emails, 'filing_identifier': email_msg.get('filing_identifier'), } - email_dict = account_unlock.process(email_msg=email_dict, token=token) From d00703de9515ab3f49301d0592c25fc0da615324 Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 14:26:00 -0800 Subject: [PATCH 11/17] change enum, add in mock for report-api --- .../src/account_mailer/enums.py | 2 +- .../tests/integration/test_worker_queue.py | 48 +++++++++++-------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/queue_services/account-mailer/src/account_mailer/enums.py b/queue_services/account-mailer/src/account_mailer/enums.py index 491f365221..e731a8c774 100644 --- a/queue_services/account-mailer/src/account_mailer/enums.py +++ b/queue_services/account-mailer/src/account_mailer/enums.py @@ -160,7 +160,7 @@ class TemplateType(Enum): """Template Types.""" NSF_LOCK_ACCOUNT_TEMPLATE_NAME = 'account_suspended_email' - NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME = 'account_restored_email' + NSF_UNLOCK_ACCOUNT_TEMPLATE_NAME = 'account_unlocked_email' ACCOUNT_CONF_OVER_TEMPLATE_NAME = 'account_conf_over_email' PAD_INVOICE_CREATED_TEMPLATE_NAME = 'pad_invoice_email' ADMIN_REMOVED_TEMPLATE_NAME = 'admin_removed_email' diff --git a/queue_services/account-mailer/tests/integration/test_worker_queue.py b/queue_services/account-mailer/tests/integration/test_worker_queue.py index 27fe06a748..fe554d6aca 100644 --- a/queue_services/account-mailer/tests/integration/test_worker_queue.py +++ b/queue_services/account-mailer/tests/integration/test_worker_queue.py @@ -12,10 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. """Test Suite to ensure the worker routines are working as expected.""" +import types from datetime import datetime from unittest.mock import patch import pytest +from auth_api.services.rest_service import RestService from entity_queue_common.service_utils import subscribe_to_queue from account_mailer.enums import MessageType, SubjectType @@ -157,28 +159,34 @@ async def test_unlock_account_mailer_queue(app, session, stan_server, event_loop events_subject = 'test_subject' events_queue = 'test_queue' events_durable_name = 'test_durable' + response = types.SimpleNamespace() + response.status_code = 200 + response.content = bytes('foo', 'utf-8') + # patch RestService.post with patch.object(notification_service, 'send_email', return_value=None) as mock_send: # register the handler to test it - await subscribe_to_queue(events_stan, - events_subject, - events_queue, - events_durable_name, - cb_subscription_handler) - - # add an event to queue - mail_details = { - 'accountId': id, - 'accountName': org.name - } - await helper_add_event_to_queue(events_stan, events_subject, org_id=id, - msg_type=MessageType.NSF_UNLOCK_ACCOUNT.value, mail_details=mail_details) - - mock_send.assert_called - assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' - assert mock_send.call_args.args[0].get('content').get('subject') == SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value - assert mock_send.call_args.args[0].get('attachments') is None - assert mock_send.call_args.args[0].get('content').get('body') is not None - assert True + with patch.object(RestService, 'post', return_value=response): + await subscribe_to_queue(events_stan, + events_subject, + events_queue, + events_durable_name, + cb_subscription_handler) + + # add an event to queue + mail_details = { + 'accountId': id, + 'accountName': org.name + } + await helper_add_event_to_queue(events_stan, events_subject, org_id=id, + msg_type=MessageType.NSF_UNLOCK_ACCOUNT.value, mail_details=mail_details) + + mock_send.assert_called + assert mock_send.call_args.args[0].get('recipients') == 'foo@bar.com' + assert mock_send.call_args.args[0].get('content').get('subject') == \ + SubjectType.NSF_UNLOCK_ACCOUNT_SUBJECT.value + assert mock_send.call_args.args[0].get('attachments') is None + assert mock_send.call_args.args[0].get('content').get('body') is not None + assert True @pytest.mark.asyncio From b7a590400ed22bd6791b27bcfaffe29cc82d1650 Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 14:31:45 -0800 Subject: [PATCH 12/17] add in additional logging --- queue_services/account-mailer/src/account_mailer/worker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/queue_services/account-mailer/src/account_mailer/worker.py b/queue_services/account-mailer/src/account_mailer/worker.py index 35099838c3..b198e47f63 100644 --- a/queue_services/account-mailer/src/account_mailer/worker.py +++ b/queue_services/account-mailer/src/account_mailer/worker.py @@ -366,6 +366,7 @@ async def cb_subscription_handler(msg: nats.aio.client.Msg): event_message = json.loads(msg.data.decode('utf-8')) logger.debug('Event Message Received: %s', event_message) await process_event(event_message, FLASK_APP) - except Exception: # NOQA # pylint: disable=broad-except + except Exception as e: # NOQA # pylint: disable=broad-except # Catch Exception so that any error is still caught and the message is removed from the queue logger.error('Queue Error: %s', json.dumps(event_message), exc_info=True) + logger.error(e) From fa8cabaf7ac0572fb3e78c334e5c70f61ed0be5c Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 14:33:16 -0800 Subject: [PATCH 13/17] More logging --- queue_services/account-mailer/logging.conf | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/queue_services/account-mailer/logging.conf b/queue_services/account-mailer/logging.conf index ffc1a01e36..ded5cb81c1 100644 --- a/queue_services/account-mailer/logging.conf +++ b/queue_services/account-mailer/logging.conf @@ -1,5 +1,5 @@ [loggers] -keys=root,api +keys=root,api,asyncio [handlers] keys=console @@ -11,6 +11,12 @@ keys=simple level=DEBUG handlers=console +[logger_asyncio] +level=DEBUG +handlers=console +qualname=asyncio +propagate=0 + [logger_api] level=DEBUG handlers=console @@ -25,4 +31,4 @@ args=(sys.stdout,) [formatter_simple] format=%(asctime)s - %(name)s - %(levelname)s in %(module)s:%(filename)s:%(lineno)d - %(funcName)s: %(message)s -datefmt= \ No newline at end of file +datefmt= From 08442eaaa7f444e89ba78f9c0af0fb4c17213a56 Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 14:56:10 -0800 Subject: [PATCH 14/17] Fix logging for unit tests --- queue_services/account-mailer/tests/conftest.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/queue_services/account-mailer/tests/conftest.py b/queue_services/account-mailer/tests/conftest.py index 5741230de7..fa8c9c8acc 100644 --- a/queue_services/account-mailer/tests/conftest.py +++ b/queue_services/account-mailer/tests/conftest.py @@ -13,8 +13,10 @@ # limitations under the License. """Common setup and fixtures for the pytest suite used by this service.""" import asyncio +import logging import os import random +import sys import time from contextlib import contextmanager @@ -28,6 +30,19 @@ from account_mailer.config import get_named_config +def setup_logging(conf): + """Create the services logger. + + TODO should be reworked to load in the proper loggers and remove others + """ + # log_file_path = path.join(path.abspath(path.dirname(__file__)), conf) + + if conf and os.path.isfile(conf): + logging.config.fileConfig(conf) + print(f'Configure logging, from conf:{conf}', file=sys.stdout) + else: + print(f'Unable to configure logging, attempted conf:{conf}', file=sys.stderr) + @contextmanager def not_raises(exception): @@ -85,6 +100,8 @@ def db(app): # pylint: disable=redefined-outer-name, invalid-name Migrate(app, _db, directory=migration_path) upgrade() + # Restore the logging, alembic and sqlalchemy have their own logging from alembic.ini. + setup_logging(os.path.abspath('logging.conf')) return _db From 50653f74bbfedc857e17930aa3f3f2e9ec2f4c34 Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 15:00:41 -0800 Subject: [PATCH 15/17] Linting fixes --- queue_services/account-mailer/tests/conftest.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/queue_services/account-mailer/tests/conftest.py b/queue_services/account-mailer/tests/conftest.py index fa8c9c8acc..face95514e 100644 --- a/queue_services/account-mailer/tests/conftest.py +++ b/queue_services/account-mailer/tests/conftest.py @@ -16,7 +16,6 @@ import logging import os import random -import sys import time from contextlib import contextmanager @@ -30,6 +29,7 @@ from account_mailer.config import get_named_config + def setup_logging(conf): """Create the services logger. @@ -39,9 +39,6 @@ def setup_logging(conf): if conf and os.path.isfile(conf): logging.config.fileConfig(conf) - print(f'Configure logging, from conf:{conf}', file=sys.stdout) - else: - print(f'Unable to configure logging, attempted conf:{conf}', file=sys.stderr) @contextmanager From 240258b9ff6657c04338b3fcb6e111161ef8e580 Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 15:17:38 -0800 Subject: [PATCH 16/17] Bypass service token --- queue_services/account-mailer/tests/conftest.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/queue_services/account-mailer/tests/conftest.py b/queue_services/account-mailer/tests/conftest.py index face95514e..f45e1dc2e2 100644 --- a/queue_services/account-mailer/tests/conftest.py +++ b/queue_services/account-mailer/tests/conftest.py @@ -18,9 +18,11 @@ import random import time from contextlib import contextmanager +from unittest import mock import pytest from auth_api import db as _db +from auth_api.services.rest_service import RestService from flask import Flask from flask_migrate import Migrate, upgrade from nats.aio.client import Client as Nats @@ -30,6 +32,11 @@ from account_mailer.config import get_named_config + +def mock_token(config_id='', config_secret=''): + """Mock token generator.""" + return 'TOKEN....' + def setup_logging(conf): """Create the services logger. @@ -60,6 +67,10 @@ def app(): _app = Flask(__name__) _app.config.from_object(get_named_config('testing')) _db.init_app(_app) + # Bypass caching. + def get_service_token(): + pass + RestService.get_service_account_token = get_service_token return _app From 5a7c84cd4bf1947070bf67df3fdbb115032aa07b Mon Sep 17 00:00:00 2001 From: Travis Semple Date: Mon, 22 Jan 2024 15:19:57 -0800 Subject: [PATCH 17/17] Fix linting --- queue_services/account-mailer/tests/conftest.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/queue_services/account-mailer/tests/conftest.py b/queue_services/account-mailer/tests/conftest.py index f45e1dc2e2..de5ac74a1c 100644 --- a/queue_services/account-mailer/tests/conftest.py +++ b/queue_services/account-mailer/tests/conftest.py @@ -18,7 +18,6 @@ import random import time from contextlib import contextmanager -from unittest import mock import pytest from auth_api import db as _db @@ -32,18 +31,11 @@ from account_mailer.config import get_named_config - -def mock_token(config_id='', config_secret=''): - """Mock token generator.""" - return 'TOKEN....' - def setup_logging(conf): """Create the services logger. TODO should be reworked to load in the proper loggers and remove others """ - # log_file_path = path.join(path.abspath(path.dirname(__file__)), conf) - if conf and os.path.isfile(conf): logging.config.fileConfig(conf) @@ -68,6 +60,7 @@ def app(): _app.config.from_object(get_named_config('testing')) _db.init_app(_app) # Bypass caching. + def get_service_token(): pass RestService.get_service_account_token = get_service_token