Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,6 @@ const CONST = {
EUR_BILLING: 'eurBilling',
NO_OPTIMISTIC_TRANSACTION_THREADS: 'noOptimisticTransactionThreads',
UBER_FOR_BUSINESS: 'uberForBusiness',
CUSTOM_REPORT_NAMES: 'newExpensifyCustomReportNames',
NEW_DOT_DEW: 'newDotDEW',
GPS_MILEAGE: 'gpsMileage',
PERSONAL_CARD_IMPORT: 'personalCardImport',
Expand Down
8 changes: 2 additions & 6 deletions src/components/KYCWall/BaseKYCWall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useParentReportAction from '@hooks/useParentReportAction';
import usePermissions from '@hooks/usePermissions';
import useReportTransactions from '@hooks/useReportTransactions';
import {openPersonalBankAccountSetupView} from '@libs/actions/BankAccounts';
import {completePaymentOnboarding, savePreferredPaymentMethod} from '@libs/actions/IOU';
Expand Down Expand Up @@ -72,8 +71,6 @@ function KYCWall({
const personalDetails = usePersonalDetails();
const employeeEmail = personalDetails?.[iouReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID]?.login ?? '';
const reportTransactions = useReportTransactions(iouReport?.reportID);
const {isBetaEnabled} = usePermissions();
const isCustomReportNamesBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES);
const anchorRef = useRef<HTMLDivElement | View>(null);
const transferBalanceButtonRef = useRef<HTMLDivElement | View | null>(null);

Expand Down Expand Up @@ -139,7 +136,7 @@ function KYCWall({
if (iouReport && isIOUReport(iouReport)) {
const adminPolicy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policy?.id}`];
if (adminPolicy) {
const inviteResult = moveIOUReportToPolicyAndInviteSubmitter(iouReport, adminPolicy, formatPhoneNumber, reportTransactions, isCustomReportNamesBetaEnabled);
const inviteResult = moveIOUReportToPolicyAndInviteSubmitter(iouReport, adminPolicy, formatPhoneNumber, reportTransactions);
if (inviteResult?.policyExpenseChatReportID) {
setNavigationActionToMicrotaskQueue(() => {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(inviteResult.policyExpenseChatReportID));
Expand All @@ -149,7 +146,7 @@ function KYCWall({
Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(adminPolicy.id));
});
} else {
const moveResult = moveIOUReportToPolicy(iouReport, adminPolicy, true, reportTransactions, isCustomReportNamesBetaEnabled);
const moveResult = moveIOUReportToPolicy(iouReport, adminPolicy, true, reportTransactions);
savePreferredPaymentMethod(iouReport.policyID, adminPolicy.id, CONST.LAST_PAYMENT_METHOD.IOU, lastPaymentMethod?.[adminPolicy.id]);

if (moveResult?.policyExpenseChatReportID && !moveResult.useTemporaryOptimisticExpenseChatReportID) {
Expand Down Expand Up @@ -212,7 +209,6 @@ function KYCWall({
currentUserEmail,
employeeEmail,
reportTransactions,
isCustomReportNamesBetaEnabled,
introSelected,
formatPhoneNumber,
lastPaymentMethod,
Expand Down
24 changes: 1 addition & 23 deletions src/libs/ReportTitleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@
*/
import type {OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Beta, BetaConfiguration, Policy, Report, ReportNameValuePairs} from '@src/types/onyx';
import Permissions from './Permissions';
import type {Policy, Report, ReportNameValuePairs} from '@src/types/onyx';
import {getTitleReportField, isChatReport} from './ReportUtils';

let allReportNameValuePairs: Record<string, ReportNameValuePairs> = {};
let betas: Beta[] = [];
let betaConfiguration: BetaConfiguration = {};

/**
* We use Onyx.connectWithoutView because we do not use this in React components and this logic is not tied directly to the UI.
Expand All @@ -26,18 +22,6 @@ Onyx.connectWithoutView({
allReportNameValuePairs = (val as Record<string, ReportNameValuePairs>) ?? {};
},
});
Onyx.connectWithoutView({
key: ONYXKEYS.BETAS,
callback: (val) => {
betas = val ?? [];
},
});
Onyx.connectWithoutView({
key: ONYXKEYS.BETA_CONFIGURATION,
callback: (val) => {
betaConfiguration = val ?? {};
},
});

/**
* Get the title field from report name value pairs
Expand All @@ -53,9 +37,6 @@ function getTitleFieldFromRNVP(reportID: string) {
* This is the JavaScript equivalent of the backend updateTitleFieldToMatchPolicy function
*/
function updateTitleFieldToMatchPolicy(reportID: string, policy?: Policy): Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS>> {
if (!Permissions.isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES, betas, betaConfiguration)) {
return [];
}
if (!reportID || !policy) {
return [];
}
Expand Down Expand Up @@ -87,9 +68,6 @@ function updateTitleFieldToMatchPolicy(reportID: string, policy?: Policy): Array
* Remove title field from report's rNVP when report is manually renamed to indicate that the manual name should be preserved, and the custom report name formula should no longer update the name.
*/
function removeTitleFieldFromReport(reportID: string): Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS>> {
if (!Permissions.isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES, betas, betaConfiguration)) {
return [];
}
if (!reportID) {
return [];
}
Expand Down
50 changes: 22 additions & 28 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6972,22 +6972,19 @@ function buildOptimisticExpenseReport({
expenseReport.managerID = submitToAccountID;
}

// Only compute optimistic report name if the user is on the CUSTOM_REPORT_NAMES beta
if (Permissions.isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES, allBetas)) {
const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {});
if (!!titleReportField && isGroupPolicy(policy?.type ?? '')) {
const formulaContext: FormulaContext = {
report: expenseReport,
policy,
allTransactions: reportTransactions ?? {},
};
const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {});
if (!!titleReportField && isGroupPolicy(policy?.type ?? '')) {
const formulaContext: FormulaContext = {
report: expenseReport,
policy,
allTransactions: reportTransactions ?? {},
};

// We use dynamic require here to avoid a circular dependency between ReportUtils and Formula
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('./Formula') as {compute: (formula?: string, context?: FormulaContext) => string};
const computedName = Formula.compute(titleReportField.defaultValue, formulaContext);
expenseReport.reportName = computedName ?? expenseReport.reportName;
}
// We use dynamic require here to avoid a circular dependency between ReportUtils and Formula
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('./Formula') as {compute: (formula?: string, context?: FormulaContext) => string};
const computedName = Formula.compute(titleReportField.defaultValue, formulaContext);
expenseReport.reportName = computedName ?? expenseReport.reportName;
}

expenseReport.fieldList = policy?.fieldList;
Expand Down Expand Up @@ -7027,20 +7024,17 @@ function buildOptimisticEmptyReport(
managerID: getManagerAccountID(policy, {ownerAccountID: accountID}),
};

// Only compute optimistic report name if the user is on the CUSTOM_REPORT_NAMES beta
if (Permissions.isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES, allBetas)) {
const formulaContext: FormulaContext = {
report: optimisticEmptyReport as Report,
policy,
allTransactions: {},
};
const formulaContext: FormulaContext = {
report: optimisticEmptyReport as Report,
policy,
allTransactions: {},
};

// We use dynamic require here to avoid a circular dependency between ReportUtils and Formula
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('./Formula') as {compute: (formula?: string, context?: FormulaContext) => string};
const optimisticReportName = Formula.compute(titleReportField?.defaultValue ?? CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN, formulaContext);
optimisticEmptyReport.reportName = optimisticReportName ?? '';
}
// We use dynamic require here to avoid a circular dependency between ReportUtils and Formula
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('./Formula') as {compute: (formula?: string, context?: FormulaContext) => string};
const optimisticReportName = Formula.compute(titleReportField?.defaultValue ?? CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN, formulaContext);
optimisticEmptyReport.reportName = optimisticReportName ?? '';

optimisticEmptyReport.participants = accountID
? {
Expand Down
49 changes: 18 additions & 31 deletions src/libs/actions/Report/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
/** @deprecated This value is deprecated and will be removed soon after migration. Use the email from useCurrentUserPersonalDetails hook instead. */
let deprecatedCurrentUserLogin: string | undefined;

Onyx.connect({

Check warning on line 291 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, val is undefined
Expand All @@ -302,7 +302,7 @@
},
});

Onyx.connect({

Check warning on line 305 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.CONCIERGE_REPORT_ID,
callback: (value) => (conciergeReportIDOnyxConnect = value),
});
Expand All @@ -310,7 +310,7 @@
// map of reportID to all reportActions for that report
const allReportActions: OnyxCollection<ReportActions> = {};

Onyx.connect({

Check warning on line 313 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
callback: (actions, key) => {
if (!key || !actions) {
Expand All @@ -322,7 +322,7 @@
});

let allReports: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 325 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -331,7 +331,7 @@
});

let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};
Onyx.connect({

Check warning on line 334 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
allPersonalDetails = value ?? {};
Expand All @@ -346,7 +346,7 @@
});

let onboarding: OnyxEntry<Onboarding>;
Onyx.connect({

Check warning on line 349 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NVP_ONBOARDING,
callback: (val) => {
if (Array.isArray(val)) {
Expand All @@ -357,7 +357,7 @@
});

let introSelected: OnyxEntry<IntroSelected> = {};
Onyx.connect({

Check warning on line 360 in src/libs/actions/Report/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NVP_INTRO_SELECTED,
callback: (val) => (introSelected = val),
});
Expand Down Expand Up @@ -5475,7 +5475,6 @@
policy: Policy,
isFromSettlementButton?: boolean,
reportTransactions: Transaction[] = [],
isCustomReportNamesBetaEnabled?: boolean,
): {policyExpenseChatReportID?: string; useTemporaryOptimisticExpenseChatReportID: boolean} | undefined {
// This flow only works for IOU reports
if (!policy || !iouReport || !isIOUReportUsingReport(iouReport)) {
Expand All @@ -5502,7 +5501,6 @@
policyID,
optimisticExpenseChatReportID,
reportTransactions,
isCustomReportNamesBetaEnabled,
);

const parameters: MoveIOUReportToExistingPolicyParams = {
Expand All @@ -5525,7 +5523,6 @@
policy: Policy,
formatPhoneNumber: LocaleContextProps['formatPhoneNumber'],
reportTransactions: Transaction[] = [],
isCustomReportNamesBetaEnabled?: boolean,
): {policyExpenseChatReportID?: string} | undefined {
if (!policy || !iouReport) {
return;
Expand Down Expand Up @@ -5656,7 +5653,7 @@
failureData: convertedFailureData,
movedExpenseReportAction,
movedReportAction,
} = convertIOUReportToExpenseReport(iouReport, policy, policyID, optimisticPolicyExpenseChatReportID, reportTransactions, isCustomReportNamesBetaEnabled);
} = convertIOUReportToExpenseReport(iouReport, policy, policyID, optimisticPolicyExpenseChatReportID, reportTransactions);

optimisticData.push(...convertedOptimisticData);
successData.push(...convertedSuccessData);
Expand All @@ -5675,14 +5672,7 @@
return {policyExpenseChatReportID: optimisticPolicyExpenseChatReportID};
}

function convertIOUReportToExpenseReport(
iouReport: Report,
policy: Policy,
policyID: string,
optimisticPolicyExpenseChatReportID: string,
reportTransactions: Transaction[] = [],
isCustomReportNamesBetaEnabled?: boolean,
) {
function convertIOUReportToExpenseReport(iouReport: Report, policy: Policy, policyID: string, optimisticPolicyExpenseChatReportID: string, reportTransactions: Transaction[] = []) {
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT | typeof ONYXKEYS.COLLECTION.TRANSACTION | typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS>> = [];
const successData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS>> = [];
const failureData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.REPORT | typeof ONYXKEYS.COLLECTION.TRANSACTION | typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS>> = [];
Expand All @@ -5704,27 +5694,24 @@
expenseReport.managerID = nextApproverAccountID;
}

// Only compute optimistic report name if the user is on the CUSTOM_REPORT_NAMES beta
if (isCustomReportNamesBetaEnabled) {
const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {});
if (!!titleReportField && isPaidGroupPolicy(policy)) {
// Convert transactions array to Record<string, Transaction> for FormulaContext
const transactionsRecord: Record<string, Transaction> = {};
for (const transaction of reportTransactions) {
if (transaction?.transactionID) {
transactionsRecord[transaction.transactionID] = transaction;
}
const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {});
if (!!titleReportField && isPaidGroupPolicy(policy)) {
// Convert transactions array to Record<string, Transaction> for FormulaContext
const transactionsRecord: Record<string, Transaction> = {};
for (const transaction of reportTransactions) {
if (transaction?.transactionID) {
transactionsRecord[transaction.transactionID] = transaction;
}

// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('@libs/Formula') as {compute: (formula?: string, context?: {report: Report; policy: Policy; allTransactions?: Record<string, Transaction>}) => string};
const computedName = Formula.compute(titleReportField.defaultValue, {
report: expenseReport,
policy,
allTransactions: transactionsRecord,
});
expenseReport.reportName = computedName ?? expenseReport.reportName;
}

// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const Formula = require('@libs/Formula') as {compute: (formula?: string, context?: {report: Report; policy: Policy; allTransactions?: Record<string, Transaction>}) => string};
const computedName = Formula.compute(titleReportField.defaultValue, {
report: expenseReport,
policy,
allTransactions: transactionsRecord,
});
expenseReport.reportName = computedName ?? expenseReport.reportName;
}

const reportID = iouReport.reportID;
Expand Down
6 changes: 2 additions & 4 deletions src/pages/ReportChangeWorkspacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ function ReportChangeWorkspacePage({report, route}: ReportChangeWorkspacePagePro
const shouldShowLoadingIndicator = isLoadingApp && !isOffline;
const {isBetaEnabled} = usePermissions();
const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT);
const isCustomReportNamesBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES);
const session = useSession();
const hasViolations = hasViolationsReportUtils(report?.reportID, transactionViolations, session?.accountID ?? CONST.DEFAULT_NUMBER_ID, session?.email ?? '');

Expand All @@ -87,9 +86,9 @@ function ReportChangeWorkspacePage({report, route}: ReportChangeWorkspacePagePro
const {backTo} = route.params;
Navigation.goBack(backTo);
if (isIOUReport(reportID)) {
const invite = moveIOUReportToPolicyAndInviteSubmitter(report, policy, formatPhoneNumber, reportTransactions, isCustomReportNamesBetaEnabled);
const invite = moveIOUReportToPolicyAndInviteSubmitter(report, policy, formatPhoneNumber, reportTransactions);
if (!invite?.policyExpenseChatReportID) {
moveIOUReportToPolicy(report, policy, false, reportTransactions, isCustomReportNamesBetaEnabled);
moveIOUReportToPolicy(report, policy, false, reportTransactions);
}
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
// eslint-disable-next-line @typescript-eslint/no-deprecated
Expand Down Expand Up @@ -136,7 +135,6 @@ function ReportChangeWorkspacePage({report, route}: ReportChangeWorkspacePagePro
session?.email,
hasViolations,
isASAPSubmitBetaEnabled,
isCustomReportNamesBetaEnabled,
reportNextStep,
isChangePolicyTrainingModalDismissed,
],
Expand Down
6 changes: 2 additions & 4 deletions src/pages/Search/SearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ function SearchPage({route}: SearchPageProps) {
const {showConfirmModal} = useConfirmModal();
const {isBetaEnabled} = usePermissions();
const isDEWBetaEnabled = isBetaEnabled(CONST.BETAS.NEW_DOT_DEW);
const isCustomReportNamesBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_REPORT_NAMES);
const [isHoldEducationalModalVisible, setIsHoldEducationalModalVisible] = useState(false);
const [rejectModalAction, setRejectModalAction] = useState<ValueOf<
typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD | typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.REJECT
Expand Down Expand Up @@ -523,9 +522,9 @@ function SearchPage({route}: SearchPageProps) {
const reportTransactions = Object.values(allTransactions ?? {}).filter(
(transaction): transaction is NonNullable<typeof transaction> => !!transaction && transaction.reportID === itemReportID,
);
const invite = moveIOUReportToPolicyAndInviteSubmitter(itemReport, adminPolicy, formatPhoneNumber, reportTransactions, isCustomReportNamesBetaEnabled);
const invite = moveIOUReportToPolicyAndInviteSubmitter(itemReport, adminPolicy, formatPhoneNumber, reportTransactions);
if (!invite?.policyExpenseChatReportID) {
moveIOUReportToPolicy(itemReport, adminPolicy, false, reportTransactions, isCustomReportNamesBetaEnabled);
moveIOUReportToPolicy(itemReport, adminPolicy, false, reportTransactions);
}
}
}
Expand Down Expand Up @@ -584,7 +583,6 @@ function SearchPage({route}: SearchPageProps) {
showDelegateNoAccessModal,
personalPolicyID,
allTransactions,
isCustomReportNamesBetaEnabled,
allReports,
],
);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/usePermissionsTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('usePermissions', () => {

it('should handle explicit only and exclusion betas correctly', async () => {
// Given: A beta configuration with both explicit only and exclusion betas
const explicitOnlyBeta = CONST.BETAS.CUSTOM_REPORT_NAMES;
const explicitOnlyBeta = CONST.BETAS.ASAP_SUBMIT;
const exclusionBeta = CONST.BETAS.PREVENT_SPOTNANA_TRAVEL;
const betaConfiguration = {
explicitOnly: [explicitOnlyBeta],
Expand Down
Loading