@zeniai/client-epic-state 5.2.11-betaRD7 → 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.
- package/lib/entity/jeSchedules/jeSchedulesPayload.d.ts +1 -0
- package/lib/entity/jeSchedules/jeSchedulesPayload.js +8 -4
- package/lib/entity/jeSchedules/jeSchedulesState.d.ts +5 -0
- package/lib/entity/jeSchedules/jeSchedulesTypes.d.ts +1 -1
- package/lib/entity/jeSchedules/jeSchedulesTypes.js +8 -0
- package/lib/esm/entity/jeSchedules/jeSchedulesPayload.js +8 -4
- package/lib/esm/entity/jeSchedules/jeSchedulesTypes.js +8 -0
- package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +3 -1
- package/lib/esm/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +38 -5
- package/lib/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js +3 -1
- package/lib/view/expenseAutomationView/selectorTypes/jeSchedulesSelectorTypes.d.ts +9 -4
- package/lib/view/expenseAutomationView/selectors/jeSchedulesViewSelector.js +38 -5
- package/package.json +1 -1
|
@@ -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:
|
|
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:
|
|
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
|
|
@@ -201,6 +201,11 @@ export interface JEOneTimeAccrualState {
|
|
|
201
201
|
accrualId: ID;
|
|
202
202
|
accrualStatus: OneTimeAccrualStatusCodeType;
|
|
203
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;
|
|
204
209
|
memo: string;
|
|
205
210
|
origin: OneTimeAccrualOriginType;
|
|
206
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:
|
|
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:
|
|
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
|
package/lib/esm/view/expenseAutomationView/epics/jeSchedule/newSchedule/saveNewScheduleEpic.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
|
@@ -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:
|
|
349
|
+
amount: sumToAmount(aiAccountantSchedules),
|
|
317
350
|
},
|
|
318
351
|
manual: {
|
|
319
352
|
count: manualSchedules.length,
|
|
320
|
-
amount:
|
|
353
|
+
amount: sumToAmount(manualSchedules),
|
|
321
354
|
},
|
|
322
355
|
needsReview: {
|
|
323
356
|
count: pendingUnfiltered.length,
|
|
324
|
-
amount:
|
|
357
|
+
amount: sumToAmount(pendingUnfiltered),
|
|
325
358
|
},
|
|
326
359
|
total: {
|
|
327
360
|
count: allSchedules.length,
|
|
328
|
-
amount:
|
|
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
|
-
|
|
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;
|
|
@@ -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:
|
|
21
|
+
amount: Amount;
|
|
17
22
|
count: number;
|
|
18
23
|
};
|
|
19
24
|
manual: {
|
|
20
|
-
amount:
|
|
25
|
+
amount: Amount;
|
|
21
26
|
count: number;
|
|
22
27
|
};
|
|
23
28
|
needsReview: {
|
|
24
|
-
amount:
|
|
29
|
+
amount: Amount;
|
|
25
30
|
count: number;
|
|
26
31
|
};
|
|
27
32
|
total: {
|
|
28
|
-
amount:
|
|
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:
|
|
364
|
+
amount: sumToAmount(aiAccountantSchedules),
|
|
332
365
|
},
|
|
333
366
|
manual: {
|
|
334
367
|
count: manualSchedules.length,
|
|
335
|
-
amount:
|
|
368
|
+
amount: sumToAmount(manualSchedules),
|
|
336
369
|
},
|
|
337
370
|
needsReview: {
|
|
338
371
|
count: pendingUnfiltered.length,
|
|
339
|
-
amount:
|
|
372
|
+
amount: sumToAmount(pendingUnfiltered),
|
|
340
373
|
},
|
|
341
374
|
total: {
|
|
342
375
|
count: allSchedules.length,
|
|
343
|
-
amount:
|
|
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-
|
|
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",
|