@veloceapps/sdk 11.0.0-2 → 11.0.0-21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. package/cms/cms.actions.d.ts +92 -29
  2. package/cms/components/element-renderer/element-renderer.component.d.ts +3 -10
  3. package/cms/services/element-context.service.d.ts +0 -1
  4. package/cms/types/common.types.d.ts +2 -0
  5. package/cms/types/index.d.ts +0 -1
  6. package/cms/utils/path.utils.d.ts +1 -2
  7. package/cms/vendor-map.d.ts +19 -40
  8. package/core/index.d.ts +0 -1
  9. package/core/modules/configuration/index.d.ts +1 -4
  10. package/core/modules/configuration/services/configuration-runtime.service.d.ts +3 -22
  11. package/core/modules/configuration/services/configuration-state.service.d.ts +8 -8
  12. package/core/modules/configuration/services/configuration.service.d.ts +23 -47
  13. package/core/modules/flow-configuration/index.d.ts +0 -3
  14. package/core/modules/flow-configuration/services/flow-configuration.service.d.ts +10 -39
  15. package/core/services/catalog-products.service.d.ts +11 -0
  16. package/core/services/flow-info.service.d.ts +25 -11
  17. package/core/services/flow-state-configuration.service.d.ts +2 -8
  18. package/core/services/flow-state.service.d.ts +13 -22
  19. package/core/services/index.d.ts +2 -3
  20. package/core/services/integration.state.d.ts +1 -1
  21. package/core/services/sales-transaction.service.d.ts +30 -0
  22. package/core/types/flow-state.types.d.ts +2 -2
  23. package/core/types/index.d.ts +0 -1
  24. package/core/utils/index.d.ts +2 -2
  25. package/core/utils/transaction-item.utils.d.ts +7 -0
  26. package/core/utils/transaction-item.worker.d.ts +8 -0
  27. package/esm2020/cms/cms.actions.mjs +93 -71
  28. package/esm2020/cms/cms.default.mjs +2 -3
  29. package/esm2020/cms/components/element-renderer/element-renderer.component.mjs +7 -64
  30. package/esm2020/cms/components/preview/preview.component.mjs +3 -3
  31. package/esm2020/cms/services/element-context.service.mjs +1 -1
  32. package/esm2020/cms/types/common.types.mjs +1 -1
  33. package/esm2020/cms/types/index.mjs +1 -2
  34. package/esm2020/cms/utils/element.utils.mjs +3 -3
  35. package/esm2020/cms/utils/path.utils.mjs +1 -10
  36. package/esm2020/cms/vendor-map.mjs +12 -17
  37. package/esm2020/core/core.module.mjs +9 -7
  38. package/esm2020/core/index.mjs +1 -2
  39. package/esm2020/core/modules/configuration/configuration.module.mjs +3 -4
  40. package/esm2020/core/modules/configuration/index.mjs +2 -5
  41. package/esm2020/core/modules/configuration/services/configuration-runtime.service.mjs +9 -102
  42. package/esm2020/core/modules/configuration/services/configuration-state.service.mjs +60 -76
  43. package/esm2020/core/modules/configuration/services/configuration.service.mjs +96 -225
  44. package/esm2020/core/modules/flow-configuration/flow-configuration.module.mjs +3 -4
  45. package/esm2020/core/modules/flow-configuration/index.mjs +1 -4
  46. package/esm2020/core/modules/flow-configuration/services/flow-configuration.service.mjs +33 -126
  47. package/esm2020/core/services/catalog-products.service.mjs +25 -0
  48. package/esm2020/core/services/flow-info.service.mjs +77 -29
  49. package/esm2020/core/services/flow-state-configuration.service.mjs +10 -25
  50. package/esm2020/core/services/flow-state.service.mjs +62 -169
  51. package/esm2020/core/services/index.mjs +3 -4
  52. package/esm2020/core/services/integration.state.mjs +2 -2
  53. package/esm2020/core/services/sales-transaction.service.mjs +68 -0
  54. package/esm2020/core/types/flow-state.types.mjs +1 -1
  55. package/esm2020/core/types/index.mjs +1 -2
  56. package/esm2020/core/utils/index.mjs +3 -3
  57. package/esm2020/core/utils/transaction-item.utils.mjs +60 -0
  58. package/esm2020/core/utils/transaction-item.worker.mjs +16 -0
  59. package/esm2020/src/components/flow-header/flow-header.component.mjs +3 -7
  60. package/esm2020/src/components/guided-selling/guided-selling.component.mjs +3 -7
  61. package/esm2020/src/flow-routing.module.mjs +11 -41
  62. package/esm2020/src/flow.component.mjs +5 -5
  63. package/esm2020/src/guards/flow.guard.mjs +13 -14
  64. package/esm2020/src/guards/product-unload.guard.mjs +7 -9
  65. package/esm2020/src/index.mjs +1 -3
  66. package/esm2020/src/pages/assets/assets.component.mjs +3 -4
  67. package/esm2020/src/pages/catalog/catalog.component.mjs +3 -4
  68. package/esm2020/src/pages/debug/debug.component.mjs +12 -21
  69. package/esm2020/src/pages/product/product.component.mjs +12 -82
  70. package/esm2020/src/pages/product/product.module.mjs +5 -5
  71. package/esm2020/src/pages/record-not-found/record-not-found.component.mjs +5 -6
  72. package/esm2020/src/pages/shopping-cart/shopping-cart.component.mjs +3 -4
  73. package/esm2020/src/resolvers/flow.resolver.mjs +10 -18
  74. package/esm2020/src/resolvers/sales-transaction.resolver.mjs +83 -0
  75. package/esm2020/src/resolvers/ui-definition.resolver.mjs +42 -0
  76. package/esm2020/src/services/flow-dialog.service.mjs +8 -8
  77. package/esm2020/src/services/flow-router.service.mjs +16 -33
  78. package/esm2020/src/services/flow.service.mjs +13 -54
  79. package/esm2020/src/types/index.mjs +2 -3
  80. package/esm2020/src/types/route.types.mjs +1 -1
  81. package/fesm2015/veloceapps-sdk-cms.mjs +126 -268
  82. package/fesm2015/veloceapps-sdk-cms.mjs.map +1 -1
  83. package/fesm2015/veloceapps-sdk-core.mjs +712 -1644
  84. package/fesm2015/veloceapps-sdk-core.mjs.map +1 -1
  85. package/fesm2015/veloceapps-sdk.mjs +167 -763
  86. package/fesm2015/veloceapps-sdk.mjs.map +1 -1
  87. package/fesm2020/veloceapps-sdk-cms.mjs +114 -262
  88. package/fesm2020/veloceapps-sdk-cms.mjs.map +1 -1
  89. package/fesm2020/veloceapps-sdk-core.mjs +758 -1725
  90. package/fesm2020/veloceapps-sdk-core.mjs.map +1 -1
  91. package/fesm2020/veloceapps-sdk.mjs +167 -757
  92. package/fesm2020/veloceapps-sdk.mjs.map +1 -1
  93. package/package.json +1 -1
  94. package/src/components/flow-header/flow-header.component.d.ts +1 -1
  95. package/src/components/guided-selling/guided-selling.component.d.ts +1 -1
  96. package/src/flow-routing.module.d.ts +1 -2
  97. package/src/flow.component.d.ts +2 -2
  98. package/src/guards/product-unload.guard.d.ts +5 -6
  99. package/src/index.d.ts +0 -2
  100. package/src/pages/assets/assets.component.d.ts +1 -1
  101. package/src/pages/catalog/catalog.component.d.ts +1 -1
  102. package/src/pages/debug/debug.component.d.ts +1 -4
  103. package/src/pages/product/product.component.d.ts +5 -14
  104. package/src/pages/product/product.module.d.ts +1 -1
  105. package/src/pages/record-not-found/record-not-found.component.d.ts +2 -3
  106. package/src/pages/shopping-cart/shopping-cart.component.d.ts +1 -1
  107. package/src/resolvers/flow.resolver.d.ts +5 -6
  108. package/src/resolvers/sales-transaction.resolver.d.ts +18 -0
  109. package/src/resolvers/ui-definition.resolver.d.ts +3 -0
  110. package/src/services/flow-dialog.service.d.ts +5 -4
  111. package/src/services/flow-router.service.d.ts +4 -6
  112. package/src/services/flow.service.d.ts +2 -7
  113. package/src/types/index.d.ts +1 -2
  114. package/src/types/route.types.d.ts +0 -5
  115. package/cms/plugins/configuration.plugin.d.ts +0 -23
  116. package/cms/types/configuration.types.d.ts +0 -21
  117. package/core/modules/configuration/helpers.d.ts +0 -6
  118. package/core/modules/configuration/services/runtime-context.service.d.ts +0 -12
  119. package/core/modules/configuration/types/configuration-runtime.types.d.ts +0 -6
  120. package/core/modules/flow-configuration/services/flow-update.service.d.ts +0 -13
  121. package/core/modules/flow-configuration/types/update.types.d.ts +0 -12
  122. package/core/services/context.service.d.ts +0 -23
  123. package/core/services/quote-draft.service.d.ts +0 -50
  124. package/core/types/runtime.types.d.ts +0 -30
  125. package/core/utils/line-item.utils.d.ts +0 -25
  126. package/core/utils/line-item.worker.d.ts +0 -9
  127. package/esm2020/cms/plugins/configuration.plugin.mjs +0 -109
  128. package/esm2020/cms/types/configuration.types.mjs +0 -2
  129. package/esm2020/core/modules/configuration/helpers.mjs +0 -73
  130. package/esm2020/core/modules/configuration/services/runtime-context.service.mjs +0 -43
  131. package/esm2020/core/modules/configuration/types/configuration-runtime.types.mjs +0 -2
  132. package/esm2020/core/modules/flow-configuration/services/flow-update.service.mjs +0 -138
  133. package/esm2020/core/modules/flow-configuration/types/update.types.mjs +0 -2
  134. package/esm2020/core/services/context.service.mjs +0 -91
  135. package/esm2020/core/services/quote-draft.service.mjs +0 -192
  136. package/esm2020/core/types/runtime.types.mjs +0 -16
  137. package/esm2020/core/utils/line-item.utils.mjs +0 -187
  138. package/esm2020/core/utils/line-item.worker.mjs +0 -19
  139. package/esm2020/src/guards/context.guard.mjs +0 -91
  140. package/esm2020/src/guards/index.mjs +0 -2
  141. package/esm2020/src/pages/remote/remote.component.mjs +0 -342
  142. package/esm2020/src/pages/remote/remote.module.mjs +0 -20
  143. package/esm2020/src/pages/remote/remote.types.mjs +0 -2
  144. package/esm2020/src/resolvers/quote.resolver.mjs +0 -82
  145. package/esm2020/src/types/context-route.types.mjs +0 -2
  146. package/esm2020/src/types/metrics.types.mjs +0 -2
  147. package/esm2020/src/utils/flow.utils.mjs +0 -25
  148. package/esm2020/src/utils/index.mjs +0 -2
  149. package/src/guards/context.guard.d.ts +0 -19
  150. package/src/guards/index.d.ts +0 -1
  151. package/src/pages/remote/remote.component.d.ts +0 -46
  152. package/src/pages/remote/remote.module.d.ts +0 -10
  153. package/src/pages/remote/remote.types.d.ts +0 -4
  154. package/src/resolvers/quote.resolver.d.ts +0 -19
  155. package/src/types/context-route.types.d.ts +0 -5
  156. package/src/types/metrics.types.d.ts +0 -5
  157. package/src/utils/flow.utils.d.ts +0 -8
  158. package/src/utils/index.d.ts +0 -1
@@ -1,249 +1,233 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, InjectionToken, Optional, Inject, NgModule, inject, Directive, Input, LOCALE_ID, Pipe } from '@angular/core';
3
- import { UUID, ConfigurationContextMode, ConfigurationContext, UITemplateType, QuoteDraft, isDefined, ConfigurationProcessorTypes, EntityUtil, DEFAULT_CURRENCY_ISO_CODE, DEFAULT_CURRENCY_SYMBOL, validateDateFormat, DEFAULT_DATE_FORMAT, DEFAULT_DECIMALS_COUNT, getSupportedDateFormats, DEFAULT_DECIMAL_SEPARATOR, DEFAULT_THOUSANDS_SEPARATOR, DEFAULT_ACTION_CODE_LABELS, parseJsonSafely, ConfigurationMode, extractErrorDetails, ConfigurationTranslatorUtils, ChargeGroupUtils, RuntimeModel, isNotLegacyUIDefinition, SalesforceIdUtils, DEFAULT_TIME_FORMAT, formatNumber } from '@veloceapps/core';
3
+ import { DEFAULT_CURRENCY_ISO_CODE, DEFAULT_CURRENCY_SYMBOL, validateDateFormat, DEFAULT_DATE_FORMAT, DEFAULT_DECIMALS_COUNT, getSupportedDateFormats, DEFAULT_DECIMAL_SEPARATOR, DEFAULT_THOUSANDS_SEPARATOR, DEFAULT_ACTION_CODE_LABELS, parseJsonSafely, UITemplateType, SalesforceIdUtils, isDefined, UUID, extractErrorDetails, ConfigurationProcessorTypes, EntityUtil, DEFAULT_TIME_FORMAT, formatNumber } from '@veloceapps/core';
4
4
  import * as i1 from '@veloceapps/api';
5
5
  import { ApiModule } from '@veloceapps/api';
6
- import { BehaviorSubject, switchMap, map as map$1, tap as tap$1, noop, catchError, throwError, forkJoin, of, zip, combineLatest, Subject, filter as filter$1, shareReplay as shareReplay$1, finalize, takeUntil, buffer, debounceTime, share, take as take$1, distinctUntilChanged } from 'rxjs';
7
- import { map, filter, tap, switchMap as switchMap$1, skip, take, shareReplay, catchError as catchError$1, finalize as finalize$1, first } from 'rxjs/operators';
8
- import { merge, isEqual, cloneDeep, assign, flatten, entries, sortBy, map as map$2, uniqBy, omit, transform } from 'lodash';
9
6
  import * as i6 from '@veloceapps/components';
10
- import { ToastType, ConfirmationComponent, ConfirmationDialogModule } from '@veloceapps/components';
11
- import { HttpErrorResponse } from '@angular/common/http';
12
- import * as i5 from 'primeng/api';
13
- import * as i6$1 from 'primeng/dynamicdialog';
14
- import moment from 'moment';
7
+ import { ToastType, ConfirmationDialogModule } from '@veloceapps/components';
8
+ import * as i4 from '@veloceapps/api/v2';
9
+ import { uniqBy, flatten, omit, cloneDeep, assign, isEqual } from 'lodash';
10
+ import { BehaviorSubject, map, tap, switchMap, of, forkJoin, throwError, noop, filter as filter$1, Subject, catchError as catchError$1, combineLatest, finalize as finalize$1, buffer, debounceTime, share, take, distinctUntilChanged, shareReplay, takeUntil } from 'rxjs';
11
+ import * as i2 from 'primeng/api';
12
+ import { filter, map as map$1, catchError, tap as tap$1, finalize } from 'rxjs/operators';
15
13
  import { NgControl } from '@angular/forms';
16
14
  import 'primeng/calendar';
17
15
  import { DATE_PIPE_DEFAULT_OPTIONS, formatDate } from '@angular/common';
18
16
 
19
- const getDefaultLineItem = (context, uiDefinitionProperties, qty = 1) => {
20
- const id = UUID.UUID();
21
- const attributes = [];
22
- const lineItems = [];
23
- return {
24
- id,
25
- type: uiDefinitionProperties.rootType ?? '',
26
- cfgStatus: 'Default',
27
- actionCode: 'ADD',
28
- qty,
29
- attributes,
30
- lineItems,
31
- productName: context.properties?.['displayName'] || context.productName,
32
- productId: context.productId ?? '',
33
- ...(uiDefinitionProperties.offeringId ? { offeringId: uiDefinitionProperties.offeringId } : {}),
34
- };
35
- };
36
- const getGuidedSellingConfigurationRequest = (data, context) => {
37
- const _context = { ...context };
38
- delete _context.configurationToken;
39
- const properties = { ...context.properties };
40
- delete properties['ConfigurationToken'];
41
- return {
42
- mode: 'SEARCH',
43
- step: 'START',
44
- attributeDomainMode: 'ALL',
45
- context: {
46
- ..._context,
47
- mode: ConfigurationContextMode.TEST,
48
- properties: {
49
- ...properties,
50
- ModelId: data.modelId,
51
- Name: 'Veloce Guided Selling',
52
- PricingEnabled: 'false',
53
- RuntimeMode: 'TEST',
54
- },
55
- },
56
- lineItem: {
57
- actionCode: 'ADD',
58
- cfgStatus: 'Default',
59
- id: UUID.UUID(),
60
- qty: 1,
61
- type: data.modelType,
62
- attributes: Object.entries(data.attributesMap).map(([name, value]) => ({
63
- name,
64
- value,
65
- cfgStatus: 'User',
66
- })),
67
- },
68
- };
69
- };
70
- const generateConfigurationLineItem = (props, qty = 1) => {
71
- const id = UUID.UUID();
72
- const attributes = Object.entries(props.attributesMap ?? {}).map(([name, value]) => ({
73
- name,
74
- value,
75
- cfgStatus: 'User',
76
- }));
77
- const lineItems = [];
78
- return {
79
- id,
80
- type: props.product.typeName ?? '',
81
- cfgStatus: 'Default',
82
- actionCode: 'ADD',
83
- qty,
84
- attributes,
85
- lineItems,
86
- productName: props.product.name,
87
- productId: props.product.id ?? '',
88
- };
89
- };
90
-
91
- class ContextService {
92
- constructor(contextApiService) {
93
- this.contextApiService = contextApiService;
94
- this.context = new BehaviorSubject(null);
17
+ class ConfigurationRuntimeService {
18
+ constructor() {
19
+ this.uiDefinitionContainer = null;
95
20
  }
96
- get isInitialized() {
97
- return Boolean(this.context.value);
21
+ get uiDefinitionProps() {
22
+ return this.uiDefinitionContainer?.source.properties ?? {};
98
23
  }
99
- get isInitialized$() {
100
- return this.context.pipe(map(Boolean));
24
+ reset() {
25
+ this.uiDefinitionContainer = null;
101
26
  }
102
- get mode() {
103
- return this.resolve().properties['#mode'];
27
+ }
28
+ ConfigurationRuntimeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
29
+ ConfigurationRuntimeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService });
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, decorators: [{
31
+ type: Injectable
32
+ }] });
33
+
34
+ const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
35
+
36
+ class RuntimeSettingsService {
37
+ constructor(configurationSettingsApiService) {
38
+ this.configurationSettingsApiService = configurationSettingsApiService;
39
+ this.configurationSettings$ = new BehaviorSubject({});
40
+ this.currencySettings$ = new BehaviorSubject({
41
+ iso: DEFAULT_CURRENCY_ISO_CODE,
42
+ symbol: DEFAULT_CURRENCY_SYMBOL,
43
+ });
44
+ this.shoppingCartSettings$ = new BehaviorSubject([]);
45
+ this.getCurrencySymbol = (locale, currency) => {
46
+ return (0)
47
+ .toLocaleString(locale, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 0 })
48
+ .replace(/\d/g, '')
49
+ .trim();
50
+ };
104
51
  }
105
- get isEditMode$() {
106
- return this.resolve$().pipe(map(() => this.isEditMode));
52
+ create() {
53
+ return this.configurationSettingsApiService.fetchSettings().pipe(map(settings => this.parseConfigurationSettings(settings)), tap(configurationSettings => {
54
+ this.configurationSettings$.next(configurationSettings);
55
+ this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
56
+ this.formattingSettings = this.getFormattingSettings();
57
+ }), map(() => undefined));
107
58
  }
108
- get isEditMode() {
109
- const context = this.resolve();
110
- if (context.properties['#mode'] === ConfigurationContextMode.ACCOUNT) {
111
- return true;
112
- }
113
- if (context.properties['#mode'] === ConfigurationContextMode.QUOTE) {
114
- return context.properties.Status === 'Draft';
59
+ initCurrency(iso) {
60
+ if (iso) {
61
+ const symbol = this.getCurrencySymbol('en-US', iso);
62
+ this.currencySettings$.next({ iso, symbol });
63
+ if (this.formattingSettings) {
64
+ this.formattingSettings.currencySymbol = symbol;
65
+ }
115
66
  }
116
- return false;
117
67
  }
118
- resolve() {
119
- if (!this.context.value) {
120
- throw new Error('Context is not initialized yet!');
68
+ getFormattingSettings() {
69
+ if (this.formattingSettings) {
70
+ return this.formattingSettings;
121
71
  }
122
- return { ...this.context.value };
72
+ const shoppingCartSettings = this.getConfigurationSettings()['shopping-cart']?.reduce((acc, setting) => {
73
+ return { ...acc, [setting.id]: setting.properties };
74
+ }, {});
75
+ const currencySettings = this.getCurrencySettings();
76
+ const dateFormat = (validateDateFormat(shoppingCartSettings?.DATE_FORMAT ?? '') && shoppingCartSettings?.DATE_FORMAT) ||
77
+ DEFAULT_DATE_FORMAT;
78
+ const decimalSeparator = shoppingCartSettings?.DECIMAL_SEPARATOR;
79
+ const thousandsSeparator = shoppingCartSettings?.THOUSANDS_SEPARATOR;
80
+ // the number of decimal places can be 0
81
+ const priceScale = shoppingCartSettings?.PRICE_SCALE;
82
+ const decimalsCount = priceScale !== null && priceScale !== '' && !isNaN(Number(priceScale)) && Number(priceScale) >= 0
83
+ ? Number(priceScale)
84
+ : DEFAULT_DECIMALS_COUNT;
85
+ const actionCodeSettings = shoppingCartSettings?.STATUS_LABEL;
86
+ return {
87
+ currencySymbol: currencySettings.symbol,
88
+ dateFormats: getSupportedDateFormats(dateFormat),
89
+ decimalsCount,
90
+ decimalSeparator: decimalSeparator !== undefined && ['.', ','].includes(decimalSeparator)
91
+ ? decimalSeparator
92
+ : DEFAULT_DECIMAL_SEPARATOR,
93
+ // thousands separator can be a blank value, so it can also be null
94
+ thousandsSeparator: thousandsSeparator !== undefined && ['.', ',', '', null].includes(thousandsSeparator)
95
+ ? thousandsSeparator || ''
96
+ : DEFAULT_THOUSANDS_SEPARATOR,
97
+ actionCodeLabels: actionCodeSettings?.length
98
+ ? actionCodeSettings.reduce((result, setting) => ({ ...result, [setting.status_label]: setting.custom_label }), {})
99
+ : DEFAULT_ACTION_CODE_LABELS,
100
+ };
123
101
  }
124
- resolve$() {
125
- return this.context.pipe(filter((ctx) => Boolean(ctx)));
102
+ getConfigurationSettings() {
103
+ return this.configurationSettings$.value;
126
104
  }
127
- create(headerId, mode) {
128
- return this.contextApiService.getContext(headerId, mode).pipe(tap(context => this.context.next(merge(new ConfigurationContext(headerId, mode), context))), map(() => this.resolve()));
105
+ getShoppingCartSettings() {
106
+ return this.shoppingCartSettings$.value;
129
107
  }
130
- initTestMode() {
131
- return this.create('TestId', ConfigurationContextMode.TEST).pipe(map(context => {
132
- return this.update({
133
- properties: {
134
- ...context.properties,
135
- RuntimeMode: ConfigurationContextMode.TEST,
136
- StartDate: new Date().toISOString().substring(0, 10),
137
- standalone: 'true',
138
- },
139
- });
140
- }));
108
+ getCurrencySettings() {
109
+ return this.currencySettings$.value;
141
110
  }
142
- update(partialContext) {
143
- const originalContext = this.resolve();
144
- const updatedContext = {
145
- ...originalContext,
146
- ...partialContext,
147
- properties: {
148
- ...originalContext.properties,
149
- ...partialContext.properties,
150
- },
151
- };
152
- this.context.next(updatedContext);
153
- return updatedContext;
154
- }
155
- set(context) {
156
- const originalContext = this.resolve();
157
- const updatedContext = {
158
- ...originalContext,
159
- ...context,
160
- };
161
- this.context.next(updatedContext);
162
- return updatedContext;
111
+ parseConfigurationSettings(settings) {
112
+ return settings.reduce((acc, setting) => {
113
+ switch (setting.key) {
114
+ case 'shopping-cart':
115
+ acc['shopping-cart'] = parseJsonSafely(setting.value, []);
116
+ break;
117
+ case 'navigation':
118
+ acc.navigation = parseJsonSafely(setting.value, {});
119
+ break;
120
+ case 'flows':
121
+ acc.flows = parseJsonSafely(setting.value, []);
122
+ break;
123
+ default:
124
+ acc[setting.key] = setting.value;
125
+ }
126
+ return acc;
127
+ }, {});
163
128
  }
164
- delete() {
165
- this.context.next(null);
129
+ addShoppingCartSettings(settings) {
130
+ // uniqBy removes items with the biggest index
131
+ const newSettings = uniqBy([...settings, ...this.shoppingCartSettings$.value], 'id');
132
+ this.shoppingCartSettings$.next(newSettings);
166
133
  }
167
134
  }
168
- ContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ContextService, deps: [{ token: i1.ContextApiService }], target: i0.ɵɵFactoryTarget.Injectable });
169
- ContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ContextService });
170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ContextService, decorators: [{
135
+ RuntimeSettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, deps: [{ token: i1.ConfigurationSettingsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
136
+ RuntimeSettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService });
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, decorators: [{
171
138
  type: Injectable
172
- }], ctorParameters: function () { return [{ type: i1.ContextApiService }]; } });
173
-
174
- const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
175
-
176
- const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
177
-
178
- var RuntimeMode;
179
- (function (RuntimeMode) {
180
- RuntimeMode[RuntimeMode["TEST"] = 0] = "TEST";
181
- RuntimeMode[RuntimeMode["PROD"] = 1] = "PROD";
182
- })(RuntimeMode || (RuntimeMode = {}));
183
- var RuntimeOperation;
184
- (function (RuntimeOperation) {
185
- RuntimeOperation["INIT"] = "INIT";
186
- RuntimeOperation["UPDATE"] = "UPDATE";
187
- })(RuntimeOperation || (RuntimeOperation = {}));
188
- var RuntimeStep;
189
- (function (RuntimeStep) {
190
- RuntimeStep["START"] = "START";
191
- RuntimeStep["UPDATE"] = "UPDATE";
192
- })(RuntimeStep || (RuntimeStep = {}));
193
-
194
- const UI_DEFINITION_VERSION = 3;
139
+ }], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
195
140
 
196
141
  class FlowInfoService {
197
142
  get flow() {
143
+ if (!this.flowSubj$.value) {
144
+ throw new Error(`Flow not initialized yet`);
145
+ }
198
146
  return this.flowSubj$.value;
199
147
  }
200
- set flow(value) {
201
- this.flowSubj$.next(value);
148
+ get isFlowInitialized() {
149
+ return Boolean(this.flowSubj$.value);
150
+ }
151
+ get context() {
152
+ if (!this.contextSubj$.value) {
153
+ throw new Error('Context is not initialized yet!');
154
+ }
155
+ return { ...this.contextSubj$.value };
156
+ }
157
+ get templates() {
158
+ return this.templatesSubj$.value;
202
159
  }
203
- get isLegacy() {
204
- return !!this.flow && this.flow?.properties.stateful == null;
160
+ get isFlowEngineInitialized$() {
161
+ return this.templates$.pipe(map(v => Boolean(v.FLOW_ENGINE)));
205
162
  }
206
163
  get isStateful() {
207
164
  return !!this.flow?.properties.stateful;
208
165
  }
209
- constructor(flowsApiService, templatesApiService, customizationService) {
210
- this.flowsApiService = flowsApiService;
166
+ constructor(runtimeSettingsService, templatesApiService, customizationService) {
167
+ this.runtimeSettingsService = runtimeSettingsService;
211
168
  this.templatesApiService = templatesApiService;
212
169
  this.customizationService = customizationService;
213
- this.templates = {};
214
170
  this.defaultTemplates = {
215
171
  flowEngine: 'Flow Engine',
216
172
  };
217
173
  this.flowSubj$ = new BehaviorSubject(null);
174
+ this.templatesSubj$ = new BehaviorSubject({});
175
+ this.contextSubj$ = new BehaviorSubject(null);
218
176
  this.flow$ = this.flowSubj$.asObservable();
177
+ this.templates$ = this.templatesSubj$.asObservable();
178
+ }
179
+ reset() {
180
+ this.flowSubj$.next(null);
181
+ this.templatesSubj$.next({});
182
+ this.contextSubj$.next(null);
219
183
  }
220
184
  init$(flowId, routeQueryParams) {
221
- return this.flowsApiService.getFlow(flowId).pipe(switchMap(flow => this.initFlowTemplates$(flow).pipe(map$1(() => flow))), tap$1(flow => {
222
- this.params = { ...routeQueryParams, ...flow.properties.queryParams };
223
- this.flowSubj$.next(flow);
224
- }), map$1(noop), catchError(e => {
225
- this.flowSubj$.next(null);
226
- return throwError(() => e);
227
- }));
185
+ return this.initFlow$(flowId, routeQueryParams).pipe(switchMap(() => this.initFlowTemplates$()));
228
186
  }
229
- cleanup() {
230
- this.flowSubj$.next(null);
231
- this.params = undefined;
232
- this.templates = {};
187
+ updateContext(update) {
188
+ this.contextSubj$.next({
189
+ ...this.context,
190
+ ...update,
191
+ });
192
+ }
193
+ initFlow$(flowId, routeQueryParams) {
194
+ const flow = this.runtimeSettingsService.getConfigurationSettings()['flows']?.find(({ id }) => flowId === id);
195
+ if (!flow) {
196
+ this.flowSubj$.next(null);
197
+ throw new Error(`Flow with flowId=${flowId} is not defined`);
198
+ }
199
+ const headerId = routeQueryParams['headerId'];
200
+ if (typeof headerId !== 'string') {
201
+ throw new Error(`Please provide 'headerId'`);
202
+ }
203
+ const mode = this.getFlowContextMode(headerId);
204
+ // Restrict if mode is not defined
205
+ if (mode == null) {
206
+ throw new Error('Mode is undefined');
207
+ }
208
+ this.contextSubj$.next({
209
+ ...flow.properties.queryParams,
210
+ ...routeQueryParams,
211
+ mode,
212
+ });
213
+ this.flowSubj$.next(flow);
214
+ return of(undefined);
233
215
  }
234
- initFlowTemplates$(flow) {
216
+ initFlowTemplates$() {
235
217
  return forkJoin([
236
218
  this.templatesApiService.fetchTemplates$(),
237
219
  this.customizationService?.getTemplates?.() ?? of([]),
238
- ]).pipe(map$1(([templates, localTemplates]) => {
239
- Object.entries({ ...this.defaultTemplates, ...flow.properties.templates }).forEach(([key, name]) => {
220
+ ]).pipe(map(([templates, localTemplates]) => {
221
+ const newValue = {};
222
+ Object.entries({ ...this.defaultTemplates, ...(this.flow?.properties.templates ?? {}) }).forEach(([key, name]) => {
240
223
  const type = this.remapTemplateName(key);
241
224
  if (type) {
242
- this.templates[type] =
225
+ newValue[type] =
243
226
  localTemplates.find(template => template.name === name && template.type === type) ??
244
227
  templates.find(template => template.name === name && template.type === type);
245
228
  }
246
229
  });
230
+ this.templatesSubj$.next(newValue);
247
231
  }));
248
232
  }
249
233
  remapTemplateName(templateType) {
@@ -269,207 +253,357 @@ class FlowInfoService {
269
253
  }
270
254
  return undefined;
271
255
  }
256
+ getFlowContextMode(headerId) {
257
+ const objectName = SalesforceIdUtils.getSfObjectNameById(headerId);
258
+ if (!objectName) {
259
+ return;
260
+ }
261
+ return objectName.toUpperCase();
262
+ }
272
263
  }
273
- FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token: i1.FlowsApiService }, { token: i1.UITemplatesApiService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
264
+ FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token: RuntimeSettingsService }, { token: i4.UITemplatesApiService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
274
265
  FlowInfoService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService });
275
266
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, decorators: [{
276
267
  type: Injectable
277
- }], ctorParameters: function () { return [{ type: i1.FlowsApiService }, { type: i1.UITemplatesApiService }, { type: undefined, decorators: [{
268
+ }], ctorParameters: function () { return [{ type: RuntimeSettingsService }, { type: i4.UITemplatesApiService }, { type: undefined, decorators: [{
278
269
  type: Optional
279
270
  }, {
280
271
  type: Inject,
281
272
  args: [FLOW_CUSTOMIZATION]
282
273
  }] }]; } });
283
274
 
284
- class QuoteDraftService {
285
- get isInitialized$() {
286
- return this.isInitializedSubj$.asObservable();
275
+ const findTransactionItem = (id, items) => {
276
+ return findTransactionItemWithComparator(items, (ti) => ti.id === id);
277
+ };
278
+ const findTransactionItemWithComparator = (items, comparator) => {
279
+ let currentLevel = items;
280
+ while (currentLevel.length) {
281
+ const found = currentLevel.find(comparator);
282
+ if (found) {
283
+ return found;
284
+ }
285
+ currentLevel = flatten(currentLevel.map(parent => parent.children));
287
286
  }
288
- get isInitialized() {
289
- return this.isInitializedSubj$.getValue();
287
+ return;
288
+ };
289
+ const insertTransactionItem = (item, parentId, toInsert) => {
290
+ const insertData = item.id === parentId ? [toInsert] : [];
291
+ return {
292
+ ...item,
293
+ children: [
294
+ ...insertData,
295
+ ...item.children.map(ti => {
296
+ return insertTransactionItem(ti, parentId, toInsert);
297
+ }),
298
+ ],
299
+ };
300
+ };
301
+ const removeTransactionItem = (item, idToRemove) => {
302
+ return {
303
+ ...item,
304
+ children: item.children
305
+ .map(ti => {
306
+ if (ti.id === idToRemove) {
307
+ return;
308
+ }
309
+ else if (ti.children.length) {
310
+ return removeTransactionItem(ti, idToRemove);
311
+ }
312
+ return ti;
313
+ })
314
+ .filter(isDefined),
315
+ };
316
+ };
317
+ const replaceTransactionItem = (item, replaceTo) => {
318
+ if (item.id === replaceTo.id) {
319
+ return { ...replaceTo };
290
320
  }
291
- set isInitialized(value) {
292
- if (this.isInitialized !== value) {
293
- this.isInitializedSubj$.next(value);
294
- }
321
+ return {
322
+ ...item,
323
+ children: item.children.map(ti => replaceTransactionItem(ti, replaceTo)),
324
+ };
325
+ };
326
+ const generateTransactionItem = (productId) => {
327
+ return {
328
+ id: UUID.UUID(),
329
+ productId,
330
+ };
331
+ };
332
+
333
+ class TransactionItemWorker {
334
+ constructor(src) {
335
+ this.ti = { ...src };
295
336
  }
296
- get hasUnsavedChanges() {
297
- return this._hasUnsavedChanges;
337
+ insert(parentId, toInsert) {
338
+ return new TransactionItemWorker(insertTransactionItem(this.ti, parentId, toInsert));
298
339
  }
299
- set hasUnsavedChanges(value) {
300
- this._hasUnsavedChanges = value;
301
- if (!this._hasUnsavedChanges) {
302
- this.initialCurrentState = this.quoteDraft?.currentState ?? [];
303
- }
340
+ remove(id) {
341
+ return new TransactionItemWorker(removeTransactionItem(this.ti, id));
304
342
  }
305
- get hasProducts$() {
306
- return this.quoteSubj$.pipe(map(() => this.hasProducts));
343
+ replace(toReplace) {
344
+ return new TransactionItemWorker(replaceTransactionItem(this.ti, toReplace));
307
345
  }
308
- get hasProducts() {
309
- return Boolean(this.quoteSubj$.value?.currentState.length);
346
+ }
347
+
348
+ function extractMetadata(uiDefinition) {
349
+ return omit(uiDefinition, [
350
+ 'children',
351
+ 'pages',
352
+ 'components',
353
+ ]);
354
+ }
355
+
356
+ class ConfigurationService {
357
+ get state$() {
358
+ return this.configurationStateSubj$.asObservable().pipe(filter(isDefined));
310
359
  }
311
- get hasAssets$() {
312
- return this.assetsSubj$.pipe(map(() => this.hasAssets));
360
+ get state() {
361
+ return this.configurationStateSubj$.getValue();
313
362
  }
314
- get hasAssets() {
315
- return Boolean(this.assetsSubj$.value?.currentState.length);
363
+ get previousState() {
364
+ return this.previousConfigurationStateSubj$.getValue();
365
+ }
366
+ get asset() {
367
+ return this.state?.assets[0] ?? null;
368
+ }
369
+ get root$() {
370
+ return this.state$.pipe(map$1(state => state.salesTransactionItems[0]), filter(isDefined));
316
371
  }
317
- get assetsState() {
318
- return this.assetsSubj$.value;
372
+ get root() {
373
+ return this.configurationStateSubj$.getValue()?.salesTransactionItems[0] ?? null;
319
374
  }
320
- constructor(context, flowInfoService, accountApiService, quoteApiService) {
321
- this.context = context;
375
+ constructor(flowInfoService, messageService, configurationRuntimeService, salesTransactionService, proceduresApiService) {
322
376
  this.flowInfoService = flowInfoService;
323
- this.accountApiService = accountApiService;
324
- this.quoteApiService = quoteApiService;
325
- this.quoteSubj$ = new BehaviorSubject(null);
326
- this.assetsSubj$ = new BehaviorSubject(null);
327
- this.resetSubj$ = new BehaviorSubject(true);
328
- this.isInitializedSubj$ = new BehaviorSubject(false);
329
- this.initialCurrentState = [];
330
- this._hasUnsavedChanges = false;
331
- this.reset$ = this.resetSubj$.asObservable();
332
- this.isInitializedSubj$
333
- .pipe(filter(isInitialized => isInitialized), switchMap$1(() => this.quoteSubj$.asObservable()), skip(1), tap(quote => this.markAsUpdated(quote)))
334
- .subscribe();
377
+ this.messageService = messageService;
378
+ this.configurationRuntimeService = configurationRuntimeService;
379
+ this.salesTransactionService = salesTransactionService;
380
+ this.proceduresApiService = proceduresApiService;
381
+ this.hasUnsavedChanges = false;
382
+ this.configurationStateSubj$ = new BehaviorSubject(null);
383
+ this.previousConfigurationStateSubj$ = new BehaviorSubject(null);
384
+ this.isLoadingSubj$ = new BehaviorSubject(false);
385
+ this.isLoading$ = this.isLoadingSubj$.asObservable();
335
386
  }
336
387
  reset() {
337
- this.resetSubj$.next(true);
338
- this.quoteSubj$.next(null);
339
- this.assetsSubj$.next(null);
340
- this.isInitialized = false;
341
388
  this.hasUnsavedChanges = false;
389
+ this.configurationStateSubj$.next(null);
390
+ this.previousConfigurationStateSubj$.next(null);
342
391
  }
343
- init(headerId, params) {
344
- const ctx = this.context.resolve();
345
- const isAccountMode = this.context.mode === ConfigurationContextMode.ACCOUNT;
346
- const accountId = isAccountMode ? headerId : ctx.properties.AccountId;
347
- return zip(accountId ? this.accountApiService.getAssetsState(accountId, params) : of(null), isAccountMode
348
- ? of(QuoteDraft.emptyQuote(ConfigurationContextMode.ACCOUNT))
349
- : this.quoteApiService.getQuoteState(headerId, params)).pipe(tap(([assets, quote]) => {
350
- if (assets) {
351
- this.assetsSubj$.next(assets);
352
- }
353
- this.quoteSubj$.next(quote);
354
- if (assets && isAccountMode) {
355
- this.context.update(assets.context);
392
+ init$() {
393
+ const { state } = this.salesTransactionService;
394
+ const { productId, transactionItemId } = this.flowInfoService.context;
395
+ if (!state) {
396
+ return of(undefined);
397
+ }
398
+ let transactionItem = state?.salesTransactionItems.find(item => item.id === transactionItemId);
399
+ if (!transactionItem) {
400
+ transactionItem = state.salesTransactionItems.find(item => item.productId === productId);
401
+ }
402
+ const assetItem = transactionItem ? state?.assets.find(item => item.id === transactionItem?.assetId) : undefined;
403
+ const configurationState = {
404
+ ...state,
405
+ salesTransactionItems: transactionItem ? [transactionItem] : [],
406
+ assets: assetItem ? [assetItem] : [],
407
+ };
408
+ this.configurationStateSubj$.next(configurationState);
409
+ this.previousConfigurationStateSubj$.next(configurationState);
410
+ return of(undefined);
411
+ }
412
+ patch$(transactionItem) {
413
+ const { state, root } = this;
414
+ if (!state) {
415
+ return throwError(() => new Error(`Configuration State is not initialized`));
416
+ }
417
+ if (!root) {
418
+ return throwError(() => new Error(`Root SalesTransactionItem not found`));
419
+ }
420
+ const newRoot = new TransactionItemWorker(root).replace(transactionItem).ti;
421
+ const newSalesTransaction = {
422
+ ...state,
423
+ salesTransactionItems: [newRoot],
424
+ };
425
+ return this.configureRequest$(newSalesTransaction).pipe(catchError(error => {
426
+ console.error(error);
427
+ if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
428
+ this.messageService.add({ severity: 'error', summary: error });
356
429
  }
357
- else {
358
- this.context.update(quote.context);
430
+ return throwError(() => error);
431
+ }), tap$1(() => {
432
+ if (!this.hasUnsavedChanges) {
433
+ this.hasUnsavedChanges = true;
359
434
  }
360
- }), map(() => noop()), take(1));
435
+ }), map$1(noop));
361
436
  }
362
- finalizeInit() {
363
- this.isInitialized = true;
364
- this.hasUnsavedChanges = false;
437
+ patch(transactionItem) {
438
+ this.patch$(transactionItem).subscribe();
365
439
  }
366
- setCurrentLineItemState(lineItems) {
367
- const quoteDraft = this.quoteSubj$.value;
368
- if (!quoteDraft) {
369
- return;
370
- }
371
- this.quoteSubj$.next({
372
- ...quoteDraft,
373
- currentState: lineItems,
374
- });
440
+ configureRequest$(salesTransaction) {
441
+ const request = {
442
+ salesTransaction,
443
+ };
444
+ this.isLoadingSubj$.next(true);
445
+ return this.proceduresApiService.apply$(request).pipe(tap$1(result => {
446
+ const newState = result.salesTransaction;
447
+ this.configurationStateSubj$.next(newState);
448
+ this.previousConfigurationStateSubj$.next(cloneDeep(newState));
449
+ }), map$1(response => response.salesTransaction), catchError(error => throwError(() => {
450
+ const resetState = this.previousConfigurationStateSubj$.getValue();
451
+ if (resetState) {
452
+ this.previousConfigurationStateSubj$.next(cloneDeep(resetState));
453
+ this.configurationStateSubj$.next(resetState);
454
+ }
455
+ if (error.error) {
456
+ return extractErrorDetails(error.error).join('. ');
457
+ }
458
+ return error.message || JSON.stringify(error);
459
+ })), finalize(() => this.isLoadingSubj$.next(false)));
375
460
  }
376
- updateQuoteDraft(update) {
377
- const quoteDraft = this.quoteSubj$.value;
378
- if (!quoteDraft) {
379
- return;
380
- }
381
- if (update.context) {
382
- this.context.set(update.context);
383
- }
384
- this.quoteSubj$.next({
385
- ...quoteDraft,
386
- ...update,
387
- });
461
+ configureExternal$(props) {
462
+ // TODO: implement
463
+ throw new Error('Not implemented');
388
464
  }
389
- updateByPriceSummary(priceSummary) {
390
- const quoteDraft = this.quoteSubj$.value;
391
- if (!quoteDraft) {
392
- return;
393
- }
394
- const updatedCurrentState = this.currentState.map(lineItem => {
395
- const updated = priceSummary.lineItems.find(li => li.id === lineItem.id);
396
- return updated ?? lineItem;
397
- });
398
- this.quoteSubj$.next({
399
- ...quoteDraft,
400
- currentState: updatedCurrentState,
401
- totalPrices: priceSummary.totalPrices,
402
- approvalItems: priceSummary.approvalItems,
403
- });
465
+ configureGuidedSelling$(data) {
466
+ // TODO: implement
467
+ throw new Error('Not implemented');
404
468
  }
405
- setAssetsState(assetsState) {
406
- this.assetsSubj$.next(assetsState);
469
+ }
470
+ ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, deps: [{ token: FlowInfoService }, { token: i2.MessageService }, { token: ConfigurationRuntimeService }, { token: SalesTransactionService }, { token: i4.ProceduresApiService }], target: i0.ɵɵFactoryTarget.Injectable });
471
+ ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
473
+ type: Injectable
474
+ }], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i2.MessageService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: i4.ProceduresApiService }]; } });
475
+
476
+ class SalesTransactionService {
477
+ get isInitialized$() {
478
+ return this.isInitializedSubj$.asObservable();
407
479
  }
408
- get quoteDraft$() {
409
- return combineLatest([this.quoteSubj$, this.context.resolve$()]).pipe(map(() => this.quoteDraft), filter((quote) => Boolean(quote)), shareReplay());
480
+ get isInitialized() {
481
+ return this.isInitializedSubj$.getValue();
410
482
  }
411
- get quoteDraft() {
412
- const quote = this.quoteSubj$.value;
413
- if (!quote) {
414
- return null;
483
+ set hasUnsavedChanges(value) {
484
+ this.hasUnsavedChangesSubj$.next(value);
485
+ if (!this.hasUnsavedChanges) {
486
+ this.initialState = this.state?.salesTransactionItems ?? [];
415
487
  }
416
- return {
417
- ...quote,
418
- context: this.context.resolve(),
419
- };
420
488
  }
421
- get currentState$() {
422
- return this.quoteDraft$.pipe(map(quote => quote.currentState));
489
+ get hasUnsavedChanges() {
490
+ return this.hasUnsavedChangesSubj$.getValue();
491
+ }
492
+ get state() {
493
+ return this.stateSubj$.getValue();
494
+ }
495
+ get hasAssets() {
496
+ return Boolean(this.state?.assets.length);
423
497
  }
424
- get currentState() {
425
- return this.quoteDraft?.currentState ?? [];
498
+ get hasProducts() {
499
+ return Boolean(this.state?.salesTransactionItems.length);
426
500
  }
427
- get isStandalone() {
428
- return this.flowInfoService.flow?.properties.standalone ?? false;
501
+ constructor(flowInfoService, salesTransactionApiService) {
502
+ this.flowInfoService = flowInfoService;
503
+ this.salesTransactionApiService = salesTransactionApiService;
504
+ this.stateSubj$ = new BehaviorSubject(null);
505
+ this.isInitializedSubj$ = new BehaviorSubject(false);
506
+ this.hasUnsavedChangesSubj$ = new BehaviorSubject(false);
507
+ this.initialState = [];
508
+ this.hasUnsavedChanges$ = this.hasUnsavedChangesSubj$.asObservable();
509
+ this.state$ = this.stateSubj$.asObservable().pipe(filter$1(isDefined));
429
510
  }
430
- get isStandalone$() {
431
- return this.flowInfoService.flow$.pipe(map(() => this.isStandalone));
511
+ init(headerId, params) {
512
+ return this.salesTransactionApiService.getState(headerId, params).pipe(tap(res => this.stateSubj$.next(res.salesTransaction)), map(res => res.salesTransaction));
432
513
  }
433
- getInitialCurrentState() {
434
- return this.initialCurrentState;
514
+ finalizeInit() {
515
+ this.isInitializedSubj$.next(true);
516
+ this.hasUnsavedChanges = false;
435
517
  }
436
- isEditMode$() {
437
- return this.context.resolve$().pipe(map(() => this.isEditMode()));
518
+ reset() {
519
+ this.stateSubj$.next(null);
520
+ this.isInitializedSubj$.next(false);
521
+ this.hasUnsavedChangesSubj$.next(false);
438
522
  }
439
- isEditMode() {
440
- const context = this.context.resolve();
441
- if (context.mode === ConfigurationContextMode.ACCOUNT) {
442
- return true;
443
- }
444
- if (context.mode === ConfigurationContextMode.QUOTE) {
445
- return context.properties.Status === 'Draft';
446
- }
447
- return false;
523
+ getInitialState() {
524
+ return this.initialState;
448
525
  }
449
- markAsUpdated(quote) {
450
- if (quote?.context.properties['#mode'] === ConfigurationContextMode.ACCOUNT) {
451
- this.hasUnsavedChanges = !!quote && !quote.currentState.every(li => li.actionCode === 'EXIST');
526
+ setState(state) {
527
+ this.stateSubj$.next(state);
528
+ }
529
+ }
530
+ SalesTransactionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, deps: [{ token: FlowInfoService }, { token: i4.SalesTransactionApiService }], target: i0.ɵɵFactoryTarget.Injectable });
531
+ SalesTransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService });
532
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, decorators: [{
533
+ type: Injectable
534
+ }], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i4.SalesTransactionApiService }]; } });
535
+
536
+ class FlowConfigurationService {
537
+ constructor(proceduresApiService, salesTransactionService) {
538
+ this.proceduresApiService = proceduresApiService;
539
+ this.salesTransactionService = salesTransactionService;
540
+ this.updatedSubj$ = new Subject();
541
+ this.updated$ = this.updatedSubj$.asObservable();
542
+ }
543
+ calculate$(state) {
544
+ return this.proceduresApiService.apply$({ salesTransaction: state }).pipe(tap(result => this.salesTransactionService.setState(result.salesTransaction)), map(noop));
545
+ }
546
+ calculate(state) {
547
+ this.calculate$(state).subscribe();
548
+ }
549
+ revert$(transactionItemId) {
550
+ const state = this.salesTransactionService.state;
551
+ const initialState = this.salesTransactionService.getInitialState();
552
+ const currentState = state?.salesTransactionItems ?? [];
553
+ const currentItemIndex = currentState.findIndex(({ id }) => id === transactionItemId);
554
+ const currentItem = currentState[currentItemIndex];
555
+ const initialItem = initialState.find(({ integrationId }) => integrationId === currentItem?.integrationId);
556
+ if (!state || !currentItem || !initialItem) {
557
+ return of(null);
452
558
  }
453
- else {
454
- this.hasUnsavedChanges = !isEqual(this.initialCurrentState, quote?.currentState);
559
+ const updatedState = cloneDeep(currentState);
560
+ updatedState.splice(currentItemIndex, 1, initialItem);
561
+ return of([]).pipe(tap(() => {
562
+ this.salesTransactionService.setState({ ...state, salesTransactionItems: updatedState });
563
+ }), switchMap(() => this.calculate$({ ...state, salesTransactionItems: updatedState })), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
564
+ }
565
+ revert(transactionItemId) {
566
+ this.revert$(transactionItemId).subscribe();
567
+ }
568
+ delete$(ids) {
569
+ const state = this.salesTransactionService.state;
570
+ if (!state) {
571
+ return of(null);
455
572
  }
573
+ return of([]).pipe(map(() => state.salesTransactionItems.filter(({ id }) => !ids.includes(id))), switchMap(updatedState => this.calculate$({ ...state, salesTransactionItems: updatedState })), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
574
+ }
575
+ delete(ids) {
576
+ this.delete$(ids).subscribe();
577
+ }
578
+ handleErrorAndBounceBack() {
579
+ return (source$) => {
580
+ return source$.pipe(catchError$1(error => {
581
+ console.error(error);
582
+ // bounce back if configuration call has failed
583
+ const state = this.salesTransactionService.state;
584
+ if (state) {
585
+ this.salesTransactionService.setState(state);
586
+ this.updatedSubj$.next();
587
+ }
588
+ return throwError(() => error);
589
+ }));
590
+ };
456
591
  }
457
592
  }
458
- QuoteDraftService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService, deps: [{ token: ContextService }, { token: FlowInfoService }, { token: i1.AccountApiService }, { token: i1.QuoteApiService }], target: i0.ɵɵFactoryTarget.Injectable });
459
- QuoteDraftService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService });
460
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService, decorators: [{
593
+ FlowConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, deps: [{ token: i4.ProceduresApiService }, { token: SalesTransactionService }], target: i0.ɵɵFactoryTarget.Injectable });
594
+ FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
595
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
461
596
  type: Injectable
462
- }], ctorParameters: function () { return [{ type: ContextService }, { type: FlowInfoService }, { type: i1.AccountApiService }, { type: i1.QuoteApiService }]; } });
597
+ }], ctorParameters: function () { return [{ type: i4.ProceduresApiService }, { type: SalesTransactionService }]; } });
463
598
 
464
599
  class FlowStateService {
465
- constructor(contextService, quoteDraftService, flowInfoService, flowConfiguration, processorsApiService, flowStateApiService, quoteApiService, toastService, customizationService) {
466
- this.contextService = contextService;
467
- this.quoteDraftService = quoteDraftService;
468
- this.flowInfoService = flowInfoService;
600
+ constructor(flowConfiguration, flowInfoService, flowStateApiService, processorsApiService, salesTransactionApiService, salesTransactionService, toastService, customizationService) {
469
601
  this.flowConfiguration = flowConfiguration;
470
- this.processorsApiService = processorsApiService;
602
+ this.flowInfoService = flowInfoService;
471
603
  this.flowStateApiService = flowStateApiService;
472
- this.quoteApiService = quoteApiService;
604
+ this.processorsApiService = processorsApiService;
605
+ this.salesTransactionApiService = salesTransactionApiService;
606
+ this.salesTransactionService = salesTransactionService;
473
607
  this.toastService = toastService;
474
608
  this.customizationService = customizationService;
475
609
  this.NOT_INITIALIZED = Symbol();
@@ -486,68 +620,22 @@ class FlowStateService {
486
620
  this.cleanup$ = new Subject();
487
621
  this.statefulExecutionRequest$ = this.initBufferedRequest$();
488
622
  /*
489
- In stateless mode watch QuoteDraft changes and call executeRequest so that
490
- all subscriptions get their updates according to updated QuoteDraft
623
+ In stateless mode watch State changes and call executeRequest so that
624
+ all subscriptions get their updates according to updated State
491
625
  */
492
626
  this.isInitialized$()
493
- .pipe(filter$1(Boolean), filter$1(() => !this.getFlowSafe().properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
627
+ .pipe(filter$1(Boolean), filter$1(() => !this.flowInfoService.flow.properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
494
628
  .subscribe();
495
- this.charges$ = this.flowInfoService.flow$.pipe(filter$1(isDefined), switchMap(() => {
496
- if (this.flowInfoService.isLegacy) {
497
- return this.quoteDraftService.quoteDraft$.pipe(map$1(quoteDraft => quoteDraft.charges));
498
- }
499
- else {
500
- return this.subscribe$(UITemplateType.FLOW_ENGINE, 'CHARGES', null, {
501
- cold: true,
502
- }).pipe(map$1(response => (response.success ? response.result : {})));
503
- }
504
- }), shareReplay$1(1));
505
- this.charges$.subscribe();
506
- this.pricePlans$ = this.flowInfoService.flow$.pipe(filter$1(isDefined), switchMap(() => {
507
- if (this.flowInfoService.isLegacy) {
508
- return this.quoteDraftService.quoteDraft$.pipe(map$1(quoteDraft => quoteDraft.pricePlans));
509
- }
510
- else {
511
- return this.subscribe$(UITemplateType.FLOW_ENGINE, 'PRICE_PLANS', null, {
512
- cold: true,
513
- }).pipe(map$1(response => (response.success ? response.result : {})));
514
- }
515
- }), shareReplay$1(1));
516
- this.pricePlans$.subscribe();
517
- this.activeMetrics$ = this.flowInfoService.flow$.pipe(filter$1(isDefined), switchMap(() => {
518
- if (this.flowInfoService.isLegacy) {
519
- return this.quoteDraftService.quoteDraft$.pipe(map$1(quoteDraft => quoteDraft.activeMetrics));
520
- }
521
- else {
522
- return this.subscribe$(UITemplateType.FLOW_ENGINE, 'ACTIVE_METRICS', null, {
523
- cold: true,
524
- }).pipe(map$1(response => (response.success ? response.result : [])));
525
- }
526
- }), shareReplay$1(1));
527
- this.activeMetrics$.subscribe();
528
- this.isPriceListLocked$ = this.flowInfoService.flow$.pipe(filter$1(isDefined), switchMap(() => {
529
- if (this.flowInfoService.isLegacy) {
530
- return of(false);
531
- }
532
- else {
533
- return this.subscribe$(UITemplateType.FLOW_ENGINE, 'IS_PRICE_LIST_LOCKED', null, {
534
- cold: true,
535
- }).pipe(map$1(response => (response.success ? response.result : false)));
536
- }
537
- }), shareReplay$1(1));
538
- this.isPriceListLocked$.subscribe();
539
629
  }
540
630
  init$() {
541
- return this.initProcessors$().pipe(switchMap(() => {
542
- if (this.getFlowSafe().properties.stateful) {
543
- return this.initStateful$();
544
- }
545
- else {
546
- return this.initStateless$();
547
- }
548
- }));
631
+ if (this.flowInfoService.flow.properties.stateful) {
632
+ return this.initProcessors$().pipe(switchMap(() => this.initStateful$()));
633
+ }
634
+ else {
635
+ return forkJoin([this.initStateless$(), this.initProcessors$()]).pipe(map(noop));
636
+ }
549
637
  }
550
- cleanup() {
638
+ reset() {
551
639
  Object.values(this.subscriptions).forEach(({ data$ }) => data$.complete());
552
640
  this.subscriptions = {};
553
641
  if (this.stateId$.value) {
@@ -559,9 +647,9 @@ class FlowStateService {
559
647
  this.cleanup$.next();
560
648
  }
561
649
  get hasUnsavedChanges() {
562
- return this.getFlowSafe().properties.stateful
650
+ return this.flowInfoService.flow.properties.stateful
563
651
  ? Array.from(this.trackedStatefulChangesMap.values()).some(Boolean)
564
- : this.quoteDraftService.hasUnsavedChanges;
652
+ : this.salesTransactionService.hasUnsavedChanges;
565
653
  }
566
654
  get stateId() {
567
655
  return this.stateId$.value;
@@ -570,14 +658,14 @@ class FlowStateService {
570
658
  return this.executionInProgress$.asObservable();
571
659
  }
572
660
  isInitialized$() {
573
- return combineLatest([this.stateId$, this.quoteDraftService.isInitialized$]).pipe(map$1(values => values.some(Boolean)));
661
+ return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map(values => values.some(Boolean)));
574
662
  }
575
663
  isInitialized() {
576
- return Boolean(this.stateId$.value) || this.quoteDraftService.isInitialized;
664
+ return Boolean(this.stateId$.value) || this.salesTransactionService.isInitialized;
577
665
  }
578
666
  execute$(scope, exec) {
579
667
  const request = this.execToRequest(scope, exec);
580
- return this.executeRequest$(request).pipe(map$1(result => {
668
+ return this.executeRequest$(request).pipe(map(result => {
581
669
  // Keep only requested results
582
670
  const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
583
671
  if (exec.selectors?.[requestId]) {
@@ -593,7 +681,7 @@ class FlowStateService {
593
681
  actions: [{ name: action, inputData }],
594
682
  };
595
683
  const request = this.execToRequest(scope, exec);
596
- return this.executeRequest$(request).pipe(map$1(noop));
684
+ return this.executeRequest$(request).pipe(map(noop));
597
685
  }
598
686
  select$(scope, selectorName, inputData) {
599
687
  const requestId = this.generateRequestId(scope, selectorName, inputData);
@@ -605,7 +693,7 @@ class FlowStateService {
605
693
  },
606
694
  },
607
695
  });
608
- return this.executeRequest$(request).pipe(map$1(response => response.selectors[requestId]));
696
+ return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
609
697
  }
610
698
  subscribe$(scope, selectorName, inputData, options) {
611
699
  const requestId = this.generateRequestId(scope, selectorName, inputData);
@@ -631,16 +719,16 @@ class FlowStateService {
631
719
  this.executeRequest$(request).subscribe();
632
720
  }
633
721
  }
634
- return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map$1(data => data), finalize(() => {
722
+ return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map(data => data), finalize$1(() => {
635
723
  if (!this.subscriptions[requestId]?.data$.observed) {
636
724
  delete this.subscriptions[requestId];
637
725
  }
638
726
  }));
639
727
  }
640
728
  save$() {
641
- if (this.getFlowSafe().properties.stateful) {
729
+ if (this.flowInfoService.flow.properties.stateful) {
642
730
  if (this.stateId$.value) {
643
- return this.flowStateApiService.save(this.stateId$.value).pipe(tap$1(() => {
731
+ return this.flowStateApiService.save(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })), tap(() => {
644
732
  Array.from(this.trackedStatefulChangesMap.keys()).forEach(key => {
645
733
  this.trackedStatefulChangesMap.set(key, false);
646
734
  });
@@ -648,30 +736,26 @@ class FlowStateService {
648
736
  }
649
737
  }
650
738
  else {
651
- const quoteDraft = this.quoteDraftService.quoteDraft;
652
- if (quoteDraft) {
653
- return this.quoteApiService.upsertQuote(quoteDraft).pipe(tap$1(({ versionId }) => {
654
- this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
655
- }));
739
+ const state = this.salesTransactionService.state;
740
+ if (state) {
741
+ return this.salesTransactionApiService.upsert(state);
656
742
  }
657
743
  }
658
- return of({ quoteId: '' });
744
+ return of({ id: '' });
659
745
  }
660
746
  submit$() {
661
- if (this.getFlowSafe().properties.stateful) {
747
+ if (this.flowInfoService.flow.properties.stateful) {
662
748
  if (this.stateId$.value) {
663
- return this.flowStateApiService.submit(this.stateId$.value);
749
+ return this.flowStateApiService.submit(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })));
664
750
  }
665
751
  }
666
752
  else {
667
- const quoteDraft = this.quoteDraftService.quoteDraft;
668
- if (quoteDraft) {
669
- return this.quoteApiService.submitQuote(quoteDraft).pipe(tap$1(({ versionId }) => {
670
- this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
671
- }));
753
+ const state = this.salesTransactionService.state;
754
+ if (state) {
755
+ return this.salesTransactionApiService.submit(state);
672
756
  }
673
757
  }
674
- return of({ quoteId: '' });
758
+ return of({ id: '' });
675
759
  }
676
760
  getFlowStore() {
677
761
  return this.flowStore;
@@ -709,10 +793,10 @@ class FlowStateService {
709
793
  fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
710
794
  }
711
795
  }
712
- const execution$ = this.getFlowSafe().properties.stateful
796
+ const execution$ = this.flowInfoService.flow.properties.stateful
713
797
  ? this.executeStateful$(fullRequest)
714
798
  : this.executeStateless$(fullRequest);
715
- return execution$.pipe(tap$1(result => this.handleSelectorsResponse(result.selectors)));
799
+ return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
716
800
  }
717
801
  handleSelectorsResponse(selectors) {
718
802
  Object.entries(selectors).forEach(([requestId, selectorResult]) => {
@@ -727,31 +811,21 @@ class FlowStateService {
727
811
  });
728
812
  }
729
813
  initStateful$() {
730
- // Subscriptions
731
- this.subscribe$(UITemplateType.FLOW_ENGINE, 'CONTEXT', null, { cold: true })
732
- .pipe(tap$1(response => {
733
- if (response.success) {
734
- this.contextService.update(response.result);
735
- }
736
- }), takeUntil(this.cleanup$))
737
- .subscribe();
738
814
  const processorsList = flatten(Object.values(this.processors).map(ownerMap => Object.values(ownerMap ?? {})));
739
815
  const processors = processorsList.length ? processorsList : undefined;
740
816
  const selectors = Object.values(this.subscriptions)
741
817
  .map(({ request }) => request.selectors)
742
818
  .filter(isDefined)
743
819
  .reduce((trunk, selectors) => ({ ...trunk, ...selectors }), {});
744
- const request = this.getDefaultExecutionRequestDTO();
745
820
  return this.flowStateApiService
746
821
  .init({
747
- quoteId: this.contextService.resolve().headerId,
748
- params: this.flowInfoService.params ?? {},
822
+ quoteId: this.flowInfoService.context.headerId,
823
+ params: this.flowInfoService.context,
749
824
  actionsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.ACTION),
750
825
  selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
751
- selectors: { ...selectors, ...request.selectors },
752
- actions: request.actions,
826
+ selectors: selectors,
753
827
  })
754
- .pipe(map$1(({ stateId, selectors }) => {
828
+ .pipe(map(({ stateId, selectors }) => {
755
829
  this.handleSelectorsResponse(selectors);
756
830
  this.stateId$.next(stateId);
757
831
  }));
@@ -771,1095 +845,175 @@ class FlowStateService {
771
845
  };
772
846
  this.executionInProgress$.next(true);
773
847
  return this.flowStateApiService.execute(this.stateId$.value, request);
774
- }), tap$1(({ stateId }) => this.stateId$.next(stateId)), share(), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
848
+ }), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
775
849
  this.executionInProgress$.next(false);
776
850
  return throwError(() => e);
777
851
  }));
778
852
  }
779
853
  executeStateful$(request) {
780
- return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
854
+ return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take(1), switchMap(() =>
781
855
  // make sure stream switches to statefulExecutionRequest$ before pushing an execution request
782
856
  combineLatest([
783
857
  this.statefulExecutionRequest$,
784
- of(undefined).pipe(tap$1(() => this.statefulRequestStream$.next(request))),
785
- ])), map$1(([response]) => response), take$1(1));
858
+ of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
859
+ ])), map(([response]) => response), take(1));
786
860
  }
787
861
  initStateless$() {
788
- const { headerId } = this.contextService.resolve();
789
- return this.quoteDraftService.init(headerId, this.flowInfoService.params ?? {}).pipe(tap$1(() => {
790
- const assets = this.quoteDraftService.assetsState;
862
+ return this.salesTransactionService.init(this.flowInfoService.context.headerId, this.flowInfoService.context).pipe(tap(() => {
863
+ const assets = this.salesTransactionService.state?.assets;
791
864
  if (assets) {
792
865
  this.flowStore = { ...this.flowStore, assets };
793
866
  }
794
- }), switchMap(() => {
795
- if (this.flowInfoService.isLegacy) {
796
- return of(null);
797
- }
798
- return this.executeRequest$(this.getDefaultExecutionRequestDTO());
799
- }), switchMap(() => this.calculate$()), tap$1(() => this.quoteDraftService.finalizeInit()), map$1(noop));
800
- }
801
- calculate$() {
802
- const flowState = this.quoteDraftService.quoteDraft;
803
- if (!flowState) {
804
- return of(undefined);
805
- }
806
- /*
807
- Don't execute procedures when:
808
- * Initializing a standalone product configuration UI, as procedure is execute in /price call
809
- * Initializing an empty account (account with no assets)
810
- */
811
- const isEmptyAccountMode = this.contextService.mode === ConfigurationContextMode.ACCOUNT &&
812
- !this.quoteDraftService.hasProducts &&
813
- !this.quoteDraftService.hasAssets &&
814
- !this.quoteDraftService.quoteDraft?.initialState.length;
815
- if (this.quoteDraftService.isStandalone || isEmptyAccountMode) {
816
- return of(undefined);
817
- }
818
- return this.flowConfiguration.calculate$(flowState);
867
+ }), switchMap(state => this.flowConfiguration.calculate$(state)), tap(() => this.salesTransactionService.finalizeInit()), map(noop));
819
868
  }
820
869
  executeStateless$(request) {
821
870
  this.executionInProgress$.next(true);
822
- return of(undefined).pipe(tap$1(() => this.executeStatelessActions(request)), switchMap(() => {
823
- /*
824
- Skip price calculation in case
825
- 1. No actions in the request
826
- 2. Initialization process execution (state not initialized yet)
827
- */
828
- if (!request.actions?.length || !this.isInitialized()) {
829
- return of(undefined);
830
- }
831
- else {
832
- return this.calculate$();
833
- }
834
- }), map$1(() => this.executeStatelessSelectors(request)), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
835
- this.executionInProgress$.next(false);
836
- return throwError(() => e);
837
- }));
838
- }
839
- executeStatelessActions(request) {
840
- if (!this.quoteDraftService.quoteDraft || !request.actions?.length) {
841
- return;
842
- }
843
- let flowState = this.quoteDraftService.quoteDraft;
844
- request.actions.forEach(action => {
845
- try {
846
- flowState = this.executeActionScript(flowState, action) ?? flowState;
847
- }
848
- catch (e) {
849
- console.error(e);
850
- this.toastService.add({ severity: ToastType.error, summary: String(e) });
851
- throw e;
852
- }
853
- });
854
- this.quoteDraftService.updateQuoteDraft(flowState);
855
- }
856
- executeStatelessSelectors(request) {
857
- if (!this.quoteDraftService.quoteDraft) {
858
- throw 'QuoteDraft is not initialized';
859
- }
860
- const flowState = this.quoteDraftService.quoteDraft;
861
- return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
862
- try {
863
- result.selectors[key] = {
864
- success: true,
865
- result: this.executeSelectorScript(flowState, selector),
866
- };
867
- }
868
- catch (e) {
869
- console.error(e);
870
- result.selectors[key] = {
871
- success: false,
872
- errorMessage: String(e),
873
- };
874
- }
875
- return result;
876
- }, { stateId: '', selectors: {} });
877
- }
878
- getFlowSafe() {
879
- if (!this.flowInfoService.flow) {
880
- throw 'Flow is not defined';
881
- }
882
- return this.flowInfoService.flow;
883
- }
884
- initProcessors$() {
885
- const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
886
- const flow = this.getFlowSafe();
887
- if (flow.properties.stateful && !hasOverrides) {
888
- // Skip initialization as backend will take processors from SF
889
- return of(undefined);
890
- }
891
- const owners$ = Object.values(this.flowInfoService.templates)
892
- .map(template => {
893
- if (!template) {
894
- return;
895
- }
896
- const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
897
- return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap$1(processors => {
898
- const processorsMap = processors.reduce((acc, p) => {
899
- acc[p.apiName] = p;
900
- return acc;
901
- }, {});
902
- this.processors[template.id] = processorsMap;
903
- }));
904
- })
905
- .filter(isDefined);
906
- if (!owners$.length) {
907
- return of(undefined);
908
- }
909
- return forkJoin(owners$).pipe(map$1(noop));
910
- }
911
- executeActionScript(request, executable) {
912
- const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
913
- if (!configurationProcessor?.script) {
914
- const scope = this.getScopeByOwnerId(executable.ownerId);
915
- const scopeText = scope ? ` in ${scope}` : '';
916
- throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
917
- }
918
- return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
919
- }
920
- executeSelectorScript(request, executable) {
921
- const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
922
- if (!configurationProcessor?.script) {
923
- const scope = this.getScopeByOwnerId(executable.ownerId);
924
- const scopeText = scope ? ` in ${scope}` : '';
925
- throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
926
- }
927
- return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
928
- }
929
- executeProcessorScript(request, configurationProcessor, inputData) {
930
- const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
931
- let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
932
- if (!functionToExecute) {
933
- const script = `${configurationProcessor.script}\nreturn transform;`;
934
- const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
935
- functionToExecute = new Function(script + sourceMap)();
936
- this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
937
- }
938
- return functionToExecute({
939
- request,
940
- inputData,
941
- flowStore: this.flowStore,
942
- });
943
- }
944
- generateRequestId(scope, selectorName, inputData) {
945
- const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
946
- return `${scope}/${selectorName}/${inputDataHash}`;
947
- }
948
- getDefaultExecutionRequestDTO() {
949
- const request = {
950
- actions: [],
951
- selectors: {},
952
- };
953
- if (this.getFlowSafe().properties.standalone) {
954
- return request;
955
- }
956
- const flowEngineTemplateId = this.getOwnerIdByScope(UITemplateType.FLOW_ENGINE);
957
- request.actions?.push({
958
- apiName: 'UPDATE_CONTEXT_PROPERTIES',
959
- ownerId: flowEngineTemplateId,
960
- inputData: this.contextService.resolve().properties,
961
- });
962
- return request;
963
- }
964
- checkStatefulChanges(requestId, selectorResult) {
965
- if (this.trackedStatefulChangesMap.has(requestId)) {
966
- if (!this.initialStatefulData[requestId]) {
967
- this.initialStatefulData[requestId] = selectorResult;
968
- }
969
- const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
970
- this.trackedStatefulChangesMap.set(requestId, hasChanges);
971
- }
972
- }
973
- }
974
- FlowStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, deps: [{ token: ContextService }, { token: QuoteDraftService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.ConfigurationProcessorsApiService }, { token: i1.FlowStateApiService }, { token: i1.QuoteApiService }, { token: i6.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
975
- FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
976
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
977
- type: Injectable
978
- }], ctorParameters: function () { return [{ type: ContextService }, { type: QuoteDraftService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.FlowStateApiService }, { type: i1.QuoteApiService }, { type: i6.ToastService }, { type: undefined, decorators: [{
979
- type: Optional
980
- }, {
981
- type: Inject,
982
- args: [FLOW_CUSTOMIZATION]
983
- }] }]; } });
984
-
985
- const findLineItem = (id, lineItems) => {
986
- return findLineItemWithComparator(lineItems, (li) => li.id === id);
987
- };
988
- const findLineItemWithComparator = (lineItems, comparator) => {
989
- let currentLevel = lineItems;
990
- while (currentLevel.length) {
991
- const found = currentLevel.find(comparator);
992
- if (found) {
993
- return found;
994
- }
995
- currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
996
- }
997
- return;
998
- };
999
- const insertLineItem = (lineItem, parentId, toInsert) => {
1000
- const insertData = lineItem.id === parentId ? [toInsert] : [];
1001
- return {
1002
- ...lineItem,
1003
- lineItems: [
1004
- ...insertData,
1005
- ...lineItem.lineItems.map(li => {
1006
- return insertLineItem(li, parentId, toInsert);
1007
- }),
1008
- ],
1009
- };
1010
- };
1011
- const removeLineItem = (lineItem, idToRemove) => {
1012
- return {
1013
- ...lineItem,
1014
- lineItems: lineItem.lineItems
1015
- .map(li => {
1016
- if (li.id === idToRemove) {
1017
- return;
1018
- }
1019
- else if (li.lineItems.length) {
1020
- return removeLineItem(li, idToRemove);
1021
- }
1022
- return li;
1023
- })
1024
- .filter(r => !!r),
1025
- };
1026
- };
1027
- const replaceLineItem = (lineItem, replaceTo, skipCardinalityCalculation = false) => {
1028
- if (lineItem.id === replaceTo.id) {
1029
- if (!skipCardinalityCalculation) {
1030
- return { ...recalculateCardinalityVariables(lineItem, replaceTo) };
1031
- }
1032
- else {
1033
- return { ...replaceTo };
1034
- }
1035
- }
1036
- return {
1037
- ...lineItem,
1038
- lineItems: lineItem.lineItems.map(li => replaceLineItem(li, replaceTo, skipCardinalityCalculation)),
1039
- };
1040
- };
1041
- const collectCardinalityComputations = (portDomains) => {
1042
- const cardinalityComputations = new Map();
1043
- entries(portDomains).forEach(([key, portDomain]) => {
1044
- cardinalityComputations.set(key, portDomain.properties['cardinalityComputation'] === 'true');
1045
- });
1046
- return cardinalityComputations;
1047
- };
1048
- const calculateCardinalityVariables = (lineItems, cardinalityComputations) => {
1049
- const cardVars = new Map();
1050
- lineItems
1051
- .filter(({ port, type }) => !!port && !!type)
1052
- .forEach(li => {
1053
- if (cardinalityComputations.get(`${li.port}`)) {
1054
- const cardinalityVariableName = `#CV-${li.type}@${li.port}`;
1055
- cardVars.set(cardinalityVariableName, (cardVars.get(cardinalityVariableName) ?? 0) + li.qty);
1056
- }
1057
- });
1058
- return cardVars;
1059
- };
1060
- const cardinalityRegexp = new RegExp('#CV-[a-zA-Z0-9_]+@(?<portName>[a-zA-Z0-9_]+)');
1061
- const recalculateCardinalityVariables = (original, updated) => {
1062
- const cardinalityComputations = collectCardinalityComputations(updated.portDomains ?? original.portDomains ?? {});
1063
- const cardinalityVariables = calculateCardinalityVariables(updated.lineItems, cardinalityComputations);
1064
- const originalCardinalityVariables = calculateCardinalityVariables(original.lineItems, cardinalityComputations);
1065
- originalCardinalityVariables.forEach((value, key) => {
1066
- const execArray = cardinalityRegexp.exec(key);
1067
- const portName = execArray?.groups?.['portName'];
1068
- if (!portName || cardinalityComputations.get(portName)) {
1069
- if (cardinalityVariables.get(key) === value) {
1070
- // no need to update cardinality if no changes
1071
- cardinalityVariables.delete(key);
1072
- }
1073
- else if (!cardinalityVariables.has(key)) {
1074
- // remove last item from port
1075
- cardinalityVariables.set(key, 0);
1076
- }
1077
- }
1078
- });
1079
- return {
1080
- ...updated,
1081
- attributes: upsertAttributes(updated.attributes, [...cardinalityVariables].map(([name, value]) => ({ name, value, cfgStatus: 'Changed' }))),
1082
- };
1083
- };
1084
- const mapAttributes = (attributes) => {
1085
- return attributes.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
1086
- };
1087
- const getAttributes = (attributes, names = []) => {
1088
- const filtered = attributes.filter(({ name }) => names.includes(name));
1089
- return sortBy(filtered, [({ name }) => names.indexOf(name)]);
1090
- };
1091
- const upsertAttributes = (originalAttributes, attributesToUpsert) => {
1092
- return attributesToUpsert.reduce((acc, { name, value }) => {
1093
- const [origAttr] = getAttributes(acc, [name]);
1094
- return [
1095
- ...acc.filter(attr => attr.name !== name),
1096
- { ...(origAttr ?? { name, type: '' }), cfgStatus: origAttr ? 'Changed' : 'User', value },
1097
- ];
1098
- }, originalAttributes);
1099
- };
1100
- const patchAttributes = (rootLineItem, id, attrs, skipCardinalityCalculation = false) => {
1101
- const lineItem = findLineItem(id, [rootLineItem]);
1102
- if (!lineItem) {
1103
- return rootLineItem;
1104
- }
1105
- const attributes = upsertAttributes(lineItem.attributes, attrs);
1106
- return replaceLineItem(rootLineItem, { ...lineItem, attributes }, skipCardinalityCalculation);
1107
- };
1108
- const getAttributeValue = (attributes, name) => attributes.find(attr => attr.name === name)?.value;
1109
- const generateLineItem = (port, type, parentId, attributes = [], lineItems = []) => {
1110
- return {
1111
- id: UUID.UUID(),
1112
- port,
1113
- type,
1114
- actionCode: 'ADD',
1115
- cfgStatus: 'New',
1116
- attributes: attributes.map(({ name, value }) => ({ cfgStatus: 'User', name, value })),
1117
- lineItems,
1118
- parentId,
1119
- qty: 1,
1120
- };
1121
- };
1122
- const getRecommendedPrices = (portDomain, type) => {
1123
- const domainType = portDomain.domainTypes.find(({ name }) => name === type);
1124
- const [net, list] = domainType?.recommendedPrices
1125
- ?.filter(({ chargeMethod }) => chargeMethod === 'ONE_TIME')
1126
- .reduce((acc, rp) => {
1127
- const [netPrice, listPrice] = acc;
1128
- return [netPrice + rp.netPrice, listPrice + rp.listPrice];
1129
- }, [0, 0]) ?? [0, 0];
1130
- return { net, list };
1131
- };
1132
- const getOriginParent = (lineItems, currentLineItem) => {
1133
- let target = currentLineItem;
1134
- while (target && target.rampInstanceId) {
1135
- target = lineItems.find(sub => sub.id === currentLineItem.rampInstanceId);
1136
- }
1137
- return target;
1138
- };
1139
- const assetPredicateFn = (lineItem, assetId) => {
1140
- if (!assetId) {
1141
- return false;
1142
- }
1143
- return lineItem.assetId === assetId || lineItem.openOrderLineItemId === assetId;
1144
- };
1145
- const multiplyLineItems = (lineItem, qty, split) => {
1146
- if (split) {
1147
- const unifyIds = (lineItem) => ({
1148
- ...lineItem,
1149
- id: UUID.UUID(),
1150
- lineItems: lineItem.lineItems.map(unifyIds),
1151
- });
1152
- return map$2(new Array(qty), () => unifyIds(lineItem));
1153
- }
1154
- else {
1155
- return [
1156
- {
1157
- ...lineItem,
1158
- qty: qty,
1159
- },
1160
- ];
1161
- }
1162
- };
1163
- const isTechnicalAttribute = (name) => {
1164
- return name.startsWith('#') || name.startsWith('$');
1165
- };
1166
- const filterOutTechnicalAttributes = (attributes) => {
1167
- return attributes.filter(({ name }) => !isTechnicalAttribute(name));
1168
- };
1169
-
1170
- var lineItem_utils = /*#__PURE__*/Object.freeze({
1171
- __proto__: null,
1172
- assetPredicateFn: assetPredicateFn,
1173
- filterOutTechnicalAttributes: filterOutTechnicalAttributes,
1174
- findLineItem: findLineItem,
1175
- findLineItemWithComparator: findLineItemWithComparator,
1176
- generateLineItem: generateLineItem,
1177
- getAttributeValue: getAttributeValue,
1178
- getAttributes: getAttributes,
1179
- getOriginParent: getOriginParent,
1180
- getRecommendedPrices: getRecommendedPrices,
1181
- insertLineItem: insertLineItem,
1182
- isTechnicalAttribute: isTechnicalAttribute,
1183
- mapAttributes: mapAttributes,
1184
- multiplyLineItems: multiplyLineItems,
1185
- patchAttributes: patchAttributes,
1186
- recalculateCardinalityVariables: recalculateCardinalityVariables,
1187
- removeLineItem: removeLineItem,
1188
- replaceLineItem: replaceLineItem,
1189
- upsertAttributes: upsertAttributes
1190
- });
1191
-
1192
- class RuntimeSettingsService {
1193
- constructor(configurationSettingsApiService) {
1194
- this.configurationSettingsApiService = configurationSettingsApiService;
1195
- this.configurationSettings$ = new BehaviorSubject({});
1196
- this.currencySettings$ = new BehaviorSubject({
1197
- iso: DEFAULT_CURRENCY_ISO_CODE,
1198
- symbol: DEFAULT_CURRENCY_SYMBOL,
1199
- });
1200
- this.shoppingCartSettings$ = new BehaviorSubject([]);
1201
- this.getCurrencySymbol = (locale, currency) => {
1202
- return (0)
1203
- .toLocaleString(locale, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 0 })
1204
- .replace(/\d/g, '')
1205
- .trim();
1206
- };
1207
- }
1208
- create() {
1209
- return this.configurationSettingsApiService.fetchSettings().pipe(map$1(settings => this.parseConfigurationSettings(settings)), tap$1(configurationSettings => {
1210
- this.configurationSettings$.next(configurationSettings);
1211
- this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
1212
- this.formattingSettings = this.getFormattingSettings();
1213
- }), map$1(() => undefined));
1214
- }
1215
- initCurrency(iso) {
1216
- if (iso) {
1217
- const symbol = this.getCurrencySymbol('en-US', iso);
1218
- this.currencySettings$.next({ iso, symbol });
1219
- if (this.formattingSettings) {
1220
- this.formattingSettings.currencySymbol = symbol;
1221
- }
1222
- }
1223
- }
1224
- getFormattingSettings() {
1225
- if (this.formattingSettings) {
1226
- return this.formattingSettings;
1227
- }
1228
- const shoppingCartSettings = this.getConfigurationSettings()['shopping-cart']?.reduce((acc, setting) => {
1229
- return { ...acc, [setting.id]: setting.properties };
1230
- }, {});
1231
- const currencySettings = this.getCurrencySettings();
1232
- const dateFormat = (validateDateFormat(shoppingCartSettings?.DATE_FORMAT ?? '') && shoppingCartSettings?.DATE_FORMAT) ||
1233
- DEFAULT_DATE_FORMAT;
1234
- const decimalSeparator = shoppingCartSettings?.DECIMAL_SEPARATOR;
1235
- const thousandsSeparator = shoppingCartSettings?.THOUSANDS_SEPARATOR;
1236
- // the number of decimal places can be 0
1237
- const priceScale = shoppingCartSettings?.PRICE_SCALE;
1238
- const decimalsCount = priceScale !== null && priceScale !== '' && !isNaN(Number(priceScale)) && Number(priceScale) >= 0
1239
- ? Number(priceScale)
1240
- : DEFAULT_DECIMALS_COUNT;
1241
- const actionCodeSettings = shoppingCartSettings?.STATUS_LABEL;
1242
- return {
1243
- currencySymbol: currencySettings.symbol,
1244
- dateFormats: getSupportedDateFormats(dateFormat),
1245
- decimalsCount,
1246
- decimalSeparator: decimalSeparator !== undefined && ['.', ','].includes(decimalSeparator)
1247
- ? decimalSeparator
1248
- : DEFAULT_DECIMAL_SEPARATOR,
1249
- // thousands separator can be a blank value, so it can also be null
1250
- thousandsSeparator: thousandsSeparator !== undefined && ['.', ',', '', null].includes(thousandsSeparator)
1251
- ? thousandsSeparator || ''
1252
- : DEFAULT_THOUSANDS_SEPARATOR,
1253
- actionCodeLabels: actionCodeSettings?.length
1254
- ? actionCodeSettings.reduce((result, setting) => ({ ...result, [setting.status_label]: setting.custom_label }), {})
1255
- : DEFAULT_ACTION_CODE_LABELS,
1256
- };
1257
- }
1258
- getConfigurationSettings() {
1259
- return this.configurationSettings$.value;
1260
- }
1261
- getShoppingCartSettings() {
1262
- return this.shoppingCartSettings$.value;
1263
- }
1264
- getCurrencySettings() {
1265
- return this.currencySettings$.value;
1266
- }
1267
- parseConfigurationSettings(settings) {
1268
- return settings.reduce((acc, setting) => {
1269
- switch (setting.key) {
1270
- case 'shopping-cart':
1271
- acc['shopping-cart'] = parseJsonSafely(setting.value, []);
1272
- break;
1273
- case 'navigation':
1274
- acc.navigation = parseJsonSafely(setting.value, {});
1275
- break;
1276
- case 'flows':
1277
- acc.flows = parseJsonSafely(setting.value, []);
1278
- break;
1279
- default:
1280
- acc[setting.key] = setting.value;
1281
- }
1282
- return acc;
1283
- }, {});
1284
- }
1285
- addShoppingCartSettings(settings) {
1286
- // uniqBy removes items with the biggest index
1287
- const newSettings = uniqBy([...settings, ...this.shoppingCartSettings$.value], 'id');
1288
- this.shoppingCartSettings$.next(newSettings);
1289
- }
1290
- }
1291
- RuntimeSettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, deps: [{ token: i1.ConfigurationSettingsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
1292
- RuntimeSettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService });
1293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, decorators: [{
1294
- type: Injectable
1295
- }], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
1296
-
1297
- class LineItemWorker {
1298
- constructor(src) {
1299
- this.li = { ...src };
1300
- }
1301
- insert(parentId, toInsert) {
1302
- return new LineItemWorker(insertLineItem(this.li, parentId, toInsert));
1303
- }
1304
- remove(id) {
1305
- return new LineItemWorker(removeLineItem(this.li, id));
1306
- }
1307
- replace(toReplace, skipCardinalityCalculation = false) {
1308
- return new LineItemWorker(replaceLineItem(this.li, toReplace, skipCardinalityCalculation));
1309
- }
1310
- patchAttribute(attrs, id, skipCardinalityCalculation = false) {
1311
- return new LineItemWorker(patchAttributes(this.li, id ?? this.li.id, attrs, skipCardinalityCalculation));
1312
- }
1313
- }
1314
-
1315
- function extractMetadata(uiDefinition) {
1316
- return omit(uiDefinition, [
1317
- 'children',
1318
- 'pages',
1319
- 'components',
1320
- ]);
1321
- }
1322
-
1323
- class ConfigurationService {
1324
- constructor(quoteDraftService, runtimeService, contextService, configurationApiService, messageService, dialogService, runtimeSettings) {
1325
- this.quoteDraftService = quoteDraftService;
1326
- this.runtimeService = runtimeService;
1327
- this.contextService = contextService;
1328
- this.configurationApiService = configurationApiService;
1329
- this.messageService = messageService;
1330
- this.dialogService = dialogService;
1331
- this.runtimeSettings = runtimeSettings;
1332
- this.mode = ConfigurationMode.SEARCH;
1333
- this.configurationState = new BehaviorSubject(null);
1334
- this.previousConfigurationState = new BehaviorSubject(null);
1335
- this.isLoadingSubj$ = new BehaviorSubject(false);
1336
- this.isLoading$ = this.isLoadingSubj$.asObservable();
1337
- this.hasUnsavedChanges = false;
1338
- }
1339
- reset() {
1340
- this.hasUnsavedChanges = false;
1341
- this.runtimeService.reset();
1342
- this.configurableRamp = undefined;
1343
- this.configurationState.next(null);
1344
- this.previousConfigurationState.next(null);
1345
- }
1346
- patch$(lineItem, options) {
1347
- const source = this.getSnapshot();
1348
- if (!source) {
1349
- return throwError(() => new Error(`Source LineItem not found`));
1350
- }
1351
- const skipCardinalityCalculation = options?.skipCardinalityCalculation || this.contextSnapshot.properties['#skipCardinalityCalculation'] === 'true';
1352
- this.configurableRamp = new LineItemWorker(source).replace(lineItem, skipCardinalityCalculation).li;
1353
- return this.configure().pipe(catchError$1(error => {
1354
- console.error(error);
1355
- if (!this.runtimeService.uiDefinitionProperties.suppressToastMessages) {
1356
- this.messageService.add({ severity: 'error', summary: error });
1357
- }
1358
- // bounce back if configuration call has failed
1359
- const prevState = this.configurationState.value;
1360
- this.configurationState.next(prevState ? { ...prevState } : null);
1361
- return throwError(() => error);
1362
- }), tap(() => {
1363
- if (!this.hasUnsavedChanges) {
1364
- this.hasUnsavedChanges = true;
1365
- }
1366
- }));
1367
- }
1368
- patch(lineItem, options) {
1369
- this.patch$(lineItem, options).subscribe();
1370
- }
1371
- setConfigurableRamp(lineItem) {
1372
- this.configurableRamp = lineItem;
1373
- }
1374
- get() {
1375
- return this.configurationState.pipe(map(state => state?.lineItem), shareReplay$1());
1376
- }
1377
- getSnapshot() {
1378
- return this.configurationState.value?.lineItem ? { ...this.configurationState.value?.lineItem } : undefined;
1379
- }
1380
- getRuntimeModel() {
1381
- const runtimeModel = this.runtimeService.runtimeModel;
1382
- if (!runtimeModel) {
1383
- throw new Error('Runtime model not initialized');
1384
- }
1385
- return runtimeModel;
1386
- }
1387
- getRuntimeContext() {
1388
- const runtimeContext = this.runtimeService.runtimeContext;
1389
- if (!runtimeContext) {
1390
- throw new Error('Runtime context not initialized');
1391
- }
1392
- return runtimeContext;
1393
- }
1394
- get state$() {
1395
- return this.configurationState.asObservable();
1396
- }
1397
- get stateSnapshot() {
1398
- return this.configurationState.value;
1399
- }
1400
- get previousStateSnapshot() {
1401
- return this.previousConfigurationState.value;
1402
- }
1403
- get contextSnapshot() {
1404
- return this.contextService.resolve();
1405
- }
1406
- get context$() {
1407
- return this.contextService.resolve$();
1408
- }
1409
- get charges$() {
1410
- return this.configurationState.pipe(map(state => state?.charges ?? {}));
1411
- }
1412
- get chargesSnapshot() {
1413
- return this.configurationState.value?.charges ?? {};
1414
- }
1415
- get pricePlans$() {
1416
- return this.configurationState.pipe(map(state => state?.pricePlans ?? {}));
1417
- }
1418
- get pricePlansSnapshot() {
1419
- return this.configurationState.value?.pricePlans ?? {};
1420
- }
1421
- get procedureContext$() {
1422
- return this.configurationState.pipe(map(state => state?.procedureContext ?? {}));
1423
- }
1424
- get procedureContextSnapshot() {
1425
- return this.configurationState.value?.procedureContext ?? {};
1426
- }
1427
- configure() {
1428
- return this.configureRequest$(this.generateRequest());
1429
- }
1430
- configureRequest$(configurationRequest) {
1431
- const runtimeContext = this.getRuntimeContext();
1432
- const runtimeModel = this.getRuntimeModel();
1433
- const uiDefinitionProperties = this.getUIDefinitionProperties();
1434
- const mainPricingEnabled = runtimeContext.properties?.PricingEnabled;
1435
- const pricingEnabled = mainPricingEnabled ? mainPricingEnabled === 'true' : uiDefinitionProperties.pricingEnabled;
1436
- const customPriceApi = this.runtimeSettings.getConfigurationSettings()['CUSTOM_PRICE_API'];
1437
- this.isLoadingSubj$.next(true);
1438
- const configure$ = pricingEnabled && customPriceApi
1439
- ? this.configurationApiService.customConfigurePrice({ url: customPriceApi, configurationRequest, runtimeModel })
1440
- : this.configurationApiService.configureLineItem({
1441
- configurationRequest,
1442
- runtimeModel,
1443
- pricingEnabled,
1444
- });
1445
- return configure$.pipe(tap(result => {
1446
- this.contextService.update(result.context);
1447
- this.configurationState.next(result);
1448
- this.previousConfigurationState.next(cloneDeep(result));
1449
- if (result.deletedLineItems?.length) {
1450
- this.showInactiveProductsConfirmation();
1451
- }
1452
- this.configurableRamp = result.lineItem;
1453
- }), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => {
1454
- const resetState = this.previousConfigurationState.value;
1455
- if (resetState) {
1456
- this.previousConfigurationState.next(cloneDeep(resetState));
1457
- this.configurationState.next(resetState);
1458
- }
1459
- if (error.error) {
1460
- return extractErrorDetails(error.error).join('. ');
1461
- }
1462
- return error.message || JSON.stringify(error);
1463
- })), finalize$1(() => this.isLoadingSubj$.next(false)));
1464
- }
1465
- configureExternal$(props) {
1466
- return this.runtimeService
1467
- .init({ productId: props.productId, defaultQty: props.qty, attributesMap: props.attributesMap })
1468
- .pipe(switchMap$1(() => this.configure()), first(), catchError$1(error => {
1469
- this.messageService.add({ severity: ToastType.error, summary: error });
1470
- throw error;
1471
- }), finalize$1(() => this.reset()));
1472
- }
1473
- configureGuidedSelling$(data) {
1474
- return this.configurationApiService
1475
- .configureLineItem({
1476
- configurationRequest: getGuidedSellingConfigurationRequest(data, this.contextService.resolve()),
1477
- })
1478
- .pipe(catchError$1(error => {
1479
- if (error instanceof HttpErrorResponse) {
1480
- this.messageService.add({ severity: ToastType.error, summary: error.error.message || error.error });
1481
- }
1482
- throw error;
1483
- }));
1484
- }
1485
- generateRequest(lightMode = true) {
1486
- const lineItem = this.generateLineItem();
1487
- let request = {
1488
- lineItem,
1489
- mode: this.mode,
1490
- step: !this.configurationState.value?.lineItem ? RuntimeStep.START : RuntimeStep.UPDATE,
1491
- attributeDomainMode: 'ALL',
1492
- context: this.contextService.resolve(),
1493
- lineItems: this.quoteDraftService.quoteDraft?.currentState || [],
1494
- asset: this.getAsset(),
1495
- };
1496
- if (lightMode) {
1497
- request = ConfigurationTranslatorUtils.lightenConfigurationRequest(request);
1498
- }
1499
- return request;
1500
- }
1501
- generateLineItem() {
1502
- const runtimeContext = this.getRuntimeContext();
1503
- const uiDefinitionProperties = this.getUIDefinitionProperties();
1504
- let lineItem = this.configurableRamp;
1505
- if (!lineItem) {
1506
- const { initializationProps } = this.runtimeService ?? {};
1507
- lineItem = getDefaultLineItem(runtimeContext, uiDefinitionProperties, initializationProps?.defaultQty);
1508
- // Set default attributes
1509
- if (initializationProps?.attributesMap) {
1510
- const attributes = transform(initializationProps?.attributesMap, (acc, value, name) => acc.push({ name, value }), []);
1511
- lineItem = new LineItemWorker(lineItem).patchAttribute(attributes).li;
1512
- }
1513
- }
1514
- return lineItem;
1515
- }
1516
- getAsset() {
1517
- const lineItem = this.configurableRamp;
1518
- if (!lineItem) {
1519
- return;
1520
- }
1521
- const assetId = lineItem.assetId ?? lineItem.openOrderLineItemId;
1522
- return this.quoteDraftService.assetsState?.initialState.find(li => assetPredicateFn(li, assetId));
1523
- }
1524
- getUIDefinitionProperties() {
1525
- return {
1526
- ...(this.getRuntimeContext().uiDefinitionContainer?.source.properties ?? {}),
1527
- ...(this.runtimeService.uiDefinitionProperties ?? {}),
1528
- };
1529
- }
1530
- showInactiveProductsConfirmation() {
1531
- const confirmationConfig = {
1532
- title: ' ',
1533
- description: 'This quote contains inactive products. Do you want to remove them?',
1534
- primaryButtonLabel: 'Remove products',
1535
- secondaryButtonLabel: 'Back to Quote',
1536
- };
1537
- this.dialogService
1538
- .open(ConfirmationComponent, {
1539
- dismissableMask: false,
1540
- closeOnEscape: false,
1541
- closable: false,
1542
- showHeader: true,
1543
- header: `Inactive Products in Quote`,
1544
- width: '440px',
1545
- data: { confirmationConfig },
1546
- })
1547
- .onClose.subscribe(result => {
1548
- if (!result) {
1549
- const context = this.contextService.resolve();
1550
- window['VELO_BACK_FN'].apply(null, [context.headerId]);
1551
- }
1552
- });
1553
- }
1554
- }
1555
- ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, deps: [{ token: QuoteDraftService }, { token: ConfigurationRuntimeService }, { token: ContextService }, { token: i1.ConfigurationApiService }, { token: i5.MessageService }, { token: i6$1.DialogService }, { token: RuntimeSettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
1556
- ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
1557
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
1558
- type: Injectable
1559
- }], ctorParameters: function () { return [{ type: QuoteDraftService }, { type: ConfigurationRuntimeService }, { type: ContextService }, { type: i1.ConfigurationApiService }, { type: i5.MessageService }, { type: i6$1.DialogService }, { type: RuntimeSettingsService }]; } });
1560
-
1561
- class FlowUpdateService {
1562
- update(rootLineItems, updates, charges) {
1563
- let remainingUpdates = [...updates];
1564
- let currentLevel = rootLineItems;
1565
- while (currentLevel.length && remainingUpdates.length) {
1566
- currentLevel.forEach(li => {
1567
- const unhandledUpdates = [];
1568
- remainingUpdates.forEach(update => {
1569
- let updated = false;
1570
- switch (update.dataType) {
1571
- case 'LINEITEM':
1572
- updated = this.applyLineItemUpdate(li, update, charges);
1573
- break;
1574
- case 'CHARGE':
1575
- updated = this.applyChargeUpdate(li, update);
1576
- break;
1577
- case 'GROUP_CHARGE':
1578
- updated = this.applyChargeGroupUpdate(li, update);
1579
- break;
1580
- default:
1581
- // Unknown dataType. Do not try to handle it anymore
1582
- updated = true;
1583
- }
1584
- if (!updated) {
1585
- unhandledUpdates.push(update);
1586
- }
1587
- });
1588
- remainingUpdates = unhandledUpdates;
1589
- });
1590
- currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
1591
- }
1592
- }
1593
- delete(lineItems, id) {
1594
- const idsToRemove = [id];
1595
- const topLevelLineItem = lineItems.find(li => li.id === id);
1596
- if (topLevelLineItem) {
1597
- // find term-related line items (which are only top level)
1598
- // expired term line items won't be deleted
1599
- let foundTermLineItem = topLevelLineItem;
1600
- while (foundTermLineItem) {
1601
- foundTermLineItem = lineItems.find(li => foundTermLineItem && li.rampInstanceId === foundTermLineItem.id);
1602
- if (foundTermLineItem) {
1603
- idsToRemove.push(foundTermLineItem.id);
1604
- }
1605
- }
1606
- }
1607
- const filtered = lineItems.filter(lineItem => !idsToRemove.includes(lineItem.id));
1608
- return filtered.map(lineItem => new LineItemWorker(lineItem).remove(id).li);
1609
- }
1610
- applyLineItemUpdate(lineItem, update, charges) {
1611
- if (lineItem.id !== update.id) {
1612
- return false;
1613
- }
1614
- switch (update.attributeType) {
1615
- case 'QTY':
1616
- lineItem.qty = update.newValue;
1617
- break;
1618
- case 'EFFECTIVE_START_DATE':
1619
- lineItem.properties['StartDate'] = moment(update.newValue).format('YYYY-MM-DD');
1620
- break;
1621
- case 'END_DATE':
1622
- lineItem.properties['EndDate'] = moment(update.newValue).format('YYYY-MM-DD');
1623
- break;
1624
- case 'PRICE_ADJUSTMENT':
1625
- {
1626
- const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
1627
- if (charge) {
1628
- charge.priceAdjustment = update.newValue;
1629
- }
1630
- }
1631
- break;
1632
- case 'LIST_PRICE_ADJUSTMENT':
1633
- case 'MARGIN_ADJUSTMENT':
1634
- {
1635
- const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
1636
- if (charge) {
1637
- charge.listPriceAdjustment = update.newValue;
1638
- }
1639
- }
1640
- break;
1641
- case 'COST_ADJUSTMENT':
1642
- {
1643
- const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
1644
- if (charge) {
1645
- charge.costAdjustment = update.newValue;
1646
- }
1647
- }
1648
- break;
1649
- default:
1650
- throw new Error(`Not suppored AttributeType for LineItem update: ${update.attributeType}`);
1651
- }
1652
- return true;
871
+ return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
872
+ /*
873
+ Skip price calculation in case
874
+ 1. No actions in the request
875
+ 2. Initialization process execution (state not initialized yet)
876
+ */
877
+ const { state } = this.salesTransactionService;
878
+ if (!state || !request.actions?.length || !this.isInitialized()) {
879
+ return of(undefined);
880
+ }
881
+ else {
882
+ return this.flowConfiguration.calculate$(state);
883
+ }
884
+ }), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
885
+ this.executionInProgress$.next(false);
886
+ return throwError(() => e);
887
+ }));
1653
888
  }
1654
- applyChargeUpdate(lineItem, update) {
1655
- const foundCharge = lineItem.chargeItems.find(({ id }) => id === update.id);
1656
- if (!foundCharge) {
1657
- return false;
1658
- }
1659
- if (update.attributeType === 'PRICE_ADJUSTMENT') {
1660
- foundCharge.priceAdjustment = update.newValue;
1661
- }
1662
- else if (update.attributeType === 'LIST_PRICE_ADJUSTMENT') {
1663
- foundCharge.listPriceAdjustment = update.newValue;
1664
- }
1665
- else {
1666
- throw new Error(`Not suppored AttributeType for Charge Item update: ${update.attributeType}`);
889
+ executeStatelessActions(request) {
890
+ const state = this.salesTransactionService.state;
891
+ if (!state || !request.actions?.length) {
892
+ return;
1667
893
  }
1668
- return true;
894
+ let flowState = state;
895
+ request.actions.forEach(action => {
896
+ try {
897
+ flowState = this.executeActionScript(flowState, action) ?? flowState;
898
+ }
899
+ catch (e) {
900
+ console.error(e);
901
+ this.toastService.add({ severity: ToastType.error, summary: String(e) });
902
+ throw e;
903
+ }
904
+ });
905
+ this.salesTransactionService.setState(flowState);
1669
906
  }
1670
- applyChargeGroupUpdate(lineItem, update) {
1671
- const foundChargeGroup = ChargeGroupUtils.findChargeGroupById(update.id, lineItem);
1672
- if (!foundChargeGroup) {
1673
- return false;
1674
- }
1675
- if (update.attributeType === 'PRICE_ADJUSTMENT') {
1676
- foundChargeGroup.priceAdjustment = update.newValue;
1677
- }
1678
- else if (update.attributeType === 'LIST_PRICE_ADJUSTMENT') {
1679
- foundChargeGroup.listPriceAdjustment = update.newValue;
1680
- }
1681
- else {
1682
- throw new Error(`Not suppored AttributeType for Charge Group Item update: ${update.attributeType}`);
907
+ executeStatelessSelectors(request) {
908
+ if (!this.salesTransactionService.state) {
909
+ throw 'State is not initialized';
1683
910
  }
1684
- return true;
1685
- }
1686
- }
1687
- FlowUpdateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1688
- FlowUpdateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService });
1689
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService, decorators: [{
1690
- type: Injectable
1691
- }] });
1692
-
1693
- class FlowConfigurationService {
1694
- constructor(proceduresApiService, contextService, quoteDraftService, updateService, configurationService, flowInfoService) {
1695
- this.proceduresApiService = proceduresApiService;
1696
- this.contextService = contextService;
1697
- this.quoteDraftService = quoteDraftService;
1698
- this.updateService = updateService;
1699
- this.configurationService = configurationService;
1700
- this.flowInfoService = flowInfoService;
1701
- this.updatedSubj$ = new Subject();
1702
- this.updated$ = this.updatedSubj$.asObservable();
1703
- }
1704
- calculate$(quoteDraft) {
1705
- return this.extendedApply$(quoteDraft).pipe(tap$1(result => {
1706
- // sort the result current state based on the quote draft initial state
1707
- const initialStateIds = quoteDraft.initialState.map(lineItem => lineItem.integrationId);
1708
- result.currentState = result.currentState
1709
- .slice()
1710
- .sort((a, b) => initialStateIds.indexOf(a.integrationId) - initialStateIds.indexOf(b.integrationId));
1711
- this.quoteDraftService.updateQuoteDraft(result);
1712
- }), map$1(noop));
1713
- }
1714
- calculate(quoteDraft) {
1715
- this.calculate$(quoteDraft).subscribe();
911
+ const flowState = this.salesTransactionService.state;
912
+ return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
913
+ try {
914
+ result.selectors[key] = {
915
+ success: true,
916
+ result: this.executeSelectorScript(flowState, selector),
917
+ };
918
+ }
919
+ catch (e) {
920
+ console.error(e);
921
+ result.selectors[key] = {
922
+ success: false,
923
+ errorMessage: String(e),
924
+ };
925
+ }
926
+ return result;
927
+ }, { stateId: '', selectors: {} });
1716
928
  }
1717
- update$(updates) {
1718
- const quoteDraft = this.quoteDraftService.quoteDraft;
1719
- if (!quoteDraft) {
1720
- return of(null);
929
+ initProcessors$() {
930
+ const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
931
+ if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
932
+ // Skip initialization as backend will take processors from SF
933
+ return of(undefined);
1721
934
  }
1722
- return of([]).pipe(map$1(() => {
1723
- const updatedState = cloneDeep(quoteDraft.currentState);
1724
- this.updateService.update(updatedState, updates, quoteDraft.charges);
1725
- return updatedState;
1726
- }), switchMap(updatedState => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
1727
- }
1728
- update(updates) {
1729
- this.update$(updates).subscribe();
1730
- }
1731
- revert$(lineItemId) {
1732
- const quoteDraft = this.quoteDraftService.quoteDraft;
1733
- const initialCurrentState = this.quoteDraftService.getInitialCurrentState();
1734
- const currentState = this.quoteDraftService.currentState;
1735
- const currentLineItemIndex = currentState.findIndex(({ id }) => id === lineItemId);
1736
- const currentLineItem = currentState[currentLineItemIndex];
1737
- const initialLineItem = initialCurrentState.find(({ integrationId }) => integrationId === currentLineItem?.integrationId);
1738
- if (!quoteDraft || !currentLineItem || !initialLineItem) {
1739
- return of(null);
935
+ const owners$ = Object.values(this.flowInfoService.templates)
936
+ .map(template => {
937
+ if (!template) {
938
+ return;
939
+ }
940
+ const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
941
+ return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
942
+ const processorsMap = processors.reduce((acc, p) => {
943
+ acc[p.apiName] = p;
944
+ return acc;
945
+ }, {});
946
+ this.processors[template.id] = processorsMap;
947
+ }));
948
+ })
949
+ .filter(isDefined);
950
+ if (!owners$.length) {
951
+ return of(undefined);
1740
952
  }
1741
- const updatedState = cloneDeep(currentState);
1742
- updatedState.splice(currentLineItemIndex, 1, initialLineItem);
1743
- return of([]).pipe(tap$1(() => {
1744
- this.quoteDraftService.setCurrentLineItemState(updatedState);
1745
- }), switchMap(() => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
953
+ return forkJoin(owners$).pipe(map(noop));
1746
954
  }
1747
- revert(lineItemId) {
1748
- this.revert$(lineItemId).subscribe();
1749
- }
1750
- delete$(ids) {
1751
- const quoteDraft = this.quoteDraftService.quoteDraft;
1752
- const currentState = this.quoteDraftService.currentState;
1753
- if (!quoteDraft) {
1754
- return of(null);
955
+ executeActionScript(request, executable) {
956
+ const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
957
+ if (!configurationProcessor?.script) {
958
+ const scope = this.getScopeByOwnerId(executable.ownerId);
959
+ const scopeText = scope ? ` in ${scope}` : '';
960
+ throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
1755
961
  }
1756
- return of([]).pipe(map$1(() => ids.reduce((result, id) => this.updateService.delete(result, id), currentState)), switchMap(updatedState => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
1757
- }
1758
- delete(ids) {
1759
- this.delete$(ids).subscribe();
962
+ return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
1760
963
  }
1761
- addTerm$(term) {
1762
- const quoteDraft = this.quoteDraftService.quoteDraft;
1763
- if (!quoteDraft) {
1764
- return of(null);
964
+ executeSelectorScript(request, executable) {
965
+ const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
966
+ if (!configurationProcessor?.script) {
967
+ const scope = this.getScopeByOwnerId(executable.ownerId);
968
+ const scopeText = scope ? ` in ${scope}` : '';
969
+ throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
1765
970
  }
1766
- const updatedState = [...quoteDraft.currentState, term];
1767
- return of([]).pipe(switchMap(() => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
971
+ return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
1768
972
  }
1769
- addToCart$(props) {
1770
- const quoteDraft = this.quoteDraftService.quoteDraft;
1771
- if (!quoteDraft) {
1772
- return of(null);
973
+ executeProcessorScript(request, configurationProcessor, inputData) {
974
+ const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
975
+ let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
976
+ if (!functionToExecute) {
977
+ const script = `${configurationProcessor.script}\nreturn transform;`;
978
+ const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
979
+ functionToExecute = new Function(script + sourceMap)();
980
+ this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
1773
981
  }
1774
- return this.configurationService.configureExternal$(props).pipe(map$1(lineItem => {
1775
- const model = this.configurationService.getRuntimeModel();
1776
- const split = model?.types.find(type => type.name === lineItem.type)?.split ?? false;
1777
- const lineItems = multiplyLineItems(lineItem, props.qty ?? 1, split);
1778
- return [...quoteDraft.currentState, ...lineItems];
1779
- }), switchMap(updatedState => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
1780
- }
1781
- get() {
1782
- return this.quoteDraftService.quoteDraft$.pipe(map$1(() => this.quoteDraftService.currentState), shareReplay$1());
1783
- }
1784
- getSnapshot() {
1785
- return this.quoteDraftService?.currentState.slice() ?? [];
1786
- }
1787
- get charges$() {
1788
- return this.quoteDraftService.quoteDraft$.pipe(map$1(({ charges }) => charges));
1789
- }
1790
- get pricePlans$() {
1791
- return this.quoteDraftService.quoteDraft$.pipe(map$1(({ pricePlans }) => pricePlans));
1792
- }
1793
- get activeMetrics$() {
1794
- return this.quoteDraftService.quoteDraft$.pipe(map$1(({ activeMetrics }) => activeMetrics));
1795
- }
1796
- get chargesSnapshot() {
1797
- return this.quoteDraftService.quoteDraft?.charges ?? {};
1798
- }
1799
- get pricePlansSnapshot() {
1800
- return this.quoteDraftService.quoteDraft?.pricePlans ?? {};
1801
- }
1802
- get activeMetricsSnapshot() {
1803
- return this.quoteDraftService.quoteDraft?.activeMetrics ?? [];
1804
- }
1805
- get contextSnapshot() {
1806
- return this.contextService.resolve();
1807
- }
1808
- get context$() {
1809
- return this.contextService.resolve$();
982
+ return functionToExecute({
983
+ request,
984
+ inputData,
985
+ flowStore: this.flowStore,
986
+ });
1810
987
  }
1811
- handleErrorAndBounceBack() {
1812
- return (source$) => {
1813
- return source$.pipe(catchError(error => {
1814
- console.error(error);
1815
- // bounce back if configuration call has failed
1816
- const quoteDraft = this.quoteDraftService.quoteDraft;
1817
- if (quoteDraft) {
1818
- this.quoteDraftService.updateQuoteDraft(quoteDraft);
1819
- this.updatedSubj$.next();
1820
- }
1821
- return throwError(() => error);
1822
- }));
1823
- };
988
+ generateRequestId(scope, selectorName, inputData) {
989
+ const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
990
+ return `${scope}/${selectorName}/${inputDataHash}`;
1824
991
  }
1825
- extendedApply$(quoteDraft) {
1826
- const request = { ...quoteDraft };
1827
- const procedureName = this.flowInfoService.flow?.properties.procedureName;
1828
- if (procedureName) {
1829
- request.procedureName = procedureName;
992
+ checkStatefulChanges(requestId, selectorResult) {
993
+ if (this.trackedStatefulChangesMap.has(requestId)) {
994
+ if (!this.initialStatefulData[requestId]) {
995
+ this.initialStatefulData[requestId] = selectorResult;
996
+ }
997
+ const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
998
+ this.trackedStatefulChangesMap.set(requestId, hasChanges);
1830
999
  }
1831
- return this.proceduresApiService.apply$(request);
1832
1000
  }
1833
1001
  }
1834
- FlowConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, deps: [{ token: i1.ProceduresApiService }, { token: ContextService }, { token: QuoteDraftService }, { token: FlowUpdateService }, { token: ConfigurationService }, { token: FlowInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
1835
- FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
1836
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
1002
+ FlowStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, deps: [{ token: FlowConfigurationService }, { token: FlowInfoService }, { token: i1.FlowStateApiService }, { token: i4.ConfigurationProcessorsApiService }, { token: i4.SalesTransactionApiService }, { token: SalesTransactionService }, { token: i6.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1003
+ FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
1004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
1837
1005
  type: Injectable
1838
- }], ctorParameters: function () { return [{ type: i1.ProceduresApiService }, { type: ContextService }, { type: QuoteDraftService }, { type: FlowUpdateService }, { type: ConfigurationService }, { type: FlowInfoService }]; } });
1839
-
1840
- class FlowConfigurationModule {
1841
- }
1842
- FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1843
- FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
1844
- FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService, FlowUpdateService], imports: [ApiModule] });
1845
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
1846
- type: NgModule,
1847
- args: [{
1848
- imports: [ApiModule],
1849
- providers: [FlowConfigurationService, FlowUpdateService],
1850
- }]
1851
- }] });
1006
+ }], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i1.FlowStateApiService }, { type: i4.ConfigurationProcessorsApiService }, { type: i4.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
1007
+ type: Optional
1008
+ }, {
1009
+ type: Inject,
1010
+ args: [FLOW_CUSTOMIZATION]
1011
+ }] }]; } });
1852
1012
 
1853
1013
  class FlowStateConfigurationService {
1854
- constructor(flowInfoService, flowConfigurationService, flowStateApiService, flowStateService) {
1014
+ constructor(flowInfoService, flowStateService) {
1855
1015
  this.flowInfoService = flowInfoService;
1856
- this.flowConfigurationService = flowConfigurationService;
1857
- this.flowStateApiService = flowStateApiService;
1858
1016
  this.flowStateService = flowStateService;
1859
- this.configurationStateId$ = new BehaviorSubject(null);
1860
- }
1861
- get configurationStateId() {
1862
- return this.configurationStateId$.value;
1863
1017
  }
1864
1018
  addToCart$(props) {
1865
1019
  let request$;
@@ -1870,26 +1024,22 @@ class FlowStateConfigurationService {
1870
1024
  request$ = of();
1871
1025
  }
1872
1026
  else {
1873
- const lineItem = generateConfigurationLineItem(props, props.qty);
1874
- request$ = this.flowStateApiService.newConfiguration(stateId, { lineItem }).pipe(tap$1(r => this.configurationStateId$.next(r.stateId)), switchMap(() => {
1875
- if (!this.configurationStateId) {
1876
- return of();
1877
- }
1878
- return this.flowStateApiService.saveConfiguration(stateId, this.configurationStateId).pipe(tap$1(() => this.configurationStateId$.next(null)), map$1(noop));
1879
- }));
1027
+ // TODO: Implement
1028
+ request$ = of();
1880
1029
  }
1881
1030
  }
1882
1031
  else {
1883
- request$ = this.flowConfigurationService.addToCart$(props).pipe(map$1(noop));
1032
+ // TODO: Implement
1033
+ request$ = of();
1884
1034
  }
1885
- return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map$1(noop));
1035
+ return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
1886
1036
  }
1887
1037
  }
1888
- FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.FlowStateApiService }, { token: FlowStateService }], target: i0.ɵɵFactoryTarget.Injectable });
1038
+ FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token: FlowStateService }], target: i0.ɵɵFactoryTarget.Injectable });
1889
1039
  FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
1890
1040
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
1891
1041
  type: Injectable
1892
- }], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.FlowStateApiService }, { type: FlowStateService }]; } });
1042
+ }], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }]; } });
1893
1043
 
1894
1044
  class IntegrationState {
1895
1045
  constructor() {
@@ -1909,12 +1059,12 @@ class IntegrationState {
1909
1059
  this.action$.next(action);
1910
1060
  }
1911
1061
  listen$(actionType) {
1912
- return this.action$.pipe(filter$1(action => action.type === actionType), map$1(action => action.payload));
1062
+ return this.action$.pipe(filter$1(action => action.type === actionType), map(action => action.payload));
1913
1063
  }
1914
1064
  listenAll$() {
1915
1065
  return this.action$.asObservable();
1916
1066
  }
1917
- clear() {
1067
+ reset() {
1918
1068
  this.stateSubj$.next({});
1919
1069
  }
1920
1070
  }
@@ -1934,12 +1084,12 @@ class ProductImagesService {
1934
1084
  this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
1935
1085
  this.fetchProductImage(productId);
1936
1086
  }
1937
- return this.imagesMap$.pipe(map$1(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
1087
+ return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
1938
1088
  }
1939
1089
  fetchProductImage(productId) {
1940
1090
  this.productApiService
1941
1091
  .fetchImage$(productId)
1942
- .pipe(map$1(file => URL.createObjectURL(file)), catchError(() => of('')), tap$1(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
1092
+ .pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
1943
1093
  .subscribe();
1944
1094
  }
1945
1095
  }
@@ -1949,153 +1099,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
1949
1099
  type: Injectable
1950
1100
  }], ctorParameters: function () { return [{ type: i1.ProductApiService }]; } });
1951
1101
 
1952
- class RuntimeContextService {
1953
- constructor(configurationApiService) {
1954
- this.configurationApiService = configurationApiService;
1955
- }
1956
- getRuntimeContext(productId, offeringId) {
1957
- return this.configurationApiService.getRuntimeDataByProductId(productId, offeringId).pipe(map(runtimeData => {
1958
- const uiDefinitionContainer = this.getUIDefinitionContainer(runtimeData);
1959
- const runtimeModel = RuntimeModel.create(runtimeData.types, runtimeData.products);
1960
- const { productName, properties } = Array.from(runtimeModel.components.values()).find(c => c.productId === productId) ?? {};
1961
- const uiDefinitionProperties = uiDefinitionContainer?.source.properties;
1962
- return {
1963
- modelId: runtimeData.modelId,
1964
- uiDefinitionContainer: uiDefinitionContainer,
1965
- runtimeModel: runtimeModel,
1966
- runtimeMode: RuntimeMode.PROD,
1967
- productId: productId,
1968
- productType: properties?.['displayName'] || productName,
1969
- offeringId: offeringId,
1970
- properties: {
1971
- PricingEnabled: uiDefinitionProperties?.pricingEnabled ? 'true' : 'false',
1972
- PriceListId: uiDefinitionProperties?.priceList,
1973
- },
1974
- };
1975
- }));
1976
- }
1977
- getUIDefinitionContainer(runtimeData) {
1978
- const containers = runtimeData.uiDefinitions.filter(container => isNotLegacyUIDefinition(container.source));
1979
- return containers.find(container => container.source.primary) ?? containers[0];
1980
- }
1981
- }
1982
- RuntimeContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, deps: [{ token: i1.ConfigurationApiService }], target: i0.ɵɵFactoryTarget.Injectable });
1983
- RuntimeContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService });
1984
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, decorators: [{
1985
- type: Injectable
1986
- }], ctorParameters: function () { return [{ type: i1.ConfigurationApiService }]; } });
1987
-
1988
- class ConfigurationRuntimeService {
1989
- constructor(apiService, contextService, runtimeContextService) {
1990
- this.apiService = apiService;
1991
- this.contextService = contextService;
1992
- this.runtimeContextService = runtimeContextService;
1993
- this._isInitialized = false;
1994
- this.uiDefinitionProperties = {};
1995
- }
1996
- reset() {
1997
- this._isInitialized = false;
1998
- this._runtimeContext = undefined;
1999
- this.initializationProps = undefined;
2000
- this.uiDefinitionProperties = {};
2001
- }
2002
- initTestMode(uiDefinitionContainer) {
2003
- this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
2004
- const uiDefinitionExternals = uiDefinitionContainer.source.externals ?? {};
2005
- return combineLatest([
2006
- this.apiService.getRuntimeDataByModelId(uiDefinitionContainer.modelId),
2007
- this.contextService.initTestMode(),
2008
- ]).pipe(first(), map(([runtimeData, context]) => {
2009
- this.contextService.update({
2010
- properties: {
2011
- ...this.runtimeContext?.properties,
2012
- ...context.properties,
2013
- ModelId: uiDefinitionContainer.modelId,
2014
- PricingEnabled: this.uiDefinitionProperties.pricingEnabled ? 'true' : 'false',
2015
- PriceListId: this.uiDefinitionProperties.priceList,
2016
- offeringId: this.uiDefinitionProperties.offeringId,
2017
- ...uiDefinitionExternals,
2018
- },
2019
- });
2020
- this._runtimeContext = {
2021
- modelId: uiDefinitionContainer.modelId,
2022
- runtimeModel: RuntimeModel.create(runtimeData.types, runtimeData.products),
2023
- runtimeMode: RuntimeMode.TEST,
2024
- uiDefinitionContainer,
2025
- };
2026
- return this._runtimeContext;
2027
- }), tap(() => (this._isInitialized = true)));
2028
- }
2029
- init(props) {
2030
- this.initializationProps = props;
2031
- const context = this.contextService.resolve();
2032
- return this.runtimeContextService.getRuntimeContext(props.productId, props.offeringId).pipe(tap(runtimeContext => {
2033
- this.uiDefinitionProperties = runtimeContext.uiDefinitionContainer?.source.properties ?? {};
2034
- const { PriceListId } = context.properties ?? {};
2035
- const mergeContext = {
2036
- ...runtimeContext,
2037
- properties: {
2038
- ...runtimeContext.properties,
2039
- ...context.properties,
2040
- PricingEnabled: PriceListId ? 'true' : 'false',
2041
- },
2042
- };
2043
- this.id15to18('AccountId', mergeContext.properties);
2044
- this._runtimeContext = mergeContext;
2045
- if (context.properties && this._runtimeContext.properties?.StartDate) {
2046
- this.contextService.update({
2047
- properties: {
2048
- ...this._runtimeContext.properties,
2049
- ...context.properties,
2050
- },
2051
- });
2052
- }
2053
- return this._runtimeContext;
2054
- }), tap(() => (this._isInitialized = true)));
2055
- }
2056
- overrideUIDefinition(uiDefinitionContainer) {
2057
- if (!this._runtimeContext) {
2058
- return;
2059
- }
2060
- this._runtimeContext.uiDefinitionContainer = uiDefinitionContainer;
2061
- this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
2062
- }
2063
- id15to18(propertyName, source) {
2064
- if (!source) {
2065
- return;
2066
- }
2067
- const value = source[propertyName];
2068
- if (typeof value === 'string' && value.length === 15) {
2069
- source[propertyName] = SalesforceIdUtils.generateId18FromId15(value);
2070
- }
2071
- }
2072
- get isInitialized() {
2073
- return this._isInitialized;
2074
- }
2075
- get runtimeModel() {
2076
- return this.runtimeContext?.runtimeModel;
2077
- }
2078
- get runtimeContext() {
2079
- return this._runtimeContext;
2080
- }
2081
- }
2082
- ConfigurationRuntimeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, deps: [{ token: i1.ConfigurationApiService }, { token: ContextService }, { token: RuntimeContextService }], target: i0.ɵɵFactoryTarget.Injectable });
2083
- ConfigurationRuntimeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService });
2084
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, decorators: [{
2085
- type: Injectable
2086
- }], ctorParameters: function () { return [{ type: i1.ConfigurationApiService }, { type: ContextService }, { type: RuntimeContextService }]; } });
2087
-
2088
1102
  class ConfigurationStateService {
2089
- constructor(configurationRuntimeService, configurationService, quoteDraftService, toastService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, quoteApiService) {
1103
+ constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService) {
2090
1104
  this.configurationRuntimeService = configurationRuntimeService;
2091
1105
  this.configurationService = configurationService;
2092
- this.quoteDraftService = quoteDraftService;
2093
- this.toastService = toastService;
2094
1106
  this.flowStateService = flowStateService;
2095
1107
  this.flowInfoService = flowInfoService;
2096
1108
  this.flowConfigurationService = flowConfigurationService;
2097
1109
  this.flowStateApiService = flowStateApiService;
2098
- this.quoteApiService = quoteApiService;
1110
+ this.salesTransactionService = salesTransactionService;
1111
+ this.salesTransactionApiService = salesTransactionApiService;
1112
+ this.toastService = toastService;
2099
1113
  this.isInitialized$ = new BehaviorSubject(false);
2100
1114
  this.canceledConfiguration$ = new Subject();
2101
1115
  this.NOT_INITIALIZED = Symbol();
@@ -2119,9 +1133,9 @@ class ConfigurationStateService {
2119
1133
  request$ = this.initStateful$();
2120
1134
  }
2121
1135
  else {
2122
- request$ = this.initStateless$();
1136
+ request$ = this.configurationService.init$();
2123
1137
  }
2124
- return request$.pipe(finalize(() => {
1138
+ return request$.pipe(take(1), tap(() => {
2125
1139
  this.isInitialized$.next(true);
2126
1140
  this.canceledConfiguration$ = new Subject();
2127
1141
  }));
@@ -2135,10 +1149,11 @@ class ConfigurationStateService {
2135
1149
  this.configurationStore = {};
2136
1150
  this.executedFunctions = {};
2137
1151
  this.configurationService.reset();
1152
+ this.configurationRuntimeService.reset();
2138
1153
  }
2139
1154
  execute$(exec) {
2140
1155
  const request = this.execToRequest(exec);
2141
- return this.executeRequest$(request).pipe(map$1(result => {
1156
+ return this.executeRequest$(request).pipe(map(result => {
2142
1157
  // Keep only requested results
2143
1158
  const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
2144
1159
  if (exec.selectors?.[requestId]) {
@@ -2160,7 +1175,7 @@ class ConfigurationStateService {
2160
1175
  }
2161
1176
  // prevent parallel configuration requests in stateless mode
2162
1177
  if (!this.statelessExecutionRequest$) {
2163
- this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay$1(), take$1(1), finalize(() => (this.statelessExecutionRequest$ = null)));
1178
+ this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
2164
1179
  }
2165
1180
  return this.statelessExecutionRequest$;
2166
1181
  }
@@ -2174,7 +1189,7 @@ class ConfigurationStateService {
2174
1189
  },
2175
1190
  },
2176
1191
  });
2177
- return this.executeRequest$(request).pipe(map$1(response => response.selectors[requestId]));
1192
+ return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
2178
1193
  }
2179
1194
  subscribe$(selectorName, inputData = {}, options) {
2180
1195
  const requestId = UUID.UUID();
@@ -2197,56 +1212,42 @@ class ConfigurationStateService {
2197
1212
  this.executeRequest$(request).subscribe();
2198
1213
  }
2199
1214
  }
2200
- return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map$1(data => data), distinctUntilChanged(), finalize(() => {
1215
+ return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
2201
1216
  if (!this.subscriptions[requestId]?.data$.observed) {
2202
1217
  delete this.subscriptions[requestId];
2203
1218
  }
2204
1219
  }), takeUntil(this.canceledConfiguration$));
2205
1220
  }
2206
- saveConfiguration(flow) {
1221
+ saveConfiguration() {
2207
1222
  if (this.isStatefulConfiguration) {
2208
- return this.flowStateApiService
2209
- .saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '')
2210
- .pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map$1(() => r))));
1223
+ return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
1224
+ }
1225
+ const state = this.salesTransactionService.state;
1226
+ if (!state) {
1227
+ return of({ id: '' });
1228
+ }
1229
+ const { standalone } = this.flowInfoService.flow.properties;
1230
+ if (standalone) {
1231
+ return this.salesTransactionApiService.upsert(state);
1232
+ }
1233
+ const salesTransaction = this.salesTransactionService.state;
1234
+ const configurationRoot = this.configurationService.root;
1235
+ if (!salesTransaction || !configurationRoot) {
1236
+ return of({ id: '' });
1237
+ }
1238
+ const isNewTransactionItem = salesTransaction.salesTransactionItems.every(li => li.id !== configurationRoot.id);
1239
+ let salesTransactionItems;
1240
+ if (isNewTransactionItem) {
1241
+ salesTransactionItems = [...salesTransaction.salesTransactionItems, configurationRoot];
2211
1242
  }
2212
1243
  else {
2213
- if (!flow) {
2214
- const quoteDraft = this.quoteDraftService.quoteDraft;
2215
- if (!quoteDraft) {
2216
- return of({ quoteId: '' });
2217
- }
2218
- const rootLineItem = this.configurationService.getSnapshot();
2219
- const asset = this.configurationService.getAsset();
2220
- const currentState = rootLineItem ? [rootLineItem] : [];
2221
- const initialState = asset ? [asset] : [];
2222
- return this.quoteApiService.upsertQuote({ ...quoteDraft, currentState, initialState });
2223
- }
2224
- else {
2225
- const quoteDraft = this.quoteDraftService.quoteDraft;
2226
- const lineItem = this.configurationService.getSnapshot();
2227
- if (!quoteDraft || !lineItem) {
2228
- return of({ quoteId: '' });
2229
- }
2230
- const isNewLineItem = quoteDraft.currentState.every(li => li.id !== lineItem.id);
2231
- let currentState;
2232
- if (isNewLineItem) {
2233
- currentState = [...quoteDraft.currentState, lineItem];
2234
- }
2235
- else {
2236
- currentState = quoteDraft.currentState.map(li => (li.id === lineItem.id ? lineItem : li));
2237
- }
2238
- const asset = this.configurationService.getAsset();
2239
- const initialState = [...(this.quoteDraftService.quoteDraft?.initialState ?? [])];
2240
- if (asset) {
2241
- if (!initialState.some(li => li.id === asset.id)) {
2242
- initialState.push(asset);
2243
- }
2244
- }
2245
- return this.flowConfigurationService
2246
- .calculate$({ ...quoteDraft, currentState, initialState })
2247
- .pipe(map$1(() => ({ quoteId: '' })));
2248
- }
1244
+ salesTransactionItems = salesTransaction.salesTransactionItems.map(ti => ti.id === configurationRoot.id ? configurationRoot : ti);
2249
1245
  }
1246
+ const newState = {
1247
+ ...salesTransaction,
1248
+ salesTransactionItems,
1249
+ };
1250
+ return this.flowConfigurationService.calculate$(newState).pipe(map(() => ({ id: '' })));
2250
1251
  }
2251
1252
  cancelConfiguration() {
2252
1253
  if (!this.isInitialized$.value) {
@@ -2265,36 +1266,32 @@ class ConfigurationStateService {
2265
1266
  return this.flowInfoService.flow?.properties.stateful ?? false;
2266
1267
  }
2267
1268
  initStateful$() {
2268
- this.ownerId = this.configurationRuntimeService.runtimeContext?.uiDefinitionContainer?.id ?? '';
2269
- const lineItemId = this.configurationRuntimeService.runtimeContext?.properties?.lineItemId;
2270
- if (!this.flowStateService.stateId) {
1269
+ this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
1270
+ const { productId, transactionItemId } = this.flowInfoService.context;
1271
+ if (!productId || !this.flowStateService.stateId) {
2271
1272
  return of(undefined);
2272
1273
  }
2273
- const container = this.configurationRuntimeService.runtimeContext?.uiDefinitionContainer;
2274
- const lineItem = this.configurationService.generateLineItem();
1274
+ const container = this.configurationRuntimeService.uiDefinitionContainer;
2275
1275
  let request$;
2276
- if (!lineItemId) {
1276
+ if (!transactionItemId) {
2277
1277
  request$ = this.flowStateApiService.newConfiguration(this.flowStateService.stateId, {
2278
- lineItem,
1278
+ transactionItem: generateTransactionItem(productId),
2279
1279
  actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
2280
1280
  selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
2281
1281
  });
2282
1282
  }
2283
1283
  else {
2284
1284
  request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
2285
- lineItemId,
1285
+ transactionItemId,
2286
1286
  actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
2287
1287
  selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
2288
1288
  });
2289
1289
  }
2290
- return request$.pipe(map$1(r => {
1290
+ return request$.pipe(map(r => {
2291
1291
  this.stateId = r.stateId;
2292
1292
  return undefined;
2293
1293
  }));
2294
1294
  }
2295
- initStateless$() {
2296
- return this.configurationService.configure().pipe(map$1(() => undefined));
2297
- }
2298
1295
  execToRequest(exec) {
2299
1296
  return {
2300
1297
  actions: exec.actions?.map(action => ({
@@ -2334,37 +1331,35 @@ class ConfigurationStateService {
2334
1331
  else {
2335
1332
  execution$ = this.executeStateless$(fullRequest);
2336
1333
  }
2337
- return execution$.pipe(tap$1(result => this.handleSelectorsResponse(result.selectors)));
1334
+ return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
2338
1335
  }
2339
1336
  executeStateless$(request) {
2340
1337
  this.executionInProgress$.next(true);
2341
- return of(undefined).pipe(switchMap(() => {
1338
+ return this.configurationService.state$.pipe(switchMap(state => {
2342
1339
  // Apply actions and execute configuration/price call
2343
1340
  // No need to run configuration if no actions in the request
2344
1341
  if (!request.actions?.length) {
2345
1342
  return of(undefined);
2346
1343
  }
2347
- let configurationRequest = this.configurationService.generateRequest(false);
2348
1344
  request.actions.forEach(action => {
2349
- configurationRequest = this.executeActionScript(configurationRequest, action) ?? configurationRequest;
1345
+ state = this.executeActionScript(state, action) ?? state;
2350
1346
  });
2351
- configurationRequest = ConfigurationTranslatorUtils.lightenConfigurationRequest(configurationRequest);
2352
- return this.configurationService.configureRequest$(configurationRequest);
2353
- }), map$1(() => {
1347
+ return this.configurationService.configureRequest$(state);
1348
+ }), map(() => {
2354
1349
  // Run selectors and apply them to the state
2355
- const configurationState = this.configurationService.stateSnapshot;
1350
+ const configurationState = this.configurationService.state;
2356
1351
  if (!configurationState) {
2357
1352
  return { stateId: '', selectors: {} };
2358
1353
  }
2359
1354
  return this.runStatelessSelectors(request, configurationState);
2360
- }), tap$1(() => this.executionInProgress$.next(false)), catchError(error => {
2361
- const configurationState = this.configurationService.previousStateSnapshot;
1355
+ }), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
1356
+ const configurationState = this.configurationService.previousState;
2362
1357
  if (configurationState) {
2363
1358
  const selectorsResult = this.runStatelessSelectors(request, configurationState);
2364
1359
  this.handleSelectorsResponse(selectorsResult.selectors);
2365
1360
  }
2366
1361
  this.executionInProgress$.next(false);
2367
- if (!this.configurationRuntimeService.uiDefinitionProperties.suppressToastMessages) {
1362
+ if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
2368
1363
  this.toastService.add({ severity: ToastType.error, summary: String(error) });
2369
1364
  }
2370
1365
  return throwError(() => error);
@@ -2385,21 +1380,21 @@ class ConfigurationStateService {
2385
1380
  };
2386
1381
  this.executionInProgress$.next(true);
2387
1382
  return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
2388
- }), tap$1(({ stateId }) => (this.stateId = stateId)), share(), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
1383
+ }), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
2389
1384
  this.executionInProgress$.next(false);
2390
1385
  return throwError(() => e);
2391
1386
  }));
2392
1387
  }
2393
1388
  executeStateful$(request) {
2394
- return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
1389
+ return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take(1), switchMap(() =>
2395
1390
  // make sure stream switches to statefulExecutionRequest$ before pushing an execution request
2396
1391
  combineLatest([
2397
1392
  this.statefulExecutionRequest$,
2398
- of(undefined).pipe(tap$1(() => this.statefulRequestStream$.next(request))),
2399
- ])), map$1(([response]) => response), take$1(1));
1393
+ of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
1394
+ ])), map(([response]) => response), take(1));
2400
1395
  }
2401
1396
  executeActionScript(request, processor) {
2402
- const { actions } = this.configurationRuntimeService.runtimeContext?.uiDefinitionContainer ?? {};
1397
+ const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
2403
1398
  const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
2404
1399
  if (!configurationProcessor?.script) {
2405
1400
  throw `ConfigurationProcessor ${processor.apiName} not found`;
@@ -2407,7 +1402,7 @@ class ConfigurationStateService {
2407
1402
  return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
2408
1403
  }
2409
1404
  executeSelectorScript(request, processor) {
2410
- const { selectors } = this.configurationRuntimeService.runtimeContext?.uiDefinitionContainer ?? {};
1405
+ const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
2411
1406
  const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
2412
1407
  if (!configurationProcessor?.script) {
2413
1408
  throw `ConfigurationProcessor ${processor.apiName} not found`;
@@ -2448,25 +1443,63 @@ class ConfigurationStateService {
2448
1443
  }, { stateId: '', selectors: {} });
2449
1444
  }
2450
1445
  }
2451
- ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token: QuoteDraftService }, { token: i6.ToastService }, { token: FlowStateService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.FlowStateApiService }, { token: i1.QuoteApiService }], target: i0.ɵɵFactoryTarget.Injectable });
1446
+ ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token: FlowStateService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.FlowStateApiService }, { token: SalesTransactionService }, { token: i4.SalesTransactionApiService }, { token: i6.ToastService }], target: i0.ɵɵFactoryTarget.Injectable });
2452
1447
  ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
2453
1448
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
2454
1449
  type: Injectable
2455
- }], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type: QuoteDraftService }, { type: i6.ToastService }, { type: FlowStateService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.FlowStateApiService }, { type: i1.QuoteApiService }]; } });
1450
+ }], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type: FlowStateService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.FlowStateApiService }, { type: SalesTransactionService }, { type: i4.SalesTransactionApiService }, { type: i6.ToastService }]; } });
2456
1451
 
2457
1452
  class ConfigurationModule {
2458
1453
  }
2459
1454
  ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2460
1455
  ConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, imports: [ConfirmationDialogModule, ApiModule] });
2461
- ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [ConfigurationRuntimeService, RuntimeContextService, ConfigurationService, ConfigurationStateService], imports: [ConfirmationDialogModule, ApiModule] });
1456
+ ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [ConfigurationService, ConfigurationStateService, ConfigurationRuntimeService], imports: [ConfirmationDialogModule, ApiModule] });
2462
1457
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
2463
1458
  type: NgModule,
2464
1459
  args: [{
2465
1460
  imports: [ConfirmationDialogModule, ApiModule],
2466
- providers: [ConfigurationRuntimeService, RuntimeContextService, ConfigurationService, ConfigurationStateService],
1461
+ providers: [ConfigurationService, ConfigurationStateService, ConfigurationRuntimeService],
1462
+ }]
1463
+ }] });
1464
+
1465
+ class FlowConfigurationModule {
1466
+ }
1467
+ FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1468
+ FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
1469
+ FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
1470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
1471
+ type: NgModule,
1472
+ args: [{
1473
+ imports: [ApiModule],
1474
+ providers: [FlowConfigurationService],
2467
1475
  }]
2468
1476
  }] });
2469
1477
 
1478
+ class CatalogProductsService {
1479
+ constructor() {
1480
+ this.stateSubj$ = new BehaviorSubject(null);
1481
+ this.state$ = this.stateSubj$.asObservable().pipe(filter$1(isDefined));
1482
+ }
1483
+ get state() {
1484
+ return this.stateSubj$.getValue();
1485
+ }
1486
+ reset() {
1487
+ this.stateSubj$.next(null);
1488
+ }
1489
+ setState(state) {
1490
+ this.stateSubj$.next(state);
1491
+ }
1492
+ }
1493
+ CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1494
+ CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
1495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
1496
+ type: Injectable
1497
+ }] });
1498
+
1499
+ const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
1500
+
1501
+ const UI_DEFINITION_VERSION = 3;
1502
+
2470
1503
  const DEFAULT_FORMATTING_SETTINGS = {
2471
1504
  currencySymbol: DEFAULT_CURRENCY_SYMBOL,
2472
1505
  decimalsCount: DEFAULT_DECIMALS_COUNT,
@@ -2480,14 +1513,14 @@ class SdkCoreModule {
2480
1513
  SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2481
1514
  SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
2482
1515
  SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
2483
- ContextService,
2484
1516
  FlowInfoService,
2485
- QuoteDraftService,
2486
1517
  ProductImagesService,
2487
1518
  IntegrationState,
2488
1519
  FlowStateService,
2489
1520
  FlowStateConfigurationService,
2490
1521
  RuntimeSettingsService,
1522
+ SalesTransactionService,
1523
+ CatalogProductsService,
2491
1524
  {
2492
1525
  provide: FORMATTING_SETTINGS_TOKEN,
2493
1526
  useExisting: RuntimeSettingsService,
@@ -2498,14 +1531,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
2498
1531
  args: [{
2499
1532
  imports: [ConfigurationModule, FlowConfigurationModule],
2500
1533
  providers: [
2501
- ContextService,
2502
1534
  FlowInfoService,
2503
- QuoteDraftService,
2504
1535
  ProductImagesService,
2505
1536
  IntegrationState,
2506
1537
  FlowStateService,
2507
1538
  FlowStateConfigurationService,
2508
1539
  RuntimeSettingsService,
1540
+ SalesTransactionService,
1541
+ CatalogProductsService,
2509
1542
  {
2510
1543
  provide: FORMATTING_SETTINGS_TOKEN,
2511
1544
  useExisting: RuntimeSettingsService,
@@ -2680,5 +1713,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
2680
1713
  * Generated bundle index. Do not edit.
2681
1714
  */
2682
1715
 
2683
- export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService, ContextService, DEFAULT_FORMATTING_SETTINGS, DatePipe, FLOW_CUSTOMIZATION, FORMATTING_SETTINGS_TOKEN, FlowConfigurationModule, FlowConfigurationService, FlowInfoService, FlowStateConfigurationService, FlowStateService, FlowUpdateService, IntegrationState, LineItemWorker, NumberPipe, PricePipe, ProductImagesService, QuoteDraftService, RuntimeMode, RuntimeOperation, RuntimeSettingsService, RuntimeStep, SdkCoreModule, SdkDirectivesModule, SdkPipesModule, UI_DEFINITION_VERSION, assetPredicateFn, extractMetadata, filterOutTechnicalAttributes, findLineItem, findLineItemWithComparator, generateConfigurationLineItem, generateLineItem, getAttributeValue, getAttributes, getDefaultLineItem, getGuidedSellingConfigurationRequest, getOriginParent, getRecommendedPrices, insertLineItem, isTechnicalAttribute, lineItem_utils as lineItemUtils, mapAttributes, multiplyLineItems, patchAttributes, recalculateCardinalityVariables, removeLineItem, replaceLineItem, upsertAttributes };
1716
+ export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService, DEFAULT_FORMATTING_SETTINGS, DatePipe, FLOW_CUSTOMIZATION, FORMATTING_SETTINGS_TOKEN, FlowConfigurationService, FlowInfoService, FlowStateConfigurationService, FlowStateService, IntegrationState, NumberPipe, PricePipe, ProductImagesService, RuntimeSettingsService, SalesTransactionService, SdkCoreModule, SdkDirectivesModule, SdkPipesModule, TransactionItemWorker, UI_DEFINITION_VERSION, extractMetadata, findTransactionItem, findTransactionItemWithComparator, generateTransactionItem, insertTransactionItem, removeTransactionItem, replaceTransactionItem };
2684
1717
  //# sourceMappingURL=veloceapps-sdk-core.mjs.map