diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 56be27480e5b2..93af3acb93574 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11083,6 +11083,7 @@ function createDraftTransactionAndNavigateToParticipantSelector( introSelected: OnyxEntry, allTransactionDrafts: OnyxCollection, activePolicy: OnyxEntry, + userBillingGraceEndPeriodCollection: OnyxCollection, isRestrictedToPreferredPolicy = false, preferredPolicyID?: string, ): void { @@ -11148,7 +11149,7 @@ function createDraftTransactionAndNavigateToParticipantSelector( } if (actionName === CONST.IOU.ACTION.CATEGORIZE) { - if (activePolicy && shouldRestrictUserBillableActions(activePolicy.id)) { + if (activePolicy && shouldRestrictUserBillableActions(activePolicy.id, userBillingGraceEndPeriodCollection)) { Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(activePolicy.id)); return; } diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index ce32a79fcb54f..89b9f0e5eeb06 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -164,6 +164,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail const expensifyIcons = useMemoizedLazyExpensifyIcons(['Users', 'Gear', 'Send', 'Folder', 'UserPlus', 'Pencil', 'Checkmark', 'Building', 'Exit', 'Bug', 'Camera', 'Trashcan']); const backTo = route.params.backTo; + const [userBillingGraceEndPeriodCollection] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, {canBeMissing: true}); const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`, {canBeMissing: true}); const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report.chatReportID}`, {canBeMissing: true}); const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, {canBeMissing: true}); @@ -458,6 +459,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail introSelected, allTransactionDrafts, activePolicy, + undefined, isRestrictedToPreferredPolicy, preferredPolicyID, ); @@ -479,6 +481,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail introSelected, allTransactionDrafts, activePolicy, + userBillingGraceEndPeriodCollection, ); }, }); @@ -497,6 +500,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail introSelected, allTransactionDrafts, activePolicy, + undefined, ); }, }); @@ -623,6 +627,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail activePolicy, parentReport, reportActionsForOriginalReportID, + userBillingGraceEndPeriodCollection, ]); const displayNamesWithTooltips = useMemo(() => { diff --git a/src/pages/inbox/report/PureReportActionItem.tsx b/src/pages/inbox/report/PureReportActionItem.tsx index 260bb9ece4801..e153093dae199 100644 --- a/src/pages/inbox/report/PureReportActionItem.tsx +++ b/src/pages/inbox/report/PureReportActionItem.tsx @@ -400,6 +400,7 @@ type PureReportActionItemProps = { introSelected: OnyxEntry, allTransactionDrafts: OnyxCollection, activePolicy: OnyxEntry, + userBillingGraceEndPeriodCollection: OnyxCollection, isRestrictedToPreferredPolicy?: boolean, preferredPolicyID?: string, ) => void; @@ -473,6 +474,8 @@ type PureReportActionItemProps = { /** Report metadata for the report */ reportMetadata?: OnyxEntry; + + userBillingGraceEndPeriodCollection: OnyxCollection; }; // This is equivalent to returning a negative boolean in normal functions, but we can keep the element return type @@ -548,6 +551,7 @@ function PureReportActionItem({ reportNameValuePairsOrigin, reportNameValuePairsOriginalID, reportMetadata, + userBillingGraceEndPeriodCollection, }: PureReportActionItemProps) { const {transitionActionSheetState} = ActionSheetAwareScrollView.useActionSheetAwareScrollViewActions(); const {translate, formatPhoneNumber, localeCompare, formatTravelDate, getLocalDateFromDatetime, datetimeToCalendarTime} = useLocalize(); @@ -946,6 +950,7 @@ function PureReportActionItem({ introSelected, allTransactionDrafts, activePolicy, + undefined, isRestrictedToPreferredPolicy, preferredPolicyID, ); @@ -967,6 +972,7 @@ function PureReportActionItem({ introSelected, allTransactionDrafts, activePolicy, + userBillingGraceEndPeriodCollection, ); }, }, @@ -982,6 +988,7 @@ function PureReportActionItem({ introSelected, allTransactionDrafts, activePolicy, + undefined, ); }, }, @@ -1126,6 +1133,7 @@ function PureReportActionItem({ report, originalReport, personalPolicyID, + userBillingGraceEndPeriodCollection, ]); /** diff --git a/src/pages/inbox/report/ReportActionItem.tsx b/src/pages/inbox/report/ReportActionItem.tsx index baa357264828d..87b08c54eb20d 100644 --- a/src/pages/inbox/report/ReportActionItem.tsx +++ b/src/pages/inbox/report/ReportActionItem.tsx @@ -38,7 +38,7 @@ import PureReportActionItem from './PureReportActionItem'; type ReportActionItemProps = Omit< PureReportActionItemProps, - 'taskReport' | 'linkedReport' | 'iouReportOfLinkedReport' | 'currentUserAccountID' | 'personalPolicyID' | 'allTransactionDrafts' + 'taskReport' | 'linkedReport' | 'iouReportOfLinkedReport' | 'currentUserAccountID' | 'personalPolicyID' | 'allTransactionDrafts' | 'userBillingGraceEndPeriodCollection' > & { /** All the data of the report collection */ allReports: OnyxCollection; @@ -110,6 +110,7 @@ function ReportActionItem({ const [cardList] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true}); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST, {canBeMissing: true}); const [personalPolicyID] = useOnyx(ONYXKEYS.PERSONAL_POLICY_ID, {canBeMissing: true}); + const [userBillingGraceEndPeriodCollection] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, {canBeMissing: true}); const transactionsOnIOUReport = useReportTransactions(iouReport?.reportID); const transactionID = isMoneyRequestAction(action) && getOriginalMessage(action)?.IOUTransactionID; @@ -192,6 +193,7 @@ function ReportActionItem({ isTryNewDotNVPDismissed={isTryNewDotNVPDismissed} bankAccountList={bankAccountList} reportMetadata={reportMetadata} + userBillingGraceEndPeriodCollection={userBillingGraceEndPeriodCollection} /> ); } diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 0a3565e655546..e627a072b99d0 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -590,6 +590,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, {}, undefined, + undefined, ); await waitForBatchedUpdates(); @@ -1149,6 +1150,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, {}, undefined, + undefined, ); await waitForBatchedUpdates(); @@ -1559,6 +1561,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, allTransactionDrafts, undefined, + undefined, ); await waitForBatchedUpdates(); @@ -1605,6 +1608,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, {}, undefined, + undefined, ); await waitForBatchedUpdates(); @@ -1640,6 +1644,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, {}, undefined, + undefined, ); await waitForBatchedUpdates(); @@ -1670,6 +1675,7 @@ describe('actions/IOU', () => { {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, {}, undefined, + undefined, ); await waitForBatchedUpdates(); diff --git a/tests/ui/PureReportActionItemTest.tsx b/tests/ui/PureReportActionItemTest.tsx index e9e6cf986ce7e..be9287b8055fa 100644 --- a/tests/ui/PureReportActionItemTest.tsx +++ b/tests/ui/PureReportActionItemTest.tsx @@ -112,6 +112,7 @@ describe('PureReportActionItem', () => { iouReportOfLinkedReport={undefined} currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} + userBillingGraceEndPeriodCollection={undefined} /> @@ -292,6 +293,7 @@ describe('PureReportActionItem', () => { reportMetadata={reportMetadata} currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} + userBillingGraceEndPeriodCollection={undefined} /> @@ -350,6 +352,7 @@ describe('PureReportActionItem', () => { iouReportOfLinkedReport={undefined} currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} + userBillingGraceEndPeriodCollection={undefined} /> @@ -420,6 +423,7 @@ describe('PureReportActionItem', () => { iouReportOfLinkedReport={undefined} currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} + userBillingGraceEndPeriodCollection={undefined} /> @@ -485,6 +489,7 @@ describe('PureReportActionItem', () => { iouReportOfLinkedReport={undefined} currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} + userBillingGraceEndPeriodCollection={undefined} /> @@ -537,6 +542,7 @@ describe('PureReportActionItem', () => { currentUserAccountID={ACTOR_ACCOUNT_ID} allTransactionDrafts={undefined} modifiedExpenseMessage={modifiedExpenseMessage} + userBillingGraceEndPeriodCollection={undefined} /> diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 43073d01d9cb9..fbbab3c45f9b7 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -12136,7 +12136,7 @@ describe('ReportUtils', () => { await Onyx.merge(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, Math.floor(Date.now() / 1000) - 3600); // When we call createDraftTransactionAndNavigateToParticipantSelector with the restricted policy - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy, undefined); // Then it should navigate to the restricted action page expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.RESTRICTED_ACTION.getRoute(activePolicy.id)); @@ -12164,7 +12164,7 @@ describe('ReportUtils', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseReport.reportID}`, policyExpenseReport); // When we call createDraftTransactionAndNavigateToParticipantSelector - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy, undefined); // Then it should navigate to the category step expect(Navigation.navigate).toHaveBeenCalledWith( @@ -12194,7 +12194,7 @@ describe('ReportUtils', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseReport.reportID}`, policyExpenseReport); // When we call createDraftTransactionAndNavigateToParticipantSelector with undefined activePolicy - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '2', CONST.IOU.ACTION.CATEGORIZE, '2', undefined, undefined, undefined); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '2', CONST.IOU.ACTION.CATEGORIZE, '2', undefined, undefined, undefined, undefined); // Then it should automatically pick the available policy and navigate to the category step expect(Navigation.navigate).toHaveBeenCalledWith( @@ -12211,7 +12211,7 @@ describe('ReportUtils', () => { await Onyx.setCollection(ONYXKEYS.COLLECTION.POLICY, {}); // When we call createDraftTransactionAndNavigateToParticipantSelector with undefined activePolicy - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, undefined); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, undefined, undefined); // Then it should navigate to the upgrade page because no policies were found to categorize with expect(Navigation.navigate).toHaveBeenCalledWith( @@ -12249,7 +12249,7 @@ describe('ReportUtils', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy2.id}`, policy2); // When we call createDraftTransactionAndNavigateToParticipantSelector with undefined activePolicy - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, undefined); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, undefined, undefined); // Then it should navigate to the upgrade page because it's ambiguous which policy to use expect(Navigation.navigate).toHaveBeenCalledWith( @@ -12283,7 +12283,7 @@ describe('ReportUtils', () => { await Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${activePolicy.id}`, activePolicy); // When we call createDraftTransactionAndNavigateToParticipantSelector - createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy); + createDraftTransactionAndNavigateToParticipantSelector(transaction.transactionID, '1', CONST.IOU.ACTION.CATEGORIZE, '1', undefined, undefined, activePolicy, undefined); // Then it should log a warning and not navigate expect(logWarnSpy).toHaveBeenCalledWith('policyExpenseReportID is not valid during expense categorizing');