Skip to content

Commit 858b386

Browse files
authored
Merge pull request Expensify#81403 from callstack-internal/fix/81349-bulk-mark-as-pay
fix: 81349 Mark as paid via bulk
2 parents c967632 + da6ca74 commit 858b386

4 files changed

Lines changed: 40 additions & 25 deletions

File tree

src/components/SettlementButton/index.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -562,14 +562,11 @@ function SettlementButton({
562562
return;
563563
}
564564

565-
const {paymentType, selectedPolicy, shouldSelectPaymentMethod} = getActivePaymentType(selectedOption, activeAdminPolicies, latestBankItem, policyIDKey);
566-
567-
// Payment type for 'Pay via workspace' option is "Elsewhere" but selected option points to one of workspaces where user is admin
568-
const isPayingViaWorkspace = paymentType === CONST.IOU.PAYMENT_TYPE.ELSEWHERE && activeAdminPolicies.find((activeAdminPolicy) => activeAdminPolicy.id === selectedOption);
565+
const {paymentType, policyFromPaymentMethod, policyFromContext, shouldSelectPaymentMethod} = getActivePaymentType(selectedOption, activeAdminPolicies, latestBankItem, policyIDKey);
569566
const isPayingWithMethod = paymentType !== CONST.IOU.PAYMENT_TYPE.ELSEWHERE;
570567

571-
if ((!!selectedPolicy || shouldSelectPaymentMethod) && (isPayingWithMethod || isPayingViaWorkspace)) {
572-
selectPaymentMethod(event, paymentType, triggerKYCFlow, selectedOption as PaymentMethod, selectedPolicy);
568+
if ((!!policyFromPaymentMethod || shouldSelectPaymentMethod) && (isPayingWithMethod || !!policyFromPaymentMethod)) {
569+
selectPaymentMethod(event, paymentType, triggerKYCFlow, selectedOption as PaymentMethod, policyFromPaymentMethod ?? policyFromContext);
573570
return;
574571
}
575572

src/libs/PaymentUtils.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,11 @@ const isSecondaryActionAPaymentOption = (item: PopoverMenuItem): item is Payment
220220
};
221221

222222
/**
223-
* Get the appropriate payment type, selected policy, and whether a payment method should be selected
223+
* Get the appropriate payment type, policy from context (policy related to payment type), policy from payment method, and whether a payment method should be selected
224224
* based on the provided payment method, active admin policies, and latest bank items.
225225
*/
226226
function getActivePaymentType(paymentMethod: string | undefined, activeAdminPolicies: Policy[], latestBankItems: BankAccountMenuItem[] | undefined, policyID?: string | undefined) {
227227
const isPaymentMethod = Object.values(CONST.PAYMENT_METHODS).includes(paymentMethod as ValueOf<typeof CONST.PAYMENT_METHODS>);
228-
// payment method is equal to policyID when user selects "Pay via workspace" option
229-
const selectedPolicy = activeAdminPolicies.find((activePolicy) => activePolicy.id === policyID || activePolicy.id === paymentMethod);
230228

231229
let paymentType;
232230
switch (paymentMethod) {
@@ -241,12 +239,19 @@ function getActivePaymentType(paymentMethod: string | undefined, activeAdminPoli
241239
break;
242240
}
243241

242+
// Policy related to the context ie: Policy related to opened chat
243+
const policyFromContext = activeAdminPolicies.find((activePolicy) => activePolicy.id === policyID);
244+
245+
// Policy that is part of payment method ie: Policy when user presses on 'Pay via workspace' option
246+
const policyFromPaymentMethod = activeAdminPolicies.find((activePolicy) => activePolicy.id === paymentMethod);
247+
244248
// When user explicitly selects "Pay Elsewhere" / "Mark as Paid", don't require payment method selection since payment happens outside of Expensify
245249
const shouldSelectPaymentMethod = paymentMethod !== CONST.IOU.PAYMENT_TYPE.ELSEWHERE && (isPaymentMethod || !isEmpty(latestBankItems));
246250

247251
return {
248252
paymentType,
249-
selectedPolicy,
253+
policyFromContext,
254+
policyFromPaymentMethod,
250255
shouldSelectPaymentMethod,
251256
};
252257
}

src/libs/actions/Search.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,10 +1245,9 @@ function handleBulkPayItemSelected(params: {
12451245
showDelegateNoAccessModal,
12461246
confirmPayment,
12471247
} = params;
1248-
const {paymentType, selectedPolicy, shouldSelectPaymentMethod} = getActivePaymentType(item.key, activeAdminPolicies, latestBankItems, policy?.id);
1249-
const isPolicyBasedPaymentOption = activeAdminPolicies.some((activePolicy) => activePolicy.id === item.key);
1248+
const {paymentType, policyFromPaymentMethod, policyFromContext, shouldSelectPaymentMethod} = getActivePaymentType(item.key, activeAdminPolicies, latestBankItems, policy?.id);
12501249
// Early return if item is not a valid payment method and not a policy-based payment option
1251-
if (!isValidBulkPayOption(item) && !isPolicyBasedPaymentOption) {
1250+
if (!isValidBulkPayOption(item) && !policyFromPaymentMethod) {
12521251
return;
12531252
}
12541253

@@ -1272,12 +1271,12 @@ function handleBulkPayItemSelected(params: {
12721271
return;
12731272
}
12741273

1275-
if ((!!selectedPolicy || shouldSelectPaymentMethod) && item.key !== CONST.IOU.PAYMENT_TYPE.ELSEWHERE) {
1274+
if ((!!policyFromPaymentMethod || shouldSelectPaymentMethod) && item.key !== CONST.IOU.PAYMENT_TYPE.ELSEWHERE) {
12761275
triggerKYCFlow({
12771276
event: undefined,
12781277
iouPaymentType: paymentType,
12791278
paymentMethod: item.key as PaymentMethod,
1280-
policy: selectedPolicy,
1279+
policy: policyFromPaymentMethod ?? policyFromContext,
12811280
});
12821281

12831282
if (paymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || paymentType === CONST.IOU.PAYMENT_TYPE.VBBA) {

tests/unit/PaymentUtilsTest.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,31 +76,35 @@ describe('PaymentUtils', () => {
7676

7777
expect(result.paymentType).toBe(CONST.IOU.PAYMENT_TYPE.EXPENSIFY);
7878
expect(result.shouldSelectPaymentMethod).toBe(true);
79-
expect(result.selectedPolicy).toBeUndefined();
79+
expect(result.policyFromContext).toBeUndefined();
80+
expect(result.policyFromPaymentMethod).toBeUndefined();
8081
});
8182

8283
it('should return VBBA payment type when paymentMethod is BUSINESS_BANK_ACCOUNT', () => {
8384
const result = getActivePaymentType(CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT, [], undefined);
8485

8586
expect(result.paymentType).toBe(CONST.IOU.PAYMENT_TYPE.VBBA);
8687
expect(result.shouldSelectPaymentMethod).toBe(true);
87-
expect(result.selectedPolicy).toBeUndefined();
88+
expect(result.policyFromContext).toBeUndefined();
89+
expect(result.policyFromPaymentMethod).toBeUndefined();
8890
});
8991

9092
it('should return ELSEWHERE payment type when paymentMethod is DEBIT_CARD', () => {
9193
const result = getActivePaymentType(CONST.PAYMENT_METHODS.DEBIT_CARD, [], undefined);
9294

9395
expect(result.paymentType).toBe(CONST.IOU.PAYMENT_TYPE.ELSEWHERE);
9496
expect(result.shouldSelectPaymentMethod).toBe(true);
95-
expect(result.selectedPolicy).toBeUndefined();
97+
expect(result.policyFromContext).toBeUndefined();
98+
expect(result.policyFromPaymentMethod).toBeUndefined();
9699
});
97100

98101
it('should return ELSEWHERE payment type when paymentMethod is undefined', () => {
99102
const result = getActivePaymentType(undefined, [], undefined);
100103

101104
expect(result.paymentType).toBe(CONST.IOU.PAYMENT_TYPE.ELSEWHERE);
102105
expect(result.shouldSelectPaymentMethod).toBe(false);
103-
expect(result.selectedPolicy).toBeUndefined();
106+
expect(result.policyFromContext).toBeUndefined();
107+
expect(result.policyFromPaymentMethod).toBeUndefined();
104108
});
105109

106110
it('should set shouldSelectPaymentMethod to true when latestBankItems is not empty', () => {
@@ -117,24 +121,34 @@ describe('PaymentUtils', () => {
117121
expect(result.shouldSelectPaymentMethod).toBe(false);
118122
});
119123

120-
it('should find selectedPolicy by policyID', () => {
124+
it('should find policyFromContext by policyID', () => {
121125
const result = getActivePaymentType(undefined, [randomPolicyA, randomPolicyB], undefined, randomPolicyA.id);
122126

123-
expect(result.selectedPolicy).toEqual(randomPolicyA);
127+
expect(result.policyFromContext).toEqual(randomPolicyA);
128+
expect(result.policyFromPaymentMethod).toBeUndefined();
124129
});
125130

126-
it('should find selectedPolicy by paymentMethod when it matches policy id (Pay via workspace scenario)', () => {
131+
it('should find policyFromPaymentMethod when paymentMethod matches policy id (Pay via workspace scenario)', () => {
127132
const result = getActivePaymentType(randomPolicyB.id, [randomPolicyA, randomPolicyB], undefined);
128133

129-
expect(result.selectedPolicy).toEqual(randomPolicyB);
134+
expect(result.policyFromPaymentMethod).toEqual(randomPolicyB);
135+
expect(result.policyFromContext).toBeUndefined();
130136
expect(result.paymentType).toBe(CONST.IOU.PAYMENT_TYPE.ELSEWHERE);
131137
expect(result.shouldSelectPaymentMethod).toBe(false);
132138
});
133139

134-
it('should return undefined selectedPolicy when no matching policy is found', () => {
140+
it('should return both policyFromContext and policyFromPaymentMethod when both match', () => {
141+
const result = getActivePaymentType(randomPolicyB.id, [randomPolicyA, randomPolicyB], undefined, randomPolicyA.id);
142+
143+
expect(result.policyFromContext).toEqual(randomPolicyA);
144+
expect(result.policyFromPaymentMethod).toEqual(randomPolicyB);
145+
});
146+
147+
it('should return undefined policies when no matching policy is found', () => {
135148
const result = getActivePaymentType(undefined, [randomPolicyA], undefined, 'non-existent-policy');
136149

137-
expect(result.selectedPolicy).toBeUndefined();
150+
expect(result.policyFromContext).toBeUndefined();
151+
expect(result.policyFromPaymentMethod).toBeUndefined();
138152
});
139153
});
140154
});

0 commit comments

Comments
 (0)