Skip to content

Commit

Permalink
feat: #1596 Implement email styling enhancements (#1608)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianliuwk1019 authored Oct 2, 2024
1 parent 9542953 commit 51b4cd3
Show file tree
Hide file tree
Showing 16 changed files with 471 additions and 298 deletions.
Binary file not shown.
14 changes: 11 additions & 3 deletions frontend/src/components/common/TermsAndConditions.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
<script lang="ts" setup>
import Dialog from 'primevue/dialog';
import { AppActlApiService } from '@/services/ApiServiceFactory';
import AuthService from '@/services/AuthService';
import {
isTermsVisible,
hideTerms,
isTermsCloseable,
isTermsVisible,
} from '@/store/TermsAndConditionsState';
import { AppActlApiService } from '@/services/ApiServiceFactory';
import { setRouteToastError } from '@/store/ToastState';
import Dialog from 'primevue/dialog';
/*
Note: about Terms and Conditions used in coding.
Ther current version of T&C file is : "2024-06-04-.FAM.terms.of.use.approved.by.WK.BB.pdf".
Contact Olga or Kajo for the latest copy. Right now its not being stored in central place.
If there is version update, developers need to be aware the changes needs to be on both
frontend and the backend (GC Notify email sending for delegated admin has T&C as a link)
*/
const acceptTermsAndConditions = async () => {
try {
Expand Down
10 changes: 10 additions & 0 deletions server/admin_management/api/app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ class EmailSendingStatus(str, Enum):
SENT_TO_EMAIL_SERVICE_FAILURE = "SENT_TO_EMAIL_SERVICE_FAILURE" # technical/validation failure during sending to external service.


# ------------------------------- Schema Constants ------------------------------- #
USER_NAME_MAX_LEN = 20
FIRST_NAME_MAX_LEN = 50
LAST_NAME_MAX_LEN = 50
ROLE_NAME_MAX_LEN = 100
CLIENT_NUMBER_MAX_LEN = 8
CLIENT_NAME_MAX_LEN = 60
APPLICATION_DESC_MAX_LEN = 200
CREATE_USER_MAX_LEN = 100

# ------- Error/Exception Code Constant -------

# Note, this is default error code but better use specific code category if possible.
Expand Down
81 changes: 70 additions & 11 deletions server/admin_management/api/app/integration/gc_notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import requests
from api.app.schemas import GCNotifyGrantDelegatedAdminEmailParam
from api.app.utils.utils import is_success_response
from api.config import config

from .integration_data import tc_file_attach_base64

LOGGER = logging.getLogger(__name__)

GC_NOTIFY_EMAIL_BASE_URL = "https://api.notification.canada.ca"
GC_NOTIFY_GRANT_DELEGATED_ADMIN_EMAIL_TEMPLATE_ID = "9abff613-e507-4562-aae0-008317dfe3b9"
GC_NOTIFY_GRANT_DELEGATED_ADMIN_EMAIL_TEMPLATE_ID = "4f36da24-7507-4813-8285-d66a254c1f88"
# Template id for granting application admin, we will use this later
GC_NOTIFY_GRANT_APP_ADMIN_EMAIL_TEMPLATE_ID = "230bca59-4906-40b2-8f2b-2f6186a98663"

Expand Down Expand Up @@ -36,27 +39,83 @@ def send_delegated_admin_granted_email(self, params: GCNotifyGrantDelegatedAdmin
"""
# GC Notify does not have sufficient conditional rendering, cannot send None to variable, and does not support
# 'variable' within coditional text. Easier to do this in code.
contact_message = (
f"Please contact your administrator {params.application_team_contact_email} if you have any questions."
if params.application_team_contact_email is not None
else "Please contact your administrator if you have any questions."
)
application_role_granted_text = self.__to_application_role_granted_text(params)
organization_list_text = self.__to_organization_list_text(params)
contact_message = self.__to_contact_message(params)
terms_conditions_comply_text = self.__to_terms_conditions_comply_text()

personalisation_params = {
"user_name": params.user_name,
"first_name": params.first_name,
"last_name": params.last_name,
"application_name": params.application_description,
"application_role_granted_text": application_role_granted_text,
"organization_list_text": organization_list_text,
"contact_message": contact_message,
"terms_conditions_comply_text": "" # empty will not be displayed by default, only BCEID user needs this.
}

if params.is_bceid_user == "yes":
"""
Note:
* About Terms and Conditions used in coding:
Ther current version of T&C file is : "2024-06-04-.FAM.terms.of.use.approved.by.WK.BB.pdf".
A copy is deposited under frontend's /public folder so it can be public accessible with a
url friendly file name "2024-06-04-fam-terms-conditions.pdf".
Contact Olga or Kajo for the latest copy.
If there is version update, developers need to be aware the changes needs to be on both
frontend and the backend (frontend has a component with word-by-word coded for T&C)
"""
# only include file as GC Notify attachment for T&C.
personalisation_params |= {
"terms_conditions_comply_text": terms_conditions_comply_text,
}

email_params = {
"email_address": params.send_to_email_address,
"template_id": GC_NOTIFY_GRANT_DELEGATED_ADMIN_EMAIL_TEMPLATE_ID,
"personalisation": {
**params.__dict__,
"contact_message": contact_message
},
"personalisation": personalisation_params
}
gc_notify_email_send_url = f"{self.email_base_url}/v2/notifications/email"

r = self.session.post(
gc_notify_email_send_url, timeout=self.TIMEOUT, json=email_params
)
r.raise_for_status() # There is a general error handler, see: requests_http_error_handler

if not is_success_response(r):
# Add a debug for python response object for easy debugging purpose. After raising python
# exception (raise_for_status()), the error message is not printed from the caller.
LOGGER.debug(f"Email sending error response: {r.__dict__}")
r.raise_for_status()

send_email_result = r.json()

LOGGER.debug(f"Send Email result: {send_email_result}")
return send_email_result

def __to_contact_message(self, params: GCNotifyGrantDelegatedAdminEmailParam):
return (
f"Please contact your administrator {params.application_team_contact_email} if you have any questions."
if params.application_team_contact_email is not None
else "Please contact your administrator if you have any questions."
)

def __to_application_role_granted_text(self, params: GCNotifyGrantDelegatedAdminEmailParam):
granted_app_role_no_org_txt = f"With this role you can grant a **{params.role_display_name}** for users."
granted_app_role_with_org_txt = f"With this role you can grant a **{params.role_display_name}** for users within the following organizations:"
return granted_app_role_no_org_txt if params.organization_list is None else granted_app_role_with_org_txt

def __to_organization_list_text(self, params: GCNotifyGrantDelegatedAdminEmailParam):
org_list = params.organization_list
if (org_list is None):
return ""

# below is formatted to: "* bold[client_name] (Client number: 111)[new line]* bold(client_name) (Client number: 222)"
org_formatted_list_str = "\n".join([f"* **{item.client_name}** (Client number: {item.forest_client_number})" for item in org_list])
return org_formatted_list_str

def __to_terms_conditions_comply_text(self):
frontend_url = config.get_env_var("ALLOW_ORIGIN") if config.is_on_aws() else "https://fam-dev.nrs.gov.bc.ca" # default to dev.
tc_filename = "2024-06-04-fam-terms-conditions.pdf"
txt = f"As a delegated admin, you are required to comply with our [terms and conditions]({frontend_url}/{tc_filename})."
return txt

Large diffs are not rendered by default.

Loading

0 comments on commit 51b4cd3

Please sign in to comment.