From 472dcd97c6c22a4862323d1d4809193cf074c430 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 12 Aug 2024 17:11:58 +0200 Subject: [PATCH 1/6] Implement workspace creation during paying as business --- src/components/SettlementButton.tsx | 36 ++++---- src/libs/API/parameters/PayInvoiceParams.ts | 7 ++ src/libs/actions/IOU.ts | 91 ++++++++++++++++----- 3 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index efe7aa91de18..f366c99f8c53 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -5,13 +5,11 @@ import {useOnyx, withOnyx} from 'react-native-onyx'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import playSound, {SOUNDS} from '@libs/Sound'; import * as SubscriptionUtils from '@libs/SubscriptionUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import * as IOU from '@userActions/IOU'; -import * as PolicyActions from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; @@ -157,10 +155,6 @@ function SettlementButton({ }: SettlementButtonProps) { const {translate} = useLocalize(); const {isOffline} = useNetwork(); - const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); - - const primaryPolicy = useMemo(() => PolicyActions.getPrimaryPolicy(activePolicyID), [activePolicyID]); - const session = useSession(); // The app would crash due to subscribing to the entire report collection if chatReportID is an empty string. So we should have a fallback ID here. const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID || -1}`); @@ -233,22 +227,20 @@ function SettlementButton({ }); } - if (PolicyUtils.isPolicyAdmin(primaryPolicy) && PolicyUtils.isPaidGroupPolicy(primaryPolicy)) { - buttonOptions.push({ - text: translate('iou.settleBusiness', {formattedAmount}), - icon: Expensicons.Building, - value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, - backButtonText: translate('iou.business'), - subMenuItems: [ - { - text: translate('iou.payElsewhere', {formattedAmount: ''}), - icon: Expensicons.Cash, - value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, - onSelected: () => onPress(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, true), - }, - ], - }); - } + buttonOptions.push({ + text: translate('iou.settleBusiness', {formattedAmount}), + icon: Expensicons.Building, + value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + backButtonText: translate('iou.business'), + subMenuItems: [ + { + text: translate('iou.payElsewhere', {formattedAmount: ''}), + icon: Expensicons.Cash, + value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + onSelected: () => onPress(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, true), + }, + ], + }); } if (shouldShowApproveButton) { diff --git a/src/libs/API/parameters/PayInvoiceParams.ts b/src/libs/API/parameters/PayInvoiceParams.ts index a6b9746d87bc..bd3d75b6da1f 100644 --- a/src/libs/API/parameters/PayInvoiceParams.ts +++ b/src/libs/API/parameters/PayInvoiceParams.ts @@ -5,6 +5,13 @@ type PayInvoiceParams = { reportActionID: string; paymentMethodType: PaymentMethodType; payAsBusiness: boolean; + policyID?: string; + announceChatReportID?: string; + adminsChatReportID?: string; + expenseChatReportID?: string; + announceCreatedReportActionID?: string; + adminsCreatedReportActionID?: string; + expenseCreatedReportActionID?: string; }; export default PayInvoiceParams; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index ef5f6d6d61c0..8f45bd6e4a07 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -135,7 +135,7 @@ type UpdateMoneyRequestData = { }; type PayMoneyRequestData = { - params: PayMoneyRequestParams; + params: PayMoneyRequestParams & Partial; optimisticData: OnyxUpdate[]; successData: OnyxUpdate[]; failureData: OnyxUpdate[]; @@ -6542,7 +6542,37 @@ function getPayMoneyRequestParams( payAsBusiness?: boolean, ): PayMoneyRequestData { const isInvoiceReport = ReportUtils.isInvoiceReport(iouReport); + const primaryPolicy = PolicyUtils.getPolicy(primaryPolicyID); + let payerPolicyID = primaryPolicyID; let chatReport = initialChatReport; + let policyParams = {}; + const optimisticData: OnyxUpdate[] = []; + const successData: OnyxUpdate[] = []; + const failureData: OnyxUpdate[] = []; + + if (ReportUtils.isIndividualInvoiceRoom(chatReport) && (!primaryPolicy || !PolicyUtils.isPolicyAdmin(primaryPolicy) || !PolicyUtils.isPaidGroupPolicy(primaryPolicy))) { + payerPolicyID = Policy.generatePolicyID(); + const { + optimisticData: policyOptimisticData, + failureData: policyFailureData, + successData: policySuccessData, + params, + } = Policy.buildPolicyData(currentUserEmail, true, undefined, payerPolicyID); + const {announceChatReportID, announceCreatedReportActionID, adminsChatReportID, adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID} = params; + policyParams = { + policyID: payerPolicyID, + announceChatReportID, + announceCreatedReportActionID, + adminsChatReportID, + adminsCreatedReportActionID, + expenseChatReportID, + expenseCreatedReportActionID, + }; + + optimisticData.push(...policyOptimisticData); + successData.push(...policySuccessData); + failureData.push(...policyFailureData); + } if (ReportUtils.isIndividualInvoiceRoom(chatReport) && payAsBusiness && primaryPolicyID) { const existingB2BInvoiceRoom = ReportUtils.getInvoiceChatByParticipants(chatReport.policyID ?? '', primaryPolicyID); @@ -6591,14 +6621,14 @@ function getPayMoneyRequestParams( lastMessageText: ReportActionsUtils.getReportActionText(optimisticIOUReportAction), lastMessageHtml: ReportActionsUtils.getReportActionHtml(optimisticIOUReportAction), }; - if (ReportUtils.isIndividualInvoiceRoom(chatReport) && payAsBusiness && primaryPolicyID) { + if (ReportUtils.isIndividualInvoiceRoom(chatReport) && payAsBusiness && payerPolicyID) { optimisticChatReport.invoiceReceiver = { type: CONST.REPORT.INVOICE_RECEIVER_TYPE.BUSINESS, - policyID: primaryPolicyID, + policyID: payerPolicyID, }; } - const optimisticData: OnyxUpdate[] = [ + optimisticData.push( { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, @@ -6640,23 +6670,21 @@ function getPayMoneyRequestParams( key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport.reportID}`, value: optimisticNextStep, }, - ]; + ); - const successData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, - value: { - pendingFields: { - preview: null, - reimbursed: null, - partial: null, - }, + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, + value: { + pendingFields: { + preview: null, + reimbursed: null, + partial: null, }, }, - ]; + }); - const failureData: OnyxUpdate[] = [ + failureData.push( { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, @@ -6683,7 +6711,7 @@ function getPayMoneyRequestParams( key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport.reportID}`, value: currentNextStep, }, - ]; + ); // In case the report preview action is loaded locally, let's update it. if (optimisticReportPreviewAction) { @@ -6729,6 +6757,7 @@ function getPayMoneyRequestParams( optimisticHoldReportID, optimisticHoldActionID, optimisticHoldReportExpenseActionIDs, + ...policyParams, }, optimisticData, successData, @@ -7369,16 +7398,38 @@ function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes. optimisticData, successData, failureData, - params: {reportActionID}, + params: { + reportActionID, + policyID, + announceChatReportID, + announceCreatedReportActionID, + adminsChatReportID, + adminsCreatedReportActionID, + expenseChatReportID, + expenseCreatedReportActionID, + }, } = getPayMoneyRequestParams(chatReport, invoiceReport, recipient, paymentMethodType, true, payAsBusiness); - const params: PayInvoiceParams = { + let params: PayInvoiceParams = { reportID: invoiceReport.reportID, reportActionID, paymentMethodType, payAsBusiness, }; + if (policyID) { + params = { + ...params, + policyID, + announceChatReportID, + announceCreatedReportActionID, + adminsChatReportID, + adminsCreatedReportActionID, + expenseChatReportID, + expenseCreatedReportActionID, + }; + } + API.write(WRITE_COMMANDS.PAY_INVOICE, params, {optimisticData, successData, failureData}); } From 449b62b6e23a2043dac7523c5bb7b9b7f88d14fd Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 19 Aug 2024 17:53:41 +0200 Subject: [PATCH 2/6] Updates to follow main branch changes --- src/libs/actions/IOU.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 2d46f157d539..0bef8ae4cd54 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6551,7 +6551,7 @@ function getPayMoneyRequestParams( payAsBusiness?: boolean, ): PayMoneyRequestData { const isInvoiceReport = ReportUtils.isInvoiceReport(iouReport); - const primaryPolicy = PolicyUtils.getPolicy(primaryPolicyID); + const activePolicy = PolicyUtils.getPolicy(activePolicyID); let payerPolicyID = activePolicyID; let chatReport = initialChatReport; let policyParams = {}; @@ -6559,7 +6559,7 @@ function getPayMoneyRequestParams( const successData: OnyxUpdate[] = []; const failureData: OnyxUpdate[] = []; - if (ReportUtils.isIndividualInvoiceRoom(chatReport) && (!primaryPolicy || !PolicyUtils.isPolicyAdmin(primaryPolicy) || !PolicyUtils.isPaidGroupPolicy(primaryPolicy))) { + if (ReportUtils.isIndividualInvoiceRoom(chatReport) && (!activePolicy || !PolicyUtils.isPolicyAdmin(activePolicy) || !PolicyUtils.isPaidGroupPolicy(activePolicy))) { payerPolicyID = Policy.generatePolicyID(); const { optimisticData: policyOptimisticData, From 314f67327ac004bff08b581894cfd7bc6d01eb5c Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 19 Aug 2024 18:02:02 +0200 Subject: [PATCH 3/6] Update active policy id optimistically --- src/libs/actions/IOU.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 0bef8ae4cd54..aee4e1139e04 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6578,9 +6578,9 @@ function getPayMoneyRequestParams( expenseCreatedReportActionID, }; - optimisticData.push(...policyOptimisticData); + optimisticData.push(...policyOptimisticData, {onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, value: payerPolicyID}); successData.push(...policySuccessData); - failureData.push(...policyFailureData); + failureData.push(...policyFailureData, {onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, value: activePolicyID ?? null}); } if (ReportUtils.isIndividualInvoiceRoom(chatReport) && payAsBusiness && activePolicyID) { From 99a95ce1efde172fbfd03636209de2e51a63d872 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Thu, 22 Aug 2024 16:07:37 +0200 Subject: [PATCH 4/6] Pass additional props for the policy creation --- src/libs/API/parameters/PayInvoiceParams.ts | 10 ++----- src/libs/actions/IOU.ts | 29 +++++++++++++++++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/libs/API/parameters/PayInvoiceParams.ts b/src/libs/API/parameters/PayInvoiceParams.ts index bd3d75b6da1f..7f80e5d20c4c 100644 --- a/src/libs/API/parameters/PayInvoiceParams.ts +++ b/src/libs/API/parameters/PayInvoiceParams.ts @@ -1,17 +1,11 @@ import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type CreateWorkspaceParams from './CreateWorkspaceParams'; -type PayInvoiceParams = { +type PayInvoiceParams = Partial & { reportID: string; reportActionID: string; paymentMethodType: PaymentMethodType; payAsBusiness: boolean; - policyID?: string; - announceChatReportID?: string; - adminsChatReportID?: string; - expenseChatReportID?: string; - announceCreatedReportActionID?: string; - adminsCreatedReportActionID?: string; - expenseCreatedReportActionID?: string; }; export default PayInvoiceParams; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index ff54800429bd..58c8b7d91b20 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6536,8 +6536,9 @@ function getPayMoneyRequestParams( const optimisticData: OnyxUpdate[] = []; const successData: OnyxUpdate[] = []; const failureData: OnyxUpdate[] = []; + const shouldCreatePolicy = !activePolicy || !PolicyUtils.isPolicyAdmin(activePolicy) || !PolicyUtils.isPaidGroupPolicy(activePolicy); - if (ReportUtils.isIndividualInvoiceRoom(chatReport) && (!activePolicy || !PolicyUtils.isPolicyAdmin(activePolicy) || !PolicyUtils.isPaidGroupPolicy(activePolicy))) { + if (ReportUtils.isIndividualInvoiceRoom(chatReport) && shouldCreatePolicy) { payerPolicyID = Policy.generatePolicyID(); const { optimisticData: policyOptimisticData, @@ -6545,7 +6546,19 @@ function getPayMoneyRequestParams( successData: policySuccessData, params, } = Policy.buildPolicyData(currentUserEmail, true, undefined, payerPolicyID); - const {announceChatReportID, announceCreatedReportActionID, adminsChatReportID, adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID} = params; + const { + announceChatReportID, + announceCreatedReportActionID, + adminsChatReportID, + adminsCreatedReportActionID, + expenseChatReportID, + expenseCreatedReportActionID, + customUnitRateID, + customUnitID, + ownerEmail, + policyName, + } = params; + policyParams = { policyID: payerPolicyID, announceChatReportID, @@ -6554,6 +6567,10 @@ function getPayMoneyRequestParams( adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID, + customUnitRateID, + customUnitID, + ownerEmail, + policyName, }; optimisticData.push(...policyOptimisticData, {onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, value: payerPolicyID}); @@ -7405,6 +7422,10 @@ function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes. adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID, + customUnitRateID, + customUnitID, + ownerEmail, + policyName, }, } = getPayMoneyRequestParams(chatReport, invoiceReport, recipient, paymentMethodType, true, payAsBusiness); @@ -7425,6 +7446,10 @@ function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes. adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID, + customUnitRateID, + customUnitID, + ownerEmail, + policyName, }; } From 16ceee400658d257c9caf3e9eb9593d0d3b261cf Mon Sep 17 00:00:00 2001 From: VickyStash Date: Fri, 23 Aug 2024 11:02:29 +0200 Subject: [PATCH 5/6] Fix condition --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 58c8b7d91b20..7cf92acdd543 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6538,7 +6538,7 @@ function getPayMoneyRequestParams( const failureData: OnyxUpdate[] = []; const shouldCreatePolicy = !activePolicy || !PolicyUtils.isPolicyAdmin(activePolicy) || !PolicyUtils.isPaidGroupPolicy(activePolicy); - if (ReportUtils.isIndividualInvoiceRoom(chatReport) && shouldCreatePolicy) { + if (ReportUtils.isIndividualInvoiceRoom(chatReport) && payAsBusiness && shouldCreatePolicy) { payerPolicyID = Policy.generatePolicyID(); const { optimisticData: policyOptimisticData, From da62d183018d6d6896a287658aef6a4be741db42 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Wed, 28 Aug 2024 18:40:39 +0200 Subject: [PATCH 6/6] Re-run checks