@zeniai/client-epic-state 5.2.11-betaRD6 → 5.2.11-betaRD8

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.
@@ -142,6 +142,7 @@ export interface JEOneTimeAccrualPayload {
142
142
  created_by_user?: UserPayload | null;
143
143
  currency?: string | null;
144
144
  expected_reversal_date?: string | null;
145
+ is_ignored?: boolean;
145
146
  je_credit_account_id?: ID | null;
146
147
  je_credit_account_name?: string | null;
147
148
  je_credit_accounting_class_id?: ID | null;
@@ -347,17 +347,20 @@ function toJEAccruedScheduledTransaction(payload) {
347
347
  label: payload.status.label,
348
348
  },
349
349
  vendorId: payload.vendor.vendor_id,
350
+ // The accrued payload extends JEScheduledTransactionPayload, so it carries currency_code and
351
+ // currency_symbol like every other schedule -- this mapper was hardcoding USD over fields it
352
+ // already had.
350
353
  recurringAmount: {
351
354
  amount: payload.recurring_amount,
352
- currencyCode: 'USD',
353
- currencySymbol: '$',
355
+ currencyCode: payload.currency_code,
356
+ currencySymbol: payload.currency_symbol,
354
357
  },
355
358
  otherAttributes: {
356
359
  startingBalance: payload.other_attributes?.starting_balance != null
357
360
  ? {
358
361
  amount: payload.other_attributes?.starting_balance ?? 0,
359
- currencyCode: 'USD',
360
- currencySymbol: '$',
362
+ currencyCode: payload.currency_code,
363
+ currencySymbol: payload.currency_symbol,
361
364
  }
362
365
  : undefined,
363
366
  },
@@ -466,6 +469,7 @@ function toJEOneTimeAccrual(payload) {
466
469
  estimatedAmount: toOneTimeAccrualAmount(payload.estimated_amount, payload.currency),
467
470
  memo: payload.memo ?? '',
468
471
  profileSnapshot: toJEOneTimeAccrualProfileSnapshot(payload.profile_snapshot, payload.currency),
472
+ isIgnored: payload.is_ignored === true,
469
473
  aiSuggestion: toJEOneTimeAccrualAiSuggestion(payload.ai_suggestion, payload.currency),
470
474
  // Exclusive by contract: a scheduled row reverses on expectedReversalDate and bills never
471
475
  // drive it, so the two never need reconciling. Defaulting to on_bill_match matches the
@@ -149,7 +149,12 @@ export interface OneTimeAccrualEdits {
149
149
  jeDebitAccountingClassId?: ID;
150
150
  jeDebitAccountingClassName?: string;
151
151
  memo?: string;
152
- reversalPolicy?: OneTimeAccrualReversalPolicyType;
152
+ /**
153
+ * The Auto Reversal toggle, modelled as the same boolean the New form and the create payload use
154
+ * rather than a policy string: `reverse_next_month` alone decides the policy server-side, and
155
+ * sending both would be two sources of truth for one control.
156
+ */
157
+ reverseNextMonth?: boolean;
153
158
  }
154
159
  export interface JEOneTimeAccrualCreator {
155
160
  userId: ID;
@@ -196,6 +201,11 @@ export interface JEOneTimeAccrualState {
196
201
  accrualId: ID;
197
202
  accrualStatus: OneTimeAccrualStatusCodeType;
198
203
  estimatedAmount: Amount;
204
+ /**
205
+ * Ignoring an accrual sets this flag and leaves the status on `draft`, so the status alone cannot
206
+ * tell an ignored row from an actionable one.
207
+ */
208
+ isIgnored: boolean;
199
209
  memo: string;
200
210
  origin: OneTimeAccrualOriginType;
201
211
  reversalPolicy: OneTimeAccrualReversalPolicyType;
@@ -15,7 +15,7 @@ export declare const toScheduleJournalEntryStatusCodeType: (v: string) => "unkno
15
15
  export type ScheduleJournalEntryStatusCodeType = ReturnType<typeof toScheduleJournalEntryStatusCodeType>;
16
16
  export declare const toScheduleStatusCodeType: (v: string) => "completed" | "draft" | "new" | "ongoing" | "marked_as_completed";
17
17
  export type ScheduleStatusCodeType = ReturnType<typeof toScheduleStatusCodeType>;
18
- export declare const toOneTimeAccrualStatusCodeType: (v: string) => "draft" | "posted" | "posting" | "posting_blocked" | "reversing" | "reversed";
18
+ export declare const toOneTimeAccrualStatusCodeType: (v: string) => "draft" | "posted" | "posting" | "posting_blocked" | "reversing" | "reversed" | "reverted";
19
19
  export type OneTimeAccrualStatusCodeType = ReturnType<typeof toOneTimeAccrualStatusCodeType>;
20
20
  export declare const toOneTimeAccrualOriginType: (v: string) => "agent" | "human";
21
21
  export type OneTimeAccrualOriginType = ReturnType<typeof toOneTimeAccrualOriginType>;
@@ -35,6 +35,13 @@ exports.toScheduleStatusCodeType = toScheduleStatusCodeType;
35
35
  // One-time accruals come from agent-je's Mongo `accruals` collection, not the JE schedule
36
36
  // datastore, so they carry their own status vocabulary rather than SCHEDULE_STATUS_CODE.
37
37
  // `posting` and `reversing` are transient claims held while a JE posts.
38
+ /**
39
+ * Mirrors agent-je's own status constants. `reverted` is the terminal state a manual revert writes
40
+ * alongside is_deleted; without it stringToUnion logs an error and passes the raw string through.
41
+ *
42
+ * There is deliberately no `ignored` member -- ignoring an accrual sets the `is_ignored` flag and
43
+ * leaves the status on `draft`.
44
+ */
38
45
  const ONE_TIME_ACCRUAL_STATUS_CODE = [
39
46
  'draft',
40
47
  'posting',
@@ -42,6 +49,7 @@ const ONE_TIME_ACCRUAL_STATUS_CODE = [
42
49
  'posting_blocked',
43
50
  'reversing',
44
51
  'reversed',
52
+ 'reverted',
45
53
  ];
46
54
  const toOneTimeAccrualStatusCodeType = (v) => (0, stringToUnion_1.stringToUnion)(v, ONE_TIME_ACCRUAL_STATUS_CODE);
47
55
  exports.toOneTimeAccrualStatusCodeType = toOneTimeAccrualStatusCodeType;
@@ -336,17 +336,20 @@ export function toJEAccruedScheduledTransaction(payload) {
336
336
  label: payload.status.label,
337
337
  },
338
338
  vendorId: payload.vendor.vendor_id,
339
+ // The accrued payload extends JEScheduledTransactionPayload, so it carries currency_code and
340
+ // currency_symbol like every other schedule -- this mapper was hardcoding USD over fields it
341
+ // already had.
339
342
  recurringAmount: {
340
343
  amount: payload.recurring_amount,
341
- currencyCode: 'USD',
342
- currencySymbol: '$',
344
+ currencyCode: payload.currency_code,
345
+ currencySymbol: payload.currency_symbol,
343
346
  },
344
347
  otherAttributes: {
345
348
  startingBalance: payload.other_attributes?.starting_balance != null
346
349
  ? {
347
350
  amount: payload.other_attributes?.starting_balance ?? 0,
348
- currencyCode: 'USD',
349
- currencySymbol: '$',
351
+ currencyCode: payload.currency_code,
352
+ currencySymbol: payload.currency_symbol,
350
353
  }
351
354
  : undefined,
352
355
  },
@@ -455,6 +458,7 @@ export function toJEOneTimeAccrual(payload) {
455
458
  estimatedAmount: toOneTimeAccrualAmount(payload.estimated_amount, payload.currency),
456
459
  memo: payload.memo ?? '',
457
460
  profileSnapshot: toJEOneTimeAccrualProfileSnapshot(payload.profile_snapshot, payload.currency),
461
+ isIgnored: payload.is_ignored === true,
458
462
  aiSuggestion: toJEOneTimeAccrualAiSuggestion(payload.ai_suggestion, payload.currency),
459
463
  // Exclusive by contract: a scheduled row reverses on expectedReversalDate and bills never
460
464
  // drive it, so the two never need reconciling. Defaulting to on_bill_match matches the
@@ -27,6 +27,13 @@ export const toScheduleStatusCodeType = (v) => stringToUnion(v, SCHEDULE_STATUS_
27
27
  // One-time accruals come from agent-je's Mongo `accruals` collection, not the JE schedule
28
28
  // datastore, so they carry their own status vocabulary rather than SCHEDULE_STATUS_CODE.
29
29
  // `posting` and `reversing` are transient claims held while a JE posts.
30
+ /**
31
+ * Mirrors agent-je's own status constants. `reverted` is the terminal state a manual revert writes
32
+ * alongside is_deleted; without it stringToUnion logs an error and passes the raw string through.
33
+ *
34
+ * There is deliberately no `ignored` member -- ignoring an accrual sets the `is_ignored` flag and
35
+ * leaves the status on `draft`.
36
+ */
30
37
  const ONE_TIME_ACCRUAL_STATUS_CODE = [
31
38
  'draft',
32
39
  'posting',
@@ -34,6 +41,7 @@ const ONE_TIME_ACCRUAL_STATUS_CODE = [
34
41
  'posting_blocked',
35
42
  'reversing',
36
43
  'reversed',
44
+ 'reverted',
37
45
  ];
38
46
  export const toOneTimeAccrualStatusCodeType = (v) => stringToUnion(v, ONE_TIME_ACCRUAL_STATUS_CODE);
39
47
  // Who created the accrual. This — not the creator's email — is the authoritative
@@ -12,7 +12,9 @@ import { prepareNewSchedulePayload, } from '../../../helpers/newScheduleLocalDat
12
12
  import { fetchJeSchedules, resetNewScheduleLocalData, saveNewSchedule, saveNewScheduleFailure, saveNewScheduleSuccess, } from '../../../reducers/jeSchedulesViewReducer';
13
13
  const FAILURE_REASON_MESSAGES = {
14
14
  missing_third_party_id: 'This transaction is missing a QuickBooks reference and cannot be scheduled.',
15
- missing_vendor: 'Select a vendor before saving this schedule.',
15
+ // The form cannot satisfy this: the vendor field is hard-disabled and inherited from the base
16
+ // transaction, so the fix is on the transaction, not here.
17
+ missing_vendor: 'This transaction has no vendor and cannot be scheduled. Add a vendor to the transaction first.',
16
18
  };
17
19
  export const saveNewScheduleEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveNewSchedule.match), mergeMap((action) => {
18
20
  const { scheduleType } = action.payload;
@@ -63,7 +63,10 @@ export const promoteOneTimeAccrualEpic = (actions$, state$, zeniAPI) => actions$
63
63
  // vendor_id, vendor_name and service_month are deliberately absent: promote takes them from
64
64
  // the stored draft and ignores them in the body, so sending them would imply a reassignment
65
65
  // that never happens.
66
- const reversalPolicy = edits?.reversalPolicy ?? accrual?.reversalPolicy;
66
+ // Untouched falls back to the stored policy, so posting without editing cannot silently
67
+ // flip a scheduled reversal to on-bill-match.
68
+ const reverseNextMonth = edits?.reverseNextMonth ??
69
+ accrual?.reversalPolicy === 'scheduled_date';
67
70
  const expectedReversalDate = edits?.expectedReversalDate ?? accrual?.expectedReversalDate;
68
71
  const debitClassId = edits?.jeDebitAccountingClassId ?? accrual?.jeDebitAccountingClassId;
69
72
  const debitClassName = edits?.jeDebitAccountingClassName ??
@@ -77,9 +80,10 @@ export const promoteOneTimeAccrualEpic = (actions$, state$, zeniAPI) => actions$
77
80
  ...(debitClassName != null
78
81
  ? { je_debit_accounting_class_name: debitClassName }
79
82
  : {}),
80
- ...(reversalPolicy != null ? { reversal_policy: reversalPolicy } : {}),
81
- // Only meaningful for the scheduled-date policy; agent-je derives it for on_bill_match.
82
- ...(reversalPolicy === 'scheduled_date' && expectedReversalDate != null
83
+ // Mirrors the create payload: reverse_next_month alone decides the policy, and the date is
84
+ // only meaningful when it is true -- agent-je derives the reversal from the bill otherwise.
85
+ reverse_next_month: reverseNextMonth,
86
+ ...(reverseNextMonth && expectedReversalDate != null
83
87
  ? {
84
88
  expected_reversal_date: expectedReversalDate.format(DEFAULT_DATE_FORMAT),
85
89
  }
@@ -38,7 +38,14 @@ const ONE_TIME_ACCRUAL_REVIEW_STATUSES = [
38
38
  * these rows do arrive.
39
39
  */
40
40
  export function isRenderableOneTimeAccrual(accrual) {
41
- return accrual.accrualStatus !== 'posting_blocked';
41
+ return (accrual.accrualStatus !== 'posting_blocked' &&
42
+ // Terminal states the user has already decided. The GET list excludes both server-side, so
43
+ // these only appear in the window between an ignore/revert response being written back and the
44
+ // background refresh landing -- during which an ignored row would otherwise sit in Pending
45
+ // Review offering a Post button. Dropped here rather than at render time so group counts and
46
+ // KPI totals do not count rows nobody can see.
47
+ accrual.accrualStatus !== 'reverted' &&
48
+ !accrual.isIgnored);
42
49
  }
43
50
  export function getJEScheduleRowType(schedule) {
44
51
  return isOneTimeAccrualRow(schedule)
@@ -89,6 +96,16 @@ export function isAccruedScheduleRow(schedule) {
89
96
  export function isOneTimeAccrualRow(schedule) {
90
97
  return 'jeOneTimeAccrualKey' in schedule;
91
98
  }
99
+ /** The row's own Amount, so callers can read its currency and not just its value. */
100
+ function getScheduleAmountObject(schedule) {
101
+ if (isOneTimeAccrualRow(schedule)) {
102
+ return schedule.estimatedAmount;
103
+ }
104
+ if (isAccruedScheduleRow(schedule)) {
105
+ return schedule.recurringAmount;
106
+ }
107
+ return schedule.baseTransaction.amount;
108
+ }
92
109
  function getScheduleAmount(schedule) {
93
110
  if (isOneTimeAccrualRow(schedule)) {
94
111
  return schedule.estimatedAmount.amount;
@@ -307,25 +324,41 @@ export function getExpenseAutomationJESchedulesView(state) {
307
324
  const sumAmount = (schedules) => schedules.reduce((total, schedule) => total + (getScheduleAmount(schedule) ?? 0), 0);
308
325
  const pendingReviewTotal = sumAmount(pendingReviewSchedules);
309
326
  const createdTotal = sumAmount(createdSchedules);
327
+ /**
328
+ * The currency the tiles render in. Taken from the schedules themselves rather than assumed:
329
+ * every row on a tab shares a tenant currency, so the first one that states it is the answer.
330
+ */
331
+ const sumToAmount = (schedules) => {
332
+ const first = schedules[0];
333
+ const currency = first != null ? getScheduleAmountObject(first) : allScheduleAmountFallback;
334
+ return {
335
+ ...currency,
336
+ amount: sumAmount(schedules),
337
+ };
338
+ };
339
+ // An empty bucket still has to render a currency; borrow it from any row on the page.
340
+ const allScheduleAmountFallback = allScheduleRows.length > 0
341
+ ? getScheduleAmountObject(allScheduleRows[0])
342
+ : { amount: 0, currencyCode: '', currencySymbol: '' };
310
343
  const aiAccountantSchedules = allSchedules.filter(isAiAccountantSchedule);
311
344
  const manualSchedules = allSchedules.filter((schedule) => !isAiAccountantSchedule(schedule));
312
345
  const pendingUnfiltered = allSchedules.filter((schedule) => isPendingReviewRow(schedule));
313
346
  const kpiSummary = {
314
347
  aiAccountant: {
315
348
  count: aiAccountantSchedules.length,
316
- amount: sumAmount(aiAccountantSchedules),
349
+ amount: sumToAmount(aiAccountantSchedules),
317
350
  },
318
351
  manual: {
319
352
  count: manualSchedules.length,
320
- amount: sumAmount(manualSchedules),
353
+ amount: sumToAmount(manualSchedules),
321
354
  },
322
355
  needsReview: {
323
356
  count: pendingUnfiltered.length,
324
- amount: sumAmount(pendingUnfiltered),
357
+ amount: sumToAmount(pendingUnfiltered),
325
358
  },
326
359
  total: {
327
360
  count: allSchedules.length,
328
- amount: sumAmount(allSchedules),
361
+ amount: sumToAmount(allSchedules),
329
362
  },
330
363
  };
331
364
  // Each tab's badge counts from that tab's own bucket. A tab that has not been fetched yet
@@ -15,7 +15,9 @@ const newScheduleLocalDataHelper_1 = require("../../../helpers/newScheduleLocalD
15
15
  const jeSchedulesViewReducer_1 = require("../../../reducers/jeSchedulesViewReducer");
16
16
  const FAILURE_REASON_MESSAGES = {
17
17
  missing_third_party_id: 'This transaction is missing a QuickBooks reference and cannot be scheduled.',
18
- missing_vendor: 'Select a vendor before saving this schedule.',
18
+ // The form cannot satisfy this: the vendor field is hard-disabled and inherited from the base
19
+ // transaction, so the fix is on the transaction, not here.
20
+ missing_vendor: 'This transaction has no vendor and cannot be scheduled. Add a vendor to the transaction first.',
19
21
  };
20
22
  const saveNewScheduleEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(jeSchedulesViewReducer_1.saveNewSchedule.match), (0, operators_1.mergeMap)((action) => {
21
23
  const { scheduleType } = action.payload;
@@ -66,7 +66,10 @@ const promoteOneTimeAccrualEpic = (actions$, state$, zeniAPI) => actions$.pipe((
66
66
  // vendor_id, vendor_name and service_month are deliberately absent: promote takes them from
67
67
  // the stored draft and ignores them in the body, so sending them would imply a reassignment
68
68
  // that never happens.
69
- const reversalPolicy = edits?.reversalPolicy ?? accrual?.reversalPolicy;
69
+ // Untouched falls back to the stored policy, so posting without editing cannot silently
70
+ // flip a scheduled reversal to on-bill-match.
71
+ const reverseNextMonth = edits?.reverseNextMonth ??
72
+ accrual?.reversalPolicy === 'scheduled_date';
70
73
  const expectedReversalDate = edits?.expectedReversalDate ?? accrual?.expectedReversalDate;
71
74
  const debitClassId = edits?.jeDebitAccountingClassId ?? accrual?.jeDebitAccountingClassId;
72
75
  const debitClassName = edits?.jeDebitAccountingClassName ??
@@ -80,9 +83,10 @@ const promoteOneTimeAccrualEpic = (actions$, state$, zeniAPI) => actions$.pipe((
80
83
  ...(debitClassName != null
81
84
  ? { je_debit_accounting_class_name: debitClassName }
82
85
  : {}),
83
- ...(reversalPolicy != null ? { reversal_policy: reversalPolicy } : {}),
84
- // Only meaningful for the scheduled-date policy; agent-je derives it for on_bill_match.
85
- ...(reversalPolicy === 'scheduled_date' && expectedReversalDate != null
86
+ // Mirrors the create payload: reverse_next_month alone decides the policy, and the date is
87
+ // only meaningful when it is true -- agent-je derives the reversal from the bill otherwise.
88
+ reverse_next_month: reverseNextMonth,
89
+ ...(reverseNextMonth && expectedReversalDate != null
86
90
  ? {
87
91
  expected_reversal_date: expectedReversalDate.format(timePeriod_1.DEFAULT_DATE_FORMAT),
88
92
  }
@@ -70,7 +70,7 @@ export interface PromoteOneTimeAccrualPayload {
70
70
  je_credit_accounting_class_name?: string;
71
71
  je_debit_accounting_class_id?: ID;
72
72
  je_debit_accounting_class_name?: string;
73
- reversal_policy?: string;
73
+ reverse_next_month?: boolean;
74
74
  }
75
75
  /**
76
76
  * Ignore body. `scope` is deliberately absent — the API returns 400 if it is sent, which is why the
@@ -1,3 +1,4 @@
1
+ import { Amount } from '../../../commonStateTypes/amount';
1
2
  import { NestedAccountHierarchyForReport } from '../../../commonStateTypes/accountView/nestedAccountID';
2
3
  import { NestedClassHierarchyForReport } from '../../../commonStateTypes/classesView/nestedClassID';
3
4
  import { CompletionStatusType, FetchStateAndError, ID } from '../../../commonStateTypes/common';
@@ -11,21 +12,25 @@ import { JEScheduledTransactionWithFailedEntries } from '../selectors/jeSchedule
11
12
  import { NewScheduleView } from '../selectorTypes/jeNewScheduleViewSelectorTypes';
12
13
  import { JEScheduleRow } from '../selectors/jeSchedulesViewSelector';
13
14
  import { JEPageTab, JEScheduleLocalData, JESchedulesViewUIState } from '../types/jeSchedulesViewState';
15
+ /**
16
+ * Amount rather than a bare number: the KPI strip formats these for display, and a number carries
17
+ * no currency, which is what made the tiles print a hardcoded dollar sign.
18
+ */
14
19
  export interface JEKpiSummary {
15
20
  aiAccountant: {
16
- amount: number;
21
+ amount: Amount;
17
22
  count: number;
18
23
  };
19
24
  manual: {
20
- amount: number;
25
+ amount: Amount;
21
26
  count: number;
22
27
  };
23
28
  needsReview: {
24
- amount: number;
29
+ amount: Amount;
25
30
  count: number;
26
31
  };
27
32
  total: {
28
- amount: number;
33
+ amount: Amount;
29
34
  count: number;
30
35
  };
31
36
  }
@@ -52,7 +52,14 @@ const ONE_TIME_ACCRUAL_REVIEW_STATUSES = [
52
52
  * these rows do arrive.
53
53
  */
54
54
  function isRenderableOneTimeAccrual(accrual) {
55
- return accrual.accrualStatus !== 'posting_blocked';
55
+ return (accrual.accrualStatus !== 'posting_blocked' &&
56
+ // Terminal states the user has already decided. The GET list excludes both server-side, so
57
+ // these only appear in the window between an ignore/revert response being written back and the
58
+ // background refresh landing -- during which an ignored row would otherwise sit in Pending
59
+ // Review offering a Post button. Dropped here rather than at render time so group counts and
60
+ // KPI totals do not count rows nobody can see.
61
+ accrual.accrualStatus !== 'reverted' &&
62
+ !accrual.isIgnored);
56
63
  }
57
64
  function getJEScheduleRowType(schedule) {
58
65
  return isOneTimeAccrualRow(schedule)
@@ -104,6 +111,16 @@ function isAccruedScheduleRow(schedule) {
104
111
  function isOneTimeAccrualRow(schedule) {
105
112
  return 'jeOneTimeAccrualKey' in schedule;
106
113
  }
114
+ /** The row's own Amount, so callers can read its currency and not just its value. */
115
+ function getScheduleAmountObject(schedule) {
116
+ if (isOneTimeAccrualRow(schedule)) {
117
+ return schedule.estimatedAmount;
118
+ }
119
+ if (isAccruedScheduleRow(schedule)) {
120
+ return schedule.recurringAmount;
121
+ }
122
+ return schedule.baseTransaction.amount;
123
+ }
107
124
  function getScheduleAmount(schedule) {
108
125
  if (isOneTimeAccrualRow(schedule)) {
109
126
  return schedule.estimatedAmount.amount;
@@ -322,25 +339,41 @@ function getExpenseAutomationJESchedulesView(state) {
322
339
  const sumAmount = (schedules) => schedules.reduce((total, schedule) => total + (getScheduleAmount(schedule) ?? 0), 0);
323
340
  const pendingReviewTotal = sumAmount(pendingReviewSchedules);
324
341
  const createdTotal = sumAmount(createdSchedules);
342
+ /**
343
+ * The currency the tiles render in. Taken from the schedules themselves rather than assumed:
344
+ * every row on a tab shares a tenant currency, so the first one that states it is the answer.
345
+ */
346
+ const sumToAmount = (schedules) => {
347
+ const first = schedules[0];
348
+ const currency = first != null ? getScheduleAmountObject(first) : allScheduleAmountFallback;
349
+ return {
350
+ ...currency,
351
+ amount: sumAmount(schedules),
352
+ };
353
+ };
354
+ // An empty bucket still has to render a currency; borrow it from any row on the page.
355
+ const allScheduleAmountFallback = allScheduleRows.length > 0
356
+ ? getScheduleAmountObject(allScheduleRows[0])
357
+ : { amount: 0, currencyCode: '', currencySymbol: '' };
325
358
  const aiAccountantSchedules = allSchedules.filter(exports.isAiAccountantSchedule);
326
359
  const manualSchedules = allSchedules.filter((schedule) => !(0, exports.isAiAccountantSchedule)(schedule));
327
360
  const pendingUnfiltered = allSchedules.filter((schedule) => isPendingReviewRow(schedule));
328
361
  const kpiSummary = {
329
362
  aiAccountant: {
330
363
  count: aiAccountantSchedules.length,
331
- amount: sumAmount(aiAccountantSchedules),
364
+ amount: sumToAmount(aiAccountantSchedules),
332
365
  },
333
366
  manual: {
334
367
  count: manualSchedules.length,
335
- amount: sumAmount(manualSchedules),
368
+ amount: sumToAmount(manualSchedules),
336
369
  },
337
370
  needsReview: {
338
371
  count: pendingUnfiltered.length,
339
- amount: sumAmount(pendingUnfiltered),
372
+ amount: sumToAmount(pendingUnfiltered),
340
373
  },
341
374
  total: {
342
375
  count: allSchedules.length,
343
- amount: sumAmount(allSchedules),
376
+ amount: sumToAmount(allSchedules),
344
377
  },
345
378
  };
346
379
  // Each tab's badge counts from that tab's own bucket. A tab that has not been fetched yet
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.2.11-betaRD6",
3
+ "version": "5.2.11-betaRD8",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",