Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the optimistic GBR for chats with money requests #38675

Merged
merged 10 commits into from
Apr 4, 2024
31 changes: 31 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ type AncestorIDs = {

type MissingPaymentMethod = 'bankAccount' | 'wallet';

type OutstandingChildRequest = {
hasOutstandingChildRequest?: boolean;
};

let currentUserEmail: string | undefined;
let currentUserPrivateDomain: string | undefined;
let currentUserAccountID: number | undefined;
Expand Down Expand Up @@ -5684,6 +5688,32 @@ function hasActionsWithErrors(reportID: string): boolean {
return Object.values(reportActions ?? {}).some((action) => !isEmptyObject(action.errors));
}

/**
* @returns the object to update `report.hasOutstandingChildRequest`
*/
function getOutstandingChildRequest(iouReport: OnyxEntry<Report> | EmptyObject): OutstandingChildRequest {
paultsimura marked this conversation as resolved.
Show resolved Hide resolved
if (!iouReport || isEmptyObject(iouReport)) {
return {};
}

if (!isExpenseReport(iouReport)) {
return {
hasOutstandingChildRequest: iouReport.managerID === currentUserAccountID && iouReport.total !== 0,
};
}

const policy = getPolicy(iouReport.policyID);
const shouldBeManuallySubmitted = PolicyUtils.isPaidGroupPolicy(policy) && !policy?.harvesting?.enabled;
if (shouldBeManuallySubmitted || PolicyUtils.isPolicyAdmin(policy)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is causing problems whenever I am trying to edit anything from Admin side. The collect policy has scheduled submit on.

return {
hasOutstandingChildRequest: true,
};
}

// We don't need to update hasOutstandingChildRequest in this case
return {};
}

export {
getReportParticipantsTitle,
isReportMessageAttachment,
Expand Down Expand Up @@ -5909,6 +5939,7 @@ export {
isTrackExpenseReport,
hasActionsWithErrors,
getGroupChatName,
getOutstandingChildRequest,
};

export type {
Expand Down
68 changes: 14 additions & 54 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,6 @@ type SendMoneyParamsData = {
failureData: OnyxUpdate[];
};

type OutstandingChildRequest = {
hasOutstandingChildRequest?: boolean;
};

let betas: OnyxTypes.Beta[] = [];
Onyx.connect({
key: ONYXKEYS.BETAS,
Expand Down Expand Up @@ -433,41 +429,6 @@ function getReceiptError(receipt?: Receipt, filename?: string, isScanRequest = t
: ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: receipt.source?.toString() ?? '', filename: filename ?? ''}, errorKey);
}

function needsToBeManuallySubmitted(iouReport: OnyxTypes.Report) {
const isPolicyExpenseChat = ReportUtils.isExpenseReport(iouReport);

if (isPolicyExpenseChat) {
const policy = ReportUtils.getPolicy(iouReport.policyID);
const isFromPaidPolicy = PolicyUtils.isPaidGroupPolicy(policy);

// If the scheduled submit is turned off on the policy, user needs to manually submit the report which is indicated by GBR in LHN
return isFromPaidPolicy && !policy.harvesting?.enabled;
}

return true;
}

/**
* Return the object to update hasOutstandingChildRequest
*/
function getOutstandingChildRequest(policy: OnyxEntry<OnyxTypes.Policy> | EmptyObject, iouReport: OnyxTypes.Report): OutstandingChildRequest {
if (!needsToBeManuallySubmitted(iouReport)) {
return {
hasOutstandingChildRequest: false,
};
}

if (PolicyUtils.isPolicyAdmin(policy)) {
return {
hasOutstandingChildRequest: true,
};
}

return {
hasOutstandingChildRequest: iouReport.managerID === userAccountID && iouReport.total !== 0,
};
}

/** Builds the Onyx data for a money request */
function buildOnyxDataForMoneyRequest(
chatReport: OnyxEntry<OnyxTypes.Report>,
Expand All @@ -491,7 +452,7 @@ function buildOnyxDataForMoneyRequest(
isOneOnOneSplit = false,
): [OnyxUpdate[], OnyxUpdate[], OnyxUpdate[]] {
const isScanRequest = TransactionUtils.isScanRequest(transaction);
const outstandingChildRequest = getOutstandingChildRequest(policy ?? {}, iouReport);
const outstandingChildRequest = ReportUtils.getOutstandingChildRequest(iouReport);
const clearedPendingFields = Object.fromEntries(Object.keys(transaction.pendingFields ?? {}).map((key) => [key, null]));
const optimisticData: OnyxUpdate[] = [];
let newQuickAction: ValueOf<typeof CONST.QUICK_ACTIONS> = isScanRequest ? CONST.QUICK_ACTIONS.REQUEST_SCAN : CONST.QUICK_ACTIONS.REQUEST_MANUAL;
Expand Down Expand Up @@ -1564,17 +1525,21 @@ function getUpdateMoneyRequestParams(
}

// Step 4: Compute the IOU total and update the report preview message (and report header) so LHN amount owed is correct.
let updatedMoneyRequestReport = {...iouReport};
const diff = calculateDiffAmount(iouReport, updatedTransaction, transaction);

if (ReportUtils.isExpenseReport(iouReport) && typeof updatedMoneyRequestReport.total === 'number') {
// For expense report, the amount is negative so we should subtract total from diff
updatedMoneyRequestReport.total -= diff;
let updatedMoneyRequestReport: OnyxTypes.Report | EmptyObject;
if (!iouReport) {
updatedMoneyRequestReport = {};
} else if (ReportUtils.isExpenseReport(iouReport) && typeof iouReport.total === 'number') {
// For expense report, the amount is negative, so we should subtract total from diff
updatedMoneyRequestReport = {
...iouReport,
total: iouReport.total - diff,
};
} else {
updatedMoneyRequestReport = iouReport
? IOUUtils.updateIOUOwnerAndTotal(iouReport, updatedReportAction.actorAccountID ?? -1, diff, TransactionUtils.getCurrency(transaction), false, true)
: {};
updatedMoneyRequestReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, updatedReportAction.actorAccountID ?? -1, diff, TransactionUtils.getCurrency(transaction), false, true);
}

updatedMoneyRequestReport.cachedTotal = CurrencyUtils.convertToDisplayString(updatedMoneyRequestReport.total, transactionDetails?.currency);

optimisticData.push(
Expand All @@ -1586,10 +1551,7 @@ function getUpdateMoneyRequestParams(
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.parentReportID}`,
value: {
hasOutstandingChildRequest:
iouReport && needsToBeManuallySubmitted(iouReport) && updatedMoneyRequestReport.managerID === userAccountID && updatedMoneyRequestReport.total !== 0,
},
value: ReportUtils.getOutstandingChildRequest(updatedMoneyRequestReport),
},
);
successData.push({
Expand Down Expand Up @@ -3773,9 +3735,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`,
value: {
hasOutstandingChildRequest: iouReport && needsToBeManuallySubmitted(iouReport) && updatedIOUReport?.managerID === userAccountID && updatedIOUReport.total !== 0,
},
value: ReportUtils.getOutstandingChildRequest(updatedIOUReport),
},
);

Expand Down
Loading