Skip to content

Commit 5b556dd

Browse files
authored
Merge pull request Expensify#64782 from linhvovan29546/fix/62911
fix: handle change report in creation flow
2 parents ad2b0c0 + e9cf7f0 commit 5b556dd

6 files changed

Lines changed: 102 additions & 19 deletions

File tree

src/components/MoneyRequestConfirmationListFooter.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@ import {getDestinationForDisplay, getSubratesFields, getSubratesForDisplay, getT
1818
import {canSendInvoice, getPerDiemCustomUnit, hasDependentTags as hasDependentTagsPolicyUtils, isMultiLevelTags as isMultiLevelTagsPolicyUtils, isPaidGroupPolicy} from '@libs/PolicyUtils';
1919
import type {ThumbnailAndImageURI} from '@libs/ReceiptUtils';
2020
import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils';
21-
import {buildOptimisticExpenseReport, getDefaultWorkspaceAvatar, getOutstandingReportsForUser, isReportOutstanding, populateOptimisticReportFormula} from '@libs/ReportUtils';
21+
import {
22+
buildOptimisticExpenseReport,
23+
getDefaultWorkspaceAvatar,
24+
getOutstandingReportsForUser,
25+
isMoneyRequestReport,
26+
isReportOutstanding,
27+
populateOptimisticReportFormula,
28+
} from '@libs/ReportUtils';
2229
import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
2330
import {
2431
getTagForDisplay,
@@ -300,7 +307,10 @@ function MoneyRequestConfirmationListFooter({
300307
const optimisticReport = buildOptimisticExpenseReport(reportID, policy?.id, policy?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, Number(formattedAmount), currency);
301308
reportName = populateOptimisticReportFormula(policy?.fieldList?.text_title?.defaultValue ?? '', optimisticReport, policy);
302309
}
303-
const shouldReportBeEditable = !!firstOutstandingReport;
310+
311+
// When creating an expense in an individual report, the report field becomes read-only
312+
// since the destination is already determined and there's no need to show a selectable list.
313+
const shouldReportBeEditable = !!firstOutstandingReport && !isMoneyRequestReport(reportID, allReports);
304314

305315
const isTypeSend = iouType === CONST.IOU.TYPE.PAY;
306316
const taxRates = policy?.taxRates ?? null;

src/libs/ReportUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,7 @@ function isMoneyRequest(reportOrID: OnyxEntry<Report> | string): boolean {
22602260
/**
22612261
* Checks if a report is an IOU or expense report.
22622262
*/
2263-
function isMoneyRequestReport(reportOrID: OnyxInputOrEntry<Report> | SearchReport | string, reports?: SearchReport[]): boolean {
2263+
function isMoneyRequestReport(reportOrID: OnyxInputOrEntry<Report> | SearchReport | string, reports?: SearchReport[] | OnyxCollection<Report>): boolean {
22642264
const report = typeof reportOrID === 'string' ? (getReport(reportOrID, reports ?? allReports) ?? null) : reportOrID;
22652265
return isIOUReport(report) || isExpenseReport(report);
22662266
}

src/libs/actions/Transaction.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,8 @@ function generateTransactionID(): string {
598598
return NumberUtils.generateHexadecimalValue(16);
599599
}
600600

601-
function setTransactionReport(transactionID: string, reportID: string, isDraft: boolean) {
602-
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {reportID});
601+
function setTransactionReport(transactionID: string, transaction: Partial<Transaction>, isDraft: boolean) {
602+
Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, transaction);
603603
}
604604

605605
function changeTransactionsReport(transactionIDs: string[], reportID: string, policy?: OnyxEntry<Policy>) {

src/pages/iou/request/step/IOURequestEditReportCommon.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ const reportSelector = (report: OnyxEntry<Report>): OnyxEntry<Report> =>
4040
type Props = {
4141
backTo: Route | undefined;
4242
transactionsReports: Report[];
43+
policyID?: string;
4344
selectReport: (item: TransactionGroupListItem) => void;
4445
};
4546

46-
function IOURequestEditReportCommon({backTo, transactionsReports, selectReport}: Props) {
47+
function IOURequestEditReportCommon({backTo, transactionsReports, selectReport, policyID: policyIDFromProps}: Props) {
4748
const {translate} = useLocalize();
4849
const {options} = useOptionsList();
4950
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {selector: (reports) => mapOnyxCollectionItems(reports, reportSelector), canBeMissing: true});
@@ -56,7 +57,7 @@ function IOURequestEditReportCommon({backTo, transactionsReports, selectReport}:
5657
const expenseReports = useMemo(
5758
() =>
5859
Object.values(allPoliciesID ?? {}).flatMap((policyID) => {
59-
if (!policyID) {
60+
if (!policyID || (policyIDFromProps && policyID !== policyIDFromProps)) {
6061
return [];
6162
}
6263
const reports = getOutstandingReportsForUser(
@@ -67,7 +68,7 @@ function IOURequestEditReportCommon({backTo, transactionsReports, selectReport}:
6768
);
6869
return reports;
6970
}),
70-
[allReports, currentUserPersonalDetails.accountID, transactionsReports, allPoliciesID, reportNameValuePairs],
71+
[allReports, currentUserPersonalDetails.accountID, transactionsReports, allPoliciesID, reportNameValuePairs, policyIDFromProps],
7172
);
7273

7374
const reportOptions: TransactionGroupListItem[] = useMemo(() => {

src/pages/iou/request/step/IOURequestStepParticipants.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ function IOURequestStepParticipants({
229229
setMoneyRequestTag(transaction.transactionID, '');
230230
setMoneyRequestCategory(transaction.transactionID, '');
231231
if (participants?.at(0)?.reportID !== newReportID) {
232-
setTransactionReport(transaction.transactionID, newReportID, true);
232+
setTransactionReport(transaction.transactionID, {reportID: newReportID}, true);
233233
}
234234
});
235235
if ((isCategorizing || isShareAction) && numberOfParticipants.current === 0) {

src/pages/iou/request/step/IOURequestStepReport.tsx

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import type {ListItem} from '@components/SelectionList/types';
33
import useOnyx from '@hooks/useOnyx';
44
import {changeTransactionsReport, setTransactionReport} from '@libs/actions/Transaction';
55
import Navigation from '@libs/Navigation/Navigation';
6+
import {getReportOrDraftReport} from '@libs/ReportUtils';
67
import CONST from '@src/CONST';
78
import ONYXKEYS from '@src/ONYXKEYS';
9+
import ROUTES from '@src/ROUTES';
810
import type SCREENS from '@src/SCREENS';
911
import IOURequestEditReportCommon from './IOURequestEditReportCommon';
1012
import withFullTransactionOrNotFound from './withFullTransactionOrNotFound';
@@ -20,34 +22,104 @@ type TransactionGroupListItem = ListItem & {
2022
type IOURequestStepReportProps = WithWritableReportOrNotFoundProps<typeof SCREENS.MONEY_REQUEST.STEP_REPORT> & WithFullTransactionOrNotFoundProps<typeof SCREENS.MONEY_REQUEST.STEP_REPORT>;
2123

2224
function IOURequestStepReport({route, transaction}: IOURequestStepReportProps) {
23-
const {backTo, action} = route.params;
25+
const {backTo, action, iouType, transactionID, reportID: reportIDFromRoute} = route.params;
2426
const reportID = transaction?.reportID === '0' ? transaction?.participants?.at(0)?.reportID : transaction?.reportID;
2527
const [transactionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: true});
2628

2729
const isEditing = action === CONST.IOU.ACTION.EDIT;
30+
const isCreateReport = action === CONST.IOU.ACTION.CREATE;
31+
const isFromGlobalCreate = !!transaction?.isFromGlobalCreate;
32+
const reportOrDraftReport = getReportOrDraftReport(reportIDFromRoute);
2833

29-
const selectReport = (item: TransactionGroupListItem) => {
34+
const handleGoBackWithReportID = (id: string) => {
35+
if (isEditing) {
36+
Navigation.dismissModalWithReport({reportID: id});
37+
} else {
38+
Navigation.goBack(backTo);
39+
}
40+
};
41+
42+
const handleGlobalCreateReport = (item: TransactionGroupListItem) => {
3043
if (!transaction) {
3144
return;
3245
}
33-
if (item.value !== transaction.reportID) {
34-
setTransactionReport(transaction.transactionID, item.value, !isEditing);
35-
if (isEditing) {
36-
changeTransactionsReport([transaction.transactionID], item.value);
37-
}
46+
const reportOrDraftReportFromValue = getReportOrDraftReport(item.value);
47+
const participants = [
48+
{
49+
selected: true,
50+
accountID: 0,
51+
isPolicyExpenseChat: true,
52+
reportID: reportOrDraftReportFromValue?.chatReportID,
53+
policyID: reportOrDraftReportFromValue?.policyID,
54+
},
55+
];
56+
57+
setTransactionReport(
58+
transaction.transactionID,
59+
{
60+
reportID: item.value,
61+
participants,
62+
},
63+
true,
64+
);
65+
66+
const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, iouType, transactionID, reportOrDraftReportFromValue?.chatReportID);
67+
// If the backTo parameter is set, we should navigate back to the confirmation screen that is already on the stack.
68+
if (backTo) {
69+
Navigation.goBack(iouConfirmationPageRoute, {compareParams: false});
70+
} else {
71+
Navigation.navigate(iouConfirmationPageRoute);
72+
}
73+
};
74+
75+
const handleRegularReportSelection = (item: TransactionGroupListItem) => {
76+
if (!transaction) {
77+
return;
3878
}
79+
setTransactionReport(
80+
transaction.transactionID,
81+
{
82+
reportID: item.value,
83+
},
84+
!isEditing,
85+
);
86+
3987
if (isEditing) {
40-
Navigation.dismissModalWithReport({reportID: item.value});
41-
} else {
42-
Navigation.goBack(backTo);
88+
changeTransactionsReport([transaction.transactionID], item.value);
89+
}
90+
91+
handleGoBackWithReportID(item.value);
92+
};
93+
94+
const selectReport = (item: TransactionGroupListItem) => {
95+
if (!transaction) {
96+
return;
4397
}
98+
99+
const isSameReport = item.value === transaction.reportID;
100+
101+
// Early return for same report selection
102+
if (isSameReport) {
103+
handleGoBackWithReportID(item.value);
104+
return;
105+
}
106+
107+
// Handle global create report
108+
if (isCreateReport && isFromGlobalCreate) {
109+
handleGlobalCreateReport(item);
110+
return;
111+
}
112+
113+
// Handle regular report selection
114+
handleRegularReportSelection(item);
44115
};
45116

46117
return (
47118
<IOURequestEditReportCommon
48119
backTo={backTo}
49120
transactionsReports={transactionReport ? [transactionReport] : []}
50121
selectReport={selectReport}
122+
policyID={!isEditing && !isFromGlobalCreate ? reportOrDraftReport?.policyID : undefined}
51123
/>
52124
);
53125
}

0 commit comments

Comments
 (0)