@@ -7,7 +7,7 @@ import {useOpenSearchReportSubmitToPopover} from '@components/ReportSubmitToPopo
77import { useSearchQueryContext , useSearchResultsContext , useSearchSelectionActions , useSearchSelectionContext } from '@components/Search/SearchContext' ;
88import type { BulkPaySelectionData , PaymentData , SearchColumnType , SearchFilterKey , SearchQueryJSON , SelectedReports , SelectedTransactions } from '@components/Search/types' ;
99
10- import { getAccountingIntegrationDisplayName } from '@libs/AccountingUtils' ;
10+ import { getAccountingIntegrationDisplayName , getExportLabelForConnection } from '@libs/AccountingUtils' ;
1111import { getExpensifyCardStatementPDF } from '@libs/actions/CompanyCards' ;
1212import { exportReceiptsToZip , exportReportsToPDF } from '@libs/actions/Export' ;
1313import { unholdRequest } from '@libs/actions/IOU/Hold' ;
@@ -1782,21 +1782,33 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
17821782 return reportExportOptions . includes ( exportOption ) ;
17831783 } ;
17841784
1785- // Group the selected reports by their connected accounting integration. A single-workspace
1785+ // Group the selected reports by their connected accounting integration / product . A single-workspace
17861786 // selection collapses to one group (unchanged behavior), while a multi-workspace selection
17871787 // surfaces one export + one "Mark as exported" option per integration, each scoped to the
1788- // reports that belong to it.
1789- const reportsByIntegration = new Map < NonNullable < ReturnType < typeof getConnectedIntegration > > , typeof selectedReports > ( ) ;
1788+ // reports that belong to it (e.g. QBO and IES workspaces form distinct groups).
1789+ const reportsByIntegration = new Map <
1790+ string ,
1791+ {
1792+ integration : NonNullable < ReturnType < typeof getConnectedIntegration > > ;
1793+ integrationPolicy : OnyxEntry < Policy > ;
1794+ reports : typeof selectedReports ;
1795+ }
1796+ > ( ) ;
17901797 if ( isReportsTab && selectedReportIDs . length > 0 && includeReportLevelExport ) {
17911798 for ( const report of selectedReports ) {
17921799 const reportPolicy = report . policyID ? policies ?. [ `${ ONYXKEYS . COLLECTION . POLICY } ${ report . policyID } ` ] : undefined ;
17931800 const reportIntegration = getConnectedIntegration ( reportPolicy ) ;
17941801 if ( ! reportIntegration ) {
17951802 continue ;
17961803 }
1797- const reportsForIntegration = reportsByIntegration . get ( reportIntegration ) ?? [ ] ;
1798- reportsForIntegration . push ( report ) ;
1799- reportsByIntegration . set ( reportIntegration , reportsForIntegration ) ;
1804+ const exportLabel = getExportLabelForConnection ( reportIntegration , reportPolicy ) ;
1805+ const group = reportsByIntegration . get ( exportLabel ) ?? {
1806+ integration : reportIntegration ,
1807+ integrationPolicy : reportPolicy ?? policy ,
1808+ reports : [ ] ,
1809+ } ;
1810+ group . reports . push ( report ) ;
1811+ reportsByIntegration . set ( exportLabel , group ) ;
18001812 }
18011813 }
18021814
@@ -1846,7 +1858,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
18461858 if ( companyIDs . size > 1 ) {
18471859 showConfirmModal ( {
18481860 title : translate ( 'workspace.exportDifferentCompaniesModal.title' ) ,
1849- prompt : translate ( 'workspace.exportDifferentCompaniesModal.description' , integration ) ,
1861+ prompt : translate ( 'workspace.exportDifferentCompaniesModal.description' , integration , connectionNameFriendly ) ,
18501862 confirmText : translate ( 'workspace.exportDifferentCompaniesModal.confirmText' ) ,
18511863 shouldShowCancelButton : false ,
18521864 } ) ;
@@ -1918,7 +1930,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
19181930 }
19191931
19201932 showConfirmModal ( {
1921- title : translate ( 'workspace.exportPartialModal.title' , integrationReportIDs . length , totalSelectedReportsCount , integration ) ,
1933+ title : translate ( 'workspace.exportPartialModal.title' , integrationReportIDs . length , totalSelectedReportsCount , integration , connectionNameFriendly ) ,
19221934 // Fixed subtitle describes the partial scope; the scrollable prompt lists the report names
19231935 // that will actually be exported for the chosen integration. A partial export can happen for
19241936 // two independent reasons: part of the selection belongs to other integrations, and/or some
@@ -1928,6 +1940,7 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
19281940 integration ,
19291941 integrationGroupSize < totalSelectedReportsCount ,
19301942 integrationReportIDs . length < integrationGroupSize ,
1943+ connectionNameFriendly ,
19311944 ) ,
19321945 prompt : exportableReportNames . join ( '\n' ) ,
19331946 confirmText : translate ( 'workspace.exportPartialModal.confirmText' , { count : integrationReportIDs . length } ) ,
@@ -1943,9 +1956,8 @@ function useSearchBulkActions({queryJSON}: UseSearchBulkActionsParams) {
19431956
19441957 // Group each integration's actions together, listing its "Export to <integration>" option
19451958 // immediately followed by its "Mark as exported" option, before moving on to the next integration.
1946- for ( const [ integration , reportsForIntegration ] of reportsByIntegration ) {
1959+ for ( const [ , { integration, integrationPolicy , reports : reportsForIntegration } ] of reportsByIntegration ) {
19471960 const integrationGroupSize = reportsForIntegration . length ;
1948- const integrationPolicy = reportsForIntegration . at ( 0 ) ?. policyID ? policies ?. [ `${ ONYXKEYS . COLLECTION . POLICY } ${ reportsForIntegration . at ( 0 ) ?. policyID } ` ] : policy ;
19491961 const connectionNameFriendly = getAccountingIntegrationDisplayName ( integrationPolicy , integration , translate ) ;
19501962 const integrationIcon = getIntegrationIcon ( integration , expensifyIcons ) ;
19511963
0 commit comments