Skip to content
Open
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
68 changes: 42 additions & 26 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2522,6 +2522,24 @@ function getApprovalModeForNewWorkspace(
return CONST.POLICY.APPROVAL_MODE.OPTIONAL;
}

/**
* Builds the default title report field (`fieldList`) used when seeding a new policy. The object intentionally omits the
* non-essential `PolicyReportField` properties (orderWeight, values, keys, etc.), so it is cast to the expected type.
*/
function buildDefaultTitleFieldList(pendingFields?: Record<string, PendingAction>): Policy['fieldList'] {
return {
[CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {
defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN,
type: CONST.POLICY.DEFAULT_FIELD_LIST_TYPE,
target: CONST.POLICY.DEFAULT_FIELD_LIST_TARGET,
name: CONST.POLICY.DEFAULT_FIELD_LIST_NAME,
fieldID: CONST.POLICY.FIELDS.FIELD_LIST_TITLE,
deletable: true,
...(pendingFields ? {pendingFields} : {}),
},
} as unknown as Policy['fieldList'];
}

/**
* Generates onyx data for creating a new workspace
*
Expand Down Expand Up @@ -2721,17 +2739,7 @@ function buildPolicyData(options: BuildPolicyDataOptions): OnyxData<BuildPolicyD
originalFileName: file?.name,
...optimisticMccGroupData.optimisticData,
requiresCategory: true,
fieldList: {
[CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {
defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN,
pendingFields: {defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD},
type: CONST.POLICY.DEFAULT_FIELD_LIST_TYPE,
target: CONST.POLICY.DEFAULT_FIELD_LIST_TARGET,
name: CONST.POLICY.DEFAULT_FIELD_LIST_NAME,
fieldID: CONST.POLICY.FIELDS.FIELD_LIST_TITLE,
deletable: true,
},
},
fieldList: buildDefaultTitleFieldList({defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}),
},
},
{
Expand Down Expand Up @@ -3201,17 +3209,7 @@ function createDraftWorkspace({
disabledFields: {defaultBillable: true, reimbursable: false},
requiresCategory: true,
defaultReimbursable: true,
fieldList: {
[CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {
defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN,
pendingFields: {defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD},
type: CONST.POLICY.DEFAULT_FIELD_LIST_TYPE,
target: CONST.POLICY.DEFAULT_FIELD_LIST_TARGET,
name: CONST.POLICY.DEFAULT_FIELD_LIST_NAME,
fieldID: CONST.POLICY.FIELDS.FIELD_LIST_TITLE,
deletable: true,
},
},
fieldList: buildDefaultTitleFieldList({defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}),
},
},
{
Expand Down Expand Up @@ -4257,6 +4255,9 @@ function createWorkspaceFromIOUPayment(
disabledFields: {defaultBillable: true, reimbursable: false},
requiresCategory: true,
defaultReimbursable: true,
// Seed the title report field so computeOptimisticReportName can produce a meaningful name
// (e.g. "Expense {date}") instead of falling back to "New report" when this policy has no fieldList yet.
fieldList: buildDefaultTitleFieldList(),
};

const optimisticData: Array<
Expand Down Expand Up @@ -4458,14 +4459,30 @@ function createWorkspaceFromIOUPayment(
// - change the sign of the report total
// - update its policyID and policyName
// - update the chatReportID to point to the new expense chat
const expenseReport = {
// - recompute reportName so the header and the policy expense chat preview don't show the stale "IOU" name
const expenseReport: Report = {
...iouReport,
chatReportID: memberData.workspaceChatReportID,
parentReportID: memberData.workspaceChatReportID,
policyID,
policyName: workspaceName,
type: CONST.REPORT.TYPE.EXPENSE,
total: -(iouReport?.total ?? 0),
fieldList: newWorkspace.fieldList,
};

const reportTransactions = ReportUtils.getReportTransactions(iouReportID);
const transactionsRecord: Record<string, Transaction> = {};
for (const transaction of reportTransactions) {
if (transaction?.transactionID) {
transactionsRecord[transaction.transactionID] = transaction;
}
}
const computedExpenseReportName = ReportUtils.computeOptimisticReportName(expenseReport, newWorkspace as Policy, policyID, transactionsRecord);
if (computedExpenseReportName !== null) {
expenseReport.reportName = computedExpenseReportName;
}

optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`,
Expand All @@ -4477,9 +4494,6 @@ function createWorkspaceFromIOUPayment(
value: iouReport,
});

// The expense report transactions need to have the amount reversed to negative values
const reportTransactions = ReportUtils.getReportTransactions(iouReportID);

// For performance reasons, we are going to compose a merge collection data for transactions
const transactionsOptimisticData: Record<string, Transaction> = {};
const transactionFailureData: Record<string, Transaction> = {};
Expand Down Expand Up @@ -4535,12 +4549,14 @@ function createWorkspaceFromIOUPayment(

if (reportPreviewAction?.reportActionID) {
// Update the created timestamp of the report preview action to be after the expense chat created timestamp.
// Also set childReportName so the preview line falls back to the recomputed expense report name if needed.
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${memberData.workspaceChatReportID}`,
value: {
[reportPreviewAction.reportActionID]: {
...reportPreviewAction,
childReportName: expenseReport.reportName,
message: [
{
type: CONST.REPORT.MESSAGE.TYPE.TEXT,
Expand Down
4 changes: 2 additions & 2 deletions src/pages/inbox/ReportFetchHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ function ReportFetchHandler() {
if (
transactionThreadReportID !== CONST.FAKE_REPORT_ID ||
transactionThreadReport?.reportID ||
(!reportLoadingState.hasOnceLoadedReportActions && !reportMetadata?.isOptimisticReport)
(!reportLoadingState.hasOnceLoadedReportActions && !reportMetadata?.isOptimisticReport && !isOffline)
) {
return;
}

createOneTransactionThread();
}, [reportLoadingState.hasOnceLoadedReportActions, reportMetadata?.isOptimisticReport, transactionThreadReport?.reportID, transactionThreadReportID]);
}, [reportLoadingState.hasOnceLoadedReportActions, reportMetadata?.isOptimisticReport, transactionThreadReport?.reportID, transactionThreadReportID, isOffline]);

useEffect(() => {
if (isLoadingReportData || !prevIsLoadingReportData || !prevIsAnonymousUser.current || isAnonymousUser) {
Expand Down
Loading