Skip to content

Commit deaae82

Browse files
Merge pull request #89447 from shubham1206agra/refactor-PolicyUtils-last
Refactor: removed ONYXKEYS.COLLECTION.POLICY from PolicyUtils
2 parents 539c9bb + d06cbb8 commit deaae82

6 files changed

Lines changed: 41 additions & 146 deletions

File tree

src/libs/DistanceRequestUtils.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import type {OnyxEntry} from 'react-native-onyx';
1+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
2+
import Onyx from 'react-native-onyx';
23
import type {CurrencyListActionsContextType} from '@components/CurrencyListContextProvider';
34
import type {LocaleContextProps} from '@components/LocaleContextProvider';
45
import CONST from '@src/CONST';
6+
import ONYXKEYS from '@src/ONYXKEYS';
57
import type {LastSelectedDistanceRates, OnyxInputOrEntry, Transaction} from '@src/types/onyx';
68
import type {Unit} from '@src/types/onyx/Policy';
79
import type Policy from '@src/types/onyx/Policy';
810
import {isEmptyObject} from '@src/types/utils/EmptyObject';
911
import {replaceAllDigits} from './MoneyRequestUtils';
10-
// This will be fixed as part of https://github.com/Expensify/App/issues/66397
11-
12-
import {getDistanceRateCustomUnit, getDistanceRateCustomUnitRate, getPersonalPolicy, getUnitRateValue} from './PolicyUtils';
12+
import {getDistanceRateCustomUnit, getDistanceRateCustomUnitRate, getUnitRateValue} from './PolicyUtils';
1313
import {getCurrency, getRateID, isCustomUnitRateIDForP2P, isExpenseUnreported} from './TransactionUtils';
1414

1515
type MileageRate = {
@@ -22,6 +22,15 @@ type MileageRate = {
2222
index?: number;
2323
};
2424

25+
/** @private Only for getRate function */
26+
let allPolicies: OnyxCollection<Policy>;
27+
28+
Onyx.connectWithoutView({
29+
key: ONYXKEYS.COLLECTION.POLICY,
30+
waitForCollectionCallback: true,
31+
callback: (value) => (allPolicies = value),
32+
});
33+
2534
const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters
2635
const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter
2736

@@ -396,6 +405,11 @@ function getDistanceUnit(transaction: OnyxEntry<Transaction>, mileageRate: OnyxE
396405
return transaction?.comment?.customUnit?.distanceUnit ?? mileageRate?.unit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES;
397406
}
398407

408+
/** @private This is only for internal use for getRate function */
409+
function getPersonalPolicy() {
410+
return Object.values(allPolicies ?? {}).find((policy) => policy?.type === CONST.POLICY.TYPE.PERSONAL);
411+
}
412+
399413
/**
400414
* Get the selected rate for a transaction, from the policy or P2P default rate.
401415
* Use the distanceUnit stored on the transaction by default to prevent policy changes modifying existing transactions. Otherwise, get the unit from the rate.
@@ -410,6 +424,7 @@ function getRate({
410424
policyForMovingExpenses,
411425
isFakeP2PRate,
412426
isMovingTransactionFromTrackExpense,
427+
personalPolicyOutputCurrency,
413428
}: {
414429
transaction: OnyxEntry<Transaction>;
415430
policy: OnyxEntry<Policy>;
@@ -418,15 +433,14 @@ function getRate({
418433
useTransactionDistanceUnit?: boolean;
419434
isFakeP2PRate?: boolean;
420435
isMovingTransactionFromTrackExpense?: boolean;
436+
personalPolicyOutputCurrency?: string;
421437
}): MileageRate {
422438
let mileageRates = getMileageRates(policy, true, transaction?.comment?.customUnit?.customUnitRateID);
423439
if (isEmptyObject(mileageRates) && policyDraft) {
424440
mileageRates = getMileageRates(policyDraft, true, transaction?.comment?.customUnit?.customUnitRateID);
425441
}
426442
const mileageRatesForMovingExpenses = getMileageRates(policyForMovingExpenses, true, transaction?.comment?.customUnit?.customUnitRateID);
427-
// This will be fixed as part of https://github.com/Expensify/App/issues/66397
428-
// eslint-disable-next-line @typescript-eslint/no-deprecated
429-
const policyCurrency = policy?.outputCurrency ?? getPersonalPolicy()?.outputCurrency ?? CONST.CURRENCY.USD;
443+
const policyCurrency = policy?.outputCurrency ?? personalPolicyOutputCurrency ?? getPersonalPolicy()?.outputCurrency ?? CONST.CURRENCY.USD;
430444
const isUnreportedExpense = isExpenseUnreported(transaction);
431445
const defaultMileageRate = getDefaultMileageRate(policy);
432446
const customUnitRateID = getRateID(transaction);
@@ -449,8 +463,18 @@ function getRate({
449463
* For example, if an expense is '10 mi @ $1.00 / mi' and the rate is updated to '$1.00 / km',
450464
* then the updated distance unit should be 'km' from the updated rate, not 'mi' from the currently stored transaction distance unit.
451465
*/
452-
function getUpdatedDistanceUnit({transaction, policy, policyDraft}: {transaction: OnyxEntry<Transaction>; policy: OnyxEntry<Policy>; policyDraft?: OnyxEntry<Policy>}) {
453-
return getRate({transaction, policy, policyDraft, useTransactionDistanceUnit: false}).unit;
466+
function getUpdatedDistanceUnit({
467+
transaction,
468+
policy,
469+
policyDraft,
470+
personalPolicyOutputCurrency,
471+
}: {
472+
transaction: OnyxEntry<Transaction>;
473+
policy: OnyxEntry<Policy>;
474+
policyDraft?: OnyxEntry<Policy>;
475+
personalPolicyOutputCurrency?: string;
476+
}) {
477+
return getRate({transaction, policy, policyDraft, useTransactionDistanceUnit: false, personalPolicyOutputCurrency}).unit;
454478
}
455479

456480
/**

src/libs/OptionsListUtils/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
getCountOfRequiredTagLists,
3333
getSubmitToAccountID,
3434
hasDynamicExternalWorkflow,
35-
isCurrentUserMemberOfAnyPolicy,
3635
isTimeTrackingEnabled,
3736
} from '@libs/PolicyUtils';
3837
import {
@@ -2410,7 +2409,7 @@ function prepareReportOptionsForDisplay(
24102409
*/
24112410
function getRestrictedLogins(config: GetOptionsConfig, options: OptionList, canShowManagerMcTest: boolean): Record<string, boolean> {
24122411
return {
2413-
[CONST.EMAIL.MANAGER_MCTEST]: !canShowManagerMcTest || !Permissions.isBetaEnabled(CONST.BETAS.NEWDOT_MANAGER_MCTEST, config.betas) || isCurrentUserMemberOfAnyPolicy(),
2412+
[CONST.EMAIL.MANAGER_MCTEST]: !canShowManagerMcTest || !Permissions.isBetaEnabled(CONST.BETAS.NEWDOT_MANAGER_MCTEST, config.betas),
24142413
};
24152414
}
24162415

src/libs/PolicyUtils.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {Str} from 'expensify-common';
22
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
3-
import Onyx from 'react-native-onyx';
43
import type {TupleToUnion, ValueOf} from 'type-fest';
54
import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider';
65
import type {SelectorType} from '@components/SelectionScreen';
@@ -72,14 +71,6 @@ type ConnectionWithLastSyncData = {
7271
lastSync?: ConnectionLastSync;
7372
};
7473

75-
let allPolicies: OnyxCollection<Policy>;
76-
77-
Onyx.connect({
78-
key: ONYXKEYS.COLLECTION.POLICY,
79-
waitForCollectionCallback: true,
80-
callback: (value) => (allPolicies = value),
81-
});
82-
8374
/**
8475
* Returns true if the policy has no fieldList or its fieldList is empty.
8576
*/
@@ -420,10 +411,6 @@ function getPolicyRole(policy: OnyxInputOrEntry<Policy>, currentUserLogin?: stri
420411
return policy?.employeeList?.[currentUserLogin]?.role;
421412
}
422413

423-
function getPolicyNameByID(policyID: string): string {
424-
return allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]?.name ?? '';
425-
}
426-
427414
/**
428415
* Check if the policy can be displayed
429416
* If shouldShowPendingDeletePolicy is true, show the policy pending deletion.
@@ -1291,11 +1278,6 @@ function getReimburserAccountID(policy: OnyxEntry<Policy>): number {
12911278
return reimburserEmail ? (getAccountIDsByLogins([reimburserEmail]).at(0) ?? -1) : -1;
12921279
}
12931280

1294-
/** @deprecated Please use ONYXKEYS.PERSONAL_POLICY_ID to find the personal policyID */
1295-
function getPersonalPolicy() {
1296-
return Object.values(allPolicies ?? {}).find((policy) => policy?.type === CONST.POLICY.TYPE.PERSONAL);
1297-
}
1298-
12991281
function getAdminEmployees(policy: OnyxEntry<Policy>): PolicyEmployee[] {
13001282
if (!policy?.employeeList) {
13011283
return [];
@@ -1321,7 +1303,7 @@ function getActiveEmployeeWorkspaces(policies: OnyxCollection<Policy> | null, cu
13211303
* Checks whether the current user has a policy with admin access
13221304
*/
13231305
function hasActiveAdminWorkspaces(currentUserLogin: string | undefined, policies?: OnyxCollection<Policy>) {
1324-
return getActiveAdminWorkspaces(policies ?? allPolicies, currentUserLogin).length > 0;
1306+
return getActiveAdminWorkspaces(policies, currentUserLogin).length > 0;
13251307
}
13261308

13271309
/**
@@ -2068,13 +2050,6 @@ function isPreferredExporter(policy: Policy, currentUserLogin: string) {
20682050
return exporters.some((exporter) => exporter && exporter === currentUserLogin);
20692051
}
20702052

2071-
/**
2072-
* Checks if the current user is a member of any policyExpenseChatEnabled policy
2073-
*/
2074-
function isCurrentUserMemberOfAnyPolicy(): boolean {
2075-
return Object.values(allPolicies ?? {}).some((policy) => policy?.isPolicyExpenseChatEnabled && policy?.id && policy.id !== CONST.POLICY.ID_FAKE);
2076-
}
2077-
20782053
/**
20792054
* Determines which travel step should be shown based on policy state
20802055
*/
@@ -2160,9 +2135,6 @@ export {
21602135
getSoftExclusionsForGuideAndAccountManager,
21612136
filterGuideAndAccountManager,
21622137
isMultiLevelTags,
2163-
// This will be fixed as part of https://github.com/Expensify/App/issues/66397
2164-
// eslint-disable-next-line @typescript-eslint/no-deprecated
2165-
getPersonalPolicy,
21662138
getPolicyBrickRoadIndicatorStatus,
21672139
getSortedTagKeys,
21682140
getTagList,
@@ -2288,7 +2260,6 @@ export {
22882260
getRuleApprovers,
22892261
canModifyPlan,
22902262
getAdminsPrivateEmailDomains,
2291-
getPolicyNameByID,
22922263
getMostFrequentEmailDomain,
22932264
getDescriptionForPolicyDomainCard,
22942265
getManagerAccountID,
@@ -2297,7 +2268,6 @@ export {
22972268
areAllGroupPoliciesExpenseChatDisabled,
22982269
getCountOfRequiredTagLists,
22992270
getActiveEmployeeWorkspaces,
2300-
isCurrentUserMemberOfAnyPolicy,
23012271
getPolicyRole,
23022272
hasIndependentTags,
23032273
getLengthOfTag,

src/libs/ReportUtils.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ import {
156156
getManagerAccountID,
157157
getPerDiemCustomUnit,
158158
getPolicyByCustomUnitID,
159-
getPolicyNameByID,
160159
getPolicyRole,
161160
getRuleApprovers,
162161
getSubmitToAccountID,
@@ -7000,14 +6999,16 @@ function getMovedActionMessage(translate: LocalizedTranslate, action: ReportActi
70006999
return '';
70017000
}
70027001
const {toPolicyID, newParentReportID, movedReportID} = movedActionOriginalMessage;
7003-
const toPolicyName = getPolicyNameByID(toPolicyID);
7002+
const toPolicyName = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${toPolicyID}`]?.name ?? '';
70047003
return translate('iou.movedAction', !isDM(report), getReportURLForCurrentContext(movedReportID), getReportURLForCurrentContext(newParentReportID), toPolicyName);
70057004
}
70067005

70077006
function getPolicyChangeMessage(translate: LocalizedTranslate, action: ReportAction) {
70087007
const PolicyChangeOriginalMessage = getOriginalMessage(action as ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.CHANGE_POLICY>) ?? {};
70097008
const {fromPolicy: fromPolicyID, toPolicy: toPolicyID} = PolicyChangeOriginalMessage as OriginalMessageChangePolicy;
7010-
const message = translate('report.actions.type.changeReportPolicy', getPolicyNameByID(toPolicyID), fromPolicyID ? getPolicyNameByID(fromPolicyID) : undefined);
7009+
const toPolicyName = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${toPolicyID}`]?.name ?? '';
7010+
const fromPolicyName = fromPolicyID ? (allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${fromPolicyID}`]?.name ?? '') : undefined;
7011+
const message = translate('report.actions.type.changeReportPolicy', toPolicyName, fromPolicyName);
70117012
return message;
70127013
}
70137014

src/pages/iou/request/ParticipantSearchResults.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ function ParticipantSearchResults({
164164

165165
// This is necessary to prevent showing the Manager McTest when there are multiple transactions being created
166166
const hasMultipleTransactions = optimisticTransactions.length > 1;
167-
const canShowManagerMcTest = !hasBeenAddedToNudgeMigration && action !== CONST.IOU.ACTION.SUBMIT && !hasMultipleTransactions;
167+
const isCurrentUserMemberOfAnyPolicy = Object.values(allPolicies ?? {}).some((pol) => pol?.isPolicyExpenseChatEnabled && pol?.id && pol.id !== CONST.POLICY.ID_FAKE);
168+
const canShowManagerMcTest = !hasBeenAddedToNudgeMigration && action !== CONST.IOU.ACTION.SUBMIT && !hasMultipleTransactions && !isCurrentUserMemberOfAnyPolicy;
168169

169170
const getValidOptionsConfig = {
170171
selectedOptions: participants as Participant[],

tests/unit/PolicyUtilsTest.ts

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
getEligibleBankAccountShareRecipients,
1919
getManagerAccountID,
2020
getPolicyEmployeeAccountIDs,
21-
getPolicyNameByID,
2221
getRateDisplayValue,
2322
getSubmitToAccountID,
2423
getTagApproverRule,
@@ -33,7 +32,6 @@ import {
3332
hasOnlyPersonalPolicies,
3433
hasOtherControlWorkspaces,
3534
hasPolicyWithXeroConnection,
36-
isCurrentUserMemberOfAnyPolicy,
3735
isPolicyMemberWithoutPendingDelete,
3836
shouldShowPolicy,
3937
sortPoliciesByName,
@@ -779,31 +777,6 @@ describe('PolicyUtils', () => {
779777
});
780778
});
781779

782-
describe('getPolicyNameByID', () => {
783-
it('should return the policy name for a given policyID', async () => {
784-
const policy: Policy = {
785-
...createRandomPolicy(1, CONST.POLICY.TYPE.TEAM),
786-
name: 'testName',
787-
};
788-
789-
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}1`, policy);
790-
791-
expect(getPolicyNameByID('1')).toBe('testName');
792-
});
793-
794-
it('should return the empty if the name is not set', async () => {
795-
const policy: Policy = {
796-
...createRandomPolicy(1, CONST.POLICY.TYPE.TEAM),
797-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
798-
name: null!,
799-
};
800-
801-
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}1`, policy);
802-
803-
expect(getPolicyNameByID('1')).toBe('');
804-
});
805-
});
806-
807780
describe('getManagerAccountID', () => {
808781
beforeEach(() => {
809782
wrapOnyxWithWaitForBatchedUpdates(Onyx);
@@ -978,79 +951,6 @@ describe('PolicyUtils', () => {
978951
});
979952
});
980953

981-
describe('isCurrentUserMemberOfAnyPolicy', () => {
982-
beforeEach(() => {
983-
wrapOnyxWithWaitForBatchedUpdates(Onyx);
984-
});
985-
afterEach(async () => {
986-
await Onyx.clear();
987-
await waitForBatchedUpdatesWithAct();
988-
});
989-
990-
it('should return false if user has no policies', async () => {
991-
const currentUserLogin = approverEmail;
992-
const currentUserAccountID = approverAccountID;
993-
994-
await Onyx.set(ONYXKEYS.SESSION, {email: currentUserLogin, accountID: currentUserAccountID});
995-
await Onyx.set(ONYXKEYS.COLLECTION.POLICY, {});
996-
997-
const result = isCurrentUserMemberOfAnyPolicy();
998-
999-
expect(result).toBeFalsy();
1000-
});
1001-
1002-
it('should return true if user owns a workspace', async () => {
1003-
const currentUserLogin = approverEmail;
1004-
const currentUserAccountID = approverAccountID;
1005-
const policies = {...createRandomPolicy(0, CONST.POLICY.TYPE.TEAM, `John's Workspace`), ownerAccountID: approverAccountID, isPolicyExpenseChatEnabled: true};
1006-
1007-
await Onyx.set(ONYXKEYS.SESSION, {email: currentUserLogin, accountID: currentUserAccountID});
1008-
await Onyx.set(ONYXKEYS.COLLECTION.POLICY, policies);
1009-
1010-
const result = isCurrentUserMemberOfAnyPolicy();
1011-
1012-
expect(result).toBeTruthy();
1013-
});
1014-
1015-
it('should return false if expense chat is not enabled', async () => {
1016-
const currentUserLogin = approverEmail;
1017-
const currentUserAccountID = approverAccountID;
1018-
const policies = {...createRandomPolicy(0, CONST.POLICY.TYPE.TEAM, `John's Workspace`), isPolicyExpenseChatEnabled: false};
1019-
1020-
await Onyx.set(ONYXKEYS.SESSION, {email: currentUserLogin, accountID: currentUserAccountID});
1021-
await Onyx.set(ONYXKEYS.COLLECTION.POLICY, policies);
1022-
1023-
const result = isCurrentUserMemberOfAnyPolicy();
1024-
1025-
expect(result).toBeFalsy();
1026-
});
1027-
1028-
it('should return false if its a fake policy id', async () => {
1029-
const currentUserLogin = approverEmail;
1030-
const currentUserAccountID = approverAccountID;
1031-
const policies = {...createRandomPolicy(0, CONST.POLICY.TYPE.TEAM, `John's Workspace`), id: CONST.POLICY.ID_FAKE};
1032-
1033-
await Onyx.set(ONYXKEYS.SESSION, {email: currentUserLogin, accountID: currentUserAccountID});
1034-
await Onyx.set(ONYXKEYS.COLLECTION.POLICY, policies);
1035-
1036-
const result = isCurrentUserMemberOfAnyPolicy();
1037-
1038-
expect(result).toBeFalsy();
1039-
});
1040-
1041-
it('should return true if user is invited to a workspace', async () => {
1042-
const currentUserLogin = approverEmail;
1043-
const currentUserAccountID = approverAccountID;
1044-
const policies = {...createRandomPolicy(0, CONST.POLICY.TYPE.TEAM, `John's Workspace`), ownerAccountID, isPolicyExpenseChatEnabled: true};
1045-
1046-
await Onyx.set(ONYXKEYS.SESSION, {email: currentUserLogin, accountID: currentUserAccountID});
1047-
await Onyx.set(ONYXKEYS.COLLECTION.POLICY, policies);
1048-
1049-
const result = isCurrentUserMemberOfAnyPolicy();
1050-
1051-
expect(result).toBeTruthy();
1052-
});
1053-
});
1054954
describe('getTagList', () => {
1055955
it.each([
1056956
['when index is 0', 0, policyTags.TagListTest0.name],

0 commit comments

Comments
 (0)