import { ReactNode } from 'react'; import { AccountBase, AccountFilterOption, AuthParams, BulkUploadResultsTab, BulkUploadSelectorData, BulkUploadSortKey, COTTransactionTrackingByTransactionId, ClassBase, ClassFilterOption, CompletedSubTab, CustomerBase, Entity, ExpenseAutomationJESchedulesViewUIState, ExpenseAutomationMissingReceiptsViewUIState, ExpenseAutomationReconciliationViewTab, ExpenseAutomationStepDetails, ExpenseAutomationTransactionsTab, ExpenseAutomationTransactionsViewUIState, ExpenseAutomationViewSelector, ExpenseAutomationViewType, FetchState, FluxAnalysisActionType, FluxAnalysisSectionType, FluxAnalysisViewUIState, ID, JEScheduleTransactionKey, LoggedInUser, MissingReceiptsTab, MonthYearPeriod, PageToken, PlaidLinkTokenType, RecommendationWithCOT, ReconReconcileSortKey, ReconReviewSortKey, ReconciliationReviewTabLocalData, SaveExpenseAutomationReconciliationActionType, ScheduleTypes, SortOrder, SupportedTransactionPayload, SupportedTransactionWithCOT, TransactionEntityType, TransactionFilters, TransactionGroup, TransactionID, TransactionType, Vendor, VendorBase, ZeniAPIStatus } from '@zeniai/client-epic-state'; import { AutoCompleteActions, AutoCompleteData } from '../common/autoComplete/autoCompleteProps'; import { ReportTreeScrollPosition } from '../reportTree/ReportTree'; import { ExpenseAutomationThreadClickTarget } from './components/ExpenseAutomationCommentingShell'; import { MonthEndReportPageProps } from './components/TableSection'; import { FormData as JEScheduleAccountSettingsFormData } from './sections/jeSchedules/JEScheduleAccountSettings'; import { JEScheduleResolveComponentFormData } from './sections/jeSchedules/JEScheduleResolveComponent'; import { TransferDrawerTransactionData } from './sections/transactionCategorization/transactionCategorizationTypes'; /** * Component & its Props */ export interface ExpenseAutomationPageProps extends MonthEndReportPageProps { authParams: AuthParams; companyId: ID; expenseAutomationViewSelector: ExpenseAutomationViewSelector; isAccountingClassesEnabled: boolean; isCOTEnabled: boolean; isDisabled: boolean; isJEScheduleCOTEnabled: boolean; isProjectsTransactionsEnabled: boolean; isRealtimeInsightsFeatureEnabled: boolean; isReconV3Enabled: boolean; isTransactionActivityEnabled: boolean; receiptUploadEndpoint: string; selectedTransactionGroup: TransactionGroup; vendorSearchAutoCompleteActions: AutoCompleteActions; vendorSearchAutoCompleteData: AutoCompleteData; /** Accounts from getAllAccounts(accountState) for Payment Account Name/Type filter dropdowns */ accountsForFilters?: AccountFilterOption[]; bulkUploadEndpoint?: string; bulkUploadSelector?: BulkUploadSelectorData; /** Options for the Category filter dropdown (converted to { label: accountName, value: accountId }) */ categoryOptions?: Array<{ accountId?: string; accountName?: string; }>; /** * Class options for the Class filter dropdown. Uses the narrow * `ClassFilterOption` ({classId, className}) — only the identity and the * display label are needed here. Passing the full `ClassBase` would be a * loose contract that lets consumers accidentally rely on fields that the * upstream selector strips out. */ classesForFilters?: ClassFilterOption[]; /** Initial receipts sub-tab (e.g. Storybook: show Unmatched without clicking tabs). */ initialMissingReceiptsTab?: MissingReceiptsTab; isAiCfoAccessEnabled?: boolean; /** * Statsig `is_create_transfer_entry_from_expense_enabled`. When false the TC list * row renders only the type pill (no clickable dropdown); when true the dropdown * is interactive on accounts that allow Transfer/Credit-card payment. */ isCreateTransferEntryFromExpenseEnabled?: boolean; /** Gates close-management commenting across the 4 tabs. */ isExpenseAutomationCommentingEnabled?: boolean; /** Transaction categorization only: when true, the right rail is expanded. */ isRightPanelOpen?: boolean; loggedInUser?: LoggedInUser; panelContent?: ReactNode; receiptsEmail?: string; /** * Transaction categorization only: inline right rail (activity or transfer panel body). */ rightSidePanel?: ReactNode; sidePanelIsFullView?: boolean; sidePanelIsOpen?: boolean; sidePanelListPercent?: number; transactionAttachmentsEndpoint?: string; clearJeScheduleLocalData: () => void; fetchFluxViewOnScroll: (selectedPeriod: MonthYearPeriod, pageToken: PageToken) => void; handleJeScheduleClick: (jeScheduleId: ID, jeScheduleKey: JEScheduleTransactionKey, jeScheduleType: ScheduleTypes) => void; ignoreRecommendedJeSchedule: (jeScheduleTransactionKey: JEScheduleTransactionKey, scheduleType: ScheduleTypes) => void; markAsReview: (opExRowId: ID[], action: FluxAnalysisActionType, selectedPeriod: MonthYearPeriod, isBulkAction?: boolean) => void; onAddStatementClick: (accountId: ID) => void; onBack: () => void; onBackClick: () => void; onClose: () => void; onEstablishConnectionClick: (accountId: ID, publicToken: ID) => void; onExcludeAccountFromReconciliation: (accountId: ID) => void; onFetchFluxViewList: () => void; onFetchLinkTokenClick: (plaidLinkTokenType: PlaidLinkTokenType) => void; onFetchMissingReceiptsList: () => void; onFetchRecommendationsForEntityCategorization: (amount: number, transactionDetails: { lineIds: ID[]; transaction: SupportedTransactionWithCOT; transactionId: TransactionID; }, isBulkFetch: boolean, selectedTab: ExpenseAutomationTransactionsTab, entity?: Entity, updatedVendor?: VendorBase) => void; onFetchRecommendationsForEntityCategorizationWithCustomer: (amount: number, transactionDetails: { lineIds: ID[]; transaction: SupportedTransactionWithCOT; transactionId: TransactionID; }, isBulkFetch: boolean, selectedTab: ExpenseAutomationTransactionsTab, entity?: Entity, updatedCustomer?: CustomerBase) => void; onFetchReimbursementView: (selectedPeriod: MonthYearPeriod, pageToken: PageToken, keepExistingListItems: boolean) => void; onFetchTransactionCategorizationList: (selectedTab: ExpenseAutomationTransactionsTab, searchString?: string, keepExistingListItems?: boolean, pageToken?: PageToken, refreshInBackground?: boolean, resetListItems?: boolean) => void; onFiltersChange: (filters: TransactionFilters) => void; onIncludeAccountIntoReconciliation: (accountId: ID) => void; onJeAccountSettingsChange: (formData: JEScheduleAccountSettingsFormData) => void; onJESchedulesFormDataChange: (scheduleJournalEntryID: ID, localData: JEScheduleResolveComponentFormData) => void; onMissingReceiptsRowClick: (transactionId: ID, transactionType: TransactionType) => void; onPostJESchedule: (scheduledJournalEntryID: ID, jeScheduleTransactionKey: JEScheduleTransactionKey) => void; onReconListPageScroll: (scrollPosition: ReportTreeScrollPosition) => void; onReconMatchedTransactionClick: (transactionId: ID) => void; onReconNodeCollapseToggled: (nodeId: ID, collapsed: boolean) => void; onReconReviewTabColumnSortConfigChanged: (sortKey: ReconReviewSortKey, sortOrder: SortOrder) => void; onReconTabColumnSortConfigChanged: (sortKey: ReconReconcileSortKey, sortOrder: SortOrder) => void; onReconTabUpdate: (tab: ExpenseAutomationReconciliationViewTab) => void; onRefresh: () => void; onReloadPage: () => void; onReloadReconciliationListPage: () => void; onReviewClicked: (accountId: string) => void; onSaveJeAccountSettingsClick: (formData: JEScheduleAccountSettingsFormData) => void; onSaveReconciliation: (action: SaveExpenseAutomationReconciliationActionType) => void; onSaveReconciliationReview: (transactionId: ID) => void; onSaveUpdateTransactionCategorization: (selectedTab: ExpenseAutomationTransactionsTab, transactionsIds: ID[], cotTrackingByTransactionId: COTTransactionTrackingByTransactionId) => void; onSearchTextChanged: (searchText: string) => void; onTransactionCategorizationRowClick: (transactionId: ID, transactionType: TransactionType) => void; onTransactionGroupChange: (group: TransactionGroup) => void; onUpdateFluxAnalysisUIState: (uiState: Partial) => void; onUpdateJESchedulesUIState: (uiState: Partial) => void; onUpdateMissingReceiptsUIState: (uiState: Partial) => void; onUpdateReconcileTabLocalData: (selectedTransactionIds: ID[]) => void; onUpdateScrollYOffSetTransactionCategorizationUIState: (selectedTab: ExpenseAutomationTransactionsTab, uiState: Partial) => void; onUpdateSelectedCheckboxTransactionIds: (selectedTab: ExpenseAutomationTransactionsTab, transactionIds: ID[]) => void; onUpdateStep: (step: ExpenseAutomationViewType) => void; onUpdateTab: (tab: ExpenseAutomationTransactionsTab) => void; onUpdateTransactionCategorizationCompletedSubTab: (subTab: CompletedSubTab) => void; onUpdateTransactionCategorizationUIState: (selectedTab: ExpenseAutomationTransactionsTab, uiState: Partial) => void; onUploadReceiptAttachment: (transaction: SupportedTransactionPayload) => void; onUploadReceiptComplete: (transactionPayload: SupportedTransactionPayload, selectedPeriod: MonthYearPeriod) => void; onUploadReceiptFetchStatus: (transactionId: ID, fetchState: FetchState, error?: ZeniAPIStatus, customErrorMessage?: string) => void; onUploadTransactionReceipt: (selectedTab: ExpenseAutomationTransactionsTab, transactionId: ID, transactionType: string, files: Blob[], fileNames: string[]) => void; onVendorAutoCompleteInputChange: (inputValue: string, entity: TransactionEntityType) => void; redirectToVendorDetailPage: (vendor: Vendor) => void; resetTransactionCategorizationLocalData: (selectedTab: ExpenseAutomationTransactionsTab, transactionIds: ID[], selectedPeriod: MonthYearPeriod, keepExistingData: boolean, totalCount: number, lineItemsByTransactionIds: Record, pageToken?: PageToken) => void; setActivityLogTransactionId: (transactionId: ID | undefined) => void; setLocalDataForCategoryAndClass: (selectedTab: ExpenseAutomationTransactionsTab, transactionId: ID, lineId: ID, transactions: SupportedTransactionWithCOT[], vendorId?: ID, customerId?: ID, selectedAccount?: AccountBase, selectedClassBase?: ClassBase, selectedVendor?: Entity, recommendations?: RecommendationWithCOT[], isAccountingClassesEnabled?: boolean) => void; setOpenDrawerClicked: (accountId: ID) => void; updateOperatingExpensesIdsForReview: (operatingExpenseIds: ID[]) => void; updateReconReviewTabLocalData: (localData: ReconciliationReviewTabLocalData, transactionId: ID, shouldFetchVendor: boolean) => void; updateSectionCollapseStatus: (status: { generalExpense: boolean; reimbursement: boolean; }) => void; updateSectionIdsForReview: (sectionIds: FluxAnalysisSectionType[]) => void; updateSelectedVendorForTransaction: (selectedTab: ExpenseAutomationTransactionsTab, transactionId: ID, lineId: ID, selectedTransaction: SupportedTransactionWithCOT, updatedVendor?: VendorBase) => void; /** * When set (e.g. from `withTransactionSidePanel` in the host app), closing the transaction * quick-view / side panel on Missing Receipts sub-tab changes avoids a stale panel over Unmatched * or Completed lists. */ closeSidePanel?: () => void; onAccountExclude?: (accountId: ID) => void; onAccountInclude?: (accountId: ID) => void; onAskAiCfoClick?: () => void; /** Resets Redux after a successful manual match so the next confirm can run (clears Completed). */ onBulkUploadConfirmMatchAcknowledged?: () => void; onBulkUploadError?: (message: string) => void; onBulkUploadFiles?: (files: File[]) => void; onBulkUploadProgress?: (percent: number) => void; onBulkUploadSuccess?: (batchId: string) => void; /** Sync Redux `uploadedFileCount` when using direct HTTP bulk upload (no `onBulkUploadFiles`). */ onBulkUploadUploadedFileCount?: (count: number) => void; onClearBulkUpload?: () => void; onClearBulkUploadBatchDetailsForScopeChange?: () => void; /** Clears one-shot Redux flag after switching Missing Receipts sub-tab (e.g. Unmatched on batch complete). */ onClearMissingReceiptsTabNavigation?: () => void; onConfirmBulkUploadMatch?: (batchId: ID, attachmentId: ID, transactionId: ID, transactionType: string, fileName: string) => void; onDeleteUnmatchedReceipt?: (attachmentId: ID) => void; onExpenseAutomationCommentingThreadClick?: (target: ExpenseAutomationThreadClickTarget) => void; onFetchBulkUploadBatches?: (input?: { cacheOverride?: boolean; invalidateBatchDetailsCache?: boolean; }) => void; onFetchCompletedTransactions?: (pageToken?: string, cacheOverride?: boolean) => void; onFetchMoreBatchDetails?: () => void; onLoadMoreManualSearch?: () => void; /** Inline transfer rail (TC): opens from list row; host renders `ReviewConfirmTransferPanel`. */ onOpenTransferRightPanel?: (data: TransferDrawerTransactionData) => void; onResetBulkUploadSort?: () => void; onSearchTransactionsForManualMatch?: (query: string, pageToken?: string | null) => void; onSetBulkUploadCompletedSubTab?: (tab: CompletedSubTab) => void; onSetBulkUploadResultsTab?: (tab: BulkUploadResultsTab) => void; onSetBulkUploadSortConfig?: (sortKey: BulkUploadSortKey, sortOrder: SortOrder) => void; } declare const ExpenseAutomationPage: (props: ExpenseAutomationPageProps) => import("react/jsx-runtime").JSX.Element; export default ExpenseAutomationPage; export declare function getNextAndPreviousSteps(allSteps: ExpenseAutomationStepDetails[], currentStep: ExpenseAutomationViewType): { nextStep: ExpenseAutomationStepDetails | undefined; previousStep: ExpenseAutomationStepDetails | undefined; }; export declare const uniqueFormName: (sectionId: ID) => `${string}_form`;