Skip to content

Commit e4049b7

Browse files
authored
Merge pull request #87399 from callstack-internal/perf-send-message-phase-2-2
refactor: PureReportActionItem, add PaymentContent
2 parents c74212c + 3dd1570 commit e4049b7

3 files changed

Lines changed: 174 additions & 45 deletions

File tree

src/pages/inbox/report/PureReportActionItem.tsx

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ import {resolveSuggestedFollowup} from '@libs/actions/Report/SuggestedFollowup';
6363
import {isPersonalCardBrokenConnection} from '@libs/CardUtils';
6464
import {isChronosOOOListAction} from '@libs/ChronosUtils';
6565
import ControlSelection from '@libs/ControlSelection';
66-
import {convertToDisplayString} from '@libs/CurrencyUtils';
6766
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
6867
import type {OnyxDataWithErrors} from '@libs/ErrorUtils';
6968
import {getLatestErrorMessageField, isReceiptError} from '@libs/ErrorUtils';
@@ -73,7 +72,6 @@ import {isReportMessageAttachment} from '@libs/isReportMessageAttachment';
7372
import Navigation from '@libs/Navigation/Navigation';
7473
import type {PlatformStackNavigationProp} from '@libs/Navigation/PlatformStackNavigation/types';
7574
import type {ReportsSplitNavigatorParamList} from '@libs/Navigation/types';
76-
import {getBankAccountLastFourDigits} from '@libs/PaymentUtils';
7775
import Permissions from '@libs/Permissions';
7876
import {getDisplayNameOrDefault} from '@libs/PersonalDetailsUtils';
7977
import {getCleanedTagName, isPolicyAdmin, isPolicyMember, isPolicyOwner} from '@libs/PolicyUtils';
@@ -248,6 +246,7 @@ import type {Errors} from '@src/types/onyx/OnyxCommon';
248246
import type {JoinWorkspaceResolution} from '@src/types/onyx/OriginalMessage';
249247
import {isEmptyObject, isEmptyValueObject} from '@src/types/utils/EmptyObject';
250248
import ApprovalFlowContent, {isApprovalFlowAction} from './actionContents/ApprovalFlowContent';
249+
import PaymentContent from './actionContents/PaymentContent';
251250
import SimpleMessageContent, {isSimpleMessageAction} from './actionContents/SimpleMessageContent';
252251
import {RestrictedReadOnlyContextMenuActions} from './ContextMenu/ContextMenuActions';
253252
import MiniReportActionContextMenu from './ContextMenu/MiniReportActionContextMenu';
@@ -1373,49 +1372,13 @@ function PureReportActionItem({
13731372
/>
13741373
);
13751374
} else if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.IOU) && getOriginalMessage(action)?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY) {
1376-
const wasAutoPaid = getOriginalMessage(action)?.automaticAction ?? false;
1377-
const paymentType = getOriginalMessage(action)?.paymentType;
1378-
1379-
if (paymentType === CONST.IOU.PAYMENT_TYPE.ELSEWHERE) {
1380-
children = <ReportActionItemBasicMessage message={translate('iou.paidElsewhere')} />;
1381-
} else if (paymentType === CONST.IOU.PAYMENT_TYPE.VBBA) {
1382-
const originalMessage = getOriginalMessage(action);
1383-
const last4Digits = getBankAccountLastFourDigits(originalMessage?.bankAccountID, bankAccountList, policy);
1384-
if (wasAutoPaid) {
1385-
const translation = translate('iou.automaticallyPaidWithBusinessBankAccount', '', last4Digits);
1386-
1387-
children = (
1388-
<ReportActionItemBasicMessage>
1389-
<RenderHTML html={`<comment><muted-text>${translation}</muted-text></comment>`} />
1390-
</ReportActionItemBasicMessage>
1391-
);
1392-
} else {
1393-
children = <ReportActionItemBasicMessage message={translate('iou.businessBankAccount', '', last4Digits)} />;
1394-
}
1395-
} else if (wasAutoPaid) {
1396-
children = (
1397-
<ReportActionItemBasicMessage>
1398-
<RenderHTML html={`<comment><muted-text>${translate('iou.automaticallyPaidWithExpensify')}</muted-text></comment>`} />
1399-
</ReportActionItemBasicMessage>
1400-
);
1401-
} else {
1402-
const originalMessage = getOriginalMessage(action);
1403-
const amount = convertToDisplayString(Math.abs(originalMessage?.amount ?? 0), originalMessage?.currency);
1404-
if (originalMessage?.bankAccountID) {
1405-
const bankAccount = bankAccountList?.[originalMessage.bankAccountID];
1406-
children = (
1407-
<ReportActionItemBasicMessage
1408-
message={translate(
1409-
originalMessage?.payAsBusiness ? 'iou.settleInvoiceBusiness' : 'iou.settleInvoicePersonal',
1410-
amount,
1411-
bankAccount?.accountData?.accountNumber?.slice(-4) ?? '',
1412-
)}
1413-
/>
1414-
);
1415-
} else {
1416-
children = <ReportActionItemBasicMessage message={translate('iou.paidWithExpensify')} />;
1417-
}
1418-
}
1375+
children = (
1376+
<PaymentContent
1377+
action={action}
1378+
bankAccountList={bankAccountList}
1379+
policy={policy}
1380+
/>
1381+
);
14191382
} else if (isActionOfType(action, CONST.REPORT.ACTIONS.TYPE.REIMBURSED)) {
14201383
children = <ReportActionItemBasicMessage message={getReimbursedMessage(translate, action, report, currentUserAccountID)} />;
14211384
} else if (isSimpleMessageAction(action)) {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from 'react';
2+
import type {OnyxEntry} from 'react-native-onyx';
3+
import RenderHTML from '@components/RenderHTML';
4+
import useLocalize from '@hooks/useLocalize';
5+
import {convertToDisplayString} from '@libs/CurrencyUtils';
6+
import {getBankAccountLastFourDigits} from '@libs/PaymentUtils';
7+
import {getOriginalMessage} from '@libs/ReportActionsUtils';
8+
import ReportActionItemBasicMessage from '@pages/inbox/report/ReportActionItemBasicMessage';
9+
import CONST from '@src/CONST';
10+
import type * as OnyxTypes from '@src/types/onyx';
11+
12+
type PaymentContentProps = {
13+
action: OnyxTypes.ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.IOU>;
14+
bankAccountList: OnyxTypes.BankAccountList | undefined;
15+
policy: OnyxEntry<OnyxTypes.Policy>;
16+
};
17+
18+
function PaymentContent({action, bankAccountList, policy}: PaymentContentProps) {
19+
const {translate} = useLocalize();
20+
const originalMessage = getOriginalMessage(action);
21+
22+
if (!originalMessage) {
23+
return null;
24+
}
25+
26+
const paymentType = originalMessage.paymentType;
27+
const wasAutoPaid = originalMessage.automaticAction ?? false;
28+
29+
if (paymentType === CONST.IOU.PAYMENT_TYPE.ELSEWHERE) {
30+
return <ReportActionItemBasicMessage message={translate('iou.paidElsewhere')} />;
31+
}
32+
33+
if (paymentType === CONST.IOU.PAYMENT_TYPE.VBBA) {
34+
const last4Digits = getBankAccountLastFourDigits(originalMessage.bankAccountID, bankAccountList, policy);
35+
if (wasAutoPaid) {
36+
const translation = translate('iou.automaticallyPaidWithBusinessBankAccount', '', last4Digits);
37+
return (
38+
<ReportActionItemBasicMessage>
39+
<RenderHTML html={`<comment><muted-text>${translation}</muted-text></comment>`} />
40+
</ReportActionItemBasicMessage>
41+
);
42+
}
43+
return <ReportActionItemBasicMessage message={translate('iou.businessBankAccount', '', last4Digits)} />;
44+
}
45+
46+
if (wasAutoPaid) {
47+
return (
48+
<ReportActionItemBasicMessage>
49+
<RenderHTML html={`<comment><muted-text>${translate('iou.automaticallyPaidWithExpensify')}</muted-text></comment>`} />
50+
</ReportActionItemBasicMessage>
51+
);
52+
}
53+
54+
const amount = convertToDisplayString(Math.abs(originalMessage.amount ?? 0), originalMessage.currency);
55+
56+
if (originalMessage.bankAccountID) {
57+
const bankAccount = bankAccountList?.[originalMessage.bankAccountID];
58+
return (
59+
<ReportActionItemBasicMessage
60+
message={translate(
61+
originalMessage.payAsBusiness ? 'iou.settleInvoiceBusiness' : 'iou.settleInvoicePersonal',
62+
amount,
63+
bankAccount?.accountData?.accountNumber?.slice(-4) ?? '',
64+
)}
65+
/>
66+
);
67+
}
68+
69+
return <ReportActionItemBasicMessage message={translate('iou.paidWithExpensify')} />;
70+
}
71+
72+
PaymentContent.displayName = 'PaymentContent';
73+
74+
export default PaymentContent;

tests/ui/PureReportActionItemTest.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,98 @@ describe('PureReportActionItem', () => {
15471547

15481548
expect(screen.getByText(/8765/)).toBeOnTheScreen();
15491549
});
1550+
1551+
it('IOU PAY with bankAccountID and payAsBusiness renders settleInvoiceBusiness message', async () => {
1552+
const action = createReportAction(CONST.REPORT.ACTIONS.TYPE.IOU, {
1553+
type: CONST.IOU.REPORT_ACTION_TYPE.PAY,
1554+
paymentType: CONST.IOU.PAYMENT_TYPE.EXPENSIFY,
1555+
automaticAction: false,
1556+
bankAccountID: 55555,
1557+
payAsBusiness: true,
1558+
amount: 5000,
1559+
currency: 'USD',
1560+
});
1561+
render(
1562+
<ComposeProviders components={[OnyxListItemProvider, LocaleContextProvider, HTMLEngineProvider]}>
1563+
<OptionsListContextProvider>
1564+
<ScreenWrapper testID="test">
1565+
<PortalProvider>
1566+
<PureReportActionItem
1567+
personalPolicyID={undefined}
1568+
currentUserEmail={undefined}
1569+
report={undefined}
1570+
parentReportAction={undefined}
1571+
action={action}
1572+
displayAsGroup={false}
1573+
shouldDisplayNewMarker={false}
1574+
index={0}
1575+
isFirstVisibleReportAction={false}
1576+
taskReport={undefined}
1577+
linkedReport={undefined}
1578+
iouReportOfLinkedReport={undefined}
1579+
currentUserAccountID={ACTOR_ACCOUNT_ID}
1580+
// eslint-disable-next-line @typescript-eslint/naming-convention
1581+
bankAccountList={{55555: {accountData: {accountNumber: '000012345'}} as never}}
1582+
betas={undefined}
1583+
draftTransactionIDs={[]}
1584+
userBillingGracePeriodEnds={undefined}
1585+
/>
1586+
</PortalProvider>
1587+
</ScreenWrapper>
1588+
</OptionsListContextProvider>
1589+
</ComposeProviders>,
1590+
);
1591+
await waitForBatchedUpdatesWithAct();
1592+
1593+
expect(screen.getByText(/with business account/i)).toBeOnTheScreen();
1594+
expect(screen.getByText(/2345/)).toBeOnTheScreen();
1595+
});
1596+
1597+
it('IOU PAY with bankAccountID and no payAsBusiness renders settleInvoicePersonal message', async () => {
1598+
const action = createReportAction(CONST.REPORT.ACTIONS.TYPE.IOU, {
1599+
type: CONST.IOU.REPORT_ACTION_TYPE.PAY,
1600+
paymentType: CONST.IOU.PAYMENT_TYPE.EXPENSIFY,
1601+
automaticAction: false,
1602+
bankAccountID: 77777,
1603+
payAsBusiness: false,
1604+
amount: 3000,
1605+
currency: 'USD',
1606+
});
1607+
render(
1608+
<ComposeProviders components={[OnyxListItemProvider, LocaleContextProvider, HTMLEngineProvider]}>
1609+
<OptionsListContextProvider>
1610+
<ScreenWrapper testID="test">
1611+
<PortalProvider>
1612+
<PureReportActionItem
1613+
personalPolicyID={undefined}
1614+
currentUserEmail={undefined}
1615+
report={undefined}
1616+
parentReportAction={undefined}
1617+
action={action}
1618+
displayAsGroup={false}
1619+
shouldDisplayNewMarker={false}
1620+
index={0}
1621+
isFirstVisibleReportAction={false}
1622+
taskReport={undefined}
1623+
linkedReport={undefined}
1624+
iouReportOfLinkedReport={undefined}
1625+
currentUserAccountID={ACTOR_ACCOUNT_ID}
1626+
// eslint-disable-next-line @typescript-eslint/naming-convention
1627+
bankAccountList={{77777: {accountData: {accountNumber: '000067890'}} as never}}
1628+
betas={undefined}
1629+
draftTransactionIDs={[]}
1630+
userBillingGracePeriodEnds={undefined}
1631+
/>
1632+
</PortalProvider>
1633+
</ScreenWrapper>
1634+
</OptionsListContextProvider>
1635+
</ComposeProviders>,
1636+
);
1637+
await waitForBatchedUpdatesWithAct();
1638+
1639+
expect(screen.getByText(/with personal account/i)).toBeOnTheScreen();
1640+
expect(screen.getByText(/7890/)).toBeOnTheScreen();
1641+
});
15501642
});
15511643

15521644
describe('Default rendering fallbacks', () => {

0 commit comments

Comments
 (0)