-
Notifications
You must be signed in to change notification settings - Fork 3k
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
[Awaiting checklist] [$250] [Held requests] 'Hold expense` option does not show in the preview overflow menu #41440
Comments
Triggered auto assignment to @twisterdotcom ( |
ProposalPlease re-state the problem that we are trying to solve in this issue.[Held requests] 'Hold expense` option does not show in the preview overflow menu What is the root cause of that problem?New feature What changes do you think we should make in order to solve the problem?Steps we need to follow to get this feature working:
Code {
isAnonymousAction: false,
textTranslateKey: 'iou.unholdExpense',
icon: Expensicons.Stopwatch,
shouldShow: (type, reportAction) =>
type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction) && ReportUtils.canHoldUnholdReportAction(reportAction).canUnholdRequest,
onPress: (closePopover, {reportID, reportAction}) => {
// const hold=ReportUtils.changeMoneyRequestHoldStatus().
if (closePopover) {
hideContextMenu(false, () => ReportUtils.changeMoneyRequestHoldStatus(reportAction));
return;
}
// No popover to hide, call changeMoneyRequestHoldStatus immediately
ReportUtils.changeMoneyRequestHoldStatus(reportAction);
},
getDescription: () => {},
},
{
isAnonymousAction: false,
textTranslateKey: 'iou.hold',
icon: Expensicons.Stopwatch,
shouldShow: (type, reportAction) =>
type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION && ReportUtils.canEditReportAction(reportAction) && ReportUtils.canHoldUnholdReportAction(reportAction).canHoldRequest,
onPress: (closePopover, {reportID, reportAction}) => {
// const hold=ReportUtils.changeMoneyRequestHoldStatus().
if (closePopover) {
hideContextMenu(false, () => ReportUtils.changeMoneyRequestHoldStatus(reportAction));
return;
}
// No popover to hide, call changeMoneyRequestHoldStatus immediately
ReportUtils.changeMoneyRequestHoldStatus(reportAction);
},
getDescription: () => {},
},
Code
function getParentReportAction(parentReportActions: ReportActions | null | undefined, parentReportActionID: string | undefined): ReportAction | null {
if (!parentReportActions || !parentReportActionID) {
return null;
}
return parentReportActions[parentReportActionID ?? '0'];
}
function canHoldUnholdReportAction(reportAction: OnyxEntry<ReportAction>): {canHoldRequest: boolean; canUnholdRequest: boolean} {
if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) {
return {canHoldRequest: false, canUnholdRequest: false};
}
const moneyRequestReportID = reportAction?.originalMessage?.IOUReportID ?? 0;
if (!moneyRequestReportID) {
return {canHoldRequest: false, canUnholdRequest: false};
}
const moneyRequestReport = getReport(String(moneyRequestReportID));
if (!moneyRequestReport) {
return {canHoldRequest: false, canUnholdRequest: false};
}
const isSettled = ReportUtils.isSettled(moneyRequestReport?.reportID);
const isApproved = ReportUtils.isReportApproved(moneyRequestReport);
const transactionID = moneyRequestReport ? reportAction?.originalMessage?.IOUTransactionID : 0;
const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction);
const parentReportActionsKey = `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`;
const parentReportActions = allReportActions?.[parentReportActionsKey];
const parentReport = getReport(String(moneyRequestReport.parentReportID));
const parentReportAction = getParentReportAction(parentReportActions, moneyRequestReport?.parentReportActionID);
const isRequestIOU = parentReport?.type === 'iou';
const isHoldCreator = ReportUtils.isHoldCreator(transaction, moneyRequestReport?.reportID) && isRequestIOU;
const isTrackExpenseReport = ReportUtils.isTrackExpenseReport(moneyRequestReport);
const isActionOwner =
typeof parentReportAction?.actorAccountID === 'number' &&
typeof currentUserPersonalDetails?.accountID === 'number' &&
parentReportAction.actorAccountID === currentUserPersonalDetails?.accountID;
const isApprover =
ReportUtils.isMoneyRequestReport(moneyRequestReport) && moneyRequestReport?.managerID !== null && currentUserPersonalDetails?.accountID === moneyRequestReport?.managerID;
const isOnHold = TransactionUtils.isOnHold(transaction);
const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction);
const canModifyStatus = !isTrackExpenseReport && (isPolicyAdmin || isActionOwner || isApprover);
const isDeletedParentAction = ReportActionsUtils.isDeletedAction(parentReportAction);
const canHoldOrUnholdRequest = !isSettled && !isApproved && !isDeletedParentAction;
const canHoldRequest = canHoldOrUnholdRequest && !isOnHold && (isHoldCreator || (!isRequestIOU && canModifyStatus)) && !isScanning;
const canUnholdRequest = Boolean(canHoldOrUnholdRequest && isOnHold && (isHoldCreator || (!isRequestIOU && canModifyStatus)));
return {canHoldRequest, canUnholdRequest};
}
Codeconst changeMoneyRequestHoldStatus = (reportAction: OnyxEntry<ReportAction>): void => {
if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) {
return;
}
const moneyRequestReportID = reportAction?.originalMessage?.IOUReportID ?? 0;
const moneyRequestReport = getReport(String(moneyRequestReportID));
if (!moneyRequestReportID || !moneyRequestReport) {
return;
}
const parentReportActionsKey = `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`;
const parentReportActions = allReportActions?.[parentReportActionsKey];
const parentReportAction = getParentReportAction(parentReportActions, moneyRequestReport?.parentReportActionID);
const transactionID = moneyRequestReport ? reportAction?.originalMessage?.IOUTransactionID : 0;
const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction);
const isOnHold = TransactionUtils.isOnHold(transaction);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${moneyRequestReport.policyID}`] ?? null;
const iouTransactionID = parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? parentReportAction.originalMessage?.IOUTransactionID ?? '' : '';
if (isOnHold) {
IOU.unholdRequest(transactionID, reportAction.childReportID);
} else {
const activeRoute = encodeURIComponent(Navigation.getActiveRouteWithoutParams());
Navigation.navigate(ROUTES.MONEY_REQUEST_HOLD_REASON.getRoute(policy?.type ?? CONST.POLICY.TYPE.PERSONAL, transactionID, reportAction.childReportID, activeRoute));
}
}; PS: This is just a pseudo-code which will be refactored. What alternative solutions did you explore? (Optional)Resulthold_unhold_feat.mp4 |
Job added to Upwork: https://www.upwork.com/jobs/~0124de9c5bfd8809b9 |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @hungvu193 ( |
@Krishna2323's proposal here is straightforward 💪. LGTM! |
Triggered auto assignment to @flodnv, see https://stackoverflow.com/c/expensify/questions/7972 for more details. |
@flodnv, @twisterdotcom, @hungvu193 Whoops! This issue is 2 days overdue. Let's get this updated quick! |
bump @flodnv for final review. |
@robertjchen @marcochavezf perhaps one of you can do the secondary proposal review? |
Reviewed and agreed with @Krishna2323 's proposal 👍 |
📣 @hungvu193 🎉 An offer has been automatically sent to your Upwork account for the Reviewer role 🎉 Thanks for contributing to the Expensify app! |
📣 @Krishna2323 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app! Offer link |
This requires a good amount of testing and work. I will raise PR on the weekends. |
Still working on the PR |
Same |
One more tiny lint issue on the PR and we can merge 👍 |
merged and now on staging |
|
The solution for this issue has been 🚀 deployed to production 🚀 in version 1.4.82-4 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue: If no regressions arise, payment will be issued on 2024-06-20. 🎊 For reference, here are some details about the assignees on this issue:
|
BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
|
Payment Summary:
|
This is more of feature request than a bug, I don't think we should create a regression test IMO. |
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: 1.4.69-0
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Expensify/Expensify Issue URL:
Issue reported by: @JmillsExpensify
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1714532350260749
Action Performed:
Expected Result:
Hold is an option in the comment action overflow menu
Actual Result:
Hold is not available
Workaround:
unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Screenshots/Videos
Add any screenshot/video evidence
View all open jobs on GitHub
Upwork Automation - Do Not Edit
Issue Owner
Current Issue Owner: @twisterdotcomThe text was updated successfully, but these errors were encountered: