Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
31823cc
add strings
rezkiy37 Oct 11, 2024
3948c12
add invoice case for getBankAccountRoute
rezkiy37 Oct 11, 2024
a2d1b9a
add invoice payment menu items
rezkiy37 Oct 11, 2024
f4f708a
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Oct 14, 2024
905f8e5
add payment method button
rezkiy37 Oct 14, 2024
94647a4
pay invoice command accepts method id
rezkiy37 Oct 14, 2024
0080e82
integrate payment logic
rezkiy37 Oct 14, 2024
abed35d
pass account type
rezkiy37 Oct 15, 2024
e45613d
set add debit card route
rezkiy37 Oct 15, 2024
8b081a7
render all payment methods
rezkiy37 Oct 15, 2024
1302948
clear todo
rezkiy37 Oct 15, 2024
699a035
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Oct 16, 2024
2e05df0
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Oct 17, 2024
16f0136
Revert "set add debit card route"
rezkiy37 Oct 17, 2024
dbd3e10
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Oct 25, 2024
4a8928a
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Oct 28, 2024
5168b6f
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Nov 6, 2024
3e5d028
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Nov 14, 2024
ee24a29
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Nov 19, 2024
27edab4
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Nov 20, 2024
38d4636
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Nov 25, 2024
90712f2
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 4, 2024
05209e7
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 6, 2024
6f13e9d
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 9, 2024
529231e
use expensify payment type
rezkiy37 Dec 9, 2024
facf112
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 12, 2024
972bd42
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 16, 2024
006cd92
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 23, 2024
e263162
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Dec 28, 2024
64d1807
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jan 7, 2025
91fcece
fix rulesdir/no-default-id-values
rezkiy37 Jan 7, 2025
83ee038
Add logging for invalid policyID and threadReportID in route generation
rezkiy37 Jan 7, 2025
fae4377
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jan 8, 2025
439bc38
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jan 15, 2025
369b329
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jan 20, 2025
4b39e70
Refactor SettlementButton component to use named imports for better c…
rezkiy37 Jan 20, 2025
5a69e42
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Jan 28, 2025
916976c
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Feb 3, 2025
a27281e
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Feb 20, 2025
95cd4b4
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Feb 25, 2025
b6bf856
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 4, 2025
b7a4859
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 6, 2025
c4edf8b
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 7, 2025
5f094bc
Conditionally show payment methods based on currency support
rezkiy37 Mar 7, 2025
0ccfb97
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 10, 2025
ea3896d
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 10, 2025
b4b8fdc
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 11, 2025
a91a7a9
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 13, 2025
572b45d
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 14, 2025
be147e5
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 17, 2025
047c8f8
Refactor payInvoice function calls to simplify parameters in MoneyRep…
rezkiy37 Mar 17, 2025
f8629cd
Merge branch 'main' of https://github.com/rezkiy37/Expensify into fea…
rezkiy37 Mar 19, 2025
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
5 changes: 3 additions & 2 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ import DelegateNoAccessModal from './DelegateNoAccessModal';
import HeaderWithBackButton from './HeaderWithBackButton';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import type {PaymentMethod} from './KYCWall/types';
import LoadingBar from './LoadingBar';
import MoneyReportHeaderStatusBar from './MoneyReportHeaderStatusBar';
import type {MoneyRequestHeaderStatusBarProps} from './MoneyRequestHeaderStatusBar';
Expand Down Expand Up @@ -241,7 +242,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
const shouldDisplaySearchRouter = !isReportInRHP || isSmallScreenWidth;

const confirmPayment = useCallback(
(type?: PaymentMethodType | undefined, payAsBusiness?: boolean) => {
(type?: PaymentMethodType | undefined, payAsBusiness?: boolean, methodID?: number, paymentMethod?: PaymentMethod) => {
if (!type || !chatReport) {
return;
}
Expand All @@ -253,7 +254,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
setIsHoldMenuVisible(true);
} else if (isInvoiceReport(moneyRequestReport)) {
startAnimation();
payInvoice(type, chatReport, moneyRequestReport, payAsBusiness);
payInvoice(type, chatReport, moneyRequestReport, payAsBusiness, methodID, paymentMethod);
} else {
startAnimation();
payMoneyRequest(type, chatReport, moneyRequestReport, true);
Expand Down
5 changes: 3 additions & 2 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {getButtonRole} from '@components/Button/utils';
import DelegateNoAccessModal from '@components/DelegateNoAccessModal';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import type {PaymentMethod} from '@components/KYCWall/types';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
import type {ActionHandledType} from '@components/ProcessMoneyReportHoldMenu';
Expand Down Expand Up @@ -262,7 +263,7 @@ function ReportPreview({
const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false);

const confirmPayment = useCallback(
(type: PaymentMethodType | undefined, payAsBusiness?: boolean) => {
(type: PaymentMethodType | undefined, payAsBusiness?: boolean, methodID?: number, paymentMethod?: PaymentMethod) => {
if (!type) {
return;
}
Expand All @@ -275,7 +276,7 @@ function ReportPreview({
} else if (chatReport && iouReport) {
startAnimation();
if (isInvoiceReportUtils(iouReport)) {
payInvoice(type, chatReport, iouReport, payAsBusiness);
payInvoice(type, chatReport, iouReport, payAsBusiness, methodID, paymentMethod);
} else {
payMoneyRequest(type, chatReport, iouReport);
}
Expand Down
39 changes: 39 additions & 0 deletions src/components/SettlementButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import * as Expensicons from '@components/Icon/Expensicons';
import KYCWall from '@components/KYCWall';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import {isCurrencySupportedForDirectReimbursement} from '@libs/actions/Policy/Policy';
import Navigation from '@libs/Navigation/Navigation';
import {formatPaymentMethods} from '@libs/PaymentUtils';
import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils';
import {
doesReportBelongToWorkspace,
Expand Down Expand Up @@ -67,6 +70,7 @@ function SettlementButton({
onlyShowPayElsewhere,
wrapperStyle,
}: SettlementButtonProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
// The app would crash due to subscribing to the entire report collection if chatReportID is an empty string. So we should have a fallback ID here.
Expand All @@ -86,6 +90,9 @@ function SettlementButton({

const isLoadingLastPaymentMethod = isLoadingOnyxValue(lastPaymentMethodResult);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
const [bankAccountList = {}] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [fundList = {}] = useOnyx(ONYXKEYS.FUND_LIST);

const isInvoiceReport = (!isEmptyObject(iouReport) && isInvoiceReportUtil(iouReport)) || false;
const shouldShowPaywithExpensifyOption = !shouldHidePaymentOptions;
const shouldShowPayElsewhereOption = !shouldHidePaymentOptions && !isInvoiceReport;
Expand Down Expand Up @@ -138,13 +145,34 @@ function SettlementButton({
}

if (isInvoiceReport) {
const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList, styles);
const isCurrencySupported = isCurrencySupportedForDirectReimbursement(currency);
const getPaymentSubitems = (payAsBusiness: boolean) =>
formattedPaymentMethods.map((formattedPaymentMethod) => ({
text: formattedPaymentMethod?.title ?? '',
description: formattedPaymentMethod?.description ?? '',
icon: formattedPaymentMethod?.icon,
onSelected: () => onPress(CONST.IOU.PAYMENT_TYPE.EXPENSIFY, payAsBusiness, formattedPaymentMethod.methodID, formattedPaymentMethod.accountType),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We also need to pass iconStyles, iconHeight, and iconWidth here, otherwise the bank icons are too small. More details: #60579 (comment)

}));

if (isIndividualInvoiceRoomUtil(chatReport)) {
buttonOptions.push({
text: translate('iou.settlePersonal', {formattedAmount}),
icon: Expensicons.User,
value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE,
backButtonText: translate('iou.individual'),
subMenuItems: [
...(isCurrencySupported ? getPaymentSubitems(false) : []),
{
text: translate('workspace.invoices.paymentMethods.addBankAccount'),
icon: Expensicons.Bank,
onSelected: () => Navigation.navigate(addBankAccountRoute),
},
{
text: translate('workspace.invoices.paymentMethods.addDebitOrCreditCard'),
icon: Expensicons.CreditCard,
onSelected: () => Navigation.navigate(addDebitCardRoute),
},
{
text: translate('iou.payElsewhere', {formattedAmount: ''}),
icon: Expensicons.Cash,
Expand All @@ -161,6 +189,17 @@ function SettlementButton({
value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE,
backButtonText: translate('iou.business'),
subMenuItems: [
...(isCurrencySupported ? getPaymentSubitems(true) : []),
{
text: translate('workspace.invoices.paymentMethods.addBankAccount'),
icon: Expensicons.Bank,
onSelected: () => Navigation.navigate(addBankAccountRoute),
},
{
text: translate('workspace.invoices.paymentMethods.addCorporateCard'),
icon: Expensicons.CreditCard,
onSelected: () => Navigation.navigate(addDebitCardRoute),
},
{
text: translate('iou.payElsewhere', {formattedAmount: ''}),
icon: Expensicons.Cash,
Expand Down
3 changes: 2 additions & 1 deletion src/components/SettlementButton/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {StyleProp, ViewStyle} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {PaymentMethod} from '@components/KYCWall/types';
import type ROUTES from '@src/ROUTES';
import type {Route} from '@src/ROUTES';
import type {ButtonSizeValue} from '@src/styles/utils/types';
Expand All @@ -11,7 +12,7 @@ type EnablePaymentsRoute = typeof ROUTES.ENABLE_PAYMENTS | typeof ROUTES.IOU_SEN

type SettlementButtonProps = {
/** Callback to execute when this button is pressed. Receives a single payment type argument. */
onPress: (paymentType?: PaymentMethodType, payAsBusiness?: boolean) => void;
onPress: (paymentType?: PaymentMethodType, payAsBusiness?: boolean, methodID?: number, paymentMethod?: PaymentMethod) => void;

/** Callback when the payment options popover is shown */
onPaymentOptionsShow?: () => void;
Expand Down
2 changes: 2 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4418,6 +4418,8 @@ const translations = {
business: 'Business',
chooseInvoiceMethod: 'Choose a payment method below:',
addBankAccount: 'Add bank account',
addDebitOrCreditCard: 'Add debit or credit card',
addCorporateCard: 'Add corporate card',
payingAsIndividual: 'Paying as an individual',
payingAsBusiness: 'Paying as a business',
},
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4464,6 +4464,8 @@ const translations = {
business: 'Empresas',
chooseInvoiceMethod: 'Elija un método de pago:',
addBankAccount: 'Añadir cuenta bancaria',
addDebitOrCreditCard: 'Agrega una tarjeta de débito o crédito',
addCorporateCard: 'Agrega una tarjeta corporativa',
payingAsIndividual: 'Pago individual',
payingAsBusiness: 'Pagar como una empresa',
},
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/parameters/PayInvoiceParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ type PayInvoiceParams = Partial<CreateWorkspaceParams> & {
reportActionID: string;
paymentMethodType: PaymentMethodType;
payAsBusiness: boolean;
bankAccountID?: number;
fundID?: number;
};

export default PayInvoiceParams;
10 changes: 9 additions & 1 deletion src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,15 @@ function isPublicAnnounceRoom(report: OnyxEntry<Report>): boolean {
* else since the report is a personal IOU, the route should be for personal bank account.
*/
function getBankAccountRoute(report: OnyxEntry<Report>): Route {
return isPolicyExpenseChat(report) ? ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(report?.policyID) : ROUTES.SETTINGS_ADD_BANK_ACCOUNT;
if (isPolicyExpenseChat(report)) {
return ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(report?.policyID);
}

if (isInvoiceRoom(report) && report?.invoiceReceiver?.type === CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS) {
return ROUTES.WORKSPACE_INVOICES.getRoute(report?.invoiceReceiver?.policyID);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👋 Coming from #64585, this has caused an issue when the wrong page opens when clicking "Add bank account" under some circumstances
More details in #64585 (comment)

}

return ROUTES.SETTINGS_ADD_BANK_ACCOUNT;
}

/**
Expand Down
18 changes: 17 additions & 1 deletion src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate}
import Onyx from 'react-native-onyx';
import type {PartialDeep, SetRequired, ValueOf} from 'type-fest';
import ReceiptGeneric from '@assets/images/receipt-generic.png';
import type {PaymentMethod} from '@components/KYCWall/types';
import * as API from '@libs/API';
import type {
ApproveMoneyRequestParams,
Expand Down Expand Up @@ -9089,7 +9090,14 @@ function payMoneyRequest(paymentType: PaymentMethodType, chatReport: OnyxTypes.R
notifyNewAction(Navigation.getTopmostReportId() ?? iouReport?.reportID, userAccountID);
}

function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes.Report, invoiceReport: OnyxEntry<OnyxTypes.Report>, payAsBusiness = false) {
function payInvoice(
paymentMethodType: PaymentMethodType,
chatReport: OnyxTypes.Report,
invoiceReport: OnyxEntry<OnyxTypes.Report>,
payAsBusiness = false,
methodID?: number,
paymentMethod?: PaymentMethod,
) {
const recipient = {accountID: invoiceReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID};
const {
optimisticData,
Expand Down Expand Up @@ -9119,6 +9127,14 @@ function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes.
payAsBusiness,
};

if (paymentMethod === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) {
params.bankAccountID = methodID;
}

if (paymentMethod === CONST.PAYMENT_METHODS.DEBIT_CARD) {
params.fundID = methodID;
}

if (policyID) {
params = {
...params,
Expand Down