Skip to content
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
5 changes: 3 additions & 2 deletions auth-api/src/auth_api/services/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def resubmit_product_subscription(org_id, subscription_data: dict[str, Any], ski

Product._send_product_subscription_confirmation(
ProductNotificationInfo(
product_model=product_model, product_sub_model=existing_sub, is_confirmation=True
product_model=product_model, product_sub_model=existing_sub, is_confirmation=True, org_id=org_id
),
org.id,
)
Expand Down Expand Up @@ -257,7 +257,7 @@ def create_product_subscription(
)
Product._send_product_subscription_confirmation(
ProductNotificationInfo(
product_model=product_model, product_sub_model=product_subscription, is_confirmation=True
product_model=product_model, product_sub_model=product_subscription, is_confirmation=True, org_id=org.id
),
org.id,
)
Expand Down Expand Up @@ -573,6 +573,7 @@ def approve_reject_parent_subscription(
product_model=product_model,
product_sub_model=product_subscription,
is_reapproved=is_reapproved,
org_id=org_id
)
)
else:
Expand Down
18 changes: 10 additions & 8 deletions auth-api/src/auth_api/utils/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,19 @@ def get_product_notification_data(product_notification_info: ProductNotification
is_confirmation = product_notification_info.is_confirmation
subscription_status_code = product_notification_info.product_sub_model.status_code
remarks = product_notification_info.remarks

org_id = product_notification_info.org_id
if product_model.code not in DETAILED_MHR_NOTIFICATIONS:
org_id = product_notification_info.org_id
org_name = product_notification_info.org_name
return get_default_product_notification_data(product_model, recipient_emails, org_id, org_name)

if is_confirmation:
return get_mhr_qs_confirmation_data(product_model, recipient_emails)
return get_mhr_qs_confirmation_data(product_model, recipient_emails, org_id)

if is_reapproved or subscription_status_code == ProductSubscriptionStatus.ACTIVE.value:
return get_mhr_qs_approval_data(product_model, recipient_emails, is_reapproved)
return get_mhr_qs_approval_data(product_model, recipient_emails, org_id, is_reapproved)

if subscription_status_code == ProductSubscriptionStatus.REJECTED.value:
return get_mhr_qs_rejected_data(product_model, recipient_emails, remarks)
return get_mhr_qs_rejected_data(product_model, recipient_emails, org_id, remarks)

return None

Expand All @@ -144,7 +143,7 @@ def get_default_product_notification_data(product_model: ProductCodeModel, recip
return data


def get_mhr_qs_approval_data(product_model: ProductCodeModel, recipient_emails: str, is_reapproved: bool = False):
def get_mhr_qs_approval_data(product_model: ProductCodeModel, recipient_emails: str, org_id: int, is_reapproved: bool = False):
"""Get the mhr qualified supplier product approval notification data."""
data = {
"subjectDescriptor": ProductSubjectDescriptor.MHR_QUALIFIED_SUPPLIER.value,
Expand All @@ -153,11 +152,12 @@ def get_mhr_qs_approval_data(product_model: ProductCodeModel, recipient_emails:
"isReapproved": is_reapproved,
"productName": product_model.description,
"emailAddresses": recipient_emails,
"accountId": org_id
}
return data


def get_mhr_qs_rejected_data(product_model: ProductCodeModel, recipient_emails: str, reject_reason: str = None):
def get_mhr_qs_rejected_data(product_model: ProductCodeModel, recipient_emails: str, org_id: int, reject_reason: str = None):
"""Get the mhr qualified supplier product rejected notification data."""
data = {
"subjectDescriptor": ProductSubjectDescriptor.MHR_QUALIFIED_SUPPLIER.value,
Expand All @@ -168,11 +168,12 @@ def get_mhr_qs_rejected_data(product_model: ProductCodeModel, recipient_emails:
"emailAddresses": recipient_emails,
"remarks": reject_reason,
"contactType": get_notification_contact_type(product_model.code),
"accountId": org_id
}
return data


def get_mhr_qs_confirmation_data(product_model: ProductCodeModel, recipient_emails: str):
def get_mhr_qs_confirmation_data(product_model: ProductCodeModel, recipient_emails: str, org_id: int):
"""Get the mhr qualified supplier product confirmation notification data."""
data = {
"subjectDescriptor": ProductSubjectDescriptor.MHR_QUALIFIED_SUPPLIER.value,
Expand All @@ -183,6 +184,7 @@ def get_mhr_qs_confirmation_data(product_model: ProductCodeModel, recipient_emai
"contactType": get_notification_contact_type(product_model.code),
"hasAgreementAttachment": True,
"attachmentType": NotificationAttachmentType.MHR_QS.value,
"accountId": org_id
}
return data

Expand Down
5 changes: 5 additions & 0 deletions auth-api/tests/unit/services/test_product_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ def test_detailed_approved_notification(mock_mailer, session, auth_mock, keycloa
"isReapproved": False,
"productName": product_code_model.description,
"emailAddresses": "test@test.com",
"accountId": dictionary["id"],
}
mock_mailer.assert_called_with(
QueueMessageTypes.PRODUCT_APPROVED_NOTIFICATION_DETAILED.value, data=expected_data
Expand Down Expand Up @@ -345,6 +346,7 @@ def test_detailed_rejected_notification(
"emailAddresses": "test@test.com",
"contactType": contact_type,
"remarks": task_dict["remarks"][0],
"accountId": dictionary["id"],
}
mock_mailer.assert_called_with(
QueueMessageTypes.PRODUCT_REJECTED_NOTIFICATION_DETAILED.value, data=expected_data
Expand Down Expand Up @@ -479,6 +481,7 @@ def test_confirmation_notification(
"contactType": contact_type,
"hasAgreementAttachment": True,
"attachmentType": NotificationAttachmentType.MHR_QS.value,
"accountId": dictionary["id"],
}

mock_mailer.assert_called_with(QueueMessageTypes.PRODUCT_CONFIRMATION_NOTIFICATION.value, data=expected_data)
Expand Down Expand Up @@ -606,6 +609,7 @@ def test_resubmission_notification(
"contactType": contact_type,
"hasAgreementAttachment": True,
"attachmentType": NotificationAttachmentType.MHR_QS.value,
"accountId": dictionary["id"],
}

# Assert that confirmation email is re-sent on re-submission
Expand Down Expand Up @@ -639,6 +643,7 @@ def test_resubmission_notification(
"isReapproved": True,
"productName": product_code_model.description,
"emailAddresses": "test@test.com",
"accountId": dictionary["id"],
}
mock_mailer.assert_called_with(
QueueMessageTypes.PRODUCT_APPROVED_NOTIFICATION_DETAILED.value, data=expected_data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from jinja2 import Template

from account_mailer.email_processors import generate_template
from account_mailer.email_processors.utils import get_account_info
from account_mailer.pdf_utils import get_pdf_from_report_api


Expand All @@ -42,10 +43,16 @@ def process(data: dict, token: str) -> dict:
}


def _get_account_unlock_email(email_msg):
filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), email_msg.get("template_name"))
def _get_account_unlock_email(data):
org_id = data.get("accountId")
_, account_name_with_branch = get_account_info(org_id)
filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), data.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"))
html_out = jnja_template.render(
logo_url=data.get("logo_url"),
account_name_with_branch=account_name_with_branch,
account_number=org_id,
)
return html_out


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,20 @@
# limitations under the License.
"""A Template for the account suspended email."""

# Local application imports
from auth_api.models import Org as OrgModel

# Third-party imports
from flask import current_app
from jinja2 import Template

from account_mailer.auth_utils import get_dashboard_url, get_login_url, get_payment_statements_url
from account_mailer.email_processors import generate_template
from account_mailer.email_processors.utils import get_account_info


def process(org_id, recipients, template_name, subject, logo_url, **kwargs) -> dict:
"""Build the email for Account notification."""
current_app.logger.debug("account notification: %s", org_id)

account_name: str = None
account_name_with_branch: str = None
if org_id:
org: OrgModel = OrgModel.find_by_id(org_id)
account_name = org.name
account_name_with_branch = org.name
if org.branch_name:
account_name_with_branch = f"{org.name} - {org.branch_name}"
current_app.logger.debug("account notification: %s", org_id)

account_name, account_name_with_branch = get_account_info(org_id)

# fill in template
filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), template_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@
from jinja2 import Template

from account_mailer.email_processors import generate_template
from account_mailer.email_processors.utils import get_account_info
from account_mailer.pdf_utils import get_pdf_from_report_api, get_pdf_from_storage


def process(email_msg: dict, token: str) -> dict:
def process(email_msg: dict, org_id: str, token: str) -> dict:
"""Build the email for PAD Confirmation notification."""
current_app.logger.debug("email_msg notification: %s", email_msg)
# fill in template

_, account_name_with_branch = get_account_info(org_id)
username = email_msg.get("padTosAcceptedBy")
pad_tos_file_name = current_app.config["PAD_TOS_FILE"]
admin_emails, admin_name = _get_admin_emails(username)
pdf_attachment = _get_pad_confirmation_report_pdf(email_msg, token)
tos_attachment = _get_pdf(pad_tos_file_name)
html_body = _get_pad_confirmation_email_body(email_msg, admin_name)
html_body = _get_pad_confirmation_email_body(email_msg, admin_name, account_name_with_branch, org_id)
return {
"recipients": admin_emails,
"content": {
Expand Down Expand Up @@ -73,11 +73,17 @@ def _get_admin_emails(username):
return admin_emails, admin_name


def _get_pad_confirmation_email_body(email_msg, admin_name):
def _get_pad_confirmation_email_body(email_msg, admin_name, account_name_with_branch, account_number):
filled_template = generate_template(current_app.config.get("TEMPLATE_PATH"), "pad_confirmation_email")
# render template with vars from email msg
jnja_template = Template(filled_template, autoescape=True)
html_out = jnja_template.render(request=email_msg, admin_name=admin_name, logo_url=email_msg.get("logo_url"))
html_out = jnja_template.render(
request=email_msg,
admin_name=admin_name,
logo_url=email_msg.get("logo_url"),
account_name_with_branch=account_name_with_branch,
account_number=account_number,
)
return html_out


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 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.
"""Utility functions for email processors."""

from auth_api.models import Org as OrgModel


def get_account_info(org_id: int | None) -> tuple[str | None, str | None]:
"""Get account name and account name with branch for an org."""
if not org_id:
return None, None
org = OrgModel.find_by_id(org_id)
account_name = org.name
account_name_with_branch = org.name
if org.branch_name:
account_name_with_branch = f"{org.name} - {org.branch_name}"
return account_name, account_name_with_branch

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})

We have received payment in the amount of ${{ paid_amount }}. Payment received over the outstanding balance has been applied as a credit to your account and will be applied to future purchases.
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})

We have received payment in the amount of ${{ paid_amount }} and your products are now available.
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image


We have received payment in the amount of ${{ paid_amount }}. Please pay the outstanding balance to access your products.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image


Please find attached your **Confirmation Letter of Pre-Authorized Debit (PAD) Sign-up** and a copy of your **Business Pre-Authorized Debit Terms and Conditions Agreement** with BC Registries and Online Services.

If you have questions, please contact the BC Online Partnership Office. Contact details are included in your confirmation letter.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image


When you setup pre-authorized debit, the bank information you entered was invalid.

To unlock your account, please review and update your bank information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})

# You've been approved for {{ product_access_descriptor }} access to {{ category_descriptor }}.

{% if is_reapproved %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})

# Your application for {{ product_access_descriptor }} access to {{ category_descriptor }} has been received.

BC Registries staff have received your application to have **{{ product_name }}** access to {{ category_descriptor }}, and your request is under review.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image


# Your Team Member Request is On hold.

Thank you for your interest with BC Registries and Online Services. Our office was attempting to approve your application sent on {{ applicationDate }} but, had to place your account creation request on hold for the following reason(s):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Account: {{ account_name_with_branch }} (Account Number: {{ account_number }})
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image


# Your Account Creation Request is On hold.

Thank you for your interest with BC Registries and Online Services. Our office was attempting to approve your application sent on {{ applicationDate }} but, had to place your account creation request on hold for the following reason(s):
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ class TemplateType(Enum):
NON_BCSC_ORG_REJECTED_NOTIFICATION_TEMPLATE_NAME = "nonbcsc_org_rejected_notification_email"
OTP_AUTHENTICATOR_RESET_NOTIFICATION_TEMPLATE_NAME = "otp_authenticator_reset_notification_email"
ROLE_CHANGED_NOTIFICATION_TEMPLATE_NAME = "role_changed_notification_email"
STAFF_REVIEW_ACCOUNT_TEMPLATE_NAME = "staff_review_account_email"
GOVM_APPROVED_NOTIFICATION_TEMPLATE_NAME = "govm_approved_notification"
GOVM_REJECTED_NOTIFICATION_TEMPLATE_NAME = "govm_rejected_notification"
PROD_PACKAGE_APPROVED_NOTIFICATION_TEMPLATE_NAME = "prod_package_approved_notification"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ def handle_pad_account_create(message_type, email_msg):
return
email_msg["registry_logo_url"] = google_store.GoogleStoreService.get_static_resource_url("bc_registry_logo_pdf.svg")
token = RestService.get_service_account_token()
email_dict = pad_confirmation.process(email_msg, token)
org_id = email_msg.get("accountId")
email_dict = pad_confirmation.process(email_msg, org_id, token)
process_email(email_dict, token)


Expand Down Expand Up @@ -397,7 +398,7 @@ def handle_product_actions(message_type, email_msg):
attachment_type = email_msg.get("attachmentType", None)
email_dict = common_mailer.process(
**{
"org_id": email_msg.get("orgId", None),
"org_id": email_msg.get("accountId"),
"recipients": email_msg.get("emailAddresses"),
"template_name": TemplateType[f"{QueueMessageTypes(message_type).name}_TEMPLATE_NAME"].value,
"subject": subject_type.format(subject_descriptor=subject_descriptor),
Expand Down