@veloceapps/sdk 11.0.0-10 → 11.0.0-12

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