From e64ad9e35b8f8c35e80aa7d2ad636639c6ceb4ca Mon Sep 17 00:00:00 2001 From: Shahzaib Date: Fri, 5 Jan 2024 12:48:06 +0800 Subject: [PATCH] [COJ] WALL-2735 / CRS confirmation on real account creation (#12499) * chore: crs confirmation checkbox in real account creation * chore: crs confirmation checkbox in real account creation * chore: crs confirmation in mt5 account creation for non-npj countries * chore: reset css for crs checkbox --- .../__tests__/personal-details-form.spec.tsx | 20 ++++++++++++- .../forms/personal-details-form.jsx | 15 ++++++++++ .../src/Configs/personal-details-config.ts | 18 +++++++++++ .../cfd-personal-details-form.spec.js | 5 ++++ .../Components/cfd-personal-details-form.tsx | 30 +++++++++++++++++++ .../RealAccountSignup/account-wizard.jsx | 1 + 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx b/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx index cffedda0aa1d..7722a6cba755 100644 --- a/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx +++ b/packages/account/src/Components/forms/__tests__/personal-details-form.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Formik } from 'formik'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import PersonalDetailsForm from '../personal-details-form'; @@ -52,4 +52,22 @@ describe('PersonalDetailsForm', () => { expect(mr_radio_input).not.toBeChecked(); expect(ms_radio_input).toBeChecked(); }); + + it('should display crs confirmation checkbox if tax residence & tin fields are filled', () => { + render( + + + + ); + + fireEvent.change(screen.getByTestId('tax_residence'), { target: { value: 'Afghanistan' } }); + fireEvent.change(screen.getByTestId('tax_identification_number'), { target: { value: '1234567890' } }); + + expect( + screen.queryByLabelText(/i confirm that my tax information is accurate and complete/i) + ).toBeInTheDocument(); + }); }); diff --git a/packages/account/src/Components/forms/personal-details-form.jsx b/packages/account/src/Components/forms/personal-details-form.jsx index dfbdcf3da5cc..bdf2c13d5f99 100644 --- a/packages/account/src/Components/forms/personal-details-form.jsx +++ b/packages/account/src/Components/forms/personal-details-form.jsx @@ -593,6 +593,21 @@ const PersonalDetailsForm = props => { required /> )} + {values?.tax_residence && values?.tax_identification_number && ( + + } + label_font_size={isMobile() ? 'xxs' : 'xs'} + onChange={e => { + setFieldValue('crs_confirmation', e.target.checked, true); + setFieldTouched('crs_confirmation', true); + }} + has_error={!!(touched?.crs_confirmation && errors?.crs_confirmation)} + /> + )} )} diff --git a/packages/account/src/Configs/personal-details-config.ts b/packages/account/src/Configs/personal-details-config.ts index f1ec4b1c3e3e..440fa18d1a98 100644 --- a/packages/account/src/Configs/personal-details-config.ts +++ b/packages/account/src/Configs/personal-details-config.ts @@ -190,6 +190,24 @@ export const personal_details_config = ({ supported_in: ['svg'], rules: [], }, + crs_confirmation: { + default_value: false, + supported_in: ['svg'], + rules: [ + [ + ( + value: string, + options: Record, + { tax_identification_number }: { tax_identification_number: string } + ) => { + // need the confirmation in case of both Tax residence and TIN are available + // only checking for TIN as we already have a rule for Tax residence to be filled if TIN field is filled + return tax_identification_number ? value : true; + }, + localize('CRS confirmation is required.'), + ], + ], + }, }; // Need to check if client is high risk (only have SVG i.e. China & Russia) diff --git a/packages/cfd/src/Components/__tests__/cfd-personal-details-form.spec.js b/packages/cfd/src/Components/__tests__/cfd-personal-details-form.spec.js index 5cdd4e51ee5d..9e3fe15d9ab4 100644 --- a/packages/cfd/src/Components/__tests__/cfd-personal-details-form.spec.js +++ b/packages/cfd/src/Components/__tests__/cfd-personal-details-form.spec.js @@ -255,6 +255,11 @@ describe('', () => { const income_earning = within(screen.getByRole('list')).getByText('Income Earning'); fireEvent.click(income_earning); + const crs_confirmation_checkbox = screen.getByRole('checkbox', { + name: /i confirm that my tax information is accurate and complete/i, + }); + fireEvent.click(crs_confirmation_checkbox); + await waitFor(() => { expect(screen.queryByText(citizenship_required_error)).not.toBeInTheDocument(); expect(screen.queryByText(tax_residence_required_error)).not.toBeInTheDocument(); diff --git a/packages/cfd/src/Components/cfd-personal-details-form.tsx b/packages/cfd/src/Components/cfd-personal-details-form.tsx index 4faf18840ee7..cff930c0490a 100644 --- a/packages/cfd/src/Components/cfd-personal-details-form.tsx +++ b/packages/cfd/src/Components/cfd-personal-details-form.tsx @@ -16,6 +16,7 @@ import { SelectNative, Text, ThemedScrollbars, + Checkbox, } from '@deriv/components'; import { isDeepEqual, isDesktop, isMobile } from '@deriv/shared'; import { Localize, localize } from '@deriv/translations'; @@ -149,6 +150,7 @@ const validatePersonalDetails = ({ (v: string) => (tin_regex ? tin_regex?.some(regex => v.match(regex)) : true), () => !!values.tax_residence, ]; + validations.crs_confirmation = [(v: string) => !!v]; } const mappedKey: { [key: string]: string } = { citizen: localize('Citizenship'), @@ -156,6 +158,7 @@ const validatePersonalDetails = ({ tax_identification_number: localize('Tax identification number'), account_opening_reason: localize('Account opening reason'), place_of_birth: localize('Place of birth'), + crs_confirmation: localize('CRS confirmation'), }; const field_error_messages = (field_name: string): string[] => [ @@ -206,6 +209,10 @@ const submitForm: TSubmitForm = (values, actions, idx, onSubmit, is_dirty, resid place_of_birth_text: values.place_of_birth, }); + if (values.crs_confirmation) { + delete values.crs_confirmation; + } + const payload = { ...values, citizen: citizen?.value || '', @@ -496,6 +503,29 @@ const CFDPersonalDetailsForm = ({ )} + {is_tin_mandatory && values?.tax_identification_number && ( + + {({ + field, + form: { handleBlur, setFieldValue }, + meta: { touched, error }, + }: FieldProps) => ( + + } + label_font_size={isMobile() ? 'xxs' : 'xs'} + onChange={(e: React.FormEvent) => + setFieldValue(field.name, e.currentTarget.checked, true) + } + onBlur={handleBlur} + has_error={!!(touched && error)} + /> + )} + + )} diff --git a/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx b/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx index 3f250cb344bb..238c6c68b118 100644 --- a/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx +++ b/packages/core/src/App/Containers/RealAccountSignup/account-wizard.jsx @@ -275,6 +275,7 @@ const AccountWizard = observer(props => { delete clone?.agreed_tnc; delete clone?.agreed_tos; delete clone?.confirmation_checkbox; + delete clone?.crs_confirmation; // BE does not accept empty strings for TIN // so we remove it from the payload if it is empty in case of optional TIN field