Skip to content

Commit

Permalink
Merge pull request #36814 from c3024/34951-pay-conditions-based-on-re…
Browse files Browse the repository at this point in the history
…imbursement-settings

pay conditions based on reimbursement settings
  • Loading branch information
marcochavezf authored Mar 4, 2024
2 parents fa298a5 + e9306bd commit c4ceaed
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1383,9 +1383,9 @@ const CONST = {
OWNER_EMAIL_FAKE: '_FAKE_',
OWNER_ACCOUNT_ID_FAKE: 0,
REIMBURSEMENT_CHOICES: {
REIMBURSEMENT_YES: 'reimburseYes',
REIMBURSEMENT_NO: 'reimburseNo',
REIMBURSEMENT_MANUAL: 'reimburseManual',
REIMBURSEMENT_YES: 'reimburseYes', // Direct
REIMBURSEMENT_NO: 'reimburseNo', // None
REIMBURSEMENT_MANUAL: 'reimburseManual', // Indirect
},
ID_FAKE: '_FAKE_',
EMPTY: 'EMPTY',
Expand Down
6 changes: 1 addition & 5 deletions src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,10 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money
const isSettled = ReportUtils.isSettled(moneyRequestReport.reportID);
const canAllowSettlement = ReportUtils.hasUpdatedTotal(moneyRequestReport);
const policyType = policy?.type;
const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN;
const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(moneyRequestReport, policy);
const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicy(moneyRequestReport);
const isManager = ReportUtils.isMoneyRequestReport(moneyRequestReport) && session?.accountID === moneyRequestReport.managerID;
const isPayer = isPaidGroupPolicy
? // In a group policy, the admin approver can pay the report directly by skipping the approval step
isPolicyAdmin && (isApproved || isManager)
: isPolicyAdmin || (ReportUtils.isMoneyRequestReport(moneyRequestReport) && isManager);
const isPayer = ReportUtils.isPayer(session, moneyRequestReport);
const isDraft = ReportUtils.isDraftExpenseReport(moneyRequestReport);
const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false);

Expand Down
8 changes: 1 addition & 7 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ function ReportPreview({
const managerID = iouReport?.managerID ?? 0;
const isCurrentUserManager = managerID === session?.accountID;
const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport);
const policyType = policy?.type;
const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(iouReport, policy);

const iouSettled = ReportUtils.isSettled(iouReportID);
Expand All @@ -132,7 +131,6 @@ function ReportPreview({

const isApproved = ReportUtils.isReportApproved(iouReport);
const canAllowSettlement = ReportUtils.hasUpdatedTotal(iouReport);
const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(iouReport);
const transactionsWithReceipts = ReportUtils.getTransactionsWithReceipts(iouReportID);
const numberOfScanningReceipts = transactionsWithReceipts.filter((transaction) => TransactionUtils.isReceiptBeingScanned(transaction)).length;
const numberOfPendingRequests = transactionsWithReceipts.filter((transaction) => TransactionUtils.isPending(transaction) && TransactionUtils.isCardTransaction(transaction)).length;
Expand Down Expand Up @@ -211,11 +209,7 @@ function ReportPreview({
const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport);

const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport);
const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN;
const isPayer = isPaidGroupPolicy
? // In a paid group policy, the admin approver can pay the report directly by skipping the approval step
isPolicyAdmin && (isApproved || isCurrentUserManager)
: isPolicyAdmin || (isMoneyRequestReport && isCurrentUserManager);
const isPayer = ReportUtils.isPayer(session, iouReport);
const isOnInstantSubmitPolicy = PolicyUtils.isInstantSubmitEnabled(policy);
const isOnSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy);
const shouldShowPayButton = useMemo(
Expand Down
11 changes: 9 additions & 2 deletions src/components/SettlementButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ButtonWithDropdownMenu from './ButtonWithDropdownMenu';
import type {PaymentType} from './ButtonWithDropdownMenu/types';
import * as Expensicons from './Icon/Expensicons';
import KYCWall from './KYCWall';
import {useSession} from './OnyxProvider';

type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined;

Expand Down Expand Up @@ -134,6 +135,13 @@ function SettlementButton({
PaymentMethods.openWalletPage();
}, []);

const policy = ReportUtils.getPolicy(policyID);
const session = useSession();
const chatReport = ReportUtils.getReport(chatReportID);
const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport as OnyxEntry<Report>);
const shouldShowPaywithExpensifyOption =
!isPaidGroupPolicy ||
(!shouldHidePaymentOptions && policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES && policy?.reimburserEmail === session?.email);
const paymentButtonOptions = useMemo(() => {
const buttonOptions = [];
const isExpenseReport = ReportUtils.isExpenseReport(iouReport);
Expand Down Expand Up @@ -173,7 +181,7 @@ function SettlementButton({
if (canUseWallet) {
buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.EXPENSIFY]);
}
if (isExpenseReport) {
if (isExpenseReport && shouldShowPaywithExpensifyOption) {
buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.VBBA]);
}
buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.ELSEWHERE]);
Expand All @@ -190,7 +198,6 @@ function SettlementButton({
// We don't want to reorder the options when the preferred payment method changes while the button is still visible
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currency, formattedAmount, iouReport, policyID, translate, shouldHidePaymentOptions, shouldShowApproveButton]);

const selectPaymentType = (event: KYCFlowEvent, iouPaymentType: PaymentMethodType, triggerKYCFlow: TriggerKYCFlow) => {
if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) {
triggerKYCFlow(event, iouPaymentType);
Expand Down
28 changes: 26 additions & 2 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,29 @@ function isOneOnOneChat(report: OnyxEntry<Report>): boolean {
);
}

/**
* Checks if the current user is a payer of the request
*/

function isPayer(session: OnyxEntry<Session>, iouReport: OnyxEntry<Report>) {
const isApproved = isReportApproved(iouReport);
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? null;
const policyType = policy?.type;
const isAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN;
const isManager = iouReport?.managerID === session?.accountID;
if (isPaidGroupPolicy(iouReport)) {
if (policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) {
const isReimburser = session?.email === policy?.reimburserEmail;
return isReimburser && (isApproved || isManager);
}
if (policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL) {
return isAdmin && (isApproved || isManager);
}
return false;
}
return isAdmin || (isMoneyRequestReport(iouReport) && isManager);
}

/**
* Get the notification preference given a report
*/
Expand Down Expand Up @@ -1611,9 +1634,9 @@ function getIcons(
name: personalDetails?.[report?.ownerAccountID ?? -1]?.displayName ?? '',
fallbackIcon: personalDetails?.[report?.ownerAccountID ?? -1]?.fallbackIcon,
};
const isPayer = currentUserAccountID === report?.managerID;
const isManager = currentUserAccountID === report?.managerID;

return isPayer ? [managerIcon, ownerIcon] : [ownerIcon, managerIcon];
return isManager ? [managerIcon, ownerIcon] : [ownerIcon, managerIcon];
}

if (isSelfDM(report)) {
Expand Down Expand Up @@ -5215,6 +5238,7 @@ export {
hasSingleParticipant,
getReportRecipientAccountIDs,
isOneOnOneChat,
isPayer,
goBackToDetailsPage,
getTransactionReportName,
getTransactionDetails,
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback<
/** Collection of tax rates attached to a policy */
taxRates?: TaxRatesWithDefault;

/** Email of the reimburser when reimbursement is set direct */
reimburserEmail?: string;

/** ReportID of the admins room for this workspace */
chatReportIDAdmins?: number;

Expand Down

0 comments on commit c4ceaed

Please sign in to comment.