diff --git a/backend/api/serializers.py b/backend/api/serializers.py index 80587f0..e72db58 100644 --- a/backend/api/serializers.py +++ b/backend/api/serializers.py @@ -1,4 +1,4 @@ -from rest_framework.serializers import Serializer, CharField, EmailField, URLField +from rest_framework.serializers import Serializer, CharField, EmailField, URLField, BooleanField class RequestMedicalRecordsSerializer(Serializer): name=CharField() @@ -18,6 +18,7 @@ class ApplyForPatientAssistanceSerializer(Serializer): first_name=CharField() last_name=CharField() email=EmailField() + useWithoutExtension=BooleanField() return_url=URLField( max_length=200, min_length=None, allow_blank=False ) diff --git a/backend/api/urls.py b/backend/api/urls.py index 4cfd2be..f6e8c8e 100644 --- a/backend/api/urls.py +++ b/backend/api/urls.py @@ -5,4 +5,5 @@ path('request-medical-records', views.request_medical_records), path('covid19-consent-form', views.covid19_consent_form), path('apply-for-patient-assistance', views.apply_for_patient_assistance), + path('extensions', views.get_extension_apps), ] diff --git a/backend/api/views.py b/backend/api/views.py index 24f4e01..86de6e4 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -5,6 +5,7 @@ from docusign.template import Template from docusign.envelope import Envelope from docusign.workflow import get_idv_workflow, is_sms_workflow +from docusign.extensions import Extensions from .serializers import ( RequestMedicalRecordsSerializer, @@ -72,19 +73,51 @@ def apply_for_patient_assistance(request): """ The Apply for Patient Assistance flow """ - serializer = ApplyForPatientAssistanceSerializer(data=request.data) - serializer.is_valid(raise_exception=True) + try: + serializer = ApplyForPatientAssistanceSerializer(data=request.data) + serializer.is_valid(raise_exception=True) - args = serializer.validated_data.copy() + args = serializer.validated_data.copy() - template_request = Template.make_application_for_participation(args) - template_id = Template.create(request.session, template_request) + template_request = Template.make_application_for_participation(args, request.session) + template_id = Template.create(request.session, template_request) - args["template_id"] = template_id + args["template_id"] = template_id - envelope_definition = Envelope.create_application_for_participation_definition(args) + envelope_definition = Envelope.create_application_for_participation_definition(args) - envelope_id = Envelope.send(request.session, envelope_definition) - view_url = Envelope.get_view_url(request.session, envelope_id, args) + envelope_id = Envelope.send(request.session, envelope_definition) + view_url = Envelope.get_view_url(request.session, envelope_id, args) - return Response({"view_url": view_url, "client_id": os.environ.get('CLIENT_ID')}) + return Response({"view_url": view_url, "client_id": os.environ.get('CLIENT_ID')}) + except Exception as err: + print(err) + +@api_view(['GET']) +@error_processing +def get_extension_apps(request): + """ + Retrieve the list of extensions + """ + try: + extensions = Extensions.get_extension_apps(request.session) + actual_extension_app_ids = [item["appId"] for item in extensions] + + required_ids = { + Extensions.get_address_extension_id(), + Extensions.get_phone_extension_id(), + Extensions.get_ssn_extension_id(), + } + + # Check missing apps one by one + missing_app_ids = [app_id for app_id in required_ids if app_id not in actual_extension_app_ids] + for app_id in missing_app_ids: + result = Extensions.get_extension_app(request.session, app_id) + if result and len(result) > 0 and not "code" in result: + actual_extension_app_ids.append(result[0]["appId"]) + + has_all_app_ids = all(app_id in actual_extension_app_ids for app_id in required_ids) + + return Response({"areExtensionsPresent": has_all_app_ids}) + except Exception as err: + print(err) diff --git a/backend/auth/views.py b/backend/auth/views.py index f2e8c3e..425c477 100644 --- a/backend/auth/views.py +++ b/backend/auth/views.py @@ -70,8 +70,11 @@ def jwt_auth(request): """ Endpoint of user authorization using JWT """ - auth_data = DsClient.jwt_auth() + try: + auth_data = DsClient.jwt_auth() - SessionData.set_auth_data(request.session, auth_data) + SessionData.set_auth_data(request.session, auth_data) - return Response({"message": "Logged in with JWT"}) + return Response({"message": "Logged in with JWT"}) + except Exception as err: + print(err.body) diff --git a/backend/docusign/ds_config.py b/backend/docusign/ds_config.py index 1dcf6d9..43998e4 100644 --- a/backend/docusign/ds_config.py +++ b/backend/docusign/ds_config.py @@ -6,8 +6,13 @@ TOKEN_EXPIRATION_IN_SECONDS = 3600 TOKEN_REPLACEMENT_IN_SECONDS = 10 * 60 -CODE_GRANT_SCOPES = ['signature', 'click.manage'] -PERMISSION_SCOPES = ['signature', 'impersonation', 'click.manage'] +CODE_GRANT_SCOPES = ['signature', 'click.manage', 'adm_store_unified_repo_read'] +PERMISSION_SCOPES = ['signature', 'impersonation', 'click.manage', 'adm_store_unified_repo_read'] + +CONNECTED_FIELDS_BASE_HOST = 'https://api-d.docusign.com' +PHONE_EXTENSION_ID = "d16f398f-8b9a-4f94-b37c-af6f9c910c04" +SMARTY_EXTENSION_ID = "04bfc1ae-1ba0-42d0-8c02-264417a7b234" +SSN_EXTENSION_ID = "b1adf7ad-38fd-44ba-85f5-38ea87f4af23" DS_RETURN_URL = os.environ.get('REACT_APP_DS_RETURN_URL') DS_AUTH_SERVER = os.environ.get('DS_AUTH_SERVER') diff --git a/backend/docusign/extensions.py b/backend/docusign/extensions.py new file mode 100644 index 0000000..55fefc4 --- /dev/null +++ b/backend/docusign/extensions.py @@ -0,0 +1,94 @@ +import requests +from docusign.ds_config import SMARTY_EXTENSION_ID, PHONE_EXTENSION_ID, SSN_EXTENSION_ID, CONNECTED_FIELDS_BASE_HOST + +class Extensions: + @staticmethod + def get_extension_apps(session): + headers = { + "Authorization": "Bearer " + session['access_token'], + "Accept": "application/json", + "Content-Type": "application/json" + } + + url = f"{CONNECTED_FIELDS_BASE_HOST}/v1/accounts/{session['account_id']}/connected-fields/tab-groups" + response = requests.get(url, headers=headers) + + return response.json() + + def get_extension_app(session, appId): + headers = { + "Authorization": "Bearer " + session['access_token'], + "Accept": "application/json", + "Content-Type": "application/json" + } + + url = f"{CONNECTED_FIELDS_BASE_HOST}/v1/accounts/{session['account_id']}/connected-fields/tab-groups?appId={appId}" + response = requests.get(url, headers=headers) + + return response.json() + + @staticmethod + def get_address_extension_id(): + return SMARTY_EXTENSION_ID + + @staticmethod + def get_phone_extension_id(): + return PHONE_EXTENSION_ID + + @staticmethod + def get_ssn_extension_id(): + return SSN_EXTENSION_ID + + @staticmethod + def get_extension_by_app_id(objects, app_id): + return next((obj for obj in objects if obj["appId"] == app_id), None) + + @staticmethod + def extract_verification_data(selected_app_id, tab): + extension_data = tab["extensionData"] + + return { + "app_id": selected_app_id, + "extension_group_id": extension_data["extensionGroupId"] if "extensionGroupId" in extension_data else "", + "publisher_name": extension_data["publisherName"] if "publisherName" in extension_data else "", + "application_name": extension_data["applicationName"] if "applicationName" in extension_data else "", + "action_name": extension_data["actionName"] if "actionName" in extension_data else "", + "action_input_key": extension_data["actionInputKey"] if "actionInputKey" in extension_data else "", + "action_contract": extension_data["actionContract"] if "actionContract" in extension_data else "", + "extension_name": extension_data["extensionName"] if "extensionName" in extension_data else "", + "extension_contract": extension_data["extensionContract"] if "extensionContract" in extension_data else "", + "required_for_extension": extension_data["requiredForExtension"] if "requiredForExtension" in extension_data else "", + "tab_label": tab["tabLabel"], + "connection_key": ( + extension_data["connectionInstances"][0]["connectionKey"] + if "connectionInstances" in extension_data and extension_data["connectionInstances"] + else "" + ), + "connection_value": ( + extension_data["connectionInstances"][0]["connectionValue"] + if "connectionInstances" in extension_data and extension_data["connectionInstances"] + else "" + ) + } + + @staticmethod + def get_extension_data(verification_data): + return { + "extensionGroupId": verification_data["extension_group_id"], + "publisherName": verification_data["publisher_name"], + "applicationId": verification_data["app_id"], + "applicationName": verification_data["application_name"], + "actionName": verification_data["action_name"], + "actionContract": verification_data["action_contract"], + "extensionName": verification_data["extension_name"], + "extensionContract": verification_data["extension_contract"], + "requiredForExtension": verification_data["required_for_extension"], + "actionInputKey": verification_data["action_input_key"], + "extensionPolicy": 'MustVerifyToSign', + "connectionInstances": [ + { + "connectionKey": verification_data["connection_key"], + "connectionValue": verification_data["connection_value"], + } + ] + } \ No newline at end of file diff --git a/backend/docusign/pdf/Application_for_participation_v2.pdf b/backend/docusign/pdf/Application_for_participation_v2.pdf index d62f0f9..db08a0a 100644 Binary files a/backend/docusign/pdf/Application_for_participation_v2.pdf and b/backend/docusign/pdf/Application_for_participation_v2.pdf differ diff --git a/backend/docusign/template.py b/backend/docusign/template.py index 7be7493..df0b929 100644 --- a/backend/docusign/template.py +++ b/backend/docusign/template.py @@ -79,12 +79,12 @@ def make_covid_19_consent_form(cls, args): return cls.make_request(template_name, document, signer) @classmethod - def make_application_for_participation(cls, args): + def make_application_for_participation(cls, args, session): """ Make template_request for application_for_participation endpoint """ template_name = "ApplicationForParticipationTemplate" document = create_document("Application_for_participation_v2.pdf") - signer = make_application_for_participation_signer(args) + signer = make_application_for_participation_signer(args, session) return cls.make_request(template_name, document, signer) diff --git a/backend/docusign/templates/make_application_for_participation_signer.py b/backend/docusign/templates/make_application_for_participation_signer.py index 3de4b41..5f897ee 100644 --- a/backend/docusign/templates/make_application_for_participation_signer.py +++ b/backend/docusign/templates/make_application_for_participation_signer.py @@ -1,8 +1,126 @@ from datetime import datetime from typing import Optional from docusign_esign import Signer, Checkbox, Text, TabGroup, Number, Tabs, SignHere, DateSigned, SignerAttachment +from docusign.extensions import Extensions -def make_application_for_participation_signer(args): +def make_tabs_with_extensions(session): + phone_extension = Extensions.get_extension_app(session, Extensions.get_phone_extension_id())[0] + address_extension = Extensions.get_extension_app(session, Extensions.get_address_extension_id())[0] + ssn_extension = Extensions.get_extension_app(session, Extensions.get_ssn_extension_id())[0] + + # define phone tab + for tab in (t for t in phone_extension["tabs"] if "VerifyPhoneNumberInput[0].phoneNumber" in t["tabLabel"]): + verification_data = Extensions.extract_verification_data(phone_extension["appId"], tab) + extension_data = Extensions.get_extension_data(verification_data) + phone = Text( + name = verification_data["application_name"], + tab_label = verification_data["tab_label"], + tooltip = verification_data["action_input_key"], + document_id = '1', + page_number = '1', + anchor_string = '/phone/', + anchor_units = 'pixels', + required = True, + locked = False, + anchor_y_offset = '-5', + width = "120", + extension_data = extension_data + ) + + # define address tabs + address_fields = { + "address": "VerifyPostalAddressInput[0].street1", + "country": "VerifyPostalAddressInput[0].countryOrRegion", + "state": "VerifyPostalAddressInput[0].subdivision", + "city": "VerifyPostalAddressInput[0].locality", + "zip": "VerifyPostalAddressInput[0].postalCode", + } + address_fields_width = { + "address": "150", + "country": "120", + "state": "30", + "city": "150", + "zip": "60", + } + address_tabs = [] + for field, label_pattern in address_fields.items(): + for tab in (t for t in address_extension["tabs"] if label_pattern in t["tabLabel"]): + verification_data = Extensions.extract_verification_data(address_extension["appId"], tab) + extension_data = Extensions.get_extension_data(verification_data) + address_tabs.append(Text( + name = verification_data["application_name"], + tab_label = verification_data["tab_label"], + tooltip = verification_data["action_input_key"], + document_id = "1", + page_number = "1", + anchor_string = f"/{field}/", + anchor_units = "pixels", + anchor_y_offset = '-5', + required = True, + locked = False, + width = address_fields_width[field], + extension_data = extension_data, + ) + ) + + # define SSN tab + for tab in (t for t in ssn_extension["tabs"] if "VerifySocialSecurityNumberInput[0].socialSecurityNumber" in t["tabLabel"]): + verification_data = Extensions.extract_verification_data(ssn_extension["appId"], tab) + extension_data = Extensions.get_extension_data(verification_data) + ssn = Text( + name = verification_data["application_name"], + tab_label = verification_data["tab_label"], + tooltip = verification_data["action_input_key"], + document_id = '1', + page_number = '1', + anchor_string = '/ssn/', + anchor_units = 'pixels', + required = True, + locked = False, + anchor_y_offset = '-5', + extension_data = extension_data + ) + + return phone, address_tabs, ssn + +def make_tabs_without_extensions(): + ssn = Text( + document_id="1", page_number="1", anchor_string='/ssn/', anchor_units='pixels', + required="true", tab_label="ssn", height="12", width="150", anchor_y_offset= "-5", + validation_message="SSN format: xxx-xx-xxxx", + validation_pattern="^[0-9]{3}-[0-9]{2}-[0-9]{4}$" + ) + + address_tabs = [] + address_tabs.append(Text( + document_id="1", page_number="1", anchor_string="/address/", anchor_units="pixels", + required="true", tab_label="address", height="12", width="150", anchor_y_offset= "-5" + )) + address_tabs.append(Text( + document_id="1", page_number="1", anchor_string="/country/", anchor_units="pixels", + required="true", tab_label="country", height="12", width="120", anchor_y_offset= "-5" + )) + address_tabs.append(Text( + document_id="1", page_number="1", anchor_string="/city/", anchor_units="pixels", + required="true", tab_label="city", height="12", width="150", anchor_y_offset= "-5" + )) + address_tabs.append(Text( + document_id="1", page_number="1", anchor_string="/state/", anchor_units="pixels", + required="true", tab_label="state", height="12", width="30", anchor_y_offset= "-5" + )) + address_tabs.append(Text( + document_id="1", page_number="1", anchor_string="/zip/", anchor_units="pixels", + required="true", tab_label="zip", height="12", width="60", anchor_y_offset= "-5" + )) + + phone = Number( + document_id="1", page_number="1", anchor_string="/phone/", anchor_units="pixels", + required="true", tab_label="phone1", height="12", width="150", anchor_y_offset= "-5" + ) + + return phone, address_tabs, ssn + +def make_application_for_participation_signer(args, session): """ Create signer and fields using absolute positioning Add the tabs model to the signer @@ -24,34 +142,6 @@ def make_application_for_participation_signer(args): document_id="1", page_number="1", x_position="231", y_position="168", required="true", tab_label="last_name", height="12", width="60" ) - ssn = Text( - document_id="1", page_number="1", x_position="399", y_position="168", - required="true", tab_label="ssn", height="12", width="150", - validation_message="SSN format: xxx-xx-xxxx", - validation_pattern="^[0-9]{3}-[0-9]{2}-[0-9]{4}$" - ) - - address = Text( - document_id="1", page_number="1", x_position="47", y_position="211", - required="true", tab_label="address", height="12", width="320" - ) - city = Text( - document_id="1", page_number="1", x_position="47", y_position="251", - required="true", tab_label="city", height="12", width="150" - ) - state = Text( - document_id="1", page_number="1", x_position="228", y_position="251", - required="true", tab_label="state", height="12", width="30" - ) - zip = Text( - document_id="1", page_number="1", x_position="287", y_position="251", - required="true", tab_label="zip", height="12", width="60" - ) - - phone = Number( - document_id="1", page_number="1", x_position="399", y_position="210", - required="true", tab_label="phone1", height="12", width="150" - ) family_size = Number( document_id="1", page_number="1", x_position="399", y_position="252", @@ -435,14 +525,18 @@ def make_application_for_participation_signer(args): document_id="1", page_number="2", x_position="456", y_position="587" ) + if args.get("useWithoutExtension", True): + phone, address_tabs, ssn = make_tabs_without_extensions() + else: + phone, address_tabs, ssn = make_tabs_with_extensions(session) + # The Tabs object requires arrays of the different field/tab types signer.tabs = Tabs( - text_tabs=[last_name, first_name, ssn, address, city, state, - zip, individual_assets, family_assets, asset1, asset2, asset3, + text_tabs=[last_name, first_name, ssn, individual_assets, family_assets, asset1, asset2, asset3, asset4, asset5, asset6, asset_total, last_12, income1, income2, income3, income4, income5, income6, income7, income8, income9, - income10, income11, income12, income13, income_total], - number_tabs=[phone, family_size], + income10, income11, income12, income13, income_total, phone, *address_tabs], + number_tabs=[family_size], checkbox_tabs=[ check1, check2, check3, check4, check5, check6, check7, check8, check9, diff --git a/backend/requirements.txt b/backend/requirements.txt index 00ed010..f3bc1f2 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -24,3 +24,4 @@ typed-ast==1.5.5 typing-extensions==4.12.2 urllib3>=2.2.3 wrapt==1.16.0 +requests==2.* diff --git a/frontend/public/locales/en/Common.json b/frontend/public/locales/en/Common.json index d1c2e95..ce66013 100644 --- a/frontend/public/locales/en/Common.json +++ b/frontend/public/locales/en/Common.json @@ -5,5 +5,9 @@ "GitHubLink": "https://github.com/docusign/sample-app-healthcare-python", "AboutLinkText": "About", "LogInText": "Log in", - "LogOutText": "Log out" + "LogOutText": "Log out", + "DownloadExtensionsButton": "Extension app is now installed, try again", + "DownloadExtensionsHeader": "Extension app not installed", + "ContinueWithoutExtensionsButton": "Continue without extension app", + "DownloadExtensionsMessage": "Extension app not installed for this account. Either go to the App Center to install one and try again, or you can continue to use this sample app without a data verification extension app.Links to extension apps: - SSN and FEIN Verification (for SSN verification) - Vonage (for phone verification) - Smarty (for address verification)" } diff --git a/frontend/src/api/healthcareAPI.js b/frontend/src/api/healthcareAPI.js index b1cfa82..38bae92 100644 --- a/frontend/src/api/healthcareAPI.js +++ b/frontend/src/api/healthcareAPI.js @@ -16,3 +16,17 @@ export async function sendRequest(request, urlPath) { handleError(error); } } + +export async function getExtensions(urlPath) { + try { + const response = await axios.get( + process.env.REACT_APP_API_BASE_URL + urlPath, + { + withCredentials: true + } + ); + return handleResponse(response); + } catch (error) { + handleError(error); + } +} diff --git a/frontend/src/assets/scss/components/_seeMore.scss b/frontend/src/assets/scss/components/_seeMore.scss index 1fa8e5d..6811fb5 100644 --- a/frontend/src/assets/scss/components/_seeMore.scss +++ b/frontend/src/assets/scss/components/_seeMore.scss @@ -22,4 +22,7 @@ .bs h5 { font-size: 1rem; font-weight: 700; +} +.container .row { + align-items: flex-start; } \ No newline at end of file diff --git a/frontend/src/components/extensionModal.js b/frontend/src/components/extensionModal.js new file mode 100644 index 0000000..b00d6e1 --- /dev/null +++ b/frontend/src/components/extensionModal.js @@ -0,0 +1,35 @@ +import { useTranslation } from "react-i18next"; +import { Modal, Button, Container } from "react-bootstrap"; + +const ExtensionsModal = ({ show, onDownloadExtensions, onHide, title, message }) => { + const { t } = useTranslation("Common"); + + const handleContinue = () => { + onHide(); + }; + + return ( + + + {title} + + + + + + + + + + + {t("DownloadExtensionsButton")} + + + {t("ContinueWithoutExtensionsButton")} + + + + ); +}; + +export default ExtensionsModal; diff --git a/frontend/src/components/header.js b/frontend/src/components/header.js index 079e718..872d112 100644 --- a/frontend/src/components/header.js +++ b/frontend/src/components/header.js @@ -27,8 +27,8 @@ const Header = () => { { return ( - diff --git a/frontend/src/pages/applyForPatientAssistance/index.js b/frontend/src/pages/applyForPatientAssistance/index.js index bfcdf8f..54df24c 100644 --- a/frontend/src/pages/applyForPatientAssistance/index.js +++ b/frontend/src/pages/applyForPatientAssistance/index.js @@ -5,21 +5,26 @@ import { useNavigate, useLocation } from "react-router-dom"; import InputText from "../../components/inputText"; import InputEmail from "../../components/inputEmail"; import SeeMore from "../../components/seeMore"; -import { sendRequest } from "../../api/healthcareAPI"; +import ExtensionsModal from "../../components/extensionModal"; +import { getExtensions, sendRequest } from "../../api/healthcareAPI"; import { getStatus } from "../../api/auth"; -const urlPath = "/apply-for-patient-assistance" +const urlPath = "/apply-for-patient-assistance"; +const extensionsUrlPath = "/extensions"; const returnUrl = process.env.REACT_APP_DS_RETURN_URL + "/success?1"; const ApplyForPatientAssistance = props => { let navigate = useNavigate(); + const { t: tCommon } = useTranslation("Common"); const { t } = useTranslation("ApplyForPatientAssistance"); const [ submitted, setSubmitted ] = useState(false); const [ formError, setFormError ] = useState([true, true, true]); const [ apiError, setApiError ] = useState(""); const [ response, setResponse ] = useState(null); + const [ areExtensionsPresent, setAreExtensionsPresent ] = useState(false); + const [ showModal, setShowModal ] = useState(false); const { setBackdrop, logged, setLogged } = useContext(AppContext); @@ -33,8 +38,8 @@ const ApplyForPatientAssistance = props => { } window.DocuSign.loadDocuSign(response.client_id).then((docusign) => { - const elem = document.getElementsByClassName("col form-holder mb-4")[0]; - elem.className = "col-sm-6"; + const elem = document.getElementsByClassName("col form-holder mb-4")[0]; + elem.className = "col-sm-6"; const signing = docusign.signing({ url: response.view_url, displayFormat: "focused", @@ -66,21 +71,31 @@ const ApplyForPatientAssistance = props => { getStatus(setLogged, navigate); setApiError("") - setSubmitted(true); + // setSubmitted(true); if (!logged) navigate("") if (!isFormValid()) return; setBackdrop(true); + const useWithoutExtension = sessionStorage.getItem("useWithoutExtension") === "true"; const el = event.target.elements; const body = { first_name: el.FirstName.value, last_name: el.LastName.value, email: el.Email.value, - return_url: returnUrl + return_url: returnUrl, + useWithoutExtension, }; - try{ + try { + if (!useWithoutExtension) { + const extensions = await getExtensions(extensionsUrlPath); + if(extensions.data?.areExtensionsPresent === false){ + setAreExtensionsPresent(true); + setShowModal(true); + return; + } + } const response = await sendRequest(body, urlPath); setResponse(response.data); } catch (error) { @@ -147,6 +162,22 @@ const ApplyForPatientAssistance = props => { /> + {areExtensionsPresent && ( + setShowModal(false) + } + onHide={ + () => { + sessionStorage.setItem("useWithoutExtension", "true"); + setShowModal(false); + } + } + title={tCommon("DownloadExtensionsHeader")} + message={tCommon("DownloadExtensionsMessage")} + /> + )} )
- diff --git a/frontend/src/pages/applyForPatientAssistance/index.js b/frontend/src/pages/applyForPatientAssistance/index.js index bfcdf8f..54df24c 100644 --- a/frontend/src/pages/applyForPatientAssistance/index.js +++ b/frontend/src/pages/applyForPatientAssistance/index.js @@ -5,21 +5,26 @@ import { useNavigate, useLocation } from "react-router-dom"; import InputText from "../../components/inputText"; import InputEmail from "../../components/inputEmail"; import SeeMore from "../../components/seeMore"; -import { sendRequest } from "../../api/healthcareAPI"; +import ExtensionsModal from "../../components/extensionModal"; +import { getExtensions, sendRequest } from "../../api/healthcareAPI"; import { getStatus } from "../../api/auth"; -const urlPath = "/apply-for-patient-assistance" +const urlPath = "/apply-for-patient-assistance"; +const extensionsUrlPath = "/extensions"; const returnUrl = process.env.REACT_APP_DS_RETURN_URL + "/success?1"; const ApplyForPatientAssistance = props => { let navigate = useNavigate(); + const { t: tCommon } = useTranslation("Common"); const { t } = useTranslation("ApplyForPatientAssistance"); const [ submitted, setSubmitted ] = useState(false); const [ formError, setFormError ] = useState([true, true, true]); const [ apiError, setApiError ] = useState(""); const [ response, setResponse ] = useState(null); + const [ areExtensionsPresent, setAreExtensionsPresent ] = useState(false); + const [ showModal, setShowModal ] = useState(false); const { setBackdrop, logged, setLogged } = useContext(AppContext); @@ -33,8 +38,8 @@ const ApplyForPatientAssistance = props => { } window.DocuSign.loadDocuSign(response.client_id).then((docusign) => { - const elem = document.getElementsByClassName("col form-holder mb-4")[0]; - elem.className = "col-sm-6"; + const elem = document.getElementsByClassName("col form-holder mb-4")[0]; + elem.className = "col-sm-6"; const signing = docusign.signing({ url: response.view_url, displayFormat: "focused", @@ -66,21 +71,31 @@ const ApplyForPatientAssistance = props => { getStatus(setLogged, navigate); setApiError("") - setSubmitted(true); + // setSubmitted(true); if (!logged) navigate("") if (!isFormValid()) return; setBackdrop(true); + const useWithoutExtension = sessionStorage.getItem("useWithoutExtension") === "true"; const el = event.target.elements; const body = { first_name: el.FirstName.value, last_name: el.LastName.value, email: el.Email.value, - return_url: returnUrl + return_url: returnUrl, + useWithoutExtension, }; - try{ + try { + if (!useWithoutExtension) { + const extensions = await getExtensions(extensionsUrlPath); + if(extensions.data?.areExtensionsPresent === false){ + setAreExtensionsPresent(true); + setShowModal(true); + return; + } + } const response = await sendRequest(body, urlPath); setResponse(response.data); } catch (error) { @@ -147,6 +162,22 @@ const ApplyForPatientAssistance = props => { />