@@ -7,6 +7,7 @@ import Onyx from 'react-native-onyx';
77import type { PartialDeep , SetRequired , ValueOf } from 'type-fest' ;
88import ReceiptGeneric from '@assets/images/receipt-generic.png' ;
99import type { PaymentMethod } from '@components/KYCWall/types' ;
10+ import type { SearchQueryJSON } from '@components/Search/types' ;
1011import * as API from '@libs/API' ;
1112import type {
1213 ApproveMoneyRequestParams ,
@@ -178,7 +179,7 @@ import {
178179 shouldCreateNewMoneyRequestReport as shouldCreateNewMoneyRequestReportReportUtils ,
179180 updateReportPreview ,
180181} from '@libs/ReportUtils' ;
181- import { getCurrentSearchQueryJSON } from '@libs/SearchQueryUtils' ;
182+ import { buildSearchQueryJSON , getCurrentSearchQueryJSON , getTodoSearchQuery } from '@libs/SearchQueryUtils' ;
182183import { getSession } from '@libs/SessionUtils' ;
183184import playSound , { SOUNDS } from '@libs/Sound' ;
184185import { shouldRestrictUserBillableActions } from '@libs/SubscriptionUtils' ;
@@ -11503,6 +11504,59 @@ function resolveDuplicates(params: MergeDuplicatesParams) {
1150311504 API . write ( WRITE_COMMANDS . RESOLVE_DUPLICATES , parameters , { optimisticData, failureData} ) ;
1150411505}
1150511506
11507+ const expenseReportStatusFilterMapping = {
11508+ [ CONST . SEARCH . STATUS . EXPENSE . DRAFTS ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) =>
11509+ expenseReport ?. stateNum === CONST . REPORT . STATE_NUM . OPEN && expenseReport ?. statusNum === CONST . REPORT . STATUS_NUM . OPEN ,
11510+ [ CONST . SEARCH . STATUS . EXPENSE . OUTSTANDING ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) =>
11511+ expenseReport ?. stateNum === CONST . REPORT . STATE_NUM . SUBMITTED && expenseReport ?. statusNum === CONST . REPORT . STATUS_NUM . SUBMITTED ,
11512+ [ CONST . SEARCH . STATUS . EXPENSE . APPROVED ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) =>
11513+ expenseReport ?. stateNum === CONST . REPORT . STATE_NUM . APPROVED && expenseReport ?. statusNum === CONST . REPORT . STATUS_NUM . APPROVED ,
11514+ [ CONST . SEARCH . STATUS . EXPENSE . PAID ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) =>
11515+ ( expenseReport ?. stateNum ?? 0 ) >= CONST . REPORT . STATE_NUM . APPROVED && expenseReport ?. statusNum === CONST . REPORT . STATUS_NUM . REIMBURSED ,
11516+ [ CONST . SEARCH . STATUS . EXPENSE . DONE ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) =>
11517+ expenseReport ?. stateNum === CONST . REPORT . STATE_NUM . APPROVED && expenseReport ?. statusNum === CONST . REPORT . STATUS_NUM . CLOSED ,
11518+ [ CONST . SEARCH . STATUS . EXPENSE . UNREPORTED ] : ( expenseReport : OnyxEntry < OnyxTypes . Report > ) => ! expenseReport ,
11519+ [ CONST . SEARCH . STATUS . EXPENSE . ALL ] : ( ) => true ,
11520+ } ;
11521+
11522+ // Determines whether the current search results should be optimistically updated
11523+ function shouldOptimisticallyUpdateSearch ( currentSearchQueryJSON : SearchQueryJSON , iouReport : OnyxEntry < OnyxTypes . Report > , isInvoice : boolean | undefined ) {
11524+ if ( currentSearchQueryJSON . type !== CONST . SEARCH . DATA_TYPES . INVOICE && currentSearchQueryJSON . type !== CONST . SEARCH . DATA_TYPES . EXPENSE ) {
11525+ return false ;
11526+ }
11527+ let shouldOptimisticallyUpdateByStatus ;
11528+ const status = currentSearchQueryJSON . status ;
11529+ if ( Array . isArray ( status ) ) {
11530+ shouldOptimisticallyUpdateByStatus = status . some ( ( val ) => {
11531+ const expenseStatus = val as ValueOf < typeof CONST . SEARCH . STATUS . EXPENSE > ;
11532+ return expenseReportStatusFilterMapping [ expenseStatus ] ( iouReport ) ;
11533+ } ) ;
11534+ } else {
11535+ const expenseStatus = status as ValueOf < typeof CONST . SEARCH . STATUS . EXPENSE > ;
11536+ shouldOptimisticallyUpdateByStatus = expenseReportStatusFilterMapping [ expenseStatus ] ( iouReport ) ;
11537+ }
11538+
11539+ if ( ! shouldOptimisticallyUpdateByStatus ) {
11540+ return false ;
11541+ }
11542+
11543+ const submitQueryString = getTodoSearchQuery ( CONST . SEARCH . SEARCH_LIST . SUBMIT , userAccountID ) ;
11544+
11545+ const submitQueryJSON = buildSearchQueryJSON ( submitQueryString ) ;
11546+
11547+ const approveQueryString = getTodoSearchQuery ( CONST . SEARCH . SEARCH_LIST . APPROVE , userAccountID ) ;
11548+ const approveQueryJSON = buildSearchQueryJSON ( approveQueryString ) ;
11549+
11550+ const validSearchTypes =
11551+ ( ! isInvoice && currentSearchQueryJSON . type === CONST . SEARCH . DATA_TYPES . EXPENSE ) || ( isInvoice && currentSearchQueryJSON . type === CONST . SEARCH . DATA_TYPES . INVOICE ) ;
11552+
11553+ return (
11554+ shouldOptimisticallyUpdateByStatus &&
11555+ validSearchTypes &&
11556+ ( currentSearchQueryJSON . flatFilters . length === 0 || [ submitQueryJSON ?. hash , approveQueryJSON ?. hash ] . includes ( currentSearchQueryJSON . hash ) )
11557+ ) ;
11558+ }
11559+
1150611560function getSearchOnyxUpdate ( {
1150711561 participant,
1150811562 transaction,
@@ -11517,11 +11571,7 @@ function getSearchOnyxUpdate({
1151711571 const currentSearchQueryJSON = getCurrentSearchQueryJSON ( ) ;
1151811572
1151911573 if ( currentSearchQueryJSON && toAccountID != null && fromAccountID != null ) {
11520- const validSearchTypes =
11521- ( ! isInvoice && currentSearchQueryJSON . type === CONST . SEARCH . DATA_TYPES . EXPENSE ) || ( isInvoice && currentSearchQueryJSON . type === CONST . SEARCH . DATA_TYPES . INVOICE ) ;
11522- const shouldOptimisticallyUpdate = currentSearchQueryJSON . status === CONST . SEARCH . STATUS . EXPENSE . ALL && validSearchTypes && currentSearchQueryJSON . flatFilters . length === 0 ;
11523-
11524- if ( shouldOptimisticallyUpdate ) {
11574+ if ( shouldOptimisticallyUpdateSearch ( currentSearchQueryJSON , iouReport , isInvoice ) ) {
1152511575 const isOptimisticToAccountData = isOptimisticPersonalDetail ( toAccountID ) ;
1152611576 const successData = [ ] ;
1152711577 if ( isOptimisticToAccountData ) {
0 commit comments