Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ function MoneyRequestConfirmationList({
const formattedSelectedParticipants = selectedParticipants.map((participant) => ({
...participant,
isSelected: false,
isDisabled: !participant.isPolicyExpenseChat && !participant.isSelfDM && ReportUtils.isOptimisticPersonalDetail(participant.accountID ?? -1),
isDisabled: !participant.isInvoiceRoom && !participant.isPolicyExpenseChat && !participant.isSelfDM && ReportUtils.isOptimisticPersonalDetail(participant.accountID ?? -1),
}));
options.push({
title: translate('common.to'),
Expand Down Expand Up @@ -1148,7 +1148,7 @@ function MoneyRequestConfirmationList({
style={styles.moneyRequestMenuItem}
labelStyle={styles.mt2}
titleStyle={styles.flex1}
disabled={didConfirm || !canUpdateSenderWorkspace}
disabled={didConfirm}
/>
)}
{isDistanceRequest && (
Expand Down
4 changes: 4 additions & 0 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ function createOption(
result.isDefaultRoom = ReportUtils.isDefaultRoom(report);
result.isArchivedRoom = ReportUtils.isArchivedRoom(report);
result.isExpenseReport = ReportUtils.isExpenseReport(report);
result.isInvoiceRoom = ReportUtils.isInvoiceRoom(report);
result.isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
result.isThread = ReportUtils.isChatThread(report);
result.isTaskReport = ReportUtils.isTaskReport(report);
Expand Down Expand Up @@ -806,6 +807,9 @@ function getReportOption(participant: Participant): ReportUtils.OptionData {
// Update text & alternateText because createOption returns workspace name only if report is owned by the user
if (option.isSelfDM) {
option.alternateText = Localize.translateLocal('reportActionsView.yourSpace');
} else if (option.isInvoiceRoom) {
option.text = ReportUtils.getReportName(report);
option.alternateText = Localize.translateLocal('workspace.common.invoices');
} else {
option.text = ReportUtils.getPolicyName(report);
option.alternateText = Localize.translateLocal('workspace.common.workspace');
Expand Down
13 changes: 11 additions & 2 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ type OptionData = {
parentReportAction?: OnyxEntry<ReportAction>;
displayNamesWithTooltips?: DisplayNameWithTooltips | null;
isDefaultRoom?: boolean;
isInvoiceRoom?: boolean;
isExpenseReport?: boolean;
isOptimisticPersonalDetail?: boolean;
selected?: boolean;
Expand Down Expand Up @@ -5506,13 +5507,21 @@ function isGroupChatAdmin(report: OnyxEntry<Report>, accountID: number) {
* - Self DMs
* - own policy expense chats
* - open and processing expense reports tied to own policy expense chat
*
* - Send invoice option should show for:
* - invoice rooms if the user is an admin of the sender workspace
* None of the options should show in chat threads or if there is some special Expensify account
* as a participant of the report.
*/
function getMoneyRequestOptions(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>, reportParticipants: number[], filterDeprecatedTypes = false): IOUType[] {
// In any thread or task report, we do not allow any new expenses yet
if (isChatThread(report) || isTaskReport(report) || isInvoiceRoom(report) || isInvoiceReport(report)) {
if (isChatThread(report) || isTaskReport(report) || isInvoiceReport(report)) {
return [];
}

if (isInvoiceRoom(report)) {
if (isPolicyAdmin(report?.policyID ?? '', allPolicies)) {
return [CONST.IOU.TYPE.INVOICE];
}
return [];
}

Expand Down
29 changes: 14 additions & 15 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1650,8 +1650,8 @@ function getSendInvoiceInformation(
const {amount = 0, currency = '', created = '', merchant = '', category = '', tag = '', taxCode = '', taxAmount = 0, billable, comment, participants} = transaction ?? {};
const trimmedComment = (comment?.comment ?? '').trim();
const senderWorkspaceID = participants?.find((participant) => participant?.isSender)?.policyID ?? '';
const receiverParticipant = participants?.find((participant) => participant?.accountID);
const receiverAccountID = receiverParticipant?.accountID ?? -1;
const receiverParticipant = participants?.find((participant) => participant?.accountID) ?? invoiceChatReport?.invoiceReceiver;
const receiverAccountID = receiverParticipant && 'accountID' in receiverParticipant && receiverParticipant.accountID ? receiverParticipant.accountID : -1;
let receiver = ReportUtils.getPersonalDetailsForAccountID(receiverAccountID);
let optimisticPersonalDetailListAction = {};

Expand Down Expand Up @@ -1704,11 +1704,12 @@ function getSendInvoiceInformation(
// STEP 4: Add optimistic personal details for participant
const shouldCreateOptimisticPersonalDetails = isNewChatReport && !allPersonalDetails[receiverAccountID];
if (shouldCreateOptimisticPersonalDetails) {
const receiverLogin = receiverParticipant && 'login' in receiverParticipant && receiverParticipant.login ? receiverParticipant.login : '';
receiver = {
accountID: receiverAccountID,
avatar: UserUtils.getDefaultAvatarURL(receiverAccountID),
displayName: LocalePhoneNumber.formatPhoneNumber(receiverParticipant?.login ?? ''),
login: receiverParticipant?.login,
displayName: LocalePhoneNumber.formatPhoneNumber(receiverLogin),
login: receiverLogin,
isOptimisticPersonalDetail: true,
};

Expand Down Expand Up @@ -6494,22 +6495,20 @@ function setMoneyRequestParticipantsFromReport(transactionID: string, report: On

if (ReportUtils.isPolicyExpenseChat(chatReport) || shouldAddAsReport) {
participants = [{accountID: 0, reportID: chatReport?.reportID, isPolicyExpenseChat: ReportUtils.isPolicyExpenseChat(chatReport), selected: true}];
} else if (ReportUtils.isInvoiceRoom(chatReport)) {
participants = [
{reportID: chatReport?.reportID, selected: true},
{
policyID: chatReport?.policyID,
isSender: true,
selected: false,
},
];
} else {
const chatReportOtherParticipants = Object.keys(chatReport?.participants ?? {})
.map(Number)
.filter((accountID) => accountID !== currentUserAccountID);
participants = chatReportOtherParticipants.map((accountID) => ({accountID, selected: true}));

if (ReportUtils.isInvoiceRoom(chatReport)) {
participants = [
...participants,
{
policyID: chatReport?.policyID,
isSender: true,
selected: false,
},
];
}
}

Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants, participantsAutoAssigned: true});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function AttachmentPickerWithMenuItems({
onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? ''),
},
[CONST.IOU.TYPE.INVOICE]: {
icon: Expensicons.Invoice,
icon: Expensicons.InvoiceGeneric,
text: translate('workspace.invoices.sendInvoice'),
onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? ''),
},
Expand Down
1 change: 1 addition & 0 deletions src/types/onyx/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type Participant = {
login?: string;
displayName?: string;
isPolicyExpenseChat?: boolean;
isInvoiceRoom?: boolean;
isOwnPolicyExpenseChat?: boolean;
chatType?: ValueOf<typeof CONST.REPORT.CHAT_TYPE>;
reportID?: string;
Expand Down