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

Create Draft reports optimistically #32157

Merged
merged 12 commits into from
Nov 29, 2023
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ const CONST = {
ADMINS: '#admins',
},
STATE: {
OPENED: 'OPENED',
SUBMITTED: 'SUBMITTED',
PROCESSING: 'PROCESSING',
},
Expand Down
3 changes: 2 additions & 1 deletion src/components/MoneyReportHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt
return isManager && !isDraft && !isApproved && !isSettled;
}, [policyType, isManager, isDraft, isApproved, isSettled]);
const shouldShowSubmitButton = isDraft && reimbursableTotal !== 0;
const shouldShowNextSteps = isDraft && nextStep && !_.isEmpty(nextStep.message);
const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE;
const shouldShowNextSteps = isFromPaidPolicy && nextStep && !_.isEmpty(nextStep.message);
Comment on lines +92 to +93
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is to ensure we show the next steps on any Paid policy expense report in any state/status not only as draft

const shouldShowAnyButton = shouldShowSettlementButton || shouldShowApproveButton || shouldShowSubmitButton || shouldShowNextSteps;
const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport);
const formattedAmount = CurrencyUtils.convertToDisplayString(reimbursableTotal, moneyRequestReport.currency);
Expand Down
15 changes: 12 additions & 3 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ type OptimisticExpenseReport = Pick<
| 'reportName'
| 'state'
| 'stateNum'
| 'statusNum'
| 'total'
| 'notificationPreference'
| 'parentReportID'
Expand Down Expand Up @@ -2545,9 +2546,16 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa
const storedTotal = total * -1;
const policyName = getPolicyName(allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`]);
const formattedTotal = CurrencyUtils.convertToDisplayString(storedTotal, currency);
const policy = getPolicy(policyID);

// The expense report is always created with the policy's output currency
const outputCurrency = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]?.outputCurrency ?? CONST.CURRENCY.USD;
const outputCurrency = policy?.outputCurrency ?? CONST.CURRENCY.USD;
const isFree = policy?.type === CONST.POLICY.TYPE.FREE;

// Definte the state and status of the report based on whether the policy is free or paid
const state = isFree ? CONST.REPORT.STATE.SUBMITTED : CONST.REPORT.STATE.OPENED;
const stateNum = isFree ? CONST.REPORT.STATE_NUM.PROCESSING : CONST.REPORT.STATE_NUM.OPEN;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed elsewhere but I will make a follow up PR to clean up the naming mess of processing/ submitted states/ status, to make it all aligned

const statusNum = isFree ? CONST.REPORT.STATUS.SUBMITTED : CONST.REPORT.STATUS.OPEN;

return {
reportID: generateReportID(),
Expand All @@ -2560,8 +2568,9 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa

// We don't translate reportName because the server response is always in English
reportName: `${policyName} owes ${formattedTotal}`,
state: CONST.REPORT.STATE.SUBMITTED,
stateNum: CONST.REPORT.STATE_NUM.PROCESSING,
state,
stateNum,
statusNum,
Comment on lines +2578 to +2579
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding statusNum too because Draft report is defined by having both state and status set to 0

total: storedTotal,
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
parentReportID: chatReportID,
Expand Down
78 changes: 58 additions & 20 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,15 @@ function getMoneyRequestInformation(
const isNewIOUReport = !chatReport.iouReportID || ReportUtils.hasIOUWaitingOnCurrentUserBankAccount(chatReport);
let iouReport = isNewIOUReport ? null : allReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`];

// If the linked expense report on paid policy is not draft, we need to create a new draft expense report
if (isPolicyExpenseChat && iouReport) {
const policyType = ReportUtils.getPolicy(iouReport.policyID).type || '';
const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE;
if (isFromPaidPolicy && !ReportUtils.isReportDraft(iouReport)) {
iouReport = null;
}
}

if (iouReport) {
if (isPolicyExpenseChat) {
iouReport = {...iouReport};
Expand Down Expand Up @@ -2659,30 +2668,46 @@ function approveMoneyRequest(expenseReport) {
*/
function submitReport(expenseReport) {
const optimisticSubmittedReportAction = ReportUtils.buildOptimisticSubmittedReportAction(expenseReport.total, expenseReport.currency, expenseReport.reportID);
const parentReport = ReportUtils.getReport(expenseReport.parentReportID);

const optimisticReportActionsData = {
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`,
value: {
[optimisticSubmittedReportAction.reportActionID]: {
...optimisticSubmittedReportAction,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
const optimisticData = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`,
value: {
[optimisticSubmittedReportAction.reportActionID]: {
...optimisticSubmittedReportAction,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
},
},
},
};
const optimisticIOUReportData = {
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`,
value: {
...expenseReport,
lastMessageText: optimisticSubmittedReportAction.message[0].text,
lastMessageHtml: optimisticSubmittedReportAction.message[0].html,
state: CONST.REPORT.STATE.SUBMITTED,
stateNum: CONST.REPORT.STATE_NUM.PROCESSING,
statusNum: CONST.REPORT.STATUS.SUBMITTED,
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`,
value: {
...expenseReport,
lastMessageText: lodashGet(optimisticSubmittedReportAction, 'message.0.text', ''),
lastMessageHtml: lodashGet(optimisticSubmittedReportAction, 'message.0.html', ''),
state: CONST.REPORT.STATE.SUBMITTED,
stateNum: CONST.REPORT.STATE_NUM.PROCESSING,
statusNum: CONST.REPORT.STATUS.SUBMITTED,
},
},
};
const optimisticData = [optimisticIOUReportData, optimisticReportActionsData];
...(parentReport.reportID
? [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`,
value: {
...parentReport,
hasOutstandingIOU: false,
hasOutstandingChildRequest: false,
iouReportID: null,
Comment on lines +2703 to +2705
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The submitter does not have an outstanding child request anymore on the workspace chat even if they did not have one before.

removing the iouReportID key ensure we wont try to create new transaction on processing report

},
},
]
: []),
];

const successData = [
{
Expand Down Expand Up @@ -2714,6 +2739,19 @@ function submitReport(expenseReport) {
stateNum: CONST.REPORT.STATE_NUM.OPEN,
},
},
...(parentReport.reportID
? [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${parentReport.reportID}`,
value: {
hasOutstandingIOU: parentReport.hasOutstandingIOU,
hasOutstandingChildRequest: parentReport.hasOutstandingChildRequest,
iouReportID: expenseReport.reportID,
},
},
]
: []),
];

API.write(
Expand Down