Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
217baa7
add exported icon
JS00001 Dec 17, 2025
4e3339f
lang updates
JS00001 Dec 17, 2025
7ff7db6
create exported icon cell
JS00001 Dec 17, 2025
7b16fec
add exported to the table and expense report
JS00001 Dec 17, 2025
5721986
add visibility
JS00001 Dec 17, 2025
5be35b0
add icons
JS00001 Dec 17, 2025
c9a1a6f
update sizing and avatars
JS00001 Dec 17, 2025
2320a64
sub to actions, add header for reports
JS00001 Dec 17, 2025
402f23a
rename to exportedto
JS00001 Dec 17, 2025
26099f7
add export labels
JS00001 Dec 17, 2025
9466416
add logic for the icons
JS00001 Dec 17, 2025
0ba4116
use some for errs
JS00001 Dec 17, 2025
79fac35
add new table svg
JS00001 Dec 17, 2025
7074e26
Merge branch 'main' of github.com:Expensify/App into jsenyitko-releas…
JS00001 Dec 17, 2025
28ef901
add tests
JS00001 Dec 17, 2025
b095524
add svg icons for bill certinia and trinet
JS00001 Dec 18, 2025
31fac34
add new icons
JS00001 Dec 18, 2025
6a7f6b6
update conditions for all items
JS00001 Dec 18, 2025
a9f15e5
update icons and conditions
JS00001 Dec 18, 2025
d3824bd
compress svgs, fix react compiler checks
JS00001 Dec 18, 2025
9450d82
fix cspell
JS00001 Dec 18, 2025
c94acd9
Merge branch 'main' of github.com:Expensify/App into jsenyitko-releas…
JS00001 Dec 18, 2025
ecd34cf
use exported for sorting
JS00001 Dec 18, 2025
106536c
Merge branch 'main' of github.com:Expensify/App into jsenyitko-releas…
JS00001 Dec 18, 2025
77659cd
Merge branch 'main' of github.com:Expensify/App into jsenyitko-releas…
JS00001 Dec 18, 2025
1b5ccfe
resolve conflicts
luacmartins Dec 18, 2025
89dc41f
more conflicts
luacmartins Dec 18, 2025
b6f6cf9
update column size
luacmartins Dec 18, 2025
348fa9a
Merge branch 'main' into jsenyitko-release-4-exported
luacmartins Dec 18, 2025
e326ba5
center icons
luacmartins Dec 18, 2025
5dcb487
resolve conflicts
luacmartins Dec 18, 2025
1383cb8
fix sort
luacmartins Dec 18, 2025
ca9478c
update lable
luacmartins Dec 18, 2025
50f72db
coalesce amount
luacmartins Dec 18, 2025
2698471
Revert "coalesce amount"
luacmartins Dec 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/images/integrationicons/bill-com-icon-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/integrationicons/certinia-icon-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/integrationicons/zenefits-icon-square.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion assets/images/table.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
"falso",
"favicons",
"Ferroalloy",
"FinancialForce",
"firebaselogging",
"firstname",
"Fiscale",
Expand Down
15 changes: 15 additions & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',

Expand Down Expand Up @@ -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: {
Expand All @@ -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: {},
Expand Down Expand Up @@ -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',
Expand Down
6 changes: 6 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -360,4 +363,7 @@ export {
XeroExport,
ArrowCircleClockwise,
PlusCircle,
BillComSquare,
CertiniaSquare,
ZenefitsSquare,
};
6 changes: 6 additions & 0 deletions src/components/Icon/chunks/expensify-icons.chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -249,6 +252,7 @@ const Expensicons = {
Bank,
CircularArrowBackwards,
Bill,
BillComSquare,
Bell,
Binoculars,
Bolt,
Expand All @@ -260,6 +264,7 @@ const Expensicons = {
Camera,
Car,
Cash,
CertiniaSquare,
ChatBubble,
ChatBubbles,
Checkbox,
Expand Down Expand Up @@ -393,6 +398,7 @@ const Expensicons = {
ThreeDots,
Transfer,
Trashcan,
ZenefitsSquare,
Uber,
Unlock,
UpArrow,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -192,6 +193,11 @@ function ExpenseReportListItemRow({
<TextCell text={item.reportID === CONST.REPORT.UNREPORTED_REPORT_ID ? '' : getBase62ReportID(Number(item.reportID))} />
</View>
),
[CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: (
<View style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO)]}>
<ExportedIconCell reportID={item.reportID} />
</View>
),
[CONST.SEARCH.TABLE_COLUMNS.ACTION]: (
<View style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.ACTION)]}>
<ActionCell
Expand Down
115 changes: 115 additions & 0 deletions src/components/SelectionListWithSections/Search/ExportedIconCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React from 'react';
import {View} from 'react-native';
import Avatar from '@components/Avatar';
import Icon from '@components/Icon';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useOnyx from '@hooks/useOnyx';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {getOriginalMessage, isExportedToIntegrationAction} from '@libs/ReportActionsUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

type ExportedIconCellProps = {
reportID?: string;
};

function ExportedIconCell({reportID}: ExportedIconCellProps) {
const theme = useTheme();
const styles = useThemeStyles();
const reportActions = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true});
Comment thread
JS00001 marked this conversation as resolved.
const icons = useMemoizedLazyExpensifyIcons(['NetSuiteSquare', 'XeroSquare', 'IntacctSquare', 'QBOSquare', 'Table', 'ZenefitsSquare', 'BillComSquare', 'CertiniaSquare']);

const actions = Object.values(reportActions[0] ?? {});

let isExportedToCsv = false;
let isExportedToNetsuite = false;
let isExportedToXero = false;
let isExportedToIntacct = false;
let isExportedToQuickbooksOnline = false;
let isExportedToQuickbooksDesktop = false;
let isExportedToCertinia = false;
let isExportedToBillCom = false;
let isExportedToZenefits = false;

for (const action of actions) {
if (action.actionName === CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_CSV) {
isExportedToCsv = true;
}

if (isExportedToIntegrationAction(action)) {
const label = getOriginalMessage(action)?.label;
Comment on lines +40 to +41

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from the #78226 checklist: when an export template is created on OldDot or when exporting “All Data,” we should verify it using the action type EXPORT_TEMPLATE and mark it as isExportedToCsv.

isExportedToXero = isExportedToXero || label === CONST.EXPORT_LABELS.XERO;
isExportedToIntacct = isExportedToIntacct || label === CONST.EXPORT_LABELS.INTACCT;
isExportedToNetsuite = isExportedToNetsuite || label === CONST.EXPORT_LABELS.NETSUITE;
isExportedToQuickbooksOnline = isExportedToQuickbooksOnline || label === CONST.EXPORT_LABELS.QBO;
isExportedToQuickbooksDesktop = isExportedToQuickbooksDesktop || label === CONST.EXPORT_LABELS.QBD;
isExportedToZenefits = isExportedToZenefits || label === CONST.EXPORT_LABELS.ZENEFITS;
isExportedToBillCom = isExportedToBillCom || label === CONST.EXPORT_LABELS.BILLCOM;
isExportedToCertinia = isExportedToCertinia || label === CONST.EXPORT_LABELS.CERTINIA;
}
}

return (
<View style={[styles.flexRow, styles.gap2]}>
{isExportedToCsv && (
<Icon
src={icons.Table}
fill={theme.icon}
small
/>
)}
{isExportedToNetsuite && (
<Avatar
source={icons.NetSuiteSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{isExportedToXero && (
<Avatar
source={icons.XeroSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{isExportedToIntacct && (
<Avatar
source={icons.IntacctSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{(isExportedToQuickbooksOnline || isExportedToQuickbooksDesktop) && (
<Avatar
source={icons.QBOSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{isExportedToCertinia && (
<Avatar
source={icons.CertiniaSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{isExportedToBillCom && (
<Avatar
source={icons.BillComSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
{isExportedToZenefits && (
<Avatar
source={icons.ZenefitsSquare}
type={CONST.ICON_TYPE_AVATAR}
size={CONST.AVATAR_SIZE.MID_SUBSCRIPT}
/>
)}
</View>
);
}

export default ExportedIconCell;
15 changes: 15 additions & 0 deletions src/components/SelectionListWithSections/SearchTableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down
6 changes: 6 additions & 0 deletions src/components/TransactionItemRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -562,6 +563,11 @@ function TransactionItemRow({
/>
</View>
),
[CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: (
<View style={[StyleUtils.getReportTableColumnStyles(CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO)]}>
<ExportedIconCell reportID={transactionItem.reportID} />
</View>
),
}),
[
StyleUtils,
Expand Down
1 change: 1 addition & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6756,6 +6756,7 @@ ${reportName}
title: 'エクスポートを作成',
description: 'おっと、かなり多くのアイテムがありますね!まとめて整理してから、まもなくConciergeがファイルをお送りします。',
},
exportedTo: 'Exported to',
exportAll: {
selectAllMatchingItems: '一致する項目をすべて選択',
allMatchingItemsSelected: '一致する項目をすべて選択済み',
Expand Down
1 change: 1 addition & 0 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Loading
Loading