Merge branch 'develop' into feature/Digital/CSR-2087

This commit is contained in:
hiteshkumar87 2024-08-21 16:37:15 +05:30 committed by GitHub
commit 20f6972361
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 499 additions and 266 deletions

View file

@ -75,7 +75,6 @@ stages:
steps:
- checkout: self
clean: true
- bash: cp applepay/apple-developer-merchantid-domain-association-nonprod.txt apple-developer-merchantid-domain-association.txt
- template: templates/digital/step-build-vue.yml@AzureDevOps
parameters:
buildOutputDir: dist
@ -135,7 +134,6 @@ stages:
steps:
- checkout: self
clean: true
- bash: cp public/applepay/apple-developer-merchantid-domain-association-nonprod.txt public/apple-developer-merchantid-domain-association.txt
- template: templates/digital/step-build-vue.yml@AzureDevOps
parameters:
buildOutputDir: dist
@ -195,7 +193,6 @@ stages:
steps:
- checkout: self
clean: true
- bash: cp public/applepay/apple-developer-merchantid-domain-association-nonprod.txt public/apple-developer-merchantid-domain-association.txt
- template: templates/digital/step-build-vue.yml@AzureDevOps
parameters:
buildOutputDir: dist
@ -255,7 +252,6 @@ stages:
steps:
- checkout: self
clean: true
- bash: cp public/applepay/apple-developer-merchantid-domain-association-prod.txt public/apple-developer-merchantid-domain-association.txt
- template: templates/digital/step-build-vue.yml@AzureDevOps
parameters:
buildOutputDir: dist

View file

@ -32,7 +32,7 @@ module.exports = {
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
coverageThreshold: {
global: {
statements: 77,
statements: 76,
},
},
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit

View file

@ -1,74 +0,0 @@
MIIQaQYJKoZIhvcNAQcCoIIQWjCCEFYCAQExCzAJBgUrDgMCGgUAMHgGCSqGSIb3DQEHAaBrBGl7
InRlYW1JZCI6IlY4SFNZMzlOWjUiLCJkb21haW4iOiJ3d3ctdGVzdDIuc2FmZWxpdGUuY29tIiwi
ZGF0ZUNyZWF0ZWQiOiIyMDI0LTA3LTE4LDE0OjU1OjA1IiwidmVyc2lvbiI6MX2ggg0_MIIENDCC
AxygAwIBAgIIY_BW8s8iV_MwDQYJKoZIhvcNAQELBQAwczEtMCsGA1UEAwwkQXBwbGUgaVBob25l
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcNMjQwMTMwMTgzMjA1WhcNMjkw
MTI4MTgzMjA0WjBZMTUwMwYDVQQDDCxBcHBsZSBpUGhvbmUgT1MgUHJvdmlzaW9uaW5nIFByb2Zp
bGUgU2lnbmluZzETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC1FX_kJQ1chXPiyq7cbeqNGGn-pv_c_cwpLk2qcBWJD79H31jO
WFlKCB2xoQ229iBxUncHfWR_QmmLKHvyw0A9s3CBF8nkhi2ZVzd1wNTjtjcc2Dcm7kAsi3Hw7xRj
TOS_0S-HUEUdpxJxkbQX9sNJQHBt64923LXzwWH5JKwxWb5X_kqWxYoAlse5CjmYUeqATgKGEejt
eO1HxmV6-LAL1Ycpfmab7T296Dm6fUhkO-eIB1-efCGWkBQAV0BlJq7bo4O8jRv3o4VjOjf0rtDO
FG8RVCdSsGjLtGs-0gDEORTorEdwUlY2X54rPlOZpuOA0lN4N7tz35kMtxySmq9lAgMBAAGjgeUw
geIwDAYDVR0TAQH_BAIwADAfBgNVHSMEGDAWgBRv8ZUYYlzgyPHF7WwYyeDTZFKYIDBABggrBgEF
BQcBAQQ0MDIwMAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYWlwY2Ew
NzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmFwcGxlLmNvbS9haXBjYS5jcmwwHQYDVR0O
BBYEFCkAQ-DGkwX04nv_NdJ5BvpUl3YjMA4GA1UdDwEB_wQEAwIHgDAPBgkqhkiG92NkBjoEAgUA
MA0GCSqGSIb3DQEBCwUAA4IBAQBA51NbANKWAu-nYD7W27ilNY9YRzstmIC5_nOz1o_RTQR_Zbps
s1G8bzM-53F6OgL8MFI2ummWpXfSL2k_bX6Y_FtCYkoyWdF-rVexy0WeCkjeRgc1G14DGy5ontva
qGzENwiFoECYoxI4cBANSDVkhZNWBzfZ2lY4cCWo4U9oVyxYDBoWSd4_JTZzWNzlX3koj7kLA7vh
nPUW53hsEk_BsH5x10qy_tEBNOKPbh4vC3q0wbEyhk6_W5iEaE9nh0_Anrq0MfQJtIo91t4QKkvE
jcNN1OrFYpmYGevd0X3H99npvad4XiYUX2Pmf0Ro8ChhvcDhFeBAq_9h6HvAOUoMMIIERDCCAyyg
AwIBAgIIXGPK5Eo3U8kwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFw
cGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQD
Ew1BcHBsZSBSb290IENBMB4XDTE3MDUxMDIxMjczMFoXDTMwMTIzMTAwMDAwMFowczEtMCsGA1UE
AwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJRWoBDz6DBIbH_L_cXvAege4XMHNjJi7ePXokzZM-
TzlHunW-88DS8Vmiqx_-CoY82S2aB_IOa7kpkRpfIgqL8XJYBa5MS0TFeaeAPLCI4IwMJ4RdGeWH
GTbL48V2t7D0QXJR9AVcg0uibaZRuPEm33terWUMxrKYUYy7fRtMwU7ICMfS7WQLtN0bjU9AfRuP
SJaSW_PQmH7ZvKQZDplhu0FdAcxbd3p9JNDc01P_w9zFlCy2Wk2OGCM5vdnGUj7R8vQliqEqh_3Y
DEYpUf_tF2yJJWuHv4ppFJ93n8MVt2iziEW9hOYGAkFkD60qKLgVyeCsp4q6cgQ0sniM-LKFAgMB
AAGjgewwgekwDwYDVR0TAQH_BAUwAwEB_zAfBgNVHSMEGDAWgBQr0GlHlHYJ_vRrjS5ApvdHTX8I
XjBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3Nw
MDMtYXBwbGVyb290Y2EwLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9v
dC5jcmwwHQYDVR0OBBYEFG_xlRhiXODI8cXtbBjJ4NNkUpggMA4GA1UdDwEB_wQEAwIBBjAQBgoq
hkiG92NkBgISBAIFADANBgkqhkiG9w0BAQsFAAOCAQEAOs-smI2-kiAhCa2V87FcIfo2LVcgRHRz
ZJIIs5as922X-ls0OCfPEkbTPBHwB8mZkLHR6BEJpeOla2xjCD-eJfrVmZxM5uXOjrJNaOyLq6Oi
T4oRFT7cFCscxkS2b2fFW0-VKS2HXD_cgx53T-3aVKct5xOBwWPEVAsbSwpqKCII1DeSfH9nKF-v
PT-3rFkdODRkWu4zShlCRCnEyhhr4cFTLS30TcIV9jMyGHjxJm-KTeuUTKPo_w-zA4tl2usu2GVQ
n9yfit8xqIRU3FJSQdKyEx0xRkeIXz7uw_KMIwSV66yKPoJsBp8u44tDmmJbNA30mc8s7rpyhhkj
pfyOtTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMxEzARBgNV
BAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYw
FAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIxNDAzNloXDTM1MDIwOTIxNDAzNlowYjEL
MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5JGpCR-R2x5HUOsF7V55hC3rNqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQ
CdN_QaiY-dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3M8vED03OFGnRyRly9V0O1X9fm_IlA7pV
j01dDfFkNSMVSxVZHbOU9_acns9QusFYUGePCLQg98usLCBvcLY_ATCMt0PPD5098ytJKBrI_s61
uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJHU1XBry9Bs_j743DN5qNMRX4fTGtQlkGJ
xHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP_Z15lvEnYdp8zFGWhd5TJLQIDAQABo4IBejCCAXYw
DgYDVR0PAQH_BAQDAgEGMA8GA1UdEwEB_wQFMAMBAf8wHQYDVR0OBBYEFCvQaUeUdgn-9GuNLkCm
90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn-9GuNLkCm90dNfwheMIIBEQYDVR0gBIIBCDCCAQQw
ggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBs
ZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFu
eSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2Vy
dGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjANBgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14
t-2Mm9zzd5vydtJ3ME_BH4WDhRuZPUc38qmbQI4s1LGQEti-9HOb7tJkD8t5TzTYoj75eP9ryAfs
fTmDi1Mg0zjEsb-aTwpr_yv8WacFCXwXQFYRHnTTt4sjO0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UX
F6jcfiI1yiXV2Q_Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4REjwYDieFfU9JmcgijNq9w2Cz97roy_5
U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU-12TZ_wYdV2aeZuTJC-9jVcZ5-oVK3G72TQiQSKscPHbZN
nF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAoUwggKBAgEBMH8wczEtMCsGA1UEAwwkQXBwbGUgaVBo
b25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMCCGPwVvLPIlfzMAkGBSsOAwIa
BQCggdwwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjQwNzE4MTQ1
NTA1WjAjBgkqhkiG9w0BCQQxFgQUYwvDx1yr56NtJEdxh--NMv9wqDEwKQYJKoZIhvcNAQk0MRww
GjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcw
DgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0G
CSqGSIb3DQEBAQUABIIBAJ6WUgCnMMT4q4LQjeOOpLWsXJRdns3b5aBEKoK3NIetn3I_bWo0wmX3
Rxuy29Ljv_0bGC0PfcXyBXWtg1LQ4EzUpgpVK_IeZrlX6HcKwxgZwkejwVg009kTYNir-otXP1AM
YNfXsPA-woLAbo_Hx0MrN1EHgejqO8x5c9s7LpQQGJpVsD9Rq6sZ4VJftMtuTz4XwvU3Qypj7_RF
Drhh-MekYg6qG7aJMzOuftkDx2BWL7Sld77ViX1Qt8zZpyoI4RW4MIxH50ERwVYlpaoHYdnit3Ct
RZki8aS0kxFdxVY0pePF0k6h-5GbwceXATkXM4UY0-fAXqk11QevHKT8was

View file

@ -1,74 +0,0 @@
MIIQaQYJKoZIhvcNAQcCoIIQWjCCEFYCAQExCzAJBgUrDgMCGgUAMHgGCSqGSIb3DQEHAaBrBGl7
InRlYW1JZCI6IlY4SFNZMzlOWjUiLCJkb21haW4iOiJ3d3ctdGVzdDIuc2FmZWxpdGUuY29tIiwi
ZGF0ZUNyZWF0ZWQiOiIyMDI0LTA3LTE4LDE0OjU1OjA1IiwidmVyc2lvbiI6MX2ggg0_MIIENDCC
AxygAwIBAgIIY_BW8s8iV_MwDQYJKoZIhvcNAQELBQAwczEtMCsGA1UEAwwkQXBwbGUgaVBob25l
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwHhcNMjQwMTMwMTgzMjA1WhcNMjkw
MTI4MTgzMjA0WjBZMTUwMwYDVQQDDCxBcHBsZSBpUGhvbmUgT1MgUHJvdmlzaW9uaW5nIFByb2Zp
bGUgU2lnbmluZzETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQC1FX_kJQ1chXPiyq7cbeqNGGn-pv_c_cwpLk2qcBWJD79H31jO
WFlKCB2xoQ229iBxUncHfWR_QmmLKHvyw0A9s3CBF8nkhi2ZVzd1wNTjtjcc2Dcm7kAsi3Hw7xRj
TOS_0S-HUEUdpxJxkbQX9sNJQHBt64923LXzwWH5JKwxWb5X_kqWxYoAlse5CjmYUeqATgKGEejt
eO1HxmV6-LAL1Ycpfmab7T296Dm6fUhkO-eIB1-efCGWkBQAV0BlJq7bo4O8jRv3o4VjOjf0rtDO
FG8RVCdSsGjLtGs-0gDEORTorEdwUlY2X54rPlOZpuOA0lN4N7tz35kMtxySmq9lAgMBAAGjgeUw
geIwDAYDVR0TAQH_BAIwADAfBgNVHSMEGDAWgBRv8ZUYYlzgyPHF7WwYyeDTZFKYIDBABggrBgEF
BQcBAQQ0MDIwMAYIKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYWlwY2Ew
NzAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmFwcGxlLmNvbS9haXBjYS5jcmwwHQYDVR0O
BBYEFCkAQ-DGkwX04nv_NdJ5BvpUl3YjMA4GA1UdDwEB_wQEAwIHgDAPBgkqhkiG92NkBjoEAgUA
MA0GCSqGSIb3DQEBCwUAA4IBAQBA51NbANKWAu-nYD7W27ilNY9YRzstmIC5_nOz1o_RTQR_Zbps
s1G8bzM-53F6OgL8MFI2ummWpXfSL2k_bX6Y_FtCYkoyWdF-rVexy0WeCkjeRgc1G14DGy5ontva
qGzENwiFoECYoxI4cBANSDVkhZNWBzfZ2lY4cCWo4U9oVyxYDBoWSd4_JTZzWNzlX3koj7kLA7vh
nPUW53hsEk_BsH5x10qy_tEBNOKPbh4vC3q0wbEyhk6_W5iEaE9nh0_Anrq0MfQJtIo91t4QKkvE
jcNN1OrFYpmYGevd0X3H99npvad4XiYUX2Pmf0Ro8ChhvcDhFeBAq_9h6HvAOUoMMIIERDCCAyyg
AwIBAgIIXGPK5Eo3U8kwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkFw
cGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQD
Ew1BcHBsZSBSb290IENBMB4XDTE3MDUxMDIxMjczMFoXDTMwMTIzMTAwMDAwMFowczEtMCsGA1UE
AwwkQXBwbGUgaVBob25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJRWoBDz6DBIbH_L_cXvAege4XMHNjJi7ePXokzZM-
TzlHunW-88DS8Vmiqx_-CoY82S2aB_IOa7kpkRpfIgqL8XJYBa5MS0TFeaeAPLCI4IwMJ4RdGeWH
GTbL48V2t7D0QXJR9AVcg0uibaZRuPEm33terWUMxrKYUYy7fRtMwU7ICMfS7WQLtN0bjU9AfRuP
SJaSW_PQmH7ZvKQZDplhu0FdAcxbd3p9JNDc01P_w9zFlCy2Wk2OGCM5vdnGUj7R8vQliqEqh_3Y
DEYpUf_tF2yJJWuHv4ppFJ93n8MVt2iziEW9hOYGAkFkD60qKLgVyeCsp4q6cgQ0sniM-LKFAgMB
AAGjgewwgekwDwYDVR0TAQH_BAUwAwEB_zAfBgNVHSMEGDAWgBQr0GlHlHYJ_vRrjS5ApvdHTX8I
XjBEBggrBgEFBQcBAQQ4MDYwNAYIKwYBBQUHMAGGKGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3Nw
MDMtYXBwbGVyb290Y2EwLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9v
dC5jcmwwHQYDVR0OBBYEFG_xlRhiXODI8cXtbBjJ4NNkUpggMA4GA1UdDwEB_wQEAwIBBjAQBgoq
hkiG92NkBgISBAIFADANBgkqhkiG9w0BAQsFAAOCAQEAOs-smI2-kiAhCa2V87FcIfo2LVcgRHRz
ZJIIs5as922X-ls0OCfPEkbTPBHwB8mZkLHR6BEJpeOla2xjCD-eJfrVmZxM5uXOjrJNaOyLq6Oi
T4oRFT7cFCscxkS2b2fFW0-VKS2HXD_cgx53T-3aVKct5xOBwWPEVAsbSwpqKCII1DeSfH9nKF-v
PT-3rFkdODRkWu4zShlCRCnEyhhr4cFTLS30TcIV9jMyGHjxJm-KTeuUTKPo_w-zA4tl2usu2GVQ
n9yfit8xqIRU3FJSQdKyEx0xRkeIXz7uw_KMIwSV66yKPoJsBp8u44tDmmJbNA30mc8s7rpyhhkj
pfyOtTCCBLswggOjoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMxEzARBgNV
BAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYw
FAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTA2MDQyNTIxNDAzNloXDTM1MDIwOTIxNDAzNlowYjEL
MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5JGpCR-R2x5HUOsF7V55hC3rNqJXTFXsixmJ3vlLbPUHqyIwAugYPvhQ
CdN_QaiY-dHKZpwkaxHQo7vkGyrDH5WeegykR4tb1BY3M8vED03OFGnRyRly9V0O1X9fm_IlA7pV
j01dDfFkNSMVSxVZHbOU9_acns9QusFYUGePCLQg98usLCBvcLY_ATCMt0PPD5098ytJKBrI_s61
uQ7ZXhzWyz21Oq30Dw4AkguxIRYudNU8DdtiFqujcZJHU1XBry9Bs_j743DN5qNMRX4fTGtQlkGJ
xHRiCxCDQYczioGxMFjsWgQyjGizjx3eZXP_Z15lvEnYdp8zFGWhd5TJLQIDAQABo4IBejCCAXYw
DgYDVR0PAQH_BAQDAgEGMA8GA1UdEwEB_wQFMAMBAf8wHQYDVR0OBBYEFCvQaUeUdgn-9GuNLkCm
90dNfwheMB8GA1UdIwQYMBaAFCvQaUeUdgn-9GuNLkCm90dNfwheMIIBEQYDVR0gBIIBCDCCAQQw
ggEABgkqhkiG92NkBQEwgfIwKgYIKwYBBQUHAgEWHmh0dHBzOi8vd3d3LmFwcGxlLmNvbS9hcHBs
ZWNhLzCBwwYIKwYBBQUHAgIwgbYagbNSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFu
eSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2Vy
dGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjANBgkqhkiG9w0BAQUFAAOCAQEAXDaZTC14
t-2Mm9zzd5vydtJ3ME_BH4WDhRuZPUc38qmbQI4s1LGQEti-9HOb7tJkD8t5TzTYoj75eP9ryAfs
fTmDi1Mg0zjEsb-aTwpr_yv8WacFCXwXQFYRHnTTt4sjO0ej1W8k4uvRt3DfD0XhJ8rxbXjt57UX
F6jcfiI1yiXV2Q_Wa9SiJCMR96Gsj3OBYMYbWwkvkrL4REjwYDieFfU9JmcgijNq9w2Cz97roy_5
U2pbZMBjM3f3OgcsVuvaDyEO2rpzGU-12TZ_wYdV2aeZuTJC-9jVcZ5-oVK3G72TQiQSKscPHbZN
nF5jyEuAF1CqitXa5PzQCQc3sHV1ITGCAoUwggKBAgEBMH8wczEtMCsGA1UEAwwkQXBwbGUgaVBo
b25lIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMCCGPwVvLPIlfzMAkGBSsOAwIa
BQCggdwwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjQwNzE4MTQ1
NTA1WjAjBgkqhkiG9w0BCQQxFgQUYwvDx1yr56NtJEdxh--NMv9wqDEwKQYJKoZIhvcNAQk0MRww
GjAJBgUrDgMCGgUAoQ0GCSqGSIb3DQEBAQUAMFIGCSqGSIb3DQEJDzFFMEMwCgYIKoZIhvcNAwcw
DgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMA0G
CSqGSIb3DQEBAQUABIIBAJ6WUgCnMMT4q4LQjeOOpLWsXJRdns3b5aBEKoK3NIetn3I_bWo0wmX3
Rxuy29Ljv_0bGC0PfcXyBXWtg1LQ4EzUpgpVK_IeZrlX6HcKwxgZwkejwVg009kTYNir-otXP1AM
YNfXsPA-woLAbo_Hx0MrN1EHgejqO8x5c9s7LpQQGJpVsD9Rq6sZ4VJftMtuTz4XwvU3Qypj7_RF
Drhh-MekYg6qG7aJMzOuftkDx2BWL7Sld77ViX1Qt8zZpyoI4RW4MIxH50ERwVYlpaoHYdnit3Ct
RZki8aS0kxFdxVY0pePF0k6h-5GbwceXATkXM4UY0-fAXqk11QevHKT8was

View file

@ -20,6 +20,7 @@ const GaActions = {
VIF: "vif",
SUBMITTED: "Submitted",
DISPLAYED: "Displayed",
CASH_QUOTE_DISPLAYED: "Cash quote displayed",
};
const GaLabels = {

View file

@ -30,6 +30,7 @@ const applicationConfig = {
OUTLOOK_CALENDAR:
"https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent",
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
AFFILIATE_COOKIE_CONTAINING_NAME: "_Track",
};
export { applicationConfig };

View file

@ -19,6 +19,7 @@ const customMappings = {
{ key: "Passenger Vent", transformedValue: "passenger side vent glass" },
{ key: "Passenger Quarter", transformedValue: "passenger side quarter panel" },
{ key: "Passenger SlideDoor", transformedValue: "passenger side sliding door" },
{ key: "Passenger SideDoor", transformedValue: "passenger side sliding door" },
],
};

View file

@ -37,11 +37,11 @@ const endpoints = {
method: "POST",
},
LookupVinByPlate: {
url: "/vehicle/api/v1/vehicle/lookup-by-plate",
url: "/vehicle/api/v1/vehicle/lookup-vin-by-plate",
method: "POST",
},
LookupVinByAddress: {
url: "/vehicle/api/v1/vehicle/lookup-by-address",
url: "/vehicle/api/v1/vehicle/lookup-vin-by-address",
method: "POST",
},
LookupVinByImage: {

View file

@ -93,6 +93,7 @@ const storeActions = {
SAVE_CCTOKEN: "saveCCToken",
SAVE_PAYPAL_TOKEN: "savePaypalToken",
SAVE_NEXTGEN_SETTLED_AMOUNT: "saveNextGenSettledAmount",
SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn",
CREATE_SUBMITTED_ORDER: "createSubmittedOrder",
RESET_SUBMITTED_ORDER: "resetSubmittedOrder",

View file

@ -60,6 +60,7 @@ const storeMutations = {
Customer_Portal_Login_Token: "updateCustomerPortalLoginToken",
LOCK_TOKEN: "updateLockToken",
UPDATE_SETTLED_TENDER_AMOUNT: "updateSettledTenderAmount",
UPDATE_IS_RECAL_ACK_OPT_IN: "updateIsRecalAckOptIn",
// EVENT BUS MUTATIONS
ADD_EVENT_TO_BUS: "addEventToBus",
@ -110,6 +111,9 @@ const storeMutations = {
RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE: "resetExternalParameterServiceZipState",
RESET_EXTERNAL_PARAMETER_QUOTE_STATE: "resetExternalParameterQuoteState",
RESET_IS_EXTERNAL_PARAMETER: "resetIsExternalParameter",
//Affiliate Cookies
UPDATE_AFFILIATE_COOKIES: "updateAffiliateCookies",
};
export { storeMutations };

View file

@ -263,6 +263,49 @@ describe("cart.vue", () => {
expect(found).toBe(true);
});
// Mobile Fee Cart Item
test("if there is mobile fee on the order, a mobile fee cart item should be added to the cart", () => {
// Arrange
const lineItems = {
glassParts: [],
supportingItems: [
{
description: null,
id: "9ff98501-03a4-432b-884e-e4e28f884a2f",
kitPrice: 0,
laborAmount: 34.98,
partNumber: "MOBILE FEE",
partType: "MOBILE FEE",
salesTax: 2.62,
sellingPrice: 0,
},
],
vaps: [],
promos: [],
};
const availableVaps = [];
// Act
const { wrapper } = setupMocks({
props: {
modelValue: lineItems,
availableVaps: availableVaps,
},
});
// Assert
expect(wrapper.vm.mobileFeeCartItem).not.toBeNull();
expect(wrapper.vm.mobileFeeCartItem.subTotal).toEqual(34.98);
expect(wrapper.vm.mobileFeeCartItem.salesTax).toEqual(2.62);
const found =
wrapper.vm.cartItems.findIndex(
(cartItem) => cartItem == wrapper.vm.mobileFeeCartItem
) >= 0;
expect(found).toBe(true);
});
// Service package discount Fee Cart Item
test("if there is service package discount fee on the order, a service package discount cart item should be added to the cart", () => {
// Arrange

View file

@ -377,6 +377,10 @@ export default {
cartItems.push(this.suppliesRepairCartItem);
}
if (this.mobileFeeCartItem) {
cartItems.push(this.mobileFeeCartItem);
}
if (this.servicePackageDiscountCartItem) {
cartItems.push(this.servicePackageDiscountCartItem);
}
@ -756,6 +760,39 @@ export default {
return cartItem;
},
mobileFeeCartItemName() {
return this.getCmsContent("MobileServiceTextWidget", "Text");
},
mobileFeeCartItem() {
let cartItem = null;
const mobileFeeLineItem = this.supportingItems.find(
(lineItem) => lineItem.partType == partTypeStrings.MOBILE_FEE
);
if (mobileFeeLineItem) {
cartItem = {
name: this.mobileFeeCartItemName,
category: cartItemCategories.SUPPORTING_ITEMS,
cartItemType: cartItemTypes.MOBILE_FEE,
isDisplayed: true,
isRemovable: false,
subTotal: 0,
salesTax: 0,
lineItems: [],
isCoveredByInsurance: cartItemTypesCoveredByInsurance.includes(
cartItemTypes.MOBILE_FEE
),
};
mobileFeeLineItem.cartItemType = cartItem.cartItemType;
cartItem.lineItems.push(mobileFeeLineItem);
cartItem.subTotal +=
(mobileFeeLineItem.kitPrice ?? 0) +
(mobileFeeLineItem.laborAmount ?? 0) +
(mobileFeeLineItem.sellingPrice ?? 0);
cartItem.salesTax += mobileFeeLineItem.salesTax ?? 0;
}
return cartItem;
},
servicePackageDiscountCartItemName() {
return this.getCmsContent("ServicePackageDiscountTextWidget", "Text");
},

View file

@ -98,15 +98,17 @@ export default {
);
}
// Do not route to error logic when no wipers found or no promo found (404s)
if (error.response.status != "404") {
//router.navigateError(); Emergency change for testing - skiener 03/12
}
// Do not route to error logic when no wipers found or no promo found (404s)
router.navigateError();
global.$logger.logError(
`${method}: ${endpoint}: ${error.message}`,
error.response
);
// do not log 404 errors from services because we return NotFound
// when a service doesn't return an object
global.$logger.logError(
`${method}: ${endpoint}: ${error.message}`,
error.response
);
}
return reject(error.response);
}

View file

@ -0,0 +1,15 @@
export function getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
const isLongAppointment = durationMaximum >= 120;
const isDurationRange = durationMinimum !== durationMaximum;
const adjustedMinimum = isLongAppointment ? durationMinimum / 60 : durationMinimum;
const adjustedMaximum = isLongAppointment ? durationMaximum / 60 : durationMaximum;
const durationText = isDurationRange
? `${adjustedMinimum} - ${adjustedMaximum}`
: adjustedMinimum;
const unitText = isLongAppointment ? "hours" : "minutes";
return `${durationText} ${unitText}`;
}

View file

@ -0,0 +1,24 @@
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
describe("damage-length-helper.js", () => {
it("Should return the expected duration for the appointment in hours", () => {
// Arrange / Act
const durationMinimum = 60;
const durationMaximum = 120;
const duration = getDisplayTextForDurationLength(durationMinimum, durationMaximum);
// Assert
expect(duration).toEqual("1 - 2 hours");
});
it("Should return the expected duration for the appointment in minutes", () => {
// Arrange / Act
const durationMinimum = 30;
const durationMaximum = 45;
const duration = getDisplayTextForDurationLength(durationMinimum, durationMaximum);
// Assert
expect(duration).toEqual("30 - 45 minutes");
});
});

View file

@ -210,6 +210,17 @@ export function refreshCookieExpiration(name, expirationTime) {
}
}
export function getAffiliateCookies() {
const affiliateCookies = [];
const cookieContainingName = applicationConfig.AFFILIATE_COOKIE_CONTAINING_NAME;
const affiliateCookiesAll = getCookiesContainingName(cookieContainingName);
affiliateCookiesAll?.forEach((cookieName) => {
const cookieValue = getCookieValueByName(cookieName);
affiliateCookies.push({ CookieName: cookieName, CookieValue: cookieValue });
});
return affiliateCookies;
}
/*
===========================
= PRIVATE FUNCTIONS =
@ -292,3 +303,15 @@ function getCookieValueByName(name) {
function isLocalhost() {
return location.hostname.includes("localhost");
}
function getCookiesContainingName(name) {
const allCookies = document.cookie.split(";");
const matchingCookies = [];
for (const cookie of allCookies) {
const [cookieName, cookieValue] = cookie.trim().split("=");
if (cookieName.includes(name)) {
matchingCookies.push(cookieName);
}
}
return matchingCookies;
}

View file

@ -11,9 +11,15 @@ import {
setSessionIdIfUnset,
isCookieSet,
refreshCookieExpiration,
getAffiliateCookies,
} from "@/helpers/heritage-integration/cookie-helper.js";
import { cookieNames } from "@/constants/cookie-names";
import { removeAllTestCookies, setupCookies, setupCrypto } from "@/helpers/unit-test-helper";
import {
removeAllTestCookies,
setupCookies,
setupCrypto,
setupAffiliateCookies,
} from "@/helpers/unit-test-helper";
import { deleteFunnelCookie } from "./cookie-helper";
const randomUUID = "68d89736-c277-46f1-8fee-c3dacdb23c08";
@ -431,3 +437,21 @@ describe("cookies", () => {
});
});
});
describe("getAffiliateCookies", () => {
it("should return an empty array if no affiliate cookies are found", () => {
setupAffiliateCookies({});
expect(getAffiliateCookies()).toEqual([]);
});
it("should return an array of affiliate cookies when they are present", () => {
setupAffiliateCookies({
CookieName: "affiliate_cookie1_Track",
CookieValue: "value_of_affiliate_cookie1",
});
const expectedCookies = [
{ CookieName: "affiliate_cookie1_Track", CookieValue: "value_of_affiliate_cookie1" },
];
expect(getAffiliateCookies()).toEqual(expectedCookies);
});
});

View file

@ -139,6 +139,10 @@ export function setupCookies({ funnelCookieValue = "", includeHeritageCookie = t
});
}
export function setupAffiliateCookies(cookie) {
setCookieProperties({ [cookie.CookieName]: cookie.CookieValue }, { isSecure: false });
}
export function setupCrypto(mockValue) {
global.crypto = {
randomUUID: jest.fn(),

View file

@ -1,6 +1,6 @@
// Components
import confirmation from "@/layouts/confirmation/confirmation.vue";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { applicationConfig } from "@/constants/application-config.js";
// Supporting Files
@ -25,6 +25,8 @@ beforeEach(() => {
startTime: "09:00",
endTime: "10:00",
routeCode: "000",
jobMaxMinutes: "120",
jobMinMinutes: "60",
},
lineItems: {
glassParts: [
@ -360,6 +362,69 @@ describe("computed properties...", () => {
// Assert
expect(testValue).toEqual("test1,<br/> test, AZ 12345");
});
test("Appointment Duration should return text in expected format.", () => {
//Arrange
const { wrapper } = setupMocks({});
// Act
const testValue = wrapper.vm.AppointmentDuration;
// Assert
expect(testValue).toEqual("Duration: 1 - 2 hours");
});
test("Appointment Duration should return with correct duration values in expected format for hours.", () => {
//Arrange
store.getters.submittedOrder.schedule.jobMaxMinutes = 120;
store.getters.submittedOrder.schedule.jobMinMinutes = 60;
const { wrapper } = setupMocks({});
// Act
const testValue = wrapper.vm.AppointmentDuration;
// Assert
expect(testValue).toEqual("Duration: 1 - 2 hours");
});
test("Appointment Duration should return with correct duration values in expected format for minutes.", () => {
//Arrange
store.getters.submittedOrder.schedule.jobMaxMinutes = 45;
store.getters.submittedOrder.schedule.jobMinMinutes = 30;
const { wrapper } = setupMocks({});
// Act
const testValue = wrapper.vm.AppointmentDuration;
// Assert
expect(testValue).toEqual("Duration: 30 - 45 minutes");
});
test("Appointment Duration should return with All Day.", () => {
//Arrange
store.getters.submittedOrder.schedule.jobMaxMinutes = 45;
store.getters.submittedOrder.schedule.jobMinMinutes = 30;
store.getters.submittedOrder.schedule.routeCode = RouteCodeFlags.ALL_DAY_DROP_OFF;
const { wrapper } = setupMocks({});
// Act
const testValue = wrapper.vm.AppointmentDuration;
// Assert
expect(testValue).toEqual("Duration: All Day");
});
test("Appointment Duration should return with Overnight.", () => {
//Arrange
store.getters.submittedOrder.schedule.jobMaxMinutes = 45;
store.getters.submittedOrder.schedule.jobMinMinutes = 30;
store.getters.submittedOrder.schedule.routeCode = RouteCodeFlags.OVERNIGHT_DROP_OFF;
const { wrapper } = setupMocks({});
// Act
const testValue = wrapper.vm.AppointmentDuration;
// Assert
expect(testValue).toEqual("Duration: Overnight");
});
});
function setupMocks({ customMountOptions }) {

View file

@ -42,6 +42,12 @@
:scheduleEndTime="ScheduleEndTime" />
<div class="appoinmenttext" v-html="AppointmentWordingText"></div>
<textBlock
:customText="AppointmentDuration"
justifyText="center"
typeStyle="medium"
class="duration-text-block" />
</div>
<hr />
@ -82,6 +88,7 @@ import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar";
import cart from "@/fmg-components/cart/cart";
import textBlock from "@/digital-components/text-block/text-block";
//Supporting files
import baseMixin from "@/mixins/base-mixin.js";
@ -89,7 +96,7 @@ import analyticsMixin from "@/mixins/analytics-mixin";
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper";
import { applicationConfig } from "@/constants/application-config.js";
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
@ -97,6 +104,7 @@ import { deepClone } from "@/helpers/object-helper";
import { Form } from "vee-validate";
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
import { coverageStatus } from "@/constants/insurance";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
export default {
name: "confirmation",
@ -315,6 +323,28 @@ export default {
isPia() {
return store.getters.submittedOrder?.payment.isPia;
},
AppointmentDuration() {
const durationMaximum = store.getters.submittedOrder?.schedule?.jobMaxMinutes;
const durationMinimum = store.getters.submittedOrder?.schedule?.jobMinMinutes;
const durationLengthString = "Duration: ";
if (
store.getters.submittedOrder?.schedule?.routeCode.includes(
RouteCodeFlags.ALL_DAY_DROP_OFF
)
) {
return durationLengthString.concat("All Day");
} else if (
store.getters.submittedOrder?.schedule?.routeCode.includes(
RouteCodeFlags.OVERNIGHT_DROP_OFF
)
) {
return durationLengthString.concat("Overnight");
} else {
return durationLengthString.concat(
getDisplayTextForDurationLength(durationMinimum, durationMaximum)
);
}
},
},
methods: {
arePagePrerequisitesValid() {
@ -365,6 +395,7 @@ export default {
vehicleBanner,
addToCalendar,
cart,
textBlock,
},
};
</script>

View file

@ -9,10 +9,8 @@
:answers="paymentMethodAnswerData"
isRequired
:validationRules="validationRules"
:hasRecal="hasRecal"
:showApplePay="showApplePay"
:isInsurance="isInsurance"
:isPiaEnabled="isPiaEnabled"
v-model="selectedMethod"
textPosition="text-start" />
</div>
@ -21,8 +19,6 @@
<script>
import buttonQuestion from "@/digital-components/button-question/button-question";
import paymentMethodListButton from "./payment-method-list-button/payment-method-list-button";
import store from "@/store";
import { paymentMethods, paymentTimes } from "@/constants/payment-method-constants";
export default {
name: "payment-method-question",
@ -34,10 +30,8 @@ export default {
props: {
modelValue: String,
validationRules: String,
hasRecal: Boolean,
showApplePay: Boolean,
isInsurance: Boolean,
isPiaEnabled: Boolean,
},
methods: {
getAnswersNullSafe(widgetName) {
@ -64,14 +58,10 @@ export default {
},
paymentMethodAnswerData() {
var cmsData;
if (this.hasRecal) {
cmsData = this.getAnswersNullSafe("PaymentMethodHasRecalWidget");
if (this.showApplePay) {
cmsData = this.getAnswersNullSafe("PaymentMethodWidget");
} else {
if (this.showApplePay) {
cmsData = this.getAnswersNullSafe("PaymentMethodWidget");
} else {
cmsData = this.getAnswersNullSafe("PaymentMethodHasRecalWidget");
}
cmsData = this.getAnswersNullSafe("PaymentMethodHasRecalWidget");
}
var tempItems = cmsData.map((answer) => {
@ -84,20 +74,13 @@ export default {
};
});
if (this.hasRecal || this.isInsurance) {
if (this.isInsurance) {
tempItems.splice(
tempItems.findIndex((a) => a.value === "Insurance"),
1
);
}
if (this.hasRecal || !this.isPiaEnabled) {
tempItems.splice(
tempItems.findIndex((a) => a.value === "PayNow"),
1
);
}
return tempItems;
},
},

View file

@ -65,16 +65,14 @@
</div>
<paymentMethodQuestion
v-if="isPiaEnabled && totalAmountDue > 0"
v-if="showPaymentMethodQuestions"
v-model="paymentMethodInternalModel"
:hasRecal="hasRecal"
:showApplePay="showApplePay"
:isInsurance="isInsurance"
:isPiaEnabled="isPiaEnabled"
validationRules="payment-method-required" />
<alert
v-if="!isPiaEnabled && totalAmountDue > 0"
v-if="!showPaymentMethodQuestions && !forwardClicked"
:isDismissible="false"
alertClass="alert-info"
cmsWidgetName="NoPiaDisclaimerWidget"
@ -347,7 +345,8 @@ export default {
availableVaps: [],
paymentMethodInternalModel: this.getPaymentMethodFromStore(),
inactivePromos: this.getInactivePromosFromStore(),
isRecalAckOptIn: false,
isRecalAckOptIn: this.getIsRecalAckOptInFromStore(),
forwardClicked: false, // this prevents the pia disclaimer from showing when switching to insurance and nav forward
};
},
methods: {
@ -486,10 +485,15 @@ export default {
this.$refs.loadingModal.hideModal();
},
getIsRecalAckOptInFromStore() {
return this.$store.getters.order.isRecalAckOptIn;
},
backButtonAction() {
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
},
async forwardButtonAction() {
this.forwardClicked = true;
await this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
this.paymentMethod,
@ -515,6 +519,7 @@ export default {
},
false
);
this.dispatchStoreAction(storeActions.SAVE_IS_RECAL_ACK_OPT_IN, this.isRecalAckOptIn);
if (this.paymentMethod == paymentMethods.LATER) {
// this creates the final work order
await submitWorkOrder({ pageNameToLog: "payment-method", submitAfterSave: true });
@ -641,6 +646,19 @@ export default {
return null;
}
},
showPaymentMethodQuestions() {
if (this.isInsurance) {
if (this.isPiaEnabled && this.totalAmountDue > 0) {
return true;
}
} else {
if (this.isPiaEnabled && this.totalAmountDue > 0 && !this.hasRecal) {
return true;
}
}
return false;
},
totalAmountDue() {
return baseMixin.methods.getAmountDue(this.lineItems);
},

View file

@ -666,7 +666,7 @@ export default {
console.log(new Date() + ": Sent hybrid: new hop no applepay");
}
if (this.paymentType == "cc") {
if (this.paymentType == "cc" || this.paymentType == "PayNow") {
iframe.contentWindow.postMessage("CreditCardChosen", "*");
console.log(new Date() + ": Sent creditcard");
} else if (this.paymentType == "ap") {
@ -694,41 +694,43 @@ export default {
if (event.data.indexOf("afterpayClosed") > -1) {
this.backButtonAction();
}
if (event.data.indexOf("creditCardSubmit") > -1) {
console.log(new Date() + ": Payment method credit card selected");
this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
paymentMethods.CREDIT_CARD,
false
);
this.updatePaymentMethod(paymentMethods.CREDIT_CARD);
this.setUIBlock(true);
}
if (event.data.indexOf("afterpayPaymentReceived") > -1) {
console.log(new Date() + ": Payment method afterpay selected");
this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
paymentMethods.AFTERPAY,
false
);
this.updatePaymentMethod(paymentMethods.AFTERPAY);
}
if (event.data.indexOf("applepayOpened") > -1) {
console.log(new Date() + ": Payment method applepay selected");
this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
paymentMethods.APPLE_PAY,
false
);
this.updatePaymentMethod(paymentMethods.APPLE_PAY);
}
if (event.data.indexOf("showLoaderForPaypal") > -1) {
console.log(new Date() + ": Payment method paypal selected");
this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
paymentMethods.PAYPAL,
false
);
this.updatePaymentMethod(paymentMethods.PAYPAL);
}
}
},
updatePaymentMethod(paymentMethod) {
// if the payment method is not set yet, then set it based on what HOP sends us
if (
store.getters.order.payment.piaType == paymentMethods.PAY_NOW ||
store.getters.order.payment.piaType == paymentMethods.NONE
) {
console.log(new Date() + " UPDATE PaymentMethod from HOP:" + paymentMethod);
this.dispatchStoreAction(
storeActions.SAVE_PAYMENT_METHOD_CHOICE,
paymentMethod,
false
);
}
},
setIFrameListener() {
window.addEventListener("message", (event) =>
this.handleIFrameContentWindowMessage(event)

View file

@ -52,9 +52,7 @@ export default {
name: "afterpay-modal-banner",
props: {
cmsWidgetName: String,
availableLineItems: Array,
lineItems: Array,
activePromos: null,
},
data() {
return {};
@ -65,9 +63,6 @@ export default {
getInlineAltText,
},
computed: {
nullSafeLineItems() {
return this.availableLineItems ?? [];
},
imageUrl() {
return this.getCmsContent(this.cmsWidgetName, "Image");
},
@ -81,8 +76,13 @@ export default {
return this.getCmsContent(this.cmsWidgetName, "SubheaderText");
},
afterpayPrice() {
let allLineItems = getArrayOfAllLineItems(this.lineItems);
if (this.lineItems.promos) {
allLineItems = allLineItems?.filter((item) => item.partType !== "PROMO_DISCOUNT");
}
let price = baseMixin.methods.getTierOnePackagePrice(
baseMixin.methods.filterOutFees(this.nullSafeLineItems)
baseMixin.methods.filterOutFees(allLineItems)
);
let vapsLineItemsForSelectedPackage = this.lineItems.vaps;
@ -90,9 +90,12 @@ export default {
price += baseMixin.methods.getTotalLineItemPrice(lineItem);
});
if (this.activePromos) {
if (this.lineItems.promos) {
let allLineItems = getArrayOfAllLineItems(this.lineItems);
const promos = getPromosThatMatchLineItemsOnOrder(this.activePromos, allLineItems);
const promos = getPromosThatMatchLineItemsOnOrder(
this.lineItems.promos,
allLineItems
);
promos.forEach((promo) => {
price += baseMixin.methods.getTotalLineItemPrice(promo);
});

View file

@ -45,8 +45,6 @@
<afterpayModalBanner
v-if="!isInsuranceSelected && !isRecalibrationOnOrder"
cmsWidgetName="AfterpayModalWidget"
:activePromos="lineItems.promos"
:availableLineItems="availableLineItems"
:lineItems="lineItems" />
<recalDisclaimer
@ -126,6 +124,7 @@ import { experimentSettings } from "@/constants/experiments";
import { partTypeStrings } from "@/constants/part-type-strings";
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
import { nextTick } from "vue";
import { packageNames } from "@/constants/package-names";
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
export default {
@ -419,6 +418,30 @@ export default {
);
}
},
attachCustomEvents() {
this.prependActionToMethod(this, this.forwardButtonAction, () => {
if (!this.isInsuranceSelected && this.lineItems.vaps?.length == 0) {
const tierOnePrice =
this.lineItems.promos?.length > 0
? this.$refs.servicePackage.getDiscountedPackagePriceString(
packageNames.TIER_ONE,
false
)
: this.$refs.servicePackage.getPackagePriceString(
packageNames.TIER_ONE
);
this.pushEventToGA(
this.$route.query[this.queryStrings.FMG_PAGE],
this.GaActions.CASH_QUOTE_DISPLAYED,
tierOnePrice,
true
);
}
});
},
},
mounted() {
this.attachCustomEvents();
},
watch: {
lineItemsCloneForWatcher: {

View file

@ -75,21 +75,23 @@ export default {
const servicePackageDiscountPartInSelectedPackage =
this.getServicePackageDiscountPartForSelectedPackage(newValue);
let supportingItems = this.supportingLineItems;
if (servicePackageDiscountPartInSelectedPackage?.length > 0) {
supportingItems?.push(servicePackageDiscountPartInSelectedPackage[0]);
} else {
if (
supportingItems?.length > 0 &&
containsLineItemWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
supportingItems
)
) {
supportingItems = supportingItems.filter(
(item) => item.partType !== partTypeStrings.SERVICE_PACKAGE_DISCOUNT
);
}
if (
containsLineItemWithPartType(
partTypeStrings.SERVICE_PACKAGE_DISCOUNT,
supportingItems
)
) {
supportingItems = supportingItems.filter(
(item) => item.partType !== partTypeStrings.SERVICE_PACKAGE_DISCOUNT
);
}
if (
servicePackageDiscountPartInSelectedPackage?.length > 0 &&
supportingItems != null
) {
supportingItems.push(servicePackageDiscountPartInSelectedPackage[0]);
}
this.$emit("servicePackageDiscountSelected", supportingItems);
},
},

View file

@ -178,13 +178,18 @@ export default {
border-radius: 0.5rem;
overflow: hidden;
min-height: 60px;
max-height: 100px;
@include media-breakpoint-up(md) {
max-height: 500px;
}
transition: max-height 0.25s ease-in;
&.has-subheader {
min-height: 80px;
}
&.has-text {
border-radius: 0 0 0.5rem 0.5rem;
border: 1px solid #469d2a; //Temp color
border: 1px solid $green;
}
&:before {
@ -288,7 +293,6 @@ export default {
width: 100%;
text-align: center;
font-size: 1.125rem;
color: $gray-500;
}
span.strikethrough-price {
text-decoration: line-through;
@ -307,7 +311,7 @@ export default {
}
span {
&.service-package-discount {
color: #469d2a; //Temp color
color: $green;
text-align: end;
font-weight: 500;
font-size: 13px;
@ -321,7 +325,7 @@ export default {
padding-right: 2px;
}
div.discount-price {
color: #469d2a; //Temp color
color: $green;
font-weight: 600;
font-size: 1.625rem;
}
@ -371,7 +375,7 @@ export default {
display: flex;
border-top-right-radius: 0.5rem;
border-top-left-radius: 0.5rem;
background-color: #469d2a; //Temp color
background-color: $green;
align-items: center;
justify-content: center;
width: 100%;

View file

@ -60,19 +60,3 @@ export function militaryToTwelveHourTime(timeString) {
return `${hours}:${minutes} ${meridianNotation}`;
}
export function getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
const isLongAppointment = durationMaximum >= 120;
const isDurationRange = durationMinimum !== durationMaximum;
const adjustedMinimum = isLongAppointment ? durationMinimum / 60 : durationMinimum;
const adjustedMaximum = isLongAppointment ? durationMaximum / 60 : durationMaximum;
const durationText = isDurationRange
? `${adjustedMinimum} - ${adjustedMaximum}`
: adjustedMinimum;
const unitText = isLongAppointment ? "hours" : "minutes";
return `${durationText} ${unitText}`;
}

View file

@ -51,8 +51,8 @@ import { deepClone } from "@/helpers/object-helper";
import {
convertDateStringToDate,
militaryToTwelveHourTime,
getDisplayTextForDurationLength,
} from "@/layouts/schedule/helpers/schedule-helper";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
// Validation - TODO: Move this somewhere more global?
import { defineRule, useField } from "vee-validate";

View file

@ -24,6 +24,11 @@
{{ errorMessage }}
</span>
</div>
<textBlock
v-if="mobileFeeApplies"
:customText="mobileFeeText"
cmsWidgetName="MobileFeeDisclaimerWidget"
typeStyle="caption" />
</div>
<modal
:ref="modalName"
@ -149,6 +154,7 @@ export default {
alertInvalidZipWidgetName: String,
customComponentId: String,
validationRules: String,
mobileFeeApplies: Boolean,
},
computed: {
mobileLocationLinkPromptText() {
@ -170,6 +176,21 @@ export default {
}
return this.getCmsContent(this.linkWidgetName, "BodyText");
},
mobileFeeText() {
const cmsContentText = this.getCmsContent("MobileFeeDisclaimerWidget", "Text");
return cmsContentText.replaceAll("{custom:mobileFee}", this.mobileFee);
},
mobileFee() {
if (!this.mobileFeePart) {
return 0;
}
return (
this.mobileFeePart.laborAmount +
this.mobileFeePart.sellingPrice +
this.mobileFeePart.kitPrice
);
},
modalName() {
return "MobileLocationModalWidget";
},

View file

@ -61,7 +61,7 @@
ref="alertMobileFeeFree"
class="my-5"
cmsWidgetName="AlertMobileFeeFreeWidget"
v-if="isServiceableMobile && !isInsurance"
v-if="showMobileFreeAlert"
alertClass="alert-success" />
</div>
</div>
@ -87,6 +87,7 @@
v-if="selectedAppointmentType === 'Mobile'"
v-model="mobileLocationQuestions"
:mobileFeePart="mobileFeePart"
:mobileFeeApplies="mobileFeeApplies"
@updated-mobile-fee-part="setMobileFeePart"
@updated-serviceability="setServiceabilityDetails"
@updated-contains-military-base="setContainsMilitaryBase"
@ -308,12 +309,22 @@ export default {
}
},
mobileFeeApplies() {
if (this.mobileFeePart) {
if (
this.mobileFeePart?.laborAmount > 0 ||
this.mobileFeePart?.sellingPrice > 0 ||
this.mobileFeePart?.kitPrice > 0
) {
return true;
} else {
return false;
}
},
showMobileFreeAlert() {
if (this.isServiceableMobile && !this.isInsurance && !this.mobileFeeApplies) {
return true;
}
return false;
},
isServiceableInshop() {
if (this.isRecalibrationServiceableInshop !== null) {
return this.isGlassServiceableInshop && this.isRecalibrationServiceableInshop;
@ -376,6 +387,14 @@ export default {
) {
return true;
} else {
console.log(
"ins: servce-location invalid prereq:" +
store.getters.payment.parentAccountNumber +
":" +
store.getters.order.policy.policyNumber +
":" +
store.getters.order.serviceLocation.zipCode
);
return false;
}
} else {
@ -385,6 +404,12 @@ export default {
) {
return true;
} else {
console.log(
"cash: servce-location invalid prereq:" +
JSON.stringify(store.getters.lineItems.supportingItems) +
":" +
store.getters.order.serviceLocation.zipCode
);
return false;
}
}

View file

@ -73,6 +73,7 @@ import { Form } from "vee-validate";
import store from "@/store";
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
import baseMixin from "@/mixins/base-mixin.js";
import { partTypeStrings } from "@/constants/part-type-strings";
export default {
name: "vehicle-parts",

View file

@ -202,9 +202,10 @@ export default {
return formValidateResponse?.valid;
},
showApplePay() {
if (window.ApplePaySession && window.ApplePaySession.canMakePayments()) {
var iOSversion = this.getiOSversion();
if (iOSversion && iOSversion[0] >= 17) {
var iOSversion = this.getiOSversion();
var isMacOS = navigator.platform.indexOf("Mac") !== -1;
if (isMacOS || (iOSversion && iOSversion[0] >= 17)) {
if (window.ApplePaySession && window.ApplePaySession.canMakePayments()) {
return true;
}
}

View file

@ -34,6 +34,7 @@ export default {
const singlePart = glass.parts[0];
reducedGlassParts.push({
partNumber: singlePart.partNumber,
basePartNumber: singlePart.basePartNumber,
description: singlePart.description,
color: singlePart.color,
partType: singlePart.partType,

View file

@ -18,6 +18,7 @@ import {
getFunnelCookie,
updateSessionIdCookie,
deleteFunnelCookie,
getAffiliateCookies,
} from "@/helpers/heritage-integration/cookie-helper";
import { loadSessionIfPresent, saveSession } from "@/helpers/heritage-integration/order-helper";
import {
@ -94,7 +95,15 @@ const routes = [
);
updateOrCreateFunnelCookie();
}
//Update external parameter state
updateExternalParameterState();
//Affiliate Cookies
const affiliateCookies = getAffiliateCookies();
if (affiliateCookies != null && affiliateCookies.length > 0) {
store.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
}
const loadSessionResponse = await loadSessionIfPresent(
to.query.isInsurance != null
? to.query.isInsurance == "true"

View file

@ -24,8 +24,8 @@ import { partTypeStrings } from "@/constants/part-type-strings";
import {
convertDateStringToDate,
militaryToTwelveHourTime,
getDisplayTextForDurationLength,
} from "@/layouts/schedule/helpers/schedule-helper";
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
import { paymentMethods } from "@/constants/payment-method-constants";
import {
getPromoCodeWithoutBundleIdentifier,
@ -160,6 +160,7 @@ const getDefaultState = () => {
customerPortalLoginToken: null,
lockToken: null,
settledTenderAmount: 0,
isRecalAckOptIn: false,
},
applicationUser: {
eventBus: [],
@ -171,6 +172,7 @@ const getDefaultState = () => {
lastPageVisited: null,
experiments: [],
triggeredSiteEntry: false,
affiliateCookies: [],
},
};
};
@ -294,6 +296,9 @@ export const mutations = {
updateSettledTenderAmount(state, settledTenderAmount) {
state.order.settledTenderAmount = settledTenderAmount;
},
updateIsRecalAckOptIn(state, isRecalAckOptIn) {
state.order.isRecalAckOptIn = isRecalAckOptIn;
},
updateCCToken(state, ccToken) {
state.order.payment.ccToken.subscriptionId = ccToken.subscriptionId;
state.order.payment.ccToken.expMonth = ccToken.expMonth;
@ -592,6 +597,7 @@ export const mutations = {
state.order.referralCorrelationId = sessionInformation.order.referralCorrelationId;
state.order.eon = sessionInformation.order.eon;
state.order.customerPortalLoginToken = sessionInformation.order.CustomerPortalLoginToken;
state.order.isRecalAckOptIn = sessionInformation.order.isRecalAckOptIn;
if (state.order.vehicle.vin !== sessionInformation.order.vehicle?.vin) {
state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null;
@ -728,6 +734,9 @@ export const mutations = {
updateTriggeredSiteEntry(state, wasSiteEntryTriggered) {
state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered;
},
updateAffiliateCookies(state, affiliateCookies) {
state.applicationUser.affiliateCookies = affiliateCookies;
},
};
// Export Getters
@ -1259,7 +1268,8 @@ export const actions = {
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
referralSequenceNumber: referralSequenceNumber,
parentAccountNumber: parentAccountNumber,
parentAccountNumber:
parentAccountNumber ?? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
};
return globalMethods
@ -1308,7 +1318,8 @@ export const actions = {
shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser,
referralSequenceNumber: referralSequenceNumber,
parentAccountNumber: parentAccountNumber,
parentAccountNumber:
parentAccountNumber ?? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
};
return globalMethods
@ -1407,6 +1418,8 @@ export const actions = {
const glassArray = damage.glassToReplace;
const zipCode = order.serviceLocation.zipCode;
const vin = vehicle.vin;
const serviceType = order.serviceLocation?.appointmentType;
const referralSeqNumber = order.referralSequenceNumber;
// create a new array to avoid mutating state
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
@ -1419,6 +1432,8 @@ export const actions = {
glassPieces: glassArrayForPayload,
zip: zipCode,
vin: vin,
serviceType: serviceType,
referralSeqNumber: referralSeqNumber,
},
logApiCall: true,
pageNameToLog: pageNameToLog,
@ -1443,6 +1458,8 @@ export const actions = {
const resultsArray = damage.partQuestionAnswers;
const zipCode = order.serviceLocation.zipCode;
const vin = vehicle.vin;
const serviceType = order.serviceLocation?.appointmentType;
const referralSeqNumber = order.referralSequenceNumber;
// create a new array to avoid mutating state
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
@ -1457,6 +1474,8 @@ export const actions = {
answerResults: resultsArrayForPayload,
zip: zipCode,
vin: vin,
serviceType: serviceType,
referralSeqNumber: referralSeqNumber,
},
logApiCall: true,
pageNameToLog: pageNameToLog,
@ -1797,6 +1816,8 @@ export const actions = {
// create a new array to avoid mutating state
const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace);
//affiliate cookie save only when submitAfterSave
const affiliateCookies = submitAfterSave ? applicationUser.affiliateCookies : null;
return globalMethods.callHttpClient({
method: endpoints.SaveSession.method,
@ -1810,6 +1831,7 @@ export const actions = {
lastPage: applicationUser.lastPageVisited,
pageData: applicationUser.pageData,
savedSessionId: applicationUser.savedSessionId,
affiliateCookies: affiliateCookies,
},
order: {
vehicle: {
@ -1926,6 +1948,7 @@ export const actions = {
eon: order.eon,
createDeleteStatusWorkOrderForPia: createDeleteStatusWorkOrderForPia,
lockToken: order.lockToken,
isRecalAckOptIn: order.isRecalAckOptIn,
},
},
logApiCall: true,
@ -2311,6 +2334,10 @@ export const actions = {
context.commit(storeMutations.UPDATE_PIA_TYPE, isPia ? paymentMethod : null);
},
saveIsRecalAckOptIn(context, isRecalAckOptIn) {
context.commit(storeMutations.UPDATE_IS_RECAL_ACK_OPT_IN, isRecalAckOptIn);
},
saveParentAccountNumber(context, parentAccountNumber) {
context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccountNumber);
},
@ -2779,6 +2806,7 @@ export const actions = {
const submittedOrder = context.state.order;
const experiments = context.state.applicationUser.experiments;
const affiliateCookies = context.state.applicationUser.affiliateCookies;
// set to local storage
window.sessionStorage.setItem("submittedOrder", JSON.stringify(submittedOrder));
@ -2794,6 +2822,10 @@ export const actions = {
//clear externalParameter session storage
window.sessionStorage.removeItem("externalParameterState");
//restore affiliate cookies
context.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
},
resetSubmittedOrder(context) {