@veloceapps/sdk 11.0.0-11 → 11.0.0-13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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