@zeniai/client-epic-state 5.1.91 → 5.1.92-betaRD0

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 (126) hide show
  1. package/lib/entity/aiCfo/aiCfoState.d.ts +2 -2
  2. package/lib/entity/jeSchedules/jeScheduleHelper.d.ts +2 -0
  3. package/lib/entity/jeSchedules/jeScheduleHelper.js +7 -0
  4. package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +66 -1
  5. package/lib/entity/jeSchedules/jeSchedulesPayload.js +135 -0
  6. package/lib/entity/jeSchedules/jeSchedulesReducer.d.ts +4 -2
  7. package/lib/entity/jeSchedules/jeSchedulesReducer.js +24 -2
  8. package/lib/entity/jeSchedules/jeSchedulesSelector.d.ts +11 -2
  9. package/lib/entity/jeSchedules/jeSchedulesSelector.js +34 -3
  10. package/lib/entity/jeSchedules/jeSchedulesState.d.ts +79 -1
  11. package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +24 -1
  12. package/lib/entity/jeSchedules/jeSchedulesTypes.js +88 -1
  13. package/lib/entity/snackbar/snackbarApiError.d.ts +8 -0
  14. package/lib/entity/snackbar/snackbarApiError.js +15 -0
  15. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  16. package/lib/entity/snackbar/snackbarTypes.js +1 -0
  17. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.d.ts +2 -0
  18. package/lib/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  19. package/lib/entity/transaction/stateTypes/scheduleTransaction.d.ts +2 -0
  20. package/lib/epic.d.ts +8 -1
  21. package/lib/epic.js +8 -1
  22. package/lib/esm/entity/jeSchedules/jeScheduleHelper.js +6 -0
  23. package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +135 -1
  24. package/lib/esm/entity/jeSchedules/jeSchedulesReducer.js +24 -2
  25. package/lib/esm/entity/jeSchedules/jeSchedulesSelector.js +32 -2
  26. package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +78 -0
  27. package/lib/esm/entity/snackbar/snackbarApiError.js +11 -0
  28. package/lib/esm/entity/snackbar/snackbarTypes.js +1 -0
  29. package/lib/esm/entity/transaction/payloadTypes/scheduleTransactionPayload.js +2 -0
  30. package/lib/esm/epic.js +8 -1
  31. package/lib/esm/index.js +13 -7
  32. package/lib/esm/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  33. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +41 -5
  34. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  35. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +81 -0
  36. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +21 -0
  37. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +110 -0
  38. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +73 -0
  39. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +129 -0
  40. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +92 -0
  41. package/lib/esm/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +22 -0
  42. package/lib/esm/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +140 -0
  43. package/lib/esm/view/expenseAutomationView/payload/jeSchedulesPayload.js +55 -0
  44. package/lib/esm/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +268 -29
  45. package/lib/esm/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +1 -0
  46. package/lib/esm/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +106 -0
  47. package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +286 -22
  48. package/lib/esm/view/expenseAutomationView/types/jeSchedulesViewState.js +5 -6
  49. package/lib/esm/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
  50. package/lib/esm/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
  51. package/lib/esm/view/invoicing/discountAction/discountActionEpic.js +6 -3
  52. package/lib/esm/view/invoicing/dunningAction/dunningActionEpic.js +6 -3
  53. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
  54. package/lib/esm/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
  55. package/lib/esm/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
  56. package/lib/esm/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
  57. package/lib/esm/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
  58. package/lib/esm/view/invoicing/invoiceAction/invoiceActionEpic.js +7 -3
  59. package/lib/esm/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
  60. package/lib/esm/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
  61. package/lib/esm/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
  62. package/lib/esm/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
  63. package/lib/esm/view/invoicing/settingsView/settingsViewEpics.js +6 -3
  64. package/lib/esm/view/invoicing/settingsView/settingsViewSelector.js +52 -0
  65. package/lib/esm/view/invoicing/subscriptionAction/subscriptionActionEpic.js +6 -3
  66. package/lib/esm/view/vendorTabView/vendorTabViewReducer.js +1 -1
  67. package/lib/index.d.ts +18 -14
  68. package/lib/index.js +92 -49
  69. package/lib/view/expenseAutomationView/epics/common/fetchAllExpenseAutomationTabsEpic.js +6 -3
  70. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.d.ts +3 -2
  71. package/lib/view/expenseAutomationView/epics/jeSchedule/fetchJeSchedulesEpic.js +38 -2
  72. package/lib/view/expenseAutomationView/epics/jeSchedule/ignoreRecommendedJeScheduleEpic.js +14 -2
  73. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.d.ts +8 -0
  74. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/createOneTimeAccrualEpic.js +85 -0
  75. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.d.ts +8 -0
  76. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/initializeNewScheduleEpic.js +25 -0
  77. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.d.ts +45 -0
  78. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +114 -0
  79. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.d.ts +8 -0
  80. package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/searchTransactionsForNewScheduleEpic.js +77 -0
  81. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.d.ts +12 -0
  82. package/lib/view/expenseAutomationView/epics/jeSchedule/oneTimeAccrualActionsEpic.js +136 -0
  83. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.d.ts +65 -0
  84. package/lib/view/expenseAutomationView/epics/jeSchedule/revertJeScheduleEpic.js +96 -0
  85. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.d.ts +6 -0
  86. package/lib/view/expenseAutomationView/epics/jeSchedule/switchJESchedulesTabEpic.js +26 -0
  87. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.d.ts +36 -0
  88. package/lib/view/expenseAutomationView/helpers/newScheduleLocalDataHelper.js +145 -0
  89. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  90. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.d.ts +72 -3
  91. package/lib/view/expenseAutomationView/payload/jeSchedulesPayload.js +58 -1
  92. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.d.ts +79 -11
  93. package/lib/view/expenseAutomationView/reducers/jeSchedulesViewReducer.js +270 -29
  94. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +1 -1
  95. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  96. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.d.ts +42 -0
  97. package/lib/view/expenseAutomationView/selectorTypes/jeNewScheduleViewSelectorTypes.js +2 -0
  98. package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +34 -8
  99. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.d.ts +21 -0
  100. package/lib/view/expenseAutomationView/selectors/jeNewScheduleViewSelector.js +112 -0
  101. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.d.ts +31 -1
  102. package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +294 -21
  103. package/lib/view/expenseAutomationView/types/completedSubTab.d.ts +1 -1
  104. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.d.ts +81 -8
  105. package/lib/view/expenseAutomationView/types/jeSchedulesViewState.js +8 -8
  106. package/lib/view/invoicing/createCreditNote/createCreditNoteEpic.js +2 -0
  107. package/lib/view/invoicing/createInvoice/createInvoiceEpic.js +2 -0
  108. package/lib/view/invoicing/discountAction/discountActionEpic.js +5 -2
  109. package/lib/view/invoicing/dunningAction/dunningActionEpic.js +5 -2
  110. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/editInvoicingCatalogItemDetailViewPayload.js +5 -4
  111. package/lib/view/invoicing/editInvoicingCatalogItemDetailView/saveInvoicingCatalogItemEpic.js +3 -0
  112. package/lib/view/invoicing/editInvoicingCouponDetailView/saveInvoicingCouponEpic.js +2 -0
  113. package/lib/view/invoicing/editInvoicingCustomerDetailView/saveInvoicingCustomerEpic.js +2 -0
  114. package/lib/view/invoicing/editInvoicingSubscriptionDetailView/saveInvoicingSubscriptionEpic.js +2 -0
  115. package/lib/view/invoicing/invoiceAction/invoiceActionEpic.js +6 -2
  116. package/lib/view/invoicing/invoicingQboView/epics/retryInvoicingQboSyncTaskEpic.js +2 -0
  117. package/lib/view/invoicing/invoicingQboView/epics/startInvoicingQboBackfillEpic.js +2 -0
  118. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewReducer.d.ts +1 -1
  119. package/lib/view/invoicing/invoicingSubscriptionListView/invoicingSubscriptionListViewState.d.ts +1 -1
  120. package/lib/view/invoicing/issueCreditNote/issueCreditNoteEpic.js +2 -0
  121. package/lib/view/invoicing/recordPayment/recordPaymentEpic.js +3 -0
  122. package/lib/view/invoicing/settingsView/settingsViewEpics.js +5 -2
  123. package/lib/view/invoicing/settingsView/settingsViewSelector.d.ts +41 -1
  124. package/lib/view/invoicing/settingsView/settingsViewSelector.js +55 -1
  125. package/lib/view/invoicing/subscriptionAction/subscriptionActionEpic.js +5 -2
  126. package/package.json +1 -1
@@ -140,9 +140,9 @@ export interface AiCfoVisualization {
140
140
  data: TableVisualization | ChartVisualization | InteractiveFormVisualization;
141
141
  type: AiCfoVisualizationType;
142
142
  }
143
- export declare const toMessageSender: (v: string) => "user" | "agent";
143
+ export declare const toMessageSender: (v: string) => "agent" | "user";
144
144
  export declare const toMessageType: (v: string) => "plain_text" | "json";
145
- export declare const toMessageSenderStrict: (v: string) => "user" | "agent" | undefined;
145
+ export declare const toMessageSenderStrict: (v: string) => "agent" | "user" | undefined;
146
146
  export declare const toMessageTypeStrict: (v: string) => "plain_text" | "json" | undefined;
147
147
  export type MessageSender = ReturnType<typeof toMessageSender>;
148
148
  export type MessageType = ReturnType<typeof toMessageType>;
@@ -1,2 +1,4 @@
1
+ import { ID } from '../../commonStateTypes/common';
1
2
  import { JEAccruedScheduledTransactionPayload } from './jeSchedulesPayload';
2
3
  export declare function generateJEScheduleKey(payload: JEAccruedScheduledTransactionPayload): `${string}_${string}`;
4
+ export declare function generateJEOneTimeAccrualKey(accrualId: ID): `${string}_one_time_accrual`;
@@ -1,6 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateJEScheduleKey = generateJEScheduleKey;
4
+ exports.generateJEOneTimeAccrualKey = generateJEOneTimeAccrualKey;
4
5
  function generateJEScheduleKey(payload) {
5
6
  return `${payload.je_schedule_id}_${payload.je_schedule_type}`;
6
7
  }
8
+ // Suffixed rather than using the bare Mongo _id so the key is a distinct type from
9
+ // JEScheduleKey / JEScheduleTransactionKey and the three cannot be passed interchangeably.
10
+ // The unsuffixed id stays on the entity as `accrualId` for callers that need it.
11
+ function generateJEOneTimeAccrualKey(accrualId) {
12
+ return `${accrualId}_one_time_accrual`;
13
+ }
@@ -7,7 +7,7 @@ import { TransactionIDPayload } from '../transaction/payloadTypes/transactionIDP
7
7
  import { TransactionCategory } from '../transaction/stateTypes/transactionType';
8
8
  import { UserPayload } from '../user/userPayload';
9
9
  import { VendorPayload } from '../vendor/vendorPayload';
10
- import { JEAccruedScheduledTransactionState, JEScheduledTransactionState, ScheduledJournalEntryState } from './jeSchedulesState';
10
+ import { JEAccruedScheduledTransactionState, JEOneTimeAccrualState, JEScheduledTransactionState, ScheduledJournalEntryState } from './jeSchedulesState';
11
11
  import { JEScheduleKey, JEScheduleTransactionKey } from './jeSchedulesTypes';
12
12
  export interface JEScheduleOtherAttributesPayload {
13
13
  asset_id?: string | null;
@@ -72,9 +72,13 @@ export interface JEScheduledTransactionPayload {
72
72
  updated_by: UserPayload;
73
73
  vendor: VendorPayload;
74
74
  ai_summaries?: JEScheduleAISummariesPayload;
75
+ confidence_score?: number | null;
76
+ create_time?: string | null;
75
77
  created_by?: UserPayload;
76
78
  end_date?: string | null;
79
+ posted_count?: number | null;
77
80
  recommendations?: JEScheduleRecommendationsPayload;
81
+ recurring_amount?: number | null;
78
82
  updated_at?: string | null;
79
83
  }
80
84
  export interface JEAccruedScheduledTransactionPayload extends Omit<JEScheduledTransactionPayload, 'base_transaction' | 'je_schedule_id' | 'je_schedule_type'> {
@@ -84,6 +88,66 @@ export interface JEAccruedScheduledTransactionPayload extends Omit<JEScheduledTr
84
88
  memo: string;
85
89
  recurring_amount: number;
86
90
  }
91
+ /**
92
+ * The frozen vendor profile the Cron used to decide an accrual, so the detail page can show its
93
+ * reasoning even after the live profile is rebuilt. Present on agent/Cron rows ONLY — a human-created
94
+ * accrual carries none, which is why every consumer has to treat it as absent rather than empty.
95
+ */
96
+ export interface JEOneTimeAccrualProfileSnapshotPayload {
97
+ billing_pattern?: {
98
+ avg_amount?: number | null;
99
+ billing_lag_days?: number | null;
100
+ consistency_score?: number | null;
101
+ frequency?: string | null;
102
+ last_bill_amount?: number | null;
103
+ last_bill_date?: string | null;
104
+ months_of_history?: number | null;
105
+ typical_bill_day?: number | null;
106
+ } | null;
107
+ monthly_totals?: Record<string, number> | null;
108
+ sorted_months?: string[] | null;
109
+ }
110
+ /** The JE the AI originally suggested, frozen at draft time for suggested-vs-posted comparison. */
111
+ export interface JEOneTimeAccrualAiSuggestionPayload {
112
+ estimated_amount?: number | null;
113
+ je_credit_account_id?: ID | null;
114
+ je_credit_account_name?: string | null;
115
+ je_debit_account_id?: ID | null;
116
+ je_debit_account_name?: string | null;
117
+ memo?: string | null;
118
+ }
119
+ export interface JEOneTimeAccrualPayload {
120
+ _id: ID;
121
+ estimated_amount: number;
122
+ origin: string;
123
+ service_month: string;
124
+ status: string;
125
+ vendor_id: ID;
126
+ vendor_name: string;
127
+ actual_post_date?: string | null;
128
+ actual_reversal_post_date?: string | null;
129
+ ai_suggestion?: JEOneTimeAccrualAiSuggestionPayload | null;
130
+ automation_tier?: string | null;
131
+ created_by_user?: UserPayload | null;
132
+ currency?: string | null;
133
+ expected_reversal_date?: string | null;
134
+ je_credit_account_id?: ID | null;
135
+ je_credit_account_name?: string | null;
136
+ je_credit_accounting_class_id?: ID | null;
137
+ je_credit_accounting_class_name?: string | null;
138
+ je_debit_account_id?: ID | null;
139
+ je_debit_account_name?: string | null;
140
+ je_debit_accounting_class_id?: ID | null;
141
+ je_debit_accounting_class_name?: string | null;
142
+ memo?: string | null;
143
+ posting_date?: string | null;
144
+ profile_snapshot?: JEOneTimeAccrualProfileSnapshotPayload | null;
145
+ reversal_policy?: string | null;
146
+ reversal_transaction_id?: ID | null;
147
+ reversal_trigger?: string | null;
148
+ transaction_id?: ID | null;
149
+ transaction_integration_id?: ID | null;
150
+ }
87
151
  export interface ScheduledJournalEntryPayload {
88
152
  actual_post_date: string | null;
89
153
  create_time: string | null;
@@ -114,3 +178,4 @@ export declare function getJEScheduleTransactionDetailKeyPayload(payload: Schedu
114
178
  export declare function getJEScheduleKey(payload: JEAccruedScheduledTransactionPayload): JEScheduleKey;
115
179
  export declare function toJEScheduledTransaction(payload: JEScheduledTransactionPayload): JEScheduledTransactionState;
116
180
  export declare function toJEAccruedScheduledTransaction(payload: JEAccruedScheduledTransactionPayload): JEAccruedScheduledTransactionState;
181
+ export declare function toJEOneTimeAccrual(payload: JEOneTimeAccrualPayload): JEOneTimeAccrualState;
@@ -8,12 +8,15 @@ exports.getJEScheduleTransactionDetailKeyPayload = getJEScheduleTransactionDetai
8
8
  exports.getJEScheduleKey = getJEScheduleKey;
9
9
  exports.toJEScheduledTransaction = toJEScheduledTransaction;
10
10
  exports.toJEAccruedScheduledTransaction = toJEAccruedScheduledTransaction;
11
+ exports.toJEOneTimeAccrual = toJEOneTimeAccrual;
11
12
  const amount_1 = require("../../commonStateTypes/amount");
12
13
  const timePeriod_1 = require("../../commonStateTypes/timePeriod");
13
14
  const zeniDayJS_1 = require("../../zeniDayJS");
15
+ const zeniUrl_1 = require("../../zeniUrl");
14
16
  const transactionIDPayload_1 = require("../transaction/payloadTypes/transactionIDPayload");
15
17
  const jeScheduleHelper_1 = require("./jeScheduleHelper");
16
18
  const jeSchedulesTypes_1 = require("./jeSchedulesTypes");
19
+ const USD_CURRENCY_CODE = 'USD';
17
20
  function toScheduledJournalEntryState(payload, currency_code, currency_symbol) {
18
21
  return {
19
22
  status: {
@@ -258,9 +261,18 @@ function toJEScheduledTransaction(payload) {
258
261
  startDate: payload.start_date != null ? (0, zeniDayJS_1.date)(payload.start_date) : undefined,
259
262
  endDate: payload.end_date != null ? (0, zeniDayJS_1.date)(payload.end_date) : undefined,
260
263
  period: payload.period != null ? Number(payload.period) : undefined,
264
+ recurringAmount: payload.recurring_amount != null
265
+ ? {
266
+ amount: payload.recurring_amount,
267
+ currencyCode: payload.currency_code,
268
+ currencySymbol: payload.currency_symbol,
269
+ }
270
+ : undefined,
271
+ postedCount: payload.posted_count ?? undefined,
261
272
  updatedByUserID: payload.updated_by.user_id,
262
273
  balanceAsOfToday: payload.balance ?? undefined,
263
274
  updatedAt: payload.updated_at != null ? (0, zeniDayJS_1.date)(payload.updated_at) : undefined,
275
+ createTime: payload.create_time != null ? (0, zeniDayJS_1.date)(payload.create_time) : undefined,
264
276
  jeCredit: {
265
277
  accountId: payload.je_credit_account_id ?? undefined,
266
278
  accountingClassId: payload.je_credit_accounting_class_id ?? undefined,
@@ -285,6 +297,7 @@ function toJEScheduledTransaction(payload) {
285
297
  : {},
286
298
  scheduledJournalEntry: [],
287
299
  aiSummaries: toJEScheduleAISummaries(payload.ai_summaries),
300
+ confidenceScore: payload.confidence_score ?? undefined,
288
301
  createdByUserID: payload.created_by?.user_id ?? undefined,
289
302
  recommendations: toJEScheduleRecommendations(payload.recommendations),
290
303
  };
@@ -342,3 +355,125 @@ function toJEAccruedScheduledTransaction(payload) {
342
355
  jeScheduleType: (0, jeSchedulesTypes_1.toScheduleTypesTypeStrict)(payload.je_schedule_type),
343
356
  };
344
357
  }
358
+ /**
359
+ * Reads the months in the order the snapshot gives them rather than deriving a range: a vendor that
360
+ * skipped a month has no entry for it, so filling gaps would invent history that was never billed.
361
+ */
362
+ function toJEOneTimeAccrualMonthlyTotals(snapshot, currencyCode) {
363
+ const monthlyTotals = snapshot.monthly_totals;
364
+ if (monthlyTotals == null) {
365
+ return [];
366
+ }
367
+ const months = snapshot.sorted_months ?? Object.keys(monthlyTotals).sort();
368
+ return months
369
+ .filter((month) => monthlyTotals[month] != null)
370
+ .map((month) => ({
371
+ month,
372
+ amount: toOneTimeAccrualAmount(monthlyTotals[month], currencyCode),
373
+ }));
374
+ }
375
+ function toJEOneTimeAccrualProfileSnapshot(payload, currencyCode) {
376
+ if (payload == null) {
377
+ return undefined;
378
+ }
379
+ const billingPattern = payload.billing_pattern;
380
+ return {
381
+ monthlyTotals: toJEOneTimeAccrualMonthlyTotals(payload, currencyCode),
382
+ billingPattern: billingPattern != null
383
+ ? {
384
+ frequency: billingPattern.frequency ?? undefined,
385
+ monthsOfHistory: billingPattern.months_of_history ?? undefined,
386
+ consistencyScore: billingPattern.consistency_score ?? undefined,
387
+ billingLagDays: billingPattern.billing_lag_days ?? undefined,
388
+ typicalBillDay: billingPattern.typical_bill_day ?? undefined,
389
+ avgAmount: billingPattern.avg_amount != null
390
+ ? toOneTimeAccrualAmount(billingPattern.avg_amount, currencyCode)
391
+ : undefined,
392
+ lastBillAmount: billingPattern.last_bill_amount != null
393
+ ? toOneTimeAccrualAmount(billingPattern.last_bill_amount, currencyCode)
394
+ : undefined,
395
+ lastBillDate: billingPattern.last_bill_date != null
396
+ ? (0, zeniDayJS_1.date)(billingPattern.last_bill_date)
397
+ : undefined,
398
+ }
399
+ : undefined,
400
+ };
401
+ }
402
+ function toJEOneTimeAccrualAiSuggestion(payload, currencyCode) {
403
+ if (payload == null) {
404
+ return undefined;
405
+ }
406
+ return {
407
+ memo: payload.memo ?? undefined,
408
+ jeDebitAccountName: payload.je_debit_account_name ?? undefined,
409
+ jeCreditAccountName: payload.je_credit_account_name ?? undefined,
410
+ estimatedAmount: payload.estimated_amount != null
411
+ ? toOneTimeAccrualAmount(payload.estimated_amount, currencyCode)
412
+ : undefined,
413
+ };
414
+ }
415
+ function toJEOneTimeAccrual(payload) {
416
+ return {
417
+ accrualId: payload._id,
418
+ vendorId: payload.vendor_id,
419
+ vendorName: payload.vendor_name,
420
+ serviceMonth: payload.service_month,
421
+ accrualStatus: (0, jeSchedulesTypes_1.toOneTimeAccrualStatusCodeType)(payload.status),
422
+ origin: (0, jeSchedulesTypes_1.toOneTimeAccrualOriginType)(payload.origin),
423
+ automationTier: payload.automation_tier != null
424
+ ? (0, jeSchedulesTypes_1.toOneTimeAccrualAutomationTierType)(payload.automation_tier)
425
+ : undefined,
426
+ estimatedAmount: toOneTimeAccrualAmount(payload.estimated_amount, payload.currency),
427
+ memo: payload.memo ?? '',
428
+ profileSnapshot: toJEOneTimeAccrualProfileSnapshot(payload.profile_snapshot, payload.currency),
429
+ aiSuggestion: toJEOneTimeAccrualAiSuggestion(payload.ai_suggestion, payload.currency),
430
+ // Exclusive by contract: a scheduled row reverses on expectedReversalDate and bills never
431
+ // drive it, so the two never need reconciling. Defaulting to on_bill_match matches the
432
+ // create path's default when the field is absent on an older document.
433
+ reversalPolicy: (0, jeSchedulesTypes_1.toOneTimeAccrualReversalPolicyType)(payload.reversal_policy ?? 'on_bill_match'),
434
+ reversalTrigger: (0, jeSchedulesTypes_1.toOneTimeAccrualReversalTriggerType)(payload.reversal_trigger ?? undefined),
435
+ expectedReversalDate: payload.expected_reversal_date != null
436
+ ? (0, zeniDayJS_1.date)(payload.expected_reversal_date)
437
+ : undefined,
438
+ postingDate: payload.posting_date != null ? (0, zeniDayJS_1.date)(payload.posting_date) : undefined,
439
+ actualPostDate: payload.actual_post_date != null
440
+ ? (0, zeniDayJS_1.date)(payload.actual_post_date)
441
+ : undefined,
442
+ actualReversalPostDate: payload.actual_reversal_post_date != null
443
+ ? (0, zeniDayJS_1.date)(payload.actual_reversal_post_date)
444
+ : undefined,
445
+ jeDebitAccountId: payload.je_debit_account_id ?? undefined,
446
+ jeDebitAccountName: payload.je_debit_account_name ?? undefined,
447
+ jeDebitAccountingClassId: payload.je_debit_accounting_class_id ?? undefined,
448
+ jeDebitAccountingClassName: payload.je_debit_accounting_class_name ?? undefined,
449
+ jeCreditAccountId: payload.je_credit_account_id ?? undefined,
450
+ jeCreditAccountName: payload.je_credit_account_name ?? undefined,
451
+ jeCreditAccountingClassId: payload.je_credit_accounting_class_id ?? undefined,
452
+ jeCreditAccountingClassName: payload.je_credit_accounting_class_name ?? undefined,
453
+ transactionId: payload.transaction_id ?? undefined,
454
+ transactionIntegrationId: payload.transaction_integration_id ?? undefined,
455
+ reversalTransactionId: payload.reversal_transaction_id ?? undefined,
456
+ createdBy: toJEOneTimeAccrualCreator(payload.created_by_user),
457
+ };
458
+ }
459
+ // The accrual wire format carries a currency CODE but no symbol, so the symbol has to be derived.
460
+ // Only USD has a known glyph today (the create path is USD-only); anything else falls back to the
461
+ // code, which reads correctly as "EUR 1,200" rather than silently rendering a wrong "$".
462
+ function toOneTimeAccrualAmount(amount, currencyCode) {
463
+ const code = currencyCode ?? USD_CURRENCY_CODE;
464
+ return (0, amount_1.toAmount)(amount, code, code === USD_CURRENCY_CODE ? '$' : code);
465
+ }
466
+ function toJEOneTimeAccrualCreator(payload) {
467
+ if (payload == null) {
468
+ return undefined;
469
+ }
470
+ return {
471
+ userId: payload.user_id,
472
+ email: payload.email ?? undefined,
473
+ firstName: payload.first_name ?? undefined,
474
+ lastName: payload.last_name ?? undefined,
475
+ photo: payload.photo?.original != null
476
+ ? (0, zeniUrl_1.toZeniUrl)(payload.photo.original)
477
+ : undefined,
478
+ };
479
+ }
@@ -1,5 +1,5 @@
1
1
  import { UpdateType } from '../../commonStateTypes/common';
2
- import { JEAccruedScheduledTransactionPayload, JEScheduledTransactionPayload, ScheduledJournalEntryPayload } from './jeSchedulesPayload';
2
+ import { JEAccruedScheduledTransactionPayload, JEOneTimeAccrualPayload, JEScheduledTransactionPayload, ScheduledJournalEntryPayload } from './jeSchedulesPayload';
3
3
  import { JESchedulesState } from './jeSchedulesState';
4
4
  export declare const initialState: JESchedulesState;
5
5
  export declare const updateJESchedules: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[jeSchedulesTransactionsPayload: JEScheduledTransactionPayload[]], {
@@ -22,6 +22,8 @@ export declare const updateJESchedules: import("@reduxjs/toolkit").ActionCreator
22
22
  jeScheduleTransactionKey: `${string}_expense_${string}` | `${string}_check_${string}` | `${string}_refund_${string}` | `${string}_invoice_${string}` | `${string}_payment_${string}` | `${string}_credit_memo_${string}` | `${string}_sales_receipt_${string}` | `${string}_delayed_credit_${string}` | `${string}_delayed_charge_${string}` | `${string}_bill_${string}` | `${string}_bill_payment_${string}` | `${string}_bill_payment_check_${string}` | `${string}_bill_payment_credit_card_${string}` | `${string}_vendor_credit_${string}` | `${string}_credit_card_credit_${string}` | `${string}_transfer_${string}` | `${string}_credit_card_payment_${string}` | `${string}_deposit_${string}` | `${string}_journal_entry_${string}`;
23
23
  }, "jeSchedules/deleteJESchedulesDetails", never, never>, deleteAccruedJESchedulesDetails: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[JEScheduleKey: `${string}_${string}`], {
24
24
  JEScheduleKey: `${string}_${string}`;
25
- }, "jeSchedules/deleteAccruedJESchedulesDetails", never, never>, clearAllAccruedJESchedules: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"jeSchedules/clearAllAccruedJESchedules">, clearAllJEScheduleTransactions: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"jeSchedules/clearAllJEScheduleTransactions">;
25
+ }, "jeSchedules/deleteAccruedJESchedulesDetails", never, never>, clearAllAccruedJESchedules: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"jeSchedules/clearAllAccruedJESchedules">, clearAllJEScheduleTransactions: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"jeSchedules/clearAllJEScheduleTransactions">, updateJEOneTimeAccruals: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[jeOneTimeAccrualsPayload: JEOneTimeAccrualPayload[]], {
26
+ jeOneTimeAccrualsPayload: JEOneTimeAccrualPayload[];
27
+ }, "jeSchedules/updateJEOneTimeAccruals", never, never>;
26
28
  declare const _default: import("redux").Reducer<JESchedulesState>;
27
29
  export default _default;
@@ -4,14 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  var _a;
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.clearAllJEScheduleTransactions = exports.clearAllAccruedJESchedules = exports.deleteAccruedJESchedulesDetails = exports.deleteJESchedulesDetails = exports.updateAccruedJESchedulesDetails = exports.updateJESchedulesDetails = exports.updateAccruedJEScheduledTransaction = exports.updateJEScheduledTransaction = exports.updateAccruedJESchedules = exports.updateJESchedules = exports.initialState = void 0;
7
+ exports.updateJEOneTimeAccruals = exports.clearAllJEScheduleTransactions = exports.clearAllAccruedJESchedules = exports.deleteAccruedJESchedulesDetails = exports.deleteJESchedulesDetails = exports.updateAccruedJESchedulesDetails = exports.updateJESchedulesDetails = exports.updateAccruedJEScheduledTransaction = exports.updateJEScheduledTransaction = exports.updateAccruedJESchedules = exports.updateJESchedules = exports.initialState = void 0;
8
8
  const toolkit_1 = require("@reduxjs/toolkit");
9
9
  const assignWith_1 = __importDefault(require("lodash/assignWith"));
10
10
  const rootActions_1 = require("../../rootActions");
11
+ const jeScheduleHelper_1 = require("./jeScheduleHelper");
11
12
  const jeSchedulesPayload_1 = require("./jeSchedulesPayload");
12
13
  exports.initialState = {
13
14
  schedulesByTransactionKey: {},
14
15
  schedulesByAccruedJEScheduleKey: {},
16
+ oneTimeAccrualsByKey: {},
15
17
  };
16
18
  const jeSchedules = (0, toolkit_1.createSlice)({
17
19
  name: 'jeSchedules',
@@ -116,6 +118,25 @@ const jeSchedules = (0, toolkit_1.createSlice)({
116
118
  delete draft.schedulesByAccruedJEScheduleKey[JEScheduleKey];
117
119
  },
118
120
  },
121
+ // Writes directly, unlike updateAccruedJESchedules / updateJESchedules, which are no-op
122
+ // actions whose only job is to trigger the entity fan-out epic that fetches vendors,
123
+ // accounts, classes and users. An accrual denormalizes all of those as names on the document,
124
+ // so there is nothing to fan out to.
125
+ updateJEOneTimeAccruals: {
126
+ prepare(jeOneTimeAccrualsPayload) {
127
+ return {
128
+ payload: {
129
+ jeOneTimeAccrualsPayload,
130
+ },
131
+ };
132
+ },
133
+ reducer(draft, action) {
134
+ action.payload.jeOneTimeAccrualsPayload.forEach((accrualPayload) => {
135
+ const accrual = (0, jeSchedulesPayload_1.toJEOneTimeAccrual)(accrualPayload);
136
+ draft.oneTimeAccrualsByKey[(0, jeScheduleHelper_1.generateJEOneTimeAccrualKey)(accrual.accrualId)] = accrual;
137
+ });
138
+ },
139
+ },
119
140
  clearAllJEScheduleTransactions(draft) {
120
141
  draft.schedulesByTransactionKey = {};
121
142
  },
@@ -127,10 +148,11 @@ const jeSchedules = (0, toolkit_1.createSlice)({
127
148
  builder.addCase(rootActions_1.clearAll, (draft) => {
128
149
  draft.schedulesByAccruedJEScheduleKey = {};
129
150
  draft.schedulesByTransactionKey = {};
151
+ draft.oneTimeAccrualsByKey = {};
130
152
  });
131
153
  },
132
154
  });
133
- _a = jeSchedules.actions, exports.updateJESchedules = _a.updateJESchedules, exports.updateAccruedJESchedules = _a.updateAccruedJESchedules, exports.updateJEScheduledTransaction = _a.updateJEScheduledTransaction, exports.updateAccruedJEScheduledTransaction = _a.updateAccruedJEScheduledTransaction, exports.updateJESchedulesDetails = _a.updateJESchedulesDetails, exports.updateAccruedJESchedulesDetails = _a.updateAccruedJESchedulesDetails, exports.deleteJESchedulesDetails = _a.deleteJESchedulesDetails, exports.deleteAccruedJESchedulesDetails = _a.deleteAccruedJESchedulesDetails, exports.clearAllAccruedJESchedules = _a.clearAllAccruedJESchedules, exports.clearAllJEScheduleTransactions = _a.clearAllJEScheduleTransactions;
155
+ _a = jeSchedules.actions, exports.updateJESchedules = _a.updateJESchedules, exports.updateAccruedJESchedules = _a.updateAccruedJESchedules, exports.updateJEScheduledTransaction = _a.updateJEScheduledTransaction, exports.updateAccruedJEScheduledTransaction = _a.updateAccruedJEScheduledTransaction, exports.updateJESchedulesDetails = _a.updateJESchedulesDetails, exports.updateAccruedJESchedulesDetails = _a.updateAccruedJESchedulesDetails, exports.deleteJESchedulesDetails = _a.deleteJESchedulesDetails, exports.deleteAccruedJESchedulesDetails = _a.deleteAccruedJESchedulesDetails, exports.clearAllAccruedJESchedules = _a.clearAllAccruedJESchedules, exports.clearAllJEScheduleTransactions = _a.clearAllJEScheduleTransactions, exports.updateJEOneTimeAccruals = _a.updateJEOneTimeAccruals;
134
156
  exports.default = jeSchedules.reducer;
135
157
  /**
136
158
  * Helper functions
@@ -9,8 +9,8 @@ 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 { JEScheduleAISummaries, JEScheduleOtherAttributes, JEScheduleRecommendations, ScheduleJournalStatusCode, ScheduleStatus } from './jeSchedulesState';
13
- import { JEScheduleKey, JEScheduleTransactionKey, JournalEntryErrorCodeType, ScheduleTypes } from './jeSchedulesTypes';
12
+ import { JEOneTimeAccrualState, JEScheduleAISummaries, JEScheduleOtherAttributes, JEScheduleRecommendations, JESchedulesState, ScheduleJournalStatusCode, ScheduleStatus } from './jeSchedulesState';
13
+ import { JEOneTimeAccrualKey, JEScheduleKey, JEScheduleTransactionKey, JournalEntryErrorCodeType, ScheduleTypes } from './jeSchedulesTypes';
14
14
  export interface ScheduledJournalEntry {
15
15
  error: JournalEntryErrorCodeType[];
16
16
  expectedPostDate: ZeniDate;
@@ -55,13 +55,17 @@ export interface JEScheduledTransaction {
55
55
  accountingClass?: Class;
56
56
  };
57
57
  jeScheduleTransactionKey: JEScheduleTransactionKey;
58
+ lifecycleTotal: number;
58
59
  otherAttributes: JEScheduleOtherAttributes;
60
+ postedCount: number;
59
61
  scheduledJournalEntry: ScheduledJournalEntry[];
60
62
  status: ScheduleStatus;
61
63
  vendor: Vendor;
62
64
  aiSummaries?: JEScheduleAISummaries;
63
65
  balanceAsOfToday?: Amount;
66
+ confidenceScore?: number;
64
67
  createdByUser?: User;
68
+ createTime?: ZeniDate;
65
69
  dayOfPostingDate?: ScheduleDaysOfMonth;
66
70
  endDate?: ZeniDate;
67
71
  jeScheduleId?: ID;
@@ -69,9 +73,14 @@ export interface JEScheduledTransaction {
69
73
  lastDayOfMonth?: boolean;
70
74
  period?: number;
71
75
  recommendations?: JEScheduleRecommendations;
76
+ recurringAmount?: Amount;
72
77
  startDate?: ZeniDate;
73
78
  updatedAt?: ZeniDate;
74
79
  updatedByUser?: User;
75
80
  }
81
+ export interface JEOneTimeAccrual extends JEOneTimeAccrualState {
82
+ jeOneTimeAccrualKey: JEOneTimeAccrualKey;
83
+ }
84
+ export declare const getJEOneTimeAccrualByKey: (jeOneTimeAccrualKey: JEOneTimeAccrualKey, jeSchedulesState: JESchedulesState) => JEOneTimeAccrual | undefined;
76
85
  export declare const getJEAccruedScheduleByJEScheduleKey: (JEScheduleKey: JEScheduleKey, state: RootState) => JEAccruedSchedule | undefined;
77
86
  export declare const getJEScheduledTransactionByJEScheduleTransactionKey: (jeScheduleTransactionKey: JEScheduleTransactionKey, state: RootState) => JEScheduledTransaction;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getJEScheduledTransactionByJEScheduleTransactionKey = exports.getJEAccruedScheduleByJEScheduleKey = void 0;
6
+ exports.getJEScheduledTransactionByJEScheduleTransactionKey = exports.getJEAccruedScheduleByJEScheduleKey = exports.getJEOneTimeAccrualByKey = void 0;
7
7
  const get_1 = __importDefault(require("lodash/get"));
8
8
  const amount_1 = require("../../commonStateTypes/amount");
9
9
  const accountSelector_1 = require("../account/accountSelector");
@@ -11,13 +11,27 @@ const classSelector_1 = require("../class/classSelector");
11
11
  const transactionSelector_1 = require("../transaction/transactionSelector");
12
12
  const userSelector_1 = require("../user/userSelector");
13
13
  const vendorSelector_1 = require("../vendor/vendorSelector");
14
+ // Takes the slice, not RootState: an accrual denormalizes its vendor, account and class names, so
15
+ // unlike getJEAccruedScheduleByJEScheduleKey this joins nothing.
16
+ //
17
+ // Spreads the stored entity rather than rebuilding it field by field. That is deliberate — the
18
+ // accrued joiner listed every field explicitly and silently dropped jeScheduleType, which made a
19
+ // whole tab render empty while its reducer test still passed. A spread cannot lose a field.
20
+ const getJEOneTimeAccrualByKey = (jeOneTimeAccrualKey, jeSchedulesState) => {
21
+ const accrual = (0, get_1.default)(jeSchedulesState.oneTimeAccrualsByKey, jeOneTimeAccrualKey);
22
+ if (accrual == null) {
23
+ return undefined;
24
+ }
25
+ return { ...accrual, jeOneTimeAccrualKey };
26
+ };
27
+ exports.getJEOneTimeAccrualByKey = getJEOneTimeAccrualByKey;
14
28
  const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
15
29
  const { jeSchedulesState, vendorState, accountState, userState, classState } = state;
16
30
  const JEAccruedScheduleState = (0, get_1.default)(jeSchedulesState.schedulesByAccruedJEScheduleKey, JEScheduleKey);
17
31
  if (JEAccruedScheduleState == null) {
18
32
  return undefined;
19
33
  }
20
- const { period, updatedByUserID: updatedBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, memo, recurringAmount, createTime, otherAttributes, } = JEAccruedScheduleState;
34
+ const { period, updatedByUserID: updatedBy, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, memo, recurringAmount, createTime, otherAttributes, jeScheduleType, } = JEAccruedScheduleState;
21
35
  const vendorDetails = (0, vendorSelector_1.getVendorByVendorId)(vendorState, vendorId);
22
36
  if (vendorDetails == null) {
23
37
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
@@ -41,6 +55,8 @@ const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
41
55
  reportId: 'class_list',
42
56
  })
43
57
  : undefined;
58
+ const postedCount = scheduledJournalEntry.filter((sje) => sje.status.code === 'posted' || sje.status.code === 'recorded').length;
59
+ const lifecycleTotal = period ?? scheduledJournalEntry.length;
44
60
  return {
45
61
  jeScheduleId,
46
62
  otherAttributes,
@@ -49,6 +65,8 @@ const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
49
65
  updatedAt,
50
66
  currencyCode,
51
67
  currencySymbol,
68
+ lifecycleTotal,
69
+ postedCount,
52
70
  jeCredit: {
53
71
  accountingClass: classCredit,
54
72
  account: accountCredit,
@@ -66,6 +84,7 @@ const getJEAccruedScheduleByJEScheduleKey = (JEScheduleKey, state) => {
66
84
  memo,
67
85
  createTime,
68
86
  recurringAmount,
87
+ jeScheduleType,
69
88
  jeAccruedScheduleKey: JEScheduleKey,
70
89
  balanceAsOfToday: balanceAsOfToday != null
71
90
  ? (0, amount_1.toAmount)(balanceAsOfToday, currencyCode, currencySymbol)
@@ -77,7 +96,7 @@ exports.getJEAccruedScheduleByJEScheduleKey = getJEAccruedScheduleByJEScheduleKe
77
96
  const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransactionKey, state) => {
78
97
  const { jeSchedulesState, vendorState, accountState, userState, classState, transactionState, } = state;
79
98
  const jeScheduleTransactionState = (0, get_1.default)(jeSchedulesState.schedulesByTransactionKey, jeScheduleTransactionKey);
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;
99
+ const { period, updatedByUserID: updatedBy, createdByUserID: createdBy, createTime, vendorId, jeCredit, jeDebit, currencyCode, currencySymbol, balanceAsOfToday, baseTransaction, startDate, endDate, status, updatedAt, jeScheduleId, scheduledJournalEntry, dayOfPostingDate: postingDate, lastDayOfMonth, otherAttributes, jeScheduleType, aiSummaries, confidenceScore, recommendations, recurringAmount, postedCount: postedCountFromServer, } = jeScheduleTransactionState;
81
100
  const vendorDetails = (0, vendorSelector_1.getVendorByVendorId)(vendorState, vendorId);
82
101
  if (vendorDetails == null) {
83
102
  throw new Error(`Vendor with ${vendorId} doesn't exist`);
@@ -106,14 +125,24 @@ const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransacti
106
125
  reportId: 'class_list',
107
126
  })
108
127
  : undefined;
128
+ // The expense-automation response carries no scheduled journal entries for these rows, so the
129
+ // filter below counts an empty array and every schedule reported 0 posted. Prefer the count the
130
+ // server derives, and keep the filter for callers that do have entries (the detail page, and
131
+ // failed postings, which come with theirs).
132
+ const postedCount = postedCountFromServer ??
133
+ scheduledJournalEntry.filter((sje) => sje.status.code === 'posted' || sje.status.code === 'recorded').length;
134
+ const lifecycleTotal = period ?? scheduledJournalEntry.length;
109
135
  return {
110
136
  jeScheduleId,
111
137
  jeScheduleType,
138
+ recurringAmount,
112
139
  jeScheduleTransactionKey: jeScheduleTransactionKey,
113
140
  vendor: vendorDetails,
114
141
  updatedByUser: userDetails,
115
142
  updatedAt: updatedAt,
116
143
  period,
144
+ lifecycleTotal,
145
+ postedCount,
117
146
  balanceAsOfToday: balanceAsOfToday != null
118
147
  ? (0, amount_1.toAmount)(balanceAsOfToday, currencyCode, currencySymbol)
119
148
  : undefined,
@@ -136,7 +165,9 @@ const getJEScheduledTransactionByJEScheduleTransactionKey = (jeScheduleTransacti
136
165
  },
137
166
  scheduledJournalEntry,
138
167
  aiSummaries,
168
+ confidenceScore,
139
169
  createdByUser: createdByUserDetails,
170
+ createTime,
140
171
  recommendations,
141
172
  };
142
173
  };
@@ -2,8 +2,9 @@ import { Amount } from '../../commonStateTypes/amount';
2
2
  import { ID } from '../../commonStateTypes/common';
3
3
  import { ScheduleDaysOfMonth } from '../../commonStateTypes/timePeriod';
4
4
  import { ZeniDate } from '../../zeniDayJS';
5
+ import { ZeniUrl as Url } from '../../zeniUrl';
5
6
  import { TransactionID } from '../transaction/stateTypes/transaction';
6
- import { JEScheduleKey, JEScheduleTransactionKey, JournalEntryErrorCodeType, ScheduleJournalEntryStatusCodeType, ScheduleStatusCodeType, ScheduleTypes } from './jeSchedulesTypes';
7
+ import { JEOneTimeAccrualKey, JEScheduleKey, JEScheduleTransactionKey, JournalEntryErrorCodeType, OneTimeAccrualAutomationTierType, OneTimeAccrualOriginType, OneTimeAccrualReversalPolicyType, OneTimeAccrualReversalTriggerType, OneTimeAccrualStatusCodeType, ScheduleJournalEntryStatusCodeType, ScheduleStatusCodeType, ScheduleTypes } from './jeSchedulesTypes';
7
8
  export interface ScheduleStatus {
8
9
  code: ScheduleStatusCodeType;
9
10
  label: string;
@@ -94,14 +95,18 @@ export interface JEScheduledTransactionState {
94
95
  vendorId: ID;
95
96
  aiSummaries?: JEScheduleAISummaries;
96
97
  balanceAsOfToday?: number;
98
+ confidenceScore?: number;
97
99
  createdByUserID?: ID;
100
+ createTime?: ZeniDate;
98
101
  dayOfPostingDate?: ScheduleDaysOfMonth;
99
102
  endDate?: ZeniDate;
100
103
  jeScheduleId?: ID;
101
104
  jeScheduleType?: ScheduleTypes;
102
105
  lastDayOfMonth?: boolean;
103
106
  period?: number;
107
+ postedCount?: number;
104
108
  recommendations?: JEScheduleRecommendations;
109
+ recurringAmount?: Amount;
105
110
  startDate?: ZeniDate;
106
111
  updatedAt?: ZeniDate;
107
112
  updatedByUserID?: ID;
@@ -112,7 +117,80 @@ export interface JEAccruedScheduledTransactionState extends Omit<JEScheduledTran
112
117
  memo: string;
113
118
  recurringAmount: Amount;
114
119
  }
120
+ export interface JEOneTimeAccrualCreator {
121
+ userId: ID;
122
+ email?: string;
123
+ firstName?: string;
124
+ lastName?: string;
125
+ photo?: Url;
126
+ }
127
+ /**
128
+ * One month of a vendor's billed history, taken from profile_snapshot. Kept as an ordered array
129
+ * rather than the payload's map because the months are not contiguous — a vendor that skipped a
130
+ * month has no entry — so consumers must not derive the sequence themselves.
131
+ */
132
+ export interface JEOneTimeAccrualMonthlyTotal {
133
+ amount: Amount;
134
+ month: string;
135
+ }
136
+ export interface JEOneTimeAccrualBillingPattern {
137
+ avgAmount?: Amount;
138
+ billingLagDays?: number;
139
+ consistencyScore?: number;
140
+ frequency?: string;
141
+ lastBillAmount?: Amount;
142
+ lastBillDate?: ZeniDate;
143
+ monthsOfHistory?: number;
144
+ typicalBillDay?: number;
145
+ }
146
+ /**
147
+ * The vendor profile the AI used to decide this accrual. Absent on human-created accruals, so every
148
+ * card built from it has to be omitted rather than rendered empty.
149
+ */
150
+ export interface JEOneTimeAccrualProfileSnapshot {
151
+ monthlyTotals: JEOneTimeAccrualMonthlyTotal[];
152
+ billingPattern?: JEOneTimeAccrualBillingPattern;
153
+ }
154
+ /** What the AI originally suggested, frozen at draft time. */
155
+ export interface JEOneTimeAccrualAiSuggestion {
156
+ estimatedAmount?: Amount;
157
+ jeCreditAccountName?: string;
158
+ jeDebitAccountName?: string;
159
+ memo?: string;
160
+ }
161
+ export interface JEOneTimeAccrualState {
162
+ accrualId: ID;
163
+ accrualStatus: OneTimeAccrualStatusCodeType;
164
+ estimatedAmount: Amount;
165
+ memo: string;
166
+ origin: OneTimeAccrualOriginType;
167
+ reversalPolicy: OneTimeAccrualReversalPolicyType;
168
+ serviceMonth: string;
169
+ vendorId: ID;
170
+ vendorName: string;
171
+ actualPostDate?: ZeniDate;
172
+ actualReversalPostDate?: ZeniDate;
173
+ aiSuggestion?: JEOneTimeAccrualAiSuggestion;
174
+ automationTier?: OneTimeAccrualAutomationTierType;
175
+ createdBy?: JEOneTimeAccrualCreator;
176
+ expectedReversalDate?: ZeniDate;
177
+ jeCreditAccountId?: ID;
178
+ jeCreditAccountingClassId?: ID;
179
+ jeCreditAccountingClassName?: string;
180
+ jeCreditAccountName?: string;
181
+ jeDebitAccountId?: ID;
182
+ jeDebitAccountingClassId?: ID;
183
+ jeDebitAccountingClassName?: string;
184
+ jeDebitAccountName?: string;
185
+ postingDate?: ZeniDate;
186
+ profileSnapshot?: JEOneTimeAccrualProfileSnapshot;
187
+ reversalTransactionId?: ID;
188
+ reversalTrigger?: OneTimeAccrualReversalTriggerType;
189
+ transactionId?: ID;
190
+ transactionIntegrationId?: ID;
191
+ }
115
192
  export interface JESchedulesState {
193
+ oneTimeAccrualsByKey: Record<JEOneTimeAccrualKey, JEOneTimeAccrualState>;
116
194
  schedulesByAccruedJEScheduleKey: Record<JEScheduleKey, JEAccruedScheduledTransactionState>;
117
195
  schedulesByTransactionKey: Record<JEScheduleTransactionKey, JEScheduledTransactionState>;
118
196
  }