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

Tgolen improve settlementbutton #34689

Closed
wants to merge 7 commits into from
Closed
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 @@ -1167,6 +1167,7 @@ const CONST = {
DEBIT_CARD: 'debitCard',
PERSONAL_BANK_ACCOUNT: 'bankAccount',
BUSINESS_BANK_ACCOUNT: 'businessBankAccount',
ELSEWHERE: 'elsewhere',
},

PAYMENT_METHOD_ID_KEYS: {
Expand Down
11 changes: 9 additions & 2 deletions src/components/ButtonWithDropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ type DropdownOption = {
};

type ButtonWithDropdownMenuProps = {
/**
* This text will be used for the main button text. If this option is ommitted, then the text of the first selected option is used for the button text instead.
* Use this when you want to display a different text for the button than the text of the first selected option.
*/
text?: string;

/** Text to display for the menu header */
menuHeaderText?: string;

Expand Down Expand Up @@ -63,6 +69,7 @@ function ButtonWithDropdownMenu({
isDisabled = false,
pressOnEnter = false,
menuHeaderText = '',
text = '',
style,
buttonSize = CONST.DROPDOWN_BUTTON_SIZE.MEDIUM,
anchorAlignment = {
Expand Down Expand Up @@ -114,7 +121,7 @@ function ButtonWithDropdownMenu({
pressOnEnter={pressOnEnter}
ref={buttonRef}
onPress={(event) => onPress(event, selectedItem.value)}
text={selectedItem.text}
text={text || selectedItem.text}
isDisabled={isDisabled}
isLoading={isLoading}
shouldRemoveRightBorderRadius
Expand Down Expand Up @@ -154,7 +161,7 @@ function ButtonWithDropdownMenu({
isDisabled={isDisabled}
style={[styles.w100, style]}
isLoading={isLoading}
text={selectedItem.text}
text={text || selectedItem.text}
onPress={(event) => onPress(event, options[0].value)}
large={isButtonSizeLarge}
medium={!isButtonSizeLarge}
Expand Down
2 changes: 2 additions & 0 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt
shouldShowApproveButton={shouldShowApproveButton}
style={[styles.pv2]}
formattedAmount={formattedAmount}
buttonText={`${translate('iou.pay')} ${formattedAmount}`}
/>
</View>
)}
Expand Down Expand Up @@ -188,6 +189,7 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt
shouldHidePaymentOptions={!shouldShowPayButton}
shouldShowApproveButton={shouldShowApproveButton}
formattedAmount={formattedAmount}
buttonText={`${translate('iou.pay')} ${formattedAmount}`}
/>
</View>
)}
Expand Down
104 changes: 91 additions & 13 deletions src/components/SettlementButton.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useEffect, useMemo} from 'react';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import compose from '@libs/compose';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import iouReportPropTypes from '@pages/iouReportPropTypes';
import * as BankAccounts from '@userActions/BankAccounts';
Expand Down Expand Up @@ -43,9 +45,6 @@
/** Should we show the payment options? */
shouldShowApproveButton: PropTypes.bool,

/** The last payment method used per policy */
nvp_lastPaymentMethod: PropTypes.objectOf(PropTypes.string),

/** The policyID of the report we are paying */
policyID: PropTypes.string,

Expand All @@ -55,6 +54,9 @@
/** Total money amount in form <currency><amount> */
formattedAmount: PropTypes.string,

/** The text to be displayed on the main button */
buttonText: PropTypes.string,

/** The size of button size */
buttonSize: PropTypes.oneOf(_.values(CONST.DROPDOWN_BUTTON_SIZE)),

Expand Down Expand Up @@ -84,6 +86,17 @@

/** Whether the personal bank account option should be shown */
shouldShowPersonalBankAccountOption: PropTypes.bool,

/* Onyx Props */

/** The last payment method used per policy */
nvp_lastPaymentMethod: PropTypes.objectOf(PropTypes.string),

/** Session info for the currently logged in user. */
session: PropTypes.shape({
/** Currently logged in user accountID */
accountID: PropTypes.number,
}),
};

const defaultProps = {
Expand All @@ -104,6 +117,7 @@
style: [],
policyID: '',
formattedAmount: '',
buttonText: '',
buttonSize: CONST.DROPDOWN_BUTTON_SIZE.MEDIUM,
kycWallAnchorAlignment: {
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, // button is at left, so horizontal anchor is at LEFT
Expand All @@ -113,6 +127,7 @@
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.RIGHT, // caret for dropdown is at right, so horizontal anchor is at RIGHT
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP, // we assume that popover menu opens below the button, anchor is at TOP
},
session: {},
shouldShowPersonalBankAccountOption: false,
};

Expand All @@ -129,10 +144,12 @@
isDisabled,
isLoading,
formattedAmount,
buttonText,
nvp_lastPaymentMethod,
onPress,
pressOnEnter,
policyID,
session,
shouldHidePaymentOptions,
shouldShowApproveButton,
style,
Expand All @@ -145,7 +162,64 @@
PaymentMethods.openWalletPage();
}, []);

const paymentButtonOptionsV2 = useMemo(() => {
const approveButtonOption = {
text: translate('iou.approve'),
icon: Expensicons.ThumbsUp,
value: CONST.IOU.REPORT_ACTION_TYPE.APPROVE,
};

// Only show the Approve button if the user cannot pay the request
if (shouldHidePaymentOptions && shouldShowApproveButton) {
return [approveButtonOption];
}

const buttonOptions = [];

const payWithBusinessBankAccountOption = {
text: translate('iou.payWithBusinessBankAccount'),
icon: Expensicons.Bank,
value: CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT,
};
const payWithPersonalBankAccountOption = {
text: translate('iou.payWithPersonalBankAccount'),
icon: Expensicons.Building,
value: CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT,
};
const payWithDebitCardOption = {
text: translate('iou.payWithDebitCard'),
icon: Expensicons.CreditCard,
value: CONST.PAYMENT_METHODS.DEBIT_CARD,
};
const payElsewhereOption = {
text: translate('iou.payElsewhere'),
icon: Expensicons.Cash,
value: CONST.PAYMENT_METHODS.ELSEWHERE,
};

// Users can choose to pay with business bank account in case of Expense reports or in case of P2P IOU report
// which then starts a bottom up flow and creates a Collect workspace where the payer is an admin and payee is an employee.
if (
ReportUtils.isExpenseReport(iouReport) ||
(ReportUtils.isIOUReport(iouReport) && !ReportActionsUtils.hasRequestFromCurrentAccount(lodashGet(iouReport, 'reportID', 0), lodashGet(session, 'accountID', 0)))
) {
buttonOptions.push(payWithBusinessBankAccountOption);
}

if (shouldShowPersonalBankAccountOption || ReportUtils.isIOUReport(iouReport)) {
buttonOptions.push(payWithPersonalBankAccountOption);
}

buttonOptions.push(payWithDebitCardOption);
buttonOptions.push(payElsewhereOption);

if (shouldShowApproveButton) {
buttonOptions.push(approveButtonOption);
}
return buttonOptions;
}, [session, iouReport, translate, shouldShowPersonalBankAccountOption, shouldHidePaymentOptions, shouldShowApproveButton]);

const paymentButtonOptions = useMemo(() => {

Check failure on line 222 in src/components/SettlementButton.js

View workflow job for this annotation

GitHub Actions / lint

'paymentButtonOptions' is assigned a value but never used
const buttonOptions = [];
const isExpenseReport = ReportUtils.isExpenseReport(iouReport);
const paymentMethods = {
Expand All @@ -165,17 +239,17 @@
value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE,
},
};
const approveButtonOption = {
text: translate('iou.approve'),
icon: Expensicons.ThumbsUp,
value: CONST.IOU.REPORT_ACTION_TYPE.APPROVE,
};
// const approveButtonOption = {
// text: translate('iou.approve'),
// icon: Expensicons.ThumbsUp,
// value: CONST.IOU.REPORT_ACTION_TYPE.APPROVE,
// };
const canUseWallet = !isExpenseReport && currency === CONST.CURRENCY.USD;

// Only show the Approve button if the user cannot pay the request
if (shouldHidePaymentOptions && shouldShowApproveButton) {
return [approveButtonOption];
}
// // Only show the Approve button if the user cannot pay the request
// if (shouldHidePaymentOptions && shouldShowApproveButton) {
// return [approveButtonOption];
// }

// To achieve the one tap pay experience we need to choose the correct payment type as default,
// if user already paid for some request or expense, let's use the last payment method or use default.
Expand All @@ -189,7 +263,7 @@
buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.ELSEWHERE]);

if (shouldShowApproveButton) {
buttonOptions.push(approveButtonOption);

Check failure on line 266 in src/components/SettlementButton.js

View workflow job for this annotation

GitHub Actions / lint

'approveButtonOption' is not defined
}

// Put the preferred payment method to the front of the array so its shown as default
Expand All @@ -197,7 +271,7 @@
return _.sortBy(buttonOptions, (method) => (method.value === paymentMethod ? 0 : 1));
}
return buttonOptions;
}, [currency, formattedAmount, iouReport, nvp_lastPaymentMethod, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]);

Check warning on line 274 in src/components/SettlementButton.js

View workflow job for this annotation

GitHub Actions / lint

React Hook useMemo has an unnecessary dependency: 'shouldHidePaymentOptions'. Either exclude it or remove the dependency array

const selectPaymentType = (event, iouPaymentType, triggerKYCFlow) => {
if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) {
Expand Down Expand Up @@ -234,10 +308,11 @@
isLoading={isLoading}
onPress={(event, iouPaymentType) => selectPaymentType(event, iouPaymentType, triggerKYCFlow)}
pressOnEnter={pressOnEnter}
options={paymentButtonOptions}
options={paymentButtonOptionsV2}
style={style}
buttonSize={buttonSize}
anchorAlignment={paymentMethodDropdownAnchorAlignment}
text={buttonText}
/>
)}
</KYCWall>
Expand All @@ -251,6 +326,9 @@
export default compose(
withNavigation,
withOnyx({
session: {
key: ONYXKEYS.SESSION,
},
nvp_lastPaymentMethod: {
key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD,
},
Expand Down
3 changes: 3 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ export default {
settledExpensify: 'Paid',
settledElsewhere: 'Paid elsewhere',
settleExpensify: ({formattedAmount}: SettleExpensifyCardParams) => (formattedAmount ? `Pay ${formattedAmount} with Expensify` : `Pay with Expensify`),
payWithBusinessBankAccount: 'Pay with business bank account',
payWithPersonalBankAccount: 'Pay with personal bank account',
payWithDebitCard: 'Pay with debit card',
payElsewhere: 'Pay elsewhere',
nextStep: 'Next Steps',
finished: 'Finished',
Expand Down
3 changes: 3 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,9 @@ export default {
settledExpensify: 'Pagado',
settledElsewhere: 'Pagado de otra forma',
settleExpensify: ({formattedAmount}: SettleExpensifyCardParams) => (formattedAmount ? `Pagar ${formattedAmount} con Expensify` : `Pagar con Expensify`),
payWithBusinessBankAccount: 'Pay with business bank account',
payWithPersonalBankAccount: 'Pay with personal bank account',
payWithDebitCard: 'Pay with debit card',
payElsewhere: 'Pagar de otra forma',
nextStep: 'Pasos Siguientes',
finished: 'Finalizado',
Expand Down
Loading