Skip to content

Commit edd1719

Browse files
authored
Merge pull request #41902 from VickyStash/feature/send-invoice-from-room
Send an invoice from an invoice room
2 parents b928739 + 0c0952d commit edd1719

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

src/components/MoneyRequestConfirmationList.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ function MoneyRequestConfirmationList({
599599
const formattedSelectedParticipants = selectedParticipants.map((participant) => ({
600600
...participant,
601601
isSelected: false,
602-
isDisabled: !participant.isPolicyExpenseChat && !participant.isSelfDM && ReportUtils.isOptimisticPersonalDetail(participant.accountID ?? -1),
602+
isDisabled: !participant.isInvoiceRoom && !participant.isPolicyExpenseChat && !participant.isSelfDM && ReportUtils.isOptimisticPersonalDetail(participant.accountID ?? -1),
603603
}));
604604
options.push({
605605
title: translate('common.to'),
@@ -1148,7 +1148,7 @@ function MoneyRequestConfirmationList({
11481148
style={styles.moneyRequestMenuItem}
11491149
labelStyle={styles.mt2}
11501150
titleStyle={styles.flex1}
1151-
disabled={didConfirm || !canUpdateSenderWorkspace}
1151+
disabled={didConfirm}
11521152
/>
11531153
)}
11541154
{isDistanceRequest && (

src/libs/OptionsListUtils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ function createOption(
694694
result.isDefaultRoom = ReportUtils.isDefaultRoom(report);
695695
result.isArchivedRoom = ReportUtils.isArchivedRoom(report);
696696
result.isExpenseReport = ReportUtils.isExpenseReport(report);
697+
result.isInvoiceRoom = ReportUtils.isInvoiceRoom(report);
697698
result.isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report);
698699
result.isThread = ReportUtils.isChatThread(report);
699700
result.isTaskReport = ReportUtils.isTaskReport(report);
@@ -806,6 +807,9 @@ function getReportOption(participant: Participant): ReportUtils.OptionData {
806807
// Update text & alternateText because createOption returns workspace name only if report is owned by the user
807808
if (option.isSelfDM) {
808809
option.alternateText = Localize.translateLocal('reportActionsView.yourSpace');
810+
} else if (option.isInvoiceRoom) {
811+
option.text = ReportUtils.getReportName(report);
812+
option.alternateText = Localize.translateLocal('workspace.common.invoices');
809813
} else {
810814
option.text = ReportUtils.getPolicyName(report);
811815
option.alternateText = Localize.translateLocal('workspace.common.workspace');

src/libs/ReportUtils.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ type OptionData = {
433433
parentReportAction?: OnyxEntry<ReportAction>;
434434
displayNamesWithTooltips?: DisplayNameWithTooltips | null;
435435
isDefaultRoom?: boolean;
436+
isInvoiceRoom?: boolean;
436437
isExpenseReport?: boolean;
437438
isOptimisticPersonalDetail?: boolean;
438439
selected?: boolean;
@@ -5515,13 +5516,21 @@ function isGroupChatAdmin(report: OnyxEntry<Report>, accountID: number) {
55155516
* - Self DMs
55165517
* - own policy expense chats
55175518
* - open and processing expense reports tied to own policy expense chat
5518-
*
5519+
* - Send invoice option should show for:
5520+
* - invoice rooms if the user is an admin of the sender workspace
55195521
* None of the options should show in chat threads or if there is some special Expensify account
55205522
* as a participant of the report.
55215523
*/
55225524
function getMoneyRequestOptions(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>, reportParticipants: number[], filterDeprecatedTypes = false): IOUType[] {
55235525
// In any thread or task report, we do not allow any new expenses yet
5524-
if (isChatThread(report) || isTaskReport(report) || isInvoiceRoom(report) || isInvoiceReport(report)) {
5526+
if (isChatThread(report) || isTaskReport(report) || isInvoiceReport(report)) {
5527+
return [];
5528+
}
5529+
5530+
if (isInvoiceRoom(report)) {
5531+
if (isPolicyAdmin(report?.policyID ?? '', allPolicies)) {
5532+
return [CONST.IOU.TYPE.INVOICE];
5533+
}
55255534
return [];
55265535
}
55275536

src/libs/actions/IOU.ts

+14-15
Original file line numberDiff line numberDiff line change
@@ -1650,8 +1650,8 @@ function getSendInvoiceInformation(
16501650
const {amount = 0, currency = '', created = '', merchant = '', category = '', tag = '', taxCode = '', taxAmount = 0, billable, comment, participants} = transaction ?? {};
16511651
const trimmedComment = (comment?.comment ?? '').trim();
16521652
const senderWorkspaceID = participants?.find((participant) => participant?.isSender)?.policyID ?? '';
1653-
const receiverParticipant = participants?.find((participant) => participant?.accountID);
1654-
const receiverAccountID = receiverParticipant?.accountID ?? -1;
1653+
const receiverParticipant = participants?.find((participant) => participant?.accountID) ?? invoiceChatReport?.invoiceReceiver;
1654+
const receiverAccountID = receiverParticipant && 'accountID' in receiverParticipant && receiverParticipant.accountID ? receiverParticipant.accountID : -1;
16551655
let receiver = ReportUtils.getPersonalDetailsForAccountID(receiverAccountID);
16561656
let optimisticPersonalDetailListAction = {};
16571657

@@ -1704,11 +1704,12 @@ function getSendInvoiceInformation(
17041704
// STEP 4: Add optimistic personal details for participant
17051705
const shouldCreateOptimisticPersonalDetails = isNewChatReport && !allPersonalDetails[receiverAccountID];
17061706
if (shouldCreateOptimisticPersonalDetails) {
1707+
const receiverLogin = receiverParticipant && 'login' in receiverParticipant && receiverParticipant.login ? receiverParticipant.login : '';
17071708
receiver = {
17081709
accountID: receiverAccountID,
17091710
avatar: UserUtils.getDefaultAvatarURL(receiverAccountID),
1710-
displayName: LocalePhoneNumber.formatPhoneNumber(receiverParticipant?.login ?? ''),
1711-
login: receiverParticipant?.login,
1711+
displayName: LocalePhoneNumber.formatPhoneNumber(receiverLogin),
1712+
login: receiverLogin,
17121713
isOptimisticPersonalDetail: true,
17131714
};
17141715

@@ -6497,22 +6498,20 @@ function setMoneyRequestParticipantsFromReport(transactionID: string, report: On
64976498

64986499
if (ReportUtils.isPolicyExpenseChat(chatReport) || shouldAddAsReport) {
64996500
participants = [{accountID: 0, reportID: chatReport?.reportID, isPolicyExpenseChat: ReportUtils.isPolicyExpenseChat(chatReport), selected: true}];
6501+
} else if (ReportUtils.isInvoiceRoom(chatReport)) {
6502+
participants = [
6503+
{reportID: chatReport?.reportID, selected: true},
6504+
{
6505+
policyID: chatReport?.policyID,
6506+
isSender: true,
6507+
selected: false,
6508+
},
6509+
];
65006510
} else {
65016511
const chatReportOtherParticipants = Object.keys(chatReport?.participants ?? {})
65026512
.map(Number)
65036513
.filter((accountID) => accountID !== currentUserAccountID);
65046514
participants = chatReportOtherParticipants.map((accountID) => ({accountID, selected: true}));
6505-
6506-
if (ReportUtils.isInvoiceRoom(chatReport)) {
6507-
participants = [
6508-
...participants,
6509-
{
6510-
policyID: chatReport?.policyID,
6511-
isSender: true,
6512-
selected: false,
6513-
},
6514-
];
6515-
}
65166515
}
65176516

65186517
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants, participantsAutoAssigned: true});

src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ function AttachmentPickerWithMenuItems({
147147
onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.TRACK, report?.reportID ?? ''),
148148
},
149149
[CONST.IOU.TYPE.INVOICE]: {
150-
icon: Expensicons.Invoice,
150+
icon: Expensicons.InvoiceGeneric,
151151
text: translate('workspace.invoices.sendInvoice'),
152152
onSelected: () => IOU.startMoneyRequest(CONST.IOU.TYPE.INVOICE, report?.reportID ?? ''),
153153
},

src/types/onyx/IOU.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type Participant = {
77
login?: string;
88
displayName?: string;
99
isPolicyExpenseChat?: boolean;
10+
isInvoiceRoom?: boolean;
1011
isOwnPolicyExpenseChat?: boolean;
1112
chatType?: ValueOf<typeof CONST.REPORT.CHAT_TYPE>;
1213
reportID?: string;

0 commit comments

Comments
 (0)