@zeniai/client-epic-state 5.0.89 → 5.0.90-betaAR1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/lib/entity/approvalRule/approvalRuleConflict.d.ts +56 -0
  2. package/lib/entity/approvalRule/approvalRuleConflict.js +77 -0
  3. package/lib/entity/approvalRule/approvalRulePayload.d.ts +34 -5
  4. package/lib/entity/approvalRule/approvalRulePayload.js +145 -10
  5. package/lib/entity/approvalRule/approvalRuleSelector.d.ts +25 -1
  6. package/lib/entity/approvalRule/approvalRuleSelector.js +40 -0
  7. package/lib/entity/approvalRule/approvalRuleState.d.ts +59 -7
  8. package/lib/entity/snackbar/snackbarTypes.d.ts +1 -1
  9. package/lib/entity/snackbar/snackbarTypes.js +2 -0
  10. package/lib/epic.d.ts +3 -1
  11. package/lib/epic.js +3 -1
  12. package/lib/esm/entity/approvalRule/approvalRuleConflict.js +74 -0
  13. package/lib/esm/entity/approvalRule/approvalRulePayload.js +145 -10
  14. package/lib/esm/entity/approvalRule/approvalRuleSelector.js +35 -0
  15. package/lib/esm/entity/snackbar/snackbarTypes.js +2 -0
  16. package/lib/esm/epic.js +3 -1
  17. package/lib/esm/index.js +7 -5
  18. package/lib/esm/view/expenseAutomationView/transactionFilterHelpers.js +106 -18
  19. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +92 -12
  20. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +10 -2
  21. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +8 -4
  22. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +11 -7
  23. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.js +54 -0
  24. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +13 -4
  25. package/lib/esm/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +119 -16
  26. package/lib/esm/view/spendManagement/billPay/editBillView/editBillViewSelector.js +43 -4
  27. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +10 -2
  28. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +8 -2
  29. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +11 -7
  30. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.js +49 -0
  31. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +13 -4
  32. package/lib/esm/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +71 -11
  33. package/lib/index.d.ts +8 -6
  34. package/lib/index.js +27 -16
  35. package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +2 -2
  36. package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
  37. package/lib/view/expenseAutomationView/helpers/transactionCategorizationLocalDataHelper.d.ts +1 -1
  38. package/lib/view/expenseAutomationView/transactionFilterHelpers.js +106 -18
  39. package/lib/view/people/peopleTypes.d.ts +1 -1
  40. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.d.ts +14 -3
  41. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer.js +93 -13
  42. package/lib/view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewState.d.ts +16 -0
  43. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/deleteBillPayApprovalRuleEpic.js +10 -2
  44. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/fetchBillPaySetupApproverViewEpic.js +8 -4
  45. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/initializeBillPaySetupApproverViewUpdateDataEpic.js +10 -6
  46. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.d.ts +23 -0
  47. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/reorderBillPayApprovalRulesEpic.js +58 -0
  48. package/lib/view/spendManagement/billPay/billPaySetupApproverView/epic/saveBillPaySetupApproverViewUpdatesEpic.js +12 -3
  49. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.d.ts +56 -1
  50. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonPayload.js +121 -17
  51. package/lib/view/spendManagement/billPay/billPaySetupApproverView/types/commonState.d.ts +31 -5
  52. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.d.ts +1 -1
  53. package/lib/view/spendManagement/billPay/editBillView/editBillViewSelector.js +43 -4
  54. package/lib/view/spendManagement/chargeCards/chargeCardList/chargeCardList.d.ts +1 -1
  55. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/deleteRemiApprovalRuleEpic.js +10 -2
  56. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/fetchRemiSetupApproverViewEpic.js +8 -2
  57. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/initializeRemiSetupApproverViewUpdateDataEpic.js +10 -6
  58. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.d.ts +14 -0
  59. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/reorderRemiApprovalRulesEpic.js +53 -0
  60. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/epic/saveRemiSetupApproverViewUpdatesEpic.js +12 -3
  61. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.d.ts +14 -3
  62. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer.js +72 -12
  63. package/lib/view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewState.d.ts +12 -0
  64. package/lib/view/taskManager/taskListView/taskList.d.ts +3 -3
  65. package/lib/view/transactionDetail/journalEntryLinesViewModel.d.ts +1 -1
  66. package/package.json +1 -1
@@ -5,15 +5,24 @@ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
5
  import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { saveBillPaySetupApproverViewUpdates, saveBillPaySetupApproverViewUpdatesFailure, saveBillPaySetupApproverViewUpdatesSuccess, } from '../billPaySetupApproverViewReducer';
8
- import { toApprovalChangableInfoPayload } from '../types/commonPayload';
9
- export const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveBillPaySetupApproverViewUpdates.match), switchMap(() => {
8
+ import { toApprovalChangableInfoPayload, toApprovalChangableInfoPayloadV1, } from '../types/commonPayload';
9
+ export const saveBillPaySetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveBillPaySetupApproverViewUpdates.match), switchMap((action) => {
10
10
  const { billPaySetupApproverViewState } = state$.value;
11
11
  const billPaySetupApproverViewUpdateData = billPaySetupApproverViewState.billPaySetupApproverViewUpdateData;
12
12
  if (billPaySetupApproverViewUpdateData != null &&
13
13
  billPaySetupApproverViewUpdateData.data != null) {
14
- const payload = toApprovalChangableInfoPayload(billPaySetupApproverViewUpdateData.data);
14
+ // Approval Rules 3.0 — gate URL + write-side payload mapper on
15
+ // the `approval_rule_v3_config` dynamic config. `useV3` arrives
16
+ // on the action payload from the screen connector.
17
+ const { useV3 } = action.payload;
18
+ const payload = useV3
19
+ ? toApprovalChangableInfoPayload(billPaySetupApproverViewUpdateData.data)
20
+ : toApprovalChangableInfoPayloadV1(billPaySetupApproverViewUpdateData.data);
21
+ const endpoint = useV3
22
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules-v2`
23
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`;
15
24
  return zeniAPI
16
- .postAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/bill-pay/approval-rules`, payload)
25
+ .postAndGetJSON(endpoint, payload)
17
26
  .pipe(mergeMap((response) => {
18
27
  if (isSuccessResponse(response) && response.data != null) {
19
28
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -1,20 +1,48 @@
1
1
  export const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
2
- let criteriaPayload = [];
2
+ // Form-side criteria is a structured object with optional slots for
3
+ // amount / vendor / department; flatten it into the wire format's
4
+ // `conditions[]` array.
5
+ let criteriaPayload;
3
6
  if (approverViewUpdateData.criteria != null) {
4
- const criteria = approverViewUpdateData.criteria;
5
- const { rangeType, rangeEntity, range } = criteria;
6
- const { min, max } = range;
7
- const { currencyCode, currencySymbol } = min;
8
- criteriaPayload = [
9
- {
10
- type: rangeType,
11
- range_entity: rangeEntity,
12
- min: min.amount,
13
- max: max?.amount ?? null,
14
- currency_code: currencyCode,
15
- currency_symbol: currencySymbol,
16
- },
17
- ];
7
+ const { amount, vendor, department } = approverViewUpdateData.criteria;
8
+ const conditions = [];
9
+ if (amount?.min != null) {
10
+ conditions.push({
11
+ field: 'amount',
12
+ type: 'gte',
13
+ value: amount.min.amount,
14
+ });
15
+ }
16
+ if (amount?.max != null) {
17
+ conditions.push({
18
+ field: 'amount',
19
+ type: 'lte',
20
+ value: amount.max.amount,
21
+ });
22
+ }
23
+ if (vendor != null && vendor.vendorIds.length > 0) {
24
+ conditions.push({
25
+ field: 'vendor_id',
26
+ type: vendor.operator === 'is_not' ? 'not_in' : 'in',
27
+ value: vendor.vendorIds,
28
+ });
29
+ }
30
+ if (department != null && department.departmentIds.length > 0) {
31
+ conditions.push({
32
+ field: 'department_id',
33
+ type: department.operator === 'is_not' ? 'not_in' : 'in',
34
+ value: department.departmentIds,
35
+ });
36
+ }
37
+ if (conditions.length > 0) {
38
+ const currency = amount?.min ?? amount?.max ?? null;
39
+ criteriaPayload = {
40
+ conditions,
41
+ criteria_operator: 'and',
42
+ currency_code: currency?.currencyCode ?? 'USD',
43
+ currency_symbol: currency?.currencySymbol ?? '$',
44
+ };
45
+ }
18
46
  }
19
47
  const steps = approverViewUpdateData.steps.map((step) => {
20
48
  return {
@@ -35,10 +63,85 @@ export const toApprovalChangableInfoPayload = (approverViewUpdateData) => {
35
63
  });
36
64
  const isUpdate = approverViewUpdateData.approvalRuleId != null;
37
65
  const payload = {
38
- criteria: criteriaPayload,
39
66
  steps,
40
67
  is_applicable_on_pending_approval_entity: approverViewUpdateData.isApplicableOnPendingApprovalEntity ?? true,
41
68
  };
69
+ if (criteriaPayload != null) {
70
+ payload.criteria = criteriaPayload;
71
+ }
72
+ // Approval Rules 3.0 — surface rule-level fields when the form set them.
73
+ // Send only what the user actually entered: an undefined value means
74
+ // "no opinion" and stays off the wire.
75
+ if (approverViewUpdateData.name != null) {
76
+ payload.name = approverViewUpdateData.name;
77
+ }
78
+ if (approverViewUpdateData.description != null) {
79
+ payload.description = approverViewUpdateData.description;
80
+ }
81
+ if (approverViewUpdateData.separationOfDuties != null) {
82
+ payload.is_separation_of_duty_enabled =
83
+ approverViewUpdateData.separationOfDuties;
84
+ }
85
+ if (approverViewUpdateData.isFallback != null) {
86
+ payload.is_fallback = approverViewUpdateData.isFallback;
87
+ }
88
+ if (isUpdate) {
89
+ payload.approval_rule_id = approverViewUpdateData.approvalRuleId;
90
+ }
91
+ return payload;
92
+ };
93
+ /**
94
+ * V1 wire mapper — used when 'approval_rule_v3_config' resolves to OFF
95
+ * for the current tenant. Emits the legacy snake_case array shape that
96
+ * '/approval-rules' historically consumed:
97
+ * criteria: [{type: 'range', range_entity: 'currency', min, max,
98
+ * currency_code, currency_symbol}]
99
+ *
100
+ * Open-ended semantics are preserved on the wire: an absent 'min' or
101
+ * 'max' is sent as 'null' rather than synthesised to '0' or
102
+ * 'MAX_SAFE_INTEGER', so a 'greater_than' / 'less_than' rule stays
103
+ * one-sided after rollback rather than collapsing into a closed range.
104
+ *
105
+ * The V1 backend does not understand vendor / department criteria or
106
+ * the rule-level 3.0 fields, so those are dropped on the wire.
107
+ */
108
+ export const toApprovalChangableInfoPayloadV1 = (approverViewUpdateData) => {
109
+ const amount = approverViewUpdateData.criteria?.amount;
110
+ const minAmount = amount?.min;
111
+ const maxAmount = amount?.max;
112
+ const currencyCode = minAmount?.currencyCode ?? maxAmount?.currencyCode ?? 'USD';
113
+ const currencySymbol = minAmount?.currencySymbol ?? maxAmount?.currencySymbol ?? '$';
114
+ const steps = approverViewUpdateData.steps.map((step) => {
115
+ return {
116
+ action: step.action,
117
+ operator: step.operator,
118
+ actors: step.actors
119
+ .filter((actor) => actor.subType !== 'admin')
120
+ .map((actor) => {
121
+ return {
122
+ type: actor.type,
123
+ id: actor.userId ?? null,
124
+ sub_type: actor.subType ?? null,
125
+ id_type: actor.idType ?? null,
126
+ is_implicit_actor: actor.isImplicitActor ?? false,
127
+ };
128
+ }),
129
+ };
130
+ });
131
+ const isUpdate = approverViewUpdateData.approvalRuleId != null;
132
+ const criteriaEntry = {
133
+ type: 'range',
134
+ range_entity: 'currency',
135
+ min: minAmount?.amount ?? null,
136
+ max: maxAmount?.amount ?? null,
137
+ currency_code: currencyCode,
138
+ currency_symbol: currencySymbol,
139
+ };
140
+ const payload = {
141
+ steps,
142
+ is_applicable_on_pending_approval_entity: approverViewUpdateData.isApplicableOnPendingApprovalEntity ?? true,
143
+ criteria: [criteriaEntry],
144
+ };
42
145
  if (isUpdate) {
43
146
  payload.approval_rule_id = approverViewUpdateData.approvalRuleId;
44
147
  }
@@ -1,5 +1,6 @@
1
1
  import recordGet from 'lodash/get';
2
2
  import has from 'lodash/has';
3
+ import { getAmountCriteria, getDepartmentCriteria, getVendorCriteria, } from '../../../../entity/approvalRule/approvalRuleSelector';
3
4
  import { reduceFetchState } from '../../../../commonStateTypes/reduceFetchState';
4
5
  import { getBankAccountByBankAccountId, getBankAccountsByBankAccountIds, } from '../../../../entity/bankAccount/bankAccountSelector';
5
6
  import { getContactById, getContactsByIds, } from '../../../../entity/billPay/contact/contactSelector';
@@ -678,12 +679,50 @@ export const getDefaultWithdrawFromAccount = (state, depositAccounts, companyId,
678
679
  }
679
680
  return undefined;
680
681
  };
681
- export const checkIfCreatorIsApprover = (billAmount, approvalRules, signedInUser) => {
682
+ export const checkIfCreatorIsApprover = (billAmount, approvalRules, signedInUser, billVendorId, billDepartmentId) => {
682
683
  let isCreatorAlsoApprover = false;
684
+ // Approval Rules 3.0 — a rule is applicable when every criterion it
685
+ // carries matches the bill. Amount uses inclusive bounds ('gte'/'lte'
686
+ // on the wire), and either bound may be absent for a one-sided
687
+ // 'greater_than' or 'less_than' rule. Vendor / department criteria
688
+ // narrow the rule by entity; an absent criterion means 'no narrowing
689
+ // on this axis'. Rules without an amount criterion at all are not
690
+ // considered here, preserving the pre-3.0 behaviour where this
691
+ // selector only ever matched amount-bearing rules.
683
692
  const approvalRule = approvalRules.find((rule) => {
684
- const { max, min } = rule.criteria[0].range;
685
- return (billAmount > min.amount &&
686
- (max?.amount != null ? billAmount <= max?.amount : true));
693
+ const amountCriteria = getAmountCriteria(rule.criteria);
694
+ if (amountCriteria == null) {
695
+ return false;
696
+ }
697
+ const { min, max } = amountCriteria;
698
+ const matchesMin = min == null || billAmount >= min.amount;
699
+ const matchesMax = max == null || billAmount <= max.amount;
700
+ if (!matchesMin || !matchesMax) {
701
+ return false;
702
+ }
703
+ const vendorCriteria = getVendorCriteria(rule.criteria);
704
+ if (vendorCriteria != null) {
705
+ const includesVendor = billVendorId != null &&
706
+ vendorCriteria.vendorIds.includes(billVendorId);
707
+ if (vendorCriteria.operator === 'is' && !includesVendor) {
708
+ return false;
709
+ }
710
+ if (vendorCriteria.operator === 'is_not' && includesVendor) {
711
+ return false;
712
+ }
713
+ }
714
+ const departmentCriteria = getDepartmentCriteria(rule.criteria);
715
+ if (departmentCriteria != null) {
716
+ const includesDepartment = billDepartmentId != null &&
717
+ departmentCriteria.departmentIds.includes(billDepartmentId);
718
+ if (departmentCriteria.operator === 'is' && !includesDepartment) {
719
+ return false;
720
+ }
721
+ if (departmentCriteria.operator === 'is_not' && includesDepartment) {
722
+ return false;
723
+ }
724
+ }
725
+ return true;
687
726
  });
688
727
  if (approvalRule != null) {
689
728
  const requireApprovalSteps = approvalRule.steps.filter((step) => step.action === 'require_approval');
@@ -6,9 +6,17 @@ import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { deleteRemiApprovalRule, deleteRemiApprovalRuleFailure, deleteRemiApprovalRuleSuccess, } from '../remiSetupApproverViewReducer';
8
8
  export const deleteRemiApprovalRuleEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(deleteRemiApprovalRule.match), switchMap((action) => {
9
- const { approvalRuleId } = action.payload;
9
+ const { approvalRuleId, useV3 } = action.payload;
10
+ // Approval Rules 3.0 — flag-gated endpoint selection.
11
+ // Explicit `=== true` keeps `strict-boolean-expressions` happy
12
+ // when RTK's payload type widens to `any` in some configs.
13
+ const endpoint = useV3 === true
14
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
15
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
10
16
  return zeniAPI
11
- .deleteAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`, { approval_rule_id: approvalRuleId })
17
+ .deleteAndGetJSON(endpoint, {
18
+ approval_rule_id: approvalRuleId,
19
+ })
12
20
  .pipe(mergeMap((response) => {
13
21
  if (isSuccessResponse(response) && response.data != null) {
14
22
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -6,7 +6,7 @@ import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
7
  import { fetchRemiSetupApproverView, fetchRemiSetupApproverViewFailure, fetchRemiSetupApproverViewSuccess, } from '../remiSetupApproverViewReducer';
8
8
  export const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchRemiSetupApproverView.match), switchMap((action) => {
9
- const { cacheOverride, resolveAttributeToUser, includeImplicitActors } = action.payload;
9
+ const { cacheOverride, resolveAttributeToUser, includeImplicitActors, useV3, } = action.payload;
10
10
  const { remiSetupApproverViewState, approvalRuleState } = state$.value;
11
11
  const approvalRules = getApprovalRulesByIds(approvalRuleState, remiSetupApproverViewState.approvalRuleIds);
12
12
  if (cacheOverride === true ||
@@ -14,8 +14,14 @@ export const fetchRemiSetupApproverViewEpic = (actions$, state$, zeniAPI) => act
14
14
  remiSetupApproverViewState.approvalRuleIds.length ||
15
15
  (remiSetupApproverViewState.hasValidState() === false &&
16
16
  remiSetupApproverViewState.fetchState !== 'In-Progress')) {
17
+ // Approval Rules 3.0 — flag-gated endpoint selection.
18
+ // Explicit `=== true` keeps `strict-boolean-expressions` happy
19
+ // when RTK's payload type widens to `any` in some configs.
20
+ const basePath = useV3 === true
21
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
22
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
17
23
  return zeniAPI
18
- .getJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
24
+ .getJSON(`${basePath}?query={"is_include_implicit_actors": ${includeImplicitActors}, "is_resolve_attribute_to_user":${resolveAttributeToUser}}`)
19
25
  .pipe(mergeMap((response) => {
20
26
  if (isSuccessResponse(response) && response.data != null) {
21
27
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -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 { clearRemiSetupApproverViewUpdateData, initializeRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdateData, } from '../remiSetupApproverViewReducer';
5
5
  export const initializeRemiSetupApproverViewUpdateDataEpic = (actions$, state$) => actions$.pipe(filter(initializeRemiSetupApproverViewUpdateData.match), mergeMap((action) => {
6
6
  const { approvalRuleId } = action.payload;
@@ -8,16 +8,20 @@ export const initializeRemiSetupApproverViewUpdateDataEpic = (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 remiSetupApproverViewUpdateData = {
14
12
  approvalRuleId,
15
13
  steps: approvalRule.steps,
16
14
  criteria: {
17
- rangeType: criteria?.rangeType,
18
- rangeEntity: criteria?.rangeEntity,
19
- range,
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(clearRemiSetupApproverViewUpdateData(), saveRemiSetupApproverViewUpdateData(remiSetupApproverViewUpdateData));
23
27
  }
@@ -25,7 +29,7 @@ export const initializeRemiSetupApproverViewUpdateDataEpic = (actions$, state$)
25
29
  else {
26
30
  const remiSetupApproverViewCreateData = {
27
31
  steps: [],
28
- criteria: undefined,
32
+ criteria: {},
29
33
  };
30
34
  fetchActions.push(clearRemiSetupApproverViewUpdateData(), saveRemiSetupApproverViewUpdateData(remiSetupApproverViewCreateData));
31
35
  }
@@ -0,0 +1,49 @@
1
+ import { from } from 'rxjs';
2
+ import { catchError, filter, mergeMap, switchMap } from 'rxjs/operators';
3
+ import { updateApprovalRules } from '../../../../../entity/approvalRule/approvalRuleReducer';
4
+ import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
+ import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
6
+ import { fetchRemiSetupApproverView, reorderRemiApprovalRules, reorderRemiApprovalRulesFailure, reorderRemiApprovalRulesSuccess, } from '../remiSetupApproverViewReducer';
7
+ export const reorderRemiApprovalRulesEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(reorderRemiApprovalRules.match), switchMap((action) => {
8
+ const { approvalRuleIds, useV3 } = action.payload;
9
+ const endpoint = `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2/reorder`;
10
+ return zeniAPI
11
+ .putAndGetJSON(endpoint, {
12
+ rule_ids: approvalRuleIds,
13
+ })
14
+ .pipe(mergeMap((response) => {
15
+ if (isSuccessResponse(response) && response.data != null) {
16
+ const serverOrderedIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
17
+ const actions = [
18
+ updateApprovalRules(response.data.approval_rules),
19
+ reorderRemiApprovalRulesSuccess(serverOrderedIds),
20
+ openSnackbar({
21
+ messageSection: `reimbursement_approval_reorder`,
22
+ messageText: 'success',
23
+ type: 'success',
24
+ }),
25
+ ];
26
+ return from(actions);
27
+ }
28
+ else {
29
+ return from([
30
+ reorderRemiApprovalRulesFailure(response.status),
31
+ openSnackbar({
32
+ messageSection: `reimbursement_approval_reorder`,
33
+ messageText: 'failed',
34
+ type: 'error',
35
+ }),
36
+ fetchRemiSetupApproverView(true, true, useV3),
37
+ ]);
38
+ }
39
+ }), catchError((error) => from([
40
+ reorderRemiApprovalRulesFailure(createZeniAPIStatus('Unexpected Error', 'Reorder Reimbursement Approval Rules errored out' +
41
+ JSON.stringify(error))),
42
+ openSnackbar({
43
+ messageSection: `reimbursement_approval_reorder`,
44
+ messageText: 'failed',
45
+ type: 'error',
46
+ }),
47
+ fetchRemiSetupApproverView(true, true, useV3),
48
+ ])));
49
+ }));
@@ -4,16 +4,25 @@ import { updateApprovalRules } from '../../../../../entity/approvalRule/approval
4
4
  import { openSnackbar } from '../../../../../entity/snackbar/snackbarReducer';
5
5
  import { updateAllUsers } from '../../../../../entity/user/userReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse, } from '../../../../../responsePayload';
7
- import { toApprovalChangableInfoPayload } from '../../../billPay/billPaySetupApproverView/types/commonPayload';
7
+ import { toApprovalChangableInfoPayload, toApprovalChangableInfoPayloadV1, } from '../../../billPay/billPaySetupApproverView/types/commonPayload';
8
8
  import { saveRemiSetupApproverViewUpdates, saveRemiSetupApproverViewUpdatesFailure, saveRemiSetupApproverViewUpdatesSuccess, } from '../remiSetupApproverViewReducer';
9
- export const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveRemiSetupApproverViewUpdates.match), switchMap(() => {
9
+ export const saveRemiSetupApproverViewUpdatesEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(saveRemiSetupApproverViewUpdates.match), switchMap((action) => {
10
10
  const { remiSetupApproverViewState } = state$.value;
11
11
  const remiSetupApproverViewUpdateData = remiSetupApproverViewState.remiSetupApproverViewUpdateData;
12
12
  if (remiSetupApproverViewUpdateData != null &&
13
13
  remiSetupApproverViewUpdateData.data != null) {
14
- const payload = toApprovalChangableInfoPayload(remiSetupApproverViewUpdateData.data);
14
+ // Approval Rules 3.0 — gate URL + write-side payload mapper on
15
+ // the `approval_rule_v3_config` dynamic config. `useV3` arrives
16
+ // on the action payload from the screen connector.
17
+ const { useV3 } = action.payload;
18
+ const payload = useV3
19
+ ? toApprovalChangableInfoPayload(remiSetupApproverViewUpdateData.data)
20
+ : toApprovalChangableInfoPayloadV1(remiSetupApproverViewUpdateData.data);
21
+ const endpoint = useV3
22
+ ? `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules-v2`
23
+ : `${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`;
15
24
  return zeniAPI
16
- .postAndGetJSON(`${zeniAPI.apiEndPoints.approvalMicroServiceBaseUrl}/1.0/reimbursements/approval-rules`, payload)
25
+ .postAndGetJSON(endpoint, payload)
17
26
  .pipe(mergeMap((response) => {
18
27
  if (isSuccessResponse(response) && response.data != null) {
19
28
  const approvalRuleIds = response.data.approval_rules.map((approvalRule) => approvalRule.approval_rule_id);
@@ -13,6 +13,7 @@ export const initialState = {
13
13
  newApprovalRuleId: undefined,
14
14
  approvalRulesDeleteStatusById: {},
15
15
  remiSetupApproverViewUpdateData: undefined,
16
+ reorderStatus: { fetchState: 'Not-Started', error: undefined },
16
17
  hasValidState() {
17
18
  return this.fetchState === 'Completed';
18
19
  },
@@ -26,12 +27,16 @@ const remiSetupApproverView = createSlice({
26
27
  draft.fetchState = 'In-Progress';
27
28
  draft.error = undefined;
28
29
  },
29
- prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false) {
30
+ // Approval Rules 3.0 `useV3` arrives from the screen connector
31
+ // (`approval_rule_v3_config` dynamic config) and picks v1 vs v2
32
+ // endpoint in the fetch epic.
33
+ prepare(cacheOverride = false, resolveAttributeToUser = false, includeImplicitActors = false, useV3 = false) {
30
34
  return {
31
35
  payload: {
32
36
  cacheOverride,
33
37
  resolveAttributeToUser,
34
38
  includeImplicitActors,
39
+ useV3,
35
40
  },
36
41
  };
37
42
  },
@@ -134,8 +139,11 @@ const remiSetupApproverView = createSlice({
134
139
  error: undefined,
135
140
  };
136
141
  },
137
- prepare(approvalRuleId) {
138
- return { payload: { approvalRuleId } };
142
+ // Approval Rules 3.0 — `useV3` flows from the screen connector
143
+ // (`approval_rule_v3_config` dynamic config) so the delete epic
144
+ // can pick the v1 vs v2 endpoint.
145
+ prepare(approvalRuleId, useV3 = false) {
146
+ return { payload: { approvalRuleId, useV3 } };
139
147
  },
140
148
  },
141
149
  deleteRemiApprovalRuleSuccess: {
@@ -167,13 +175,65 @@ const remiSetupApproverView = createSlice({
167
175
  };
168
176
  },
169
177
  },
170
- saveRemiSetupApproverViewUpdates(draft) {
171
- if (draft.remiSetupApproverViewUpdateData != null) {
172
- draft.remiSetupApproverViewUpdateData.updateStatus = {
173
- fetchState: 'In-Progress',
174
- error: undefined,
175
- };
176
- }
178
+ /**
179
+ * Approval Rules 3.0 list-page drag-and-drop reorder.
180
+ * See BillPay equivalent for the longer rationale.
181
+ */
182
+ reorderRemiApprovalRules: {
183
+ reducer(draft, action) {
184
+ const { approvalRuleIds } = action.payload;
185
+ draft.reorderStatus = { fetchState: 'In-Progress', error: undefined };
186
+ // Stash the pre-reorder order for synchronous rollback on
187
+ // 'Failure'. See the BillPay reducer for the rationale.
188
+ draft.reorderRollbackIds = draft.approvalRuleIds;
189
+ draft.approvalRuleIds = approvalRuleIds;
190
+ },
191
+ prepare(approvalRuleIds, useV3 = false) {
192
+ return { payload: { approvalRuleIds, useV3 } };
193
+ },
194
+ },
195
+ reorderRemiApprovalRulesSuccess: {
196
+ reducer(draft, action) {
197
+ const { approvalRuleIds } = action.payload;
198
+ draft.reorderStatus = { fetchState: 'Completed', error: undefined };
199
+ draft.approvalRuleIds = approvalRuleIds;
200
+ draft.reorderRollbackIds = undefined;
201
+ },
202
+ prepare(approvalRuleIds) {
203
+ return { payload: { approvalRuleIds } };
204
+ },
205
+ },
206
+ reorderRemiApprovalRulesFailure: {
207
+ reducer(draft, action) {
208
+ const { status } = action.payload;
209
+ draft.reorderStatus = { fetchState: 'Error', error: status };
210
+ if (draft.reorderRollbackIds != null) {
211
+ draft.approvalRuleIds = draft.reorderRollbackIds;
212
+ draft.reorderRollbackIds = undefined;
213
+ }
214
+ },
215
+ prepare(status) {
216
+ return { payload: { status } };
217
+ },
218
+ },
219
+ saveRemiSetupApproverViewUpdates: {
220
+ // Approval Rules 3.0 — `useV3` sourced from
221
+ // `approval_rule_v3_config` dynamic config in the screen
222
+ // connector; epic uses it to pick v1 vs v2 URL + mapper. The
223
+ // reducer doesn't read the action but the parameter must be
224
+ // declared so the action payload type carries downstream.
225
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
226
+ reducer(draft, _action) {
227
+ if (draft.remiSetupApproverViewUpdateData != null) {
228
+ draft.remiSetupApproverViewUpdateData.updateStatus = {
229
+ fetchState: 'In-Progress',
230
+ error: undefined,
231
+ };
232
+ }
233
+ },
234
+ prepare(useV3) {
235
+ return { payload: { useV3 } };
236
+ },
177
237
  },
178
238
  saveRemiSetupApproverViewUpdatesSuccess: {
179
239
  reducer(draft, action) {
@@ -262,5 +322,5 @@ const remiSetupApproverView = createSlice({
262
322
  },
263
323
  },
264
324
  });
265
- export const { fetchRemiSetupApproverView, fetchRemiSetupApproverViewSuccess, fetchRemiSetupApproverViewFailure, fetchRemiApproversDetails, fetchRemiApproversList, fetchRemiApproversListSuccess, fetchRemiApproversListFailure, deleteRemiApprovalRule, deleteRemiApprovalRuleSuccess, deleteRemiApprovalRuleFailure, saveRemiSetupApproverViewUpdates, saveRemiSetupApproverViewUpdatesSuccess, saveRemiSetupApproverViewUpdatesFailure, initializeRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdateData, setListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, } = remiSetupApproverView.actions;
325
+ export const { fetchRemiSetupApproverView, fetchRemiSetupApproverViewSuccess, fetchRemiSetupApproverViewFailure, fetchRemiApproversDetails, fetchRemiApproversList, fetchRemiApproversListSuccess, fetchRemiApproversListFailure, deleteRemiApprovalRule, deleteRemiApprovalRuleSuccess, deleteRemiApprovalRuleFailure, reorderRemiApprovalRules, reorderRemiApprovalRulesSuccess, reorderRemiApprovalRulesFailure, saveRemiSetupApproverViewUpdates, saveRemiSetupApproverViewUpdatesSuccess, saveRemiSetupApproverViewUpdatesFailure, initializeRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdateData, setListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, } = remiSetupApproverView.actions;
266
326
  export default remiSetupApproverView.reducer;
package/lib/index.d.ts CHANGED
@@ -52,7 +52,9 @@ import { AccountReconciliationEntity, getAccountReconByAccountIdAndSelectedPerio
52
52
  import { BalanceDataStatusCodeType, BankStatusCodeType, RecommendedActionCodeType, ReconciliationStatusCodeType, StatementDataStatusCodeType, StatementStatusCodeType, TransactionsToReview } from './entity/accountRecon/accountReconState';
53
53
  import { getAddressByAddressId } from './entity/address/addressSelector';
54
54
  import { Address } from './entity/address/addressState';
55
- import { Actor, ActorType, ApprovalActionType, ApprovalRule, ApprovalRuleState, Approvers, AttributeType, RoleType, Step, StepOperatorType, toAttributeOrRoleTypeStrict, toAttributeTypeStrict, toRoleTypeStrict } from './entity/approvalRule/approvalRuleState';
55
+ import { Actor, ActorType, AmountComparator, AmountCriteria, ApprovalActionType, ApprovalRule, ApprovalRuleState, Approvers, AttributeType, ConditionType, Criteria, DepartmentCriteria, RoleType, Step, StepOperatorType, VendorCriteria, toAttributeOrRoleTypeStrict, toAttributeTypeStrict, toRoleTypeStrict } from './entity/approvalRule/approvalRuleState';
56
+ import { getAmountCriteria, getApprovalRulesByEntityType, getDepartmentCriteria, getFallbackApprovalRule, getVendorCriteria } from './entity/approvalRule/approvalRuleSelector';
57
+ import { DetectRuleOverlapInput, RuleForOverlapCheck, RuleOverlap, detectRuleOverlap } from './entity/approvalRule/approvalRuleConflict';
56
58
  import { BankAccount } from './entity/bankAccount/bankAccount';
57
59
  import { BillPayInfo, BillPaymentRefundStatus, BillPaymentRefundStatusCodeType, BillPaymentStatus, BillPaymentStatusCodeType, BillStage, BillStageCodeType, BillStatus, BillStatusCodeType, BillTransaction, DeletionSourceType, InternationalTransferFeeBearerPaymentMethod, toOutsideZeniPaymentModeType } from './entity/billPay/billTransaction/billTransactionState';
58
60
  import { Contact } from './entity/billPay/contact/contact';
@@ -420,7 +422,7 @@ import { getInternationalSubConfigCodeKey } from './view/spendManagement/billPay
420
422
  import { AccountTypeSubConfigCodeKeyType, BILL_NEW_PAYMENT_METHODS, BillPayConfig, BillPaymentConfigCodeType, BillPaymentSubConfigCodeType, InternationalSubConfigCodeType, LOCAL_CURRENCY_INTERNATIONAL_METHOD_SUBTEXT, NEW_INTERNATIONAL_METHOD_SUBTEXT, SWIFT_OUR_INTERNATIONAL_METHOD_SUBTEXT, VendorCurrency } from './view/spendManagement/billPay/billPayConfig/billPayConfigState';
421
423
  import { clearBillPayReview, fetchDuplicateBill } from './view/spendManagement/billPay/billPayReview/billPayReviewReducer';
422
424
  import { BillPayReviewSelectorView, DuplicateBillsSelectorView, getReviewPageBillDetail } from './view/spendManagement/billPay/billPayReview/billPayReviewSelector';
423
- import { clearBillPaySetupApproverView, clearBillPaySetupApproverViewUpdateData, deleteBillPayApprovalRule, fetchBillPayApproversDetails, fetchBillPayApproversList, fetchBillPaySetupApproverView, initializeBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setListeningToPusherEvent as setBillsSetupApproverViewListeningToPusherEvent } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer';
425
+ import { clearBillPaySetupApproverView, clearBillPaySetupApproverViewUpdateData, deleteBillPayApprovalRule, fetchBillPayApproversDetails, fetchBillPayApproversList, fetchBillPaySetupApproverView, initializeBillPaySetupApproverViewUpdateData, reorderBillPayApprovalRules, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setListeningToPusherEvent as setBillsSetupApproverViewListeningToPusherEvent } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewReducer';
424
426
  import { getBillPaySetupApproverUpdateDataView, getBillPaySetupApproverView } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelector';
425
427
  import { ApprovalRuleWithUser as BillPayApprovalRuleWithUser, BillPaySetupApproverUpdateDataView, BillPaySetupApproverView } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewSelectorTypes';
426
428
  import { BillPaySetupApproverViewState } from './view/spendManagement/billPay/billPaySetupApproverView/billPaySetupApproverViewState';
@@ -500,7 +502,7 @@ import { RemiListDownloadReport, getRemiDownloadList } from './view/spendManagem
500
502
  import { fetchRemiList, fetchRemiListPerTab, updateRemiDetailSaveRemiCode, updateRemiListDownloadUIState, updateFilterResult as updateRemiListFilterResult, updateSearchResult as updateRemiListSearchResult, updateSubTab as updateRemiListSubTab, updateTab as updateRemiListTab, updateRemiListUIState } from './view/spendManagement/reimbursement/remiListView/remiListReducer';
501
503
  import { ReimbursementView, RemiListReport, getRemiList } from './view/spendManagement/reimbursement/remiListView/remiListSelector';
502
504
  import { REIMBURSEMENT_FILTER_CATEGORIES, REIMBURSEMENT_FILTER_CATEGORIES_RESTRICTED, ReimbursementFilterCategory, ReimbursementFilters, ReimbursementViewSortKey, RemiBulkSelectExceptionInfoType, RemiListUIState, RemiListViewFilterCategoryField, RemiSubTabType, RemiTabType, toRemiSubTabType, toRemiSubTabTypeStrict, toRemiTabType, toRemiTabTypeStrict } from './view/spendManagement/reimbursement/remiListView/remiListState';
503
- import { clearRemiSetupApproverView, clearRemiSetupApproverViewUpdateData, deleteRemiApprovalRule, fetchRemiApproversDetails, fetchRemiApproversList, fetchRemiSetupApproverView, initializeRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, setListeningToPusherEvent as setRemiSetupApproverViewListeningToPusherEvent } from './view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer';
505
+ import { clearRemiSetupApproverView, clearRemiSetupApproverViewUpdateData, deleteRemiApprovalRule, fetchRemiApproversDetails, fetchRemiApproversList, fetchRemiSetupApproverView, initializeRemiSetupApproverViewUpdateData, reorderRemiApprovalRules, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, setListeningToPusherEvent as setRemiSetupApproverViewListeningToPusherEvent } from './view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewReducer';
504
506
  import { getRemiSetupApproverUpdateDataView, getRemiSetupApproverView } from './view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewSelector';
505
507
  import { ApprovalRuleWithUser as RemiApprovalRuleWithUser, RemiSetupApproverUpdateDataView, RemiSetupApproverView } from './view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewSelectorTypes';
506
508
  import { RemiSetupApproverViewState } from './view/spendManagement/reimbursement/remiSetupApproverView/remiSetupApproverViewState';
@@ -810,9 +812,9 @@ export { RemiSetupViewState, RemiSetupViewLocalData, MileageDetailsLocalData, Mi
810
812
  export { PaymentAccount, Logo, VERIFIED_PAYMENT_ACCOUNT_PROVIDER_VERIFICATION_STATUS, };
811
813
  export { SubscriptionPaymentAccount };
812
814
  export { PreviousBillsSelectorView, InvoiceProcessingPayload, InvoiceProcessingResponse, isSuccessResponse, isInvalidSessionError, isAccessDeniedError, };
813
- export { Step, Actor as ApprovalRuleActor, ActorType, ApprovalActionType, StepOperatorType, ApprovalRuleState, ApprovalRule, AttributeType, Approvers, RoleType, EntityApprovalStatusState, EntityApprovalStatus, SpendManagementEntityType, SpendManagementEntityTypeWithOtherConnection, toAttributeTypeStrict, toAttributeOrRoleTypeStrict, toRoleTypeStrict, };
814
- export { ApprovalRuleUpdateData, ApprovalRuleCreateData, BillPayApprovalRuleWithUser, ApprovalUpdateActionType, ApproverViewUpdateData, BillPaySetupApproverViewState, BillPaySetupApproverView, BillPaySetupApproverUpdateDataView, getBillPaySetupApproverView, getBillPaySetupApproverUpdateDataView, fetchBillPaySetupApproverView, fetchBillPayApproversDetails, fetchBillPayApproversList, deleteBillPayApprovalRule, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setBillsSetupApproverViewListeningToPusherEvent, initializeBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverView, };
815
- export { RemiApprovalRuleWithUser, RemiSetupApproverViewState, RemiSetupApproverView, RemiSetupApproverUpdateDataView, getRemiSetupApproverView, getRemiSetupApproverUpdateDataView, fetchRemiSetupApproverView, fetchRemiApproversList, fetchRemiApproversDetails, deleteRemiApprovalRule, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, initializeRemiSetupApproverViewUpdateData, setRemiSetupApproverViewListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, };
815
+ export { Step, Actor as ApprovalRuleActor, ActorType, ApprovalActionType, StepOperatorType, ApprovalRuleState, ApprovalRule, AmountComparator, AmountCriteria, ConditionType, Criteria, DepartmentCriteria, VendorCriteria, AttributeType, Approvers, RoleType, EntityApprovalStatusState, EntityApprovalStatus, SpendManagementEntityType, SpendManagementEntityTypeWithOtherConnection, getAmountCriteria, getApprovalRulesByEntityType, getDepartmentCriteria, getFallbackApprovalRule, getVendorCriteria, toAttributeTypeStrict, toAttributeOrRoleTypeStrict, toRoleTypeStrict, DetectRuleOverlapInput, RuleForOverlapCheck, RuleOverlap, detectRuleOverlap, };
816
+ export { ApprovalRuleUpdateData, ApprovalRuleCreateData, BillPayApprovalRuleWithUser, ApprovalUpdateActionType, ApproverViewUpdateData, BillPaySetupApproverViewState, BillPaySetupApproverView, BillPaySetupApproverUpdateDataView, getBillPaySetupApproverView, getBillPaySetupApproverUpdateDataView, fetchBillPaySetupApproverView, fetchBillPayApproversDetails, fetchBillPayApproversList, deleteBillPayApprovalRule, reorderBillPayApprovalRules, saveBillPaySetupApproverViewUpdateData, saveBillPaySetupApproverViewUpdates, setBillsSetupApproverViewListeningToPusherEvent, initializeBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverViewUpdateData, clearBillPaySetupApproverView, };
817
+ export { RemiApprovalRuleWithUser, RemiSetupApproverViewState, RemiSetupApproverView, RemiSetupApproverUpdateDataView, getRemiSetupApproverView, getRemiSetupApproverUpdateDataView, fetchRemiSetupApproverView, fetchRemiApproversList, fetchRemiApproversDetails, deleteRemiApprovalRule, reorderRemiApprovalRules, saveRemiSetupApproverViewUpdateData, saveRemiSetupApproverViewUpdates, initializeRemiSetupApproverViewUpdateData, setRemiSetupApproverViewListeningToPusherEvent, clearRemiSetupApproverViewUpdateData, clearRemiSetupApproverView, };
816
818
  export { RemiDetailViewSelector, getRemiDetailView, RemiActivity, RemiDetails, checkApproveRejectBtnShowForRemi, };
817
819
  export { RemiApprovalType, RemiDetailView, DuplicateLine };
818
820
  export { saveRealTimeApproval, updateIsEditModeRealTimeApprovals, RealTimeApprovalDetailLocalData, RealTimeStepsData, };