diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index d3916220ca88..7a7e4e584363 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -4,8 +4,10 @@ import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx, withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; +import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; @@ -227,6 +229,11 @@ function SettlementButton({ }, [currency, formattedAmount, iouReport, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton, shouldDisableApproveButton]); const selectPaymentType = (event: KYCFlowEvent, iouPaymentType: PaymentMethodType, triggerKYCFlow: TriggerKYCFlow) => { + if (policy && SubscriptionUtils.shouldRestrictUserBillableActions(policy.id)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(policy.id)); + return; + } + if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { triggerKYCFlow(event, iouPaymentType); BankAccounts.setPersonalBankAccountContinueKYCOnSuccess(ROUTES.ENABLE_PAYMENTS); diff --git a/src/languages/en.ts b/src/languages/en.ts index eaf22051dd12..fca5b64eb00e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3516,7 +3516,7 @@ export default { preTrial: { title: 'Start a free trial', subtitle: 'To get started, ', - subtitleLink: 'complete your setup checklist here', + subtitleLink: 'complete your setup checklist here.', }, }, cardSection: { diff --git a/src/languages/es.ts b/src/languages/es.ts index 87369d407d77..964e72f3656b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -4018,7 +4018,7 @@ export default { preTrial: { title: 'Iniciar una prueba gratuita', subtitle: 'Para empezar, ', - subtitleLink: 'completa la lista de configuración aquí', + subtitleLink: 'completa la lista de configuración aquí.', }, }, cardSection: { diff --git a/src/libs/SubscriptionUtils.ts b/src/libs/SubscriptionUtils.ts index c8ce7a455906..8569a3f03128 100644 --- a/src/libs/SubscriptionUtils.ts +++ b/src/libs/SubscriptionUtils.ts @@ -5,6 +5,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {BillingGraceEndPeriod, BillingStatus, Fund, FundList, Policy, StripeCustomerID} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import * as PolicyUtils from './PolicyUtils'; const PAYMENT_STATUS = { POLICY_OWNER_WITH_AMOUNT_OWED: 'policy_owner_with_amount_owed', @@ -21,6 +22,14 @@ const PAYMENT_STATUS = { GENERIC_API_ERROR: 'generic_api_error', } as const; +let currentUserAccountID = -1; +Onyx.connect({ + key: ONYXKEYS.SESSION, + callback: (value) => { + currentUserAccountID = value?.accountID ?? -1; + }, +}); + let amountOwed: OnyxEntry; Onyx.connect({ key: ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED, @@ -401,6 +410,8 @@ function doesUserHavePaymentCardAdded(): boolean { function shouldRestrictUserBillableActions(policyID: string): boolean { const currentDate = new Date(); + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + // This logic will be executed if the user is a workspace's non-owner (normal user or admin). // We should restrict the workspace's non-owner actions if it's member of a workspace where the owner is // past due and is past its grace period end. @@ -409,10 +420,9 @@ function shouldRestrictUserBillableActions(policyID: string): boolean { if (userBillingGracePeriodEnd && isAfter(currentDate, fromUnixTime(userBillingGracePeriodEnd.value))) { // Extracts the owner account ID from the collection member key. - const ownerAccountID = entryKey.slice(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END.length); + const ownerAccountID = Number(entryKey.slice(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END.length)); - const ownerPolicy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; - if (String(ownerPolicy?.ownerAccountID ?? -1) === ownerAccountID) { + if (PolicyUtils.isPolicyOwner(policy, ownerAccountID)) { return true; } } @@ -420,7 +430,13 @@ function shouldRestrictUserBillableActions(policyID: string): boolean { // If it reached here it means that the user is actually the workspace's owner. // We should restrict the workspace's owner actions if it's past its grace period end date and it's owing some amount. - if (ownerBillingGraceEndPeriod && amountOwed !== undefined && amountOwed > 0 && isAfter(currentDate, fromUnixTime(ownerBillingGraceEndPeriod))) { + if ( + PolicyUtils.isPolicyOwner(policy, currentUserAccountID) && + ownerBillingGraceEndPeriod && + amountOwed !== undefined && + amountOwed > 0 && + isAfter(currentDate, fromUnixTime(ownerBillingGraceEndPeriod)) + ) { return true; } diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a4a53346aa9c..645b547e7088 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -44,6 +44,7 @@ import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import type {OptimisticChatReport, OptimisticCreatedReportAction, OptimisticIOUReportAction, TransactionDetails} from '@libs/ReportUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import ViolationsUtils from '@libs/Violations/ViolationsUtils'; import type {IOUAction, IOUType} from '@src/CONST'; @@ -6218,6 +6219,11 @@ function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedI } function approveMoneyRequest(expenseReport: OnyxEntry, full?: boolean) { + if (expenseReport?.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(expenseReport.policyID)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(expenseReport.policyID)); + return; + } + const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`] ?? null; let total = expenseReport?.total ?? 0; const hasHeldExpenses = ReportUtils.hasHeldExpenses(expenseReport?.reportID); @@ -6351,6 +6357,11 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: } function submitReport(expenseReport: OnyxTypes.Report) { + if (expenseReport.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(expenseReport.policyID)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(expenseReport.policyID)); + return; + } + const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; const parentReport = getReportOrDraftReport(expenseReport.parentReportID); const policy = PolicyUtils.getPolicy(expenseReport.policyID); @@ -6581,6 +6592,11 @@ function cancelPayment(expenseReport: OnyxTypes.Report, chatReport: OnyxTypes.Re } function payMoneyRequest(paymentType: PaymentMethodType, chatReport: OnyxTypes.Report, iouReport: OnyxTypes.Report, full = true) { + if (chatReport.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(chatReport.policyID)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(chatReport.policyID)); + return; + } + const recipient = {accountID: iouReport.ownerAccountID}; const {params, optimisticData, successData, failureData} = getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentType, full); diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx index efc9c36de51a..b8880f372809 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceAdminRestrictedAction.tsx @@ -10,7 +10,6 @@ import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Report from '@libs/actions/Report'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; import variables from '@styles/variables'; @@ -28,7 +27,7 @@ function WorkspaceAdminRestrictedAction({policyID}: WorkspaceAdminRestrictedActi const openAdminsReport = useCallback(() => { const reportID = `${PolicyUtils.getPolicy(policyID)?.chatReportIDAdmins}` ?? '-1'; - Report.openReport(reportID); + Navigation.closeRHPFlow(); Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID)); }, [policyID]); diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction.tsx index fd6d0fc717b8..52156c05a873 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceOwnerRestrictedAction.tsx @@ -20,6 +20,7 @@ function WorkspaceOwnerRestrictedAction() { const styles = useThemeStyles(); const addPaymentCard = () => { + Navigation.closeRHPFlow(); Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION); }; diff --git a/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx b/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx index 33c159446398..4d2aabd8774e 100644 --- a/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx +++ b/src/pages/RestrictedAction/Workspace/WorkspaceUserRestrictedAction.tsx @@ -10,7 +10,6 @@ import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Report from '@libs/actions/Report'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; @@ -28,7 +27,7 @@ function WorkspaceUserRestrictedAction({policyID}: WorkspaceUserRestrictedAction const openPolicyExpenseReport = useCallback(() => { const reportID = ReportUtils.findPolicyExpenseChatByPolicyID(policyID)?.reportID ?? '-1'; - Report.openReport(reportID); + Navigation.closeRHPFlow(); Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID)); }, [policyID]); diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index fd9a244f210b..0119c3e39871 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -19,13 +19,16 @@ import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as Browser from '@libs/Browser'; import getIconForAction from '@libs/getIconForAction'; +import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; +import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as IOU from '@userActions/IOU'; import * as Report from '@userActions/Report'; import * as Task from '@userActions/Task'; import type {IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; type MoneyRequestOptions = Record, PopoverMenuItem>; @@ -125,31 +128,40 @@ function AttachmentPickerWithMenuItems({ * Returns the list of IOU Options */ const moneyRequestOptions = useMemo(() => { + const selectOption = (onSelected: () => void, shouldRestrictAction: boolean) => { + if (shouldRestrictAction && policy && SubscriptionUtils.shouldRestrictUserBillableActions(policy.id)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(policy.id)); + return; + } + + onSelected(); + }; + const options: MoneyRequestOptions = { [CONST.IOU.TYPE.SPLIT]: { icon: Expensicons.Transfer, text: translate('iou.splitExpense'), - onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, report?.reportID ?? '-1'), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.SUBMIT]: { icon: getIconForAction(CONST.IOU.TYPE.REQUEST), text: translate('iou.submitExpense'), - onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, report?.reportID ?? '-1'), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.PAY]: { icon: getIconForAction(CONST.IOU.TYPE.SEND), text: translate('iou.paySomeone', {name: ReportUtils.getPayeeName(report)}), - onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, report?.reportID ?? '-1'), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, report?.reportID ?? '-1'), false), }, [CONST.IOU.TYPE.TRACK]: { icon: getIconForAction(CONST.IOU.TYPE.TRACK), text: translate('iou.trackExpense'), - onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? '-1'), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? '-1'), true), }, [CONST.IOU.TYPE.INVOICE]: { icon: Expensicons.InvoiceGeneric, text: translate('workspace.invoices.sendInvoice'), - onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? '-1'), + onSelected: () => selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? '-1'), false), }, }; diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index ff5cfa05b57b..a870948b959a 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -23,6 +23,7 @@ import Navigation from '@libs/Navigation/Navigation'; import type {CentralPaneName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as App from '@userActions/App'; import * as IOU from '@userActions/IOU'; import * as Policy from '@userActions/Policy/Policy'; @@ -228,41 +229,54 @@ function FloatingActionButtonAndPopover( }, [personalDetails, quickActionReport, quickAction?.action, quickActionAvatars]); const navigateToQuickAction = () => { + const selectOption = (onSelected: () => void, shouldRestrictAction: boolean) => { + if (shouldRestrictAction && quickActionReport?.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(quickActionReport.policyID)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(quickActionReport.policyID)); + return; + } + + onSelected(); + }; + const isValidReport = !(isEmptyObject(quickActionReport) || ReportUtils.isArchivedRoom(quickActionReport)); const quickActionReportID = isValidReport ? quickActionReport?.reportID ?? '-1' : ReportUtils.generateReportID(); + switch (quickAction?.action) { case CONST.QUICK_ACTIONS.REQUEST_MANUAL: - IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true), true); return; case CONST.QUICK_ACTIONS.REQUEST_SCAN: - IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true), true); return; case CONST.QUICK_ACTIONS.REQUEST_DISTANCE: - IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true), true); return; case CONST.QUICK_ACTIONS.SPLIT_MANUAL: - IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true), true); return; case CONST.QUICK_ACTIONS.SPLIT_SCAN: - IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true), true); return; case CONST.QUICK_ACTIONS.SPLIT_DISTANCE: - IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.SPLIT, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true), true); return; case CONST.QUICK_ACTIONS.SEND_MONEY: - IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.PAY, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true), false); return; case CONST.QUICK_ACTIONS.ASSIGN_TASK: - Task.clearOutTaskInfoAndNavigate(isValidReport ? quickActionReportID : '', isValidReport ? quickActionReport : undefined, quickAction.targetAccountID ?? -1, true); + selectOption( + () => Task.clearOutTaskInfoAndNavigate(isValidReport ? quickActionReportID : '', isValidReport ? quickActionReport : undefined, quickAction.targetAccountID ?? -1, true), + false, + ); break; case CONST.QUICK_ACTIONS.TRACK_MANUAL: - IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.MANUAL, true), false); break; case CONST.QUICK_ACTIONS.TRACK_SCAN: - IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.SCAN, true), false); break; case CONST.QUICK_ACTIONS.TRACK_DISTANCE: - IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true); + selectOption(() => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, quickActionReportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true), false); break; default: } diff --git a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx index 58e69485c1b3..2ead96854e3a 100644 --- a/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx +++ b/src/pages/iou/request/MoneyRequestParticipantsSelector.tsx @@ -19,13 +19,16 @@ import usePermissions from '@hooks/usePermissions'; import useScreenWrapperTranstionStatus from '@hooks/useScreenWrapperTransitionStatus'; import useThemeStyles from '@hooks/useThemeStyles'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as Policy from '@userActions/Policy/Policy'; import * as Report from '@userActions/Report'; import type {IOUAction, IOURequestType, IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type {Participant} from '@src/types/onyx/IOU'; type MoneyRequestParticipantsSelectorProps = { @@ -380,12 +383,18 @@ function MoneyRequestParticipantsSelector({participants = CONST.EMPTY_ARRAY, onF ]); const onSelectRow = useCallback( - (item: Participant) => { + (option: Participant) => { + if (option.isPolicyExpenseChat && option.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(option.policyID)) { + Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(option.policyID)); + return; + } + if (isIOUSplit) { - addParticipantToSelection(item); + addParticipantToSelection(option); return; } - addSingleParticipant(item); + + addSingleParticipant(option); }, [isIOUSplit, addParticipantToSelection, addSingleParticipant], ); diff --git a/tests/unit/SubscriptionUtilsTest.ts b/tests/unit/SubscriptionUtilsTest.ts index 90781840a718..c997e6f0048a 100644 --- a/tests/unit/SubscriptionUtilsTest.ts +++ b/tests/unit/SubscriptionUtilsTest.ts @@ -179,6 +179,7 @@ describe('SubscriptionUtils', () => { afterEach(async () => { await Onyx.clear(); await Onyx.multiSet({ + [ONYXKEYS.SESSION]: null, [ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END]: null, [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: null, [ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: null, @@ -244,37 +245,72 @@ describe('SubscriptionUtils', () => { expect(SubscriptionUtils.shouldRestrictUserBillableActions(policyID)).toBeTruthy(); }); - it('should return false if the user is a workspace owner but is not past due billing', async () => { + it("should return false if the user is the workspace's owner but is not past due billing", async () => { + const accountID = 1; const policyID = '1001'; await Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email: '', accountID}, [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: getUnixTime(addDays(new Date(), 3)), // not past due + [`${ONYXKEYS.COLLECTION.POLICY}${policyID}` as const]: { + ...createRandomPolicy(Number(policyID)), + ownerAccountID: accountID, + }, }); expect(SubscriptionUtils.shouldRestrictUserBillableActions(policyID)).toBeFalsy(); }); - it("should return false if the user is a workspace owner but is past due billing but isn't owning any amount", async () => { + it("should return false if the user is the workspace's owner that is past due billing but isn't owning any amount", async () => { + const accountID = 1; const policyID = '1001'; await Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email: '', accountID}, [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: getUnixTime(subDays(new Date(), 3)), // past due [ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: 0, + [`${ONYXKEYS.COLLECTION.POLICY}${policyID}` as const]: { + ...createRandomPolicy(Number(policyID)), + ownerAccountID: accountID, + }, }); expect(SubscriptionUtils.shouldRestrictUserBillableActions(policyID)).toBeFalsy(); }); - it('should return true if the user is a workspace owner but is past due billing and is owning some amount', async () => { + it("should return true if the user is the workspace's owner that is past due billing and is owning some amount", async () => { + const accountID = 1; const policyID = '1001'; await Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email: '', accountID}, [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: getUnixTime(subDays(new Date(), 3)), // past due [ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: 8010, + [`${ONYXKEYS.COLLECTION.POLICY}${policyID}` as const]: { + ...createRandomPolicy(Number(policyID)), + ownerAccountID: accountID, + }, }); expect(SubscriptionUtils.shouldRestrictUserBillableActions(policyID)).toBeTruthy(); }); + + it("should return false if the user is past due billing but is not the workspace's owner", async () => { + const accountID = 1; + const policyID = '1001'; + + await Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email: '', accountID}, + [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: getUnixTime(subDays(new Date(), 3)), // past due + [ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: 8010, + [`${ONYXKEYS.COLLECTION.POLICY}${policyID}` as const]: { + ...createRandomPolicy(Number(policyID)), + ownerAccountID: 2, // not the user + }, + }); + + expect(SubscriptionUtils.shouldRestrictUserBillableActions(policyID)).toBeFalsy(); + }); }); describe('getSubscriptionStatus', () => {