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

[CP Staging] Expense - No option to cancel payment for paid expense as 3-dot menu is removed #45130

Merged
Merged
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
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2351,6 +2351,7 @@ const CONST = {
PRIVATE_NOTES: 'privateNotes',
DELETE: 'delete',
MARK_AS_INCOMPLETE: 'markAsIncomplete',
CANCEL_PAYMENT: 'cancelPayment',
UNAPPROVE: 'unapprove',
},
EDIT_REQUEST_FIELD: {
Expand Down
20 changes: 0 additions & 20 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const canAllowSettlement = ReportUtils.hasUpdatedTotal(moneyRequestReport, policy);
const policyType = policy?.type;
const isDraft = ReportUtils.isOpenExpenseReport(moneyRequestReport);
const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);

const navigateBackToAfterDelete = useRef<Route>();
const hasScanningReceipt = ReportUtils.getTransactionsWithReceipts(moneyRequestReport?.reportID).some((t) => TransactionUtils.isReceiptBeingScanned(t));
Expand All @@ -108,14 +107,6 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
// allTransactions in TransactionUtils might have stale data
const hasOnlyHeldExpenses = ReportUtils.hasOnlyHeldExpenses(moneyRequestReport.reportID, transactions);

const cancelPayment = useCallback(() => {
if (!chatReport) {
return;
}
IOU.cancelPayment(moneyRequestReport, chatReport);
setIsConfirmModalVisible(false);
}, [moneyRequestReport, chatReport]);

const shouldShowPayButton = useMemo(() => IOU.canIOUBePaid(moneyRequestReport, chatReport, policy), [moneyRequestReport, chatReport, policy]);

const shouldShowApproveButton = useMemo(() => IOU.canApproveIOU(moneyRequestReport, chatReport, policy), [moneyRequestReport, chatReport, policy]);
Expand Down Expand Up @@ -371,17 +362,6 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
transactionCount={transactionIDs.length}
/>
)}
<ConfirmModal
title={translate('iou.cancelPayment')}
isVisible={isConfirmModalVisible}
onConfirm={cancelPayment}
onCancel={() => setIsConfirmModalVisible(false)}
prompt={translate('iou.cancelPaymentConfirmation')}
confirmText={translate('iou.cancelPayment')}
cancelText={translate('common.dismiss')}
danger
shouldEnableNewFocusManagement
/>
<ConfirmModal
title={translate('iou.deleteExpense')}
isVisible={isDeleteRequestModalVisible}
Expand Down
6 changes: 5 additions & 1 deletion src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6604,7 +6604,11 @@ function submitReport(expenseReport: OnyxTypes.Report) {
API.write(WRITE_COMMANDS.SUBMIT_REPORT, parameters, {optimisticData, successData, failureData});
}

function cancelPayment(expenseReport: OnyxTypes.Report, chatReport: OnyxTypes.Report) {
function cancelPayment(expenseReport: OnyxEntry<OnyxTypes.Report>, chatReport: OnyxTypes.Report) {
if (isEmptyObject(expenseReport)) {
return;
}

const optimisticReportAction = ReportUtils.buildOptimisticCancelPaymentReportAction(expenseReport.reportID, -(expenseReport.total ?? 0), expenseReport.currency ?? '');
const policy = PolicyUtils.getPolicy(chatReport.policyID);
const isFree = policy && policy.type === CONST.POLICY.TYPE.FREE;
Expand Down
38 changes: 38 additions & 0 deletions src/pages/ReportDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
const [isLastMemberLeavingGroupModalVisible, setIsLastMemberLeavingGroupModalVisible] = useState(false);
const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
const [isUnapproveModalVisible, setIsUnapproveModalVisible] = useState(false);
const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);
const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? '-1'}`], [policies, report?.policyID]);
const isPolicyAdmin = useMemo(() => PolicyUtils.isPolicyAdmin(policy), [policy]);
const isPolicyEmployee = useMemo(() => PolicyUtils.isPolicyEmployee(report?.policyID ?? '-1', policies), [report?.policyID, policies]);
Expand Down Expand Up @@ -263,6 +264,21 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
const shouldShowWriteCapability = !isMoneyRequestReport;
const shouldShowMenuItem = shouldShowNotificationPref || shouldShowWriteCapability || (!!report?.visibility && report.chatType !== CONST.REPORT.CHAT_TYPE.INVOICE);

const isPayer = ReportUtils.isPayer(session, moneyRequestReport);
const isSettled = ReportUtils.isSettled(moneyRequestReport?.reportID ?? '-1');
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we need this default really

Suggested change
const isSettled = ReportUtils.isSettled(moneyRequestReport?.reportID ?? '-1');
const isSettled = ReportUtils.isSettled(moneyRequestReport?.reportID);

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 might be obsolete but I wanted to add it as an extra percussion to make sure this doesn't cause a crash anytime in the app.


const shouldShowCancelPaymentButton = caseID === CASES.MONEY_REPORT && isPayer && isSettled && ReportUtils.isExpenseReport(moneyRequestReport);
Comment on lines +267 to +270
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make a utility function out of this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, why are we adding this extra check here? This did not exist in the MoneyReportHeader component previously.

Copy link
Contributor Author

@cdOut cdOut Jul 10, 2024

Choose a reason for hiding this comment

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

I don't think that is necessary, this is done in the same way as shouldShowLeaveButton and canUnapproveRequest have been handled in the same file.

This is also the only place where the payment cancellation use-case gets called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again, the extra check is due to ReportDetailsPage unifying the functionality of three different components from before, MoneyRequestHeader, MoneyReportHeader and HeaderView. I wanted to make sure this only works for the case which it comes from, hence the CASES.MONEY_REPORT check.

const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReport?.chatReportID ?? '-1'}`);

const cancelPayment = useCallback(() => {
if (!chatReport) {
return;
}

IOU.cancelPayment(moneyRequestReport, chatReport);
setIsConfirmModalVisible(false);
}, [moneyRequestReport, chatReport]);

const menuItems: ReportDetailsPageMenuItem[] = useMemo(() => {
const items: ReportDetailsPageMenuItem[] = [];

Expand Down Expand Up @@ -356,6 +372,16 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
}
}

if (shouldShowCancelPaymentButton) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.CANCEL_PAYMENT,
icon: Expensicons.Trashcan,
translationKey: 'iou.cancelPayment',
isAnonymousAction: false,
action: () => setIsConfirmModalVisible(true),
});
}

if (shouldShowLeaveButton) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM,
Expand Down Expand Up @@ -403,6 +429,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
isCanceledTaskReport,
shouldShowLeaveButton,
activeChatMembers.length,
shouldShowCancelPaymentButton,
isPolicyAdmin,
session,
leaveChat,
Expand Down Expand Up @@ -710,6 +737,17 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
confirmText={translate('common.leave')}
cancelText={translate('common.cancel')}
/>
<ConfirmModal
title={translate('iou.cancelPayment')}
isVisible={isConfirmModalVisible}
onConfirm={cancelPayment}
onCancel={() => setIsConfirmModalVisible(false)}
prompt={translate('iou.cancelPaymentConfirmation')}
confirmText={translate('iou.cancelPayment')}
cancelText={translate('common.dismiss')}
danger
shouldEnableNewFocusManagement
/>
<ConfirmModal
title={caseID === CASES.DEFAULT ? translate('task.deleteTask') : translate('iou.deleteExpense')}
isVisible={isDeleteModalVisible}
Expand Down
Loading