@zeniai/client-epic-state 4.19.99-betaAD01 → 4.19.99-betaAD07

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.d.ts +19 -0
  2. package/lib/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +2 -0
  3. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +9 -6
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.js +36 -2
  5. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -2
  6. package/lib/entity/jeSchedules/jeSchedulesSelector.js +5 -2
  7. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +26 -2
  8. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +4 -1
  9. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  10. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +1 -0
  11. package/lib/esm/common/aiCfo/aiCfoSuggestedQuestionsPageContext.js +1 -0
  12. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +36 -2
  13. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +5 -2
  14. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  15. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  16. package/lib/esm/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  17. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +13 -3
  18. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +11 -3
  19. package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  20. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -6
  21. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +1 -0
  22. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -8
  23. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +140 -59
  24. package/lib/index.d.ts +3 -3
  25. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  26. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +1 -1
  27. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +1 -1
  28. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +1 -1
  29. package/lib/view/aiCfoView/aiCfoViewState.d.ts +1 -4
  30. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  31. package/lib/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  32. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +13 -3
  33. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +11 -3
  34. package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  35. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +11 -5
  36. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  37. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +1 -0
  38. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -8
  39. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +140 -59
  40. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { AiCfoAnswerPayload, ChatSessionPayload } from '../../entity/aiCfo/aiCfoPayload';
2
2
  import { UserRolePayload } from '../../entity/userRole/userRolePayload';
3
3
  import { ZeniAPIResponse } from '../../responsePayload';
4
- import { AiCfoSuggestedQuestionsPageContext } from './aiCfoViewState';
4
+ import type { AiCfoSuggestedQuestionsPageContext } from '../../common/aiCfo/aiCfoSuggestedQuestionsPageContext';
5
5
  export type ContextStatus = 'NONE' | 'NOT_FOUND' | 'PERMISSION_DENIED' | 'SUCCESS';
6
6
  export interface CreateSessionResponseData {
7
7
  chat_session_id: string;
@@ -4,7 +4,7 @@ import { ChatSessionPayload } from '../../entity/aiCfo/aiCfoPayload';
4
4
  import { AiCfoAnswerResponseType } from '../../entity/aiCfo/aiCfoState';
5
5
  import { ZeniAPIStatus } from '../../responsePayload';
6
6
  import { ContextStatus } from './aiCfoViewPayload';
7
- import { AiCfoSuggestedQuestionsPageContext } from './aiCfoViewState';
7
+ import type { AiCfoSuggestedQuestionsPageContext } from '../../common/aiCfo/aiCfoSuggestedQuestionsPageContext';
8
8
  import { AiCfoViewState } from './aiCfoViewState';
9
9
  export declare const initialAiCfoViewState: AiCfoViewState;
10
10
  export declare const submitQuestion: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[sessionId: string, questionAnswerId: string, userId: string, questionId: string, createdAt: import("dayjs").Dayjs, question: string, files?: File[] | undefined], {
@@ -3,7 +3,7 @@ import { FetchStateAndError } from '../../commonStateTypes/common';
3
3
  import { SelectorView } from '../../commonStateTypes/viewAndReport/viewAndReport';
4
4
  import { AiCfoSelectorView } from '../../entity/aiCfo/aiCfoSelector';
5
5
  import { RootState } from '../../reducer';
6
- import { AiCfoSuggestedQuestionsPageContext } from './aiCfoViewState';
6
+ import type { AiCfoSuggestedQuestionsPageContext } from '../../common/aiCfo/aiCfoSuggestedQuestionsPageContext';
7
7
  import { AiCfoViewUIState, SuggestedQuestionsForPageContext } from './aiCfoViewState';
8
8
  export interface AiCfoViewSelector extends SelectorView, AiCfoSelectorView {
9
9
  createSessionAndSubmitState: FetchStateAndError;
@@ -1,3 +1,4 @@
1
+ import type { AiCfoSuggestedQuestionsPageContext } from '../../common/aiCfo/aiCfoSuggestedQuestionsPageContext';
1
2
  import { FetchStateAndError, ID } from '../../commonStateTypes/common';
2
3
  import { PageToken } from '../../commonStateTypes/viewAndReport/viewAndReport';
3
4
  import { ContextStatus } from './aiCfoViewPayload';
@@ -31,10 +32,6 @@ export interface AiCfoViewUIState {
31
32
  lastContextMessage?: string;
32
33
  lastContextStatus?: ContextStatus;
33
34
  }
34
- /**
35
- * Supported `page_context` values for GET .../suggested-questions and related UI state.
36
- */
37
- export type AiCfoSuggestedQuestionsPageContext = 'balance_sheet' | 'profit_loss' | 'vendors' | 'transactions' | 'cash_flow' | 'accounts_receivable' | 'accounts_payable' | 'transaction_details' | 'dashboard' | 'cash_balance' | 'card_balance' | 'command_centre' | 'je_schedules' | 'reconciliation' | 'flux_analysis' | 'receipts' | 'mei' | 'task_checklist' | 'performance' | 'bills_list' | 'bills_details' | 'reimbursement_list' | 'reimbursement_details' | 'vendors_summary' | 'opex_by_vendor' | 'prepaid_expenses' | 'fixed_assets' | 'form_1099' | 'accrued_expenses' | 'forecast' | 'checking' | 'checking_details' | 'treasury' | 'cards' | 'cards_detail' | 'people' | 'rewards' | 'notifications';
38
35
  export interface SuggestedQuestionsForPageContext extends FetchStateAndError {
39
36
  pageContext: AiCfoSuggestedQuestionsPageContext;
40
37
  suggestedQuestions: string[];
@@ -94,7 +94,6 @@ function getExpenseAutomationView(state) {
94
94
  const fetchStateVariables = [
95
95
  expenseAutomationMissingReceiptsViewState,
96
96
  expenseAutomationJESchedulesViewState,
97
- monthEndCloseChecksView,
98
97
  expenseAutomationTransactionsView,
99
98
  expenseAutomationReconciliationViewState,
100
99
  ];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getExpenseAutomationFluxAnalysisView = getExpenseAutomationFluxAnalysisView;
4
+ const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
4
5
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
5
6
  const accountSelector_1 = require("../../../entity/account/accountSelector");
6
7
  const classSelector_1 = require("../../../entity/class/classSelector");
@@ -9,7 +10,7 @@ const userSelector_1 = require("../../../entity/user/userSelector");
9
10
  const vendorSelector_1 = require("../../../entity/vendor/vendorSelector");
10
11
  const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
11
12
  function getExpenseAutomationFluxAnalysisView(state) {
12
- const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState } = state;
13
+ const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
13
14
  const { fetchState, error, refreshStatus, uiState, reviewOperatingExpenseIdsByPeriod, selectedSectionIdsByPeriod, groupsBySelectedPeriod, fluxAnalysisEntities, bulkReviewStatus, currency, totalBalancesAndVariance, } = expenseAutomationFluxAnalysisViewState;
14
15
  const fetchStateAndError = {
15
16
  fetchState,
@@ -94,10 +95,17 @@ function getExpenseAutomationFluxAnalysisView(state) {
94
95
  },
95
96
  };
96
97
  const completionStatus = fluxCompletionStatus != null ? fluxCompletionStatus : 'incomplete';
98
+ const monthEndFetchState = monthYearPeriodId != null
99
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
100
+ : { fetchState: 'Not-Started', error: undefined };
101
+ const reducedFetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
102
+ fetchStateAndError,
103
+ monthEndFetchState,
104
+ ]);
97
105
  return {
98
106
  sections,
99
107
  totalBalancesAndVariance,
100
- fetchStatus: fetchStateAndError,
108
+ fetchStatus: reducedFetchStatus,
101
109
  bulkReviewStatus,
102
110
  reviewOperatingExpensesIds,
103
111
  selectedSectionIds,
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getExpenseAutomationJESchedulesView = getExpenseAutomationJESchedulesView;
7
7
  const omit_1 = __importDefault(require("lodash/omit"));
8
8
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
9
+ const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
9
10
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
10
11
  const accountSelector_1 = require("../../../entity/account/accountSelector");
11
12
  const jeSchedulesSelector_1 = require("../../../entity/jeSchedules/jeSchedulesSelector");
@@ -25,6 +26,8 @@ function getJEScheduleSortAccessor(sortKey) {
25
26
  return (s) => s.jeDebit.account?.accountName?.toLowerCase();
26
27
  case 'class':
27
28
  return (s) => s.jeDebit.accountingClass?.className?.toLowerCase();
29
+ case 'depCategory':
30
+ return (s) => s.jeCredit.account?.accountName?.toLowerCase();
28
31
  case 'scheduleCategory':
29
32
  return (s) => s.jeScheduleType;
30
33
  case 'startMonth':
@@ -56,7 +59,7 @@ function sortJEScheduledTransactions(transactions, sortKey, sortOrder) {
56
59
  function getExpenseAutomationJESchedulesView(state) {
57
60
  const jeScheduledTransaction = [];
58
61
  const failedJeScheduledTransaction = [];
59
- const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, } = state;
62
+ const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
60
63
  const { jeScheduleTransactionKeysByPeriod, failedJeScheduleTransactionKeysByPeriod, jeScheduleLocalDataById, postStatusById, ignoreStatusById, uiState, error, fetchState, refreshStatus, } = expenseAutomationJESchedulesViewState;
61
64
  const accountSettingsView = (0, jeAccountSettingsViewSelector_1.getJEAccountSettingsView)(state);
62
65
  const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
@@ -122,6 +125,13 @@ function getExpenseAutomationJESchedulesView(state) {
122
125
  : [];
123
126
  const jeCompletionStatus = allSteps.find((step) => step.step === 'je_schedules')?.completionStatus;
124
127
  const completionStatus = jeCompletionStatus != null ? jeCompletionStatus : 'incomplete';
128
+ const monthEndFetchState = monthYearPeriodId != null
129
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
130
+ : { fetchState: 'Not-Started', error: undefined };
131
+ const reducedFetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
132
+ { fetchState, error },
133
+ monthEndFetchState,
134
+ ]);
125
135
  return {
126
136
  uncategorizedAccounts,
127
137
  allDepreciationAccountList: filteredDepAccounts,
@@ -137,10 +147,10 @@ function getExpenseAutomationJESchedulesView(state) {
137
147
  accountSettingsView,
138
148
  postStatusById: postStatusById,
139
149
  ignoreStatusById: ignoreStatusById,
140
- fetchState: fetchState,
150
+ fetchState: reducedFetchStatus.fetchState,
141
151
  jeScheduleLocalDataById: jeScheduleLocalDataById,
142
152
  uiState: uiState,
143
- error: error,
153
+ error: reducedFetchStatus.error,
144
154
  refreshStatus,
145
155
  completionStatus,
146
156
  };
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getExpenseAutomationMissingReceiptsView = getExpenseAutomationMissingReceiptsView;
7
7
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
8
+ const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
8
9
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
9
10
  const tenantSelector_1 = require("../../../entity/tenant/tenantSelector");
10
11
  const transactionSelector_1 = require("../../../entity/transaction/transactionSelector");
@@ -13,7 +14,7 @@ const missingReceiptsViewReducer_1 = require("../reducers/missingReceiptsViewRed
13
14
  const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
14
15
  const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
15
16
  function getExpenseAutomationMissingReceiptsView(state) {
16
- const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
17
+ const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
17
18
  const currentTenant = (0, tenantSelector_1.getCurrentTenant)(state);
18
19
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
19
20
  const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
@@ -181,9 +182,16 @@ function getExpenseAutomationMissingReceiptsView(state) {
181
182
  vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
182
183
  };
183
184
  });
185
+ const monthEndFetchState = monthYearPeriodId != null
186
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
187
+ : { fetchState: 'Not-Started', error: undefined };
188
+ const reducedFetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
189
+ { fetchState, error },
190
+ monthEndFetchState,
191
+ ]);
184
192
  return {
185
- fetchState,
186
- error,
193
+ fetchState: reducedFetchStatus.fetchState,
194
+ error: reducedFetchStatus.error,
187
195
  uploadReceiptStatusById,
188
196
  uiState,
189
197
  refreshStatus,
@@ -19,7 +19,7 @@ const accountListSelector_1 = require("../../accountList/accountListSelector");
19
19
  const classListSelector_1 = require("../../classList/classListSelector");
20
20
  const reconciliationViewReducer_1 = require("../reducers/reconciliationViewReducer");
21
21
  const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
22
- exports.getExpenseAutomationReconciliationView = (0, toolkit_1.createSelector)((state) => state, (state) => (0, tenantSelector_1.getCurrentTenant)(state), (state) => state.expenseAutomationReconciliationViewState, (state) => state.expenseAutomationViewState, (state) => state.plaidAccountViewState, (state) => state.accountListState, (state) => state.accountState, (state) => state.classListState, (state) => state.classState, (state) => state.monthEndCloseChecksState, (state) => state.vendorState, (state, currentTenant, reconciliationViewState, expenseAutomationViewState, plaidAccountViewState, accountListState, accountState, classListState, classState, monthEndCloseChecksState, vendorState) => {
22
+ exports.getExpenseAutomationReconciliationView = (0, toolkit_1.createSelector)((state) => state, (state) => (0, tenantSelector_1.getCurrentTenant)(state), (state) => state.expenseAutomationReconciliationViewState, (state) => state.expenseAutomationViewState, (state) => state.plaidAccountViewState, (state) => state.accountListState, (state) => state.accountState, (state) => state.classListState, (state) => state.classState, (state) => state.monthEndCloseChecksState, (state) => state.vendorState, (state) => state.monthEndCloseChecksViewState, (state, currentTenant, reconciliationViewState, expenseAutomationViewState, plaidAccountViewState, accountListState, accountState, classListState, classState, monthEndCloseChecksState, vendorState, monthEndCloseChecksViewState) => {
23
23
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
24
24
  const reconcileTabUiState = reconciliationViewState.reconTabsState.reconcile.uiState;
25
25
  const reviewTabUiState = reconciliationViewState.reconTabsState.review.uiState;
@@ -41,6 +41,13 @@ exports.getExpenseAutomationReconciliationView = (0, toolkit_1.createSelector)((
41
41
  }
42
42
  return acc;
43
43
  }, []);
44
+ const monthYearPeriodId = selectedPeriod != null ? (0, timePeriod_1.toMonthYearPeriodId)(selectedPeriod) : null;
45
+ const monthEndFetchState = monthYearPeriodId != null
46
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? {
47
+ fetchState: 'Not-Started',
48
+ error: undefined,
49
+ })
50
+ : { fetchState: 'Not-Started', error: undefined };
44
51
  if (accountReconForMonthYearPeriod == null) {
45
52
  return {
46
53
  bankAccounts: [],
@@ -50,10 +57,13 @@ exports.getExpenseAutomationReconciliationView = (0, toolkit_1.createSelector)((
50
57
  classListNestedAccountHierarchy: [],
51
58
  allAccountList: [],
52
59
  allClassList: [],
53
- fetchStatus: {
54
- fetchState: reconciliationViewState.fetchState,
55
- error: reconciliationViewState.error,
56
- },
60
+ fetchStatus: (0, reduceFetchState_1.reduceAnyFetchState)([
61
+ {
62
+ fetchState: reconciliationViewState.fetchState,
63
+ error: reconciliationViewState.error,
64
+ },
65
+ monthEndFetchState,
66
+ ]),
57
67
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
58
68
  .plaidConnectionDetails,
59
69
  completionStatus: 'incomplete',
@@ -276,10 +286,13 @@ exports.getExpenseAutomationReconciliationView = (0, toolkit_1.createSelector)((
276
286
  bankAccounts: uniqueBankAccounts,
277
287
  creditCards: uniqueCreditCards,
278
288
  accountReconciliationsByAccountID: reconList,
279
- fetchStatus: {
280
- fetchState: reconciliationViewState.fetchState,
281
- error: reconciliationViewState.error,
282
- },
289
+ fetchStatus: (0, reduceFetchState_1.reduceAnyFetchState)([
290
+ {
291
+ fetchState: reconciliationViewState.fetchState,
292
+ error: reconciliationViewState.error,
293
+ },
294
+ monthEndFetchState,
295
+ ]),
283
296
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
284
297
  .plaidConnectionDetails,
285
298
  reconciliationTabsState: reconciliationViewState.reconTabsState,
@@ -14,7 +14,7 @@ const accountListSelector_1 = require("../../accountList/accountListSelector");
14
14
  const classListSelector_1 = require("../../classList/classListSelector");
15
15
  const expenseAutomationViewSelectorTypes_1 = require("../selectorTypes/expenseAutomationViewSelectorTypes");
16
16
  function getExpenseAutomationTransactionView(state) {
17
- const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
17
+ const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
18
18
  const { selectedTransactionCategorizationTab } = expenseAutomationTransactionsViewState;
19
19
  const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
20
20
  const uncategorizedIncomeExpense = (0, accountListSelector_1.getUncategorizedAccounts)(accountState, accountListState, 'accountList');
@@ -47,10 +47,16 @@ function getExpenseAutomationTransactionView(state) {
47
47
  .filter((transaction) => transaction != null);
48
48
  const transactions = (0, transactionSelector_1.getSupportedTransactionsByIds)(transactionState, transactionIds);
49
49
  const transactionsWithCOT = transactions.map((transaction) => (0, transactionHelper_1.getTransactionWithCOT)(transaction));
50
- const fetchStatus = (0, reduceFetchState_1.reduceAllFetchState)([
51
- accountList,
52
- classList,
53
- expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
50
+ const monthEndFetchState = monthYearPeriodId != null
51
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
52
+ : { fetchState: 'Not-Started', error: undefined };
53
+ const fetchStatus = (0, reduceFetchState_1.reduceAnyFetchState)([
54
+ (0, reduceFetchState_1.reduceAllFetchState)([
55
+ accountList,
56
+ classList,
57
+ expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
58
+ ]),
59
+ monthEndFetchState,
54
60
  ]);
55
61
  const totalCountByReview = expenseAutomationTransactionsViewState.transactionCategorizationView.review
56
62
  .uiState.totalCount;
@@ -6,7 +6,7 @@ import { MonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
6
6
  import { AccountBase } from '../../../entity/account/accountState';
7
7
  import { JEScheduleTransactionKey, ScheduleTypes } from '../../../entity/jeSchedules/jeSchedulesTypes';
8
8
  import { VendorBase } from '../../../entity/vendor/vendorState';
9
- export declare const toJEScheduleSortKey: (v: string) => "vendor" | "type" | "category" | "class" | "memo" | "transactionDate" | "totalAmount" | "runningBalance" | "scheduleCategory" | "startMonth" | "amortizationPeriod" | "jePostingDate" | "remainingMonths";
9
+ export declare const toJEScheduleSortKey: (v: string) => "vendor" | "type" | "category" | "class" | "memo" | "transactionDate" | "totalAmount" | "runningBalance" | "depCategory" | "scheduleCategory" | "startMonth" | "amortizationPeriod" | "jePostingDate" | "remainingMonths";
10
10
  export type JEScheduleSortKey = ReturnType<typeof toJEScheduleSortKey>;
11
11
  export interface JESchedulesViewUIState {
12
12
  scrollPosition: {
@@ -6,6 +6,7 @@ const JE_SCHEDULE_SORT_KEYS = [
6
6
  'vendor',
7
7
  'category',
8
8
  'class',
9
+ 'depCategory',
9
10
  'scheduleCategory',
10
11
  'startMonth',
11
12
  'type',
@@ -52,16 +52,11 @@ const getProfitAndLossClassesHorizontalView = (filter, accountState, classState,
52
52
  const calculatedSections = {};
53
53
  let reportCurrency = currencyHelper_1.defaultCustomerCurrency;
54
54
  if (fetchState.fetchState === 'Completed' && selectedPeriod != null) {
55
- // Get section reports using existing selector infrastructure
56
- const sectionReports = {};
57
- HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
58
- sectionReports[sectionId] = (0, sectionClassesViewSelector_1.getSectionClassesViewReport)(accountState, classState, sectionsState, { reportId, sectionId }, filter);
59
- });
60
55
  reportCurrency =
61
56
  profitAndLossClassesViewState.currency ?? currencyHelper_1.defaultCustomerCurrency;
62
- // Pivot each section from class→account to account→class
57
+ // Fetch each section and pivot class→account to account→class in one pass
63
58
  HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
64
- const sectionReport = sectionReports[sectionId];
59
+ const sectionReport = (0, sectionClassesViewSelector_1.getSectionClassesViewReport)(accountState, classState, sectionsState, { reportId, sectionId }, filter);
65
60
  if (sectionReport != null) {
66
61
  sections[sectionId] = pivotSectionToHorizontal(sectionReport, classColumns, SECTION_TITLES[sectionId] ?? sectionId, reportCurrency);
67
62
  }
@@ -265,7 +260,7 @@ function sumBalancesInSlice(balances) {
265
260
  if (balances.length === 0) {
266
261
  return 0;
267
262
  }
268
- const summed = (0, getSummationBalance_1.getSummationFreeRangeTotalBalance)([...balances]);
263
+ const summed = (0, getSummationBalance_1.getSummationFreeRangeTotalBalance)(balances);
269
264
  return summed?.balance.amount ?? 0;
270
265
  }
271
266
  /**
@@ -28,30 +28,31 @@ function enrichHorizontalSection(report, section) {
28
28
  return total?.balance.amount ?? 0;
29
29
  });
30
30
  section.sectionHeaderBalancesSlice = buildHorizontalClassColumnBalancesSlice(report, classAmounts, section.sectionTotal.amount);
31
- const childrenRowIndicesByParent = buildHorizontalAccountChildIndicesByParent(section.accounts);
31
+ const parentIndices = computeHorizontalAccountParentIndices(section.accounts);
32
+ const childrenRowIndicesByParent = buildHorizontalAccountChildIndicesByParent(parentIndices);
32
33
  const childrenRecord = {};
33
34
  childrenRowIndicesByParent.forEach((childIndices, parentIndex) => {
34
35
  childrenRecord[parentIndex] = childIndices;
35
36
  });
36
37
  section.treeLayout = {
37
38
  rootAccountRowIndices: section.accounts
38
- .map((_, i) => findHorizontalAccountParentIndex(section.accounts, i) === -1 ? i : -1)
39
+ .map((_, i) => (parentIndices[i] === -1 ? i : -1))
39
40
  .filter((i) => i >= 0),
40
41
  childrenRowIndicesByParent: childrenRecord,
41
42
  };
43
+ const siblingsPerRow = buildSiblingIndicesPerRow(section.accounts, parentIndices);
44
+ const hasChildFlags = computeHorizontalHasChildFlags(parentIndices);
42
45
  for (let i = 0; i < section.accounts.length; i++) {
43
46
  const row = section.accounts[i];
44
- const classRowAmounts = report.classColumns.map((col) => {
45
- const cb = row.classBalances.find((b) => b.classId === col.classId);
46
- return cb?.balance.amount ?? 0;
47
- });
47
+ // Same column order as `report.classColumns` (see `pivotSectionToHorizontal`).
48
+ const classRowAmounts = row.classBalances.map((b) => b.balance.amount);
48
49
  row.accountReportData = {
49
50
  accountId: row.accountId,
50
51
  accountName: row.accountName,
51
52
  accountType: row.accountType,
52
53
  depth: row.depth,
53
54
  balancesInTimeframe: buildHorizontalClassColumnBalancesSlice(report, classRowAmounts, row.rowTotal.amount),
54
- horizontalTreeView: buildHorizontalTreeView(section.accounts, i),
55
+ horizontalTreeView: buildHorizontalTreeViewFromPrecomputed(section.accounts, i, parentIndices, siblingsPerRow, hasChildFlags),
55
56
  };
56
57
  }
57
58
  }
@@ -123,64 +124,157 @@ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmou
123
124
  },
124
125
  };
125
126
  }
126
- function findHorizontalAccountParentIndex(dfsOrderedAccountRows, childRowIndex) {
127
- const childDepth = dfsOrderedAccountRows[childRowIndex].depth;
128
- if (childDepth <= 2) {
129
- return -1;
130
- }
131
- for (let earlierRowIndex = childRowIndex - 1; earlierRowIndex >= 0; earlierRowIndex--) {
132
- const earlierDepth = dfsOrderedAccountRows[earlierRowIndex].depth;
133
- if (earlierDepth < childDepth) {
134
- if (earlierDepth === childDepth - 1) {
135
- return earlierRowIndex;
127
+ /**
128
+ * Parent index per DFS row — O(n). Matches the scan in the former
129
+ * `findHorizontalAccountParentIndex` (depth &lt;= 2 rows have no parent).
130
+ */
131
+ function computeHorizontalAccountParentIndices(rows) {
132
+ const accountRowCount = rows.length;
133
+ const parentIndex = new Array(accountRowCount).fill(-1);
134
+ const stack = [];
135
+ for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
136
+ const accountRow = rows[rowIndex];
137
+ if (accountRow == null) {
138
+ continue;
139
+ }
140
+ const d = accountRow.depth;
141
+ while (stack.length > 0) {
142
+ const topIdx = stack[stack.length - 1];
143
+ if (topIdx == null) {
144
+ break;
136
145
  }
137
- return -1;
146
+ const topRow = rows[topIdx];
147
+ if (topRow == null) {
148
+ stack.pop();
149
+ continue;
150
+ }
151
+ if (topRow.depth < d) {
152
+ break;
153
+ }
154
+ stack.pop();
155
+ }
156
+ if (d <= 2) {
157
+ parentIndex[rowIndex] = -1;
158
+ }
159
+ else if (stack.length === 0) {
160
+ parentIndex[rowIndex] = -1;
138
161
  }
162
+ else {
163
+ const peek = stack[stack.length - 1];
164
+ if (peek == null) {
165
+ parentIndex[rowIndex] = -1;
166
+ }
167
+ else {
168
+ const parentRow = rows[peek];
169
+ parentIndex[rowIndex] =
170
+ parentRow != null && parentRow.depth === d - 1 ? peek : -1;
171
+ }
172
+ }
173
+ stack.push(rowIndex);
139
174
  }
140
- return -1;
175
+ return parentIndex;
141
176
  }
142
- function getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex) {
143
- const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
144
- const rowDepth = dfsOrderedAccountRows[rowIndex].depth;
145
- const siblings = [];
146
- for (let i = 0; i < dfsOrderedAccountRows.length; i++) {
147
- if (dfsOrderedAccountRows[i].depth === rowDepth &&
148
- findHorizontalAccountParentIndex(dfsOrderedAccountRows, i) ===
149
- parentRowIndex) {
150
- siblings.push(i);
177
+ /** Sibling row indices (same parent + depth), in traversal order — O(n). */
178
+ function buildSiblingIndicesPerRow(rows, parentIndices) {
179
+ const accountRowCount = rows.length;
180
+ const keyToIndices = new Map();
181
+ for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
182
+ const parentRowIndex = parentIndices[rowIndex];
183
+ const accountRow = rows[rowIndex];
184
+ if (parentRowIndex == null || accountRow == null) {
185
+ continue;
186
+ }
187
+ const key = `${parentRowIndex}:${accountRow.depth}`;
188
+ let g = keyToIndices.get(key);
189
+ if (g == null) {
190
+ g = [];
191
+ keyToIndices.set(key, g);
151
192
  }
193
+ g.push(rowIndex);
152
194
  }
153
- return siblings;
195
+ const siblingsPerRow = new Array(accountRowCount);
196
+ for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
197
+ const parentRowIndex = parentIndices[rowIndex];
198
+ const accountRow = rows[rowIndex];
199
+ if (parentRowIndex == null || accountRow == null) {
200
+ siblingsPerRow[rowIndex] = [rowIndex];
201
+ continue;
202
+ }
203
+ const key = `${parentRowIndex}:${accountRow.depth}`;
204
+ const group = keyToIndices.get(key);
205
+ siblingsPerRow[rowIndex] = group != null ? group : [rowIndex];
206
+ }
207
+ return siblingsPerRow;
154
208
  }
155
- function horizontalAccountHasChildRows(dfsOrderedAccountRows, parentRowIndex) {
156
- return dfsOrderedAccountRows.some((_, rowIndex) => findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex) ===
157
- parentRowIndex);
209
+ function computeHorizontalHasChildFlags(parentIndices) {
210
+ const rowCount = parentIndices.length;
211
+ const flags = new Array(rowCount).fill(false);
212
+ for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
213
+ const parentRowIndex = parentIndices[rowIndex];
214
+ if (parentRowIndex != null &&
215
+ parentRowIndex >= 0 &&
216
+ parentRowIndex < rowCount) {
217
+ flags[parentRowIndex] = true;
218
+ }
219
+ }
220
+ return flags;
158
221
  }
159
- function buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex) {
160
- const ancestorRowIndicesRootToLeaf = [];
222
+ function buildHorizontalSubAccountAncestorMetadataFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags) {
223
+ const chain = [];
161
224
  let walkRowIndex = currentRowIndex;
162
225
  while (walkRowIndex >= 0) {
163
- ancestorRowIndicesRootToLeaf.unshift(walkRowIndex);
164
- walkRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, walkRowIndex);
226
+ chain.unshift(walkRowIndex);
227
+ const parentRowIndex = parentIndices[walkRowIndex];
228
+ if (parentRowIndex == null) {
229
+ break;
230
+ }
231
+ walkRowIndex = parentRowIndex;
165
232
  }
166
- return ancestorRowIndicesRootToLeaf.map((rowIndex) => {
167
- const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex);
233
+ return chain.map((rowIndex) => {
234
+ const accountRow = dfsOrderedAccountRows[rowIndex];
235
+ const siblingIndices = siblingsPerRow[rowIndex];
236
+ const hasChild = hasChildFlags[rowIndex];
237
+ if (accountRow == null || siblingIndices == null) {
238
+ return {
239
+ depth: 0,
240
+ hasSibling: false,
241
+ hasChildren: hasChild === true,
242
+ isLastNode: true,
243
+ name: '',
244
+ };
245
+ }
168
246
  return {
169
- depth: dfsOrderedAccountRows[rowIndex].depth - 2,
247
+ depth: accountRow.depth - 2,
170
248
  hasSibling: siblingIndices.length > 1,
171
- hasChildren: horizontalAccountHasChildRows(dfsOrderedAccountRows, rowIndex),
249
+ hasChildren: hasChild === true,
172
250
  isLastNode: rowIndex === siblingIndices[siblingIndices.length - 1],
173
- name: dfsOrderedAccountRows[rowIndex].accountName,
251
+ name: accountRow.accountName,
174
252
  };
175
253
  });
176
254
  }
177
- function buildHorizontalAccountChildIndicesByParent(dfsOrderedAccountRows) {
255
+ function buildHorizontalTreeViewFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags) {
256
+ const siblingIndices = siblingsPerRow[currentRowIndex];
257
+ const accountRow = dfsOrderedAccountRows[currentRowIndex];
258
+ const hasChildrenFlag = hasChildFlags[currentRowIndex];
259
+ const treeDepth = accountRow != null ? Math.max(0, accountRow.depth - 2) : 0;
260
+ const hasChildren = hasChildrenFlag === true;
261
+ const sibs = siblingIndices ?? [currentRowIndex];
262
+ return {
263
+ subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadataFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags),
264
+ treeDepth,
265
+ hasChildren,
266
+ hasSiblings: sibs.length > 1,
267
+ isLeaf: !hasChildren,
268
+ isLastNode: currentRowIndex === sibs[sibs.length - 1],
269
+ };
270
+ }
271
+ function buildHorizontalAccountChildIndicesByParent(parentIndices) {
178
272
  const childIndicesByParentRowIndex = new Map();
179
- for (let rowIndex = 0; rowIndex < dfsOrderedAccountRows.length; rowIndex++) {
180
- const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
181
- if (parentRowIndex >= 0) {
273
+ for (let rowIndex = 0; rowIndex < parentIndices.length; rowIndex++) {
274
+ const parentRowIndex = parentIndices[rowIndex];
275
+ if (parentRowIndex != null && parentRowIndex >= 0) {
182
276
  let childRowIndices = childIndicesByParentRowIndex.get(parentRowIndex);
183
- if (childRowIndices === undefined) {
277
+ if (childRowIndices == null) {
184
278
  childRowIndices = [];
185
279
  childIndicesByParentRowIndex.set(parentRowIndex, childRowIndices);
186
280
  }
@@ -189,16 +283,3 @@ function buildHorizontalAccountChildIndicesByParent(dfsOrderedAccountRows) {
189
283
  }
190
284
  return childIndicesByParentRowIndex;
191
285
  }
192
- function buildHorizontalTreeView(dfsOrderedAccountRows, currentRowIndex) {
193
- const treeDepth = Math.max(0, dfsOrderedAccountRows[currentRowIndex].depth - 2);
194
- const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, currentRowIndex);
195
- const hasChildren = horizontalAccountHasChildRows(dfsOrderedAccountRows, currentRowIndex);
196
- return {
197
- subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex),
198
- treeDepth,
199
- hasChildren,
200
- hasSiblings: siblingIndices.length > 1,
201
- isLeaf: !hasChildren,
202
- isLastNode: currentRowIndex === siblingIndices[siblingIndices.length - 1],
203
- };
204
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "4.19.99-betaAD01",
3
+ "version": "4.19.99-betaAD07",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",