@zeniai/client-epic-state 5.0.69-betaAR3 → 5.0.69-betaAR4
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/account/accountSelector.d.ts +0 -26
- package/lib/entity/account/accountSelector.js +1 -47
- package/lib/entity/account/accountState.d.ts +0 -5
- package/lib/entity/account/accountState.js +4 -11
- package/lib/entity/approvalRule/approvalRulePayload.d.ts +27 -5
- package/lib/entity/approvalRule/approvalRulePayload.js +131 -10
- package/lib/entity/approvalRule/approvalRuleSelector.d.ts +25 -1
- package/lib/entity/approvalRule/approvalRuleSelector.js +40 -0
- package/lib/entity/approvalRule/approvalRuleState.d.ts +48 -7
- package/lib/entity/class/classSelector.d.ts +0 -35
- package/lib/entity/class/classSelector.js +0 -50
- package/lib/esm/entity/account/accountSelector.js +1 -46
- package/lib/esm/entity/account/accountState.js +1 -7
- package/lib/esm/entity/approvalRule/approvalRulePayload.js +131 -10
- package/lib/esm/entity/approvalRule/approvalRuleSelector.js +35 -0
- package/lib/esm/entity/class/classSelector.js +0 -48
- package/lib/esm/index.js +6 -11
- package/lib/esm/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
- package/lib/esm/view/companyView/helpers/cockpitHelpers.js +1 -1
- package/lib/esm/view/companyView/selector/companyManagementViewSelector.js +1 -1
- package/lib/esm/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
- package/lib/esm/view/expenseAutomationView/reducers/transactionsViewReducer.js +1 -11
- package/lib/esm/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -69
- package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +11 -7
- package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +61 -16
- package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +7 -2
- package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +11 -7
- package/lib/esm/view/spendManagement/spendManagementFilterHelpers.js +2 -4
- package/lib/esm/view/subscriptionView/subscriptionViewSelector.js +1 -1
- package/lib/esm/view/taskManager/taskListView/taskListReducer.js +1 -1
- package/lib/index.d.ts +8 -9
- package/lib/index.js +38 -41
- package/lib/view/companyHealthMetricView/companyHealthMetricViewSelector.js +1 -1
- package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +2 -2
- package/lib/view/companyView/helpers/cockpitHelpers.js +1 -1
- package/lib/view/companyView/selector/companyManagementViewSelector.js +1 -1
- package/lib/view/companyView/selector/companyPortfolioViewSelector.js +1 -1
- package/lib/view/companyView/types/cockpitTypes.d.ts +2 -2
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +1 -5
- package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.js +2 -12
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.d.ts +1 -4
- package/lib/view/expenseAutomationView/selectors/transactionCategorizationSelector.js +12 -71
- package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +0 -2
- package/lib/view/people/peopleTypes.d.ts +1 -1
- package/lib/view/spendManagement/billPay/billList/billListState.d.ts +1 -1
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +10 -6
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +9 -1
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +61 -16
- package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonState.d.ts +31 -5
- package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +7 -2
- package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
- package/lib/view/spendManagement/chargeCards/chargeCardPaymentHistory/chargeCardPaymentHistory.d.ts +1 -1
- package/lib/view/spendManagement/reimbursement/remiListView/remiListState.d.ts +1 -1
- package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +10 -6
- package/lib/view/spendManagement/spendManagementFilterHelpers.d.ts +1 -1
- package/lib/view/spendManagement/spendManagementFilterHelpers.js +2 -4
- package/lib/view/subscriptionView/subscriptionViewSelector.js +1 -1
- package/lib/view/taskManager/taskListView/taskList.d.ts +4 -4
- package/lib/view/taskManager/taskListView/taskListReducer.js +1 -1
- package/package.json +1 -1
- package/lib/esm/view/expenseAutomationView/transactionFilterHelpers.js +0 -228
- package/lib/view/expenseAutomationView/transactionFilterHelpers.d.ts +0 -65
- package/lib/view/expenseAutomationView/transactionFilterHelpers.js +0 -232
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getNestedAccountIDStr, } from '../../commonStateTypes/accountView/nestedAccountID';
|
|
2
2
|
import { getNestedClassIDStr, } from '../../commonStateTypes/classesView/nestedClassID';
|
|
3
3
|
import { stringToUnion, stringToUnionStrict, } from '../../commonStateTypes/stringToUnion';
|
|
4
|
-
|
|
4
|
+
const ALL_ACCOUNT_TYPES = [
|
|
5
5
|
'bank',
|
|
6
6
|
'credit_card',
|
|
7
7
|
'expenses',
|
|
@@ -25,12 +25,6 @@ export const ALL_ACCOUNT_TYPES = [
|
|
|
25
25
|
];
|
|
26
26
|
export const toAccountType = (v) => stringToUnion(v, ALL_ACCOUNT_TYPES);
|
|
27
27
|
export const toAccountTypeStrict = (v) => stringToUnionStrict(v ?? '', ALL_ACCOUNT_TYPES);
|
|
28
|
-
/** Account types used for payment-account filters (e.g. transaction filter "payment account name"). */
|
|
29
|
-
export const PAYMENT_ACCOUNT_TYPES = ['bank', 'credit_card'];
|
|
30
|
-
export function isPaymentAccountType(accountType) {
|
|
31
|
-
return (accountType != null &&
|
|
32
|
-
PAYMENT_ACCOUNT_TYPES.includes(accountType));
|
|
33
|
-
}
|
|
34
28
|
const ALL_ACCOUNT_LABELS = [
|
|
35
29
|
'uncategorized_income',
|
|
36
30
|
'uncategorized_expense',
|
|
@@ -14,18 +14,139 @@ export const toApprovalRule = (payload) => ({
|
|
|
14
14
|
version: payload.version,
|
|
15
15
|
criteria: toApprovalCriteria(payload.criteria),
|
|
16
16
|
steps: toApprovalSteps(payload.steps),
|
|
17
|
+
description: payload.description ?? undefined,
|
|
18
|
+
priority: payload.priority,
|
|
19
|
+
isFallback: payload.is_fallback ?? false,
|
|
20
|
+
// separationOfDuties: backend doesn't ship this field yet; left undefined
|
|
21
|
+
// until the spec is finalized.
|
|
22
|
+
areApprovalsSerialized: payload.are_approvals_serialized,
|
|
23
|
+
pendingApprovalsCount: payload.pending_approvals_count,
|
|
24
|
+
pendingEntityApprovalUpdateStatus: payload.pending_entity_approval_update_status,
|
|
17
25
|
});
|
|
26
|
+
/**
|
|
27
|
+
* Maps the wire-level criteria block into the state-side discriminated
|
|
28
|
+
* `Criteria[]` union.
|
|
29
|
+
*
|
|
30
|
+
* The wire keeps each condition as a flat row inside `conditions[]`.
|
|
31
|
+
* Amount comparisons can show up as a `gte` only, a `lte` only, or a
|
|
32
|
+
* `gte` + `lte` pair — those collapse into a single AmountCriteria whose
|
|
33
|
+
* `comparator` is `greater_than`, `less_than`, or `range` respectively.
|
|
34
|
+
*
|
|
35
|
+
* Vendor and department conditions map one-to-one: `in` becomes `is`,
|
|
36
|
+
* `not_in` becomes `is_not`.
|
|
37
|
+
*
|
|
38
|
+
* Resilient to two forms of upstream drift:
|
|
39
|
+
* - Missing / null criteria → returns [].
|
|
40
|
+
* - Legacy criteria shape (array of amount-range objects, the pre-3.0
|
|
41
|
+
* wire) → converted to an AmountCriteria so existing rules in production
|
|
42
|
+
* still render while the backend rolls out.
|
|
43
|
+
*/
|
|
18
44
|
const toApprovalCriteria = (payload) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
45
|
+
if (payload == null) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(payload)) {
|
|
49
|
+
// Legacy pre-3.0 wire: an array of amount-range entries.
|
|
50
|
+
return legacyAmountRangeToCriteria(payload);
|
|
51
|
+
}
|
|
52
|
+
if (!Array.isArray(payload.conditions)) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const results = [];
|
|
56
|
+
const amountCriteria = toAmountCriteria(payload);
|
|
57
|
+
if (amountCriteria != null) {
|
|
58
|
+
results.push(amountCriteria);
|
|
59
|
+
}
|
|
60
|
+
payload.conditions
|
|
61
|
+
.filter((condition) => condition.field === 'vendor_id')
|
|
62
|
+
.forEach((condition) => {
|
|
63
|
+
const vendor = toVendorCriteria(condition);
|
|
64
|
+
if (vendor != null) {
|
|
65
|
+
results.push(vendor);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
payload.conditions
|
|
69
|
+
.filter((condition) => condition.field === 'department_id')
|
|
70
|
+
.forEach((condition) => {
|
|
71
|
+
const department = toDepartmentCriteria(condition);
|
|
72
|
+
if (department != null) {
|
|
73
|
+
results.push(department);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return results;
|
|
77
|
+
};
|
|
78
|
+
const legacyAmountRangeToCriteria = (legacy) => {
|
|
79
|
+
if (legacy.length === 0) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
const first = legacy[0] ?? {};
|
|
83
|
+
const currency = first.currency_code ?? 'USD';
|
|
84
|
+
const symbol = first.currency_symbol ?? '$';
|
|
85
|
+
const min = typeof first.min === 'number'
|
|
86
|
+
? toAmount(first.min, currency, symbol)
|
|
87
|
+
: undefined;
|
|
88
|
+
const max = typeof first.max === 'number'
|
|
89
|
+
? toAmount(first.max, currency, symbol)
|
|
90
|
+
: undefined;
|
|
91
|
+
if (min == null && max == null) {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const comparator = min != null && max != null
|
|
95
|
+
? 'range'
|
|
96
|
+
: min != null
|
|
97
|
+
? 'greater_than'
|
|
98
|
+
: 'less_than';
|
|
99
|
+
return [{ type: 'amount', comparator, min, max }];
|
|
100
|
+
};
|
|
101
|
+
const toAmountCriteria = (payload) => {
|
|
102
|
+
if (!Array.isArray(payload.conditions)) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
const amountConditions = payload.conditions.filter((condition) => condition.field === 'amount');
|
|
106
|
+
const gteCondition = amountConditions.find((condition) => condition.type === 'gte' || condition.type === 'eq');
|
|
107
|
+
const lteCondition = amountConditions.find((condition) => condition.type === 'lte');
|
|
108
|
+
if (gteCondition == null && lteCondition == null) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const currencyCode = payload.currency_code ?? 'USD';
|
|
112
|
+
const currencySymbol = payload.currency_symbol ?? '$';
|
|
113
|
+
const min = typeof gteCondition?.value === 'number'
|
|
114
|
+
? toAmount(gteCondition.value, currencyCode, currencySymbol)
|
|
115
|
+
: undefined;
|
|
116
|
+
const max = typeof lteCondition?.value === 'number'
|
|
117
|
+
? toAmount(lteCondition.value, currencyCode, currencySymbol)
|
|
118
|
+
: undefined;
|
|
119
|
+
let comparator;
|
|
120
|
+
if (min != null && max != null) {
|
|
121
|
+
comparator = 'range';
|
|
122
|
+
}
|
|
123
|
+
else if (min != null) {
|
|
124
|
+
comparator = 'greater_than';
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
comparator = 'less_than';
|
|
128
|
+
}
|
|
129
|
+
return { type: 'amount', comparator, min, max };
|
|
130
|
+
};
|
|
131
|
+
const toVendorCriteria = (condition) => {
|
|
132
|
+
if (!Array.isArray(condition.value)) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
type: 'vendor',
|
|
137
|
+
operator: condition.type === 'not_in' ? 'is_not' : 'is',
|
|
138
|
+
vendorIds: condition.value,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
const toDepartmentCriteria = (condition) => {
|
|
142
|
+
if (!Array.isArray(condition.value)) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
type: 'department',
|
|
147
|
+
operator: condition.type === 'not_in' ? 'is_not' : 'is',
|
|
148
|
+
departmentIds: condition.value,
|
|
149
|
+
};
|
|
29
150
|
};
|
|
30
151
|
const toApprovalSteps = (payload) => {
|
|
31
152
|
return payload.map((step) => ({
|
|
@@ -7,3 +7,38 @@ export function getApprovalRulesByIds(approvalRuleState, approvalRuleIds) {
|
|
|
7
7
|
.filter((value) => value != null);
|
|
8
8
|
return approvalRulesByIds;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Returns the amount-range portion of a rule's criteria, if any.
|
|
12
|
+
*
|
|
13
|
+
* Use this whenever a caller needs to read amount min/max from the new
|
|
14
|
+
* discriminated `Criteria` union without inlining a type guard.
|
|
15
|
+
*/
|
|
16
|
+
export function getAmountCriteria(criteria) {
|
|
17
|
+
return criteria.find((c) => c.type === 'amount');
|
|
18
|
+
}
|
|
19
|
+
export function getVendorCriteria(criteria) {
|
|
20
|
+
return criteria.find((c) => c.type === 'vendor');
|
|
21
|
+
}
|
|
22
|
+
export function getDepartmentCriteria(criteria) {
|
|
23
|
+
return criteria.find((c) => c.type === 'department');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns all rules of the given entityType, sorted by `priority` ascending.
|
|
27
|
+
*
|
|
28
|
+
* Rules without a `priority` value sort to the end (treated as Infinity).
|
|
29
|
+
* Use this for the list page where rules render in evaluation order.
|
|
30
|
+
*/
|
|
31
|
+
export function getApprovalRulesByEntityType(approvalRuleState, entityType) {
|
|
32
|
+
return Object.values(approvalRuleState.approvalRuleById)
|
|
33
|
+
.filter((rule) => rule.entityType === entityType)
|
|
34
|
+
.sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the tenant's fallback rule for the given entityType, if one exists.
|
|
38
|
+
*
|
|
39
|
+
* The fallback rule is shown by the "fallback engine active" banner on the
|
|
40
|
+
* list page and is used to handle bills/reimbursements that match no other rule.
|
|
41
|
+
*/
|
|
42
|
+
export function getFallbackApprovalRule(approvalRuleState, entityType) {
|
|
43
|
+
return Object.values(approvalRuleState.approvalRuleById).find((rule) => rule.entityType === entityType && rule.isFallback === true);
|
|
44
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createSelector } from '@reduxjs/toolkit';
|
|
2
1
|
import recordGet from 'lodash/get';
|
|
3
2
|
import { getCOABalances } from '../../commonStateTypes/coaBalance/coaBalance';
|
|
4
3
|
import { getAccount } from '../account/accountSelector';
|
|
@@ -51,50 +50,3 @@ export function getClassReport(classState, accountState, id, filter) {
|
|
|
51
50
|
accounts: accountReport,
|
|
52
51
|
};
|
|
53
52
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Returns all classes currently in state (single pass over classesByKey).
|
|
56
|
-
* Use for dropdowns that need class names; map to { classId, className } as needed.
|
|
57
|
-
*/
|
|
58
|
-
export function getAllClasses(classState) {
|
|
59
|
-
return Object.values(classState.classesByKey);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Memoised projection of `getAllClasses` to the `{classId, className}` shape
|
|
63
|
-
* expected by filter dropdowns. Consumers should prefer this over inlining a
|
|
64
|
-
* `getAllClasses(...).map(...)` inside `useSelector`: the inline map allocates
|
|
65
|
-
* a fresh array on every Redux dispatch, breaking `useSelector`'s
|
|
66
|
-
* reference-equality optimisation and triggering re-renders on every state
|
|
67
|
-
* change unrelated to class data.
|
|
68
|
-
*
|
|
69
|
-
* Two cleanups happen here, intentionally inside the selector so every
|
|
70
|
-
* consumer benefits uniformly:
|
|
71
|
-
* 1. **Drop entries with a blank `className`.** Soft-deleted classes can
|
|
72
|
-
* retain their classId in state while the human name is blanked, which
|
|
73
|
-
* would otherwise render as an empty row in the filter dropdown.
|
|
74
|
-
* 2. **Dedupe by `classId`.** `classesByKey` is keyed by
|
|
75
|
-
* `${classId}-${reportId}` (see `getClassKey`), so a class loaded under
|
|
76
|
-
* multiple report contexts appears as multiple entries from
|
|
77
|
-
* `Object.values(classesByKey)`. The first non-blank entry per
|
|
78
|
-
* `classId` wins.
|
|
79
|
-
*/
|
|
80
|
-
export const getClassFilterOptions = createSelector(
|
|
81
|
-
// Key the memo on the underlying `classesByKey` record rather than on
|
|
82
|
-
// `getAllClasses` output: the latter returns a fresh `Object.values(...)`
|
|
83
|
-
// array on every call, which would defeat reselect's reference-equality
|
|
84
|
-
// check and re-run the projection on every dispatch.
|
|
85
|
-
[(classState) => classState.classesByKey], (classesByKey) => {
|
|
86
|
-
const classes = Object.values(classesByKey);
|
|
87
|
-
const seenClassIds = new Set();
|
|
88
|
-
const options = [];
|
|
89
|
-
for (const c of classes) {
|
|
90
|
-
if (c.classId == null || seenClassIds.has(c.classId)) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (c.className == null || c.className.trim() === '') {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
seenClassIds.add(c.classId);
|
|
97
|
-
options.push({ classId: c.classId, className: c.className });
|
|
98
|
-
}
|
|
99
|
-
return options;
|
|
100
|
-
});
|
package/lib/esm/index.js
CHANGED
|
@@ -24,7 +24,6 @@ import { mapTimePeriodtoTimeframeTick, toTimePeriod, toTimeframeTick, } from './
|
|
|
24
24
|
import { isAgingReport, isCashFlowOrBalanceSheetReport, isDashboardClassesViewReport, isDashboardReport, isFluxAnalysisOpExReport, isOpExByVendorReport, isPAndLClassesViewReport, isPAndLProjectViewReport, isPAndLReport, } from './commonStateTypes/viewAndReport/reportIDHelper';
|
|
25
25
|
import { toReportFormatStrict, toReportID, } from './commonStateTypes/viewAndReport/viewAndReport';
|
|
26
26
|
import { PAYMENT_BUSINESS_DAYS, filterDays, getNextNthWorkingDay, getPreviousNthWorkingDay, getYearsList, holidaysFormatted, isHoliday, isHolidayToday, } from './commonStateTypes/workingDayHelper';
|
|
27
|
-
import { getAllAccounts, getTransactionFilterAccountOptions, } from './entity/account/accountSelector';
|
|
28
27
|
import { toAccountType, toReconciliationAccountSource, } from './entity/account/accountState';
|
|
29
28
|
import { getAccountGroupKey, toAccountGroupType, } from './entity/accountGroup/accountGroupState';
|
|
30
29
|
/**
|
|
@@ -33,6 +32,7 @@ import { getAccountGroupKey, toAccountGroupType, } from './entity/accountGroup/a
|
|
|
33
32
|
import { getAccountReconByAccountIdAndSelectedPeriod, } from './entity/accountRecon/accountReconSelector';
|
|
34
33
|
import { getAddressByAddressId } from './entity/address/addressSelector';
|
|
35
34
|
import { toAttributeOrRoleTypeStrict, toAttributeTypeStrict, toRoleTypeStrict, } from './entity/approvalRule/approvalRuleState';
|
|
35
|
+
import { getAmountCriteria, getApprovalRulesByEntityType, getDepartmentCriteria, getFallbackApprovalRule, getVendorCriteria, } from './entity/approvalRule/approvalRuleSelector';
|
|
36
36
|
import { toOutsideZeniPaymentModeType, } from './entity/billPay/billTransaction/billTransactionState';
|
|
37
37
|
import { toRecurringBillFrequency, toRecurringBillFrequencyStrict, } from './entity/billPay/recurringBills/recurringBillsState';
|
|
38
38
|
import { toCardAddressType, toCardType, toCreditLimitFrequencyCodeType, toShippingAddressType, } from './entity/chargeCard/chargeCard';
|
|
@@ -169,7 +169,7 @@ import { clearExpenseAutomationFluxAnalysisView, fetchFluxAnalysisView, reviewFl
|
|
|
169
169
|
import { clearJeScheduleLocalData as clearExpenseAutomationJEScheduleLocalData, clearExpenseAutomationJESchedulesView, fetchJeSchedulesPage as fetchExpenseAutomationJESchedulesPage, ignoreRecommendedJeSchedule as ignoreExpenseAutomationJESchedule, initializeAccountSettingsView as initializeJeAccountSettingsView, initializeJeScheduleLocalData, removeJeScheduleTransactionKey, retryJeSchedule as retryExpenseAutomationJESchedule, saveAccountSettings as saveJeAccountSettings, saveAccountSettingsLocalData as saveJeAccountSettingsLocalData, updateJESchedulesUIState as updateExpenseAutomationJESchedulesUIState, updateJeScheduleLocalDataById, updateJeScheduleTransactionKeys, } from './view/expenseAutomationView/reducers/jeSchedulesViewReducer';
|
|
170
170
|
import { acknowledgeBulkUploadConfirmMatchComplete, bulkUploadAutomatchingTimedOut, bulkUploadReceipts, bulkUploadReceiptsFailure, bulkUploadReceiptsSuccess, clearBulkUpload, clearManualSearchResults, clearMissingReceiptsTabNavigation, confirmBulkUploadMatch, confirmBulkUploadMatchFailure, confirmBulkUploadMatchSuccess, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsFailure, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, fetchBulkUploadBatchesFailure, fetchBulkUploadBatchesSuccess, fetchCompletedTransactions, fetchCompletedTransactionsFailure, fetchCompletedTransactionsSuccess, fetchMissingReceipts as fetchExpenseAutomationMissingReceipts, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, markMissingReceiptAsDone as markExpenseAutomationMissingReceiptAsDone, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, searchTransactionsForManualMatch, searchTransactionsForManualMatchFailure, searchTransactionsForManualMatchSuccess, setBulkUploadCompletedSubTab, setBulkUploadResultsTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, storeBatchDetails, updateBulkUploadProgress, updateMissingReceiptUploadState as updateExpenseAutomationMissingReceiptUploadState, updateMissingReceiptsUIState as updateExpenseAutomationMissingReceiptsUIState, uploadMissingReceiptSuccess as uploadExpenseAutomationMissingReceiptSuccess, } from './view/expenseAutomationView/reducers/missingReceiptsViewReducer';
|
|
171
171
|
import { deleteAccountStatement, excludeAccountFromReconciliation, fetchReconciliation as fetchReconciliationView, includeAccountInReconciliation, saveReconciliationDetail as saveExpenseAutomationReconciliationDetail, saveReconciliationReview as saveExpenseAutomationReconciliationReview, setConnectionInProgressForAccount as setConnectionInProgressForAccountReconciliation, setStatementParseInProgress, updateAccountReconciliationLocalData as updateExpenseAutomationAccountReconciliationLocalData, updateSelectedAccountId as updateExpenseAutomationAccountReconciliationSelectedAccountId, updateSelectedTab as updateExpenseAutomationAccountReconciliationSelectedTab, updateReconListScrollPosition as updateExpenseAutomationReconListScrollPosition, updateReviewTabSortState as updateExpenseAutomationReconReviewTabListSortState, updateReviewTabLocalData as updateExpenseAutomationReconReviewTabLocalData, updateReconcileTabListScrollState as updateExpenseAutomationReconcileTabListScrollState, updateReconcileTabListSortState as updateExpenseAutomationReconcileTabListSortState, updateReconcileTabLocalData as updateExpenseAutomationReconcileTabLocalData, updateSelectedDrawerAccountId as updateExpenseAutomationSelectedDrawerAccountId, updateNodeCollapseState, updateStatementUploadChosen, uploadAccountStatement, } from './view/expenseAutomationView/reducers/reconciliationViewReducer';
|
|
172
|
-
import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, updateTransactionCategorizationUploadReceiptState,
|
|
172
|
+
import { backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, fetchTransactionCategorization, fetchTransactionCategorizationFailure, fetchTransactionCategorizationView, initializeTransactionCategorizationViewLocalData, markTransactionAsNotMiscategorized, saveTransactionCategorization, saveTransactionCategorizationLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, setEntityRecommendationForLineIdsForCategorization, syncTransactionCategorizationFromDetailSave, updateCurrentSelectedTransactionCategorizationTab, updateSelectedCheckboxTransactionIds, updateSelectedCustomerForTransaction, updateSelectedTransactionId, updateSelectedVendorForTransaction, updateTransactionCategorization, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, updateTransactionCategorizationUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } from './view/expenseAutomationView/reducers/transactionsViewReducer';
|
|
173
173
|
import { getExpenseAutomationFluxAnalysisView } from './view/expenseAutomationView/selectors/fluxAnalysisViewSelector';
|
|
174
174
|
import { getExpenseAutomationReconciliationView, isAccountReconReport, } from './view/expenseAutomationView/selectors/reconciliationViewSelector';
|
|
175
175
|
import { getExpenseAutomationTransactionView } from './view/expenseAutomationView/selectors/transactionCategorizationSelector';
|
|
@@ -337,7 +337,6 @@ import { getRemiBusinessVerificationDetails, getRemiSetupViewDetails, } from './
|
|
|
337
337
|
import { approveOrRejectRemisBulkAction, autoReviewPendingApprovalRemis, cancelOrDeleteRemisBulkAction, clearAllRemisFromBulkActionList, clearRemiBulkActionView, incrementRemiBulkActionProcessedCount, removeRemiFromBulkActionList, reviewDraftRemisBulkAction, submitDraftRemisBulkAction, updateRemisBulkActionList, } from './view/spendManagement/reimbursement/remisBulkActionView/remisBulkActionViewReducer';
|
|
338
338
|
import { getRemisBulkOperationProgress, getRemisBulkReviewView, } from './view/spendManagement/reimbursement/remisBulkActionView/remisBulkActionViewSelector';
|
|
339
339
|
import { hideCreatedByFilter, } from './view/spendManagement/spendManagementFilterHelpers';
|
|
340
|
-
import { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, } from './view/expenseAutomationView/transactionFilterHelpers';
|
|
341
340
|
import { acceptTreasuryTerms, clearTreasurySetupView, fetchPortfolioAllocation, fetchTreasuryFunds, fetchTreasurySetupView, updateFundAllocationLocalData, updatePortfolioAllocation, updateTreasuryVideoViewed, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewReducer';
|
|
342
341
|
import { getTreasuryBusinessVerificationDetails, getTreasurySetupViewDetails, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewSelector';
|
|
343
342
|
import { getTreasuryFundsMaximumYield, } from './view/spendManagement/treasury/treasurySetUp/treasurySetupViewState';
|
|
@@ -450,15 +449,15 @@ export {
|
|
|
450
449
|
BATCH_FILE_STATUSES, isUnmatchedTabFileStatus, DEFAULT_COMPLETED_SUB_TAB, toBatchFileStatus, toBatchStatusValue, toBulkUploadPhase, toBulkUploadResultsTab, toBulkUploadSortKey, toCompletedSubTab, toMatchSource, toMissingReceiptsTab, toExpenseAutomationJEScheduleMainTab, toExpenseAutomationJEScheduleSortKey, getExpenseAutomationView, toExpenseAutomationMissingReceiptsSortKey, toExpenseAutomationTransactionsTabKey, toExpenseAutomationViewType, uploadExpenseAutomationMissingReceiptSuccess, markExpenseAutomationMissingReceiptAsDone, fetchAllExpenseAutomationTabs, refreshExpenseAutomationCurrentTab, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, fetchExpenseAutomationMissingReceipts,
|
|
451
450
|
// Bulk Upload Actions
|
|
452
451
|
bulkUploadReceipts, bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, bulkUploadReceiptsFailure, restoreBulkUploadAutomatchingOnMount, restoreBulkUploadMatchingState, updateBulkUploadProgress, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, clearMissingReceiptsTabNavigation, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatchDetailsFailure, storeBatchDetails, fetchMoreBatchDetails, fetchMoreBatchDetailsComplete, fetchMoreBatchDetailsFailure, fetchBulkUploadBatches, fetchBulkUploadBatchesSuccess, fetchBulkUploadBatchesFailure, confirmBulkUploadMatch, confirmBulkUploadMatchSuccess, confirmBulkUploadMatchFailure, setBulkUploadResultsTab, setBulkUploadCompletedSubTab, setBulkUploadSortConfig, setBulkUploadUploadedFileCount, clearBulkUpload, searchTransactionsForManualMatch, searchTransactionsForManualMatchSuccess, searchTransactionsForManualMatchFailure, clearManualSearchResults, acknowledgeBulkUploadConfirmMatchComplete, fetchCompletedTransactions, fetchCompletedTransactionsSuccess, fetchCompletedTransactionsFailure, fetchFluxAnalysisView, clearExpenseAutomationFluxAnalysisView, updateOperatingExpensesIdsForReview as updateFluxOperatingExpensesIdsForReview, updateSelectedSectionIdsForReview as updateFluxAnalysisSelectedSectionIdsForReview, reviewFluxAnalysisView, updateExpenseAutomationMissingReceiptUploadState, updateExpenseAutomationMissingReceiptsUIState, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, getExpenseAutomationFluxAnalysisView, updateCurrentSelectedView, updateCurrentSelectedPeriod, getExpenseAutomationTransactionView, updateFluxAnalysisViewUIState, updateFluxAnalysisViewPageMetaData, MAX_SELECTION_LIMIT, checkIfAllLineItemsAreCategoryClassFilled, getLineItemsByTransactionIdsFromLocalData, isAnyItemWithUncategorizedExpenseAccount, excludeAccountFromReconciliation, includeAccountInReconciliation, saveExpenseAutomationReconciliationDetail, updateExpenseAutomationReconcileTabListScrollState, updateExpenseAutomationReconReviewTabListSortState, updateExpenseAutomationReconcileTabListSortState, updateExpenseAutomationReconcileTabLocalData, updateExpenseAutomationAccountReconciliationSelectedTab, updateExpenseAutomationAccountReconciliationSelectedAccountId, getExpenseAutomationReconciliationView, fetchReconciliationView, uploadAccountStatementIntoDocumentAI, updateExpenseAutomationReconListScrollPosition, setConnectionInProgressForAccountReconciliation, getAccountReconByAccountIdAndSelectedPeriod, toReconciliationTabsType, isAccountReconReport, updateExpenseAutomationReconReviewTabLocalData, updateExpenseAutomationSelectedDrawerAccountId, saveExpenseAutomationReconciliationReview, updateExpenseAutomationAccountReconciliationLocalData, toReconciliationAccountSource, deleteAccountStatement, uploadAccountStatement, updateNodeCollapseState, updateStatementUploadChosen, isReviewTransactionBankTransferType, isReviewTransactionBillPaymentType, isReviewTransactionCreditCardPaymentType, isReviewTransactionDepositType, isReviewTransactionExpenseType, isReviewTransactionCreditCardCreditType, setStatementParseInProgress, };
|
|
453
|
-
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState,
|
|
452
|
+
export { fetchTransactionCategorization, fetchTransactionCategorizationView, updateTransactionCategorizationUIState, updateSelectedCheckboxTransactionIds, setEntityRecommendationForLineIdsForCategorization, initializeTransactionCategorizationViewLocalData, setAllItemsToCategoryClassInLocalDataForCategorization, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, clearExpenseAutomationTransactionsView, toTransactionsSortKey, };
|
|
454
453
|
export { TOP_EX_TIME_PERIODS };
|
|
455
454
|
export { toTimeframeTick, mapTimePeriodtoTimeframeTick, toTimePeriod, toAbsoluteDay, toMonthYearPeriodId, convertToPeriod, };
|
|
456
455
|
export { toVendorSpendTrendFilterTabsTypeStrict, } from './entity/vendorExpense/vendorExpenseSelector';
|
|
457
456
|
export { getNumberOfPeriods };
|
|
458
457
|
export { SCHEDULE_DAYS_OF_MONTH, toScheduleDaysOfMonth, toMonth, toMonthStrict, toQuarter, toQuarterStrict, };
|
|
459
458
|
export { getTenantBaseById, getCurrentTenant, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, getTenantsByCheckInDateSelector, getTenantsBaseByCheckInDateSelector, getTenantsCoreDetailsByCheckInDateSelector, toTenantCoreDetailsView, getTenantBaseViewForTenantView, getTenantBaseViewForTenantId, isZeniDomainTenant, isTenantUsingZeniCOA, fetchActiveTenant, fetchAllTenants, updateCurrentTenant, clearAll, doMagicLinkSignIn, verifyDeviceWithTwoFA, resendVerifyDeviceOTP, sendEmailMagicLinkToUser, doSignIn, updateSignInState, doSignOut, sendSessionHeartbeat, resetSignInState, fetchExcludedResourcesForTenant, fetchExternalConnectionsForTenant, saveExternalConnectionForTenant, deleteConnection, saveAPIKeyConnection, saveConnectorCredentials, saveOAuthConnection, toExternalIntegrationType, toExternalSupportedTool, fetchSubscriptionSummaryForTenant, isTenantBankingOnly, isTenantCardsOnly, isTenantBookkeepingEnabled, isOtherProductsEnabledForTenant, };
|
|
460
|
-
export { toAccountType, toAccountGroupType, getAccountGroupKey,
|
|
461
|
-
export {
|
|
459
|
+
export { toAccountType, toAccountGroupType, getAccountGroupKey, };
|
|
460
|
+
export { getClassById } from './entity/class/classSelector';
|
|
462
461
|
export { getForecast };
|
|
463
462
|
export { getUserName, getUserByUserId, getUsersByUserIds, getAllZeniUsersFromState, } from './entity/user/userSelector';
|
|
464
463
|
export { toUserRoleType, toUserRoleTypeStrict, isFinOpsUserRoleType, hasAdminLevelAccess, hasFullOrAdminLevelAccess, hasReimbursementUserAccess, hasEmployeeLevelAccess, hasBookKeepingAdminLevelAccess, hasBookKeepingUserLevelAccess, isNonZeniRole, hasInvestorBankerLevelAccess, getUserRoleMap, hasOnlyBillPayAccess, hasZeniRoleOrCompanyOfficerAccess, hasSuperAdminLevelAccess, hasBillPayFallbackAdminLevelAccess, hasRemiFallbackAdminLevelAccess, hasOnlyReimbursementAccess, hasOnlyChargeCardAccess, hasOnlyZeniAccountsAccess, isZeniSignedInUser, getUserRoleByUserId, getUserRoleByUserIds, hasChargeCardAccess, hasZeniAccountsAccess, hasTreasuryAccess, hasTreasuryAdminLevelAccess, hasBillPayAccess, hasReimbursementAccess, hasReimbursementAdminLevelAccess, hasBillPayAdminLevelAccess, hasChargeCardAdminLevelAccess, hasSpendManagementAccess, hasSpendManagementAdminLevelAccess, hasZeniAccountsAdminLevelAccess, hasAnyCompanyRole, hasAnyFinOpRole, hasBillPayAccessible, hasReimbursementAccessible, hasZeniAccountsAccessible, hasChargeCardAccessible, hasTreasuryAccessible, hasAICFOAccess, };
|
|
@@ -558,10 +557,6 @@ export { toRemiSubTabType, toRemiSubTabTypeStrict, toRemiTabType, toRemiTabTypeS
|
|
|
558
557
|
export { getClassList, fetchClassList, getProjectList, fetchProjectList, };
|
|
559
558
|
export { fetchBillList, fetchBillListPerTab, updateTab, updateSubTab, updateSelectedBillId, updateBillDetailSaveBillCode, fetchVendorByNameAndParseInvoice, saveBillUpdatesToLocalStore, discardBillUpdatesInLocalStore, saveBillDetail, approveOrRejectBill, updateApprovalStatusOnSuccess, deleteBill, cancelAndDeleteBill, retryOrRefundBill, getBillList, getBillDownloadList, getBillDetailView, checkApproveRejectBtnShowForBill, getBillTransactionDetailKey, fetchBillDetail, fetchEditBillDetailPage, fetchAndUpdateVendorRecommendations, fetchDuplicateBill, clearBillPayReview, getEditBillDetail, getReviewPageBillDetail, fetchBillAndInitializeLocalStore, updateShowAutofill, saveVendorSuccessOrFailure, updateBillListUIState, BILL_PAY_FILTER_CATEGORIES, updateVendorDetailLocalData, resetVendorDetailLocalData, resetVendorSaveStatus, updateContactsInVendorDetailLocalData, updateVendorTabDetailUIState, updateContactsInVendorTabDetailLocalData, updateBillUploadFetchState, updateBillListSearchResult, fetchUserDetails, verifyUser, updateVendorContact, toPaymentToOption, convertAmountToHomeCurrency, fetchVendorAndUpdateBillLocalData, markBillForRetry, updateWithdrawFromAccountId, removeBillFileFromLocalStore, replaceBillFileInLocalStore, updateShouldReplaceBillData, };
|
|
560
559
|
export { hideCreatedByFilter, };
|
|
561
|
-
// Transaction Categorization filter API — lives under Expense Automation,
|
|
562
|
-
// not Spend Management. Kept in a separate re-export block to make the
|
|
563
|
-
// separation visible at the barrel level.
|
|
564
|
-
export { TRANSACTION_FILTER_CATEGORIES, applyTransactionFilters, };
|
|
565
560
|
export { fetchBillPaySetupView, fetchZeniAccountSetupView, enableSetup, getPaymentAccounts, getPlaidLinkToken, updateSelectedCompanyOfficer, updateSetupViewLocalStoreData, updateBusinessVerificationDetails, updatePaymentAccount, updatePaymentAccountLoginStatus, updatePaymentAccountStatus, establishPlaidConnection, updateMappedCashAccount, updatePrimaryFundingAccount, acceptBillPayTerms, acceptZeniAccountTerms, acceptBillPayUpdatedTerms, saveSetupViewDataInLocalStore, saveCompnayOfficerPhoneInLocalStore, saveCompnayOfficerAdditionalDocumentsInLocalStore, saveTreasuryAdditionalDocumentsInLocalStore, saveIndustryAndIncDateInLocalStore, clearSetupViewDataInLocalStore, clearBillPaySetupView, clearZeniAccountSetupView, sendOtp, resendOtp, verifyOtp, getBillPaySetupViewDetails, getPlaidAccountDetails, getZeniAccountSetupViewDetails, getBusinessVerificationDetails, getBillPayBusinessVerificationDetails, getZeniAccountBusinessVerificationDetails, getTreasuryBusinessVerificationDetails, getCommonSetupViewDetails, getTwoFactorAuthenticationView, getTwoFactorAuthenticationViewForCardUserOnboarding, getTwoFactorAuthenticationViewForChargeCardHolder, };
|
|
566
561
|
export { getApprovalRuleViewDetails, getBankConnectionsSetupViewDetails, getIntegrationsView, };
|
|
567
562
|
export { fetchUserFinancialAccount };
|
|
@@ -569,7 +564,7 @@ export { getUserFinancialAccount };
|
|
|
569
564
|
export { fetchRemiSetupView, updateMileageDetails, saveRemiSetupViewDataInLocalStore, acceptRemiTerms, acceptEmployeeRemiTerms, clearRemiSetupView, getRemiSetupViewDetails, getRemiBusinessVerificationDetails, };
|
|
570
565
|
export { VERIFIED_PAYMENT_ACCOUNT_PROVIDER_VERIFICATION_STATUS, };
|
|
571
566
|
export { isSuccessResponse, isInvalidSessionError, isAccessDeniedError, };
|
|
572
|
-
export { toAttributeTypeStrict, toAttributeOrRoleTypeStrict, toRoleTypeStrict, };
|
|
567
|
+
export { getAmountCriteria, getApprovalRulesByEntityType, getDepartmentCriteria, getFallbackApprovalRule, getVendorCriteria, toAttributeTypeStrict, toAttributeOrRoleTypeStrict, toRoleTypeStrict, };
|
|
573
568
|
export { getBillPaySetupApproverView, getBillPaySetupApproverUpdateDataView, fetchBillPaySetupApproverView, fetchBillPayApproversDetails, fetchBillPayApproversList, deleteBillPayApprovalRule, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setBillsSetupApproverViewListeningToPusherEvent, initializeBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverView, };
|
|
574
569
|
export { getRemiSetupApproverView, getRemiSetupApproverUpdateDataView, fetchRemiSetupApproverView, fetchRemiApproversList, fetchRemiApproversDetails, deleteRemiApprovalRule, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, initializeRemiSetupApproverViewUpdateData, setRemiSetupApproverViewListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, };
|
|
575
570
|
export { getRemiDetailView, checkApproveRejectBtnShowForRemi, };
|
|
@@ -291,7 +291,7 @@ const applyAdvancedFiltersOnCompaniesList = (allCompanies, filters, filteredComp
|
|
|
291
291
|
const key = currentFilter.field;
|
|
292
292
|
const categoryValue = getCategoryValueForCompany(key, company);
|
|
293
293
|
if (categoryValue == null) {
|
|
294
|
-
if (currentFilter.matchingOperator === '
|
|
294
|
+
if (currentFilter.matchingOperator === 'not-equal') {
|
|
295
295
|
return true;
|
|
296
296
|
}
|
|
297
297
|
return false;
|
|
@@ -48,7 +48,7 @@ export const filterCompanyOnCategoriesWithSingleValue = (categoryValue, currentF
|
|
|
48
48
|
return filterCompanyOnRangeCategoryType(categoryValue, currentFilter);
|
|
49
49
|
}
|
|
50
50
|
// if filter category is not annualRecurringRevenue OR monthlyRecurringRevenue
|
|
51
|
-
if (currentFilter.matchingOperator === '
|
|
51
|
+
if (currentFilter.matchingOperator === 'not-equal') {
|
|
52
52
|
return currentFilter.values.indexOf(categoryValue) === -1;
|
|
53
53
|
}
|
|
54
54
|
return currentFilter.values.indexOf(categoryValue) > -1;
|
|
@@ -150,7 +150,7 @@ const applyAdvancedFiltersOnCompaniesList = (allCompanies, filters, filteredComp
|
|
|
150
150
|
const key = currentFilter.field;
|
|
151
151
|
const categoryValue = getCategoryValueForCompany(key, company);
|
|
152
152
|
if (categoryValue == null) {
|
|
153
|
-
if (currentFilter.matchingOperator === '
|
|
153
|
+
if (currentFilter.matchingOperator === 'not-equal') {
|
|
154
154
|
return true;
|
|
155
155
|
}
|
|
156
156
|
return false;
|
|
@@ -116,7 +116,7 @@ const applyAdvancedFiltersOnCompaniesList = (allCompanies, filters, filteredComp
|
|
|
116
116
|
const key = currentFilter.field;
|
|
117
117
|
const categoryValue = getCategoryValueForCompany(key, company);
|
|
118
118
|
if (categoryValue == null) {
|
|
119
|
-
if (currentFilter.matchingOperator === '
|
|
119
|
+
if (currentFilter.matchingOperator === 'not-equal') {
|
|
120
120
|
return true;
|
|
121
121
|
}
|
|
122
122
|
return false;
|
|
@@ -28,10 +28,6 @@ export const initialTransactionTabViewState = {
|
|
|
28
28
|
totalCount: {},
|
|
29
29
|
limit: 10,
|
|
30
30
|
},
|
|
31
|
-
filters: {
|
|
32
|
-
categoryCombinationOperator: 'AND',
|
|
33
|
-
categories: [],
|
|
34
|
-
},
|
|
35
31
|
fetchState: 'Not-Started',
|
|
36
32
|
error: undefined,
|
|
37
33
|
hasValidState() {
|
|
@@ -303,12 +299,6 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
303
299
|
uiState.totalCount;
|
|
304
300
|
}
|
|
305
301
|
},
|
|
306
|
-
updateTransactionFilters(draft, action) {
|
|
307
|
-
const { selectedTab, filters } = action.payload;
|
|
308
|
-
if (filters != null) {
|
|
309
|
-
draft.transactionCategorizationView[selectedTab].filters = filters;
|
|
310
|
-
}
|
|
311
|
-
},
|
|
312
302
|
saveTransactionCategorization: {
|
|
313
303
|
prepare(selectedTab, transactionIds, cotTrackingByTransactionId, isUncategorizedExpenseCategoryEnabled) {
|
|
314
304
|
return {
|
|
@@ -939,5 +929,5 @@ const expenseAutomationTransactionsView = createSlice({
|
|
|
939
929
|
},
|
|
940
930
|
},
|
|
941
931
|
});
|
|
942
|
-
export const { fetchTransactionCategorization, updateTransactionCategorizationUIState,
|
|
932
|
+
export const { fetchTransactionCategorization, updateTransactionCategorizationUIState, initializeTransactionCategorizationViewLocalData, saveTransactionCategorizationLocalData, fetchTransactionCategorizationFailure, saveTransactionCategorization, updateTransactionCategorization, updateCurrentSelectedTransactionCategorizationTab, updateTransactionCategorizationCompletedSubTab, updateTransactionCategorizationSaveStatus, markTransactionAsNotMiscategorized, updateStatusForTransactionNotMiscategorizedUpdateForCategorization, updateSelectedVendorForTransaction, updateSelectedCustomerForTransaction, setAllItemsToCategoryClassInLocalDataForCategorization, updateTotalCountForTransactionCategorization, updateParentTotalCountForTab, fetchTransactionCategorizationSuccess, resetOtherTabsFetchState, fetchTransactionCategorizationView, updateSelectedCheckboxTransactionIds, clearExpenseAutomationTransactionsViewPerTabView, clearExpenseAutomationTransactionsView, setEntityRecommendationForLineIdsForCategorization, updateSelectedTransactionId, syncTransactionCategorizationFromDetailSave, backgroundRefetchReviewTab, updateTransactionCategorizationUploadReceiptState, uploadTransactionCategorizationReceiptSuccess, } = expenseAutomationTransactionsView.actions;
|
|
943
933
|
export default expenseAutomationTransactionsView.reducer;
|
|
@@ -4,33 +4,14 @@ import { toMonthYearPeriodId } from '../../../commonStateTypes/timePeriod';
|
|
|
4
4
|
import { getCurrentTenant, getIsAccountingClassesEnabled, getIsAccountingProjectsEnabled, } from '../../../entity/tenant/tenantSelector';
|
|
5
5
|
import { getTransactionWithCOT } from '../../../entity/transaction/transactionHelper';
|
|
6
6
|
import { getSupportedTransactionsByIds } from '../../../entity/transaction/transactionSelector';
|
|
7
|
-
import { applyTransactionFilters, } from '../transactionFilterHelpers';
|
|
8
7
|
import { getAccountList, getNestedAccountListHierarchy, getUncategorizedAccounts, } from '../../accountList/accountListSelector';
|
|
9
8
|
import { getClassList, getNestedClassListHierarchy, } from '../../classList/classListSelector';
|
|
10
9
|
import { getProjectList } from '../../projectList/projectListSelector';
|
|
11
10
|
import { getAllSteps } from '../selectorTypes/expenseAutomationViewSelectorTypes';
|
|
12
|
-
export const toTransactionView = (transaction, transactionLocalData) => {
|
|
13
|
-
return {
|
|
14
|
-
id: transaction.id,
|
|
15
|
-
date: transaction.date,
|
|
16
|
-
amount: transaction.amount,
|
|
17
|
-
vendorName: transaction.vendorName,
|
|
18
|
-
customerName: transaction.customerName,
|
|
19
|
-
vendorId: transaction.vendorId,
|
|
20
|
-
customerId: transaction.customerId,
|
|
21
|
-
description: transaction.description,
|
|
22
|
-
memo: transaction.memo,
|
|
23
|
-
type: transaction.type,
|
|
24
|
-
typeName: transaction.typeName,
|
|
25
|
-
createTime: transaction.createTime,
|
|
26
|
-
transaction: transaction,
|
|
27
|
-
transactionLocalData,
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
11
|
export function getExpenseAutomationTransactionView(state) {
|
|
31
12
|
const { accountState, classState, classListState, accountListState, expenseAutomationTransactionsViewState, expenseAutomationViewState, projectState, projectListState, transactionState, monthEndCloseChecksState, monthEndCloseChecksViewState, } = state;
|
|
32
13
|
const { selectedTransactionCategorizationCompletedSubTab, selectedTransactionCategorizationTab, } = expenseAutomationTransactionsViewState;
|
|
33
|
-
const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId,
|
|
14
|
+
const { uiState, refreshStatus, saveStatus, markAsNotMiscategorizedStatus, transactionIdsBySelectedPeriod, transactionReviewLocalDataById, selectedCheckBoxTransactionIds, transactionIdsWithUnsavedData, uploadReceiptStatusById, selectedTransactionId, selectedTransactionLineId, } = expenseAutomationTransactionsViewState.transactionCategorizationView[selectedTransactionCategorizationTab];
|
|
34
15
|
const uncategorizedIncomeExpense = getUncategorizedAccounts(accountState, accountListState, 'accountList');
|
|
35
16
|
const accountList = getAccountList(accountState, accountListState, 'accountList');
|
|
36
17
|
const classList = getClassList(classState, classListState);
|
|
@@ -49,58 +30,20 @@ export function getExpenseAutomationTransactionView(state) {
|
|
|
49
30
|
? transactionIdsBySelectedPeriod[monthYearPeriodId]
|
|
50
31
|
: null;
|
|
51
32
|
const transactionIds = transactionIdsForSelectedPeriod ?? [];
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const transactionLocalDataMap = new Map();
|
|
55
|
-
transactionIds.forEach((transactionId) => {
|
|
33
|
+
const transactionLocalData = transactionIds
|
|
34
|
+
.map((transactionId) => {
|
|
56
35
|
const transactionData = transactionReviewLocalDataById[transactionId];
|
|
57
36
|
if (transactionData != null) {
|
|
58
|
-
|
|
37
|
+
return {
|
|
59
38
|
transactionId,
|
|
60
39
|
transactionReviewLocalData: transactionData.transactionReviewLocalData,
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
// Step 2: Convert to TransactionView and apply advanced filters
|
|
65
|
-
const transactionViews = transactionsWithCOT.map((transaction) => {
|
|
66
|
-
const localData = transactionLocalDataMap.get(transaction.id);
|
|
67
|
-
return toTransactionView(transaction, localData);
|
|
68
|
-
});
|
|
69
|
-
// Apply TC-specific filters (lives under expenseAutomationView, independent
|
|
70
|
-
// of the Spend Management filter pipeline).
|
|
71
|
-
const filteredTransactionViews = applyTransactionFilters(transactionViews, filters);
|
|
72
|
-
// Convert back to TransactionWithCOT for return
|
|
73
|
-
const filteredTransactionsWithCOT = filteredTransactionViews.map((view) => view.transaction);
|
|
74
|
-
// Get transactionLocalData for filtered transactions
|
|
75
|
-
// Also include transactionLocalData for transactions that don't exist in transactionState
|
|
76
|
-
// but have local data (to match original behavior)
|
|
77
|
-
const filteredTransactionIds = new Set(filteredTransactionViews.map((view) => view.id));
|
|
78
|
-
// Pre-compute the membership set once. The previous implementation called
|
|
79
|
-
// `transactions.some(t => t.id === transactionId)` inside the per-id loop,
|
|
80
|
-
// turning the pipeline into O(n × m) — measurable on tenants with large
|
|
81
|
-
// transaction lists since this selector runs on every Redux dispatch.
|
|
82
|
-
const transactionExistsById = new Set(transactions.map((t) => t.id));
|
|
83
|
-
// `.flatMap` returns `X[]` directly when the callback returns `[]` for the
|
|
84
|
-
// skip case, so we don't need the trailing `.filter((d): d is X => …)` type
|
|
85
|
-
// predicate that the previous `map → filter` pipeline required.
|
|
86
|
-
const filteredTransactionLocalData = transactionIds.flatMap((transactionId) => {
|
|
87
|
-
const transactionData = transactionReviewLocalDataById[transactionId];
|
|
88
|
-
if (transactionData == null) {
|
|
89
|
-
return [];
|
|
40
|
+
};
|
|
90
41
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
transactionId,
|
|
98
|
-
transactionReviewLocalData: transactionData.transactionReviewLocalData,
|
|
99
|
-
},
|
|
100
|
-
];
|
|
101
|
-
}
|
|
102
|
-
return [];
|
|
103
|
-
});
|
|
42
|
+
return null;
|
|
43
|
+
})
|
|
44
|
+
.filter((transaction) => transaction != null);
|
|
45
|
+
const transactions = getSupportedTransactionsByIds(transactionState, transactionIds);
|
|
46
|
+
const transactionsWithCOT = transactions.map((transaction) => getTransactionWithCOT(transaction));
|
|
104
47
|
const monthEndFetchState = monthYearPeriodId != null
|
|
105
48
|
? (monthEndCloseChecksViewState.monthEndCloseChecksViewByTenantId[currentTenant.tenantId]?.[monthYearPeriodId] ?? { fetchState: 'Not-Started', error: undefined })
|
|
106
49
|
: { fetchState: 'Not-Started', error: undefined };
|
|
@@ -164,7 +107,7 @@ export function getExpenseAutomationTransactionView(state) {
|
|
|
164
107
|
version: 0,
|
|
165
108
|
fetchState: fetchStatus.fetchState,
|
|
166
109
|
error: fetchStatus.error,
|
|
167
|
-
transactions:
|
|
110
|
+
transactions: transactionsWithCOT,
|
|
168
111
|
selectedCheckBoxTransactionIds,
|
|
169
112
|
transactionIdsWithUnsavedData,
|
|
170
113
|
uncategorizedAccounts: uncategorizedIncomeExpense,
|
|
@@ -175,7 +118,7 @@ export function getExpenseAutomationTransactionView(state) {
|
|
|
175
118
|
classHierarchyList,
|
|
176
119
|
isAccountingProjectsEnabled,
|
|
177
120
|
projectList,
|
|
178
|
-
transactionLocalData
|
|
121
|
+
transactionLocalData,
|
|
179
122
|
uiState,
|
|
180
123
|
refreshStatus,
|
|
181
124
|
saveStatus,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { from } from 'rxjs';
|
|
2
2
|
import { filter, mergeMap } from 'rxjs/operators';
|
|
3
|
-
import { getApprovalRuleById } from '../../../../../entity/approvalRule/approvalRuleSelector';
|
|
3
|
+
import { getAmountCriteria, getApprovalRuleById, getDepartmentCriteria, getVendorCriteria, } from '../../../../../entity/approvalRule/approvalRuleSelector';
|
|
4
4
|
import { clearBillPaySetupApproverViewUpdateData, initializeBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdateData, } from '../billPaySetupApproverViewReducer';
|
|
5
5
|
export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state$) => actions$.pipe(filter(initializeBillPaySetupApproverViewUpdateData.match), mergeMap((action) => {
|
|
6
6
|
const { approvalRuleId } = action.payload;
|
|
@@ -8,16 +8,20 @@ export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state
|
|
|
8
8
|
if (approvalRuleId != null) {
|
|
9
9
|
const approvalRule = getApprovalRuleById(state$.value.approvalRuleState, approvalRuleId);
|
|
10
10
|
if (approvalRule != null) {
|
|
11
|
-
const criteria = approvalRule.criteria[0];
|
|
12
|
-
const range = criteria?.range;
|
|
13
11
|
const billPaySetupApproverViewUpdateData = {
|
|
14
12
|
approvalRuleId,
|
|
15
13
|
steps: approvalRule.steps,
|
|
16
14
|
criteria: {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
amount: getAmountCriteria(approvalRule.criteria),
|
|
16
|
+
vendor: getVendorCriteria(approvalRule.criteria),
|
|
17
|
+
department: getDepartmentCriteria(approvalRule.criteria),
|
|
20
18
|
},
|
|
19
|
+
// Approval Rules 3.0 — seed rule-level fields so the form can
|
|
20
|
+
// round-trip them on edit. Each may be undefined on legacy rules.
|
|
21
|
+
name: approvalRule.name,
|
|
22
|
+
description: approvalRule.description,
|
|
23
|
+
separationOfDuties: approvalRule.separationOfDuties,
|
|
24
|
+
isFallback: approvalRule.isFallback,
|
|
21
25
|
};
|
|
22
26
|
fetchActions.push(clearBillPaySetupApproverViewUpdateData(), saveBillPaySetupApproverViewUpdateData(billPaySetupApproverViewUpdateData));
|
|
23
27
|
}
|
|
@@ -25,7 +29,7 @@ export const initializeBillPaySetupApproverViewUpdateDataEpic = (actions$, state
|
|
|
25
29
|
else {
|
|
26
30
|
const billPaySetupApproverViewCreateData = {
|
|
27
31
|
steps: [],
|
|
28
|
-
criteria:
|
|
32
|
+
criteria: {},
|
|
29
33
|
};
|
|
30
34
|
fetchActions.push(clearBillPaySetupApproverViewUpdateData(), saveBillPaySetupApproverViewUpdateData(billPaySetupApproverViewCreateData));
|
|
31
35
|
}
|