Skip to content

Commit a9c3c31

Browse files
authored
Merge pull request #90202 from nabi-ebrahimi/fix-reimbursement-regression
Allow submitters to select "Received reimbursement" option v2
2 parents c5d98a4 + 9ef5a3d commit a9c3c31

21 files changed

Lines changed: 630 additions & 10 deletions

src/CONST/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,7 @@ const CONST = {
13671367
SECONDARY_ACTIONS: {
13681368
SUBMIT: 'submit',
13691369
APPROVE: 'approve',
1370+
RECEIVED_PAYMENT: 'receivedPayment',
13701371
REMOVE_HOLD: 'removeHold',
13711372
UNAPPROVE: 'unapprove',
13721373
CANCEL_PAYMENT: 'cancelPayment',
@@ -8576,6 +8577,7 @@ const CONST = {
85768577
CLOSE_PDF_MODAL: 'MoreMenu-ClosePDFModal',
85778578
SUBMIT: 'MoreMenu-Submit',
85788579
APPROVE: 'MoreMenu-Approve',
8580+
RECEIVED_PAYMENT: 'MoreMenu-ReceivedPayment',
85798581
UNAPPROVE: 'MoreMenu-Unapprove',
85808582
CANCEL_PAYMENT: 'MoreMenu-CancelPayment',
85818583
HOLD: 'MoreMenu-Hold',

src/components/MoneyReportHeaderActions/MoneyReportHeaderSecondaryActions.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,10 @@ function MoneyReportHeaderSecondaryActionsInner({reportID, primaryAction, isRepo
276276
const lifecycleActions = useLifecycleActions({
277277
reportID,
278278
startApprovedAnimation,
279+
startAnimation,
279280
startSubmittingAnimation,
280-
onHoldMenuOpen: (requestType, onConfirm) => {
281-
openHoldMenu({requestType, onConfirm: onConfirm ?? (() => startApprovedAnimation())});
281+
onHoldMenuOpen: (requestType, onConfirm, paymentType) => {
282+
openHoldMenu({requestType, onConfirm: onConfirm ?? (() => startApprovedAnimation()), paymentType});
282283
},
283284
});
284285

src/components/MoneyReportHeaderActions/MoneyReportHeaderSelectionDropdown.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,17 @@ function MoneyReportHeaderSelectionDropdown({reportID, primaryAction, isReportIn
157157
const {confirmApproval, handleSubmitReport, shouldBlockSubmit, isBlockSubmitDueToPreventSelfApproval} = useLifecycleActions({
158158
reportID,
159159
startApprovedAnimation,
160+
startAnimation,
160161
startSubmittingAnimation,
161-
onHoldMenuOpen: (requestType) => openHoldMenu({requestType, onConfirm: () => clearSelectedTransactions(true)}),
162+
onHoldMenuOpen: (requestType, onConfirm, paymentType) =>
163+
openHoldMenu({
164+
requestType,
165+
onConfirm: () => {
166+
onConfirm?.();
167+
clearSelectedTransactions(true);
168+
},
169+
paymentType,
170+
}),
162171
});
163172

164173
const {

src/hooks/useLifecycleActions.tsx

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ import {
2020
shouldBlockSubmitDueToStrictPolicyRules,
2121
} from '@libs/ReportUtils';
2222
import {hasAnyPendingRTERViolation as hasAnyPendingRTERViolationTransactionUtils, hasOnlyPendingCardTransactions, showPendingCardTransactionsBlockModal} from '@libs/TransactionUtils';
23-
import {cancelPayment} from '@userActions/IOU/PayMoneyRequest';
23+
import {cancelPayment, markReportPaymentReceived} from '@userActions/IOU/PayMoneyRequest';
2424
import {approveMoneyRequest, reopenReport, retractReport, submitReport, unapproveExpenseReport} from '@userActions/IOU/ReportWorkflow';
2525
import {markPendingRTERTransactionsAsCash} from '@userActions/Transaction';
2626
import CONST from '@src/CONST';
2727
import ONYXKEYS from '@src/ONYXKEYS';
28+
import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage';
2829
import useConfirmModal from './useConfirmModal';
2930
import useConfirmPendingRTERAndProceed from './useConfirmPendingRTERAndProceed';
3031
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
@@ -42,8 +43,9 @@ import useTransactionsAndViolationsForReport from './useTransactionsAndViolation
4243
type UseLifecycleActionsParams = {
4344
reportID: string | undefined;
4445
startApprovedAnimation: () => void;
46+
startAnimation: () => void;
4547
startSubmittingAnimation: () => void;
46-
onHoldMenuOpen: (requestType: ActionHandledType, onConfirm?: () => void) => void;
48+
onHoldMenuOpen: (requestType: ActionHandledType, onConfirm?: () => void, paymentType?: PaymentMethodType) => void;
4749
};
4850

4951
type UseLifecycleActionsResult = {
@@ -58,7 +60,7 @@ type UseLifecycleActionsResult = {
5860
* Provides report lifecycle transition actions (submit, approve, unapprove, cancel payment, retract, reopen)
5961
* and their associated guards (delegate access, hold, pending RTER, strict policy rules).
6062
*/
61-
function useLifecycleActions({reportID, startApprovedAnimation, startSubmittingAnimation, onHoldMenuOpen}: UseLifecycleActionsParams): UseLifecycleActionsResult {
63+
function useLifecycleActions({reportID, startApprovedAnimation, startAnimation, startSubmittingAnimation, onHoldMenuOpen}: UseLifecycleActionsParams): UseLifecycleActionsResult {
6264
const [moneyRequestReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
6365
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(moneyRequestReport?.policyID)}`);
6466
const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(moneyRequestReport?.chatReportID)}`);
@@ -95,7 +97,7 @@ function useLifecycleActions({reportID, startApprovedAnimation, startSubmittingA
9597
const {clearSelectedTransactions} = useSearchActionsContext();
9698
const shouldCalculateTotals = useSearchShouldCalculateTotals(currentSearchKey, currentSearchQueryJSON?.hash, true);
9799

98-
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Send', 'ThumbsUp', 'CircularArrowBackwards', 'Clear']);
100+
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Send', 'ThumbsUp', 'CircularArrowBackwards', 'Clear', 'MoneyBag']);
99101

100102
const nextApproverAccountID = getNextApproverAccountID(moneyRequestReport);
101103
const isSubmitterSameAsNextApprover =
@@ -262,6 +264,44 @@ function useLifecycleActions({reportID, startApprovedAnimation, startSubmittingA
262264
sentryLabel: CONST.SENTRY_LABEL.MORE_MENU.APPROVE,
263265
onSelected: confirmApproval,
264266
},
267+
[CONST.REPORT.SECONDARY_ACTIONS.RECEIVED_PAYMENT]: {
268+
value: CONST.REPORT.SECONDARY_ACTIONS.RECEIVED_PAYMENT,
269+
text: translate('iou.receivedPayment'),
270+
icon: expensifyIcons.MoneyBag,
271+
sentryLabel: CONST.SENTRY_LABEL.MORE_MENU.RECEIVED_PAYMENT,
272+
onSelected: async () => {
273+
if (isDelegateAccessRestricted) {
274+
showDelegateNoAccessModal();
275+
return;
276+
}
277+
278+
const result = await showConfirmModal({
279+
title: translate('iou.confirmPaymentReceivedModalTitle'),
280+
prompt: translate('iou.receivedPaymentConfirmation'),
281+
confirmText: translate('iou.confirmReceivedPayment'),
282+
cancelText: translate('common.cancel'),
283+
});
284+
285+
if (result.action !== ModalActions.CONFIRM) {
286+
return;
287+
}
288+
289+
if (isAnyTransactionOnHold) {
290+
onHoldMenuOpen(
291+
CONST.IOU.REPORT_ACTION_TYPE.PAY,
292+
() => {
293+
startAnimation();
294+
markReportPaymentReceived(chatReport, moneyRequestReport, nextStep, accountID, email ?? '');
295+
},
296+
CONST.IOU.PAYMENT_TYPE.ELSEWHERE,
297+
);
298+
return;
299+
}
300+
301+
startAnimation();
302+
markReportPaymentReceived(chatReport, moneyRequestReport, nextStep, accountID, email ?? '');
303+
},
304+
},
265305
[CONST.REPORT.SECONDARY_ACTIONS.UNAPPROVE]: {
266306
value: CONST.REPORT.SECONDARY_ACTIONS.UNAPPROVE,
267307
text: translate('iou.unapprove'),

src/languages/de.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,10 @@ const translations: TranslationDeepObject<typeof en> = {
13211321
settlePayment: (formattedAmount: string) => `${formattedAmount} bezahlen`,
13221322
settleBusiness: (formattedAmount?: string) => (formattedAmount ? `${formattedAmount} als Unternehmen bezahlen` : `Mit Geschäftskonto bezahlen`),
13231323
payElsewhere: (formattedAmount?: string) => (formattedAmount ? `${formattedAmount} als bezahlt markieren` : `Als bezahlt markieren`),
1324+
confirmPaymentReceivedModalTitle: 'Zahlungseingang bestätigen',
1325+
receivedPayment: 'Zahlung erhalten',
1326+
receivedPaymentConfirmation: 'Bitte fahren Sie nur fort, wenn Sie die Zahlung bereits außerhalb von Expensify erhalten haben.',
1327+
confirmReceivedPayment: 'Ja, ich habe die Zahlung erhalten.',
13241328
settleInvoicePersonal: (amount?: string, last4Digits?: string) => (amount ? `${amount} mit persönlichem Konto ${last4Digits} bezahlt` : `Mit Privatkonto bezahlt`),
13251329
settleInvoiceBusiness: (amount?: string, last4Digits?: string) => (amount ? `${amount} mit Geschäftskonto ${last4Digits} bezahlt` : `Mit Geschäftskonto bezahlt`),
13261330
payWithPolicy: (policyName: string, formattedAmount?: string) => (formattedAmount ? `Bezahle ${formattedAmount} über ${policyName}` : `Bezahlen über ${policyName}`),

src/languages/en.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,10 @@ const translations = {
13751375
settlePayment: (formattedAmount: string) => `Pay ${formattedAmount}`,
13761376
settleBusiness: (formattedAmount?: string) => (formattedAmount ? `Pay ${formattedAmount} as a business` : `Pay with business account`),
13771377
payElsewhere: (formattedAmount?: string) => (formattedAmount ? `Mark ${formattedAmount} as paid` : `Mark as paid`),
1378+
confirmPaymentReceivedModalTitle: 'Confirm payment received',
1379+
receivedPayment: 'Received payment',
1380+
receivedPaymentConfirmation: "Please proceed only if you've already received payment outside of Expensify.",
1381+
confirmReceivedPayment: "Yes, I've received payment",
13781382
settleInvoicePersonal: (amount?: string, last4Digits?: string) => (amount ? `paid ${amount} with personal account ${last4Digits}` : `Paid with personal account`),
13791383
settleInvoiceBusiness: (amount?: string, last4Digits?: string) => (amount ? `paid ${amount} with business account ${last4Digits}` : `Paid with business account`),
13801384
payWithPolicy: (policyName: string, formattedAmount?: string) => (formattedAmount ? `Pay ${formattedAmount} via ${policyName}` : `Pay via ${policyName}`),

src/languages/es.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,10 @@ const translations: TranslationDeepObject<typeof en> = {
12811281
settlePayment: (formattedAmount) => `Pagar ${formattedAmount}`,
12821282
settleBusiness: (formattedAmount) => (formattedAmount ? `Pagar ${formattedAmount} como negocio` : `Pago con cuenta empresarial`),
12831283
payElsewhere: (formattedAmount) => (formattedAmount ? `Marcar ${formattedAmount} como pagado` : `Marcar como pagado`),
1284+
confirmPaymentReceivedModalTitle: 'Confirmar el pago recibido',
1285+
receivedPayment: 'Pago recibido',
1286+
receivedPaymentConfirmation: 'Por favor, continúa solo si ya has recibido el pago fuera de Expensify.',
1287+
confirmReceivedPayment: 'Sí, he recibido el pago.',
12841288
settleInvoicePersonal: (amount, last4Digits) => (amount ? `pagado ${amount} con cuenta personal ${last4Digits}` : `Pagado con cuenta personal`),
12851289
settleInvoiceBusiness: (amount, last4Digits) => (amount ? `pagado ${amount} con cuenta de empresa ${last4Digits}` : `Pagado con cuenta de empresa`),
12861290
payWithPolicy: (policyName, formattedAmount) => (formattedAmount ? `Pay ${formattedAmount} via ${policyName}` : `Pay via ${policyName}`),

src/languages/fr.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,10 @@ const translations: TranslationDeepObject<typeof en> = {
13261326
settlePayment: (formattedAmount: string) => `Payer ${formattedAmount}`,
13271327
settleBusiness: (formattedAmount?: string) => (formattedAmount ? `Payer ${formattedAmount} en tant qu’entreprise` : `Payer avec le compte professionnel`),
13281328
payElsewhere: (formattedAmount?: string) => (formattedAmount ? `Marquer ${formattedAmount} comme payé` : `Marquer comme payé`),
1329+
confirmPaymentReceivedModalTitle: 'Confirmer la réception du paiement',
1330+
receivedPayment: 'Paiement reçu',
1331+
receivedPaymentConfirmation: 'Veuillez continuer uniquement si vous avez déjà reçu le paiement en dehors d’Expensify.',
1332+
confirmReceivedPayment: 'Oui, j’ai reçu le paiement.',
13291333
settleInvoicePersonal: (amount?: string, last4Digits?: string) => (amount ? `a payé ${amount} avec le compte personnel ${last4Digits}` : `Payé avec un compte personnel`),
13301334
settleInvoiceBusiness: (amount?: string, last4Digits?: string) => (amount ? `a payé ${amount} avec le compte professionnel ${last4Digits}` : `Payé avec le compte professionnel`),
13311335
payWithPolicy: (policyName: string, formattedAmount?: string) => (formattedAmount ? `Payer ${formattedAmount} via ${policyName}` : `Payer via ${policyName}`),

src/languages/it.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,10 @@ const translations: TranslationDeepObject<typeof en> = {
13211321
settlePayment: (formattedAmount: string) => `Paga ${formattedAmount}`,
13221322
settleBusiness: (formattedAmount?: string) => (formattedAmount ? `Paga ${formattedAmount} come azienda` : `Paga con conto aziendale`),
13231323
payElsewhere: (formattedAmount?: string) => (formattedAmount ? `Segna ${formattedAmount} come pagato` : `Segna come pagata`),
1324+
confirmPaymentReceivedModalTitle: 'Conferma la ricezione del pagamento',
1325+
receivedPayment: 'Pagamento ricevuto',
1326+
receivedPaymentConfirmation: 'Procedi solo se hai già ricevuto il pagamento al di fuori di Expensify.',
1327+
confirmReceivedPayment: 'Sì, ho ricevuto il pagamento.',
13241328
settleInvoicePersonal: (amount?: string, last4Digits?: string) => (amount ? `pagato ${amount} con conto personale ${last4Digits}` : `Pagato con conto personale`),
13251329
settleInvoiceBusiness: (amount?: string, last4Digits?: string) => (amount ? `ha pagato ${amount} con il conto aziendale ${last4Digits}` : `Pagato con conto aziendale`),
13261330
payWithPolicy: (policyName: string, formattedAmount?: string) => (formattedAmount ? `Paga ${formattedAmount} tramite ${policyName}` : `Paga tramite ${policyName}`),

src/languages/ja.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,10 @@ const translations: TranslationDeepObject<typeof en> = {
13041304
settlePayment: (formattedAmount: string) => `${formattedAmount} を支払う`,
13051305
settleBusiness: (formattedAmount?: string) => (formattedAmount ? `${formattedAmount} をビジネスとして支払う` : `ビジネスアカウントで支払う`),
13061306
payElsewhere: (formattedAmount?: string) => (formattedAmount ? `${formattedAmount} を支払済みにする` : `支払い済みにする`),
1307+
confirmPaymentReceivedModalTitle: '支払いを受領したことを確認',
1308+
receivedPayment: '支払い受領済み',
1309+
receivedPaymentConfirmation: 'Expensify以外で支払いを受け取っている場合のみ続行してください。',
1310+
confirmReceivedPayment: 'はい、支払いを受け取りました。',
13071311
settleInvoicePersonal: (amount?: string, last4Digits?: string) => (amount ? `個人アカウント(下4桁 ${last4Digits})で ${amount} を支払いました` : `個人アカウントで支払い済み`),
13081312
settleInvoiceBusiness: (amount?: string, last4Digits?: string) => (amount ? `ビジネス口座(末尾${last4Digits})で${amount}を支払いました` : `ビジネスアカウントで支払済み`),
13091313
payWithPolicy: (policyName: string, formattedAmount?: string) => (formattedAmount ? `${policyName}で${formattedAmount}を支払う` : `${policyName}で支払う`),

0 commit comments

Comments
 (0)