diff --git a/src/CONST.ts b/src/CONST.ts index 79bc62ab8ac0..8c733ef2bcaf 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -440,6 +440,14 @@ const CONST = { }, CURRENCY: { USD: 'USD', + AUD: 'AUD', + CAD: 'CAD', + GBP: 'GBP', + NZD: 'NZD', + EUR: 'EUR', + }, + get DIRECT_REIMBURSEMENT_CURRENCIES() { + return [this.CURRENCY.USD, this.CURRENCY.AUD, this.CURRENCY.CAD, this.CURRENCY.GBP, this.CURRENCY.NZD, this.CURRENCY.EUR]; }, EXAMPLE_PHONE_NUMBER: '+15005550006', CONCIERGE_CHAT_NAME: 'Concierge', @@ -1294,6 +1302,11 @@ const CONST = { CUSTOM_UNIT_RATE_BASE_OFFSET: 100, OWNER_EMAIL_FAKE: '_FAKE_', OWNER_ACCOUNT_ID_FAKE: 0, + REIMBURSEMENT_CHOICES: { + REIMBURSEMENT_YES: 'reimburseYes', + REIMBURSEMENT_NO: 'reimburseNo', + REIMBURSEMENT_MANUAL: 'reimburseManual', + }, ID_FAKE: '_FAKE_', }, diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index afdc62218f95..7043173b3641 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -57,6 +57,7 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt const isSettled = ReportUtils.isSettled(moneyRequestReport.reportID); 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 @@ -65,8 +66,8 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt : isPolicyAdmin || (ReportUtils.isMoneyRequestReport(moneyRequestReport) && isManager); const isDraft = ReportUtils.isDraftExpenseReport(moneyRequestReport); const shouldShowPayButton = useMemo( - () => isPayer && !isDraft && !isSettled && !moneyRequestReport.isWaitingOnBankAccount && reimbursableTotal !== 0 && !ReportUtils.isArchivedRoom(chatReport), - [isPayer, isDraft, isSettled, moneyRequestReport, reimbursableTotal, chatReport], + () => isPayer && !isDraft && !isSettled && !moneyRequestReport.isWaitingOnBankAccount && reimbursableTotal !== 0 && !ReportUtils.isArchivedRoom(chatReport) && !isAutoReimbursable, + [isPayer, isDraft, isSettled, moneyRequestReport, reimbursableTotal, chatReport, isAutoReimbursable], ); const shouldShowApproveButton = useMemo(() => { if (!isPaidGroupPolicy) { diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 8483b7a481f2..a22022aaabb2 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -148,6 +148,7 @@ function ReportPreview(props) { const isCurrentUserManager = managerID === lodashGet(props.session, 'accountID'); const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(props.iouReport); const policyType = lodashGet(props.policy, 'type'); + const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(props.iouReport, props.policy); const iouSettled = ReportUtils.isSettled(props.iouReportID); const iouCanceled = ReportUtils.isArchivedRoom(props.chatReport); @@ -239,8 +240,8 @@ function ReportPreview(props) { isPolicyAdmin && (isApproved || isCurrentUserManager) : isPolicyAdmin || (isMoneyRequestReport && isCurrentUserManager); const shouldShowPayButton = useMemo( - () => isPayer && !isDraftExpenseReport && !iouSettled && !props.iouReport.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled, - [isPayer, isDraftExpenseReport, iouSettled, reimbursableSpend, iouCanceled, props.iouReport], + () => isPayer && !isDraftExpenseReport && !iouSettled && !props.iouReport.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable, + [isPayer, isDraftExpenseReport, iouSettled, reimbursableSpend, iouCanceled, isAutoReimbursable, props.iouReport], ); const shouldShowApproveButton = useMemo(() => { if (!isPaidGroupPolicy) { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8e747ab8dafe..016685625152 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4442,10 +4442,27 @@ function shouldDisableThread(reportAction: OnyxEntry, reportID: st ); } +function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry = null): boolean { + if (!policy) { + return false; + } + type CurrencyType = (typeof CONST.DIRECT_REIMBURSEMENT_CURRENCIES)[number]; + const reimbursableTotal = getMoneyRequestReimbursableTotal(report); + const autoReimbursementLimit = policy.autoReimbursementLimit ?? 0; + const isAutoReimbursable = + isGroupPolicy(report) && + policy.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES && + autoReimbursementLimit >= reimbursableTotal && + reimbursableTotal > 0 && + CONST.DIRECT_REIMBURSEMENT_CURRENCIES.includes(report?.currency as CurrencyType); + return isAutoReimbursable; +} + export { getReportParticipantsTitle, isReportMessageAttachment, findLastAccessedReport, + canBeAutoReimbursed, canEditReportAction, canFlagReportAction, shouldShowFlagComment, diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 81e5b8392ee2..4bc64ee13b16 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -90,6 +90,12 @@ type Policy = { /** The employee list of the policy */ employeeList?: []; + /** The reimbursement choice for policy */ + reimbursementChoice?: ValueOf; + + /** The maximum report total allowed to trigger auto reimbursement. */ + autoReimbursementLimit?: number; + /** Whether to leave the calling account as an admin on the policy */ makeMeAdmin?: boolean;