Skip to content

Commit a6fc5ec

Browse files
authored
Merge pull request #50847 from nkdengineer/fix/49801
fix: Not here page when create new request
2 parents 7983984 + 730f3ff commit a6fc5ec

File tree

4 files changed

+122
-1
lines changed

4 files changed

+122
-1
lines changed

src/libs/ReportUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ function canAddOrDeleteTransactions(moneyRequestReport: OnyxEntry<Report>): bool
18051805
return isAwaitingFirstLevelApproval(moneyRequestReport);
18061806
}
18071807

1808-
if (isReportApproved(moneyRequestReport) || isSettled(moneyRequestReport?.reportID)) {
1808+
if (isReportApproved(moneyRequestReport) || isClosedReport(moneyRequestReport) || isSettled(moneyRequestReport?.reportID)) {
18091809
return false;
18101810
}
18111811

src/libs/actions/IOU.ts

+12
Original file line numberDiff line numberDiff line change
@@ -7568,6 +7568,10 @@ function cancelPayment(expenseReport: OnyxEntry<OnyxTypes.Report>, chatReport: O
75687568
const stateNum: ValueOf<typeof CONST.REPORT.STATE_NUM> = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.APPROVED;
75697569
const statusNum: ValueOf<typeof CONST.REPORT.STATUS_NUM> = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATUS_NUM.CLOSED : CONST.REPORT.STATUS_NUM.APPROVED;
75707570
const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, statusNum);
7571+
const iouReportActions = ReportActionsUtils.getAllReportActions(chatReport.iouReportID ?? '-1');
7572+
const expenseReportActions = ReportActionsUtils.getAllReportActions(expenseReport.reportID ?? '-1');
7573+
const iouCreatedAction = Object.values(iouReportActions).find((action) => ReportActionsUtils.isCreatedAction(action));
7574+
const expenseCreatedAction = Object.values(expenseReportActions).find((action) => ReportActionsUtils.isCreatedAction(action));
75717575
const optimisticData: OnyxUpdate[] = [
75727576
{
75737577
onyxMethod: Onyx.METHOD.MERGE,
@@ -7579,6 +7583,14 @@ function cancelPayment(expenseReport: OnyxEntry<OnyxTypes.Report>, chatReport: O
75797583
},
75807584
},
75817585
},
7586+
{
7587+
onyxMethod: Onyx.METHOD.MERGE,
7588+
key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`,
7589+
value: {
7590+
// The report created later will become the iouReportID of the chat report
7591+
iouReportID: (iouCreatedAction?.created ?? '') > (expenseCreatedAction?.created ?? '') ? chatReport?.iouReportID : expenseReport.reportID,
7592+
},
7593+
},
75827594
{
75837595
onyxMethod: Onyx.METHOD.MERGE,
75847596
key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`,

tests/actions/IOUTest.ts

+90
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,96 @@ describe('actions/IOU', () => {
19071907
});
19081908
});
19091909

1910+
describe('a workspace chat with a cancelled payment', () => {
1911+
const amount = 10000;
1912+
const comment = '💸💸💸💸';
1913+
const merchant = 'NASDAQ';
1914+
1915+
afterEach(() => {
1916+
mockFetch?.resume?.();
1917+
});
1918+
1919+
it("has an iouReportID of the cancelled payment's expense report", () => {
1920+
let expenseReport: OnyxEntry<OnyxTypes.Report>;
1921+
let chatReport: OnyxEntry<OnyxTypes.Report>;
1922+
1923+
// Given a signed in account, which owns a workspace, and has a policy expense chat
1924+
Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
1925+
return waitForBatchedUpdates()
1926+
.then(() => {
1927+
// Which owns a workspace
1928+
PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
1929+
return waitForBatchedUpdates();
1930+
})
1931+
.then(() =>
1932+
TestHelper.getOnyxData({
1933+
key: ONYXKEYS.COLLECTION.REPORT,
1934+
waitForCollectionCallback: true,
1935+
callback: (allReports) => {
1936+
chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
1937+
},
1938+
}),
1939+
)
1940+
.then(() => {
1941+
if (chatReport) {
1942+
// When an IOU expense is submitted to that policy expense chat
1943+
IOU.requestMoney({
1944+
report: chatReport,
1945+
participantParams: {
1946+
payeeEmail: RORY_EMAIL,
1947+
payeeAccountID: RORY_ACCOUNT_ID,
1948+
participant: {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID},
1949+
},
1950+
transactionParams: {
1951+
amount,
1952+
attendees: [],
1953+
currency: CONST.CURRENCY.USD,
1954+
created: '',
1955+
merchant,
1956+
comment,
1957+
},
1958+
});
1959+
}
1960+
return waitForBatchedUpdates();
1961+
})
1962+
.then(() =>
1963+
// And given an expense report has now been created which holds the IOU
1964+
TestHelper.getOnyxData({
1965+
key: ONYXKEYS.COLLECTION.REPORT,
1966+
waitForCollectionCallback: true,
1967+
callback: (allReports) => {
1968+
expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
1969+
},
1970+
}),
1971+
)
1972+
.then(() => {
1973+
// When the expense report is paid elsewhere (but really, any payment option would work)
1974+
if (chatReport && expenseReport) {
1975+
IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, chatReport, expenseReport);
1976+
}
1977+
return waitForBatchedUpdates();
1978+
})
1979+
.then(() => {
1980+
if (chatReport && expenseReport) {
1981+
// And when the payment is cancelled
1982+
IOU.cancelPayment(expenseReport, chatReport);
1983+
}
1984+
return waitForBatchedUpdates();
1985+
})
1986+
.then(() =>
1987+
TestHelper.getOnyxData({
1988+
key: ONYXKEYS.COLLECTION.REPORT,
1989+
waitForCollectionCallback: true,
1990+
callback: (allReports) => {
1991+
const chatReportData = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`];
1992+
// Then the policy expense chat report has the iouReportID of the IOU expense report
1993+
expect(chatReportData?.iouReportID).toBe(expenseReport?.reportID);
1994+
},
1995+
}),
1996+
);
1997+
});
1998+
});
1999+
19102000
describe('deleteMoneyRequest', () => {
19112001
const amount = 10000;
19122002
const comment = 'Send me money please';

tests/utils/TestHelper.ts

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {fireEvent, screen} from '@testing-library/react-native';
22
import {Str} from 'expensify-common';
33
import {Linking} from 'react-native';
44
import Onyx from 'react-native-onyx';
5+
import type {ConnectOptions} from 'react-native-onyx/dist/types';
56
import type {ApiCommand, ApiRequestCommandParameters} from '@libs/API/types';
67
import * as Localize from '@libs/Localize';
78
import * as Pusher from '@libs/Pusher/pusher';
@@ -12,6 +13,7 @@ import * as Session from '@src/libs/actions/Session';
1213
import HttpUtils from '@src/libs/HttpUtils';
1314
import * as NumberUtils from '@src/libs/NumberUtils';
1415
import ONYXKEYS from '@src/ONYXKEYS';
16+
import type {OnyxKey} from '@src/ONYXKEYS';
1517
import appSetup from '@src/setup';
1618
import type {Response as OnyxResponse, PersonalDetails, Report} from '@src/types/onyx';
1719
import waitForBatchedUpdates from './waitForBatchedUpdates';
@@ -25,6 +27,9 @@ type MockFetch = jest.MockedFn<typeof fetch> & {
2527
mockAPICommand: <TCommand extends ApiCommand>(command: TCommand, responseHandler: (params: ApiRequestCommandParameters[TCommand]) => OnyxResponse) => void;
2628
};
2729

30+
type ConnectionCallback<TKey extends OnyxKey> = NonNullable<ConnectOptions<TKey>['callback']>;
31+
type ConnectionCallbackParams<TKey extends OnyxKey> = Parameters<ConnectionCallback<TKey>>;
32+
2833
type QueueItem = {
2934
resolve: (value: Partial<Response> | PromiseLike<Partial<Response>>) => void;
3035
input: RequestInfo;
@@ -65,6 +70,19 @@ function buildPersonalDetails(login: string, accountID: number, firstName = 'Tes
6570
};
6671
}
6772

73+
function getOnyxData<TKey extends OnyxKey>(options: ConnectOptions<TKey>) {
74+
return new Promise<void>((resolve) => {
75+
const connectionID = Onyx.connect({
76+
...options,
77+
callback: (...params: ConnectionCallbackParams<TKey>) => {
78+
Onyx.disconnect(connectionID);
79+
(options.callback as (...args: ConnectionCallbackParams<TKey>) => void)?.(...params);
80+
resolve();
81+
},
82+
});
83+
});
84+
}
85+
6886
/**
6987
* Simulate signing in and make sure all API calls in this flow succeed. Every time we add
7088
* a mockImplementationOnce() we are altering what Network.post() will return.
@@ -335,4 +353,5 @@ export {
335353
expectAPICommandToHaveBeenCalledWith,
336354
setupGlobalFetchMock,
337355
navigateToSidebarOption,
356+
getOnyxData,
338357
};

0 commit comments

Comments
 (0)