From 04e8ed0538767bb59e9c96c0dc1fce4c5c068032 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Sun, 31 Mar 2024 16:05:06 +0700 Subject: [PATCH 1/8] Remove deprecated ReportUtils.getPolicy() method --- src/components/SettlementButton.tsx | 10 ++++++++-- src/libs/NextStepUtils.ts | 12 ++++++++++-- src/libs/actions/IOU.ts | 15 +++++++++++---- src/libs/actions/Policy.ts | 17 +++++++++-------- src/pages/workspace/WorkspaceJoinUserPage.tsx | 3 +-- .../actions/EnforceActionExportRestrictions.ts | 5 +++++ 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index c6d603514014b..a76007034fc0d 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -14,7 +14,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type {ButtonSizeValue} from '@src/styles/utils/types'; -import type {LastPaymentMethod, Report} from '@src/types/onyx'; +import type {LastPaymentMethod, Policy, Report} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; @@ -33,6 +33,9 @@ type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEN type SettlementButtonOnyxProps = { /** The last payment method used per policy */ nvpLastPaymentMethod?: OnyxEntry; + + /** The policy of the report */ + policy: OnyxEntry; }; type SettlementButtonProps = SettlementButtonOnyxProps & { @@ -135,6 +138,7 @@ function SettlementButton({ shouldShowPersonalBankAccountOption = false, enterKeyEventListenerPriority = 0, confirmApproval, + policy, }: SettlementButtonProps) { const {translate} = useLocalize(); const {isOffline} = useNetwork(); @@ -143,7 +147,6 @@ function SettlementButton({ PaymentMethods.openWalletPage(); }, []); - const policy = ReportUtils.getPolicy(policyID); const session = useSession(); const chatReport = ReportUtils.getReport(chatReportID); const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport as OnyxEntry); @@ -272,4 +275,7 @@ export default withOnyx({ key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD, selector: (paymentMethod) => paymentMethod ?? {}, }, + policy: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + }, })(SettlementButton); diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 5a19e68afe72a..8b0afe2d24c32 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -1,10 +1,11 @@ import {format, lastDayOfMonth, setDate} from 'date-fns'; import Str from 'expensify-common/lib/str'; import Onyx from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Report, ReportNextStep} from '@src/types/onyx'; +import type {Policy, Report, ReportNextStep} from '@src/types/onyx'; import type {Message} from '@src/types/onyx/ReportNextStep'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; @@ -25,6 +26,13 @@ Onyx.connect({ }, }); +let allPolicies: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.POLICY, + waitForCollectionCallback: true, + callback: (value) => (allPolicies = value), +}); + function parseMessage(messages: Message[] | undefined) { let nextStepHTML = ''; @@ -72,7 +80,7 @@ function buildNextStep( } const {policyID = '', ownerAccountID = -1, managerID = -1} = report; - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const {submitsTo, harvesting, isPreventSelfApprovalEnabled, preventSelfApproval, autoReportingFrequency, autoReportingOffset} = policy; const isOwner = currentUserAccountID === ownerAccountID; const isManager = currentUserAccountID === managerID; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 33cd660b65f94..dd94f394bd6be 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -253,6 +253,13 @@ Onyx.connect({ }, }); +let allPolicies: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.POLICY, + waitForCollectionCallback: true, + callback: (value) => (allPolicies = value), +}); + /** * Initialize money request info * @param reportID to attach the transaction to @@ -440,7 +447,7 @@ function needsToBeManuallySubmitted(iouReport: OnyxTypes.Report) { const isPolicyExpenseChat = ReportUtils.isExpenseReport(iouReport); if (isPolicyExpenseChat) { - const policy = ReportUtils.getPolicy(iouReport.policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport.policyID}`] ?? ({} as OnyxTypes.Policy); const isFromPaidPolicy = PolicyUtils.isPaidGroupPolicy(policy); // If the scheduled submit is turned off on the policy, user needs to manually submit the report which is indicated by GBR in LHN @@ -4598,7 +4605,7 @@ function hasIOUToApproveOrPay(chatReport: OnyxEntry | EmptyObj return Object.values(chatReportActions).some((action) => { const iouReport = ReportUtils.getReport(action.childReportID ?? ''); - const policy = ReportUtils.getPolicy(iouReport?.policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? ({} as OnyxTypes.Policy); const shouldShowSettlementButton = canIOUBePaid(iouReport, chatReport, policy) || canApproveIOU(iouReport, chatReport, policy); return action.childReportID?.toString() !== excludedIOUReportID && action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && shouldShowSettlementButton; @@ -4715,7 +4722,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; const optimisticSubmittedReportAction = ReportUtils.buildOptimisticSubmittedReportAction(expenseReport?.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID); const parentReport = ReportUtils.getReport(expenseReport.parentReportID); - const policy = ReportUtils.getPolicy(expenseReport.policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${expenseReport.policyID}`] ?? ({} as OnyxTypes.Policy); const isCurrentUserManager = currentUserPersonalDetails.accountID === expenseReport.managerID; const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, CONST.REPORT.STATUS_NUM.SUBMITTED); @@ -4820,7 +4827,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { function cancelPayment(expenseReport: OnyxTypes.Report, chatReport: OnyxTypes.Report) { const optimisticReportAction = ReportUtils.buildOptimisticCancelPaymentReportAction(expenseReport.reportID, -(expenseReport.total ?? 0), expenseReport.currency ?? ''); - const policy = ReportUtils.getPolicy(chatReport.policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${chatReport.policyID}`] ?? ({} as OnyxTypes.Policy); const isFree = policy && policy.type === CONST.POLICY.TYPE.FREE; const approvalMode = policy.approvalMode ?? CONST.POLICY.APPROVAL_MODE.BASIC; let stateNum: ValueOf = CONST.REPORT.STATE_NUM.SUBMITTED; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 44258a67618ba..40ecaea2ca60a 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -483,7 +483,7 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[] } function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency: ValueOf) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -531,7 +531,7 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency } function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const optimisticData: OnyxUpdate[] = [ { @@ -572,7 +572,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingOffset: number | ValueOf) { const value = JSON.stringify({autoReportingOffset: autoReportingOffset.toString()}); - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const optimisticData: OnyxUpdate[] = [ { @@ -612,7 +612,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingO } function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: ValueOf) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const value = { approver, @@ -665,7 +665,7 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo } function setWorkspacePayer(policyID: string, reimburserEmail: string, reimburserAccountID: number) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const optimisticData: OnyxUpdate[] = [ { @@ -714,7 +714,7 @@ function clearPolicyErrorField(policyID: string, fieldName: string) { } function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf, reimburserAccountID: number, reimburserEmail: string) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const optimisticData: OnyxUpdate[] = [ { @@ -826,7 +826,8 @@ function removeMembers(accountIDs: number[], policyID: string) { } const membersListKey = `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}` as const; - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const workspaceChats = ReportUtils.getWorkspaceChats(policyID, accountIDs); const optimisticClosedReportActions = workspaceChats.map(() => ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy.name, CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY)); @@ -3974,7 +3975,7 @@ function enablePolicyTaxes(policyID: string, enabled: boolean) { } function enablePolicyWorkflows(policyID: string, enabled: boolean) { - const policy = ReportUtils.getPolicy(policyID); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const onyxData: OnyxData = { optimisticData: [ { diff --git a/src/pages/workspace/WorkspaceJoinUserPage.tsx b/src/pages/workspace/WorkspaceJoinUserPage.tsx index eff129443f02e..05a9e0ec5a993 100644 --- a/src/pages/workspace/WorkspaceJoinUserPage.tsx +++ b/src/pages/workspace/WorkspaceJoinUserPage.tsx @@ -7,7 +7,6 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useThemeStyles from '@hooks/useThemeStyles'; import navigateAfterJoinRequest from '@libs/navigateAfterJoinRequest'; import * as PolicyUtils from '@libs/PolicyUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import Navigation from '@navigation/Navigation'; import type {AuthScreensParamList} from '@navigation/types'; import * as PolicyAction from '@userActions/Policy'; @@ -30,7 +29,7 @@ function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { const styles = useThemeStyles(); const policyID = route?.params?.policyID; const inviterEmail = route?.params?.email; - const policy = ReportUtils.getPolicy(policyID); + const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; const isUnmounted = useRef(false); useEffect(() => { diff --git a/tests/actions/EnforceActionExportRestrictions.ts b/tests/actions/EnforceActionExportRestrictions.ts index 92d96869d02d5..c16c7fb21fb9f 100644 --- a/tests/actions/EnforceActionExportRestrictions.ts +++ b/tests/actions/EnforceActionExportRestrictions.ts @@ -10,6 +10,11 @@ describe('ReportUtils', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal expect(ReportUtils.getParentReport).toBeUndefined(); }); + + it('does not export getPolicy', () => { + // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal + expect(ReportUtils.getPolicy).toBeUndefined(); + }); }); describe('Task', () => { From 7f9b72ed3770f60849eac336d502ef45767b9189 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 1 Apr 2024 11:16:38 +0700 Subject: [PATCH 2/8] remove export getPolicy --- src/libs/ReportUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index c50244f6d4420..e7db103315fb1 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5800,7 +5800,6 @@ export { getReportOfflinePendingActionAndErrors, isDM, isSelfDM, - getPolicy, getWorkspaceChats, shouldDisableRename, hasSingleParticipant, From cf89178ca2a7ae3cb0175cbacd3c9ce8ba2787cf Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 1 Apr 2024 16:21:27 +0700 Subject: [PATCH 3/8] fix lint --- tests/actions/EnforceActionExportRestrictions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/actions/EnforceActionExportRestrictions.ts b/tests/actions/EnforceActionExportRestrictions.ts index 614aa56744cbb..96b72b4d8f007 100644 --- a/tests/actions/EnforceActionExportRestrictions.ts +++ b/tests/actions/EnforceActionExportRestrictions.ts @@ -15,11 +15,11 @@ describe('ReportUtils', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal expect(ReportUtils.isOneTransactionReport).toBeUndefined(); }); - + it('does not export getPolicy', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal expect(ReportUtils.getPolicy).toBeUndefined(); - }) + }); }); describe('Task', () => { From 6f70c2fe75dd23137816dc4f1ad140614e77ab64 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 2 Apr 2024 11:28:33 +0700 Subject: [PATCH 4/8] chore: backup policy --- src/libs/ReportUtils.ts | 3 +++ src/pages/workspace/WorkspaceJoinUserPage.tsx | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e7db103315fb1..95b2d88fa1019 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -570,6 +570,9 @@ function getRootParentReport(report: OnyxEntry | undefined | EmptyObject return getRootParentReport(!isEmptyObject(parentReport) ? parentReport : null); } +/** + * Returns the policy of the report + */ function getPolicy(policyID: string | undefined): Policy | EmptyObject { if (!allPolicies || !policyID) { return {}; diff --git a/src/pages/workspace/WorkspaceJoinUserPage.tsx b/src/pages/workspace/WorkspaceJoinUserPage.tsx index 05a9e0ec5a993..2e3e602a8485d 100644 --- a/src/pages/workspace/WorkspaceJoinUserPage.tsx +++ b/src/pages/workspace/WorkspaceJoinUserPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useEffect, useRef} from 'react'; +import React, {useEffect, useMemo, useRef} from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxCollection} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; @@ -29,7 +29,8 @@ function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { const styles = useThemeStyles(); const policyID = route?.params?.policyID; const inviterEmail = route?.params?.email; - const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy), [policies, policyID]); + const isUnmounted = useRef(false); useEffect(() => { From dce5cb47ee4057822ec492356dc5de33b408e00c Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 3 Apr 2024 10:55:32 +0700 Subject: [PATCH 5/8] fix: logic get policy in workspace join user page --- src/pages/workspace/WorkspaceJoinUserPage.tsx | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/pages/workspace/WorkspaceJoinUserPage.tsx b/src/pages/workspace/WorkspaceJoinUserPage.tsx index 2e3e602a8485d..3b583cbc542b7 100644 --- a/src/pages/workspace/WorkspaceJoinUserPage.tsx +++ b/src/pages/workspace/WorkspaceJoinUserPage.tsx @@ -1,12 +1,11 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useEffect, useMemo, useRef} from 'react'; +import React, {useEffect, useRef} from 'react'; import {withOnyx} from 'react-native-onyx'; -import type {OnyxCollection} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import ScreenWrapper from '@components/ScreenWrapper'; import useThemeStyles from '@hooks/useThemeStyles'; import navigateAfterJoinRequest from '@libs/navigateAfterJoinRequest'; -import * as PolicyUtils from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import type {AuthScreensParamList} from '@navigation/types'; import * as PolicyAction from '@userActions/Policy'; @@ -14,10 +13,11 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {Policy} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; type WorkspaceJoinUserPageOnyxProps = { - /** The list of this user's policies */ - policies: OnyxCollection; + /** The policy of the report */ + policy: OnyxEntry; }; type WorkspaceJoinUserPageRoute = {route: StackScreenProps['route']}; @@ -25,11 +25,10 @@ type WorkspaceJoinUserPageProps = WorkspaceJoinUserPageRoute & WorkspaceJoinUser let isJoinLinkUsed = false; -function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { +function WorkspaceJoinUserPage({route, policy}: WorkspaceJoinUserPageProps) { const styles = useThemeStyles(); const policyID = route?.params?.policyID; const inviterEmail = route?.params?.email; - const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy), [policies, policyID]); const isUnmounted = useRef(false); @@ -41,11 +40,10 @@ function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { }, []); useEffect(() => { - if (!policy || !policies || isUnmounted.current || isJoinLinkUsed) { + if (!policy || isUnmounted.current || isJoinLinkUsed) { return; } - const isPolicyMember = PolicyUtils.isPolicyMember(policyID, policies as Record); - if (isPolicyMember) { + if (!isEmptyObject(policy)) { Navigation.isNavigationReady().then(() => { Navigation.goBack(undefined, false, true); Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID ?? '')); @@ -60,7 +58,7 @@ function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { } navigateAfterJoinRequest(); }); - }, [policy, policyID, policies, inviterEmail]); + }, [policy, policyID, inviterEmail]); useEffect( () => () => { @@ -78,7 +76,7 @@ function WorkspaceJoinUserPage({route, policies}: WorkspaceJoinUserPageProps) { WorkspaceJoinUserPage.displayName = 'WorkspaceJoinUserPage'; export default withOnyx({ - policies: { - key: ONYXKEYS.COLLECTION.POLICY, + policy: { + key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY}${route?.params?.policyID}`, }, })(WorkspaceJoinUserPage); From 6a5616335cbf460f696a337c8b5a9b57bd929c6f Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 3 Apr 2024 15:01:15 +0700 Subject: [PATCH 6/8] remove empty line --- src/pages/workspace/WorkspaceJoinUserPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceJoinUserPage.tsx b/src/pages/workspace/WorkspaceJoinUserPage.tsx index 3b583cbc542b7..09f8e9425c743 100644 --- a/src/pages/workspace/WorkspaceJoinUserPage.tsx +++ b/src/pages/workspace/WorkspaceJoinUserPage.tsx @@ -29,7 +29,6 @@ function WorkspaceJoinUserPage({route, policy}: WorkspaceJoinUserPageProps) { const styles = useThemeStyles(); const policyID = route?.params?.policyID; const inviterEmail = route?.params?.email; - const isUnmounted = useRef(false); useEffect(() => { From 448ad89e3654a9b088af399558d233cb4336bcfe Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 3 Apr 2024 15:42:31 +0700 Subject: [PATCH 7/8] add local function get policy --- src/libs/actions/Policy.ts | 36 ++++++++++++------- .../EnforceActionExportRestrictions.ts | 8 +++++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 515d46092de61..d0f641ccebe38 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -275,6 +275,16 @@ function isCurrencySupportedForDirectReimbursement(currency: string) { return currency === CONST.CURRENCY.USD; } +/** + * Returns the policy of the report + */ +function getPolicy(policyID: string | undefined): Policy | EmptyObject { + if (!allPolicies || !policyID) { + return {}; + } + return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {}; +} + /** * Check if the user has any active free policies (aka workspaces) */ @@ -483,7 +493,7 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[] } function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency: ValueOf) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -531,7 +541,7 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency } function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const optimisticData: OnyxUpdate[] = [ { @@ -572,7 +582,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingOffset: number | ValueOf) { const value = JSON.stringify({autoReportingOffset: autoReportingOffset.toString()}); - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const optimisticData: OnyxUpdate[] = [ { @@ -612,7 +622,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingO } function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: ValueOf) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const value = { approver, @@ -665,7 +675,7 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo } function setWorkspacePayer(policyID: string, reimburserEmail: string, reimburserAccountID: number) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const optimisticData: OnyxUpdate[] = [ { @@ -714,7 +724,7 @@ function clearPolicyErrorField(policyID: string, fieldName: string) { } function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf, reimburserAccountID: number, reimburserEmail: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const optimisticData: OnyxUpdate[] = [ { @@ -821,7 +831,7 @@ function removeMembers(accountIDs: number[], policyID: string) { } const membersListKey = `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}` as const; - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const workspaceChats = ReportUtils.getWorkspaceChats(policyID, accountIDs); const optimisticClosedReportActions = workspaceChats.map(() => ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy.name, CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY)); @@ -1023,7 +1033,7 @@ function updateWorkspaceMembersRole(policyID: string, accountIDs: number[], newR } function requestWorkspaceOwnerChange(policyID: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const ownershipChecks = {...policyOwnershipChecks?.[policyID]} ?? {}; const changeOwnerErrors = Object.keys(policy?.errorFields?.changeOwner ?? {}); @@ -3915,7 +3925,7 @@ function enablePolicyTaxes(policyID: string, enabled: boolean) { }, ], }; - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = getPolicy(policyID); const shouldAddDefaultTaxRatesData = (!policy?.taxRates || isEmptyObject(policy.taxRates)) && enabled; const onyxData: OnyxData = { optimisticData: [ @@ -3974,7 +3984,7 @@ function enablePolicyTaxes(policyID: string, enabled: boolean) { } function enablePolicyWorkflows(policyID: string, enabled: boolean) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); + const policy = getPolicy(policyID); const onyxData: OnyxData = { optimisticData: [ { @@ -4626,7 +4636,7 @@ function deletePolicyDistanceRates(policyID: string, customUnit: CustomUnit, rat } function setPolicyCustomTaxName(policyID: string, customTaxName: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = getPolicy(policyID); const originalCustomTaxName = policy?.taxRates?.name; const onyxData: OnyxData = { optimisticData: [ @@ -4678,7 +4688,7 @@ function setPolicyCustomTaxName(policyID: string, customTaxName: string) { } function setWorkspaceCurrencyDefault(policyID: string, taxCode: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = getPolicy(policyID); const originalDefaultExternalID = policy?.taxRates?.defaultExternalID; const onyxData: OnyxData = { optimisticData: [ @@ -4730,7 +4740,7 @@ function setWorkspaceCurrencyDefault(policyID: string, taxCode: string) { } function setForeignCurrencyDefault(policyID: string, taxCode: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = getPolicy(policyID); const originalDefaultForeignCurrencyID = policy?.taxRates?.foreignTaxDefault; const onyxData: OnyxData = { optimisticData: [ diff --git a/tests/actions/EnforceActionExportRestrictions.ts b/tests/actions/EnforceActionExportRestrictions.ts index 96b72b4d8f007..bbd2188d5b915 100644 --- a/tests/actions/EnforceActionExportRestrictions.ts +++ b/tests/actions/EnforceActionExportRestrictions.ts @@ -1,3 +1,4 @@ +import * as Policy from '@libs/actions/Policy'; import * as ReportUtils from '@libs/ReportUtils'; import * as Task from '@userActions/Task'; @@ -22,6 +23,13 @@ describe('ReportUtils', () => { }); }); +describe('ReportUtils', () => { + it('does not export getPolicy', () => { + // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal + expect(Policy.getPolicy).toBeUndefined(); + }); +}); + describe('Task', () => { it('does not export getParentReport', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal From 5eb8ee21401671d2fec4742c16dd211d3561dcf1 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 3 Apr 2024 16:02:06 +0700 Subject: [PATCH 8/8] add local function get policy in iou --- src/libs/actions/IOU.ts | 19 ++++++++++++++----- .../EnforceActionExportRestrictions.ts | 10 +++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d2582505286f0..ad040c260f2aa 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -256,6 +256,16 @@ Onyx.connect({ callback: (value) => (allPolicies = value), }); +/** + * Returns the policy of the report + */ +function getPolicy(policyID: string | undefined): OnyxTypes.Policy | EmptyObject { + if (!allPolicies || !policyID) { + return {}; + } + return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {}; +} + /** * Initialize money request info * @param reportID to attach the transaction to @@ -444,7 +454,7 @@ function needsToBeManuallySubmitted(iouReport: OnyxTypes.Report) { const isPolicyExpenseChat = ReportUtils.isExpenseReport(iouReport); if (isPolicyExpenseChat) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport.policyID}`] ?? ({} as OnyxTypes.Policy); + const policy = getPolicy(iouReport.policyID); const isFromPaidPolicy = PolicyUtils.isPaidGroupPolicy(policy); // If the scheduled submit is turned off on the policy, user needs to manually submit the report which is indicated by GBR in LHN @@ -4654,8 +4664,7 @@ function hasIOUToApproveOrPay(chatReport: OnyxEntry | EmptyObj return Object.values(chatReportActions).some((action) => { const iouReport = ReportUtils.getReport(action.childReportID ?? ''); - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? ({} as OnyxTypes.Policy); - + const policy = getPolicy(iouReport?.policyID); const shouldShowSettlementButton = canIOUBePaid(iouReport, chatReport, policy) || canApproveIOU(iouReport, chatReport, policy); return action.childReportID?.toString() !== excludedIOUReportID && action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && shouldShowSettlementButton; }); @@ -4771,7 +4780,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; const optimisticSubmittedReportAction = ReportUtils.buildOptimisticSubmittedReportAction(expenseReport?.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID); const parentReport = ReportUtils.getReport(expenseReport.parentReportID); - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${expenseReport.policyID}`] ?? ({} as OnyxTypes.Policy); + const policy = getPolicy(expenseReport.policyID); const isCurrentUserManager = currentUserPersonalDetails.accountID === expenseReport.managerID; const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, CONST.REPORT.STATUS_NUM.SUBMITTED); const isSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); @@ -4894,7 +4903,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { function cancelPayment(expenseReport: OnyxTypes.Report, chatReport: OnyxTypes.Report) { const optimisticReportAction = ReportUtils.buildOptimisticCancelPaymentReportAction(expenseReport.reportID, -(expenseReport.total ?? 0), expenseReport.currency ?? ''); - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${chatReport.policyID}`] ?? ({} as OnyxTypes.Policy); + const policy = getPolicy(chatReport.policyID); const isFree = policy && policy.type === CONST.POLICY.TYPE.FREE; const approvalMode = policy.approvalMode ?? CONST.POLICY.APPROVAL_MODE.BASIC; let stateNum: ValueOf = CONST.REPORT.STATE_NUM.SUBMITTED; diff --git a/tests/actions/EnforceActionExportRestrictions.ts b/tests/actions/EnforceActionExportRestrictions.ts index bbd2188d5b915..6af42e5f93c18 100644 --- a/tests/actions/EnforceActionExportRestrictions.ts +++ b/tests/actions/EnforceActionExportRestrictions.ts @@ -1,3 +1,4 @@ +import * as IOU from '@libs/actions/IOU'; import * as Policy from '@libs/actions/Policy'; import * as ReportUtils from '@libs/ReportUtils'; import * as Task from '@userActions/Task'; @@ -23,13 +24,20 @@ describe('ReportUtils', () => { }); }); -describe('ReportUtils', () => { +describe('Policy', () => { it('does not export getPolicy', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal expect(Policy.getPolicy).toBeUndefined(); }); }); +describe('IOU', () => { + it('does not export getPolicy', () => { + // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal + expect(IOU.getPolicy).toBeUndefined(); + }); +}); + describe('Task', () => { it('does not export getParentReport', () => { // @ts-expect-error the test is asserting that it's undefined, so the TS error is normal