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