Skip to content

Commit

Permalink
Merge pull request #42714 from rezkiy37/feature/42590-select-invoice-…
Browse files Browse the repository at this point in the history
…room

Allow selecting an existing invoice room as the receiver in the Send Invoice flow from FAB
  • Loading branch information
cristipaval authored Jun 7, 2024
2 parents 4fcc5a9 + 4c3353b commit 02bd068
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 12 deletions.
6 changes: 5 additions & 1 deletion src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,11 @@ function MoneyRequestConfirmationList({
return allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${senderWorkspaceParticipant?.policyID}`];
}, [allPolicies, selectedParticipantsProp]);

const canUpdateSenderWorkspace = useMemo(() => PolicyUtils.canSendInvoice(allPolicies) && !!transaction?.isFromGlobalCreate, [allPolicies, transaction?.isFromGlobalCreate]);
const canUpdateSenderWorkspace = useMemo(() => {
const isInvoiceRoomParticipant = selectedParticipantsProp.some((participant) => participant.isInvoiceRoom);

return PolicyUtils.canSendInvoice(allPolicies) && !!transaction?.isFromGlobalCreate && !isInvoiceRoomParticipant;
}, [allPolicies, selectedParticipantsProp, transaction?.isFromGlobalCreate]);

const canModifyTaxFields = !isReadOnly && !isDistanceRequest;

Expand Down
16 changes: 14 additions & 2 deletions src/libs/OptionsListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ type GetOptionsConfig = {
policyReportFieldOptions?: string[];
recentlyUsedPolicyReportFieldOptions?: string[];
transactionViolations?: OnyxCollection<TransactionViolation[]>;
includeInvoiceRooms?: boolean;
};

type GetUserToInviteConfig = {
Expand Down Expand Up @@ -1746,6 +1747,7 @@ function getOptions(
includePolicyReportFieldOptions = false,
policyReportFieldOptions = [],
recentlyUsedPolicyReportFieldOptions = [],
includeInvoiceRooms = false,
}: GetOptionsConfig,
): Options {
if (includeCategories) {
Expand Down Expand Up @@ -1945,8 +1947,16 @@ function getOptions(
const isCurrentUserOwnedPolicyExpenseChatThatCouldShow =
reportOption.isPolicyExpenseChat && reportOption.ownerAccountID === currentUserAccountID && includeOwnedWorkspaceChats && !reportOption.isArchivedRoom;

// Skip if we aren't including multiple participant reports and this report has multiple participants
if (!isCurrentUserOwnedPolicyExpenseChatThatCouldShow && !includeMultipleParticipantReports && !reportOption.login) {
const shouldShowInvoiceRoom = includeInvoiceRooms && ReportUtils.isInvoiceRoom(reportOption.item) && ReportUtils.isPolicyAdmin(reportOption.policyID ?? '', policies);

/**
Exclude the report option if it doesn't meet any of the following conditions:
- It is not an owned policy expense chat that could be shown
- Multiple participant reports are not included
- It doesn't have a login
- It is not an invoice room that should be shown
*/
if (!isCurrentUserOwnedPolicyExpenseChatThatCouldShow && !includeMultipleParticipantReports && !reportOption.login && !shouldShowInvoiceRoom) {
continue;
}

Expand Down Expand Up @@ -2136,6 +2146,7 @@ function getFilteredOptions(
policyReportFieldOptions: string[] = [],
recentlyUsedPolicyReportFieldOptions: string[] = [],
maxRecentReportsToShow = 5,
includeInvoiceRooms = false,
) {
return getOptions(
{reports, personalDetails},
Expand All @@ -2162,6 +2173,7 @@ function getFilteredOptions(
includePolicyReportFieldOptions,
policyReportFieldOptions,
recentlyUsedPolicyReportFieldOptions,
includeInvoiceRooms,
},
);
}
Expand Down
7 changes: 4 additions & 3 deletions src/pages/iou/request/MoneyRequestParticipantsSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import type {MaybePhraseKey} from '@libs/Localize';
import type {Options} from '@libs/OptionsListUtils';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import * as ReportUtils from '@libs/ReportUtils';
import * as Policy from '@userActions/Policy/Policy';
import * as Report from '@userActions/Report';
import type {IOUAction, IOURequestType, IOUType} from '@src/CONST';
Expand Down Expand Up @@ -116,6 +117,7 @@ function MoneyRequestParticipantsSelector({participants = [], onFinish, onPartic
undefined,
undefined,
isCategorizeOrShareAction ? 0 : undefined,
iouType === CONST.IOU.TYPE.INVOICE,
);

const formatResults = OptionsListUtils.formatSectionsFromSearchTerm(
Expand Down Expand Up @@ -189,10 +191,9 @@ function MoneyRequestParticipantsSelector({participants = [], onFinish, onPartic
];

if (iouType === CONST.IOU.TYPE.INVOICE) {
const primaryPolicy = Policy.getPrimaryPolicy(activePolicyID);

const policyID = option.item && ReportUtils.isInvoiceRoom(option.item) ? option.policyID : Policy.getPrimaryPolicy(activePolicyID)?.id;
newParticipants.push({
policyID: primaryPolicy?.id,
policyID,
isSender: true,
selected: false,
iouType,
Expand Down
15 changes: 9 additions & 6 deletions src/pages/iou/request/step/IOURequestStepParticipants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,26 @@ function IOURequestStepParticipants({
const addParticipant = useCallback(
(val: Participant[]) => {
HttpUtils.cancelPendingRequests(READ_COMMANDS.SEARCH_FOR_REPORTS);
IOU.setMoneyRequestParticipants(transactionID, val);
const rateID = DistanceRequestUtils.getCustomUnitRateID(val[0]?.reportID ?? '');
IOU.setCustomUnitRateID(transactionID, rateID);

const firstParticipantReportID = val[0]?.reportID ?? '';
const rateID = DistanceRequestUtils.getCustomUnitRateID(firstParticipantReportID);
const isInvoice = iouType === CONST.IOU.TYPE.INVOICE && ReportUtils.isInvoiceRoom(ReportUtils.getReport(firstParticipantReportID));
numberOfParticipants.current = val.length;

IOU.setMoneyRequestParticipants(transactionID, val);
IOU.setCustomUnitRateID(transactionID, rateID);

// When multiple participants are selected, the reportID is generated at the end of the confirmation step.
// So we are resetting selectedReportID ref to the reportID coming from params.
if (val.length !== 1) {
if (val.length !== 1 && !isInvoice) {
selectedReportID.current = reportID;
return;
}

// When a participant is selected, the reportID needs to be saved because that's the reportID that will be used in the confirmation step.
selectedReportID.current = val[0]?.reportID ?? reportID;
selectedReportID.current = firstParticipantReportID || reportID;
},
[reportID, transactionID],
[iouType, reportID, transactionID],
);

const goToNextStep = useCallback(() => {
Expand Down
2 changes: 2 additions & 0 deletions src/types/onyx/IOU.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {ValueOf} from 'type-fest';
import type CONST from '@src/CONST';
import type {Icon} from './OnyxCommon';
import type Report from './Report';

type Participant = {
accountID?: number;
Expand All @@ -25,6 +26,7 @@ type Participant = {
isSelfDM?: boolean;
isSender?: boolean;
iouType?: string;
item?: Report;
ownerAccountID?: number;
};

Expand Down

0 comments on commit 02bd068

Please sign in to comment.