diff --git a/assets/images/integrationicons/bill-com-icon-square.svg b/assets/images/integrationicons/bill-com-icon-square.svg
new file mode 100644
index 000000000000..ef1a5c7b44f8
--- /dev/null
+++ b/assets/images/integrationicons/bill-com-icon-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/integrationicons/certinia-icon-square.svg b/assets/images/integrationicons/certinia-icon-square.svg
new file mode 100644
index 000000000000..f429ac4d2fc8
--- /dev/null
+++ b/assets/images/integrationicons/certinia-icon-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/integrationicons/zenefits-icon-square.svg b/assets/images/integrationicons/zenefits-icon-square.svg
new file mode 100644
index 000000000000..2d9ecabfc88d
--- /dev/null
+++ b/assets/images/integrationicons/zenefits-icon-square.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/table.svg b/assets/images/table.svg
index 90a4224765fc..876fb4e88c5d 100644
--- a/assets/images/table.svg
+++ b/assets/images/table.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/cspell.json b/cspell.json
index 00e61e76bda5..13c585b5b0cb 100644
--- a/cspell.json
+++ b/cspell.json
@@ -244,6 +244,7 @@
"falso",
"favicons",
"Ferroalloy",
+ "FinancialForce",
"firebaselogging",
"firstname",
"Fiscale",
diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index 66273a3408f7..4abc43ec4ba4 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -389,6 +389,18 @@ const CONST = {
MAX_LENGTH: 83,
},
+ EXPORT_LABELS: {
+ NETSUITE: 'NetSuite',
+ QBO: 'QuickBooks Online',
+ QBD: 'QuickBooks Desktop',
+ XERO: 'Xero',
+ INTACCT: 'Intacct',
+ SAGE_INTACCT: 'Sage Intacct',
+ CERTINIA: 'FinancialForce',
+ BILLCOM: 'Bill.com',
+ ZENEFITS: 'Zenefits',
+ },
+
REVERSED_TRANSACTION_ATTRIBUTE: 'is-reversed-transaction',
HIDDEN_MESSAGE_ATTRIBUTE: 'is-hidden-message',
@@ -6726,6 +6738,7 @@ const CONST = {
STATUS: this.TABLE_COLUMNS.STATUS,
TITLE: this.TABLE_COLUMNS.TITLE,
AMOUNT: this.TABLE_COLUMNS.TOTAL_AMOUNT,
+ EXPORTED_TO: this.TABLE_COLUMNS.EXPORTED_TO,
ACTION: this.TABLE_COLUMNS.ACTION,
},
EXPENSE_REPORT: {
@@ -6743,6 +6756,7 @@ const CONST = {
REPORT_ID: this.TABLE_COLUMNS.REPORT_ID,
BASE_62_REPORT_ID: this.TABLE_COLUMNS.BASE_62_REPORT_ID,
AMOUNT: this.TABLE_COLUMNS.TOTAL,
+ EXPORTED_ICON: this.TABLE_COLUMNS.EXPORTED_TO,
ACTION: this.TABLE_COLUMNS.ACTION,
},
INVOICE: {},
@@ -6860,6 +6874,7 @@ const CONST = {
REPORT_ID: 'reportID',
BASE_62_REPORT_ID: 'base62ReportID',
TAX: 'tax',
+ EXPORTED_TO: 'exportedto',
EXCHANGE_RATE: 'exchangeRate',
REIMBURSABLE_TOTAL: 'reimbursableTotal',
NON_REIMBURSABLE_TOTAL: 'nonReimbursableTotal',
diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts
index aec8abbfecec..de9aac04070e 100644
--- a/src/components/Icon/Expensicons.ts
+++ b/src/components/Icon/Expensicons.ts
@@ -90,6 +90,8 @@ import ImageCropCircleMask from '@assets/images/image-crop-circle-mask.svg';
import ImageCropSquareMask from '@assets/images/image-crop-square-mask.svg';
import Inbox from '@assets/images/inbox.svg';
import Info from '@assets/images/info.svg';
+import BillComSquare from '@assets/images/integrationicons/bill-com-icon-square.svg';
+import CertiniaSquare from '@assets/images/integrationicons/certinia-icon-square.svg';
import CircleSlash from '@assets/images/integrationicons/circle-slash.svg';
import NetSuiteExport from '@assets/images/integrationicons/export/netsuite-icon.svg';
import QBOExport from '@assets/images/integrationicons/export/qbo-icon.svg';
@@ -106,6 +108,7 @@ import SapSquare from '@assets/images/integrationicons/sap-icon-square.svg';
import Uber from '@assets/images/integrationicons/uber.svg';
import XeroCircle from '@assets/images/integrationicons/xero-icon-circle.svg';
import XeroSquare from '@assets/images/integrationicons/xero-icon-square.svg';
+import ZenefitsSquare from '@assets/images/integrationicons/zenefits-icon-square.svg';
import InvoiceGeneric from '@assets/images/invoice-generic.svg';
import Invoice from '@assets/images/invoice.svg';
import LinkCopy from '@assets/images/link-copy.svg';
@@ -360,4 +363,7 @@ export {
XeroExport,
ArrowCircleClockwise,
PlusCircle,
+ BillComSquare,
+ CertiniaSquare,
+ ZenefitsSquare,
};
diff --git a/src/components/Icon/chunks/expensify-icons.chunk.ts b/src/components/Icon/chunks/expensify-icons.chunk.ts
index 50db48729da6..14ca823c177c 100644
--- a/src/components/Icon/chunks/expensify-icons.chunk.ts
+++ b/src/components/Icon/chunks/expensify-icons.chunk.ts
@@ -111,6 +111,8 @@ import ImageCropCircleMask from '@assets/images/image-crop-circle-mask.svg';
import ImageCropSquareMask from '@assets/images/image-crop-square-mask.svg';
import Inbox from '@assets/images/inbox.svg';
import Info from '@assets/images/info.svg';
+import BillComSquare from '@assets/images/integrationicons/bill-com-icon-square.svg';
+import CertiniaSquare from '@assets/images/integrationicons/certinia-icon-square.svg';
import CircleSlash from '@assets/images/integrationicons/circle-slash.svg';
import NetSuiteExport from '@assets/images/integrationicons/export/netsuite-icon.svg';
import QBOExport from '@assets/images/integrationicons/export/qbo-icon.svg';
@@ -127,6 +129,7 @@ import SapSquare from '@assets/images/integrationicons/sap-icon-square.svg';
import Uber from '@assets/images/integrationicons/uber.svg';
import XeroCircle from '@assets/images/integrationicons/xero-icon-circle.svg';
import XeroSquare from '@assets/images/integrationicons/xero-icon-square.svg';
+import ZenefitsSquare from '@assets/images/integrationicons/zenefits-icon-square.svg';
import InvoiceGeneric from '@assets/images/invoice-generic.svg';
import Invoice from '@assets/images/invoice.svg';
import Key from '@assets/images/key.svg';
@@ -249,6 +252,7 @@ const Expensicons = {
Bank,
CircularArrowBackwards,
Bill,
+ BillComSquare,
Bell,
Binoculars,
Bolt,
@@ -260,6 +264,7 @@ const Expensicons = {
Camera,
Car,
Cash,
+ CertiniaSquare,
ChatBubble,
ChatBubbles,
Checkbox,
@@ -393,6 +398,7 @@ const Expensicons = {
ThreeDots,
Transfer,
Trashcan,
+ ZenefitsSquare,
Uber,
Unlock,
UpArrow,
diff --git a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx
index ac57da465d81..87b909b97ba5 100644
--- a/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx
+++ b/src/components/SelectionListWithSections/Search/ExpenseReportListItemRow.tsx
@@ -18,6 +18,7 @@ import CONST from '@src/CONST';
import type {Policy} from '@src/types/onyx';
import ActionCell from './ActionCell';
import DateCell from './DateCell';
+import ExportedIconCell from './ExportedIconCell';
import StatusCell from './StatusCell';
import TextCell from './TextCell';
import TotalCell from './TotalCell';
@@ -192,6 +193,11 @@ function ExpenseReportListItemRow({
),
+ [CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: (
+
+
+
+ ),
[CONST.SEARCH.TABLE_COLUMNS.ACTION]: (
+ {isExportedToCsv && (
+
+ )}
+ {isExportedToNetsuite && (
+
+ )}
+ {isExportedToXero && (
+
+ )}
+ {isExportedToIntacct && (
+
+ )}
+ {(isExportedToQuickbooksOnline || isExportedToQuickbooksDesktop) && (
+
+ )}
+ {isExportedToCertinia && (
+
+ )}
+ {isExportedToBillCom && (
+
+ )}
+ {isExportedToZenefits && (
+
+ )}
+
+ );
+}
+
+export default ExportedIconCell;
diff --git a/src/components/SelectionListWithSections/SearchTableHeader.tsx b/src/components/SelectionListWithSections/SearchTableHeader.tsx
index 429d66bf2a62..47e1e5b9a2c7 100644
--- a/src/components/SelectionListWithSections/SearchTableHeader.tsx
+++ b/src/components/SelectionListWithSections/SearchTableHeader.tsx
@@ -148,6 +148,11 @@ const getExpenseHeaders = (groupBy?: SearchGroupBy): SearchColumnConfig[] => [
translationKey: 'common.status',
canBeMissing: false,
},
+ {
+ columnName: CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO,
+ translationKey: 'search.exportedTo',
+ isColumnSortable: false,
+ },
{
columnName: CONST.SEARCH.TABLE_COLUMNS.ACTION,
translationKey: 'common.action',
@@ -187,6 +192,11 @@ const taskHeaders: SearchColumnConfig[] = [
translationKey: 'common.assignee',
canBeMissing: false,
},
+ {
+ columnName: CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO,
+ translationKey: 'search.exportedTo',
+ isColumnSortable: false,
+ },
{
columnName: CONST.SEARCH.TABLE_COLUMNS.ACTION,
translationKey: 'common.action',
@@ -258,6 +268,11 @@ const getExpenseReportHeaders = (profileIcon?: IconAsset): SearchColumnConfig[]
columnName: CONST.SEARCH.TABLE_COLUMNS.REPORT_ID,
translationKey: 'common.longID',
},
+ {
+ columnName: CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO,
+ translationKey: 'search.exportedTo',
+ isColumnSortable: false,
+ },
{
columnName: CONST.SEARCH.TABLE_COLUMNS.ACTION,
translationKey: 'common.action',
diff --git a/src/components/TransactionItemRow/index.tsx b/src/components/TransactionItemRow/index.tsx
index a495ee95300b..06c8d563debe 100644
--- a/src/components/TransactionItemRow/index.tsx
+++ b/src/components/TransactionItemRow/index.tsx
@@ -9,6 +9,7 @@ import RadioButton from '@components/RadioButton';
import type {SearchColumnType, TableColumnSize} from '@components/Search/types';
import ActionCell from '@components/SelectionListWithSections/Search/ActionCell';
import DateCell from '@components/SelectionListWithSections/Search/DateCell';
+import ExportedIconCell from '@components/SelectionListWithSections/Search/ExportedIconCell';
import StatusCell from '@components/SelectionListWithSections/Search/StatusCell';
import TextCell from '@components/SelectionListWithSections/Search/TextCell';
import AmountCell from '@components/SelectionListWithSections/Search/TotalCell';
@@ -562,6 +563,11 @@ function TransactionItemRow({
/>
),
+ [CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: (
+
+
+
+ ),
}),
[
StyleUtils,
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 80dcd2164157..0a7e6c50170a 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -6827,6 +6827,7 @@ Fordere Spesendetails wie Belege und Beschreibungen an, lege Limits und Standard
title: 'Export erstellen',
description: 'Wow, das sind viele Elemente! Wir bündeln sie, und Concierge sendet dir in Kürze eine Datei.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Alle passenden Elemente auswählen',
allMatchingItemsSelected: 'Alle passenden Elemente ausgewählt',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index d4d66599c6c0..fac987aae4fe 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -6683,6 +6683,7 @@ const translations = {
title: 'Create export',
description: "Whoa, that's a lot of items! We'll bundle them up, and Concierge will send you a file shortly.",
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Select all matching items',
allMatchingItemsSelected: 'All matching items selected',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index d75bcacdb7f0..0166d16e8781 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -6363,6 +6363,7 @@ ${amount} para ${merchant} - ${date}`,
title: 'Crear exportación',
description: '¡Wow, esos son muchos elementos! Los agruparemos y Concierge te enviará un archivo en breve.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Seleccionar todos los elementos coincidentes',
allMatchingItemsSelected: 'Todos los elementos coincidentes seleccionados',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index a98d3b427516..049066d73143 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -6837,6 +6837,7 @@ Exigez des informations de dépense comme les reçus et les descriptions, défin
title: 'Créer une exportation',
description: 'Ouah, ça fait beaucoup d’éléments ! Nous allons les regrouper, et Concierge vous enverra bientôt un fichier.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Sélectionner tous les éléments correspondants',
allMatchingItemsSelected: 'Tous les éléments correspondants sont sélectionnés',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 9a761598cfd9..35cec2602802 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -6810,6 +6810,7 @@ Richiedi dettagli di spesa come ricevute e descrizioni, imposta limiti e valori
title: 'Crea esportazione',
description: 'Wow, sono davvero tanti elementi! Li raggrupperemo e Concierge ti invierà un file a breve.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Seleziona tutti gli elementi corrispondenti',
allMatchingItemsSelected: 'Tutti gli elementi corrispondenti selezionati',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 28d56c69a6e5..8d7a17818256 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -6756,6 +6756,7 @@ ${reportName}
title: 'エクスポートを作成',
description: 'おっと、かなり多くのアイテムがありますね!まとめて整理してから、まもなくConciergeがファイルをお送りします。',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: '一致する項目をすべて選択',
allMatchingItemsSelected: '一致する項目をすべて選択済み',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 919cf4d608f4..c7ec04c1f873 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -6797,6 +6797,7 @@ Vraag verplichte uitgavedetails zoals bonnetjes en beschrijvingen, stel limieten
title: 'Export maken',
description: 'Wow, dat zijn veel items! We bundelen ze, en Concierge stuurt je binnenkort een bestand.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Selecteer alle overeenkomende items',
allMatchingItemsSelected: 'Alle overeenkomende items geselecteerd',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index e8de68789f50..815bc3f7fea3 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -6786,6 +6786,7 @@ Wymagaj szczegółów wydatków, takich jak paragony i opisy, ustawiaj limity i
title: 'Utwórz eksport',
description: 'Uff, to całkiem sporo pozycji! Spakujemy je, a Concierge wkrótce wyśle Ci plik.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Zaznacz wszystkie pasujące elementy',
allMatchingItemsSelected: 'Wybrano wszystkie pasujące elementy',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 03a5a38d879a..fd7534117bf8 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -6791,6 +6791,7 @@ Exija detalhes de despesas como recibos e descrições, defina limites e padrõe
title: 'Criar exportação',
description: 'Uau, são muitos itens! Vamos agrupá-los e o Concierge enviará um arquivo para você em breve.',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: 'Selecionar todos os itens correspondentes',
allMatchingItemsSelected: 'Todos os itens correspondentes selecionados',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 6f730225bab4..76dfe031fc99 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -6656,6 +6656,7 @@ ${reportName}
title: '创建导出',
description: '哇,项目真不少!我们会把它们打包好,Concierge 很快就会给你发送一个文件。',
},
+ exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: '选择所有匹配的项目',
allMatchingItemsSelected: '已选择所有匹配的项目',
diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts
index 6acc8bd6fec6..070e935a6aef 100644
--- a/src/libs/ReportActionsUtils.ts
+++ b/src/libs/ReportActionsUtils.ts
@@ -208,6 +208,10 @@ function isMoneyRequestAction(reportAction: OnyxInputOrEntry): rep
return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.IOU);
}
+function isExportedToIntegrationAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction {
+ return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION);
+}
+
function isReportPreviewAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction {
return isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW);
}
@@ -3596,6 +3600,7 @@ export {
isClosedAction,
isConsecutiveActionMadeByPreviousActor,
isConsecutiveChronosAutomaticTimerAction,
+ isExportedToIntegrationAction,
hasNextActionMadeBySameActor,
isCreatedAction,
isCreatedTaskReportAction,
diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts
index 38d07b3e3a9e..60abda7cae7c 100644
--- a/src/libs/SearchUIUtils.ts
+++ b/src/libs/SearchUIUtils.ts
@@ -2182,6 +2182,14 @@ function getSortedTransactionData(
});
}
+ if (sortBy === CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO) {
+ return data.sort((a, b) => {
+ const aValue = `${!!a.exported}`;
+ const bValue = `${!!b.exported}`;
+ return compareValues(aValue, bValue, sortOrder, sortBy, localeCompare);
+ });
+ }
+
const sortingProperty = transactionColumnNamesToSortingProperty[sortBy];
if (sortBy === CONST.SEARCH.TABLE_COLUMNS.POLICY_NAME) {
@@ -2349,6 +2357,14 @@ function getSortedReportData(
});
}
+ if (sortBy === CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO) {
+ return data.sort((a, b) => {
+ const aValue = `${!!a.exported}`;
+ const bValue = `${!!b.exported}`;
+ return compareValues(aValue, bValue, sortOrder, sortBy, localeCompare);
+ });
+ }
+
const sortingProperty = expenseReportColumnNamesToSortingProperty[sortBy];
if (!sortingProperty) {
@@ -2577,6 +2593,8 @@ function getSearchColumnTranslationKey(columnId: SearchCustomColumnIds): Transla
return 'common.total';
case CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID:
return 'common.reportID';
+ case CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO:
+ return 'search.exportedTo';
}
}
@@ -3067,6 +3085,7 @@ function getColumnsToShow(
[CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID]: false,
[CONST.SEARCH.TABLE_COLUMNS.REPORT_ID]: false,
[CONST.SEARCH.TABLE_COLUMNS.TITLE]: false,
+ [CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: false,
[CONST.SEARCH.TABLE_COLUMNS.STATUS]: false,
[CONST.SEARCH.TABLE_COLUMNS.TOTAL_AMOUNT]: true,
[CONST.SEARCH.TABLE_COLUMNS.ACTION]: true,
diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts
index 53469413b5fb..6b7e881f3226 100644
--- a/src/styles/utils/index.ts
+++ b/src/styles/utils/index.ts
@@ -1797,6 +1797,9 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
case CONST.SEARCH.TABLE_COLUMNS.ACTION:
columnWidth = {...getWidthStyle(variables.w80), ...styles.alignItemsCenter};
break;
+ case CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO:
+ columnWidth = {...getWidthStyle(variables.w72), ...styles.alignItemsCenter};
+ break;
case CONST.SEARCH.TABLE_COLUMNS.FEED:
case CONST.SEARCH.TABLE_COLUMNS.BANK_ACCOUNT:
case CONST.SEARCH.TABLE_COLUMNS.WITHDRAWAL_ID: