@veloceapps/sdk 11.0.0-4 → 11.0.0-40
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 +18 -41
- 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 +20 -0
- package/core/modules/configuration/types/configuration-runtime.types.d.ts +0 -3
- 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 +18 -19
- 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 -99
- package/esm2020/core/modules/configuration/services/configuration-state.service.mjs +60 -76
- package/esm2020/core/modules/configuration/services/configuration.service.mjs +97 -223
- package/esm2020/core/modules/configuration/services/test-mode-configuration.service.mjs +53 -0
- package/esm2020/core/modules/configuration/types/configuration-runtime.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 +95 -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 -82
- 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 +139 -276
- package/fesm2015/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk-core.mjs +784 -1639
- package/fesm2015/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk.mjs +188 -794
- package/fesm2015/veloceapps-sdk.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-cms.mjs +135 -268
- package/fesm2020/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-core.mjs +844 -1735
- package/fesm2020/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk.mjs +188 -788
- 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 -43
- 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,256 @@
|
|
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 } 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;
|
29
|
+
}
|
30
|
+
init$(props) {
|
31
|
+
this.initializationProps = props;
|
32
|
+
return this.pcmApiService.fetchPCMByProductId(props.productId).pipe(tap(pcmModel => (this.pcmModel = pcmModel)));
|
101
33
|
}
|
102
|
-
|
103
|
-
|
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));
|
166
|
+
}
|
167
|
+
get templates() {
|
168
|
+
return this.templatesSubj$.value;
|
202
169
|
}
|
203
|
-
get
|
204
|
-
return
|
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: { entryPath: '/product', queryParams: {} },
|
206
|
+
version: 2,
|
207
|
+
});
|
208
|
+
return of(undefined);
|
209
|
+
}
|
210
|
+
updateContext(update) {
|
211
|
+
this.contextSubj$.next({
|
212
|
+
...this.context,
|
213
|
+
...update,
|
214
|
+
});
|
233
215
|
}
|
234
|
-
|
216
|
+
initFlow$(flowId, routeQueryParams) {
|
217
|
+
const flow = this.runtimeSettingsService.getConfigurationSettings()['flows']?.find(({ id }) => flowId === id);
|
218
|
+
if (!flow) {
|
219
|
+
this.flowSubj$.next(null);
|
220
|
+
throw new Error(`Flow with flowId=${flowId} is not defined`);
|
221
|
+
}
|
222
|
+
const headerId = routeQueryParams['headerId'];
|
223
|
+
if (typeof headerId !== 'string') {
|
224
|
+
throw new Error(`Please provide 'headerId'`);
|
225
|
+
}
|
226
|
+
const mode = this.getFlowContextMode(headerId);
|
227
|
+
// Restrict if mode is not defined
|
228
|
+
if (mode == null) {
|
229
|
+
throw new Error('Mode is undefined');
|
230
|
+
}
|
231
|
+
this.contextSubj$.next({
|
232
|
+
...flow.properties.queryParams,
|
233
|
+
...routeQueryParams,
|
234
|
+
mode,
|
235
|
+
});
|
236
|
+
this.flowSubj$.next(flow);
|
237
|
+
return of(undefined);
|
238
|
+
}
|
239
|
+
initFlowTemplates$() {
|
235
240
|
return forkJoin([
|
236
|
-
this.
|
241
|
+
this.templatesAdminApiService.fetchTemplates$(),
|
237
242
|
this.customizationService?.getTemplates?.() ?? of([]),
|
238
|
-
]).pipe(map
|
239
|
-
|
243
|
+
]).pipe(map(([templates, localTemplates]) => {
|
244
|
+
const newValue = {};
|
245
|
+
Object.entries({ ...this.defaultTemplates, ...(this.flow?.properties.templates ?? {}) }).forEach(([key, name]) => {
|
240
246
|
const type = this.remapTemplateName(key);
|
241
247
|
if (type) {
|
242
|
-
|
248
|
+
newValue[type] =
|
243
249
|
localTemplates.find(template => template.name === name && template.type === type) ??
|
244
250
|
templates.find(template => template.name === name && template.type === type);
|
245
251
|
}
|
246
252
|
});
|
253
|
+
this.templatesSubj$.next(newValue);
|
247
254
|
}));
|
248
255
|
}
|
249
256
|
remapTemplateName(templateType) {
|
@@ -269,207 +276,401 @@ class FlowInfoService {
|
|
269
276
|
}
|
270
277
|
return undefined;
|
271
278
|
}
|
279
|
+
getFlowContextMode(headerId) {
|
280
|
+
const objectName = SalesforceIdUtils.getSfObjectNameById(headerId);
|
281
|
+
if (!objectName) {
|
282
|
+
return;
|
283
|
+
}
|
284
|
+
return objectName.toUpperCase();
|
285
|
+
}
|
272
286
|
}
|
273
|
-
FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token:
|
287
|
+
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
288
|
FlowInfoService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService });
|
275
289
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, decorators: [{
|
276
290
|
type: Injectable
|
277
|
-
}], ctorParameters: function () { return [{ type:
|
291
|
+
}], ctorParameters: function () { return [{ type: RuntimeSettingsService }, { type: i1.UITemplatesAdminApiService }, { type: undefined, decorators: [{
|
278
292
|
type: Optional
|
279
293
|
}, {
|
280
294
|
type: Inject,
|
281
295
|
args: [FLOW_CUSTOMIZATION]
|
282
296
|
}] }]; } });
|
283
297
|
|
284
|
-
|
285
|
-
|
286
|
-
|
298
|
+
const findTransactionItem = (id, items) => {
|
299
|
+
return findTransactionItemWithComparator(items, (ti) => ti.id === id);
|
300
|
+
};
|
301
|
+
const findTransactionItemWithComparator = (items, comparator) => {
|
302
|
+
let currentLevel = items;
|
303
|
+
while (currentLevel.length) {
|
304
|
+
const found = currentLevel.find(comparator);
|
305
|
+
if (found) {
|
306
|
+
return found;
|
307
|
+
}
|
308
|
+
currentLevel = flatten(currentLevel.map(parent => parent.children));
|
287
309
|
}
|
288
|
-
|
289
|
-
|
310
|
+
return;
|
311
|
+
};
|
312
|
+
const insertTransactionItem = (item, parentId, toInsert) => {
|
313
|
+
const insertData = item.id === parentId ? [toInsert] : [];
|
314
|
+
return {
|
315
|
+
...item,
|
316
|
+
children: [
|
317
|
+
...insertData,
|
318
|
+
...item.children.map(ti => {
|
319
|
+
return insertTransactionItem(ti, parentId, toInsert);
|
320
|
+
}),
|
321
|
+
],
|
322
|
+
};
|
323
|
+
};
|
324
|
+
const removeTransactionItem = (item, idToRemove) => {
|
325
|
+
return {
|
326
|
+
...item,
|
327
|
+
children: item.children
|
328
|
+
.map(ti => {
|
329
|
+
if (ti.id === idToRemove) {
|
330
|
+
return;
|
331
|
+
}
|
332
|
+
else if (ti.children.length) {
|
333
|
+
return removeTransactionItem(ti, idToRemove);
|
334
|
+
}
|
335
|
+
return ti;
|
336
|
+
})
|
337
|
+
.filter(isDefined),
|
338
|
+
};
|
339
|
+
};
|
340
|
+
const replaceTransactionItem = (item, replaceTo) => {
|
341
|
+
if (item.id === replaceTo.id) {
|
342
|
+
return { ...replaceTo };
|
290
343
|
}
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
344
|
+
return {
|
345
|
+
...item,
|
346
|
+
children: item.children.map(ti => replaceTransactionItem(ti, replaceTo)),
|
347
|
+
};
|
348
|
+
};
|
349
|
+
const generateTransactionItem = (productId) => {
|
350
|
+
return {
|
351
|
+
id: UUID.UUID(),
|
352
|
+
productId,
|
353
|
+
};
|
354
|
+
};
|
355
|
+
|
356
|
+
class TransactionItemWorker {
|
357
|
+
constructor(src) {
|
358
|
+
this.ti = { ...src };
|
295
359
|
}
|
296
|
-
|
297
|
-
return this.
|
360
|
+
insert(parentId, toInsert) {
|
361
|
+
return new TransactionItemWorker(insertTransactionItem(this.ti, parentId, toInsert));
|
298
362
|
}
|
299
|
-
|
300
|
-
this.
|
301
|
-
if (!this._hasUnsavedChanges) {
|
302
|
-
this.initialCurrentState = this.quoteDraft?.currentState ?? [];
|
303
|
-
}
|
363
|
+
remove(id) {
|
364
|
+
return new TransactionItemWorker(removeTransactionItem(this.ti, id));
|
304
365
|
}
|
305
|
-
|
306
|
-
return
|
366
|
+
replace(toReplace) {
|
367
|
+
return new TransactionItemWorker(replaceTransactionItem(this.ti, toReplace));
|
307
368
|
}
|
308
|
-
|
309
|
-
|
369
|
+
}
|
370
|
+
|
371
|
+
function extractMetadata(uiDefinition) {
|
372
|
+
return omit(uiDefinition, [
|
373
|
+
'children',
|
374
|
+
'pages',
|
375
|
+
'components',
|
376
|
+
]);
|
377
|
+
}
|
378
|
+
|
379
|
+
class ConfigurationService {
|
380
|
+
get state$() {
|
381
|
+
return this.configurationStateSubj$.asObservable().pipe(filter$1(isDefined));
|
382
|
+
}
|
383
|
+
get state() {
|
384
|
+
return this.configurationStateSubj$.getValue();
|
310
385
|
}
|
311
|
-
get
|
312
|
-
return this.
|
386
|
+
get previousState() {
|
387
|
+
return this.previousConfigurationStateSubj$.getValue();
|
313
388
|
}
|
314
|
-
get
|
315
|
-
return
|
389
|
+
get root$() {
|
390
|
+
return this.state$.pipe(map$1(state => state.salesTransactionItems[0]), filter$1(isDefined));
|
316
391
|
}
|
317
|
-
get
|
318
|
-
return this.
|
392
|
+
get root() {
|
393
|
+
return this.configurationStateSubj$.getValue()?.salesTransactionItems[0] ?? null;
|
319
394
|
}
|
320
|
-
constructor(
|
321
|
-
this.context = context;
|
395
|
+
constructor(flowInfoService, messageService, configurationRuntimeService, salesTransactionService, orchestrationsApiService) {
|
322
396
|
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();
|
397
|
+
this.messageService = messageService;
|
398
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
399
|
+
this.salesTransactionService = salesTransactionService;
|
400
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
401
|
+
this.hasUnsavedChanges = false;
|
402
|
+
this.configurationStateSubj$ = new BehaviorSubject(null);
|
403
|
+
this.previousConfigurationStateSubj$ = new BehaviorSubject(null);
|
404
|
+
this.isLoadingSubj$ = new BehaviorSubject(false);
|
405
|
+
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
335
406
|
}
|
336
407
|
reset() {
|
337
|
-
this.resetSubj$.next(true);
|
338
|
-
this.quoteSubj$.next(null);
|
339
|
-
this.assetsSubj$.next(null);
|
340
|
-
this.isInitialized = false;
|
341
408
|
this.hasUnsavedChanges = false;
|
409
|
+
this.configurationStateSubj$.next(null);
|
410
|
+
this.previousConfigurationStateSubj$.next(null);
|
342
411
|
}
|
343
|
-
init(
|
344
|
-
const
|
345
|
-
const
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
412
|
+
init$() {
|
413
|
+
const { state } = this.salesTransactionService;
|
414
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
415
|
+
if (!state) {
|
416
|
+
return of(undefined);
|
417
|
+
}
|
418
|
+
let transactionItem = state?.salesTransactionItems.find(item => item.id === transactionItemId);
|
419
|
+
if (!transactionItem && productId) {
|
420
|
+
transactionItem =
|
421
|
+
state.salesTransactionItems.find(item => item.productId === productId) ?? generateTransactionItem(productId);
|
422
|
+
}
|
423
|
+
const configurationState = {
|
424
|
+
...state,
|
425
|
+
salesTransactionItems: transactionItem ? [transactionItem] : [],
|
426
|
+
};
|
427
|
+
this.configurationStateSubj$.next(configurationState);
|
428
|
+
this.previousConfigurationStateSubj$.next(configurationState);
|
429
|
+
return of(undefined);
|
430
|
+
}
|
431
|
+
patch$(transactionItem) {
|
432
|
+
const { state, root } = this;
|
433
|
+
if (!state) {
|
434
|
+
return throwError(() => new Error(`Configuration State is not initialized`));
|
435
|
+
}
|
436
|
+
if (!root) {
|
437
|
+
return throwError(() => new Error(`Root SalesTransactionItem not found`));
|
438
|
+
}
|
439
|
+
const newRoot = new TransactionItemWorker(root).replace(transactionItem).ti;
|
440
|
+
const newSalesTransaction = {
|
441
|
+
...state,
|
442
|
+
salesTransactionItems: [newRoot],
|
443
|
+
};
|
444
|
+
return this.configureRequest$(newSalesTransaction).pipe(catchError(error => {
|
445
|
+
console.error(error);
|
446
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
447
|
+
this.messageService.add({ severity: 'error', summary: error });
|
352
448
|
}
|
353
|
-
|
354
|
-
|
355
|
-
|
449
|
+
return throwError(() => error);
|
450
|
+
}), tap$1(() => {
|
451
|
+
if (!this.hasUnsavedChanges) {
|
452
|
+
this.hasUnsavedChanges = true;
|
356
453
|
}
|
357
|
-
|
358
|
-
|
454
|
+
}), map$1(noop));
|
455
|
+
}
|
456
|
+
patch(transactionItem) {
|
457
|
+
this.patch$(transactionItem).subscribe();
|
458
|
+
}
|
459
|
+
configureRequest$(salesTransaction) {
|
460
|
+
const request = {
|
461
|
+
salesTransaction,
|
462
|
+
};
|
463
|
+
this.isLoadingSubj$.next(true);
|
464
|
+
return this.orchestrationsApiService.apply$(request).pipe(tap$1(result => {
|
465
|
+
const newState = result.salesTransaction;
|
466
|
+
this.configurationStateSubj$.next(newState);
|
467
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(newState));
|
468
|
+
}), map$1(response => response.salesTransaction), catchError(error => throwError(() => {
|
469
|
+
const resetState = this.previousConfigurationStateSubj$.getValue();
|
470
|
+
if (resetState) {
|
471
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(resetState));
|
472
|
+
this.configurationStateSubj$.next(resetState);
|
359
473
|
}
|
360
|
-
|
474
|
+
if (error.error) {
|
475
|
+
return extractErrorDetails(error.error).join('. ');
|
476
|
+
}
|
477
|
+
return error.message || JSON.stringify(error);
|
478
|
+
})), finalize(() => this.isLoadingSubj$.next(false)));
|
361
479
|
}
|
362
|
-
|
363
|
-
|
364
|
-
|
480
|
+
configureExternal$(props) {
|
481
|
+
// TODO: implement
|
482
|
+
throw new Error('Not implemented');
|
365
483
|
}
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
return;
|
370
|
-
}
|
371
|
-
this.quoteSubj$.next({
|
372
|
-
...quoteDraft,
|
373
|
-
currentState: lineItems,
|
374
|
-
});
|
484
|
+
configureGuidedSelling$(data) {
|
485
|
+
// TODO: implement
|
486
|
+
throw new Error('Not implemented');
|
375
487
|
}
|
376
|
-
|
377
|
-
const
|
378
|
-
if (!
|
379
|
-
|
488
|
+
getPCMModel() {
|
489
|
+
const pcmModel = this.configurationRuntimeService.pcmModel;
|
490
|
+
if (!pcmModel) {
|
491
|
+
throw new Error('PCM model not initialized');
|
380
492
|
}
|
381
|
-
|
382
|
-
this.context.set(update.context);
|
383
|
-
}
|
384
|
-
this.quoteSubj$.next({
|
385
|
-
...quoteDraft,
|
386
|
-
...update,
|
387
|
-
});
|
493
|
+
return pcmModel;
|
388
494
|
}
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
495
|
+
}
|
496
|
+
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 });
|
497
|
+
ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
|
498
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
|
499
|
+
type: Injectable
|
500
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i2.MessageService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: i1.OrchestrationsApiService }]; } });
|
501
|
+
|
502
|
+
class TestModeConfigurationService {
|
503
|
+
constructor(flowInfoService, configurationService, configurationRuntimeService, salesTransactionService) {
|
504
|
+
this.flowInfoService = flowInfoService;
|
505
|
+
this.configurationService = configurationService;
|
506
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
507
|
+
this.salesTransactionService = salesTransactionService;
|
508
|
+
this.isInitialized = false;
|
509
|
+
}
|
510
|
+
initTestMode$(uiDefinitionContainer) {
|
511
|
+
this.configurationRuntimeService.uiDefinitionContainer = uiDefinitionContainer;
|
512
|
+
if (this.checkInitialized(uiDefinitionContainer)) {
|
513
|
+
this.configurationRuntimeService.pcmModel = this.pcmModel;
|
514
|
+
return of(undefined);
|
393
515
|
}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
516
|
+
this.configurationService.reset();
|
517
|
+
const { productId, quoteId } = uiDefinitionContainer.source.properties ?? {};
|
518
|
+
if (!productId) {
|
519
|
+
return throwError(() => 'Unable to start the Configuration Preview: Product is missing.');
|
520
|
+
}
|
521
|
+
if (!quoteId) {
|
522
|
+
return throwError(() => `Unable to start the Configuration Preview: Quote is missing.`);
|
523
|
+
}
|
524
|
+
return this.flowInfoService.initTestFlow$(productId).pipe(switchMap(() => this.configurationRuntimeService.init$({ productId })), tap(pcmModel => (this.pcmModel = pcmModel)), tap(() => this.salesTransactionService.setState(this.getTestSalesTransaction(quoteId))), switchMap(() => this.configurationService.init$()), switchMap(() => this.configurationService.state
|
525
|
+
? this.configurationService.configureRequest$(this.configurationService.state)
|
526
|
+
: of(undefined)), tap(() => (this.isInitialized = true)), map(noop));
|
527
|
+
}
|
528
|
+
getTestSalesTransaction(quoteId) {
|
529
|
+
const testTransaction = {
|
530
|
+
id: quoteId,
|
531
|
+
businessObjectType: 'Quote',
|
532
|
+
salesTransactionItems: [],
|
533
|
+
};
|
534
|
+
return testTransaction;
|
535
|
+
}
|
536
|
+
checkInitialized(uiDefinitionContainer) {
|
537
|
+
return this.isInitialized && !!uiDefinitionContainer.source.properties?.persistTestState;
|
404
538
|
}
|
405
|
-
|
406
|
-
|
539
|
+
}
|
540
|
+
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 });
|
541
|
+
TestModeConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService });
|
542
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService, decorators: [{
|
543
|
+
type: Injectable
|
544
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: ConfigurationService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }]; } });
|
545
|
+
|
546
|
+
class SalesTransactionService {
|
547
|
+
get isInitialized$() {
|
548
|
+
return this.isInitializedSubj$.asObservable();
|
407
549
|
}
|
408
|
-
get
|
409
|
-
return
|
550
|
+
get isInitialized() {
|
551
|
+
return this.isInitializedSubj$.getValue();
|
410
552
|
}
|
411
|
-
|
412
|
-
|
413
|
-
if (!
|
414
|
-
|
553
|
+
set hasUnsavedChanges(value) {
|
554
|
+
this.hasUnsavedChangesSubj$.next(value);
|
555
|
+
if (!this.hasUnsavedChanges) {
|
556
|
+
this.initialState = this.state?.salesTransactionItems ?? [];
|
415
557
|
}
|
416
|
-
return {
|
417
|
-
...quote,
|
418
|
-
context: this.context.resolve(),
|
419
|
-
};
|
420
558
|
}
|
421
|
-
get
|
422
|
-
return this.
|
559
|
+
get hasUnsavedChanges() {
|
560
|
+
return this.hasUnsavedChangesSubj$.getValue();
|
561
|
+
}
|
562
|
+
get state() {
|
563
|
+
return this.stateSubj$.getValue();
|
564
|
+
}
|
565
|
+
get hasProducts() {
|
566
|
+
return Boolean(this.state?.salesTransactionItems.length);
|
423
567
|
}
|
424
|
-
|
425
|
-
|
568
|
+
constructor(flowInfoService, salesTransactionApiService) {
|
569
|
+
this.flowInfoService = flowInfoService;
|
570
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
571
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
572
|
+
this.isInitializedSubj$ = new BehaviorSubject(false);
|
573
|
+
this.hasUnsavedChangesSubj$ = new BehaviorSubject(false);
|
574
|
+
this.initialState = [];
|
575
|
+
this.hasUnsavedChanges$ = this.hasUnsavedChangesSubj$.asObservable();
|
576
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
577
|
+
}
|
578
|
+
init(headerId, params) {
|
579
|
+
return this.salesTransactionApiService.getState(headerId, params).pipe(tap(res => this.stateSubj$.next(res.salesTransaction)), map(res => res.salesTransaction));
|
426
580
|
}
|
427
|
-
|
428
|
-
|
581
|
+
finalizeInit() {
|
582
|
+
this.isInitializedSubj$.next(true);
|
583
|
+
this.hasUnsavedChanges = false;
|
429
584
|
}
|
430
|
-
|
431
|
-
|
585
|
+
reset() {
|
586
|
+
this.stateSubj$.next(null);
|
587
|
+
this.isInitializedSubj$.next(false);
|
588
|
+
this.hasUnsavedChangesSubj$.next(false);
|
432
589
|
}
|
433
|
-
|
434
|
-
return this.
|
590
|
+
getInitialState() {
|
591
|
+
return this.initialState;
|
435
592
|
}
|
436
|
-
|
437
|
-
|
593
|
+
setState(state) {
|
594
|
+
this.stateSubj$.next(state);
|
438
595
|
}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
596
|
+
}
|
597
|
+
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 });
|
598
|
+
SalesTransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService });
|
599
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, decorators: [{
|
600
|
+
type: Injectable
|
601
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i1.SalesTransactionApiService }]; } });
|
602
|
+
|
603
|
+
class FlowConfigurationService {
|
604
|
+
constructor(orchestrationsApiService, salesTransactionService) {
|
605
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
606
|
+
this.salesTransactionService = salesTransactionService;
|
607
|
+
this.updatedSubj$ = new Subject();
|
608
|
+
this.updated$ = this.updatedSubj$.asObservable();
|
609
|
+
}
|
610
|
+
calculate$(state) {
|
611
|
+
return this.orchestrationsApiService.apply$({ salesTransaction: state }).pipe(tap(result => this.salesTransactionService.setState(result.salesTransaction)), map(noop));
|
448
612
|
}
|
449
|
-
|
450
|
-
|
451
|
-
|
613
|
+
calculate(state) {
|
614
|
+
this.calculate$(state).subscribe();
|
615
|
+
}
|
616
|
+
revert$(transactionItemId) {
|
617
|
+
const state = this.salesTransactionService.state;
|
618
|
+
const initialState = this.salesTransactionService.getInitialState();
|
619
|
+
const currentState = state?.salesTransactionItems ?? [];
|
620
|
+
const currentItemIndex = currentState.findIndex(({ id }) => id === transactionItemId);
|
621
|
+
const currentItem = currentState[currentItemIndex];
|
622
|
+
const initialItem = initialState.find(({ integrationId }) => integrationId === currentItem?.integrationId);
|
623
|
+
if (!state || !currentItem || !initialItem) {
|
624
|
+
return of(null);
|
452
625
|
}
|
453
|
-
|
454
|
-
|
626
|
+
const updatedState = cloneDeep(currentState);
|
627
|
+
updatedState.splice(currentItemIndex, 1, initialItem);
|
628
|
+
return of([]).pipe(tap(() => {
|
629
|
+
this.salesTransactionService.setState({ ...state, salesTransactionItems: updatedState });
|
630
|
+
}), switchMap(() => this.calculate$({ ...state, salesTransactionItems: updatedState })), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
631
|
+
}
|
632
|
+
revert(transactionItemId) {
|
633
|
+
this.revert$(transactionItemId).subscribe();
|
634
|
+
}
|
635
|
+
delete$(ids) {
|
636
|
+
const state = this.salesTransactionService.state;
|
637
|
+
if (!state) {
|
638
|
+
return of(null);
|
455
639
|
}
|
640
|
+
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());
|
641
|
+
}
|
642
|
+
delete(ids) {
|
643
|
+
this.delete$(ids).subscribe();
|
644
|
+
}
|
645
|
+
handleErrorAndBounceBack() {
|
646
|
+
return (source$) => {
|
647
|
+
return source$.pipe(catchError$1(error => {
|
648
|
+
console.error(error);
|
649
|
+
// bounce back if configuration call has failed
|
650
|
+
const state = this.salesTransactionService.state;
|
651
|
+
if (state) {
|
652
|
+
this.salesTransactionService.setState(state);
|
653
|
+
this.updatedSubj$.next();
|
654
|
+
}
|
655
|
+
return throwError(() => error);
|
656
|
+
}));
|
657
|
+
};
|
456
658
|
}
|
457
659
|
}
|
458
|
-
|
459
|
-
|
460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
660
|
+
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 });
|
661
|
+
FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
|
662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
|
461
663
|
type: Injectable
|
462
|
-
}], ctorParameters: function () { return [{ type:
|
664
|
+
}], ctorParameters: function () { return [{ type: i1.OrchestrationsApiService }, { type: SalesTransactionService }]; } });
|
463
665
|
|
464
666
|
class FlowStateService {
|
465
|
-
constructor(
|
466
|
-
this.contextService = contextService;
|
467
|
-
this.quoteDraftService = quoteDraftService;
|
468
|
-
this.flowInfoService = flowInfoService;
|
667
|
+
constructor(flowConfiguration, flowInfoService, flowStateApiService, processorsApiService, salesTransactionApiService, salesTransactionService, toastService, customizationService) {
|
469
668
|
this.flowConfiguration = flowConfiguration;
|
470
|
-
this.
|
669
|
+
this.flowInfoService = flowInfoService;
|
471
670
|
this.flowStateApiService = flowStateApiService;
|
472
|
-
this.
|
671
|
+
this.processorsApiService = processorsApiService;
|
672
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
673
|
+
this.salesTransactionService = salesTransactionService;
|
473
674
|
this.toastService = toastService;
|
474
675
|
this.customizationService = customizationService;
|
475
676
|
this.NOT_INITIALIZED = Symbol();
|
@@ -486,68 +687,22 @@ class FlowStateService {
|
|
486
687
|
this.cleanup$ = new Subject();
|
487
688
|
this.statefulExecutionRequest$ = this.initBufferedRequest$();
|
488
689
|
/*
|
489
|
-
In stateless mode watch
|
490
|
-
all subscriptions get their updates according to updated
|
690
|
+
In stateless mode watch State changes and call executeRequest so that
|
691
|
+
all subscriptions get their updates according to updated State
|
491
692
|
*/
|
492
693
|
this.isInitialized$()
|
493
|
-
.pipe(filter
|
694
|
+
.pipe(filter(Boolean), filter(() => !this.flowInfoService.flow.properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
|
494
695
|
.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
696
|
}
|
540
697
|
init$() {
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
}
|
548
|
-
}));
|
698
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
699
|
+
return this.initProcessors$().pipe(switchMap(() => this.initStateful$()));
|
700
|
+
}
|
701
|
+
else {
|
702
|
+
return forkJoin([this.initStateless$(), this.initProcessors$()]).pipe(map(noop));
|
703
|
+
}
|
549
704
|
}
|
550
|
-
|
705
|
+
reset() {
|
551
706
|
Object.values(this.subscriptions).forEach(({ data$ }) => data$.complete());
|
552
707
|
this.subscriptions = {};
|
553
708
|
if (this.stateId$.value) {
|
@@ -559,9 +714,9 @@ class FlowStateService {
|
|
559
714
|
this.cleanup$.next();
|
560
715
|
}
|
561
716
|
get hasUnsavedChanges() {
|
562
|
-
return this.
|
717
|
+
return this.flowInfoService.flow.properties.stateful
|
563
718
|
? Array.from(this.trackedStatefulChangesMap.values()).some(Boolean)
|
564
|
-
: this.
|
719
|
+
: this.salesTransactionService.hasUnsavedChanges;
|
565
720
|
}
|
566
721
|
get stateId() {
|
567
722
|
return this.stateId$.value;
|
@@ -570,14 +725,14 @@ class FlowStateService {
|
|
570
725
|
return this.executionInProgress$.asObservable();
|
571
726
|
}
|
572
727
|
isInitialized$() {
|
573
|
-
return combineLatest([this.stateId$, this.
|
728
|
+
return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map(values => values.some(Boolean)));
|
574
729
|
}
|
575
730
|
isInitialized() {
|
576
|
-
return Boolean(this.stateId$.value) || this.
|
731
|
+
return Boolean(this.stateId$.value) || this.salesTransactionService.isInitialized;
|
577
732
|
}
|
578
733
|
execute$(scope, exec) {
|
579
734
|
const request = this.execToRequest(scope, exec);
|
580
|
-
return this.executeRequest$(request).pipe(map
|
735
|
+
return this.executeRequest$(request).pipe(map(result => {
|
581
736
|
// Keep only requested results
|
582
737
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
583
738
|
if (exec.selectors?.[requestId]) {
|
@@ -593,7 +748,7 @@ class FlowStateService {
|
|
593
748
|
actions: [{ name: action, inputData }],
|
594
749
|
};
|
595
750
|
const request = this.execToRequest(scope, exec);
|
596
|
-
return this.executeRequest$(request).pipe(map
|
751
|
+
return this.executeRequest$(request).pipe(map(noop));
|
597
752
|
}
|
598
753
|
select$(scope, selectorName, inputData) {
|
599
754
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -605,7 +760,7 @@ class FlowStateService {
|
|
605
760
|
},
|
606
761
|
},
|
607
762
|
});
|
608
|
-
return this.executeRequest$(request).pipe(map
|
763
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
609
764
|
}
|
610
765
|
subscribe$(scope, selectorName, inputData, options) {
|
611
766
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -631,16 +786,16 @@ class FlowStateService {
|
|
631
786
|
this.executeRequest$(request).subscribe();
|
632
787
|
}
|
633
788
|
}
|
634
|
-
return subscription.data$.pipe(filter
|
789
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), finalize$1(() => {
|
635
790
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
636
791
|
delete this.subscriptions[requestId];
|
637
792
|
}
|
638
793
|
}));
|
639
794
|
}
|
640
795
|
save$() {
|
641
|
-
if (this.
|
796
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
642
797
|
if (this.stateId$.value) {
|
643
|
-
return this.flowStateApiService.save(this.stateId$.value).pipe(tap
|
798
|
+
return this.flowStateApiService.save(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })), tap(() => {
|
644
799
|
Array.from(this.trackedStatefulChangesMap.keys()).forEach(key => {
|
645
800
|
this.trackedStatefulChangesMap.set(key, false);
|
646
801
|
});
|
@@ -648,30 +803,26 @@ class FlowStateService {
|
|
648
803
|
}
|
649
804
|
}
|
650
805
|
else {
|
651
|
-
const
|
652
|
-
if (
|
653
|
-
return this.
|
654
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
655
|
-
}));
|
806
|
+
const state = this.salesTransactionService.state;
|
807
|
+
if (state) {
|
808
|
+
return this.salesTransactionApiService.upsert(state);
|
656
809
|
}
|
657
810
|
}
|
658
|
-
return of({
|
811
|
+
return of({ id: '' });
|
659
812
|
}
|
660
813
|
submit$() {
|
661
|
-
if (this.
|
814
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
662
815
|
if (this.stateId$.value) {
|
663
|
-
return this.flowStateApiService.submit(this.stateId$.value);
|
816
|
+
return this.flowStateApiService.submit(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })));
|
664
817
|
}
|
665
818
|
}
|
666
819
|
else {
|
667
|
-
const
|
668
|
-
if (
|
669
|
-
return this.
|
670
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
671
|
-
}));
|
820
|
+
const state = this.salesTransactionService.state;
|
821
|
+
if (state) {
|
822
|
+
return this.salesTransactionApiService.submit(state);
|
672
823
|
}
|
673
824
|
}
|
674
|
-
return of({
|
825
|
+
return of({ id: '' });
|
675
826
|
}
|
676
827
|
getFlowStore() {
|
677
828
|
return this.flowStore;
|
@@ -709,10 +860,10 @@ class FlowStateService {
|
|
709
860
|
fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
|
710
861
|
}
|
711
862
|
}
|
712
|
-
const execution$ = this.
|
863
|
+
const execution$ = this.flowInfoService.flow.properties.stateful
|
713
864
|
? this.executeStateful$(fullRequest)
|
714
865
|
: this.executeStateless$(fullRequest);
|
715
|
-
return execution$.pipe(tap
|
866
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
716
867
|
}
|
717
868
|
handleSelectorsResponse(selectors) {
|
718
869
|
Object.entries(selectors).forEach(([requestId, selectorResult]) => {
|
@@ -727,31 +878,21 @@ class FlowStateService {
|
|
727
878
|
});
|
728
879
|
}
|
729
880
|
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
881
|
const processorsList = flatten(Object.values(this.processors).map(ownerMap => Object.values(ownerMap ?? {})));
|
739
882
|
const processors = processorsList.length ? processorsList : undefined;
|
740
883
|
const selectors = Object.values(this.subscriptions)
|
741
884
|
.map(({ request }) => request.selectors)
|
742
885
|
.filter(isDefined)
|
743
886
|
.reduce((trunk, selectors) => ({ ...trunk, ...selectors }), {});
|
744
|
-
const request = this.getDefaultExecutionRequestDTO();
|
745
887
|
return this.flowStateApiService
|
746
888
|
.init({
|
747
|
-
quoteId: this.
|
748
|
-
params: this.flowInfoService.
|
889
|
+
quoteId: this.flowInfoService.context.headerId,
|
890
|
+
params: this.flowInfoService.context,
|
749
891
|
actionsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.ACTION),
|
750
892
|
selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
|
751
|
-
selectors:
|
752
|
-
actions: request.actions,
|
893
|
+
selectors: selectors,
|
753
894
|
})
|
754
|
-
.pipe(map
|
895
|
+
.pipe(map(({ stateId, selectors }) => {
|
755
896
|
this.handleSelectorsResponse(selectors);
|
756
897
|
this.stateId$.next(stateId);
|
757
898
|
}));
|
@@ -771,1095 +912,170 @@ class FlowStateService {
|
|
771
912
|
};
|
772
913
|
this.executionInProgress$.next(true);
|
773
914
|
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 => {
|
915
|
+
}), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
835
916
|
this.executionInProgress$.next(false);
|
836
917
|
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;
|
918
|
+
}));
|
1653
919
|
}
|
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;
|
920
|
+
executeStateful$(request) {
|
921
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
922
|
+
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
923
|
+
combineLatest([
|
924
|
+
this.statefulExecutionRequest$,
|
925
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
926
|
+
])), map(([response]) => response), take(1));
|
1669
927
|
}
|
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;
|
928
|
+
initStateless$() {
|
929
|
+
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
930
|
}
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
this.
|
1702
|
-
|
931
|
+
executeStateless$(request) {
|
932
|
+
this.executionInProgress$.next(true);
|
933
|
+
return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
|
934
|
+
/*
|
935
|
+
Skip price calculation in case
|
936
|
+
1. No actions in the request
|
937
|
+
2. Initialization process execution (state not initialized yet)
|
938
|
+
*/
|
939
|
+
const { state } = this.salesTransactionService;
|
940
|
+
if (!state || !request.actions?.length || !this.isInitialized()) {
|
941
|
+
return of(undefined);
|
942
|
+
}
|
943
|
+
else {
|
944
|
+
return this.flowConfiguration.calculate$(state);
|
945
|
+
}
|
946
|
+
}), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
947
|
+
this.executionInProgress$.next(false);
|
948
|
+
return throwError(() => e);
|
949
|
+
}));
|
1703
950
|
}
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
951
|
+
executeStatelessActions(request) {
|
952
|
+
const state = this.salesTransactionService.state;
|
953
|
+
if (!state || !request.actions?.length) {
|
954
|
+
return;
|
955
|
+
}
|
956
|
+
let flowState = state;
|
957
|
+
request.actions.forEach(action => {
|
958
|
+
try {
|
959
|
+
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
960
|
+
}
|
961
|
+
catch (e) {
|
962
|
+
console.error(e);
|
963
|
+
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
964
|
+
throw e;
|
965
|
+
}
|
966
|
+
});
|
967
|
+
this.salesTransactionService.setState(flowState);
|
1713
968
|
}
|
1714
|
-
|
1715
|
-
this.
|
969
|
+
executeStatelessSelectors(request) {
|
970
|
+
if (!this.salesTransactionService.state) {
|
971
|
+
throw 'State is not initialized';
|
972
|
+
}
|
973
|
+
const flowState = this.salesTransactionService.state;
|
974
|
+
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
975
|
+
try {
|
976
|
+
result.selectors[key] = {
|
977
|
+
success: true,
|
978
|
+
result: this.executeSelectorScript(flowState, selector),
|
979
|
+
};
|
980
|
+
}
|
981
|
+
catch (e) {
|
982
|
+
console.error(e);
|
983
|
+
result.selectors[key] = {
|
984
|
+
success: false,
|
985
|
+
errorMessage: String(e),
|
986
|
+
};
|
987
|
+
}
|
988
|
+
return result;
|
989
|
+
}, { stateId: '', selectors: {} });
|
1716
990
|
}
|
1717
|
-
|
1718
|
-
const
|
1719
|
-
if (!
|
1720
|
-
|
991
|
+
initProcessors$() {
|
992
|
+
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
993
|
+
if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
|
994
|
+
// Skip initialization as backend will take processors from SF
|
995
|
+
return of(undefined);
|
1721
996
|
}
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
return of(null);
|
997
|
+
const owners$ = Object.values(this.flowInfoService.templates)
|
998
|
+
.map(template => {
|
999
|
+
if (!template) {
|
1000
|
+
return;
|
1001
|
+
}
|
1002
|
+
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
1003
|
+
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
|
1004
|
+
const processorsMap = processors.reduce((acc, p) => {
|
1005
|
+
acc[p.apiName] = p;
|
1006
|
+
return acc;
|
1007
|
+
}, {});
|
1008
|
+
this.processors[template.id] = processorsMap;
|
1009
|
+
}));
|
1010
|
+
})
|
1011
|
+
.filter(isDefined);
|
1012
|
+
if (!owners$.length) {
|
1013
|
+
return of(undefined);
|
1740
1014
|
}
|
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());
|
1015
|
+
return forkJoin(owners$).pipe(map(noop));
|
1746
1016
|
}
|
1747
|
-
|
1748
|
-
this.
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
if (!quoteDraft) {
|
1754
|
-
return of(null);
|
1017
|
+
executeActionScript(request, executable) {
|
1018
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1019
|
+
if (!configurationProcessor?.script) {
|
1020
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1021
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1022
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1755
1023
|
}
|
1756
|
-
return
|
1757
|
-
}
|
1758
|
-
delete(ids) {
|
1759
|
-
this.delete$(ids).subscribe();
|
1024
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1760
1025
|
}
|
1761
|
-
|
1762
|
-
const
|
1763
|
-
if (!
|
1764
|
-
|
1026
|
+
executeSelectorScript(request, executable) {
|
1027
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1028
|
+
if (!configurationProcessor?.script) {
|
1029
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1030
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1031
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1765
1032
|
}
|
1766
|
-
|
1767
|
-
return of([]).pipe(switchMap(() => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
1033
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1768
1034
|
}
|
1769
|
-
|
1770
|
-
const
|
1771
|
-
|
1772
|
-
|
1035
|
+
executeProcessorScript(request, configurationProcessor, inputData) {
|
1036
|
+
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
1037
|
+
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
1038
|
+
if (!functionToExecute) {
|
1039
|
+
const script = `${configurationProcessor.script}\nreturn transform;`;
|
1040
|
+
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
1041
|
+
functionToExecute = new Function(script + sourceMap)();
|
1042
|
+
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
1773
1043
|
}
|
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$();
|
1044
|
+
return functionToExecute({
|
1045
|
+
request,
|
1046
|
+
inputData,
|
1047
|
+
flowStore: this.flowStore,
|
1048
|
+
});
|
1810
1049
|
}
|
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
|
-
};
|
1050
|
+
generateRequestId(scope, selectorName, inputData) {
|
1051
|
+
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
1052
|
+
return `${scope}/${selectorName}/${inputDataHash}`;
|
1824
1053
|
}
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1054
|
+
checkStatefulChanges(requestId, selectorResult) {
|
1055
|
+
if (this.trackedStatefulChangesMap.has(requestId)) {
|
1056
|
+
if (!this.initialStatefulData[requestId]) {
|
1057
|
+
this.initialStatefulData[requestId] = selectorResult;
|
1058
|
+
}
|
1059
|
+
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
1060
|
+
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
1830
1061
|
}
|
1831
|
-
return this.proceduresApiService.apply$(request);
|
1832
1062
|
}
|
1833
1063
|
}
|
1834
|
-
|
1835
|
-
|
1836
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1064
|
+
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 });
|
1065
|
+
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
1066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
1837
1067
|
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
|
-
}] });
|
1068
|
+
}], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i3.FlowStateApiService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
1069
|
+
type: Optional
|
1070
|
+
}, {
|
1071
|
+
type: Inject,
|
1072
|
+
args: [FLOW_CUSTOMIZATION]
|
1073
|
+
}] }]; } });
|
1852
1074
|
|
1853
1075
|
class FlowStateConfigurationService {
|
1854
|
-
constructor(flowInfoService,
|
1076
|
+
constructor(flowInfoService, flowStateService) {
|
1855
1077
|
this.flowInfoService = flowInfoService;
|
1856
|
-
this.flowConfigurationService = flowConfigurationService;
|
1857
|
-
this.flowStateApiService = flowStateApiService;
|
1858
1078
|
this.flowStateService = flowStateService;
|
1859
|
-
this.configurationStateId$ = new BehaviorSubject(null);
|
1860
|
-
}
|
1861
|
-
get configurationStateId() {
|
1862
|
-
return this.configurationStateId$.value;
|
1863
1079
|
}
|
1864
1080
|
addToCart$(props) {
|
1865
1081
|
let request$;
|
@@ -1870,26 +1086,22 @@ class FlowStateConfigurationService {
|
|
1870
1086
|
request$ = of();
|
1871
1087
|
}
|
1872
1088
|
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
|
-
}));
|
1089
|
+
// TODO: Implement
|
1090
|
+
request$ = of();
|
1880
1091
|
}
|
1881
1092
|
}
|
1882
1093
|
else {
|
1883
|
-
|
1094
|
+
// TODO: Implement
|
1095
|
+
request$ = of();
|
1884
1096
|
}
|
1885
|
-
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map
|
1097
|
+
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1886
1098
|
}
|
1887
1099
|
}
|
1888
|
-
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token:
|
1100
|
+
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
1101
|
FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
|
1890
1102
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
|
1891
1103
|
type: Injectable
|
1892
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type:
|
1104
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }]; } });
|
1893
1105
|
|
1894
1106
|
class IntegrationState {
|
1895
1107
|
constructor() {
|
@@ -1909,12 +1121,12 @@ class IntegrationState {
|
|
1909
1121
|
this.action$.next(action);
|
1910
1122
|
}
|
1911
1123
|
listen$(actionType) {
|
1912
|
-
return this.action$.pipe(filter
|
1124
|
+
return this.action$.pipe(filter(action => action.type === actionType), map(action => action.payload));
|
1913
1125
|
}
|
1914
1126
|
listenAll$() {
|
1915
1127
|
return this.action$.asObservable();
|
1916
1128
|
}
|
1917
|
-
|
1129
|
+
reset() {
|
1918
1130
|
this.stateSubj$.next({});
|
1919
1131
|
}
|
1920
1132
|
}
|
@@ -1925,8 +1137,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1925
1137
|
}] });
|
1926
1138
|
|
1927
1139
|
class ProductImagesService {
|
1928
|
-
constructor(
|
1929
|
-
this.
|
1140
|
+
constructor(productsAdminApiService) {
|
1141
|
+
this.productsAdminApiService = productsAdminApiService;
|
1930
1142
|
this.imagesMap$ = new BehaviorSubject({});
|
1931
1143
|
}
|
1932
1144
|
getImageUrl$(productId) {
|
@@ -1934,168 +1146,53 @@ class ProductImagesService {
|
|
1934
1146
|
this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
|
1935
1147
|
this.fetchProductImage(productId);
|
1936
1148
|
}
|
1937
|
-
return this.imagesMap$.pipe(map
|
1149
|
+
return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
|
1938
1150
|
}
|
1939
1151
|
fetchProductImage(productId) {
|
1940
|
-
this.
|
1152
|
+
this.productsAdminApiService
|
1941
1153
|
.fetchImage$(productId)
|
1942
|
-
.pipe(map
|
1154
|
+
.pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
|
1943
1155
|
.subscribe();
|
1944
1156
|
}
|
1945
1157
|
}
|
1946
|
-
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.
|
1158
|
+
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
1159
|
ProductImagesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService });
|
1948
1160
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, decorators: [{
|
1949
1161
|
type: Injectable
|
1950
|
-
}], ctorParameters: function () { return [{ type: i1.
|
1162
|
+
}], ctorParameters: function () { return [{ type: i1.ProductsAdminApiService }]; } });
|
1951
1163
|
|
1952
|
-
class
|
1953
|
-
constructor(
|
1954
|
-
this.
|
1955
|
-
|
1956
|
-
getRuntimeContext(productId, offeringId) {
|
1957
|
-
return this.configurationApiService.getRuntimeDataByProductId(productId, offeringId).pipe(map(runtimeData => {
|
1958
|
-
const uiDefinitionContainer = this.getUIDefinitionContainer(runtimeData);
|
1959
|
-
const runtimeModel = RuntimeModel.create(runtimeData.types, runtimeData.products);
|
1960
|
-
const { productName, properties } = Array.from(runtimeModel.components.values()).find(c => c.productId === productId) ?? {};
|
1961
|
-
const uiDefinitionProperties = uiDefinitionContainer?.source.properties;
|
1962
|
-
return {
|
1963
|
-
modelId: runtimeData.modelId,
|
1964
|
-
uiDefinitionContainer: uiDefinitionContainer,
|
1965
|
-
runtimeModel: runtimeModel,
|
1966
|
-
runtimeMode: RuntimeMode.PROD,
|
1967
|
-
productId: productId,
|
1968
|
-
productType: properties?.['displayName'] || productName,
|
1969
|
-
offeringId: offeringId,
|
1970
|
-
properties: {
|
1971
|
-
PricingEnabled: uiDefinitionProperties?.pricingEnabled ? 'true' : 'false',
|
1972
|
-
PriceListId: uiDefinitionProperties?.priceList,
|
1973
|
-
},
|
1974
|
-
};
|
1975
|
-
}));
|
1976
|
-
}
|
1977
|
-
getUIDefinitionContainer(runtimeData) {
|
1978
|
-
const containers = runtimeData.uiDefinitions.filter(container => isNotLegacyUIDefinition(container.source));
|
1979
|
-
return containers.find(container => container.source.primary) ?? containers[0];
|
1164
|
+
class CatalogProductsService {
|
1165
|
+
constructor() {
|
1166
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
1167
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
1980
1168
|
}
|
1981
|
-
|
1982
|
-
|
1983
|
-
RuntimeContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService });
|
1984
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, decorators: [{
|
1985
|
-
type: Injectable
|
1986
|
-
}], ctorParameters: function () { return [{ type: i1.ConfigurationApiService }]; } });
|
1987
|
-
|
1988
|
-
class ConfigurationRuntimeService {
|
1989
|
-
constructor(apiService, contextService, runtimeContextService) {
|
1990
|
-
this.apiService = apiService;
|
1991
|
-
this.contextService = contextService;
|
1992
|
-
this.runtimeContextService = runtimeContextService;
|
1993
|
-
this._isInitialized = false;
|
1994
|
-
this.uiDefinitionProperties = {};
|
1169
|
+
get state() {
|
1170
|
+
return this.stateSubj$.getValue();
|
1995
1171
|
}
|
1996
1172
|
reset() {
|
1997
|
-
this.
|
1998
|
-
this._runtimeContext = undefined;
|
1999
|
-
this.initializationProps = undefined;
|
2000
|
-
this.uiDefinitionProperties = {};
|
2001
|
-
}
|
2002
|
-
initTestMode(uiDefinitionContainer) {
|
2003
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
2004
|
-
const uiDefinitionExternals = uiDefinitionContainer.source.externals ?? {};
|
2005
|
-
return combineLatest([
|
2006
|
-
this.apiService.getRuntimeDataByModelId(uiDefinitionContainer.modelId),
|
2007
|
-
this.contextService.initTestMode(),
|
2008
|
-
]).pipe(first(), map(([runtimeData, context]) => {
|
2009
|
-
this.contextService.update({
|
2010
|
-
properties: {
|
2011
|
-
...this.runtimeContext?.properties,
|
2012
|
-
...context.properties,
|
2013
|
-
ModelId: uiDefinitionContainer.modelId,
|
2014
|
-
PricingEnabled: this.uiDefinitionProperties.pricingEnabled ? 'true' : 'false',
|
2015
|
-
PriceListId: this.uiDefinitionProperties.priceList,
|
2016
|
-
offeringId: this.uiDefinitionProperties.offeringId,
|
2017
|
-
...uiDefinitionExternals,
|
2018
|
-
},
|
2019
|
-
});
|
2020
|
-
this._runtimeContext = {
|
2021
|
-
modelId: uiDefinitionContainer.modelId,
|
2022
|
-
runtimeModel: RuntimeModel.create(runtimeData.types, runtimeData.products),
|
2023
|
-
runtimeMode: RuntimeMode.TEST,
|
2024
|
-
uiDefinitionContainer,
|
2025
|
-
};
|
2026
|
-
return this._runtimeContext;
|
2027
|
-
}), tap(() => (this._isInitialized = true)));
|
2028
|
-
}
|
2029
|
-
init(props) {
|
2030
|
-
this.initializationProps = props;
|
2031
|
-
const context = this.contextService.resolve();
|
2032
|
-
return this.runtimeContextService.getRuntimeContext(props.productId, props.offeringId).pipe(tap(runtimeContext => {
|
2033
|
-
this.uiDefinitionProperties = runtimeContext.uiDefinitionContainer?.source.properties ?? {};
|
2034
|
-
const { PriceListId } = context.properties ?? {};
|
2035
|
-
const mergeContext = {
|
2036
|
-
...runtimeContext,
|
2037
|
-
properties: {
|
2038
|
-
...runtimeContext.properties,
|
2039
|
-
...context.properties,
|
2040
|
-
PricingEnabled: PriceListId ? 'true' : 'false',
|
2041
|
-
},
|
2042
|
-
};
|
2043
|
-
this.id15to18('AccountId', mergeContext.properties);
|
2044
|
-
this._runtimeContext = mergeContext;
|
2045
|
-
if (context.properties && this._runtimeContext.properties?.StartDate) {
|
2046
|
-
this.contextService.update({
|
2047
|
-
properties: {
|
2048
|
-
...this._runtimeContext.properties,
|
2049
|
-
...context.properties,
|
2050
|
-
},
|
2051
|
-
});
|
2052
|
-
}
|
2053
|
-
return this._runtimeContext;
|
2054
|
-
}), tap(() => (this._isInitialized = true)));
|
2055
|
-
}
|
2056
|
-
overrideUIDefinition(uiDefinitionContainer) {
|
2057
|
-
if (!this._runtimeContext) {
|
2058
|
-
return;
|
2059
|
-
}
|
2060
|
-
this._runtimeContext.uiDefinitionContainer = uiDefinitionContainer;
|
2061
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
2062
|
-
}
|
2063
|
-
id15to18(propertyName, source) {
|
2064
|
-
if (!source) {
|
2065
|
-
return;
|
2066
|
-
}
|
2067
|
-
const value = source[propertyName];
|
2068
|
-
if (typeof value === 'string' && value.length === 15) {
|
2069
|
-
source[propertyName] = SalesforceIdUtils.generateId18FromId15(value);
|
2070
|
-
}
|
2071
|
-
}
|
2072
|
-
get isInitialized() {
|
2073
|
-
return this._isInitialized;
|
1173
|
+
this.stateSubj$.next(null);
|
2074
1174
|
}
|
2075
|
-
|
2076
|
-
|
2077
|
-
}
|
2078
|
-
get runtimeContext() {
|
2079
|
-
return this._runtimeContext;
|
1175
|
+
setState(state) {
|
1176
|
+
this.stateSubj$.next(state);
|
2080
1177
|
}
|
2081
1178
|
}
|
2082
|
-
|
2083
|
-
|
2084
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1179
|
+
CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1180
|
+
CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
|
1181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
|
2085
1182
|
type: Injectable
|
2086
|
-
}]
|
1183
|
+
}] });
|
2087
1184
|
|
2088
1185
|
class ConfigurationStateService {
|
2089
|
-
constructor(configurationRuntimeService, configurationService,
|
1186
|
+
constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService) {
|
2090
1187
|
this.configurationRuntimeService = configurationRuntimeService;
|
2091
1188
|
this.configurationService = configurationService;
|
2092
|
-
this.quoteDraftService = quoteDraftService;
|
2093
|
-
this.toastService = toastService;
|
2094
1189
|
this.flowStateService = flowStateService;
|
2095
1190
|
this.flowInfoService = flowInfoService;
|
2096
1191
|
this.flowConfigurationService = flowConfigurationService;
|
2097
1192
|
this.flowStateApiService = flowStateApiService;
|
2098
|
-
this.
|
1193
|
+
this.salesTransactionService = salesTransactionService;
|
1194
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
1195
|
+
this.toastService = toastService;
|
2099
1196
|
this.isInitialized$ = new BehaviorSubject(false);
|
2100
1197
|
this.canceledConfiguration$ = new Subject();
|
2101
1198
|
this.NOT_INITIALIZED = Symbol();
|
@@ -2119,9 +1216,9 @@ class ConfigurationStateService {
|
|
2119
1216
|
request$ = this.initStateful$();
|
2120
1217
|
}
|
2121
1218
|
else {
|
2122
|
-
request$ = this.
|
1219
|
+
request$ = this.configurationService.init$();
|
2123
1220
|
}
|
2124
|
-
return request$.pipe(
|
1221
|
+
return request$.pipe(take(1), tap(() => {
|
2125
1222
|
this.isInitialized$.next(true);
|
2126
1223
|
this.canceledConfiguration$ = new Subject();
|
2127
1224
|
}));
|
@@ -2135,10 +1232,11 @@ class ConfigurationStateService {
|
|
2135
1232
|
this.configurationStore = {};
|
2136
1233
|
this.executedFunctions = {};
|
2137
1234
|
this.configurationService.reset();
|
1235
|
+
this.configurationRuntimeService.reset();
|
2138
1236
|
}
|
2139
1237
|
execute$(exec) {
|
2140
1238
|
const request = this.execToRequest(exec);
|
2141
|
-
return this.executeRequest$(request).pipe(map
|
1239
|
+
return this.executeRequest$(request).pipe(map(result => {
|
2142
1240
|
// Keep only requested results
|
2143
1241
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
2144
1242
|
if (exec.selectors?.[requestId]) {
|
@@ -2160,7 +1258,7 @@ class ConfigurationStateService {
|
|
2160
1258
|
}
|
2161
1259
|
// prevent parallel configuration requests in stateless mode
|
2162
1260
|
if (!this.statelessExecutionRequest$) {
|
2163
|
-
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay
|
1261
|
+
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
|
2164
1262
|
}
|
2165
1263
|
return this.statelessExecutionRequest$;
|
2166
1264
|
}
|
@@ -2174,7 +1272,7 @@ class ConfigurationStateService {
|
|
2174
1272
|
},
|
2175
1273
|
},
|
2176
1274
|
});
|
2177
|
-
return this.executeRequest$(request).pipe(map
|
1275
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
2178
1276
|
}
|
2179
1277
|
subscribe$(selectorName, inputData = {}, options) {
|
2180
1278
|
const requestId = UUID.UUID();
|
@@ -2197,56 +1295,42 @@ class ConfigurationStateService {
|
|
2197
1295
|
this.executeRequest$(request).subscribe();
|
2198
1296
|
}
|
2199
1297
|
}
|
2200
|
-
return subscription.data$.pipe(filter
|
1298
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
|
2201
1299
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
2202
1300
|
delete this.subscriptions[requestId];
|
2203
1301
|
}
|
2204
1302
|
}), takeUntil(this.canceledConfiguration$));
|
2205
1303
|
}
|
2206
|
-
saveConfiguration(
|
1304
|
+
saveConfiguration() {
|
2207
1305
|
if (this.isStatefulConfiguration) {
|
2208
|
-
return this.flowStateApiService
|
2209
|
-
|
2210
|
-
|
1306
|
+
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
|
1307
|
+
}
|
1308
|
+
const state = this.salesTransactionService.state;
|
1309
|
+
if (!state) {
|
1310
|
+
return of({ id: '' });
|
1311
|
+
}
|
1312
|
+
const { standalone } = this.flowInfoService.flow.properties;
|
1313
|
+
if (standalone) {
|
1314
|
+
return this.salesTransactionApiService.upsert(state);
|
1315
|
+
}
|
1316
|
+
const salesTransaction = this.salesTransactionService.state;
|
1317
|
+
const configurationRoot = this.configurationService.root;
|
1318
|
+
if (!salesTransaction || !configurationRoot) {
|
1319
|
+
return of({ id: '' });
|
1320
|
+
}
|
1321
|
+
const isNewTransactionItem = salesTransaction.salesTransactionItems.every(li => li.id !== configurationRoot.id);
|
1322
|
+
let salesTransactionItems;
|
1323
|
+
if (isNewTransactionItem) {
|
1324
|
+
salesTransactionItems = [...salesTransaction.salesTransactionItems, configurationRoot];
|
2211
1325
|
}
|
2212
1326
|
else {
|
2213
|
-
|
2214
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
2215
|
-
if (!quoteDraft) {
|
2216
|
-
return of({ quoteId: '' });
|
2217
|
-
}
|
2218
|
-
const rootLineItem = this.configurationService.getSnapshot();
|
2219
|
-
const asset = this.configurationService.getAsset();
|
2220
|
-
const currentState = rootLineItem ? [rootLineItem] : [];
|
2221
|
-
const initialState = asset ? [asset] : [];
|
2222
|
-
return this.quoteApiService.upsertQuote({ ...quoteDraft, currentState, initialState });
|
2223
|
-
}
|
2224
|
-
else {
|
2225
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
2226
|
-
const lineItem = this.configurationService.getSnapshot();
|
2227
|
-
if (!quoteDraft || !lineItem) {
|
2228
|
-
return of({ quoteId: '' });
|
2229
|
-
}
|
2230
|
-
const isNewLineItem = quoteDraft.currentState.every(li => li.id !== lineItem.id);
|
2231
|
-
let currentState;
|
2232
|
-
if (isNewLineItem) {
|
2233
|
-
currentState = [...quoteDraft.currentState, lineItem];
|
2234
|
-
}
|
2235
|
-
else {
|
2236
|
-
currentState = quoteDraft.currentState.map(li => (li.id === lineItem.id ? lineItem : li));
|
2237
|
-
}
|
2238
|
-
const asset = this.configurationService.getAsset();
|
2239
|
-
const initialState = [...(this.quoteDraftService.quoteDraft?.initialState ?? [])];
|
2240
|
-
if (asset) {
|
2241
|
-
if (!initialState.some(li => li.id === asset.id)) {
|
2242
|
-
initialState.push(asset);
|
2243
|
-
}
|
2244
|
-
}
|
2245
|
-
return this.flowConfigurationService
|
2246
|
-
.calculate$({ ...quoteDraft, currentState, initialState })
|
2247
|
-
.pipe(map$1(() => ({ quoteId: '' })));
|
2248
|
-
}
|
1327
|
+
salesTransactionItems = salesTransaction.salesTransactionItems.map(ti => ti.id === configurationRoot.id ? configurationRoot : ti);
|
2249
1328
|
}
|
1329
|
+
const newState = {
|
1330
|
+
...salesTransaction,
|
1331
|
+
salesTransactionItems,
|
1332
|
+
};
|
1333
|
+
return this.flowConfigurationService.calculate$(newState).pipe(map(() => ({ id: '' })));
|
2250
1334
|
}
|
2251
1335
|
cancelConfiguration() {
|
2252
1336
|
if (!this.isInitialized$.value) {
|
@@ -2265,36 +1349,32 @@ class ConfigurationStateService {
|
|
2265
1349
|
return this.flowInfoService.flow?.properties.stateful ?? false;
|
2266
1350
|
}
|
2267
1351
|
initStateful$() {
|
2268
|
-
this.ownerId = this.configurationRuntimeService.
|
2269
|
-
const
|
2270
|
-
if (!this.flowStateService.stateId) {
|
1352
|
+
this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
|
1353
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
1354
|
+
if (!productId || !this.flowStateService.stateId) {
|
2271
1355
|
return of(undefined);
|
2272
1356
|
}
|
2273
|
-
const container = this.configurationRuntimeService.
|
2274
|
-
const lineItem = this.configurationService.generateLineItem();
|
1357
|
+
const container = this.configurationRuntimeService.uiDefinitionContainer;
|
2275
1358
|
let request$;
|
2276
|
-
if (!
|
1359
|
+
if (!transactionItemId) {
|
2277
1360
|
request$ = this.flowStateApiService.newConfiguration(this.flowStateService.stateId, {
|
2278
|
-
|
1361
|
+
transactionItem: generateTransactionItem(productId),
|
2279
1362
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2280
1363
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2281
1364
|
});
|
2282
1365
|
}
|
2283
1366
|
else {
|
2284
1367
|
request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
|
2285
|
-
|
1368
|
+
transactionItemId,
|
2286
1369
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2287
1370
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2288
1371
|
});
|
2289
1372
|
}
|
2290
|
-
return request$.pipe(map
|
1373
|
+
return request$.pipe(map(r => {
|
2291
1374
|
this.stateId = r.stateId;
|
2292
1375
|
return undefined;
|
2293
1376
|
}));
|
2294
1377
|
}
|
2295
|
-
initStateless$() {
|
2296
|
-
return this.configurationService.configure().pipe(map$1(() => undefined));
|
2297
|
-
}
|
2298
1378
|
execToRequest(exec) {
|
2299
1379
|
return {
|
2300
1380
|
actions: exec.actions?.map(action => ({
|
@@ -2334,37 +1414,35 @@ class ConfigurationStateService {
|
|
2334
1414
|
else {
|
2335
1415
|
execution$ = this.executeStateless$(fullRequest);
|
2336
1416
|
}
|
2337
|
-
return execution$.pipe(tap
|
1417
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
2338
1418
|
}
|
2339
1419
|
executeStateless$(request) {
|
2340
1420
|
this.executionInProgress$.next(true);
|
2341
|
-
return
|
1421
|
+
return this.configurationService.state$.pipe(switchMap(state => {
|
2342
1422
|
// Apply actions and execute configuration/price call
|
2343
1423
|
// No need to run configuration if no actions in the request
|
2344
1424
|
if (!request.actions?.length) {
|
2345
1425
|
return of(undefined);
|
2346
1426
|
}
|
2347
|
-
let configurationRequest = this.configurationService.generateRequest(false);
|
2348
1427
|
request.actions.forEach(action => {
|
2349
|
-
|
1428
|
+
state = this.executeActionScript(state, action) ?? state;
|
2350
1429
|
});
|
2351
|
-
|
2352
|
-
|
2353
|
-
}), map$1(() => {
|
1430
|
+
return this.configurationService.configureRequest$(state);
|
1431
|
+
}), map(() => {
|
2354
1432
|
// Run selectors and apply them to the state
|
2355
|
-
const configurationState = this.configurationService.
|
1433
|
+
const configurationState = this.configurationService.state;
|
2356
1434
|
if (!configurationState) {
|
2357
1435
|
return { stateId: '', selectors: {} };
|
2358
1436
|
}
|
2359
1437
|
return this.runStatelessSelectors(request, configurationState);
|
2360
|
-
}), tap
|
2361
|
-
const configurationState = this.configurationService.
|
1438
|
+
}), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
|
1439
|
+
const configurationState = this.configurationService.previousState;
|
2362
1440
|
if (configurationState) {
|
2363
1441
|
const selectorsResult = this.runStatelessSelectors(request, configurationState);
|
2364
1442
|
this.handleSelectorsResponse(selectorsResult.selectors);
|
2365
1443
|
}
|
2366
1444
|
this.executionInProgress$.next(false);
|
2367
|
-
if (!this.configurationRuntimeService.
|
1445
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
2368
1446
|
this.toastService.add({ severity: ToastType.error, summary: String(error) });
|
2369
1447
|
}
|
2370
1448
|
return throwError(() => error);
|
@@ -2385,21 +1463,21 @@ class ConfigurationStateService {
|
|
2385
1463
|
};
|
2386
1464
|
this.executionInProgress$.next(true);
|
2387
1465
|
return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
|
2388
|
-
}), tap
|
1466
|
+
}), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
2389
1467
|
this.executionInProgress$.next(false);
|
2390
1468
|
return throwError(() => e);
|
2391
1469
|
}));
|
2392
1470
|
}
|
2393
1471
|
executeStateful$(request) {
|
2394
|
-
return this.executionInProgress$.pipe(filter
|
1472
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
2395
1473
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
2396
1474
|
combineLatest([
|
2397
1475
|
this.statefulExecutionRequest$,
|
2398
|
-
of(undefined).pipe(tap
|
2399
|
-
])), map
|
1476
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1477
|
+
])), map(([response]) => response), take(1));
|
2400
1478
|
}
|
2401
1479
|
executeActionScript(request, processor) {
|
2402
|
-
const { actions } = this.configurationRuntimeService.
|
1480
|
+
const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2403
1481
|
const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
|
2404
1482
|
if (!configurationProcessor?.script) {
|
2405
1483
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2407,7 +1485,7 @@ class ConfigurationStateService {
|
|
2407
1485
|
return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
|
2408
1486
|
}
|
2409
1487
|
executeSelectorScript(request, processor) {
|
2410
|
-
const { selectors } = this.configurationRuntimeService.
|
1488
|
+
const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2411
1489
|
const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
|
2412
1490
|
if (!configurationProcessor?.script) {
|
2413
1491
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2448,25 +1526,52 @@ class ConfigurationStateService {
|
|
2448
1526
|
}, { stateId: '', selectors: {} });
|
2449
1527
|
}
|
2450
1528
|
}
|
2451
|
-
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token:
|
1529
|
+
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 });
|
2452
1530
|
ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
|
2453
1531
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
|
2454
1532
|
type: Injectable
|
2455
|
-
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type:
|
1533
|
+
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type: FlowStateService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i3.FlowStateApiService }, { type: SalesTransactionService }, { type: i1.SalesTransactionApiService }, { type: i6.ToastService }]; } });
|
2456
1534
|
|
2457
1535
|
class ConfigurationModule {
|
2458
1536
|
}
|
2459
1537
|
ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2460
1538
|
ConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, imports: [ConfirmationDialogModule, ApiModule] });
|
2461
|
-
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1539
|
+
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1540
|
+
ConfigurationService,
|
1541
|
+
ConfigurationStateService,
|
1542
|
+
ConfigurationRuntimeService,
|
1543
|
+
TestModeConfigurationService,
|
1544
|
+
], imports: [ConfirmationDialogModule, ApiModule] });
|
2462
1545
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
|
2463
1546
|
type: NgModule,
|
2464
1547
|
args: [{
|
2465
1548
|
imports: [ConfirmationDialogModule, ApiModule],
|
2466
|
-
providers: [
|
1549
|
+
providers: [
|
1550
|
+
ConfigurationService,
|
1551
|
+
ConfigurationStateService,
|
1552
|
+
ConfigurationRuntimeService,
|
1553
|
+
TestModeConfigurationService,
|
1554
|
+
],
|
1555
|
+
}]
|
1556
|
+
}] });
|
1557
|
+
|
1558
|
+
class FlowConfigurationModule {
|
1559
|
+
}
|
1560
|
+
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
1561
|
+
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
1562
|
+
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
|
1563
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
1564
|
+
type: NgModule,
|
1565
|
+
args: [{
|
1566
|
+
imports: [ApiModule],
|
1567
|
+
providers: [FlowConfigurationService],
|
2467
1568
|
}]
|
2468
1569
|
}] });
|
2469
1570
|
|
1571
|
+
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
1572
|
+
|
1573
|
+
const UI_DEFINITION_VERSION = 3;
|
1574
|
+
|
2470
1575
|
const DEFAULT_FORMATTING_SETTINGS = {
|
2471
1576
|
currencySymbol: DEFAULT_CURRENCY_SYMBOL,
|
2472
1577
|
decimalsCount: DEFAULT_DECIMALS_COUNT,
|
@@ -2480,14 +1585,14 @@ class SdkCoreModule {
|
|
2480
1585
|
SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2481
1586
|
SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
|
2482
1587
|
SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
|
2483
|
-
ContextService,
|
2484
1588
|
FlowInfoService,
|
2485
|
-
QuoteDraftService,
|
2486
1589
|
ProductImagesService,
|
2487
1590
|
IntegrationState,
|
2488
1591
|
FlowStateService,
|
2489
1592
|
FlowStateConfigurationService,
|
2490
1593
|
RuntimeSettingsService,
|
1594
|
+
SalesTransactionService,
|
1595
|
+
CatalogProductsService,
|
2491
1596
|
{
|
2492
1597
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2493
1598
|
useExisting: RuntimeSettingsService,
|
@@ -2498,14 +1603,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2498
1603
|
args: [{
|
2499
1604
|
imports: [ConfigurationModule, FlowConfigurationModule],
|
2500
1605
|
providers: [
|
2501
|
-
ContextService,
|
2502
1606
|
FlowInfoService,
|
2503
|
-
QuoteDraftService,
|
2504
1607
|
ProductImagesService,
|
2505
1608
|
IntegrationState,
|
2506
1609
|
FlowStateService,
|
2507
1610
|
FlowStateConfigurationService,
|
2508
1611
|
RuntimeSettingsService,
|
1612
|
+
SalesTransactionService,
|
1613
|
+
CatalogProductsService,
|
2509
1614
|
{
|
2510
1615
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2511
1616
|
useExisting: RuntimeSettingsService,
|
@@ -2561,6 +1666,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2561
1666
|
}]
|
2562
1667
|
}] });
|
2563
1668
|
|
1669
|
+
function filterSuccessfulExecute() {
|
1670
|
+
return (source) => source.pipe(filter((result) => result.success), map(r => r.result));
|
1671
|
+
}
|
1672
|
+
|
2564
1673
|
class DatePipe {
|
2565
1674
|
constructor() {
|
2566
1675
|
this.locale = inject(LOCALE_ID);
|
@@ -2680,5 +1789,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2680
1789
|
* Generated bundle index. Do not edit.
|
2681
1790
|
*/
|
2682
1791
|
|
2683
|
-
export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService,
|
1792
|
+
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 };
|
2684
1793
|
//# sourceMappingURL=veloceapps-sdk-core.mjs.map
|