Implement Send Invoice flow from Global Create#40015
Implement Send Invoice flow from Global Create#40015cristipaval merged 64 commits intoExpensify:mainfrom
Conversation
# Conflicts: # src/pages/iou/request/IOURequestStartPage.js # src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js # src/pages/iou/request/step/withWritableReportOrNotFound.tsx
# Conflicts: # src/components/MoneyTemporaryForRefactorRequestConfirmationList.tsx # src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js # src/pages/iou/request/step/withFullTransactionOrNotFound.tsx # src/pages/iou/request/step/withWritableReportOrNotFound.tsx
# Conflicts: # src/libs/API/parameters/index.ts # src/libs/API/types.ts # src/libs/Navigation/types.ts # src/libs/ReportUtils.ts # src/pages/iou/request/IOURequestStartPage.tsx # src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
# Conflicts: # src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js
src/components/MoneyTemporaryForRefactorRequestConfirmationList.tsx
Outdated
Show resolved
Hide resolved
# Conflicts: # src/components/MoneyTemporaryForRefactorRequestConfirmationList.tsx # src/libs/PolicyUtils.ts # src/libs/actions/IOU.ts # src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js # src/pages/iou/request/step/IOURequestStepConfirmation.tsx
|
Yes, that's right. Just like workspace chats we'd have the big sender avatar of the sender's workspace with the small payer user avatar. |
|
@cristipaval Can we please create a follow-up issue to update the invoice room avatars display?
|
I created the issue here: #41261 Let me know if I need to do anything else. |
|
🚀 Cherry-picked to staging by https://github.com/francoisl in version: 1.4.67-7 🚀
@Expensify/applauseleads please QA this PR and check it off on the deploy checklist if it passes. |
|
🚀 Deployed to staging by https://github.com/cristipaval in version: 1.4.68-0 🚀
|
|
🚀 Cherry-picked to staging by https://github.com/francoisl in version: 1.4.67-7 🚀
@Expensify/applauseleads please QA this PR and check it off on the deploy checklist if it passes. |
|
There's a bug noted mostly coming from this PR #41287. If anyone can please take a look |
|
🚀 Deployed to production by https://github.com/francoisl in version: 1.4.68-3 🚀
|
| type SendInvoiceParams = { | ||
| senderWorkspaceID: string; | ||
| accountID: number; | ||
| receiverEmail?: string; |
There was a problem hiding this comment.
Nice little pro tip: either receiverEmail or receiverInvoiceRoomID is required. So I see why you made them both optional, but it later led to a problem here. So what you can do is use RequireAtLeastOne from type-fest.
|
We missed considering the enabled features of the collect workspace to show in the send invoice confirmation screen which raised an issue here. |
| } | ||
| const reportPreviewAction = ReportUtils.buildOptimisticReportPreview(chatReport, optimisticInvoiceReport, trimmedComment, optimisticTransaction); | ||
|
|
||
| // STEP 6: Build Onyx Data |
There was a problem hiding this comment.
We forgot to properly link the reportAction and parent report, which led to bug mentioned #43582
| @@ -0,0 +1,19 @@ | |||
| type SendInvoiceParams = { | |||
There was a problem hiding this comment.
FYI, This PR missed createdIOUReportActionID, createdReportActionIDForThread, reportActionID Send Invoice params and caused these issues: #43797, #43571, #43577, #44992. More info in this proposal: #43797 (comment)
| */ | ||
| function getPrimaryPolicy(activePolicyID?: string): Policy | undefined { | ||
| const activeAdminWorkspaces = PolicyUtils.getActiveAdminWorkspaces(allPolicies); | ||
| const primaryPolicy: Policy | null | undefined = allPolicies?.[activePolicyID ?? '']; |
There was a problem hiding this comment.
As we did not exclude personal policies while fetching primary policy, this resulted in #46705
There was a problem hiding this comment.
FYI, this PR caused this issue: #47922 because it missed updating the logic for invoking openDraftWorkspaceRequest to retrieve the policy details (e.g., categories) when changing the invoice sender policy. More info in this proposal: #47922 (comment)
| if (isNewChatReport) { | ||
| inviteReportAction = ReportUtils.buildOptimisticInviteReportAction(receiver?.displayName ?? '', receiver.accountID ?? -1); | ||
| } | ||
| const reportPreviewAction = ReportUtils.buildOptimisticReportPreview(chatReport, optimisticInvoiceReport, trimmedComment, optimisticTransaction); |
There was a problem hiding this comment.
We returned an incorrect actorAccountID for the invoice report here. It caused the report preview sender appears and disappears when sending invoices consecutively. More details here #51128 (comment)
| key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, | ||
| value: { | ||
| errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateInvoiceFailureMessage'), | ||
| pendingAction: null, |
There was a problem hiding this comment.
✋ Coming from #54035
We already have a logic to delete the transaction if the transaction pending action is ADD when closing the error.
App/src/components/ReportActionItem/MoneyRequestView.tsx
Lines 458 to 472 in d56dfec
So, clear the pendingAction makes the report not deleted. We only need to clear the pendingAction on success.
| filename = receipt.name; | ||
| } | ||
| const optimisticTransaction = TransactionUtils.buildOptimisticTransaction( | ||
| amount, |
There was a problem hiding this comment.
We should multiply by "-1" here before building optimistic data for a transaction in case of sending invoice. Otherwise, it will cause calculating total amount to be incorrect when offline. More details here #61050 (comment)
| API.write(WRITE_COMMANDS.SEND_INVOICE, parameters, onyxData); | ||
|
|
||
| Navigation.dismissModal(invoiceRoomReportID); | ||
| Report.notifyNewAction(invoiceRoomReportID, receiver.accountID); |
There was a problem hiding this comment.
Sending a new invoice did not scroll down the view as we missed passing the current account id instead of the receiver's account id. We fixed this in #63089
| if (isInvoiceReport(moneyRequestReport) && isManager) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
This check was missing an additional variable (isManager || isChatReportArchived) which led to this issue:
we applied the missing variable and fixed the issue by not allowing editing fields of an archived report.


Details
Implementation of invoice creation flow from Global Create
Fixed Issues
$ #40012
PROPOSAL: N/A
Tests
Note (!): Use staging server by turning it on in
Settings->Troubleshoot->Use Staging ServerNote (!): the backend has a know issue related to the invoice currency. If you want your test results to not be affected by that issue, set the sender workspace and the invoice currencies to be USD.
Flow 1
Send Invoiceappears in Global Create3.1 Verify “Distance” and “Scan" do not appear in the big number pad (BNP) screen.
3.2 Verify the Currency can be modified
6.1 The sender Workspace is displayed as expected.
6.2 The receiver is displayed as expected.
Send fromworkspace, you should be navigated to the Send from the screen.Flow 2
Flow 3
Send Invoiceoption in Global CreateOffline tests
Same as in the Tests section
QA Steps
Same as in the Tests section
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
android1.mp4
Android: mWeb Chrome
android_web1.mp4
iOS: Native
ios1.mp4
iOS: mWeb Safari
ios_web1.mp4
MacOS: Chrome / Safari
web1.mp4
MacOS: Desktop
desktop1.mp4