@zeniai/client-epic-state 4.19.99-betaRD6 → 4.19.99-betaRD7

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 (45) hide show
  1. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +3 -1
  2. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +7 -5
  3. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerSelector.d.ts +1 -1
  4. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerState.d.ts +2 -2
  5. package/lib/entity/aiAccountantCustomer/aiAccountantCustomerState.js +1 -0
  6. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +9 -6
  7. package/lib/entity/jeSchedules/jeSchedulesPayload.js +36 -2
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +4 -2
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.js +5 -2
  10. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +26 -2
  11. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +4 -1
  12. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  13. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +1 -0
  14. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerPayload.js +3 -1
  15. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerReducer.js +7 -5
  16. package/lib/esm/entity/aiAccountantCustomer/aiAccountantCustomerState.js +1 -0
  17. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +36 -2
  18. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +5 -2
  19. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +1 -0
  20. package/lib/esm/view/aiAccountantView/aiAccountantViewReducer.js +6 -4
  21. package/lib/esm/view/aiAccountantView/aiAccountantViewSelector.js +3 -3
  22. package/lib/esm/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  23. package/lib/esm/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  24. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +13 -3
  25. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +11 -3
  26. package/lib/esm/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  27. package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -6
  28. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +1 -0
  29. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -8
  30. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +140 -59
  31. package/lib/index.d.ts +2 -2
  32. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  33. package/lib/view/aiAccountantView/aiAccountantViewReducer.js +6 -4
  34. package/lib/view/aiAccountantView/aiAccountantViewSelector.js +3 -3
  35. package/lib/view/expenseAutomationView/expenseAutomationViewSelector.js +0 -1
  36. package/lib/view/expenseAutomationView/selectors/fluxAnalysisViewSelector.js +10 -2
  37. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +13 -3
  38. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +11 -3
  39. package/lib/view/expenseAutomationView/selectors/reconciliationViewSelector.js +22 -9
  40. package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +11 -5
  41. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +1 -1
  42. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +1 -0
  43. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +3 -8
  44. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +140 -59
  45. package/package.json +1 -1
@@ -7,7 +7,9 @@ const aiAccountantCustomerState_1 = require("./aiAccountantCustomerState");
7
7
  const toAiAccountantEnrollment = (payload) => ({
8
8
  status: (0, aiAccountantCustomerState_1.toAiAccountantEnrollmentStatus)(payload.status),
9
9
  accuracy: payload.accuracy,
10
- latestTraining: payload.latest_training,
10
+ latestTraining: payload.latest_training != null
11
+ ? (0, zeniDayJS_1.date)(payload.latest_training)
12
+ : undefined,
11
13
  latestTransactionSync: payload.latest_transaction_sync != null
12
14
  ? (0, zeniDayJS_1.date)(payload.latest_transaction_sync)
13
15
  : undefined,
@@ -13,10 +13,12 @@ const aiAccountantCustomer = (0, toolkit_1.createSlice)({
13
13
  initialState: exports.initialAiAccountantCustomerState,
14
14
  reducers: {
15
15
  updateAiAccountantCustomers(draft, action) {
16
+ const newCustomerByTenantId = {};
16
17
  action.payload.forEach((payload) => {
17
18
  const customer = (0, aiAccountantCustomerPayload_1.toAiAccountantCustomer)(payload);
18
- draft.customerByTenantId[customer.tenantId] = customer;
19
+ newCustomerByTenantId[customer.tenantId] = customer;
19
20
  });
21
+ draft.customerByTenantId = newCustomerByTenantId;
20
22
  },
21
23
  updateAiAccountantCustomer(draft, action) {
22
24
  const customer = (0, aiAccountantCustomerPayload_1.toAiAccountantCustomer)(action.payload);
@@ -27,10 +29,10 @@ const aiAccountantCustomer = (0, toolkit_1.createSlice)({
27
29
  const mappedJobs = action.payload.jobs.map(aiAccountantCustomerPayload_1.toAiAccountantJob);
28
30
  if (action.payload.append) {
29
31
  const existing = draft.jobsByTenantId[action.payload.tenantId] ?? [];
30
- draft.jobsByTenantId[action.payload.tenantId] = [
31
- ...existing,
32
- ...mappedJobs,
33
- ];
32
+ const jobMap = new Map(existing.map((job) => [job.jobId, job]));
33
+ mappedJobs.forEach((job) => jobMap.set(job.jobId, job));
34
+ draft.jobsByTenantId[action.payload.tenantId] =
35
+ Array.from(jobMap.values());
34
36
  }
35
37
  else {
36
38
  draft.jobsByTenantId[action.payload.tenantId] = mappedJobs;
@@ -6,7 +6,7 @@ import { AiAccountantCustomerState, AiAccountantEnrollmentStatus, AiAccountantJo
6
6
  export interface AiAccountantEnrollmentView {
7
7
  status: AiAccountantEnrollmentStatus;
8
8
  accuracy?: Record<string, number>;
9
- latestTraining?: string;
9
+ latestTraining?: ZeniDate;
10
10
  latestTransactionSync?: ZeniDate;
11
11
  offboardedAt?: ZeniDate;
12
12
  offboardedBy?: User;
@@ -4,12 +4,12 @@ export declare const toAiAccountantOperationType: (v: string) => "onboard" | "of
4
4
  export type AiAccountantOperationType = ReturnType<typeof toAiAccountantOperationType>;
5
5
  export declare const toAiAccountantEnrollmentStatus: (v: string) => "onboarding" | "error" | "active" | "pending" | "offboarding" | "offboarded" | "failed";
6
6
  export type AiAccountantEnrollmentStatus = ReturnType<typeof toAiAccountantEnrollmentStatus>;
7
- export declare const toAiAccountantJobStatus: (v: string) => "failed" | "queued" | "running" | "completed" | "cancelled";
7
+ export declare const toAiAccountantJobStatus: (v: string) => "failed" | "queued" | "running" | "completed" | "cancelled" | "retried";
8
8
  export type AiAccountantJobStatus = ReturnType<typeof toAiAccountantJobStatus>;
9
9
  export interface AiAccountantEnrollment {
10
10
  status: AiAccountantEnrollmentStatus;
11
11
  accuracy?: Record<string, number>;
12
- latestTraining?: string;
12
+ latestTraining?: ZeniDate;
13
13
  latestTransactionSync?: ZeniDate;
14
14
  offboardedAt?: ZeniDate;
15
15
  offboardedBy?: ID;
@@ -31,6 +31,7 @@ const ALL_JOB_STATUSES = [
31
31
  'completed',
32
32
  'failed',
33
33
  'cancelled',
34
+ 'retried',
34
35
  ];
35
36
  const toAiAccountantJobStatus = (v) => (0, stringToUnion_1.stringToUnion)(v, ALL_JOB_STATUSES);
36
37
  exports.toAiAccountantJobStatus = toAiAccountantJobStatus;
@@ -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
  }
@@ -4,7 +4,9 @@ import { toAiAccountantEnrollmentStatus, toAiAccountantJobStatus, toAiAccountant
4
4
  export const toAiAccountantEnrollment = (payload) => ({
5
5
  status: toAiAccountantEnrollmentStatus(payload.status),
6
6
  accuracy: payload.accuracy,
7
- latestTraining: payload.latest_training,
7
+ latestTraining: payload.latest_training != null
8
+ ? date(payload.latest_training)
9
+ : undefined,
8
10
  latestTransactionSync: payload.latest_transaction_sync != null
9
11
  ? date(payload.latest_transaction_sync)
10
12
  : undefined,
@@ -9,10 +9,12 @@ const aiAccountantCustomer = createSlice({
9
9
  initialState: initialAiAccountantCustomerState,
10
10
  reducers: {
11
11
  updateAiAccountantCustomers(draft, action) {
12
+ const newCustomerByTenantId = {};
12
13
  action.payload.forEach((payload) => {
13
14
  const customer = toAiAccountantCustomer(payload);
14
- draft.customerByTenantId[customer.tenantId] = customer;
15
+ newCustomerByTenantId[customer.tenantId] = customer;
15
16
  });
17
+ draft.customerByTenantId = newCustomerByTenantId;
16
18
  },
17
19
  updateAiAccountantCustomer(draft, action) {
18
20
  const customer = toAiAccountantCustomer(action.payload);
@@ -23,10 +25,10 @@ const aiAccountantCustomer = createSlice({
23
25
  const mappedJobs = action.payload.jobs.map(toAiAccountantJob);
24
26
  if (action.payload.append) {
25
27
  const existing = draft.jobsByTenantId[action.payload.tenantId] ?? [];
26
- draft.jobsByTenantId[action.payload.tenantId] = [
27
- ...existing,
28
- ...mappedJobs,
29
- ];
28
+ const jobMap = new Map(existing.map((job) => [job.jobId, job]));
29
+ mappedJobs.forEach((job) => jobMap.set(job.jobId, job));
30
+ draft.jobsByTenantId[action.payload.tenantId] =
31
+ Array.from(jobMap.values());
30
32
  }
31
33
  else {
32
34
  draft.jobsByTenantId[action.payload.tenantId] = mappedJobs;
@@ -26,5 +26,6 @@ const ALL_JOB_STATUSES = [
26
26
  'completed',
27
27
  'failed',
28
28
  'cancelled',
29
+ 'retried',
29
30
  ];
30
31
  export const toAiAccountantJobStatus = (v) => stringToUnion(v, ALL_JOB_STATUSES);
@@ -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
  };
@@ -21,7 +21,7 @@ const aiAccountantView = createSlice({
21
21
  draft.customersFetchStatus = { fetchState: 'In-Progress' };
22
22
  },
23
23
  updateAiAccountantCustomers(draft, action) {
24
- draft.customersByTenantId = toCustomersByTenantId(action.payload);
24
+ draft.customersByTenantId = toCustomersByTenantId(action.payload, draft.customersByTenantId);
25
25
  draft.customersFetchStatus = { fetchState: 'Completed' };
26
26
  },
27
27
  updateAiAccountantCustomersFailure(draft, action) {
@@ -133,14 +133,16 @@ const aiAccountantView = createSlice({
133
133
  export const { cancelAiAccountantOnboarding, cancelAiAccountantOnboardingFailure, cancelAiAccountantOnboardingSuccess, clearAiAccountantView, fetchAiAccountantCustomers, fetchAiAccountantJobs, setSelectedTenantIdsForJobTrigger, triggerAiAccountantJob, triggerAiAccountantJobFailure, triggerAiAccountantJobSuccess, updateAiAccountantCustomers, updateAiAccountantCustomersFailure, updateAiAccountantJobs, updateAiAccountantJobsFailure, updateAiAccountantUIState, } = aiAccountantView.actions;
134
134
  export default aiAccountantView.reducer;
135
135
  // ── Helpers ──
136
- const toCustomersByTenantId = (customers) => {
136
+ const toCustomersByTenantId = (customers, existing) => {
137
137
  const result = {};
138
138
  for (const payload of customers) {
139
- result[payload.tenant_id] = {
139
+ const tenantId = payload.tenant_id;
140
+ const existingState = existing[tenantId];
141
+ result[tenantId] = existingState ?? {
140
142
  cancelOnboardingStatus: { fetchState: 'Not-Started' },
141
143
  jobsFetchStatus: { fetchState: 'Not-Started' },
142
144
  jobsPageToken: null,
143
- tenantId: payload.tenant_id,
145
+ tenantId,
144
146
  };
145
147
  }
146
148
  return result;
@@ -48,11 +48,11 @@ const getSortedCustomers = (customers, sortKey, sortOrder) => {
48
48
  case 'status':
49
49
  return (customer.enrollment?.status ?? 'unknown').toLowerCase();
50
50
  case 'bookcloseDate':
51
- return customer.bookcloseDate ?? '';
51
+ return customer.bookcloseDate?.valueOf() ?? 0;
52
52
  case 'latestTraining':
53
- return customer.enrollment?.latestTraining ?? '';
53
+ return customer.enrollment?.latestTraining?.valueOf() ?? 0;
54
54
  case 'latestSync':
55
- return customer.enrollment?.latestTransactionSync ?? '';
55
+ return customer.enrollment?.latestTransactionSync?.valueOf() ?? 0;
56
56
  case 'accuracy':
57
57
  return customer.averageAccuracy;
58
58
  default:
@@ -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
  };