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

pay conditions based on reimbursement settings #36814

6 changes: 3 additions & 3 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1380,9 +1380,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;

Expand Down Expand Up @@ -209,11 +207,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 @@ -21,6 +21,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject';
import ButtonWithDropdownMenu from './ButtonWithDropdownMenu';
import * as Expensicons from './Icon/Expensicons';
import KYCWall from './KYCWall';
import {useSession} from './OnyxProvider';

type KYCFlowEvent = GestureResponderEvent | KeyboardEvent | undefined;

Expand Down Expand Up @@ -133,6 +134,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 @@ -172,7 +180,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 @@ -189,7 +197,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 @@ -1221,6 +1221,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 @@ -1603,9 +1626,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];
}

return getIconsForParticipants(report?.participantAccountIDs ?? [], personalDetails);
Expand Down Expand Up @@ -5156,6 +5179,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
Loading