@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
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Canonical union of `page_context` values for GET …/suggested-questions (and related Redux
3
+ * `suggestedQuestionsByPageContext` on `AiCfoViewState`).
4
+ *
5
+ * ## Report IDs vs `page_context`
6
+ *
7
+ * **These strings are not all finance `report_id` values.** They are the **API’s** `page_context`
8
+ * slugs. Only the **reports tab** subset is *derived* from `ReportID` (e.g. `profit_and_loss` →
9
+ * `profit_loss`). That mapping lives in the web app:
10
+ * `zeni-web-app-ui/src/aiCfo/aiCfoSuggestedQuestionsPageContext.ts`
11
+ * (`reportIdToAiCfoSuggestedQuestionsPageContext`).
12
+ *
13
+ * Other members (e.g. `dashboard`, `bills_list`, `task_checklist`) come from **product routes /
14
+ * screens**, not from report IDs. Adding a new host screen usually means extending this union and
15
+ * wiring route resolution in the UI; coordinate with the backend for suggested-questions support.
16
+ *
17
+ * @see README.md in this directory for maintenance expectations.
18
+ */
19
+ 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';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -25,26 +25,28 @@ export interface JEScheduleAISummariesPayload {
25
25
  debit_accounting_class?: JEScheduleAISummaryFieldPayload;
26
26
  period?: JEScheduleAISummaryFieldPayload;
27
27
  posting_date?: JEScheduleAISummaryFieldPayload;
28
+ schedule_type?: JEScheduleAISummaryFieldPayload;
28
29
  }
29
30
  export interface JEScheduleRecommendationsPayload {
30
- amortization_days?: number | null;
31
- amortization_months_estimate?: number | null;
32
31
  credit_account_confidence?: number;
33
- credit_account_id?: string | null;
34
- credit_accounting_class_id?: string | null;
35
32
  credit_class_confidence?: number;
36
33
  debit_account_confidence?: number;
37
- debit_account_id?: string | null;
38
- debit_accounting_class_id?: string | null;
39
34
  debit_class_confidence?: number;
40
35
  end_date?: string | null;
36
+ je_credit_account_id?: string | null;
37
+ je_credit_accounting_class_id?: string | null;
38
+ je_debit_account_id?: string | null;
39
+ je_debit_accounting_class_id?: string | null;
41
40
  je_schedule_type?: string | null;
41
+ je_schedule_type_confidence?: number;
42
42
  period?: number | null;
43
43
  period_confidence?: number;
44
44
  posting_date?: string | null;
45
+ posting_date_confidence?: number;
45
46
  similar_transactions?: unknown[];
46
47
  start_date?: string | null;
47
48
  starting_month?: string | null;
49
+ starting_month_confidence?: number;
48
50
  }
49
51
  export interface JEScheduledTransactionPayload {
50
52
  balance: number | null;
@@ -69,6 +71,7 @@ export interface JEScheduledTransactionPayload {
69
71
  updated_by: UserPayload;
70
72
  vendor: VendorPayload;
71
73
  ai_summaries?: JEScheduleAISummariesPayload;
74
+ created_by?: UserPayload;
72
75
  end_date?: string | null;
73
76
  recommendations?: JEScheduleRecommendationsPayload;
74
77
  updated_at?: string | null;
@@ -146,7 +146,7 @@ function toJEScheduleOtherAttributes(payload) {
146
146
  assetId: payload.asset_id ?? undefined,
147
147
  };
148
148
  }
149
- function toJEScheduleAIRecommendations(payload) {
149
+ function toJEScheduleAISummaries(payload) {
150
150
  if (payload == null) {
151
151
  return undefined;
152
152
  }
@@ -187,8 +187,40 @@ function toJEScheduleAIRecommendations(payload) {
187
187
  reasoning: payload.posting_date.reasoning,
188
188
  };
189
189
  }
190
+ if (payload.schedule_type != null) {
191
+ result.scheduleType = {
192
+ confidence: payload.schedule_type.confidence,
193
+ reasoning: payload.schedule_type.reasoning,
194
+ };
195
+ }
190
196
  return Object.keys(result).length > 0 ? result : undefined;
191
197
  }
198
+ function toJEScheduleRecommendations(payload) {
199
+ if (payload == null) {
200
+ return undefined;
201
+ }
202
+ return {
203
+ creditAccountConfidence: payload.credit_account_confidence,
204
+ creditClassConfidence: payload.credit_class_confidence,
205
+ debitAccountConfidence: payload.debit_account_confidence,
206
+ debitClassConfidence: payload.debit_class_confidence,
207
+ endDate: payload.end_date ?? undefined,
208
+ jeCreditAccountId: payload.je_credit_account_id ?? undefined,
209
+ jeCreditAccountingClassId: payload.je_credit_accounting_class_id ?? undefined,
210
+ jeDebitAccountId: payload.je_debit_account_id ?? undefined,
211
+ jeDebitAccountingClassId: payload.je_debit_accounting_class_id ?? undefined,
212
+ jeScheduleType: payload.je_schedule_type ?? undefined,
213
+ jeScheduleTypeConfidence: payload.je_schedule_type_confidence,
214
+ period: payload.period ?? undefined,
215
+ periodConfidence: payload.period_confidence,
216
+ postingDate: payload.posting_date ?? undefined,
217
+ postingDateConfidence: payload.posting_date_confidence,
218
+ similarTransactions: payload.similar_transactions,
219
+ startDate: payload.start_date ?? undefined,
220
+ startingMonth: payload.starting_month ?? undefined,
221
+ startingMonthConfidence: payload.starting_month_confidence,
222
+ };
223
+ }
192
224
  function toJEScheduledTransaction(payload) {
193
225
  return {
194
226
  jeScheduleId: payload.je_schedule_id ?? undefined,
@@ -233,7 +265,9 @@ function toJEScheduledTransaction(payload) {
233
265
  ? toJEScheduleOtherAttributes(payload.other_attributes)
234
266
  : {},
235
267
  scheduledJournalEntry: [],
236
- aiRecommendations: toJEScheduleAIRecommendations(payload.ai_summaries),
268
+ aiSummaries: toJEScheduleAISummaries(payload.ai_summaries),
269
+ createdByUserID: payload.created_by?.user_id ?? undefined,
270
+ recommendations: toJEScheduleRecommendations(payload.recommendations),
237
271
  };
238
272
  }
239
273
  function toJEAccruedScheduledTransaction(payload) {
@@ -9,7 +9,7 @@ import { ScheduleTransaction } from '../transaction/stateTypes/scheduleTransacti
9
9
  import { TransactionID } from '../transaction/stateTypes/transaction';
10
10
  import { User } from '../user/userState';
11
11
  import { Vendor } from '../vendor/vendorState';
12
- import { JEScheduleAIRecommendations, JEScheduleOtherAttributes, ScheduleJournalStatusCode, ScheduleStatus } from './jeSchedulesState';
12
+ import { JEScheduleAISummaries, JEScheduleOtherAttributes, JEScheduleRecommendations, ScheduleJournalStatusCode, ScheduleStatus } from './jeSchedulesState';
13
13
  import { JEScheduleKey, JEScheduleTransactionKey, JournalEntryErrorCodeType, ScheduleTypes } from './jeSchedulesTypes';
14
14
  export interface ScheduledJournalEntry {
15
15
  error: JournalEntryErrorCodeType[];
@@ -59,14 +59,16 @@ export interface JEScheduledTransaction {
59
59
  scheduledJournalEntry: ScheduledJournalEntry[];
60
60
  status: ScheduleStatus;
61
61
  vendor: Vendor;
62
- aiRecommendations?: JEScheduleAIRecommendations;
62
+ aiSummaries?: JEScheduleAISummaries;
63
63
  balanceAsOfToday?: Amount;
64
+ createdByUser?: User;
64
65
  dayOfPostingDate?: ScheduleDaysOfMonth;
65
66
  endDate?: ZeniDate;
66
67
  jeScheduleId?: ID;
67
68
  jeScheduleType?: ScheduleTypes;
68
69
  lastDayOfMonth?: boolean;
69
70
  period?: number;
71
+ recommendations?: JEScheduleRecommendations;
70
72
  startDate?: ZeniDate;
71
73
  updatedAt?: ZeniDate;
72
74
  updatedByUser?: User;
@@ -77,12 +77,13 @@ exports.getJEAccruedScheduleByJEScheduleKey = getJEAccruedScheduleByJEScheduleKe
77
77
  const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransactionKey, state) => {
78
78
  const { jeSchedulesState, vendorState, accountState, userState, classState, transactionState, } = state;
79
79
  const jeScheduleTransactionState = (0, get_1.default)(jeSchedulesState.schedulesByTransactionKey, jeScheduleTransactionKey);
80
- const { period, updatedByUserID: updatedBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiRecommendations, } = jeScheduleTransactionState;
80
+ const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiSummaries, recommendations, } = jeScheduleTransactionState;
81
81
  const vendorDetails = (0, vendorSelector_1.getVendorByVendorId)(vendorState, vendorId);
82
82
  if (vendorDetails == null) {
83
83
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
84
84
  }
85
85
  const userDetails = updatedBy != null ? (0, userSelector_1.getUserByUserId)(userState, updatedBy) : undefined;
86
+ const createdByUserDetails = createdBy != null ? (0, userSelector_1.getUserByUserId)(userState, createdBy) : undefined;
86
87
  const baseTransactionObject = (0, transactionSelector_1.getScheduleTransactionById)(transactionState, baseTransaction);
87
88
  if (baseTransactionObject == null) {
88
89
  throw Error('Base Schedule transaction cannot be null');
@@ -134,7 +135,9 @@ const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransacti
134
135
  account: accountDebit,
135
136
  },
136
137
  scheduledJournalEntry,
137
- aiRecommendations,
138
+ aiSummaries,
139
+ createdByUser: createdByUserDetails,
140
+ recommendations,
138
141
  };
139
142
  };
140
143
  exports.getJEScheduledTransactionByJEScheduleTransactionKey = getJEScheduledTransactionByJEScheduleTransactionKey;
@@ -16,13 +16,35 @@ export interface JEScheduleFieldRecommendation {
16
16
  confidence: number;
17
17
  reasoning: string;
18
18
  }
19
- export interface JEScheduleAIRecommendations {
19
+ export interface JEScheduleAISummaries {
20
20
  creditAccount?: JEScheduleFieldRecommendation;
21
21
  creditClass?: JEScheduleFieldRecommendation;
22
22
  debitAccount?: JEScheduleFieldRecommendation;
23
23
  debitClass?: JEScheduleFieldRecommendation;
24
24
  period?: JEScheduleFieldRecommendation;
25
25
  postingDate?: JEScheduleFieldRecommendation;
26
+ scheduleType?: JEScheduleFieldRecommendation;
27
+ }
28
+ export interface JEScheduleRecommendations {
29
+ creditAccountConfidence?: number;
30
+ creditClassConfidence?: number;
31
+ debitAccountConfidence?: number;
32
+ debitClassConfidence?: number;
33
+ endDate?: string;
34
+ jeCreditAccountId?: string;
35
+ jeCreditAccountingClassId?: string;
36
+ jeDebitAccountId?: string;
37
+ jeDebitAccountingClassId?: string;
38
+ jeScheduleType?: string;
39
+ jeScheduleTypeConfidence?: number;
40
+ period?: number;
41
+ periodConfidence?: number;
42
+ postingDate?: string;
43
+ postingDateConfidence?: number;
44
+ similarTransactions?: unknown[];
45
+ startDate?: string;
46
+ startingMonth?: string;
47
+ startingMonthConfidence?: number;
26
48
  }
27
49
  export interface JEScheduleOtherAttributes {
28
50
  assetId?: string;
@@ -68,14 +90,16 @@ export interface JEScheduledTransactionState {
68
90
  scheduledJournalEntry: ScheduledJournalEntryState[];
69
91
  status: ScheduleStatus;
70
92
  vendorId: ID;
71
- aiRecommendations?: JEScheduleAIRecommendations;
93
+ aiSummaries?: JEScheduleAISummaries;
72
94
  balanceAsOfToday?: number;
95
+ createdByUserID?: ID;
73
96
  dayOfPostingDate?: ScheduleDaysOfMonth;
74
97
  endDate?: ZeniDate;
75
98
  jeScheduleId?: ID;
76
99
  jeScheduleType?: ScheduleTypes;
77
100
  lastDayOfMonth?: boolean;
78
101
  period?: number;
102
+ recommendations?: JEScheduleRecommendations;
79
103
  startDate?: ZeniDate;
80
104
  updatedAt?: ZeniDate;
81
105
  updatedByUserID?: ID;
@@ -2,12 +2,15 @@ import { AccountBasePayload } from '../../account/accountPayload';
2
2
  import { ClassBasePayload } from '../../class/classPayload';
3
3
  import { ScheduleTransaction } from '../stateTypes/scheduleTransaction';
4
4
  import { TransactionIDPayload } from './transactionIDPayload';
5
- export interface ScheduleTransactionPayload extends TransactionIDPayload, Omit<AccountBasePayload, 'qbo_id'>, Omit<ClassBasePayload, 'qbo_id' | 'labels'> {
5
+ export interface ScheduleTransactionPayload extends TransactionIDPayload, Omit<AccountBasePayload, 'qbo_id' | 'labels'>, Omit<ClassBasePayload, 'qbo_id' | 'labels'> {
6
6
  line_id: string;
7
7
  third_party_transaction_id: string;
8
8
  total_amount: number;
9
9
  transaction_date: string;
10
10
  transaction_memo: string;
11
11
  transaction_type_name: string;
12
+ labels?: string[];
13
+ sync_token?: number;
14
+ transaction_description?: string | null;
12
15
  }
13
16
  export declare const toScheduleTransaction: (payload: ScheduleTransactionPayload, currency_code: string, currency_symbol: string) => ScheduleTransaction;
@@ -32,6 +32,7 @@ const toScheduleTransaction = (payload, currency_code, currency_symbol) => {
32
32
  currencyCode: currency_code,
33
33
  currencySymbol: currency_symbol,
34
34
  },
35
+ description: payload.transaction_description ?? undefined,
35
36
  };
36
37
  };
37
38
  exports.toScheduleTransaction = toScheduleTransaction;
@@ -9,4 +9,5 @@ export interface ScheduleTransaction extends BaseTransaction {
9
9
  lineId: ID;
10
10
  thirdPartyTransactionId: ID;
11
11
  classBase?: ClassBase;
12
+ description?: string;
12
13
  }
@@ -136,7 +136,7 @@ function toJEScheduleOtherAttributes(payload) {
136
136
  assetId: payload.asset_id ?? undefined,
137
137
  };
138
138
  }
139
- function toJEScheduleAIRecommendations(payload) {
139
+ function toJEScheduleAISummaries(payload) {
140
140
  if (payload == null) {
141
141
  return undefined;
142
142
  }
@@ -177,8 +177,40 @@ function toJEScheduleAIRecommendations(payload) {
177
177
  reasoning: payload.posting_date.reasoning,
178
178
  };
179
179
  }
180
+ if (payload.schedule_type != null) {
181
+ result.scheduleType = {
182
+ confidence: payload.schedule_type.confidence,
183
+ reasoning: payload.schedule_type.reasoning,
184
+ };
185
+ }
180
186
  return Object.keys(result).length > 0 ? result : undefined;
181
187
  }
188
+ function toJEScheduleRecommendations(payload) {
189
+ if (payload == null) {
190
+ return undefined;
191
+ }
192
+ return {
193
+ creditAccountConfidence: payload.credit_account_confidence,
194
+ creditClassConfidence: payload.credit_class_confidence,
195
+ debitAccountConfidence: payload.debit_account_confidence,
196
+ debitClassConfidence: payload.debit_class_confidence,
197
+ endDate: payload.end_date ?? undefined,
198
+ jeCreditAccountId: payload.je_credit_account_id ?? undefined,
199
+ jeCreditAccountingClassId: payload.je_credit_accounting_class_id ?? undefined,
200
+ jeDebitAccountId: payload.je_debit_account_id ?? undefined,
201
+ jeDebitAccountingClassId: payload.je_debit_accounting_class_id ?? undefined,
202
+ jeScheduleType: payload.je_schedule_type ?? undefined,
203
+ jeScheduleTypeConfidence: payload.je_schedule_type_confidence,
204
+ period: payload.period ?? undefined,
205
+ periodConfidence: payload.period_confidence,
206
+ postingDate: payload.posting_date ?? undefined,
207
+ postingDateConfidence: payload.posting_date_confidence,
208
+ similarTransactions: payload.similar_transactions,
209
+ startDate: payload.start_date ?? undefined,
210
+ startingMonth: payload.starting_month ?? undefined,
211
+ startingMonthConfidence: payload.starting_month_confidence,
212
+ };
213
+ }
182
214
  export function toJEScheduledTransaction(payload) {
183
215
  return {
184
216
  jeScheduleId: payload.je_schedule_id ?? undefined,
@@ -223,7 +255,9 @@ export function toJEScheduledTransaction(payload) {
223
255
  ? toJEScheduleOtherAttributes(payload.other_attributes)
224
256
  : {},
225
257
  scheduledJournalEntry: [],
226
- aiRecommendations: toJEScheduleAIRecommendations(payload.ai_summaries),
258
+ aiSummaries: toJEScheduleAISummaries(payload.ai_summaries),
259
+ createdByUserID: payload.created_by?.user_id ?? undefined,
260
+ recommendations: toJEScheduleRecommendations(payload.recommendations),
227
261
  };
228
262
  }
229
263
  export function toJEAccruedScheduledTransaction(payload) {
@@ -70,12 +70,13 @@ export const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
70
70
  export const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransactionKey, state) => {
71
71
  const { jeSchedulesState, vendorState, accountState, userState, classState, transactionState, } = state;
72
72
  const jeScheduleTransactionState = recordGet(jeSchedulesState.schedulesByTransactionKey, jeScheduleTransactionKey);
73
- const { period, updatedByUserID: updatedBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiRecommendations, } = jeScheduleTransactionState;
73
+ const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiSummaries, recommendations, } = jeScheduleTransactionState;
74
74
  const vendorDetails = getVendorByVendorId(vendorState, vendorId);
75
75
  if (vendorDetails == null) {
76
76
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
77
77
  }
78
78
  const userDetails = updatedBy != null ? getUserByUserId(userState, updatedBy) : undefined;
79
+ const createdByUserDetails = createdBy != null ? getUserByUserId(userState, createdBy) : undefined;
79
80
  const baseTransactionObject = getScheduleTransactionById(transactionState, baseTransaction);
80
81
  if (baseTransactionObject == null) {
81
82
  throw Error('Base Schedule transaction cannot be null');
@@ -127,6 +128,8 @@ export const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTr
127
128
  account: accountDebit,
128
129
  },
129
130
  scheduledJournalEntry,
130
- aiRecommendations,
131
+ aiSummaries,
132
+ createdByUser: createdByUserDetails,
133
+ recommendations,
131
134
  };
132
135
  };
@@ -29,5 +29,6 @@ export const toScheduleTransaction = (payload, currency_code, currency_symbol) =
29
29
  currencyCode: currency_code,
30
30
  currencySymbol: currency_symbol,
31
31
  },
32
+ description: payload.transaction_description ?? undefined,
32
33
  };
33
34
  };
@@ -91,7 +91,6 @@ export function getExpenseAutomationView(state) {
91
91
  const fetchStateVariables = [
92
92
  expenseAutomationMissingReceiptsViewState,
93
93
  expenseAutomationJESchedulesViewState,
94
- monthEndCloseChecksView,
95
94
  expenseAutomationTransactionsView,
96
95
  expenseAutomationReconciliationViewState,
97
96
  ];
@@ -1,3 +1,4 @@
1
+ import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
1
2
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
2
3
  import { getAccountBase } from '../../../entity/account/accountSelector';
3
4
  import { getClassById } from '../../../entity/class/classSelector';
@@ -6,7 +7,7 @@ import { getUserByUserId } from '../../../entity/user/userSelector';
6
7
  import { getVendorByVendorId } from '../../../entity/vendor/vendorSelector';
7
8
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
8
9
  export function getExpenseAutomationFluxAnalysisView(state) {
9
- const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState } = state;
10
+ const { expenseAutomationFluxAnalysisViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
10
11
  const { fetchState, error, refreshStatus, uiState, reviewOperatingExpenseIdsByPeriod, selectedSectionIdsByPeriod, groupsBySelectedPeriod, fluxAnalysisEntities, bulkReviewStatus, currency, totalBalancesAndVariance, } = expenseAutomationFluxAnalysisViewState;
11
12
  const fetchStateAndError = {
12
13
  fetchState,
@@ -91,10 +92,17 @@ export function getExpenseAutomationFluxAnalysisView(state) {
91
92
  },
92
93
  };
93
94
  const completionStatus = fluxCompletionStatus != null ? fluxCompletionStatus : 'incomplete';
95
+ const monthEndFetchState = monthYearPeriodId != null
96
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
97
+ : { fetchState: 'Not-Started', error: undefined };
98
+ const reducedFetchStatus = reduceAnyFetchState([
99
+ fetchStateAndError,
100
+ monthEndFetchState,
101
+ ]);
94
102
  return {
95
103
  sections,
96
104
  totalBalancesAndVariance,
97
- fetchStatus: fetchStateAndError,
105
+ fetchStatus: reducedFetchStatus,
98
106
  bulkReviewStatus,
99
107
  reviewOperatingExpensesIds,
100
108
  selectedSectionIds,
@@ -1,5 +1,6 @@
1
1
  import omit from 'lodash/omit';
2
2
  import orderBy from 'lodash/orderBy';
3
+ import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
3
4
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
4
5
  import { getAccountIdsForTypes } from '../../../entity/account/accountSelector';
5
6
  import { getJEScheduledTransactionByJEScheduleTransactionKey, } from '../../../entity/jeSchedules/jeSchedulesSelector';
@@ -19,6 +20,8 @@ function getJEScheduleSortAccessor(sortKey) {
19
20
  return (s) => s.jeDebit.account?.accountName?.toLowerCase();
20
21
  case 'class':
21
22
  return (s) => s.jeDebit.accountingClass?.className?.toLowerCase();
23
+ case 'depCategory':
24
+ return (s) => s.jeCredit.account?.accountName?.toLowerCase();
22
25
  case 'scheduleCategory':
23
26
  return (s) => s.jeScheduleType;
24
27
  case 'startMonth':
@@ -50,7 +53,7 @@ function sortJEScheduledTransactions(transactions, sortKey, sortOrder) {
50
53
  export function getExpenseAutomationJESchedulesView(state) {
51
54
  const jeScheduledTransaction = [];
52
55
  const failedJeScheduledTransaction = [];
53
- const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, } = state;
56
+ const { accountState, accountListState, classState, classListState, expenseAutomationJESchedulesViewState, expenseAutomationViewState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
54
57
  const { jeScheduleTransactionKeysByPeriod, failedJeScheduleTransactionKeysByPeriod, jeScheduleLocalDataById, postStatusById, ignoreStatusById, uiState, error, fetchState, refreshStatus, } = expenseAutomationJESchedulesViewState;
55
58
  const accountSettingsView = getJEAccountSettingsView(state);
56
59
  const currentTenant = getCurrentTenant(state);
@@ -116,6 +119,13 @@ export function getExpenseAutomationJESchedulesView(state) {
116
119
  : [];
117
120
  const jeCompletionStatus = allSteps.find((step) => step.step === 'je_schedules')?.completionStatus;
118
121
  const completionStatus = jeCompletionStatus != null ? jeCompletionStatus : 'incomplete';
122
+ const monthEndFetchState = monthYearPeriodId != null
123
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
124
+ : { fetchState: 'Not-Started', error: undefined };
125
+ const reducedFetchStatus = reduceAnyFetchState([
126
+ { fetchState, error },
127
+ monthEndFetchState,
128
+ ]);
119
129
  return {
120
130
  uncategorizedAccounts,
121
131
  allDepreciationAccountList: filteredDepAccounts,
@@ -131,10 +141,10 @@ export function getExpenseAutomationJESchedulesView(state) {
131
141
  accountSettingsView,
132
142
  postStatusById: postStatusById,
133
143
  ignoreStatusById: ignoreStatusById,
134
- fetchState: fetchState,
144
+ fetchState: reducedFetchStatus.fetchState,
135
145
  jeScheduleLocalDataById: jeScheduleLocalDataById,
136
146
  uiState: uiState,
137
- error: error,
147
+ error: reducedFetchStatus.error,
138
148
  refreshStatus,
139
149
  completionStatus,
140
150
  };
@@ -1,4 +1,5 @@
1
1
  import orderBy from 'lodash/orderBy';
2
+ import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
2
3
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
3
4
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
4
5
  import { getSupportedTransactionById, getSupportedTransactionsByIds, } from '../../../entity/transaction/transactionSelector';
@@ -7,7 +8,7 @@ import { getCompletedTransactionsCacheKey } from '../reducers/missingReceiptsVie
7
8
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
8
9
  import { isUnmatchedTabFileStatus, } from '../types/missingReceiptsViewState';
9
10
  export function getExpenseAutomationMissingReceiptsView(state) {
10
- const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
11
+ const { expenseAutomationMissingReceiptsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
11
12
  const currentTenant = getCurrentTenant(state);
12
13
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
13
14
  const selectedPeriod = selectedPeriodByTenantId[currentTenant.tenantId];
@@ -175,9 +176,16 @@ export function getExpenseAutomationMissingReceiptsView(state) {
175
176
  vendorLogo: result.vendorLogo ?? transaction?.logo?.href,
176
177
  };
177
178
  });
179
+ const monthEndFetchState = monthYearPeriodId != null
180
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
181
+ : { fetchState: 'Not-Started', error: undefined };
182
+ const reducedFetchStatus = reduceAnyFetchState([
183
+ { fetchState, error },
184
+ monthEndFetchState,
185
+ ]);
178
186
  return {
179
- fetchState,
180
- error,
187
+ fetchState: reducedFetchStatus.fetchState,
188
+ error: reducedFetchStatus.error,
181
189
  uploadReceiptStatusById,
182
190
  uiState,
183
191
  refreshStatus,
@@ -13,7 +13,7 @@ import { getAccountList, getNestedAccountListHierarchy, } from '../../accountLis
13
13
  import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
14
14
  import { initialActionFetchState, initialReconciliationTabsState, initialState, } from '../reducers/reconciliationViewReducer';
15
15
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
16
- export const getExpenseAutomationReconciliationView = createSelector((state) => state, (state) => 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) => {
16
+ export const getExpenseAutomationReconciliationView = createSelector((state) => state, (state) => 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) => {
17
17
  const { selectedPeriodByTenantId } = expenseAutomationViewState;
18
18
  const reconcileTabUiState = reconciliationViewState.reconTabsState.reconcile.uiState;
19
19
  const reviewTabUiState = reconciliationViewState.reconTabsState.review.uiState;
@@ -35,6 +35,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
35
35
  }
36
36
  return acc;
37
37
  }, []);
38
+ const monthYearPeriodId = selectedPeriod != null ? toMonthYearPeriodId(selectedPeriod) : null;
39
+ const monthEndFetchState = monthYearPeriodId != null
40
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? {
41
+ fetchState: 'Not-Started',
42
+ error: undefined,
43
+ })
44
+ : { fetchState: 'Not-Started', error: undefined };
38
45
  if (accountReconForMonthYearPeriod == null) {
39
46
  return {
40
47
  bankAccounts: [],
@@ -44,10 +51,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
44
51
  classListNestedAccountHierarchy: [],
45
52
  allAccountList: [],
46
53
  allClassList: [],
47
- fetchStatus: {
48
- fetchState: reconciliationViewState.fetchState,
49
- error: reconciliationViewState.error,
50
- },
54
+ fetchStatus: reduceAnyFetchState([
55
+ {
56
+ fetchState: reconciliationViewState.fetchState,
57
+ error: reconciliationViewState.error,
58
+ },
59
+ monthEndFetchState,
60
+ ]),
51
61
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
52
62
  .plaidConnectionDetails,
53
63
  completionStatus: 'incomplete',
@@ -270,10 +280,13 @@ export const getExpenseAutomationReconciliationView = createSelector((state) =>
270
280
  bankAccounts: uniqueBankAccounts,
271
281
  creditCards: uniqueCreditCards,
272
282
  accountReconciliationsByAccountID: reconList,
273
- fetchStatus: {
274
- fetchState: reconciliationViewState.fetchState,
275
- error: reconciliationViewState.error,
276
- },
283
+ fetchStatus: reduceAnyFetchState([
284
+ {
285
+ fetchState: reconciliationViewState.fetchState,
286
+ error: reconciliationViewState.error,
287
+ },
288
+ monthEndFetchState,
289
+ ]),
277
290
  plaidConnectionDetails: plaidAccountViewState['expense_automation_reconcile']
278
291
  .plaidConnectionDetails,
279
292
  reconciliationTabsState: reconciliationViewState.reconTabsState,
@@ -1,5 +1,5 @@
1
1
  import omit from 'lodash/omit';
2
- import { reduceAllFetchState } from '../../../commonStateTypes/reduceFetchState';
2
+ import { reduceAllFetchState, reduceAnyFetchState, } from '../../../commonStateTypes/reduceFetchState';
3
3
  import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
4
4
  import { getCurrentTenant } from '../../../entity/tenant/tenantSelector';
5
5
  import { getTransactionWithCOT } from '../../../entity/transaction/transactionHelper';
@@ -8,7 +8,7 @@ import { getAccountList, getNestedAccountListHierarchy, getUncategorizedAccounts
8
8
  import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
9
9
  import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
10
10
  export function getExpenseAutomationTransactionView(state) {
11
- const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, } = state;
11
+ const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
12
12
  const { selectedTransactionCategorizationTab } = expenseAutomationTransactionsViewState;
13
13
  const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
14
14
  const uncategorizedIncomeExpense = getUncategorizedAccounts(accountState, accountListState, 'accountList');
@@ -41,10 +41,16 @@ export function getExpenseAutomationTransactionView(state) {
41
41
  .filter((transaction) => transaction != null);
42
42
  const transactions = getSupportedTransactionsByIds(transactionState, transactionIds);
43
43
  const transactionsWithCOT = transactions.map((transaction) => getTransactionWithCOT(transaction));
44
- const fetchStatus = reduceAllFetchState([
45
- accountList,
46
- classList,
47
- expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
44
+ const monthEndFetchState = monthYearPeriodId != null
45
+ ? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
46
+ : { fetchState: 'Not-Started', error: undefined };
47
+ const fetchStatus = reduceAnyFetchState([
48
+ reduceAllFetchState([
49
+ accountList,
50
+ classList,
51
+ expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab],
52
+ ]),
53
+ monthEndFetchState,
48
54
  ]);
49
55
  const totalCountByReview = expenseAutomationTransactionsViewState.transactionCategorizationView.review
50
56
  .uiState.totalCount;
@@ -3,6 +3,7 @@ const JE_SCHEDULE_SORT_KEYS = [
3
3
  'vendor',
4
4
  'category',
5
5
  'class',
6
+ 'depCategory',
6
7
  'scheduleCategory',
7
8
  'startMonth',
8
9
  'type',
@@ -49,16 +49,11 @@ export const getProfitAndLossClassesHorizontalView = (filter, accountState, clas
49
49
  const calculatedSections = {};
50
50
  let reportCurrency = defaultCustomerCurrency;
51
51
  if (fetchState.fetchState === 'Completed' && selectedPeriod != null) {
52
- // Get section reports using existing selector infrastructure
53
- const sectionReports = {};
54
- HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
55
- sectionReports[sectionId] = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
56
- });
57
52
  reportCurrency =
58
53
  profitAndLossClassesViewState.currency ?? defaultCustomerCurrency;
59
- // Pivot each section from class→account to account→class
54
+ // Fetch each section and pivot class→account to account→class in one pass
60
55
  HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
61
- const sectionReport = sectionReports[sectionId];
56
+ const sectionReport = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
62
57
  if (sectionReport != null) {
63
58
  sections[sectionId] = pivotSectionToHorizontal(sectionReport, classColumns, SECTION_TITLES[sectionId] ?? sectionId, reportCurrency);
64
59
  }
@@ -261,7 +256,7 @@ function sumBalancesInSlice(balances) {
261
256
  if (balances.length === 0) {
262
257
  return 0;
263
258
  }
264
- const summed = getSummationFreeRangeTotalBalance([...balances]);
259
+ const summed = getSummationFreeRangeTotalBalance(balances);
265
260
  return summed?.balance.amount ?? 0;
266
261
  }
267
262
  /**