Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated ReportUtils.getPolicy() method #39344

Merged
merged 11 commits into from
Apr 3, 2024
10 changes: 8 additions & 2 deletions src/components/SettlementButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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<LastPaymentMethod>;

/** The policy of the report */
policy: OnyxEntry<Policy>;
};

type SettlementButtonProps = SettlementButtonOnyxProps & {
Expand Down Expand Up @@ -135,6 +138,7 @@ function SettlementButton({
shouldShowPersonalBankAccountOption = false,
enterKeyEventListenerPriority = 0,
confirmApproval,
policy,
}: SettlementButtonProps) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();
Expand All @@ -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<Report>);
Expand Down Expand Up @@ -272,4 +275,7 @@ export default withOnyx<SettlementButtonProps, SettlementButtonOnyxProps>({
key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD,
selector: (paymentMethod) => paymentMethod ?? {},
},
policy: {
key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
},
})(SettlementButton);
12 changes: 10 additions & 2 deletions src/libs/NextStepUtils.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -25,6 +26,13 @@ Onyx.connect({
},
});

let allPolicies: OnyxCollection<Policy>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => (allPolicies = value),
});

function parseMessage(messages: Message[] | undefined) {
let nextStepHTML = '';

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ function getRootParentReport(report: OnyxEntry<Report> | undefined | EmptyObject
}

/**
* @deprecated Use withOnyx or Onyx.connect() instead
* Returns the policy of the report
*/
function getPolicy(policyID: string | undefined): Policy | EmptyObject {
nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
if (!allPolicies || !policyID) {
Expand Down Expand Up @@ -5828,7 +5828,6 @@ export {
getReportOfflinePendingActionAndErrors,
isDM,
isSelfDM,
getPolicy,
getWorkspaceChats,
shouldDisableRename,
hasSingleParticipant,
Expand Down
15 changes: 11 additions & 4 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@ Onyx.connect({
},
});

let allPolicies: OnyxCollection<OnyxTypes.Policy>;
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => (allPolicies = value),
});

/**
* Initialize money request info
* @param reportID to attach the transaction to
Expand Down Expand Up @@ -437,7 +444,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
Expand Down Expand Up @@ -4647,7 +4654,7 @@ function hasIOUToApproveOrPay(chatReport: OnyxEntry<OnyxTypes.Report> | 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;
Expand Down Expand Up @@ -4764,7 +4771,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);
const isSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy);
Expand Down Expand Up @@ -4887,7 +4894,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<typeof CONST.REPORT.STATE_NUM> = CONST.REPORT.STATE_NUM.SUBMITTED;
Expand Down
17 changes: 9 additions & 8 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[]
}

function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency: ValueOf<typeof CONST.POLICY.AUTO_REPORTING_FREQUENCIES>) {
const policy = ReportUtils.getPolicy(policyID);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy);
const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down Expand Up @@ -531,7 +531,7 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency
}

function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf<typeof CONST.POLICY.AUTO_REPORTING_FREQUENCIES>) {
const policy = ReportUtils.getPolicy(policyID);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy);

const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -572,7 +572,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf

function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingOffset: number | ValueOf<typeof CONST.POLICY.AUTO_REPORTING_OFFSET>) {
const value = JSON.stringify({autoReportingOffset: autoReportingOffset.toString()});
const policy = ReportUtils.getPolicy(policyID);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy);

const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -612,7 +612,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingO
}

function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: ValueOf<typeof CONST.POLICY.APPROVAL_MODE>) {
const policy = ReportUtils.getPolicy(policyID);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy);

const value = {
approver,
Expand Down Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB: you could DRY all these up by creating a similar getPolicy() method and then also ensuring that getPolicy() isn't exported in the unit tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nkdengineer Also should do the same thing in src/libs/actions/IOU.ts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you test again to make sure everything works well after these updates?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DylanDylann please check again, i updated code and tested well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nkdengineer Look good but getPolicy function is duplicated

@tgolen Should we create a utils function like this

function getPolicy(policyID: string | undefined, allPolicies): OnyxTypes.Policy | EmptyObject {
    if (!allPolicies || !policyID) {
        return {};
    }
    return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {};
}

And export it to use in all files

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, the balance of DRYness here is difficult to get right. As soon as you export that method, we're back in the same spot that this PR is attempting to clean up. So, I think the DRYness here is acceptable IMO.

Copy link
Contributor

@tgolen tgolen Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I think the DRYness here is acceptable IMO.

I realized right after I posted it that this might not be clear. I am suggesting that we leave the duplicated methods and that it is OK in this instance for it to not be DRY so that no one is tempted to use the exported method when they shouldn't.


const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -714,7 +714,7 @@ function clearPolicyErrorField(policyID: string, fieldName: string) {
}

function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf<typeof CONST.POLICY.REIMBURSEMENT_CHOICES>, reimburserAccountID: number, reimburserEmail: string) {
const policy = ReportUtils.getPolicy(policyID);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy);

const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -821,7 +821,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));

Expand Down Expand Up @@ -3973,7 +3974,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: [
{
Expand Down
6 changes: 3 additions & 3 deletions src/pages/workspace/WorkspaceJoinUserPage.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
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';
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';
Expand All @@ -30,7 +29,8 @@ 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 = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy), [policies, policyID]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first instinct was that this component doesn't need to connect to the entire policy collection. It looks like the only reason it connects to the entire collection is pass all policies to PolicyUtils.isPolicyMember(). All that method does is check that Onyx contains a policy with that ID (which doesn't necessarily mean the user is a member).

If that's all that isPolicyMember() is looking for, then it seems like isPolicyMember would be true as long as the policy object returned here is not an empty object.

Following that logic, then the full policy collection doesn't need to be subscribed to and isPolicyMember can be replaced with !isEmptyObject(policy).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgolen Thanks your suggestions. I just updated code, please check again @DylanDylann


nkdengineer marked this conversation as resolved.
Show resolved Hide resolved
const isUnmounted = useRef(false);

useEffect(() => {
Expand Down
6 changes: 6 additions & 0 deletions tests/actions/EnforceActionExportRestrictions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ 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 isOneTransactionReport', () => {
// @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', () => {
Expand Down
Loading