Skip to content
Draft
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
19 changes: 19 additions & 0 deletions example/src/ContractorOnboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@
<div className='contractor-onboarding-form-layout'>
<SelectCountryStep
onSubmit={(payload: SelectCountryFormPayload) =>
console.log('payload', payload)

Check warning on line 123 in example/src/ContractorOnboarding.tsx

View workflow job for this annotation

GitHub Actions / Checks and Tests

Unexpected console statement. Only these console methods are allowed: warn, error
}
onSuccess={(response: SelectCountrySuccess) =>
console.log('response', response)

Check warning on line 126 in example/src/ContractorOnboarding.tsx

View workflow job for this annotation

GitHub Actions / Checks and Tests

Unexpected console statement. Only these console methods are allowed: warn, error
}
onError={({
error,
Expand Down Expand Up @@ -369,6 +369,7 @@
};

export const ContractorOnboardingWithProps = ({
countryCode,
employmentId,
externalId,
}: ContractorOnboardingFormData) => {
Expand All @@ -383,6 +384,8 @@
render={OnBoardingRender}
employmentId={employmentId}
externalId={externalId}
countryCode={countryCode}
skipSteps={countryCode ? ['select_country'] : undefined}
options={{
jsfModify: {
contract_details: {
Expand Down Expand Up @@ -410,6 +413,7 @@
employmentId:
import.meta.env.VITE_CONTRACTOR_MANAGEMENT_EMPLOYMENT_ID || '', // use your own employment ID
externalId: '',
countryCode: '',
});
const [showOnboarding, setShowOnboarding] = useState(false);

Expand Down Expand Up @@ -454,6 +458,21 @@
className='onboarding-form-input'
/>
</div>
<div className='onboarding-form-group'>
<label htmlFor='countryCode' className='onboarding-form-label'>
Country Code:
</label>
<input
id='countryCode'
type='text'
value={formData.countryCode}
onChange={(e) =>
setFormData((prev) => ({ ...prev, countryCode: e.target.value }))
}
placeholder='Enter Country Code'
className='onboarding-form-input'
/>
</div>
<button type='submit' className='onboarding-form-button'>
Start Onboarding
</button>
Expand Down
11 changes: 6 additions & 5 deletions src/flows/ContractorOnboarding/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export const useUpdateUKandSaudiFields = (
return {
mutateAsync: async ({ employmentId }: { employmentId: string }) => {
const {
saudi_nationality_status: saudiNationalityStatus,
nationality_status: nationalityStatus,
ir35: ir35Status,
ir35_sds_file: ir35SdsFile,
} = parsedValues;
Expand All @@ -338,9 +338,9 @@ export const useUpdateUKandSaudiFields = (
ir_35: ir35Status,
},
};
const saudiContractDetailsPayload = {
const nationalityContractDetailsPayload = {
contract_document: {
nationality: saudiNationalityStatus,
nationality: nationalityStatus,
},
};
if (ir35Status) {
Expand All @@ -358,10 +358,11 @@ export const useUpdateUKandSaudiFields = (
}
return Promise.resolve();
}
if (saudiNationalityStatus) {
// nationality status is sent for the countries SAU, KWT, OMN, QAT
if (nationalityStatus) {
return createContractorContractDocumentMutationAsync({
employmentId: employmentId,
payload: saudiContractDetailsPayload,
payload: nationalityContractDetailsPayload,
});
}

Expand Down
19 changes: 16 additions & 3 deletions src/flows/ContractorOnboarding/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,18 @@ export const useContractorOnboarding = ({
}
}, [contractDocuments, internalContractDocumentId]);

const countryName = useMemo(() => {
// TODO: get the country name from the correct countries endpoint for contractors
const countryNames = {
SAU: 'Saudi Arabia',
KWT: 'Kuwait',
OMN: 'Oman',
QAT: 'Qatar',
BHR: 'Bahrain',
};
return countryNames[internalCountryCode as keyof typeof countryNames];
}, [internalCountryCode]);

const {
data: basicInformationForm,
isLoading: isLoadingBasicInformationForm,
Expand All @@ -317,6 +329,7 @@ export const useContractorOnboarding = ({
options: {
jsfModify: buildBasicInformationJsfModify(
internalCountryCode as string,
countryName,
options,
),
queryOptions: {
Expand Down Expand Up @@ -457,7 +470,7 @@ export const useContractorOnboarding = ({
...onboardingInitialValues,
...employmentBasicInformation,
ir35: employment?.contract_details?.ir_35,
saudi_nationality_status: employment?.contract_details?.nationality,
nationality_status: employment?.contract_details?.nationality,
...(convertedIr35File && {
ir35_sds_file: [convertedIr35File],
}),
Expand Down Expand Up @@ -704,7 +717,7 @@ export const useContractorOnboarding = ({
if (isEmploymentNotLoaded || hasChangedCountry) {
const basicInformationParsedValues = omit(
parsedValues,
'saudi_nationality_status',
'nationality_status',
'ir35',
'ir35_sds_file',
);
Expand All @@ -731,7 +744,7 @@ export const useContractorOnboarding = ({
} else if (internalEmploymentId) {
const basicInformationParsedValues = omit(
parsedValues,
'saudi_nationality_status',
'nationality_status',
'ir35',
'ir35_sds_file',
);
Expand Down
26 changes: 18 additions & 8 deletions src/flows/ContractorOnboarding/jsfModify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ContractPreviewHeader } from '@/src/flows/ContractorOnboarding/componen
import { ContractPreviewStatement } from '@/src/flows/ContractorOnboarding/components/ContractPreviewStatement';
import { contractorStandardProductIdentifier } from '@/src/flows/ContractorOnboarding/constants';
import { ContractorOnboardingFlowProps } from '@/src/flows/ContractorOnboarding/types';
import { isNationalityCountryCode } from '@/src/flows/ContractorOnboarding/utils';
import { JSFModify } from '@/src/flows/types';
import { FILE_TYPES, MAX_FILE_SIZE } from '@/src/lib/uploadConfig';
import { JSFCustomComponentProps } from '@/src/types/remoteFlows';
Expand Down Expand Up @@ -76,17 +77,20 @@ export const buildContractDetailsJsfModify = (
/**
* Builds the basic information jsf modify for the contractor onboarding flow
* @param countryCode - The country code to use for the onboarding.
* @param countryName - The name of the country to use for the onboarding.
* @param options - The options to use for the onboarding.
* @returns The basic information jsf modify for the contractor onboarding flow
*/
export const buildBasicInformationJsfModify = (
countryCode: string,
countryName: string | undefined,
options: ContractorOnboardingFlowProps['options'] | undefined,
) => {
const isSaudiArabia = countryCode === 'SAU';
const isUk = countryCode === 'GBR';
const hasNationalityStatusField = isNationalityCountryCode(countryCode);

if (!isSaudiArabia && !isUk) {
if (!isSaudiArabia && !isUk && !hasNationalityStatusField) {
return options?.jsfModify?.basic_information;
}

Expand Down Expand Up @@ -169,13 +173,20 @@ export const buildBasicInformationJsfModify = (
};
}

const label = isSaudiArabia
? 'Is your contractor a Saudi Arabia national, or a non-Saudi national contracting via a local business entity or under a Special Privilege Iqama visa?'
: `Is the contractor a ${countryName} national, or a non-${countryName} national contracting through their local business entity?`;

const descriptionNonNationalRadio = isSaudiArabia
? `Please be aware that contracting with non-Saudi Arabia nationals that are not operating as a company or under a Special Privilege Iqama visa can lead to fines for operating without proper work authorization. If you are concerned, please speak with the Contractor and/or local Saudi Arabia counsel to ensure compliance.`
: `Be aware that the Contractor must be a ${countryName} national, or a non-${countryName} national operating through their company to comply with the legal requirements for performing services and deliverables as a contractor in ${countryName}. If you are concerned, speak with the Contractor and/or local counsel to ensure compliance.`;

return {
...options?.jsfModify?.basic_information,
create: {
...options?.jsfModify?.basic_information?.create,
saudi_nationality_status: {
title:
'Is your contractor a Saudi Arabia national, or a non-Saudi national contracting via a local business entity or under a Special Privilege Iqama visa?',
nationality_status: {
title: label,
description: '',
type: 'string',
oneOf: [
Expand All @@ -186,8 +197,7 @@ export const buildBasicInformationJsfModify = (
},
{
const: 'non-national',
description:
'Please be aware that contracting with non-Saudi Arabia nationals that are not operating as a company or under a Special Privilege Iqama visa can lead to fines for operating without proper work authorization. If you are concerned, please speak with the Contractor and/or local Saudi Arabia counsel to ensure compliance.',
description: descriptionNonNationalRadio,
title: 'No',
},
],
Expand All @@ -196,9 +206,9 @@ export const buildBasicInformationJsfModify = (
},
},
},
required: ['saudi_nationality_status'],
required: ['nationality_status'],
orderRoot: (originalOrder: string[]) => {
return [...originalOrder, 'saudi_nationality_status'];
return [...originalOrder, 'nationality_status'];
},
};
};
Expand Down
9 changes: 9 additions & 0 deletions src/flows/ContractorOnboarding/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,12 @@ export const isCMOrCMPlus = (subscription: string | undefined): boolean => {
subscription === contractorPlusProductIdentifier
);
};

const NATIONALITY_COUNTRY_CODES = ['SAU', 'KWT', 'OMN', 'QAT', 'BHR'];

/**
* Checks if the country code is a country code that requires nationality status field
*/
export const isNationalityCountryCode = (countryCode: string) => {
return NATIONALITY_COUNTRY_CODES.includes(countryCode);
};
Loading