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
2 changes: 2 additions & 0 deletions src/components/SubStepForms/AgreementsFullStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@
[inputIDs.agreeToTermsAndConditions, inputIDs.authorizedToBindClientToAgreement, inputIDs.consentToPrivacyNotice, inputIDs.provideTruthfulInformation, stepFields, translate],
);

console.log('AgreementsFullStep render', {defaultValues, formID, inputIDs, isLoading, stepNames, startStepIndex, bankStatementInputID, bankStatementDefaultValue});

Check failure on line 174 in src/components/SubStepForms/AgreementsFullStep.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unexpected console statement. Only these console methods are allowed: debug, error

Check failure on line 174 in src/components/SubStepForms/AgreementsFullStep.tsx

View workflow job for this annotation

GitHub Actions / ESLint check

Unexpected console statement. Only these console methods are allowed: debug, error

return (
<InteractiveStepWrapper
wrapperID="AgreementsFullStep"
Expand Down
2 changes: 2 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4148,6 +4148,8 @@ ${amount} für ${merchant} – ${date}`,
proofOfBeneficialOwner: 'Nachweis des wirtschaftlich Berechtigten',
proofOfBeneficialOwnerDescription:
'Bitte legen Sie eine unterzeichnete Bescheinigung und ein Organigramm vor, ausgestellt von einem vereidigten Buchhalter, Notar oder Rechtsanwalt, die den Besitz von 25 % oder mehr des Unternehmens bestätigt. Das Dokument muss innerhalb der letzten drei Monate datiert sein und die Lizenznummer der unterzeichnenden Person enthalten.',
proofOfBeneficialOwnerDescriptionCA:
'Bitte legen Sie Ihr Schedule 50 (Shareholder Information) aus Ihrer letzten T2-Körperschaftsteuererklärung vor, das jede Person aufführt, die 25 % oder mehr des Unternehmens besitzt.',
copyOfID: 'Kopie des Ausweises des wirtschaftlich Berechtigten',
copyOfIDDescription: 'Beispiele: Reisepass, Führerschein usw.',
proofOfAddress: 'Adressnachweis für wirtschaftlich Berechtigte',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/el.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4210,6 +4210,8 @@ ${amount} για ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Απόδειξη πραγματικού δικαιούχου',
proofOfBeneficialOwnerDescription:
'Παρακαλούμε προσκομίστε υπογεγραμμένη βεβαίωση και οργανόγραμμα από ορκωτό λογιστή, συμβολαιογράφο ή δικηγόρο που να επιβεβαιώνουν την κατοχή του 25% ή περισσότερο της επιχείρησης. Πρέπει να φέρουν ημερομηνία εντός των τελευταίων τριών μηνών και να περιλαμβάνουν τον αριθμό άδειας του υπογράφοντος.',
proofOfBeneficialOwnerDescriptionCA:
'Παρακαλούμε υποβάλετε το Schedule 50 (Shareholder Information) από την πιο πρόσφατη εταιρική φορολογική δήλωση T2, όπου εμφανίζεται κάθε άτομο που κατέχει 25% ή περισσότερο της επιχείρησης.',
copyOfID: 'Αντίγραφο ταυτότητας πραγματικού δικαιούχου',
copyOfIDDescription: 'Παραδείγματα: διαβατήριο, άδεια οδήγησης κ.λπ.',
proofOfAddress: 'Απόδειξη διεύθυνσης για τον πραγματικό δικαιούχο',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4248,6 +4248,8 @@ const translations = {
proofOfBeneficialOwner: 'Proof of beneficial owner',
proofOfBeneficialOwnerDescription:
"Please provide a signed attestation and org chart from a public accountant, notary, or lawyer verifying ownership of 25% or more of the business. It must be dated within the last three months and include the signer's license number.",
proofOfBeneficialOwnerDescriptionCA:
'Please provide your Schedule 50 (Shareholder Information) from your most recent T2 corporate income tax return, showing every individual who owns 25% or more of the business.',
copyOfID: 'Copy of ID for beneficial owner',
copyOfIDDescription: "Examples: Passport, driver's license, etc.",
proofOfAddress: 'Address proof for beneficial owner',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4065,6 +4065,8 @@ ${amount} para ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Prueba del propietario beneficiario',
proofOfBeneficialOwnerDescription:
'Por favor, proporciona una declaración firmada y un organigrama de un contador público, notario o abogado que verifique la propiedad del 25% o más del negocio. Debe estar fechado dentro de los últimos tres meses e incluir el número de licencia del firmante.',
proofOfBeneficialOwnerDescriptionCA:
'Por favor, proporciona tu Schedule 50 (Shareholder Information) de tu declaración de impuestos corporativos T2 más reciente, que muestre a cada persona que posee el 25% o más del negocio.',
copyOfID: 'Copia de la identificación del propietario beneficiario',
copyOfIDDescription: 'Ejemplos: Pasaporte, licencia de conducir, etc.',
proofOfAddress: 'Prueba de la dirección del propietario beneficiario',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4157,6 +4157,8 @@ ${amount} pour ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Preuve du bénéficiaire effectif',
proofOfBeneficialOwnerDescription:
'Veuillez fournir une attestation signée et un organigramme émis par un expert-comptable, un notaire ou un avocat, confirmant la détention de 25 % ou plus de l’entreprise. Le document doit être daté de moins de trois mois et inclure le numéro de licence du signataire.',
proofOfBeneficialOwnerDescriptionCA:
'Veuillez fournir votre annexe 50 (Renseignements sur les actionnaires) de votre plus récente déclaration de revenus des sociétés T2, indiquant chaque personne qui détient 25 % ou plus de l’entreprise.',
copyOfID: 'Copie de la pièce d’identité du bénéficiaire effectif',
copyOfIDDescription: 'Exemples : passeport, permis de conduire, etc.',
proofOfAddress: 'Justificatif de domicile du bénéficiaire effectif',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4131,6 +4131,8 @@ ${amount} per ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Prova del titolare effettivo',
proofOfBeneficialOwnerDescription:
'Fornisci un’attestazione firmata e un organigramma da parte di un commercialista, notaio o avvocato che verifichi la titolarità del 25% o più dell’azienda. Il documento deve essere datato negli ultimi tre mesi e includere il numero di licenza del firmatario.',
proofOfBeneficialOwnerDescriptionCA:
'Fornisci il tuo Schedule 50 (Shareholder Information) della tua più recente dichiarazione dei redditi societaria T2, che indichi ogni persona che detiene il 25% o più dell’azienda.',
copyOfID: 'Copia del documento d’identità del titolare effettivo',
copyOfIDDescription: 'Esempi: passaporto, patente di guida, ecc.',
proofOfAddress: 'Prova di indirizzo per il titolare effettivo',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4099,6 +4099,8 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの'
proofOfBeneficialOwner: '受益所有者の証明',
proofOfBeneficialOwnerDescription:
'事業の所有権が25%以上であることを証明するため、公認会計士、公証人、または弁護士が署名した宣誓書および組織図をご提出ください。日付は過去3か月以内のものであり、署名者の免許番号が記載されている必要があります。',
proofOfBeneficialOwnerDescriptionCA:
'直近のT2法人所得税申告書のSchedule 50(Shareholder Information/株主情報)をご提出ください。事業の25%以上を保有するすべての個人が記載されている必要があります。',
copyOfID: '実質的支配者の本人確認書類のコピー',
copyOfIDDescription: '例:パスポート、運転免許証など',
proofOfAddress: '実質的支配者の住所証明',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4130,6 +4130,8 @@ ${amount} voor ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Bewijs van uiteindelijk belanghebbende',
proofOfBeneficialOwnerDescription:
'Geef een ondertekende verklaring en een organisatieschema van een openbare accountant, notaris of advocaat waarin wordt bevestigd wie 25% of meer van het bedrijf bezit. Deze moeten dateren van binnen de laatste drie maanden en het licentienummer van de ondertekenaar bevatten.',
proofOfBeneficialOwnerDescriptionCA:
'Lever je Schedule 50 (Shareholder Information) aan uit je meest recente T2-aangifte vennootschapsbelasting, waarin iedere persoon staat die 25% of meer van het bedrijf bezit.',
copyOfID: 'Kopie van identiteitsbewijs van uiteindelijk belanghebbende',
copyOfIDDescription: 'Voorbeelden: paspoort, rijbewijs, enz.',
proofOfAddress: 'Adresbewijs voor uiteindelijke belanghebbende',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4116,6 +4116,8 @@ ${amount} dla ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Dowód beneficjenta rzeczywistego',
proofOfBeneficialOwnerDescription:
'Prosimy o dostarczenie podpisanego oświadczenia oraz schematu organizacyjnego od biegłego rewidenta, notariusza lub prawnika, potwierdzających posiadanie 25% lub więcej udziałów w firmie. Dokument musi być opatrzony datą z ostatnich trzech miesięcy i zawierać numer licencji osoby podpisującej.',
proofOfBeneficialOwnerDescriptionCA:
'Prześlij formularz Schedule 50 (Shareholder Information) z najnowszej deklaracji podatkowej spółki T2, wskazujący każdą osobę posiadającą 25% lub więcej udziałów w firmie.',
copyOfID: 'Kopia dokumentu tożsamości rzeczywistego właściciela',
copyOfIDDescription: 'Przykłady: paszport, prawo jazdy itp.',
proofOfAddress: 'Potwierdzenie adresu rzeczywistego właściciela',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4119,6 +4119,8 @@ ${amount} para ${merchant} - ${date}`,
proofOfBeneficialOwner: 'Comprovante de beneficiário final',
proofOfBeneficialOwnerDescription:
'Forneça uma declaração assinada e um organograma emitidos por um contador público, tabelião ou advogado comprovando a titularidade de 25% ou mais do negócio. Eles devem estar datados dos últimos três meses e incluir o número da licença do signatário.',
proofOfBeneficialOwnerDescriptionCA:
'Forneça seu Schedule 50 (Shareholder Information) da sua declaração de imposto de renda corporativa T2 mais recente, mostrando cada pessoa que possui 25% ou mais do negócio.',
copyOfID: 'Cópia do documento de identificação do beneficiário final',
copyOfIDDescription: 'Exemplos: Passaporte, carteira de motorista, etc.',
proofOfAddress: 'Comprovante de endereço do beneficiário final',
Expand Down
1 change: 1 addition & 0 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4008,6 +4008,7 @@ ${amount},商户:${merchant} - 日期:${date}`,
proofOfBeneficialOwner: '受益所有人证明',
proofOfBeneficialOwnerDescription:
'请提供由注册会计师、公证人或律师出具并签署的声明和组织结构图,以核实对该企业25%或以上的持股情况。文件日期必须在最近三个月内,并包含签署人的执业证书号码。',
proofOfBeneficialOwnerDescriptionCA: '请提供您最近一期 T2 企业所得税申报表中的 Schedule 50(股东信息),列明持有该企业 25% 或以上股份的每一位个人。',
copyOfID: '受益所有人身份证复印件',
copyOfIDDescription: '示例:护照、驾驶证等。',
proofOfAddress: '实益所有人地址证明',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {FileObject} from '@src/types/utils/Attachment';
type EnableGlobalReimbursementsForUSDBankAccountParams = {
inputs: string;
achAuthorizationForm?: FileObject;
bankStatement?: FileObject;
bankAccountID: number;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function Agreements({onBackButtonPress, onSubmit, stepNames, currency}: NonUSDPa
const bankAccountID = reimbursementAccount?.achData?.bankAccountID ?? CONST.DEFAULT_NUMBER_ID;
const isDocusignStepRequired = requiresDocusignStep(currency);
const isSubmittingRef = useRef(false);
const isBankStatementNeeded = currency === CONST.CURRENCY.AUD;
const isBankStatementNeeded = currency === CONST.CURRENCY.AUD || currency === CONST.CURRENCY.CAD;
const bankStatementDefaultValue = reimbursementAccountDraft?.[INPUT_IDS.ADDITIONAL_DATA.CORPAY.BANK_STATEMENT] ?? [];

const submit = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ function Documents({onNext, isEditing, ownerBeingModifiedID}: DocumentsProps) {
value={defaultValues[proofOfOwnershipInputID]}
inputID={proofOfOwnershipInputID}
/>
<Text style={[styles.mutedTextLabel, styles.mt6]}>{translate('ownershipInfoStep.proofOfBeneficialOwnerDescription')}</Text>
<Text style={[styles.mutedTextLabel, styles.mt6]}>
{translate(country === CONST.COUNTRY.CA ? 'ownershipInfoStep.proofOfBeneficialOwnerDescriptionCA' : 'ownershipInfoStep.proofOfBeneficialOwnerDescription')}
</Text>
{(isDocumentNeededStatus.isCopyOfIDNeeded || isDocumentNeededStatus.isProofOfAddressNeeded || isDocumentNeededStatus.isCodiceFiscaleNeeded) && (
<View style={[styles.sectionDividerLine, styles.mv6]} />
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ function getStartPageForContinueSetup(
!!(reimbursementAccountDraft?.consentToPrivacyNotice ?? achData?.corpay?.consentToPrivacyNotice) &&
!!(reimbursementAccountDraft?.provideTruthfulInformation ?? achData?.corpay?.provideTruthfulInformation);

// AUD accounts must upload a bank statement, which is collected on the Agreements page and only lives in the draft until
// it's submitted on the Docusign page. Accounts that checked the agreements before the bank statement became required won't
// have one, so gate the Docusign resume on it to avoid submitting without a bank statement.
const isBankStatementNeeded = policyCurrency === CONST.CURRENCY.AUD;
// AUD and CAD accounts must upload a bank statement, which is collected on the Agreements page and only lives in the draft
// until it's submitted on the Docusign page. Accounts that checked the agreements before the bank statement became required
// won't have one, so gate the Docusign resume on it to avoid submitting without a bank statement.
const isBankStatementNeeded = policyCurrency === CONST.CURRENCY.AUD || policyCurrency === CONST.CURRENCY.CAD;
const isBankStatementUploaded = !!reimbursementAccountDraft?.[INPUT_IDS.ADDITIONAL_DATA.CORPAY.BANK_STATEMENT]?.length;

if (nonUSDCountryDraftValue !== '' && achData?.created === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function EnableGlobalReimbursementsAgreementsPage({route}: EnableGlobalReimburse
return [typedKey, enableGlobalReimbursementsDraft?.[typedKey] ?? false];
}),
) as Record<keyof typeof inputIDs, boolean>;
const bankStatementDefaultValue = enableGlobalReimbursementsDraft?.[INPUT_IDS.BANK_STATEMENT] ?? [];

const goBack = () => {
Navigation.goBack(ROUTES.SETTINGS_WALLET_ENABLE_GLOBAL_REIMBURSEMENTS_BUSINESS.getRoute(Number(bankAccountID), CONST.ENABLE_GLOBAL_REIMBURSEMENTS.PAGE_NAME.BUSINESS_INFO.CONFIRM));
Expand All @@ -53,6 +54,8 @@ function EnableGlobalReimbursementsAgreementsPage({route}: EnableGlobalReimburse
currency={currency}
startStepIndex={1}
stepNames={CONST.ENABLE_GLOBAL_REIMBURSEMENTS.STEP_INDEX_LIST}
bankStatementInputID={INPUT_IDS.BANK_STATEMENT}
bankStatementDefaultValue={bankStatementDefaultValue}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function EnableGlobalReimbursementsSignPage({route}: EnableGlobalReimbursementsS
purposeOfTransactionId: CONST.NON_USD_BANK_ACCOUNT.PURPOSE_OF_TRANSACTION_ID,
}),
achAuthorizationForm: enableGlobalReimbursementsDraft?.[INPUT_IDS.ACH_AUTHORIZATION_FORM].at(0),
bankStatement: enableGlobalReimbursementsDraft?.[INPUT_IDS.BANK_STATEMENT]?.at(0),
bankAccountID: Number(bankAccountID),
});
};
Expand Down
2 changes: 2 additions & 0 deletions src/types/form/EnableGlobalReimbursementsForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const INPUT_IDS = {
CONSENT_TO_PRIVACY_NOTICE: 'consentToPrivacyNotice',
AUTHORIZED_TO_BIND_CLIENT_TO_AGREEMENT: 'authorizedToBindClientToAgreement',
ACH_AUTHORIZATION_FORM: 'achAuthorizationForm',
BANK_STATEMENT: 'bankStatement',
} as const;

type InputID = ValueOf<typeof INPUT_IDS>;
Expand All @@ -32,6 +33,7 @@ type EnableGlobalReimbursementsForm = Form<
[INPUT_IDS.CONSENT_TO_PRIVACY_NOTICE]: boolean;
[INPUT_IDS.AUTHORIZED_TO_BIND_CLIENT_TO_AGREEMENT]: boolean;
[INPUT_IDS.ACH_AUTHORIZATION_FORM]: FileObject[];
[INPUT_IDS.BANK_STATEMENT]: FileObject[];
}
> & {isEnablingGlobalReimbursements?: boolean; isSuccess?: boolean};

Expand Down
70 changes: 70 additions & 0 deletions tests/unit/AgreementsFullStepTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {render, screen} from '@testing-library/react-native';

import AgreementsFullStep from '@components/SubStepForms/AgreementsFullStep';

import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import INPUT_IDS from '@src/types/form/EnableGlobalReimbursementsForm';

import React from 'react';
import Onyx from 'react-native-onyx';

// RenderHTML needs a TRenderEngineProvider that unit tests don't set up, and the two agreement labels that use it aren't
// what these assertions are about.
jest.mock('@components/RenderHTML', () => () => null);

// Without a LocaleContextProvider every translate() call resolves to an empty string, which would make text queries
// pass or fail regardless of what rendered. Returning the key keeps the assertions about rendering, not translation.
jest.mock('@hooks/useLocalize', () =>
jest.fn(() => ({
translate: (key: string) => key,
})),
);

const inputIDs = {
provideTruthfulInformation: INPUT_IDS.PROVIDE_TRUTHFUL_INFORMATION,
agreeToTermsAndConditions: INPUT_IDS.AGREE_TO_TERMS_AND_CONDITIONS,
consentToPrivacyNotice: INPUT_IDS.CONSENT_TO_PRIVACY_NOTICE,
authorizedToBindClientToAgreement: INPUT_IDS.AUTHORIZED_TO_BIND_CLIENT_TO_AGREEMENT,
};

const defaultValues = {
provideTruthfulInformation: true,
agreeToTermsAndConditions: true,
consentToPrivacyNotice: true,
authorizedToBindClientToAgreement: true,
};

function renderStep(bankStatementInputID?: typeof INPUT_IDS.BANK_STATEMENT) {
return render(
<AgreementsFullStep
defaultValues={defaultValues}
formID={ONYXKEYS.FORMS.ENABLE_GLOBAL_REIMBURSEMENTS}
inputIDs={inputIDs}
isLoading={false}
onBackButtonPress={jest.fn()}
onSubmit={jest.fn()}
currency={CONST.CURRENCY.USD}
startStepIndex={1}
stepNames={CONST.ENABLE_GLOBAL_REIMBURSEMENTS.STEP_INDEX_LIST}
bankStatementInputID={bankStatementInputID}
bankStatementDefaultValue={[]}
/>,
);
}

describe('AgreementsFullStep', () => {
beforeAll(() => {
Onyx.init({keys: ONYXKEYS});
});

it('renders the bank statement upload when bankStatementInputID is passed', () => {
renderStep(INPUT_IDS.BANK_STATEMENT);
expect(screen.getByText('agreementsStep.bankStatement')).toBeOnTheScreen();
});

it('omits the bank statement upload when bankStatementInputID is not passed', () => {
renderStep(undefined);
expect(screen.queryByText('agreementsStep.bankStatement')).not.toBeOnTheScreen();
});
});
Loading