diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 0869505bca0d..00ae80860eac 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -127,7 +127,18 @@ import type { } from '@src/types/onyx'; import type {Participant} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors, PendingAction} from '@src/types/onyx/OnyxCommon'; -import type {Attributes, CompanyAddress, CustomUnit, NetSuiteCustomList, NetSuiteCustomSegment, ProhibitedExpenses, Rate, TaxRate, UberReceiptPartner} from '@src/types/onyx/Policy'; +import type { + Attributes, + AutoReportingOffset, + CompanyAddress, + CustomUnit, + NetSuiteCustomList, + NetSuiteCustomSegment, + ProhibitedExpenses, + Rate, + TaxRate, + UberReceiptPartner, +} from '@src/types/onyx/Policy'; import type {CustomFieldType} from '@src/types/onyx/PolicyEmployee'; import type {NotificationPreference} from '@src/types/onyx/Report'; import type ReportNextStepDeprecated from '@src/types/onyx/ReportNextStepDeprecated'; @@ -229,6 +240,8 @@ type SetWorkspaceReimbursementActionParams = { state?: string; lastPaymentMethod?: LastPaymentMethodType | string; shouldUpdateLastPaymentMethod?: boolean; + currentReimbursementChoice: Policy['reimbursementChoice']; + currentAchAccount: Policy['achAccount']; bankAccountList?: BankAccountList; }; @@ -694,12 +707,15 @@ function setWorkspaceAutoHarvesting(policy: Policy, enabled: boolean) { API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_HARVESTING, params, {optimisticData, failureData, successData}); } -function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - - const wasPolicyOnManualReporting = PolicyUtils.getCorrectedAutoReportingFrequency(policy) === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; +function setWorkspaceAutoReportingFrequency( + policyID: string, + frequency: ValueOf, + currentAutoReportingFrequency: Policy['autoReportingFrequency'], + currentHarvesting: Policy['harvesting'], +) { + const wasPolicyOnManualReporting = + PolicyUtils.getCorrectedAutoReportingFrequency({autoReportingFrequency: currentAutoReportingFrequency, harvesting: currentHarvesting} as Policy) === + CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MANUAL; const optimisticData: Array> = [ { @@ -734,8 +750,8 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReportingFrequency: policy?.autoReportingFrequency ?? null, - harvesting: policy?.harvesting ?? null, + autoReportingFrequency: currentAutoReportingFrequency ?? null, + harvesting: currentHarvesting ?? null, pendingFields: {autoReportingFrequency: null}, errorFields: {autoReportingFrequency: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workflowsDelayedSubmissionPage.autoReportingFrequencyErrorMessage')}, }, @@ -756,14 +772,12 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_FREQUENCY, params, {optimisticData, failureData, successData}); } -function setWorkspaceAutoReportingMonthlyOffset(policyID: string | undefined, autoReportingOffset: number | ValueOf) { - if (!policyID) { - return; - } +function setWorkspaceAutoReportingMonthlyOffset( + policyID: string, + autoReportingOffset: number | ValueOf, + currentAutoReportingOffset: AutoReportingOffset | undefined, +) { const value = JSON.stringify({autoReportingOffset}); - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); const optimisticData: Array> = [ { @@ -781,7 +795,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string | undefined, au onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReportingOffset: policy?.autoReportingOffset ?? null, + autoReportingOffset: currentAutoReportingOffset ?? null, pendingFields: {autoReportingOffset: null}, errorFields: {autoReportingOffset: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workflowsDelayedSubmissionPage.monthlyOffsetErrorMessage')}, }, @@ -802,11 +816,17 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string | undefined, au API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET, params, {optimisticData, failureData, successData}); } -function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: ValueOf, additionalData?: SetWorkspaceApprovalModeAdditionalData) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); +function setWorkspaceApprovalMode( + policy: OnyxEntry, + approver: string, + approvalMode: ValueOf, + additionalData?: SetWorkspaceApprovalModeAdditionalData, +) { + if (!policy) { + return; + } + const policyID = policy.id; const value = { approver, approvalMode, @@ -962,11 +982,7 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo } } -function setWorkspacePayer(policyID: string, reimburserEmail: string) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - +function setWorkspacePayer(policyID: string, reimburserEmail: string, currentReimburser: string | undefined) { const optimisticData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -996,7 +1012,7 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - achAccount: {reimburser: policy?.achAccount?.reimburser ?? null}, + achAccount: {reimburser: currentReimburser ?? null}, errorFields: {reimburser: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workflowsPayerPage.genericErrorMessage')}, pendingFields: {reimburser: null}, }, @@ -1091,11 +1107,10 @@ function setWorkspaceReimbursement({ state, lastPaymentMethod, shouldUpdateLastPaymentMethod, + currentReimbursementChoice, + currentAchAccount, bankAccountList = {}, }: SetWorkspaceReimbursementActionParams) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); const lastUsedPaymentMethod = typeof lastPaymentMethod === 'string' ? lastPaymentMethod : lastPaymentMethod?.expense?.name; const oldBankAccountID = Object.keys(bankAccountList ?? {}).find((accountID) => { @@ -1185,14 +1200,14 @@ function setWorkspaceReimbursement({ key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { isLoadingWorkspaceReimbursement: false, - reimbursementChoice: policy?.reimbursementChoice ?? null, + reimbursementChoice: currentReimbursementChoice ?? null, achAccount: { - reimburser: policy?.achAccount?.reimburser ?? null, - bankAccountID: policy?.achAccount?.bankAccountID ?? null, - accountNumber: policy?.achAccount?.accountNumber ?? null, - addressName: policy?.achAccount?.addressName ?? null, - bankName: policy?.achAccount?.bankName ?? null, - state: policy?.achAccount?.state ?? null, + reimburser: currentAchAccount?.reimburser ?? null, + bankAccountID: currentAchAccount?.bankAccountID ?? null, + accountNumber: currentAchAccount?.accountNumber ?? null, + addressName: currentAchAccount?.addressName ?? null, + bankName: currentAchAccount?.bankName ?? null, + state: currentAchAccount?.state ?? null, }, errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, pendingFields: {reimbursementChoice: null}, @@ -6362,13 +6377,10 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) * Call the API to enable or disable self approvals for the reports * @param policyID - id of the policy to apply the naming pattern to * @param preventSelfApproval - flag whether to prevent workspace members from approving their own expense reports + * @param currentPreventSelfApproval - current value of preventSelfApproval */ -function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boolean) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - - if (preventSelfApproval === policy?.preventSelfApproval) { +function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boolean, currentPreventSelfApproval: boolean | undefined) { + if (preventSelfApproval === currentPreventSelfApproval) { return; } @@ -6403,7 +6415,7 @@ function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boo onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - preventSelfApproval: policy?.preventSelfApproval ?? false, + preventSelfApproval: currentPreventSelfApproval ?? false, pendingFields: { preventSelfApproval: null, }, @@ -6430,16 +6442,13 @@ function setPolicyPreventSelfApproval(policyID: string, preventSelfApproval: boo * Call the API to apply automatic approval limit for the given policy * @param policyID - id of the policy to apply the limit to * @param limit - max amount for auto-approval of the reports in the given policy + * @param currentAutoApprovalLimit - current value of autoApproval.limit */ -function setPolicyAutomaticApprovalLimit(policyID: string, limit: string) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - +function setPolicyAutomaticApprovalLimit(policyID: string, limit: string, currentAutoApprovalLimit: number | undefined) { const fallbackLimit = limit === '' ? '0' : limit; const parsedLimit = CurrencyUtils.convertToBackendAmount(parseFloat(fallbackLimit)); - if (parsedLimit === (policy?.autoApproval?.limit ?? CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_DEFAULT_CENTS)) { + if (parsedLimit === (currentAutoApprovalLimit ?? CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_DEFAULT_CENTS)) { return; } @@ -6477,7 +6486,7 @@ function setPolicyAutomaticApprovalLimit(policyID: string, limit: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { autoApproval: { - limit: policy?.autoApproval?.limit ?? CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_DEFAULT_CENTS, + limit: currentAutoApprovalLimit ?? CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_DEFAULT_CENTS, pendingFields: { limit: null, }, @@ -6505,16 +6514,14 @@ function setPolicyAutomaticApprovalLimit(policyID: string, limit: string) { * Call the API to set the audit rate for the given policy * @param policyID - id of the policy to apply the limit to * @param auditRate - percentage of the reports to be qualified for a random audit + * @param currentAutoApprovalAuditRate - current value of autoApproval.auditRate */ -function setPolicyAutomaticApprovalRate(policyID: string, auditRate: string) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); +function setPolicyAutomaticApprovalRate(policyID: string, auditRate: string, currentAutoApprovalAuditRate: number | undefined) { const fallbackAuditRate = auditRate === '' ? '0' : auditRate; const parsedAuditRate = parseInt(fallbackAuditRate, 10) / 100; // The auditRate arrives as an int to this method so we will convert it to a float before sending it to the API. - if (parsedAuditRate === (policy?.autoApproval?.auditRate ?? CONST.POLICY.RANDOM_AUDIT_DEFAULT_PERCENTAGE)) { + if (parsedAuditRate === (currentAutoApprovalAuditRate ?? CONST.POLICY.RANDOM_AUDIT_DEFAULT_PERCENTAGE)) { return; } @@ -6554,7 +6561,7 @@ function setPolicyAutomaticApprovalRate(policyID: string, auditRate: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { autoApproval: { - auditRate: policy?.autoApproval?.auditRate ?? CONST.POLICY.RANDOM_AUDIT_DEFAULT_PERCENTAGE, + auditRate: currentAutoApprovalAuditRate ?? CONST.POLICY.RANDOM_AUDIT_DEFAULT_PERCENTAGE, pendingFields: { auditRate: null, }, @@ -6583,12 +6590,14 @@ function setPolicyAutomaticApprovalRate(policyID: string, auditRate: string) { * @param policyID - id of the policy to apply the limit to * @param enabled - whether auto-approve for the reports is enabled in the given policy */ -function enableAutoApprovalOptions(policyID: string, enabled: boolean) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - - if (enabled === policy?.shouldShowAutoApprovalOptions) { +function enableAutoApprovalOptions( + policyID: string, + enabled: boolean, + currentShouldShowAutoApprovalOptions: boolean | undefined, + currentAutoApprovalLimit: number | undefined, + currentAutoApprovalAuditRate: number | undefined, +) { + if (enabled === currentShouldShowAutoApprovalOptions) { return; } @@ -6596,7 +6605,7 @@ function enableAutoApprovalOptions(policyID: string, enabled: boolean) { auditRate: enabled ? CONST.POLICY.RANDOM_AUDIT_SUGGESTED_PERCENTAGE : 0, limit: enabled ? CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_SUGGESTED_CENTS : 0, }; - const autoApprovalFailureValues = {autoApproval: {limit: policy?.autoApproval?.limit, auditRate: policy?.autoApproval?.auditRate, pendingFields: null}}; + const autoApprovalFailureValues = {autoApproval: {limit: currentAutoApprovalLimit, auditRate: currentAutoApprovalAuditRate, pendingFields: null}}; const optimisticData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -6636,7 +6645,7 @@ function enableAutoApprovalOptions(policyID: string, enabled: boolean) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { ...autoApprovalFailureValues, - shouldShowAutoApprovalOptions: policy?.shouldShowAutoApprovalOptions, + shouldShowAutoApprovalOptions: currentShouldShowAutoApprovalOptions, pendingFields: { shouldShowAutoApprovalOptions: null, }, @@ -6661,14 +6670,11 @@ function enableAutoApprovalOptions(policyID: string, enabled: boolean) { * @param policyID - id of the policy to apply the limit to * @param limit - max amount for auto-payment for the reports in the given policy */ -function setPolicyAutoReimbursementLimit(policyID: string, limit: string) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); +function setPolicyAutoReimbursementLimit(policyID: string, limit: string, currentAutoReimbursementLimit: number | undefined) { const fallbackLimit = limit === '' ? '0' : limit; const parsedLimit = CurrencyUtils.convertToBackendAmount(parseFloat(fallbackLimit)); - if (parsedLimit === (policy?.autoReimbursement?.limit ?? CONST.POLICY.AUTO_REIMBURSEMENT_LIMIT_DEFAULT_CENTS)) { + if (parsedLimit === (currentAutoReimbursementLimit ?? 0)) { return; } @@ -6708,7 +6714,7 @@ function setPolicyAutoReimbursementLimit(policyID: string, limit: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReimbursement: {limit: policy?.autoReimbursement?.limit ?? policy?.autoReimbursementLimit, pendingFields: {limit: null}}, + autoReimbursement: {limit: currentAutoReimbursementLimit ?? 0, pendingFields: {limit: null}}, errorFields: { autoReimbursement: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), }, @@ -6734,16 +6740,17 @@ function setPolicyAutoReimbursementLimit(policyID: string, limit: string) { * @param policyID - id of the policy to apply the limit to * @param enabled - whether auto-payment for the reports is enabled in the given policy */ -function enablePolicyAutoReimbursementLimit(policyID: string, enabled: boolean) { - // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 - // eslint-disable-next-line @typescript-eslint/no-deprecated - const policy = getPolicy(policyID); - - if (enabled === policy?.shouldShowAutoReimbursementLimitOption) { +function enablePolicyAutoReimbursementLimit( + policyID: string, + enabled: boolean, + currentShouldShowAutoReimbursementLimitOption: boolean | undefined, + currentAutoReimbursementLimit: number | undefined, +) { + if (enabled === currentShouldShowAutoReimbursementLimitOption) { return; } - const autoReimbursementFailureValues = {autoReimbursement: {limit: policy?.autoReimbursement?.limit, pendingFields: null}}; + const autoReimbursementFailureValues = {autoReimbursement: {limit: currentAutoReimbursementLimit, pendingFields: null}}; const autoReimbursementValues = {limit: enabled ? CONST.POLICY.AUTO_REIMBURSEMENT_LIMIT_SUGGESTED_CENTS : CONST.POLICY.AUTO_REIMBURSEMENT_LIMIT_DEFAULT_CENTS}; const optimisticData: Array> = [ { @@ -6784,7 +6791,7 @@ function enablePolicyAutoReimbursementLimit(policyID: string, enabled: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { ...autoReimbursementFailureValues, - shouldShowAutoReimbursementLimitOption: policy?.shouldShowAutoReimbursementLimitOption, + shouldShowAutoReimbursementLimitOption: currentShouldShowAutoReimbursementLimitOption, pendingFields: { shouldShowAutoReimbursementLimitOption: null, }, diff --git a/src/pages/workspace/ConnectExistingBusinessBankAccountPage.tsx b/src/pages/workspace/ConnectExistingBusinessBankAccountPage.tsx index db0b2880ae54..ff4db662ff0e 100644 --- a/src/pages/workspace/ConnectExistingBusinessBankAccountPage.tsx +++ b/src/pages/workspace/ConnectExistingBusinessBankAccountPage.tsx @@ -51,6 +51,8 @@ function ConnectExistingBusinessBankAccountPage({route}: ConnectExistingBusiness if (bankAccountList && methodID && !bankAccountList[methodID]?.accountData?.policyIDs?.includes(policyID)) { setWorkspaceReimbursement({ policyID, + currentAchAccount: policy?.achAccount, + currentReimbursementChoice: policy?.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: methodID ?? CONST.DEFAULT_NUMBER_ID, reimburserEmail: newReimburserEmail, diff --git a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx index a531bc2aa4bb..f010df8f4b92 100644 --- a/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx +++ b/src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx @@ -168,7 +168,7 @@ function WorkspaceMemberDetailsPage({personalDetails, policy, route}: WorkspaceM const remainingEmployeeCount = previousEmployeesCount - 1; if (remainingEmployeeCount === 1 && policy?.preventSelfApproval) { // We can't let the "Prevent Self Approvals" enabled if there's only one workspace user - setPolicyPreventSelfApproval(policyID, false); + setPolicyPreventSelfApproval(policyID, false, policy.preventSelfApproval); } }; diff --git a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx index 862f637099fa..3c495989b2bc 100644 --- a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx +++ b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx @@ -55,7 +55,7 @@ function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) { return; } - setPolicyPreventSelfApproval(policyID, isEnabled); + setPolicyPreventSelfApproval(policyID, isEnabled, policy?.preventSelfApproval); }, }, { @@ -77,7 +77,7 @@ function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) { return; } - enableAutoApprovalOptions(policyID, isEnabled); + enableAutoApprovalOptions(policyID, isEnabled, policy?.shouldShowAutoApprovalOptions, policy?.autoApproval?.limit, policy?.autoApproval?.auditRate); }, subMenuItems: [ { - setPolicyAutomaticApprovalLimit(policyID, maxExpenseAutoApprovalAmount); + setPolicyAutomaticApprovalLimit(policyID, maxExpenseAutoApprovalAmount, policy?.autoApproval?.limit); Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack); }} submitButtonText={translate('common.save')} diff --git a/src/pages/workspace/rules/RulesAutoPayReportsUnderPage.tsx b/src/pages/workspace/rules/RulesAutoPayReportsUnderPage.tsx index ebee524cd66c..20a302fe598e 100644 --- a/src/pages/workspace/rules/RulesAutoPayReportsUnderPage.tsx +++ b/src/pages/workspace/rules/RulesAutoPayReportsUnderPage.tsx @@ -70,7 +70,7 @@ function RulesAutoPayReportsUnderPage({route}: RulesAutoPayReportsUnderPageProps formID={ONYXKEYS.FORMS.RULES_AUTO_PAY_REPORTS_UNDER_MODAL_FORM} validate={validateLimit} onSubmit={({maxExpenseAutoPayAmount}) => { - setPolicyAutoReimbursementLimit(policyID, maxExpenseAutoPayAmount); + setPolicyAutoReimbursementLimit(policyID, maxExpenseAutoPayAmount, policy?.autoReimbursement?.limit ?? policy?.autoReimbursementLimit); Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack); }} submitButtonText={translate('common.save')} diff --git a/src/pages/workspace/rules/RulesRandomReportAuditPage.tsx b/src/pages/workspace/rules/RulesRandomReportAuditPage.tsx index f90f1a882b81..101b807a05ed 100644 --- a/src/pages/workspace/rules/RulesRandomReportAuditPage.tsx +++ b/src/pages/workspace/rules/RulesRandomReportAuditPage.tsx @@ -54,7 +54,7 @@ function RulesRandomReportAuditPage({route}: RulesRandomReportAuditPageProps) { style={[styles.flexGrow1, styles.mh5]} formID={ONYXKEYS.FORMS.RULES_RANDOM_REPORT_AUDIT_MODAL_FORM} onSubmit={({auditRatePercentage}) => { - setPolicyAutomaticApprovalRate(policyID, auditRatePercentage); + setPolicyAutomaticApprovalRate(policyID, auditRatePercentage, policy?.autoApproval?.auditRate); Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack); }} submitButtonText={translate('common.save')} diff --git a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx index c9997b341190..8136f2f68144 100644 --- a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx +++ b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx @@ -149,13 +149,13 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { } switch (feature.id) { case CONST.UPGRADE_FEATURE_INTRO_MAPPING.preventSelfApproval.id: - setPolicyPreventSelfApproval(policyID, true); + setPolicyPreventSelfApproval(policyID, true, policy?.preventSelfApproval); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.autoApproveCompliantReports.id: - enableAutoApprovalOptions(policyID, true); + enableAutoApprovalOptions(policyID, true, policy?.shouldShowAutoApprovalOptions, policy?.autoApproval?.limit, policy?.autoApproval?.auditRate); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.autoPayApprovedReports.id: - enablePolicyAutoReimbursementLimit(policyID, true); + enablePolicyAutoReimbursementLimit(policyID, true, policy?.shouldShowAutoReimbursementLimitOption, policy?.autoReimbursement?.limit); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.reportFields.id: switch (route.params.featureName) { @@ -195,7 +195,7 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { enablePerDiem(policyID, true, perDiemCustomUnit?.customUnitID, false); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.approvals.id: - setWorkspaceApprovalMode(policyID, defaultApprover, CONST.POLICY.APPROVAL_MODE.ADVANCED); + setWorkspaceApprovalMode(policy, defaultApprover, CONST.POLICY.APPROVAL_MODE.ADVANCED); break; default: } diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx index 8e0a40998843..0b94b5a3e8a7 100644 --- a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx @@ -57,7 +57,7 @@ function WorkspaceAutoReportingFrequencyPage({policy, route}: WorkspaceAutoRepor if (!policy?.id) { return; } - setWorkspaceAutoReportingFrequency(policy.id, item.keyForList as AutoReportingFrequencyKey); + setWorkspaceAutoReportingFrequency(policy.id, item.keyForList as AutoReportingFrequencyKey, policy.autoReportingFrequency, policy.harvesting); if (item.keyForList === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY) { return; diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx index e8c67caf12c1..167c6cfeb448 100644 --- a/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx @@ -66,8 +66,11 @@ function WorkspaceAutoReportingMonthlyOffsetPage({policy, route}: WorkspaceAutoR const filteredDaysOfMonth = daysOfMonth.filter((dayItem) => dayItem.text.toLowerCase().includes(trimmedText)); const onSelectDayOfMonth = (item: WorkspaceAutoReportingMonthlyOffsetPageItem) => { - setWorkspaceAutoReportingMonthlyOffset(policy?.id, item.isNumber ? parseInt(item.keyForList, 10) : (item.keyForList as AutoReportingOffsetKeys)); - Navigation.goBack(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id)); + if (!policy?.id) { + return; + } + setWorkspaceAutoReportingMonthlyOffset(policy.id, item.isNumber ? parseInt(item.keyForList, 10) : (item.keyForList as AutoReportingOffsetKeys), policy.autoReportingOffset); + Navigation.goBack(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy.id)); }; const textInputOptions = useMemo( () => ({ diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index a6c13e50cf6e..ffdc7a4172ec 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -171,12 +171,12 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, []); const confirmDisableApprovals = useCallback(() => { - setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', CONST.POLICY.APPROVAL_MODE.OPTIONAL, { + setWorkspaceApprovalMode(policy, policy?.owner ?? '', CONST.POLICY.APPROVAL_MODE.OPTIONAL, { reportNextSteps: allReportNextSteps, transactionViolations, betas, }); - }, [allReportNextSteps, betas, policy?.owner, route.params.policyID, transactionViolations]); + }, [allReportNextSteps, betas, policy, transactionViolations]); // User should be allowed to add new Approval Workflow only if he's upgraded to Control Plan, otherwise redirected to the Upgrade Page const addApprovalAction = useCallback(() => { @@ -311,7 +311,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }); return; } - setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? updateApprovalMode : CONST.POLICY.APPROVAL_MODE.OPTIONAL, { + setWorkspaceApprovalMode(policy, policy?.owner ?? '', isEnabled ? updateApprovalMode : CONST.POLICY.APPROVAL_MODE.OPTIONAL, { reportNextSteps: allReportNextSteps, transactionViolations, betas, @@ -399,6 +399,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const newReimburserEmail = policy?.achAccount?.reimburser ?? policy?.owner; setWorkspaceReimbursement({ policyID: route.params.policyID, + currentAchAccount: policy?.achAccount, + currentReimbursementChoice: policy?.reimbursementChoice, reimbursementChoice: newReimbursementChoice, reimburserEmail: newReimburserEmail ?? '', bankAccountID: policy?.achAccount?.bankAccountID, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 314626847993..df1e15dc56d7 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -187,7 +187,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, personalDetails, isLoadingR Navigation.closeRHPFlow(); return; } - setWorkspacePayer(policy?.id, authorizedPayerEmail); + setWorkspacePayer(policy.id, authorizedPayerEmail, policy.achAccount?.reimburser); Navigation.closeRHPFlow(); }; diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 89f318f8bd80..38a6c21e1c89 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -2135,6 +2135,7 @@ type PolicyConnectionSyncProgress = { export default Policy; export type { + AutoReportingOffset, PolicyReportField, PolicyReportFieldType, Unit, diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 906c7f3b319d..5f99deb3d50e 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -106,7 +106,7 @@ import type {PersonalDetailsList, PersonalDetailsMetadata} from './PersonalDetai import type PersonalDetails from './PersonalDetails'; import type PlaidData from './PlaidData'; import type Policy from './Policy'; -import type {PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; +import type {AutoReportingOffset, PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; import type {PolicyCategories, PolicyCategory} from './PolicyCategory'; import type {PolicyEmployeeList} from './PolicyEmployee'; import type PolicyEmployee from './PolicyEmployee'; @@ -260,6 +260,7 @@ export type { PolicyConnectionName, PolicyConnectionSyncProgress, PolicyOwnershipChangeChecks, + AutoReportingOffset, PolicyTag, PolicyTags, PolicyTagLists, diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index e17c5af77198..8946af2bb128 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -9641,7 +9641,7 @@ describe('actions/IOU', () => { let expenseReport: OnyxEntry; let chatReport: OnyxEntry; return waitForBatchedUpdates() - .then(() => { + .then(async () => { const policyID = generatePolicyID(); createWorkspace({ policyOwnerEmail: CARLOS_EMAIL, @@ -9655,8 +9655,9 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); return waitForBatchedUpdates(); }) .then( @@ -9787,7 +9788,7 @@ describe('actions/IOU', () => { let chatReport: OnyxEntry; return waitForBatchedUpdates() - .then(() => { + .then(async () => { const policyID = generatePolicyID(); createWorkspace({ policyOwnerEmail: CARLOS_EMAIL, @@ -9801,7 +9802,8 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); return waitForBatchedUpdates(); }) .then( @@ -10368,8 +10370,9 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); return waitForBatchedUpdates() - .then(() => { - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.DYNAMICEXTERNAL); + .then(async () => { + policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.DYNAMICEXTERNAL, {}); return waitForBatchedUpdates(); }) .then( @@ -10595,7 +10598,7 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); await waitForBatchedUpdates(); let chatReport: OnyxEntry; @@ -12787,8 +12790,9 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); await waitForBatchedUpdates(); await getOnyxData({ key: ONYXKEYS.COLLECTION.REPORT, @@ -12961,8 +12965,9 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, RORY_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, RORY_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); await waitForBatchedUpdates(); await getOnyxData({ key: ONYXKEYS.COLLECTION.REPORT, @@ -13139,7 +13144,8 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); await waitForBatchedUpdates(); await getOnyxData({ @@ -13326,8 +13332,9 @@ describe('actions/IOU', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC, {}); await waitForBatchedUpdates(); await getOnyxData({ diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 2463373c1cf3..7870af04e8d1 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -2067,7 +2067,8 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { isSelfTourViewed: false, hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ @@ -2545,8 +2546,9 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ key: ONYXKEYS.COLLECTION.REPORT, @@ -2719,8 +2721,9 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, RORY_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, RORY_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ key: ONYXKEYS.COLLECTION.REPORT, @@ -2897,7 +2900,8 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ @@ -3084,8 +3088,9 @@ describe('updateSplitTransactionsFromSplitExpensesFlow', () => { hasActiveAdminPolicies: false, }); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); // Change the approval mode for the policy since default is Submit and Close - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ @@ -3347,7 +3352,8 @@ describe('updateSplitTransactions', () => { isSelfTourViewed: false, hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ @@ -3475,7 +3481,8 @@ describe('updateSplitTransactions', () => { isSelfTourViewed: false, hasActiveAdminPolicies: false, }); - setWorkspaceApprovalMode(policyID, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + const policy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); + setWorkspaceApprovalMode(policy, CARLOS_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); await getOnyxData({ diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index b5ec5945eb08..7f8f58a37f3b 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -2061,7 +2061,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); let policy: OnyxEntry = await new Promise((resolve) => { @@ -2134,7 +2134,7 @@ describe('actions/Policy', () => { // eslint-disable-next-line @typescript-eslint/no-deprecated -- We need a minimal ReportNextStepDeprecated shape to simulate rollback on failure. const currentNextStep2 = {type: 'neutral', icon: CONST.NEXT_STEP.ICONS.CHECKMARK, message: [{text: 'Old next step 2'}]} as never; - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL, { + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL, { reportNextSteps: { [nextStepKey1]: currentNextStep1, [nextStepKey2]: currentNextStep2, @@ -2187,7 +2187,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); expect(getAllPolicyReportsSpy).not.toHaveBeenCalled(); @@ -2235,7 +2235,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); const policy: OnyxEntry = await new Promise((resolve) => { @@ -2282,7 +2282,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); expect(apiWriteSpy).toHaveBeenCalledWith(WRITE_COMMANDS.DISABLE_POLICY_APPROVALS, expect.objectContaining({policyID}), expect.anything()); @@ -2307,7 +2307,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); expect(apiWriteSpy).toHaveBeenCalledWith(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, expect.objectContaining({policyID}), expect.anything()); @@ -2349,7 +2349,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); // optimisticMembersState should be empty for non-OPTIONAL mode @@ -2394,7 +2394,7 @@ describe('actions/Policy', () => { // Simulate API failure mockFetch?.fail?.(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); const policy: OnyxEntry = await new Promise((resolve) => { @@ -2451,7 +2451,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as @@ -2501,7 +2501,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); const writeOptions = apiWriteSpy.mock.calls.at(0)?.at(2) as @@ -2538,7 +2538,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.BASIC); await waitForBatchedUpdates(); let policy: OnyxEntry = await new Promise((resolve) => { @@ -2594,7 +2594,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); let policy: OnyxEntry = await new Promise((resolve) => { @@ -2647,7 +2647,7 @@ describe('actions/Policy', () => { await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); await waitForBatchedUpdates(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); let policy: OnyxEntry = await new Promise((resolve) => { @@ -2704,7 +2704,7 @@ describe('actions/Policy', () => { mockFetch?.fail?.(); - Policy.setWorkspaceApprovalMode(policyID, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); + Policy.setWorkspaceApprovalMode(fakePolicy, ESH_EMAIL, CONST.POLICY.APPROVAL_MODE.OPTIONAL); await waitForBatchedUpdates(); const policy: OnyxEntry = await new Promise((resolve) => { @@ -3310,6 +3310,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3346,6 +3348,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3378,6 +3382,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3412,6 +3418,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3443,6 +3451,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3470,6 +3480,8 @@ describe('actions/Policy', () => { Policy.setWorkspaceReimbursement({ policyID: FAKE_POLICY_ID, + currentAchAccount: fakePolicy.achAccount, + currentReimbursementChoice: fakePolicy.reimbursementChoice, reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, bankAccountID: FAKE_BANK_ACCOUNT_ID, reimburserEmail: FAKE_REIMBURSER_EMAIL, @@ -3803,4 +3815,449 @@ describe('actions/Policy', () => { expect(updatedPolicy?.invoice?.pendingFields?.companyWebsite).toBeUndefined(); }); }); + + describe('setWorkspaceAutoReportingFrequency', () => { + it('should update auto reporting frequency optimistically and succeed', async () => { + // Given a workspace with immediate reporting frequency + const policy = { + ...createRandomPolicy(0), + autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE, + harvesting: {enabled: true}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting auto reporting frequency to monthly + Policy.setWorkspaceAutoReportingFrequency(policy.id, CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY, policy.autoReportingFrequency, policy.harvesting); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReportingFrequency).toBe(CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY); + expect(updatedPolicy?.pendingFields?.autoReportingFrequency).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.autoReportingFrequency).toBeUndefined(); + }); + + it('should revert auto reporting frequency when fail', async () => { + // Given a workspace with immediate reporting frequency + const policy = { + ...createRandomPolicy(0), + autoReportingFrequency: CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE, + harvesting: {enabled: true}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting auto reporting frequency to monthly but fail + mockFetch.fail(); + Policy.setWorkspaceAutoReportingFrequency(policy.id, CONST.POLICY.AUTO_REPORTING_FREQUENCIES.MONTHLY, policy.autoReportingFrequency, policy.harvesting); + await waitForBatchedUpdates(); + + // Then the frequency should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReportingFrequency).toBe(CONST.POLICY.AUTO_REPORTING_FREQUENCIES.IMMEDIATE); + expect(updatedPolicy?.pendingFields?.autoReportingFrequency).toBeUndefined(); + expect(updatedPolicy?.errorFields?.autoReportingFrequency).toBeTruthy(); + }); + }); + + describe('setWorkspaceAutoReportingMonthlyOffset', () => { + it('should update auto reporting monthly offset optimistically and succeed', async () => { + // Given a workspace with offset 1 + const policy = { + ...createRandomPolicy(0), + autoReportingOffset: 1, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting auto reporting offset to 2 + Policy.setWorkspaceAutoReportingMonthlyOffset(policy.id, 2, policy.autoReportingOffset); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReportingOffset).toBe(2); + expect(updatedPolicy?.pendingFields?.autoReportingOffset).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.autoReportingOffset).toBeUndefined(); + }); + + it('should revert auto reporting monthly offset when fail', async () => { + // Given a workspace with offset 1 + const policy = { + ...createRandomPolicy(0), + autoReportingOffset: 1, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting auto reporting offset to 2 but fail + mockFetch.fail(); + Policy.setWorkspaceAutoReportingMonthlyOffset(policy.id, 2, policy.autoReportingOffset); + await waitForBatchedUpdates(); + + // Then the offset should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReportingOffset).toBe(1); + expect(updatedPolicy?.pendingFields?.autoReportingOffset).toBeUndefined(); + expect(updatedPolicy?.errorFields?.autoReportingOffset).toBeTruthy(); + }); + }); + + describe('setWorkspacePayer', () => { + it('should update workspace payer optimistically and succeed', async () => { + // Given a workspace with a payer + const policy = { + ...createRandomPolicy(0), + reimburser: 'old@test.com', + achAccount: {reimburser: 'old@test.com'}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting workspace payer to new@test.com + Policy.setWorkspacePayer(policy.id, 'new@test.com', policy.reimburser); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.reimburser).toBe('new@test.com'); + expect(updatedPolicy?.achAccount?.reimburser).toBe('new@test.com'); + expect(updatedPolicy?.pendingFields?.reimburser).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.reimburser).toBeUndefined(); + }); + + it('should revert workspace payer when fail', async () => { + // Given a workspace with a payer + const policy = { + ...createRandomPolicy(0), + reimburser: 'old@test.com', + achAccount: {reimburser: 'old@test.com'}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting workspace payer to new@test.com but fail + mockFetch.fail(); + Policy.setWorkspacePayer(policy.id, 'new@test.com', policy.reimburser); + await waitForBatchedUpdates(); + + // Then the payer should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.achAccount?.reimburser).toBe('old@test.com'); + expect(updatedPolicy?.pendingFields?.reimburser).toBeUndefined(); + expect(updatedPolicy?.errorFields?.reimburser).toBeTruthy(); + }); + }); + + describe('setPolicyPreventSelfApproval', () => { + it('should update prevent self approval optimistically and succeed', async () => { + // Given a workspace with prevent self approval disabled + const policy = { + ...createRandomPolicy(0), + preventSelfApproval: false, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When enabling prevent self approval + Policy.setPolicyPreventSelfApproval(policy.id, true, policy.preventSelfApproval); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.preventSelfApproval).toBe(true); + expect(updatedPolicy?.pendingFields?.preventSelfApproval).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.preventSelfApproval).toBeUndefined(); + }); + + it('should revert prevent self approval when fail', async () => { + // Given a workspace with prevent self approval disabled + const policy = { + ...createRandomPolicy(0), + preventSelfApproval: false, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When enabling prevent self approval but fail + mockFetch.fail(); + Policy.setPolicyPreventSelfApproval(policy.id, true, policy.preventSelfApproval); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.preventSelfApproval).toBe(false); + expect(updatedPolicy?.pendingFields?.preventSelfApproval).toBeUndefined(); + expect(updatedPolicy?.errorFields?.preventSelfApproval).toBeTruthy(); + }); + }); + + describe('setPolicyAutomaticApprovalLimit', () => { + it('should update automatic approval limit optimistically and succeed', async () => { + // Given a workspace with auto approval limit 100 + const policy = { + ...createRandomPolicy(0), + autoApproval: {limit: 10000}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting automatic approval limit to 200 + Policy.setPolicyAutomaticApprovalLimit(policy.id, '200', policy.autoApproval.limit); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.limit).toBe(20000); + expect(updatedPolicy?.autoApproval?.pendingFields?.limit).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.pendingFields?.limit).toBeUndefined(); + }); + + it('should revert automatic approval limit when fail', async () => { + // Given a workspace with auto approval limit 100 + const policy = { + ...createRandomPolicy(0), + autoApproval: {limit: 10000}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting automatic approval limit to 200 but fail + mockFetch.fail(); + Policy.setPolicyAutomaticApprovalLimit(policy.id, '200', policy.autoApproval.limit); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.limit).toBe(10000); + expect(updatedPolicy?.autoApproval?.pendingFields?.limit).toBeUndefined(); + expect(updatedPolicy?.errorFields?.autoApproval).toBeTruthy(); + }); + }); + + describe('setPolicyAutomaticApprovalRate', () => { + it('should update automatic approval rate optimistically and succeed', async () => { + // Given a workspace with auto approval audit rate 0.5 + const policy = { + ...createRandomPolicy(0), + autoApproval: {auditRate: 0.5}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting automatic approval rate to 80% + Policy.setPolicyAutomaticApprovalRate(policy.id, '80', policy.autoApproval.auditRate); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.auditRate).toBe(0.8); + expect(updatedPolicy?.autoApproval?.pendingFields?.auditRate).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.pendingFields?.auditRate).toBeUndefined(); + }); + + it('should revert automatic approval rate when fail', async () => { + // Given a workspace with auto approval audit rate 0.5 + const policy = { + ...createRandomPolicy(0), + autoApproval: {auditRate: 0.5}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting automatic approval rate to 80% but fail + mockFetch.fail(); + Policy.setPolicyAutomaticApprovalRate(policy.id, '80', policy.autoApproval.auditRate); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoApproval?.auditRate).toBe(0.5); + expect(updatedPolicy?.autoApproval?.pendingFields?.auditRate).toBeUndefined(); + expect(updatedPolicy?.errorFields?.autoApproval).toBeTruthy(); + }); + }); + + describe('enableAutoApprovalOptions', () => { + it('should enable auto approval options optimistically and succeed', async () => { + // Given a workspace with auto approval options disabled + const policy = { + ...createRandomPolicy(0), + shouldShowAutoApprovalOptions: false, + autoApproval: {limit: 0, auditRate: 0}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When enabling auto approval options + Policy.enableAutoApprovalOptions(policy.id, true, policy.shouldShowAutoApprovalOptions, policy.autoApproval.limit, policy.autoApproval.auditRate); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.shouldShowAutoApprovalOptions).toBe(true); + expect(updatedPolicy?.autoApproval?.limit).toBe(CONST.POLICY.AUTO_APPROVE_REPORTS_UNDER_SUGGESTED_CENTS); + expect(updatedPolicy?.autoApproval?.auditRate).toBe(CONST.POLICY.RANDOM_AUDIT_SUGGESTED_PERCENTAGE); + expect(updatedPolicy?.pendingFields?.shouldShowAutoApprovalOptions).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.shouldShowAutoApprovalOptions).toBeUndefined(); + }); + + it('should revert auto approval options when fail', async () => { + // Given a workspace with auto approval options disabled + const policy = { + ...createRandomPolicy(0), + shouldShowAutoApprovalOptions: false, + autoApproval: {limit: 0, auditRate: 0}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When enabling auto approval options but fail + mockFetch.fail(); + Policy.enableAutoApprovalOptions(policy.id, true, policy.shouldShowAutoApprovalOptions, policy.autoApproval.limit, policy.autoApproval.auditRate); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.shouldShowAutoApprovalOptions).toBe(false); + expect(updatedPolicy?.autoApproval?.limit).toBe(0); + expect(updatedPolicy?.autoApproval?.auditRate).toBe(0); + expect(updatedPolicy?.pendingFields?.shouldShowAutoApprovalOptions).toBeUndefined(); + }); + }); + + describe('setPolicyAutoReimbursementLimit', () => { + it('should update auto reimbursement limit optimistically and succeed', async () => { + // Given a workspace with auto reimbursement limit 100 + const policy = { + ...createRandomPolicy(0), + autoReimbursement: {limit: 10000}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When setting auto reimbursement limit to 200 + Policy.setPolicyAutoReimbursementLimit(policy.id, '200', policy.autoReimbursement.limit); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReimbursement?.limit).toBe(20000); + expect(updatedPolicy?.autoReimbursement?.pendingFields?.limit).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReimbursement?.pendingFields?.limit).toBeUndefined(); + }); + + it('should revert auto reimbursement limit when fail', async () => { + // Given a workspace with auto reimbursement limit 100 + const policy = { + ...createRandomPolicy(0), + autoReimbursement: {limit: 10000}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When setting auto reimbursement limit to 200 but fail + mockFetch.fail(); + Policy.setPolicyAutoReimbursementLimit(policy.id, '200', policy.autoReimbursement.limit); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.autoReimbursement?.limit).toBe(10000); + expect(updatedPolicy?.autoReimbursement?.pendingFields?.limit).toBeUndefined(); + expect(updatedPolicy?.errorFields?.autoReimbursement).toBeTruthy(); + }); + }); + + describe('enablePolicyAutoReimbursementLimit', () => { + it('should enable auto reimbursement limit option optimistically and succeed', async () => { + // Given a workspace with auto reimbursement limit option disabled + const policy = { + ...createRandomPolicy(0), + shouldShowAutoReimbursementLimitOption: false, + autoReimbursement: {limit: 0}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + mockFetch.pause(); + + // When enabling auto reimbursement limit option + Policy.enablePolicyAutoReimbursementLimit(policy.id, true, policy.shouldShowAutoReimbursementLimitOption, policy.autoReimbursement.limit); + + // Then optimistic data should be set in Onyx + await waitForBatchedUpdates(); + let updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.shouldShowAutoReimbursementLimitOption).toBe(true); + expect(updatedPolicy?.autoReimbursement?.limit).toBe(CONST.POLICY.AUTO_REIMBURSEMENT_LIMIT_SUGGESTED_CENTS); + expect(updatedPolicy?.pendingFields?.shouldShowAutoReimbursementLimitOption).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + + // When the fetch resumes and succeeds + await mockFetch.resume(); + + // Then pendingFields should be cleared + updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.pendingFields?.shouldShowAutoReimbursementLimitOption).toBeUndefined(); + }); + + it('should revert auto reimbursement limit option when fail', async () => { + // Given a workspace with auto reimbursement limit option disabled + const policy = { + ...createRandomPolicy(0), + shouldShowAutoReimbursementLimitOption: false, + autoReimbursement: {limit: 0}, + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, policy); + + // When enabling auto reimbursement limit option but fail + mockFetch.fail(); + Policy.enablePolicyAutoReimbursementLimit(policy.id, true, policy.shouldShowAutoReimbursementLimitOption, policy.autoReimbursement.limit); + await waitForBatchedUpdates(); + + // Then it should be reverted + const updatedPolicy = await getOnyxValue(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`); + expect(updatedPolicy?.shouldShowAutoReimbursementLimitOption).toBe(false); + expect(updatedPolicy?.autoReimbursement?.limit).toBe(0); + expect(updatedPolicy?.pendingFields?.shouldShowAutoReimbursementLimitOption).toBeUndefined(); + }); + }); }); diff --git a/tests/actions/ShareBankAccountAndWorkspacePayerTest.ts b/tests/actions/ShareBankAccountAndWorkspacePayerTest.ts index b1e72cd8c44c..8815d7045098 100644 --- a/tests/actions/ShareBankAccountAndWorkspacePayerTest.ts +++ b/tests/actions/ShareBankAccountAndWorkspacePayerTest.ts @@ -83,7 +83,7 @@ describe('actions/ShareBankAccountAndWorkspacePayer', () => { const policyID = 'policy_abc'; const reimburserEmail = 'payer@example.com'; - setWorkspacePayer(policyID, reimburserEmail); + setWorkspacePayer(policyID, reimburserEmail, undefined); await waitForBatchedUpdates(); expect(write).toHaveBeenCalledWith(