diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 851dc08defaf..fb05407ab39a 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -475,6 +475,16 @@ function isChatThread(report) { return isThread(report) && report.type === CONST.REPORT.TYPE.CHAT; } +/** + * Returns true if report is a DM/Group DM chat. + * + * @param {Object} report + * @returns {Boolean} + */ +function isDM(report) { + return !getChatType(report); +} + /** * Only returns true if this is our main 1:1 DM report with Concierge * @@ -514,6 +524,23 @@ function isExpensifyOnlyParticipantInReport(report) { return reportParticipants.length === 1 && _.some(reportParticipants, (accountID) => _.contains(CONST.EXPENSIFY_ACCOUNT_IDS, accountID)); } +/** + * Returns whether a given report can have tasks created in it. + * We only prevent the task option if it's a DM/group-DM and the other users are all special Expensify accounts + * + * @param {Object} report + * @returns {Boolean} + */ +function canCreateTaskInReport(report) { + const otherReportParticipants = _.without(lodashGet(report, 'participantAccountIDs', []), currentUserAccountID); + const areExpensifyAccountsOnlyOtherParticipants = _.every(otherReportParticipants, (accountID) => _.contains(CONST.EXPENSIFY_ACCOUNT_IDS, accountID)); + if (areExpensifyAccountsOnlyOtherParticipants && isDM(report)) { + return false; + } + + return true; +} + /** * Returns true if there are any Expensify accounts (i.e. with domain 'expensify.com') in the set of accountIDs * by cross-referencing the accountIDs with personalDetails. @@ -646,16 +673,6 @@ function isPolicyAdmin(policyID, policies) { return policyRole === CONST.POLICY.ROLE.ADMIN; } -/** - * Returns true if report is a DM/Group DM chat. - * - * @param {Object} report - * @returns {Boolean} - */ -function isDM(report) { - return !getChatType(report); -} - /** * Returns true if report has a single participant. * @@ -3638,15 +3655,16 @@ function getMoneyRequestOptions(report, reportParticipants) { const participants = _.filter(reportParticipants, (accountID) => currentUserPersonalDetails.accountID !== accountID); - // Verify if there is any of the expensify accounts amongst the participants in which case user cannot take IOU actions on such report - const hasExcludedIOUAccountIDs = lodashIntersection(reportParticipants, CONST.EXPENSIFY_ACCOUNT_IDS).length > 0; - const hasSingleParticipantInReport = participants.length === 1; - const hasMultipleParticipants = participants.length > 1; - - if (hasExcludedIOUAccountIDs) { + // We don't allow IOU actions if an Expensify account is a participant of the report, unless the policy that the report is on is owned by an Expensify account + const doParticipantsIncludeExpensifyAccounts = lodashIntersection(reportParticipants, CONST.EXPENSIFY_ACCOUNT_IDS).length > 0; + const isPolicyOwnedByExpensifyAccounts = report.policyID ? CONST.EXPENSIFY_ACCOUNT_IDS.includes(getPolicy(report.policyID).ownerAccountID || 0) : false; + if (doParticipantsIncludeExpensifyAccounts && !isPolicyOwnedByExpensifyAccounts) { return []; } + const hasSingleParticipantInReport = participants.length === 1; + const hasMultipleParticipants = participants.length > 1; + // User created policy rooms and default rooms like #admins or #announce will always have the Split Bill option // unless there are no participants at all (e.g. #admins room for a policy with only 1 admin) // DM chats will have the Split Bill option only when there are at least 3 people in the chat. @@ -4135,6 +4153,7 @@ export { getPolicyType, isArchivedRoom, isExpensifyOnlyParticipantInReport, + canCreateTaskInReport, isPolicyExpenseChatAdmin, isPolicyAdmin, isPublicRoom, diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.js b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.js index b4845e943a74..a31e718933ea 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.js +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.js @@ -151,8 +151,7 @@ function AttachmentPickerWithMenuItems({ * @returns {Boolean} */ const taskOption = useMemo(() => { - // We only prevent the task option from showing if it's a DM and the other user is an Expensify default email - if (!Permissions.canUseTasks(betas) || ReportUtils.isExpensifyOnlyParticipantInReport(report)) { + if (!Permissions.canUseTasks(betas) || !ReportUtils.canCreateTaskInReport(report)) { return []; } diff --git a/src/pages/tasks/TaskShareDestinationSelectorModal.js b/src/pages/tasks/TaskShareDestinationSelectorModal.js index 43d4a70a6ba4..cd0d8166770e 100644 --- a/src/pages/tasks/TaskShareDestinationSelectorModal.js +++ b/src/pages/tasks/TaskShareDestinationSelectorModal.js @@ -60,7 +60,7 @@ function TaskShareDestinationSelectorModal(props) { _.keys(props.reports).forEach((reportKey) => { if ( !ReportUtils.canUserPerformWriteAction(props.reports[reportKey]) || - ReportUtils.isExpensifyOnlyParticipantInReport(props.reports[reportKey]) || + !ReportUtils.canCreateTaskInReport(props.reports[reportKey]) || ReportUtils.isCanceledTaskReport(props.reports[reportKey]) ) { return;