[$125] [Search v2.2] Remove Invoice type from LHN if workspaces don't have it enabled
Problem
We currently show Invoice as a Search type in the LHN for users, but that's confusing if they never enabled that feature
Solution
Avoid confusion and remove the Invoice type if users don't have this option enabled in any of their policies
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~021851031006738225317
- Upwork Job ID: 1851031006738225317
- Last Price Increase: 2024-10-28
Issue Owner
Current Issue Owner: @eVoloshchak
Triggered auto assignment to @alexpensify (NewFeature), see https://stackoverflowteams.com/c/expensify/questions/14418#:~:text=BugZero%20process%20steps%20for%20feature%20requests for more details. Please add this Feature request to a GH project, as outlined in the SO.
Job added to Upwork: https://www.upwork.com/jobs/~021851031006738225317
Triggered auto assignment to Contributor-plus team member for initial proposal review - @eVoloshchak (External)
Upwork job price has been updated to $125
Edited by proposal-police: This proposal was edited at 2024-10-28 22:58:42 UTC.
Proposalβ¨
Please re-state the problem that we are trying to solve in this issue.
[Search v2.2] Remove Invoice type from LHN if workspaces don't have it enabled
What is the root cause of that problem?
Improvement
What changes do you think we should make in order to solve the problem?β¨
- We should create a new util function
hasPolicyWithEnabledInvoiceinPolicyUtilsto check if there is any workspace with enabled invoice.
function hasPolicyWithEnabledInvoice() {
return Object.values(allPolicies ?? {}).some((policy) => {
return policy && policy.areInvoicesEnabled && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
});
}
- We should remove the
Invoicesoption fromtypeMenuItemsand only push it ifPolicyUtils.hasPolicyWithEnabledInvoice()is true. - We can also use
useMemoto memoize the result ofhasPolicyWithEnabledInvoice. We would nee to getallPoliciesfrom onyx.
const isInvoiceEnabled = useMemo(() => PolicyUtils.hasPolicyWithEnabledInvoice(), [allPolicies]);
https://github.com/Expensify/App/blob/8ef040a10a1b7b2b900ff0bf10b4e7d49ff1e60a/src/pages/Search/SearchTypeMenu.tsx#L90-L98
if (PolicyUtils.hasPolicyWithEnabledInvoice()) {
typeMenuItems.push({
title: translate('workspace.common.invoices'),
type: CONST.SEARCH.DATA_TYPES.INVOICE,
icon: Expensicons.InvoiceGeneric,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.INVOICE, status: CONST.SEARCH.STATUS.INVOICE.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
});
}
- Same should be done in
SearchTypeMenuNarrowfile.
What alternative solutions did you explore? (Optional)
- We can optionally add the option in the array to keep the option at the same index.
const typeMenuItems: SearchTypeMenuItem[] = [
{
title: translate('common.expenses'),
type: CONST.SEARCH.DATA_TYPES.EXPENSE,
icon: Expensicons.Receipt,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
{
title: translate('common.chats'),
type: CONST.SEARCH.DATA_TYPES.CHAT,
icon: Expensicons.ChatBubbles,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.CHAT, status: CONST.SEARCH.STATUS.CHAT.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
...((PolicyUtils.hasPolicyWithEnabledInvoice()
? [
{
title: translate('workspace.common.invoices'),
type: CONST.SEARCH.DATA_TYPES.INVOICE,
icon: Expensicons.InvoiceGeneric,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.INVOICE, status: CONST.SEARCH.STATUS.INVOICE.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
]
: []),
{
title: translate('travel.trips'),
type: CONST.SEARCH.DATA_TYPES.TRIP,
icon: Expensicons.Suitcase,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.TRIP, status: CONST.SEARCH.STATUS.TRIP.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
},
];
Result
only push it to the array if policyID from query is undefined
I think this part is incorrect. We want to push it to the array if you have any policies with invoices enabled in Onyx.
@luacmartins, I have updated my proposal .
Proposal
Please re-state the problem that we are trying to solve in this issue.
Remove Invoice type from LHN in Search if it is not enabled
What is the root cause of that problem?
Invoice type is added to search LHN from here and it is always added to the LHN Menu even if user does not use invoices.
What changes do you think we should make in order to solve the problem?
A user will only use invoices if it is enabled in one of their workspaces or they have received an invoice from somebody else as admins can send Invoice to users outside their workspace and the user will not be added to workspace. So, we need to update here to only add Invoices to menu items if they have a workspace with invoices or an invoice has been sent to them. The updated logic would look like this. The Implementation can be done like below:
Current:
https://github.com/Expensify/App/blob/b2d14a13b2dac82be60c79b6959bda14741e01f1/src/pages/Search/SearchTypeMenu.tsx#L71-L108
New:
const session = useOnyx(ONYXKEYS.SESSION)
const typeMenuItems = [
...
]
if (PolicyUtils.hasWorkspaceWithInvoices(session?.email) || ReportUtils.hasInvoiceReports()) typeMenuItems.push({
title: translate('workspace.common.invoices'),
type: CONST.SEARCH.DATA_TYPES.INVOICE,
icon: Expensicons.InvoiceGeneric,
getRoute: (policyID?: string) => {
const query = SearchQueryUtils.buildCannedSearchQuery({type: CONST.SEARCH.DATA_TYPES.INVOICE, status: CONST.SEARCH.STATUS.INVOICE.ALL, policyID});
return ROUTES.SEARCH_CENTRAL_PANE.getRoute({query});
},
})
typeMenuItems.push({
title: translate('travel.trips'),
type: CONST.SEARCH.DATA_TYPES.TRIP,
...
})
Policies with Invoice
We can reuse some of the logic from the Send Invoice button for FAB, which currently looks like this:
https://github.com/Expensify/App/blob/ce0161406526fe7b333cbca7c08f93a74f5204e5/src/libs/PolicyUtils.ts#L597-L612
so, hasWorkspaceWithInvoices will look like:
function hasWorkspaceWithInvoices(currentUserLogin) {
const activePolicies = getActivePolicies(allPolicies);
return activePolicies.some((policy) => shouldShowPolicy(policy, NetworkStore.isOffline(), currentUserLogin) && policy.areInvoicesEnabled);
}
Invoice Report to external members
function hasInvoiceReports() {
const allReports = ReportConnection.getAllReports();
return allReports.some(report => isInvoiceReport(report))
}
Note: all the code samples are for explaination only and can be improved during PR
What alternative solutions did you explore? (Optional)
Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.
@eVoloshchak - when you get a chance, can you please review if one of these proposals will fix the issue? Thanks!
@alexpensify, @eVoloshchak, @luacmartins Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
@eVoloshchak any update here? Thanks!
π£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πΈ
@eVoloshchak please keep me posted if you are unable to review. I will need to reassign by Wednesday if no answer.
@alexpensify, @eVoloshchak, @luacmartins Still overdue 6 days?! Let's take care of this!
@eVoloshchak any updates here?
π£ @Krishna2323 π An offer has been automatically sent to your Upwork account for the Contributor role π Thanks for contributing to the Expensify app!
Offer link Upwork job Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review π§βπ» Keep in mind: Code of Conduct | Contributing π
Actually, @Krishna2323's proposal looks good, so gonna assign the issue to him.
@Krishna2323 please prioritize this PR as it's a high value one
@luacmartins, thanks for assigning, PR will be up in 30 mins.
Love it! Thank you.
@luacmartins, apologies, but I think my proposal is incomplete. My current proposal only checks whether we have a workspace with invoices enabled. However, an invoice can still be sent to a user who does not have an invoice-enabled workspace, and in that case, my solution will not show the Invoices filter even if an invoice exists. We need to also check if there is a invoice report or not as mentioned in this proposal.
Let me know if the PR is urgent, I can complete it using @jaydamani's solution without any compensation, and jaydamani will be compensated for their solution. Thanks for your understanding.
AH I see. Thanks for bringing that up. @jaydamani are you available to work on the PR?
I am not available right now but I can work on it tomorrow so if it's urgent please assign it to @Krishna2323 Also, I think whoever implements it should be compensated so, if it's assigned to @Krishna2323 then they should be compensated.
Sure, I'll reassign to you @jaydamani since you're proposal was more complete as @Krishna2323 pointed out above.
π£ @jaydamani π An offer has been automatically sent to your Upwork account for the Contributor role π Thanks for contributing to the Expensify app!
Offer link Upwork job Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review π§βπ» Keep in mind: Code of Conduct | Contributing π
Starting work on this
Created PR
Reviewing label has been removed, please complete the "BugZero Checklist".
The solution for this issue has been :rocket: deployed to production :rocket: in version 9.0.60-3 and is now subject to a 7-day regression period :calendar:. Here is the list of pull requests that resolve this issue:
- https://github.com/Expensify/App/pull/52148
If no regressions arise, payment will be issued on 2024-11-20. :confetti_ball:
For reference, here are some details about the assignees on this issue:
- @rushatgabhane requires payment through NewDot Manual Requests
- @jaydamani requires payment automatic offer (Contributor)
BugZero Checklist: The PR adding this new feature has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
- [ ] [@rushatgabhane] Please propose regression test steps to ensure the new feature will work correctly on production in further releases.
- [ ] [@alexpensify] Link the GH issue for creating/updating the regression test once above steps have been agreed upon.