Skip to content

[$250] We show wallet balance badge even for those who haven't enabled Expensify wallet #61248

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

Open
4 of 16 tasks
m-natarajan opened this issue May 1, 2025 · 19 comments
Open
4 of 16 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2

Comments

@m-natarajan
Copy link

m-natarajan commented May 1, 2025

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: 9.1.38-3
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: @joekaufmanexpensify
Slack conversation (hyperlinked to channel name): #Expensify Bugs

Action Performed:

  1. Login to a new account.
  2. Go to Settings > Wallet.

Expected Result:

You only see the badge for wallet balance in the wallet row if you've enabled your wallet.

Actual Result:

You see the badge for wallet balance, even if you haven't enabled your wallet.

Workaround:

Unknown

Platforms:

Select the officially supported platforms where the issue was reproduced:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari
  • MacOS: Desktop
Platforms Tested: On which of our officially supported platforms was this issue tested:
  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Add any screenshot/video evidence

Image

Image

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~021920822669207141133
  • Upwork Job ID: 1920822669207141133
  • Last Price Increase: 2025-05-09
  • Automatic offers:
    • twilight2294 | Contributor | 107282150
Issue OwnerCurrent Issue Owner: @lakchote
@m-natarajan m-natarajan added Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 labels May 1, 2025
Copy link

melvin-bot bot commented May 1, 2025

Triggered auto assignment to @JmillsExpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@twilight2294
Copy link
Contributor

twilight2294 commented May 1, 2025

Image

🚨 Edited by proposal-police: This proposal was edited at 2025-05-01 15:22:17 UTC.

Proposal

Please re-state the problem that we are trying to solve in this issue.

We show wallet balance badge even for those who haven't enabled Expensify wallet

What is the root cause of that problem?

We show the balance regardless of it beeing enabled or disabled

pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
errors={walletTerms?.errors}
onClose={clearWalletTermsError}
errorRowStyles={[styles.ml10, styles.mr2]}
style={[styles.mt4, styles.mb2]}
>
<MenuItemWithTopDescription
description={translate('walletPage.balance')}
title={convertToDisplayString(userWallet?.currentBalance ?? 0)}
titleStyle={styles.textHeadlineH2}

What changes do you think we should make in order to solve the problem?

We should add condition to only show when the wallet is enabled

pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
errors={walletTerms?.errors}
onClose={clearWalletTermsError}
errorRowStyles={[styles.ml10, styles.mr2]}
style={[styles.mt4, styles.mb2]}
>
<MenuItemWithTopDescription
description={translate('walletPage.balance')}
title={convertToDisplayString(userWallet?.currentBalance ?? 0)}
titleStyle={styles.textHeadlineH2}

use condition hasActivatedWallet:

{shouldShowLoadingSpinner ? (
    <ActivityIndicator
        color={theme.spinner}
        size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
        style={[styles.mt7, styles.mb5]}
    />
) : hasActivatedWallet ? (
    <OfflineWithFeedback
        pendingAction={CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}
        errors={walletTerms?.errors}
        onClose={clearWalletTermsError}
        errorRowStyles={[styles.ml10, styles.mr2]}
        style={[styles.mt4, styles.mb2]}
    >
        <MenuItemWithTopDescription
            description={translate('walletPage.balance')}
            title={convertToDisplayString(userWallet?.currentBalance ?? 0)}
            titleStyle={styles.textHeadlineH2}
            interactive={false}
            wrapperStyle={styles.sectionMenuItemTopDescription}
            copyValue={convertToDisplayString(userWallet?.currentBalance ?? 0)}
        />
    </OfflineWithFeedback>
) : null}

Also we need to update the initial settings page to not show the balance until the card is in active state:

badgeText={item.badgeText ?? getWalletBalance(isPaymentItem)}

    const hasActivatedWallet = ([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM] as string[]).includes(userWallet?.tierName ?? '');
badgeText={hasActivatedWallet ? item.badgeText ?? getWalletBalance(isPaymentItem) : undefined} 

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

N/A

What alternative solutions did you explore? (Optional)

N/A

Image

@nyomanjyotisa
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

We show wallet balance badge even for those who haven't enabled Expensify wallet

What is the root cause of that problem?

We always show the balance badge

What changes do you think we should make in order to solve the problem?

We should pass undefined to badgeText if wallet not enabled

const hasWallet = !isEmpty(userWallet);
badgeText={hasWallet ? item.badgeText ?? getWalletBalance(isPaymentItem) : undefined}

badgeText={item.badgeText ?? getWalletBalance(isPaymentItem)}

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

None

What alternative solutions did you explore? (Optional)

N/A

@ryntgh
Copy link
Contributor

ryntgh commented May 1, 2025

Proposal

Please re-state the problem that we are trying to solve in this issue.

We show wallet balance badge even for those who haven't enabled Expensify wallet

What is the root cause of that problem?

The badge logic does not check the wallet’s activation status (tierName). It currently shows the balance if userWallet.currentBalance exists, even if the wallet is inactive.

const getWalletBalance = (isPaymentItem: boolean): string | undefined => (isPaymentItem ? convertToDisplayString(userWallet?.currentBalance) : undefined);

What changes do you think we should make in order to solve the problem?

Only display the wallet balance badge if the wallet is activated (userWallet.tierName is GOLD or PLATINUM).

            const getWalletBalance = (isPaymentItem: boolean): string | undefined => {
                if (!isPaymentItem) {
                    return undefined;
                }
                const isWalletActivated = userWallet?.tierName === CONST.WALLET.TIER_NAME.GOLD || userWallet?.tierName === CONST.WALLET.TIER_NAME.PLATINUM;
                return isWalletActivated ? convertToDisplayString(userWallet?.currentBalance) : undefined;
            };

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

N/A


What alternative solutions did you explore? (Optional)

@Burhan-Rashid
Copy link

Proposal

Please re-state the problem that we are trying to solve in this issue.

We show wallet balance badge even for those users who haven't enabled Expensify wallet

What is the root cause of that problem?

we don't check whether the wallet is enabled or disabled for the user. We show the wallet balance when user has currentBalance in the wallet and the badgeText is null or undefined.

What changes do you think we should make in order to solve the problem?

we are already calculating the wallet status at couple of places in the codebase. we should create a utility function named isWalletActivated inside src/libs/Wallet/index.ts and use that at all the places to check the wallet status.

function isWalletActivated(tierName: string | undefined): boolean {
    return [CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM].some((name) => name === tierName);
}

Changes to be made in file: src/pages/settings/InitialSettingsPage.tsx

    const hasActivatedWallet = isWalletActivated(userWallet?.tierName);

    <MenuItem
                      key={keyTitle}
                      wrapperStyle={styles.sectionMenuItem}
                      title={keyTitle}
                      icon={item.icon}
                      iconType={item.iconType}
                      disabled={isExecuting}
                      onPress={singleExecution(() => {
                          item.action();
                      })}
                      iconStyles={item.iconStyles}
                      badgeText={item.badgeText ?? getWalletBalance(hasActivatedWallet && isPaymentItem)}

const getWalletBalance = (isPaymentItem: boolean): string | undefined => (isPaymentItem ? convertToDisplayString(userWallet?.currentBalance) : undefined);

getWalletBalance already returns undefined if we pass false to it.
so this line will work perfectly fine for our usecase: getWalletBalance(hasActivatedWallet && isPaymentItem)

Other files where we are currently calculating the wallet status:

const hasActivatedWallet = userWallet?.tierName && [CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM].some((name) => name === userWallet.tierName);

const hasActivatedWallet = ([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM] as string[]).includes(userWallet?.tierName ?? '');

Changes that we need to make in these files:

    import {isWalletActivated} from '@libs/Wallet';

    const hasActivatedWallet = isWalletActivated(userWallet?.tierName);

What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?

N/A

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.

@melvin-bot melvin-bot bot added the Overdue label May 5, 2025
Copy link

melvin-bot bot commented May 5, 2025

@JmillsExpensify Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

Copy link

melvin-bot bot commented May 7, 2025

@JmillsExpensify Eep! 4 days overdue now. Issues have feelings too...

Copy link

melvin-bot bot commented May 9, 2025

@JmillsExpensify 6 days overdue. This is scarier than being forced to listen to Vogon poetry!

@joekaufmanexpensify joekaufmanexpensify added the External Added to denote the issue can be worked on by a contributor label May 9, 2025
@melvin-bot melvin-bot bot changed the title We show wallet balance badge even for those who haven't enabled Expensify wallet [$250] We show wallet balance badge even for those who haven't enabled Expensify wallet May 9, 2025
Copy link

melvin-bot bot commented May 9, 2025

Job added to Upwork: https://www.upwork.com/jobs/~021920822669207141133

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label May 9, 2025
Copy link

melvin-bot bot commented May 9, 2025

Triggered auto assignment to Contributor-plus team member for initial proposal review - @hungvu193 (External)

@melvin-bot melvin-bot bot removed the Overdue label May 9, 2025
@hungvu193
Copy link
Contributor

will review in the morning

@hungvu193
Copy link
Contributor

Thanks for the proposals, everyone. I've checked the codes. Every user will have the wallet object by default. I think it makes sense to hide the balance only if they don't have an active wallet. Because of that, I'm aligned with @twilight2294 's proposal here, as he was the first one to propose the correct solution.
@twilight2294 I'm not a big fan of double ternary operation, let's address that during PR phase.

Image

🎀 👀 🎀

Copy link

melvin-bot bot commented May 13, 2025

Triggered auto assignment to @lakchote, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@Burhan-Rashid
Copy link

@hungvu193 The condition to show the badgeText is not correct in the accepted solution.
badgeText={hasActivatedWallet ? item.badgeText ?? getWalletBalance(isPaymentItem) : undefined}
if the hasActivatedWallet condition gets false, the badgeText is going to be undefined according to that solution but that should not be the case always as MenuItem is a generic component and we only need to hide the badgeText for the wallet row.
Moreover We only need to hide the badgeText in the left side bar as mentioned in the bug details. I don't think we need to hide the Wallet balance on the details page as well.

@hungvu193
Copy link
Contributor

Sorry, I don't get it. badgeText is an optional prop, I don't have any issue if it's undefined. As I explained above, we should hide it when user doesn't have an active wallet.

{!!badgeText && (
<Badge
text={badgeText}
badgeStyles={badgeStyle}
/>
)}

@lakchote
Copy link
Contributor

Let's go with @twilight2294's proposal. I do agree with @hungvu193 that the double ternary is not ideal and should be addressed in the PR.

@melvin-bot melvin-bot bot removed the Help Wanted Apply this label when an issue is open to proposals by contributors label May 13, 2025
Copy link

melvin-bot bot commented May 13, 2025

📣 @twilight2294 🎉 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 📖

@Burhan-Rashid
Copy link

@hungvu193 We can address this at the time of PR review.
I was saying if there is another menuItem which is showing badgeText and we don't have activatedWallet then for that row also we will get undefined.
badgeText={hasActivatedWallet ? item.badgeText ?? getWalletBalance(isPaymentItem) : undefined}
as we are checking hasActivatedWallet before even checking the item.badgeText.
For example consider this row when hasActivatedWallet is false.

if (subscriptionPlan) {
items.splice(1, 0, {
translationKey: 'allSettingsScreen.subscription',
icon: Expensicons.CreditCard,
screenName: SCREENS.SETTINGS.SUBSCRIPTION.ROOT,
brickRoadIndicator: !!privateSubscription?.errors || hasSubscriptionRedDotError() ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
badgeText: freeTrialText,
badgeStyle: freeTrialText ? styles.badgeSuccess : undefined,
action: () => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION.route),
});
}

{menuItemsData.items.map((item) => {
const keyTitle = item.translationKey ? translate(item.translationKey) : item.title;
const isPaymentItem = item.translationKey === 'common.wallet';
const isFocused = focusedRouteName ? focusedRouteName === item.screenName : false;
return (
<MenuItem
key={keyTitle}
wrapperStyle={styles.sectionMenuItem}
title={keyTitle}
icon={item.icon}
iconType={item.iconType}
disabled={isExecuting}
onPress={singleExecution(() => {
item.action();
})}
iconStyles={item.iconStyles}
badgeText={item.badgeText ?? getWalletBalance(isPaymentItem)}
badgeStyle={item.badgeStyle}

@twilight2294
Copy link
Contributor

PR ready for review @hungvu193

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review Weekly KSv2
Projects
Status: No status
Development

No branches or pull requests

9 participants