@veloceapps/sdk 11.0.0-8 → 11.0.0-80
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/components/preview/preview.component.d.ts +5 -6
- package/cms/components/preview/preview.types.d.ts +0 -4
- package/cms/services/element-context.service.d.ts +0 -1
- package/cms/types/common.types.d.ts +2 -0
- package/cms/types/index.d.ts +0 -1
- package/cms/utils/path.utils.d.ts +1 -2
- package/cms/vendor-map.d.ts +17 -40
- package/core/index.d.ts +1 -1
- package/core/modules/configuration/index.d.ts +3 -4
- package/core/modules/configuration/services/configuration-runtime.service.d.ts +8 -19
- package/core/modules/configuration/services/configuration-state.service.d.ts +8 -8
- package/core/modules/configuration/services/configuration.service.d.ts +23 -47
- package/core/modules/configuration/services/test-mode-configuration.service.d.ts +23 -0
- package/core/modules/configuration/types/configuration-runtime.types.d.ts +0 -5
- package/core/modules/configuration/types/configuration.types.d.ts +4 -2
- 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 -38
- 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 +27 -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 +27 -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/element-tools-panel/element-tools-panel.component.mjs +3 -3
- package/esm2020/cms/components/preview/preview.component.mjs +19 -28
- package/esm2020/cms/components/preview/preview.types.mjs +1 -1
- package/esm2020/cms/services/element-context.service.mjs +1 -1
- package/esm2020/cms/types/common.types.mjs +1 -1
- package/esm2020/cms/types/index.mjs +1 -2
- package/esm2020/cms/utils/element.utils.mjs +3 -3
- package/esm2020/cms/utils/elements-resolver.mjs +16 -5
- package/esm2020/cms/utils/path.utils.mjs +1 -10
- package/esm2020/cms/vendor-map.mjs +17 -18
- package/esm2020/core/core.module.mjs +7 -7
- package/esm2020/core/index.mjs +2 -2
- package/esm2020/core/modules/configuration/configuration.module.mjs +14 -4
- package/esm2020/core/modules/configuration/index.mjs +4 -5
- package/esm2020/core/modules/configuration/services/configuration-runtime.service.mjs +16 -101
- package/esm2020/core/modules/configuration/services/configuration-state.service.mjs +65 -77
- package/esm2020/core/modules/configuration/services/configuration.service.mjs +109 -223
- package/esm2020/core/modules/configuration/services/test-mode-configuration.service.mjs +74 -0
- package/esm2020/core/modules/configuration/types/configuration-runtime.types.mjs +1 -1
- package/esm2020/core/modules/configuration/types/configuration.types.mjs +1 -1
- package/esm2020/core/modules/configuration/types/index.mjs +3 -0
- package/esm2020/core/modules/flow-configuration/flow-configuration.module.mjs +3 -4
- package/esm2020/core/modules/flow-configuration/index.mjs +1 -4
- package/esm2020/core/modules/flow-configuration/services/flow-configuration.service.mjs +44 -128
- 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 +82 -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 +62 -0
- package/esm2020/core/types/flow-customization.types.mjs +1 -1
- package/esm2020/core/types/flow-state.types.mjs +1 -1
- package/esm2020/core/types/index.mjs +1 -2
- package/esm2020/core/utils/index.mjs +3 -3
- package/esm2020/core/utils/transaction-item.utils.mjs +60 -0
- package/esm2020/core/utils/transaction-item.worker.mjs +16 -0
- package/esm2020/src/components/flow-header/flow-header.component.mjs +8 -12
- package/esm2020/src/components/guided-selling/guided-selling.component.mjs +8 -12
- package/esm2020/src/flow-routing.module.mjs +12 -41
- package/esm2020/src/flow.component.mjs +5 -5
- package/esm2020/src/guards/flow.guard.mjs +13 -14
- package/esm2020/src/guards/product-unload.guard.mjs +7 -9
- package/esm2020/src/index.mjs +1 -3
- package/esm2020/src/pages/assets/assets.component.mjs +8 -9
- package/esm2020/src/pages/catalog/catalog.component.mjs +8 -9
- package/esm2020/src/pages/debug/debug.component.mjs +14 -23
- package/esm2020/src/pages/product/product.component.mjs +12 -89
- package/esm2020/src/pages/product/product.module.mjs +5 -5
- package/esm2020/src/pages/record-not-found/record-not-found.component.mjs +5 -6
- package/esm2020/src/pages/shopping-cart/shopping-cart.component.mjs +8 -9
- package/esm2020/src/resolvers/flow.resolver.mjs +10 -18
- package/esm2020/src/resolvers/pcm-model.resolver.mjs +12 -0
- package/esm2020/src/resolvers/sales-transaction.resolver.mjs +64 -0
- package/esm2020/src/resolvers/ui-definition.resolver.mjs +42 -0
- package/esm2020/src/services/flow-dialog.service.mjs +8 -8
- package/esm2020/src/services/flow-router.service.mjs +16 -33
- package/esm2020/src/services/flow.service.mjs +13 -54
- package/esm2020/src/types/index.mjs +2 -3
- package/esm2020/src/types/route.types.mjs +1 -1
- package/fesm2015/veloceapps-sdk-cms.mjs +162 -309
- package/fesm2015/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk-core.mjs +812 -1657
- package/fesm2015/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk.mjs +188 -801
- package/fesm2015/veloceapps-sdk.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-cms.mjs +158 -300
- package/fesm2020/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-core.mjs +875 -1741
- package/fesm2020/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk.mjs +188 -795
- package/fesm2020/veloceapps-sdk.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/flow-header/flow-header.component.d.ts +3 -3
- package/src/components/guided-selling/guided-selling.component.d.ts +3 -3
- package/src/flow-routing.module.d.ts +1 -2
- package/src/flow.component.d.ts +2 -2
- package/src/guards/product-unload.guard.d.ts +5 -6
- package/src/index.d.ts +0 -2
- package/src/pages/assets/assets.component.d.ts +3 -3
- package/src/pages/catalog/catalog.component.d.ts +3 -3
- package/src/pages/debug/debug.component.d.ts +2 -5
- package/src/pages/product/product.component.d.ts +5 -14
- package/src/pages/product/product.module.d.ts +1 -1
- package/src/pages/record-not-found/record-not-found.component.d.ts +2 -3
- package/src/pages/shopping-cart/shopping-cart.component.d.ts +3 -3
- package/src/resolvers/flow.resolver.d.ts +5 -6
- package/src/resolvers/pcm-model.resolver.d.ts +3 -0
- package/src/resolvers/sales-transaction.resolver.d.ts +18 -0
- package/src/resolvers/ui-definition.resolver.d.ts +3 -0
- package/src/services/flow-dialog.service.d.ts +5 -4
- package/src/services/flow-router.service.d.ts +4 -6
- package/src/services/flow.service.d.ts +2 -7
- package/src/types/index.d.ts +1 -2
- package/src/types/route.types.d.ts +0 -5
- package/cms/plugins/configuration.plugin.d.ts +0 -23
- package/cms/types/configuration.types.d.ts +0 -21
- package/core/modules/configuration/helpers.d.ts +0 -6
- package/core/modules/configuration/services/runtime-context.service.d.ts +0 -12
- package/core/modules/flow-configuration/services/flow-update.service.d.ts +0 -13
- package/core/modules/flow-configuration/types/update.types.d.ts +0 -12
- package/core/services/context.service.d.ts +0 -23
- package/core/services/quote-draft.service.d.ts +0 -50
- package/core/types/runtime.types.d.ts +0 -30
- package/core/utils/line-item.utils.d.ts +0 -25
- package/core/utils/line-item.worker.d.ts +0 -9
- package/esm2020/cms/plugins/configuration.plugin.mjs +0 -109
- package/esm2020/cms/types/configuration.types.mjs +0 -2
- package/esm2020/core/modules/configuration/helpers.mjs +0 -73
- package/esm2020/core/modules/configuration/services/runtime-context.service.mjs +0 -45
- package/esm2020/core/modules/flow-configuration/services/flow-update.service.mjs +0 -138
- package/esm2020/core/modules/flow-configuration/types/update.types.mjs +0 -2
- package/esm2020/core/services/context.service.mjs +0 -91
- package/esm2020/core/services/quote-draft.service.mjs +0 -192
- package/esm2020/core/types/runtime.types.mjs +0 -16
- package/esm2020/core/utils/line-item.utils.mjs +0 -187
- package/esm2020/core/utils/line-item.worker.mjs +0 -19
- package/esm2020/src/guards/context.guard.mjs +0 -91
- package/esm2020/src/guards/index.mjs +0 -2
- package/esm2020/src/pages/remote/remote.component.mjs +0 -342
- package/esm2020/src/pages/remote/remote.module.mjs +0 -20
- package/esm2020/src/pages/remote/remote.types.mjs +0 -2
- package/esm2020/src/resolvers/quote.resolver.mjs +0 -82
- package/esm2020/src/types/context-route.types.mjs +0 -2
- package/esm2020/src/types/metrics.types.mjs +0 -2
- package/esm2020/src/utils/flow.utils.mjs +0 -25
- package/esm2020/src/utils/index.mjs +0 -2
- package/src/guards/context.guard.d.ts +0 -19
- package/src/guards/index.d.ts +0 -1
- package/src/pages/remote/remote.component.d.ts +0 -46
- package/src/pages/remote/remote.module.d.ts +0 -10
- package/src/pages/remote/remote.types.d.ts +0 -4
- package/src/resolvers/quote.resolver.d.ts +0 -19
- package/src/types/context-route.types.d.ts +0 -5
- package/src/types/metrics.types.d.ts +0 -5
- package/src/utils/flow.utils.d.ts +0 -8
- package/src/utils/index.d.ts +0 -1
@@ -1,249 +1,243 @@
|
|
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, noop, throwError, Subject, catchError as catchError$1, combineLatest, finalize as finalize$1, buffer, debounceTime, share, take, distinctUntilChanged, shareReplay, takeUntil, first } from 'rxjs';
|
10
|
+
import { uniqBy, flatten, omit, cloneDeep, assign, isEqual } from 'lodash';
|
11
|
+
import * as i2 from 'primeng/api';
|
12
|
+
import { filter as filter$1, map as map$1, tap as tap$1, catchError, finalize } from 'rxjs/operators';
|
15
13
|
import { NgControl } from '@angular/forms';
|
16
14
|
import 'primeng/calendar';
|
17
15
|
import { DATE_PIPE_DEFAULT_OPTIONS, formatDate } from '@angular/common';
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
return {
|
24
|
-
id,
|
25
|
-
type: uiDefinitionProperties.rootType ?? '',
|
26
|
-
cfgStatus: 'Default',
|
27
|
-
actionCode: 'ADD',
|
28
|
-
qty,
|
29
|
-
attributes,
|
30
|
-
lineItems,
|
31
|
-
productName: context.properties?.['displayName'] || context.productName,
|
32
|
-
productId: context.productId ?? '',
|
33
|
-
...(uiDefinitionProperties.offeringId ? { offeringId: uiDefinitionProperties.offeringId } : {}),
|
34
|
-
};
|
35
|
-
};
|
36
|
-
const getGuidedSellingConfigurationRequest = (data, context) => {
|
37
|
-
const _context = { ...context };
|
38
|
-
delete _context.configurationToken;
|
39
|
-
const properties = { ...context.properties };
|
40
|
-
delete properties['ConfigurationToken'];
|
41
|
-
return {
|
42
|
-
mode: 'SEARCH',
|
43
|
-
step: 'START',
|
44
|
-
attributeDomainMode: 'ALL',
|
45
|
-
context: {
|
46
|
-
..._context,
|
47
|
-
mode: ConfigurationContextMode.TEST,
|
48
|
-
properties: {
|
49
|
-
...properties,
|
50
|
-
ModelId: data.modelId,
|
51
|
-
Name: 'Veloce Guided Selling',
|
52
|
-
PricingEnabled: 'false',
|
53
|
-
RuntimeMode: 'TEST',
|
54
|
-
},
|
55
|
-
},
|
56
|
-
lineItem: {
|
57
|
-
actionCode: 'ADD',
|
58
|
-
cfgStatus: 'Default',
|
59
|
-
id: UUID.UUID(),
|
60
|
-
qty: 1,
|
61
|
-
type: data.modelType,
|
62
|
-
attributes: Object.entries(data.attributesMap).map(([name, value]) => ({
|
63
|
-
name,
|
64
|
-
value,
|
65
|
-
cfgStatus: 'User',
|
66
|
-
})),
|
67
|
-
},
|
68
|
-
};
|
69
|
-
};
|
70
|
-
const generateConfigurationLineItem = (props, qty = 1) => {
|
71
|
-
const id = UUID.UUID();
|
72
|
-
const attributes = Object.entries(props.attributesMap ?? {}).map(([name, value]) => ({
|
73
|
-
name,
|
74
|
-
value,
|
75
|
-
cfgStatus: 'User',
|
76
|
-
}));
|
77
|
-
const lineItems = [];
|
78
|
-
return {
|
79
|
-
id,
|
80
|
-
type: props.product.typeName ?? '',
|
81
|
-
cfgStatus: 'Default',
|
82
|
-
actionCode: 'ADD',
|
83
|
-
qty,
|
84
|
-
attributes,
|
85
|
-
lineItems,
|
86
|
-
productName: props.product.name,
|
87
|
-
productId: props.product.id ?? '',
|
88
|
-
};
|
89
|
-
};
|
90
|
-
|
91
|
-
class ContextService {
|
92
|
-
constructor(contextApiService) {
|
93
|
-
this.contextApiService = contextApiService;
|
94
|
-
this.context = new BehaviorSubject(null);
|
17
|
+
class ConfigurationRuntimeService {
|
18
|
+
constructor(pcmApiService) {
|
19
|
+
this.pcmApiService = pcmApiService;
|
20
|
+
this.uiDefinitionContainer = null;
|
95
21
|
}
|
96
|
-
get
|
97
|
-
return
|
22
|
+
get uiDefinitionProps() {
|
23
|
+
return this.uiDefinitionContainer?.source.properties ?? {};
|
98
24
|
}
|
99
|
-
|
100
|
-
|
25
|
+
reset() {
|
26
|
+
this.uiDefinitionContainer = null;
|
27
|
+
this.initializationProps = undefined;
|
28
|
+
this.pcmModel = undefined;
|
101
29
|
}
|
102
|
-
|
103
|
-
|
30
|
+
init$(props) {
|
31
|
+
this.initializationProps = props;
|
32
|
+
return this.pcmApiService.fetchPCMByProductId(props.productId).pipe(tap(pcmModel => (this.pcmModel = pcmModel)));
|
33
|
+
}
|
34
|
+
}
|
35
|
+
ConfigurationRuntimeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, deps: [{ token: i1.PCMApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
36
|
+
ConfigurationRuntimeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService });
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, decorators: [{
|
38
|
+
type: Injectable
|
39
|
+
}], ctorParameters: function () { return [{ type: i1.PCMApiService }]; } });
|
40
|
+
|
41
|
+
const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
|
42
|
+
|
43
|
+
class RuntimeSettingsService {
|
44
|
+
constructor(configurationSettingsApiService) {
|
45
|
+
this.configurationSettingsApiService = configurationSettingsApiService;
|
46
|
+
this.configurationSettings$ = new BehaviorSubject({});
|
47
|
+
this.currencySettings$ = new BehaviorSubject({
|
48
|
+
iso: DEFAULT_CURRENCY_ISO_CODE,
|
49
|
+
symbol: DEFAULT_CURRENCY_SYMBOL,
|
50
|
+
});
|
51
|
+
this.shoppingCartSettings$ = new BehaviorSubject([]);
|
52
|
+
this.getCurrencySymbol = (locale, currency) => {
|
53
|
+
return (0)
|
54
|
+
.toLocaleString(locale, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 0 })
|
55
|
+
.replace(/\d/g, '')
|
56
|
+
.trim();
|
57
|
+
};
|
104
58
|
}
|
105
|
-
|
106
|
-
return this.
|
59
|
+
create() {
|
60
|
+
return this.configurationSettingsApiService.fetchSettings().pipe(map(settings => this.parseConfigurationSettings(settings)), tap(configurationSettings => {
|
61
|
+
this.configurationSettings$.next(configurationSettings);
|
62
|
+
this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
|
63
|
+
this.formattingSettings = this.getFormattingSettings();
|
64
|
+
}), map(() => undefined));
|
107
65
|
}
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
66
|
+
initCurrency(iso) {
|
67
|
+
if (iso) {
|
68
|
+
const symbol = this.getCurrencySymbol('en-US', iso);
|
69
|
+
this.currencySettings$.next({ iso, symbol });
|
70
|
+
if (this.formattingSettings) {
|
71
|
+
this.formattingSettings.currencySymbol = symbol;
|
72
|
+
}
|
115
73
|
}
|
116
|
-
return false;
|
117
74
|
}
|
118
|
-
|
119
|
-
if (
|
120
|
-
|
75
|
+
getFormattingSettings() {
|
76
|
+
if (this.formattingSettings) {
|
77
|
+
return this.formattingSettings;
|
121
78
|
}
|
122
|
-
|
79
|
+
const shoppingCartSettings = this.getConfigurationSettings()['shopping-cart']?.reduce((acc, setting) => {
|
80
|
+
return { ...acc, [setting.id]: setting.properties };
|
81
|
+
}, {});
|
82
|
+
const currencySettings = this.getCurrencySettings();
|
83
|
+
const dateFormat = (validateDateFormat(shoppingCartSettings?.DATE_FORMAT ?? '') && shoppingCartSettings?.DATE_FORMAT) ||
|
84
|
+
DEFAULT_DATE_FORMAT;
|
85
|
+
const decimalSeparator = shoppingCartSettings?.DECIMAL_SEPARATOR;
|
86
|
+
const thousandsSeparator = shoppingCartSettings?.THOUSANDS_SEPARATOR;
|
87
|
+
// the number of decimal places can be 0
|
88
|
+
const priceScale = shoppingCartSettings?.PRICE_SCALE;
|
89
|
+
const decimalsCount = priceScale !== null && priceScale !== '' && !isNaN(Number(priceScale)) && Number(priceScale) >= 0
|
90
|
+
? Number(priceScale)
|
91
|
+
: DEFAULT_DECIMALS_COUNT;
|
92
|
+
const actionCodeSettings = shoppingCartSettings?.STATUS_LABEL;
|
93
|
+
return {
|
94
|
+
currencySymbol: currencySettings.symbol,
|
95
|
+
dateFormats: getSupportedDateFormats(dateFormat),
|
96
|
+
decimalsCount,
|
97
|
+
decimalSeparator: decimalSeparator !== undefined && ['.', ','].includes(decimalSeparator)
|
98
|
+
? decimalSeparator
|
99
|
+
: DEFAULT_DECIMAL_SEPARATOR,
|
100
|
+
// thousands separator can be a blank value, so it can also be null
|
101
|
+
thousandsSeparator: thousandsSeparator !== undefined && ['.', ',', '', null].includes(thousandsSeparator)
|
102
|
+
? thousandsSeparator || ''
|
103
|
+
: DEFAULT_THOUSANDS_SEPARATOR,
|
104
|
+
actionCodeLabels: actionCodeSettings?.length
|
105
|
+
? actionCodeSettings.reduce((result, setting) => ({ ...result, [setting.status_label]: setting.custom_label }), {})
|
106
|
+
: DEFAULT_ACTION_CODE_LABELS,
|
107
|
+
};
|
123
108
|
}
|
124
|
-
|
125
|
-
return this.
|
109
|
+
getConfigurationSettings() {
|
110
|
+
return this.configurationSettings$.value;
|
126
111
|
}
|
127
|
-
|
128
|
-
return this.
|
112
|
+
getShoppingCartSettings() {
|
113
|
+
return this.shoppingCartSettings$.value;
|
129
114
|
}
|
130
|
-
|
131
|
-
return this.
|
132
|
-
return this.update({
|
133
|
-
properties: {
|
134
|
-
...context.properties,
|
135
|
-
RuntimeMode: ConfigurationContextMode.TEST,
|
136
|
-
StartDate: new Date().toISOString().substring(0, 10),
|
137
|
-
standalone: 'true',
|
138
|
-
},
|
139
|
-
});
|
140
|
-
}));
|
115
|
+
getCurrencySettings() {
|
116
|
+
return this.currencySettings$.value;
|
141
117
|
}
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
...context,
|
160
|
-
};
|
161
|
-
this.context.next(updatedContext);
|
162
|
-
return updatedContext;
|
118
|
+
parseConfigurationSettings(settings) {
|
119
|
+
return settings.reduce((acc, setting) => {
|
120
|
+
switch (setting.key) {
|
121
|
+
case 'shopping-cart':
|
122
|
+
acc['shopping-cart'] = parseJsonSafely(setting.value, []);
|
123
|
+
break;
|
124
|
+
case 'navigation':
|
125
|
+
acc.navigation = parseJsonSafely(setting.value, {});
|
126
|
+
break;
|
127
|
+
case 'flows':
|
128
|
+
acc.flows = parseJsonSafely(setting.value, []);
|
129
|
+
break;
|
130
|
+
default:
|
131
|
+
acc[setting.key] = setting.value;
|
132
|
+
}
|
133
|
+
return acc;
|
134
|
+
}, {});
|
163
135
|
}
|
164
|
-
|
165
|
-
|
136
|
+
addShoppingCartSettings(settings) {
|
137
|
+
// uniqBy removes items with the biggest index
|
138
|
+
const newSettings = uniqBy([...settings, ...this.shoppingCartSettings$.value], 'id');
|
139
|
+
this.shoppingCartSettings$.next(newSettings);
|
166
140
|
}
|
167
141
|
}
|
168
|
-
|
169
|
-
|
170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
142
|
+
RuntimeSettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, deps: [{ token: i1.ConfigurationSettingsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
143
|
+
RuntimeSettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService });
|
144
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, decorators: [{
|
171
145
|
type: Injectable
|
172
|
-
}], ctorParameters: function () { return [{ type: i1.
|
173
|
-
|
174
|
-
const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
|
175
|
-
|
176
|
-
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
177
|
-
|
178
|
-
var RuntimeMode;
|
179
|
-
(function (RuntimeMode) {
|
180
|
-
RuntimeMode[RuntimeMode["TEST"] = 0] = "TEST";
|
181
|
-
RuntimeMode[RuntimeMode["PROD"] = 1] = "PROD";
|
182
|
-
})(RuntimeMode || (RuntimeMode = {}));
|
183
|
-
var RuntimeOperation;
|
184
|
-
(function (RuntimeOperation) {
|
185
|
-
RuntimeOperation["INIT"] = "INIT";
|
186
|
-
RuntimeOperation["UPDATE"] = "UPDATE";
|
187
|
-
})(RuntimeOperation || (RuntimeOperation = {}));
|
188
|
-
var RuntimeStep;
|
189
|
-
(function (RuntimeStep) {
|
190
|
-
RuntimeStep["START"] = "START";
|
191
|
-
RuntimeStep["UPDATE"] = "UPDATE";
|
192
|
-
})(RuntimeStep || (RuntimeStep = {}));
|
193
|
-
|
194
|
-
const UI_DEFINITION_VERSION = 3;
|
146
|
+
}], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
|
195
147
|
|
196
148
|
class FlowInfoService {
|
197
149
|
get flow() {
|
150
|
+
if (!this.flowSubj$.value) {
|
151
|
+
throw new Error(`Flow not initialized yet`);
|
152
|
+
}
|
198
153
|
return this.flowSubj$.value;
|
199
154
|
}
|
200
|
-
|
201
|
-
this.flowSubj$.
|
155
|
+
get isFlowInitialized() {
|
156
|
+
return Boolean(this.flowSubj$.value);
|
157
|
+
}
|
158
|
+
get context() {
|
159
|
+
if (!this.contextSubj$.value) {
|
160
|
+
throw new Error('Context is not initialized yet!');
|
161
|
+
}
|
162
|
+
return { ...this.contextSubj$.value };
|
163
|
+
}
|
164
|
+
get context$() {
|
165
|
+
return this.contextSubj$.asObservable().pipe(filter(isDefined));
|
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
|
+
updateContext(update) {
|
198
|
+
this.contextSubj$.next({
|
199
|
+
...this.context,
|
200
|
+
...update,
|
201
|
+
});
|
202
|
+
}
|
203
|
+
initFlow$(flowId, routeQueryParams) {
|
204
|
+
const flow = this.runtimeSettingsService.getConfigurationSettings()['flows']?.find(({ id }) => flowId === id);
|
205
|
+
if (!flow) {
|
206
|
+
this.flowSubj$.next(null);
|
207
|
+
throw new Error(`Flow with flowId=${flowId} is not defined`);
|
208
|
+
}
|
209
|
+
const headerId = routeQueryParams['headerId'];
|
210
|
+
if (typeof headerId !== 'string') {
|
211
|
+
throw new Error(`Please provide 'headerId'`);
|
212
|
+
}
|
213
|
+
const mode = this.getFlowContextMode(headerId);
|
214
|
+
// Restrict if mode is not defined
|
215
|
+
if (mode == null) {
|
216
|
+
throw new Error('Mode is undefined');
|
217
|
+
}
|
218
|
+
this.contextSubj$.next({
|
219
|
+
...flow.properties.queryParams,
|
220
|
+
...routeQueryParams,
|
221
|
+
mode,
|
222
|
+
});
|
223
|
+
this.flowSubj$.next(flow);
|
224
|
+
return of(undefined);
|
233
225
|
}
|
234
|
-
initFlowTemplates$(
|
226
|
+
initFlowTemplates$() {
|
235
227
|
return forkJoin([
|
236
|
-
this.
|
228
|
+
this.templatesAdminApiService.fetchTemplates$(),
|
237
229
|
this.customizationService?.getTemplates?.() ?? of([]),
|
238
|
-
]).pipe(map
|
239
|
-
|
230
|
+
]).pipe(map(([templates, localTemplates]) => {
|
231
|
+
const newValue = {};
|
232
|
+
Object.entries({ ...this.defaultTemplates, ...(this.flow?.properties.templates ?? {}) }).forEach(([key, name]) => {
|
240
233
|
const type = this.remapTemplateName(key);
|
241
234
|
if (type) {
|
242
|
-
|
235
|
+
newValue[type] =
|
243
236
|
localTemplates.find(template => template.name === name && template.type === type) ??
|
244
237
|
templates.find(template => template.name === name && template.type === type);
|
245
238
|
}
|
246
239
|
});
|
240
|
+
this.templatesSubj$.next(newValue);
|
247
241
|
}));
|
248
242
|
}
|
249
243
|
remapTemplateName(templateType) {
|
@@ -269,207 +263,439 @@ class FlowInfoService {
|
|
269
263
|
}
|
270
264
|
return undefined;
|
271
265
|
}
|
266
|
+
getFlowContextMode(headerId) {
|
267
|
+
const objectName = SalesforceIdUtils.getSfObjectNameById(headerId);
|
268
|
+
if (!objectName) {
|
269
|
+
return;
|
270
|
+
}
|
271
|
+
return objectName.toUpperCase();
|
272
|
+
}
|
272
273
|
}
|
273
|
-
FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token:
|
274
|
+
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
275
|
FlowInfoService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService });
|
275
276
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, decorators: [{
|
276
277
|
type: Injectable
|
277
|
-
}], ctorParameters: function () { return [{ type:
|
278
|
+
}], ctorParameters: function () { return [{ type: RuntimeSettingsService }, { type: i1.UITemplatesAdminApiService }, { type: undefined, decorators: [{
|
278
279
|
type: Optional
|
279
280
|
}, {
|
280
281
|
type: Inject,
|
281
282
|
args: [FLOW_CUSTOMIZATION]
|
282
283
|
}] }]; } });
|
283
284
|
|
284
|
-
|
285
|
-
|
286
|
-
|
285
|
+
const findTransactionItem = (id, items) => {
|
286
|
+
return findTransactionItemWithComparator(items, (ti) => ti.id === id);
|
287
|
+
};
|
288
|
+
const findTransactionItemWithComparator = (items, comparator) => {
|
289
|
+
let currentLevel = items;
|
290
|
+
while (currentLevel.length) {
|
291
|
+
const found = currentLevel.find(comparator);
|
292
|
+
if (found) {
|
293
|
+
return found;
|
294
|
+
}
|
295
|
+
currentLevel = flatten(currentLevel.map(parent => parent.children));
|
287
296
|
}
|
288
|
-
|
289
|
-
|
297
|
+
return;
|
298
|
+
};
|
299
|
+
const insertTransactionItem = (item, parentId, toInsert) => {
|
300
|
+
const insertData = item.id === parentId ? [toInsert] : [];
|
301
|
+
return {
|
302
|
+
...item,
|
303
|
+
children: [
|
304
|
+
...insertData,
|
305
|
+
...item.children.map(ti => {
|
306
|
+
return insertTransactionItem(ti, parentId, toInsert);
|
307
|
+
}),
|
308
|
+
],
|
309
|
+
};
|
310
|
+
};
|
311
|
+
const removeTransactionItem = (item, idToRemove) => {
|
312
|
+
return {
|
313
|
+
...item,
|
314
|
+
children: item.children
|
315
|
+
.map(ti => {
|
316
|
+
if (ti.id === idToRemove) {
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
else if (ti.children.length) {
|
320
|
+
return removeTransactionItem(ti, idToRemove);
|
321
|
+
}
|
322
|
+
return ti;
|
323
|
+
})
|
324
|
+
.filter(isDefined),
|
325
|
+
};
|
326
|
+
};
|
327
|
+
const replaceTransactionItem = (item, replaceTo) => {
|
328
|
+
if (item.id === replaceTo.id) {
|
329
|
+
return { ...replaceTo };
|
290
330
|
}
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
331
|
+
return {
|
332
|
+
...item,
|
333
|
+
children: item.children.map(ti => replaceTransactionItem(ti, replaceTo)),
|
334
|
+
};
|
335
|
+
};
|
336
|
+
const generateTransactionItem = (productId) => {
|
337
|
+
return {
|
338
|
+
id: UUID.UUID(),
|
339
|
+
productId,
|
340
|
+
};
|
341
|
+
};
|
342
|
+
|
343
|
+
class TransactionItemWorker {
|
344
|
+
constructor(src) {
|
345
|
+
this.ti = { ...src };
|
295
346
|
}
|
296
|
-
|
297
|
-
return this.
|
347
|
+
insert(parentId, toInsert) {
|
348
|
+
return new TransactionItemWorker(insertTransactionItem(this.ti, parentId, toInsert));
|
298
349
|
}
|
299
|
-
|
300
|
-
this.
|
301
|
-
if (!this._hasUnsavedChanges) {
|
302
|
-
this.initialCurrentState = this.quoteDraft?.currentState ?? [];
|
303
|
-
}
|
350
|
+
remove(id) {
|
351
|
+
return new TransactionItemWorker(removeTransactionItem(this.ti, id));
|
304
352
|
}
|
305
|
-
|
306
|
-
return
|
353
|
+
replace(toReplace) {
|
354
|
+
return new TransactionItemWorker(replaceTransactionItem(this.ti, toReplace));
|
307
355
|
}
|
308
|
-
|
309
|
-
|
356
|
+
}
|
357
|
+
|
358
|
+
function extractMetadata(uiDefinition) {
|
359
|
+
return omit(uiDefinition, [
|
360
|
+
'children',
|
361
|
+
'pages',
|
362
|
+
'components',
|
363
|
+
]);
|
364
|
+
}
|
365
|
+
|
366
|
+
class ConfigurationService {
|
367
|
+
get state$() {
|
368
|
+
return this.configurationStateSubj$.asObservable().pipe(filter$1(isDefined));
|
310
369
|
}
|
311
|
-
get
|
312
|
-
return this.
|
370
|
+
get state() {
|
371
|
+
return this.configurationStateSubj$.getValue();
|
313
372
|
}
|
314
|
-
get
|
315
|
-
return
|
373
|
+
get previousState() {
|
374
|
+
return this.previousConfigurationStateSubj$.getValue();
|
316
375
|
}
|
317
|
-
get
|
318
|
-
return this.
|
376
|
+
get root$() {
|
377
|
+
return this.state$.pipe(map$1(state => state.salesTransaction.salesTransactionItems[0]), filter$1(isDefined));
|
319
378
|
}
|
320
|
-
|
321
|
-
this.
|
322
|
-
this.flowInfoService = flowInfoService;
|
323
|
-
this.accountApiService = accountApiService;
|
324
|
-
this.quoteApiService = quoteApiService;
|
325
|
-
this.quoteSubj$ = new BehaviorSubject(null);
|
326
|
-
this.assetsSubj$ = new BehaviorSubject(null);
|
327
|
-
this.resetSubj$ = new BehaviorSubject(true);
|
328
|
-
this.isInitializedSubj$ = new BehaviorSubject(false);
|
329
|
-
this.initialCurrentState = [];
|
330
|
-
this._hasUnsavedChanges = false;
|
331
|
-
this.reset$ = this.resetSubj$.asObservable();
|
332
|
-
this.isInitializedSubj$
|
333
|
-
.pipe(filter(isInitialized => isInitialized), switchMap$1(() => this.quoteSubj$.asObservable()), skip(1), tap(quote => this.markAsUpdated(quote)))
|
334
|
-
.subscribe();
|
379
|
+
get root() {
|
380
|
+
return this.configurationStateSubj$.getValue()?.salesTransaction.salesTransactionItems[0] ?? null;
|
335
381
|
}
|
336
|
-
|
337
|
-
this.
|
338
|
-
this.
|
339
|
-
this.
|
340
|
-
this.
|
382
|
+
constructor(flowInfoService, messageService, configurationRuntimeService, salesTransactionService, orchestrationsApiService) {
|
383
|
+
this.flowInfoService = flowInfoService;
|
384
|
+
this.messageService = messageService;
|
385
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
386
|
+
this.salesTransactionService = salesTransactionService;
|
387
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
341
388
|
this.hasUnsavedChanges = false;
|
389
|
+
this.configurationStateSubj$ = new BehaviorSubject(null);
|
390
|
+
this.previousConfigurationStateSubj$ = new BehaviorSubject(null);
|
391
|
+
this.isLoadingSubj$ = new BehaviorSubject(false);
|
392
|
+
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
342
393
|
}
|
343
|
-
|
344
|
-
const ctx = this.context.resolve();
|
345
|
-
const isAccountMode = this.context.mode === ConfigurationContextMode.ACCOUNT;
|
346
|
-
const accountId = isAccountMode ? headerId : ctx.properties.AccountId;
|
347
|
-
return zip(accountId ? this.accountApiService.getAssetsState(accountId, params) : of(null), isAccountMode
|
348
|
-
? of(QuoteDraft.emptyQuote(ConfigurationContextMode.ACCOUNT))
|
349
|
-
: this.quoteApiService.getQuoteState(headerId, params)).pipe(tap(([assets, quote]) => {
|
350
|
-
if (assets) {
|
351
|
-
this.assetsSubj$.next(assets);
|
352
|
-
}
|
353
|
-
this.quoteSubj$.next(quote);
|
354
|
-
if (assets && isAccountMode) {
|
355
|
-
this.context.update(assets.context);
|
356
|
-
}
|
357
|
-
else {
|
358
|
-
this.context.update(quote.context);
|
359
|
-
}
|
360
|
-
}), map(() => noop()), take(1));
|
361
|
-
}
|
362
|
-
finalizeInit() {
|
363
|
-
this.isInitialized = true;
|
394
|
+
reset() {
|
364
395
|
this.hasUnsavedChanges = false;
|
396
|
+
this.configurationStateSubj$.next(null);
|
397
|
+
this.previousConfigurationStateSubj$.next(null);
|
365
398
|
}
|
366
|
-
|
367
|
-
const
|
368
|
-
|
369
|
-
|
399
|
+
init$() {
|
400
|
+
const { state } = this.salesTransactionService;
|
401
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
402
|
+
if (!state || !productId) {
|
403
|
+
return of(undefined);
|
370
404
|
}
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
405
|
+
const salesTransactionItems = state?.salesTransaction.salesTransactionItems ?? [];
|
406
|
+
let isRootGenerated = false;
|
407
|
+
let transactionItem = salesTransactionItems.find(item => item.id === transactionItemId);
|
408
|
+
if (!transactionItem) {
|
409
|
+
transactionItem = salesTransactionItems.find(item => item.productId === productId);
|
410
|
+
}
|
411
|
+
if (!transactionItem) {
|
412
|
+
transactionItem = generateTransactionItem(productId);
|
413
|
+
isRootGenerated = true;
|
414
|
+
}
|
415
|
+
const configurationState = {
|
416
|
+
...state,
|
417
|
+
salesTransaction: {
|
418
|
+
...state.salesTransaction,
|
419
|
+
salesTransactionItems: transactionItem ? [transactionItem] : [],
|
420
|
+
},
|
421
|
+
};
|
422
|
+
return (isRootGenerated ? this.configureRequest$(configurationState) : of(configurationState)).pipe(tap$1(configurationState => {
|
423
|
+
this.configurationStateSubj$.next(configurationState);
|
424
|
+
this.previousConfigurationStateSubj$.next(configurationState);
|
425
|
+
}), map$1(noop));
|
375
426
|
}
|
376
|
-
|
377
|
-
const
|
378
|
-
if (!
|
379
|
-
return;
|
380
|
-
}
|
381
|
-
if (update.context) {
|
382
|
-
this.context.set(update.context);
|
427
|
+
patch$(transactionItem) {
|
428
|
+
const { state, root } = this;
|
429
|
+
if (!state) {
|
430
|
+
return throwError(() => new Error(`Configuration State is not initialized`));
|
383
431
|
}
|
384
|
-
|
385
|
-
|
386
|
-
...update,
|
387
|
-
});
|
388
|
-
}
|
389
|
-
updateByPriceSummary(priceSummary) {
|
390
|
-
const quoteDraft = this.quoteSubj$.value;
|
391
|
-
if (!quoteDraft) {
|
392
|
-
return;
|
432
|
+
if (!root) {
|
433
|
+
return throwError(() => new Error(`Root SalesTransactionItem not found`));
|
393
434
|
}
|
394
|
-
const
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
435
|
+
const newRoot = new TransactionItemWorker(root).replace(transactionItem).ti;
|
436
|
+
const newTransactionContext = {
|
437
|
+
...state,
|
438
|
+
salesTransaction: {
|
439
|
+
...state.salesTransaction,
|
440
|
+
salesTransactionItems: [newRoot],
|
441
|
+
},
|
442
|
+
};
|
443
|
+
return this.configureRequest$(newTransactionContext).pipe(catchError(error => {
|
444
|
+
console.error(error);
|
445
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
446
|
+
this.messageService.add({ severity: 'error', summary: error });
|
447
|
+
}
|
448
|
+
return throwError(() => error);
|
449
|
+
}), tap$1(() => {
|
450
|
+
if (!this.hasUnsavedChanges) {
|
451
|
+
this.hasUnsavedChanges = true;
|
452
|
+
}
|
453
|
+
}), map$1(noop));
|
404
454
|
}
|
405
|
-
|
406
|
-
this.
|
455
|
+
patch(transactionItem) {
|
456
|
+
this.patch$(transactionItem).subscribe();
|
407
457
|
}
|
408
|
-
|
409
|
-
|
458
|
+
configureRequest$(transactionContext) {
|
459
|
+
const request = {
|
460
|
+
transactionContext,
|
461
|
+
flowId: this.flowInfoService.flow.id,
|
462
|
+
};
|
463
|
+
this.isLoadingSubj$.next(true);
|
464
|
+
return this.orchestrationsApiService.apply$(request).pipe(tap$1(result => {
|
465
|
+
this.configurationStateSubj$.next(result);
|
466
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(result));
|
467
|
+
}), catchError(error => throwError(() => {
|
468
|
+
const resetState = this.previousConfigurationStateSubj$.getValue();
|
469
|
+
if (resetState) {
|
470
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(resetState));
|
471
|
+
this.configurationStateSubj$.next(resetState);
|
472
|
+
}
|
473
|
+
if (error.error) {
|
474
|
+
return extractErrorDetails(error.error).join('. ');
|
475
|
+
}
|
476
|
+
return error.message || JSON.stringify(error);
|
477
|
+
})), finalize(() => this.isLoadingSubj$.next(false)));
|
478
|
+
}
|
479
|
+
configureExternal$(props) {
|
480
|
+
// TODO: implement
|
481
|
+
throw new Error('Not implemented');
|
482
|
+
}
|
483
|
+
configureGuidedSelling$(data) {
|
484
|
+
// TODO: implement
|
485
|
+
throw new Error('Not implemented');
|
486
|
+
}
|
487
|
+
getPCMModel() {
|
488
|
+
const pcmModel = this.configurationRuntimeService.pcmModel;
|
489
|
+
if (!pcmModel) {
|
490
|
+
throw new Error('PCM model not initialized');
|
491
|
+
}
|
492
|
+
return pcmModel;
|
493
|
+
}
|
494
|
+
}
|
495
|
+
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 });
|
496
|
+
ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
|
497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
|
498
|
+
type: Injectable
|
499
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i2.MessageService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: i1.OrchestrationsApiService }]; } });
|
500
|
+
|
501
|
+
class TestModeConfigurationService {
|
502
|
+
constructor(flowInfoService, configurationService, configurationRuntimeService, salesTransactionService, runtimeSettingsService) {
|
503
|
+
this.flowInfoService = flowInfoService;
|
504
|
+
this.configurationService = configurationService;
|
505
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
506
|
+
this.salesTransactionService = salesTransactionService;
|
507
|
+
this.runtimeSettingsService = runtimeSettingsService;
|
508
|
+
this.isInitialized = false;
|
410
509
|
}
|
411
|
-
|
412
|
-
|
413
|
-
if (
|
414
|
-
|
510
|
+
initTestMode$(uiDefinitionContainer, options) {
|
511
|
+
this.configurationRuntimeService.uiDefinitionContainer = uiDefinitionContainer;
|
512
|
+
if (this.checkInitialized(uiDefinitionContainer)) {
|
513
|
+
this.configurationRuntimeService.pcmModel = this.pcmModel;
|
514
|
+
return of(undefined);
|
515
|
+
}
|
516
|
+
this.configurationService.reset();
|
517
|
+
const { productId, quoteId, flowId } = uiDefinitionContainer.source.properties ?? {};
|
518
|
+
if (!productId) {
|
519
|
+
return throwError(() => 'Unable to start the Configuration Preview: Product is missing.');
|
415
520
|
}
|
521
|
+
if (!quoteId) {
|
522
|
+
return throwError(() => `Unable to start the Configuration Preview: Quote is missing.`);
|
523
|
+
}
|
524
|
+
if (!flowId) {
|
525
|
+
return throwError(() => `Unable to start the Configuration Preview: Flow is missing.`);
|
526
|
+
}
|
527
|
+
return this.runtimeSettingsService.create().pipe(switchMap(() => this.flowInfoService.init$(flowId, { productId, headerId: quoteId })), switchMap(() => this.configurationRuntimeService.init$({ productId })), tap(pcmModel => (this.pcmModel = pcmModel)), switchMap(() => {
|
528
|
+
if (options?.customizationMode) {
|
529
|
+
return of(undefined);
|
530
|
+
}
|
531
|
+
return this.initConfiguration$(quoteId);
|
532
|
+
}), tap(() => (this.isInitialized = true)), map(noop));
|
533
|
+
}
|
534
|
+
initConfiguration$(quoteId) {
|
535
|
+
this.salesTransactionService.setState(this.getTestTransactionContext(quoteId));
|
536
|
+
return this.configurationService.init$().pipe(switchMap(() => this.configurationService.state
|
537
|
+
? this.configurationService.configureRequest$(this.configurationService.state)
|
538
|
+
: of(undefined)), map(noop));
|
539
|
+
}
|
540
|
+
getTestTransactionContext(quoteId) {
|
541
|
+
const testTransaction = {
|
542
|
+
id: quoteId,
|
543
|
+
businessObjectType: 'Quote',
|
544
|
+
salesTransactionItems: [],
|
545
|
+
};
|
416
546
|
return {
|
417
|
-
|
418
|
-
|
547
|
+
salesTransaction: testTransaction,
|
548
|
+
transactionId: quoteId,
|
549
|
+
businessObjectType: 'Quote',
|
550
|
+
childNodes: {},
|
551
|
+
id: UUID.UUID(),
|
552
|
+
tagAttributes: {},
|
419
553
|
};
|
420
554
|
}
|
421
|
-
|
422
|
-
return this.
|
555
|
+
checkInitialized(uiDefinitionContainer) {
|
556
|
+
return this.isInitialized && !!uiDefinitionContainer.source.properties?.persistTestState;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
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 }, { token: RuntimeSettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
560
|
+
TestModeConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService });
|
561
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService, decorators: [{
|
562
|
+
type: Injectable
|
563
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: ConfigurationService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: RuntimeSettingsService }]; } });
|
564
|
+
|
565
|
+
class SalesTransactionService {
|
566
|
+
get isInitialized$() {
|
567
|
+
return this.isInitializedSubj$.asObservable();
|
568
|
+
}
|
569
|
+
get isInitialized() {
|
570
|
+
return this.isInitializedSubj$.getValue();
|
571
|
+
}
|
572
|
+
set hasUnsavedChanges(value) {
|
573
|
+
this.hasUnsavedChangesSubj$.next(value);
|
574
|
+
if (!this.hasUnsavedChanges) {
|
575
|
+
this.initialState = this.state?.salesTransaction.salesTransactionItems ?? [];
|
576
|
+
}
|
577
|
+
}
|
578
|
+
get hasUnsavedChanges() {
|
579
|
+
return this.hasUnsavedChangesSubj$.getValue();
|
580
|
+
}
|
581
|
+
get state() {
|
582
|
+
return this.stateSubj$.getValue();
|
583
|
+
}
|
584
|
+
get hasProducts() {
|
585
|
+
return Boolean(this.state?.salesTransaction.salesTransactionItems.length);
|
586
|
+
}
|
587
|
+
constructor(salesTransactionApiService) {
|
588
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
589
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
590
|
+
this.isInitializedSubj$ = new BehaviorSubject(false);
|
591
|
+
this.hasUnsavedChangesSubj$ = new BehaviorSubject(false);
|
592
|
+
this.initialState = [];
|
593
|
+
this.hasUnsavedChanges$ = this.hasUnsavedChangesSubj$.asObservable();
|
594
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
423
595
|
}
|
424
|
-
|
425
|
-
return this.
|
596
|
+
init(headerId, params) {
|
597
|
+
return this.salesTransactionApiService.getState(headerId, params).pipe(tap(res => this.stateSubj$.next(res)));
|
426
598
|
}
|
427
|
-
|
428
|
-
|
599
|
+
finalizeInit() {
|
600
|
+
this.isInitializedSubj$.next(true);
|
601
|
+
this.hasUnsavedChanges = false;
|
429
602
|
}
|
430
|
-
|
431
|
-
|
603
|
+
reset() {
|
604
|
+
this.stateSubj$.next(null);
|
605
|
+
this.isInitializedSubj$.next(false);
|
606
|
+
this.hasUnsavedChangesSubj$.next(false);
|
432
607
|
}
|
433
|
-
|
434
|
-
return this.
|
608
|
+
getInitialState() {
|
609
|
+
return this.initialState;
|
435
610
|
}
|
436
|
-
|
437
|
-
|
611
|
+
setState(state) {
|
612
|
+
this.stateSubj$.next(state);
|
438
613
|
}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
614
|
+
}
|
615
|
+
SalesTransactionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, deps: [{ token: i1.SalesTransactionApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
616
|
+
SalesTransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService });
|
617
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, decorators: [{
|
618
|
+
type: Injectable
|
619
|
+
}], ctorParameters: function () { return [{ type: i1.SalesTransactionApiService }]; } });
|
620
|
+
|
621
|
+
class FlowConfigurationService {
|
622
|
+
constructor(orchestrationsApiService, salesTransactionService, flowInfoService) {
|
623
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
624
|
+
this.salesTransactionService = salesTransactionService;
|
625
|
+
this.flowInfoService = flowInfoService;
|
626
|
+
this.updatedSubj$ = new Subject();
|
627
|
+
this.updated$ = this.updatedSubj$.asObservable();
|
448
628
|
}
|
449
|
-
|
450
|
-
|
451
|
-
|
629
|
+
calculate$(state) {
|
630
|
+
return this.orchestrationsApiService
|
631
|
+
.apply$({ transactionContext: state, flowId: this.flowInfoService.flow.id })
|
632
|
+
.pipe(tap(result => this.salesTransactionService.setState(result)), map(noop));
|
633
|
+
}
|
634
|
+
calculate(state) {
|
635
|
+
this.calculate$(state).subscribe();
|
636
|
+
}
|
637
|
+
revert$(transactionItemId) {
|
638
|
+
const state = this.salesTransactionService.state;
|
639
|
+
const initialState = this.salesTransactionService.getInitialState();
|
640
|
+
const currentState = state?.salesTransaction.salesTransactionItems ?? [];
|
641
|
+
const currentItemIndex = currentState.findIndex(({ id }) => id === transactionItemId);
|
642
|
+
const currentItem = currentState[currentItemIndex];
|
643
|
+
const initialItem = initialState.find(({ integrationId }) => integrationId === currentItem?.integrationId);
|
644
|
+
if (!state || !currentItem || !initialItem) {
|
645
|
+
return of(null);
|
452
646
|
}
|
453
|
-
|
454
|
-
|
647
|
+
const updatedState = cloneDeep(currentState);
|
648
|
+
updatedState.splice(currentItemIndex, 1, initialItem);
|
649
|
+
return of([]).pipe(map(() => ({
|
650
|
+
...state,
|
651
|
+
salesTransaction: { ...state.salesTransaction, salesTransactionItems: updatedState },
|
652
|
+
})), tap(newState => this.salesTransactionService.setState(newState)), switchMap(newState => this.calculate$(newState)), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
653
|
+
}
|
654
|
+
revert(transactionItemId) {
|
655
|
+
this.revert$(transactionItemId).subscribe();
|
656
|
+
}
|
657
|
+
delete$(ids) {
|
658
|
+
const state = this.salesTransactionService.state;
|
659
|
+
if (!state) {
|
660
|
+
return of(null);
|
455
661
|
}
|
662
|
+
return of([]).pipe(map(() => state.salesTransaction.salesTransactionItems.filter(({ id }) => !ids.includes(id))), switchMap(updatedState => this.calculate$({
|
663
|
+
...state,
|
664
|
+
salesTransaction: { ...state.salesTransaction, salesTransactionItems: updatedState },
|
665
|
+
})), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
666
|
+
}
|
667
|
+
delete(ids) {
|
668
|
+
this.delete$(ids).subscribe();
|
669
|
+
}
|
670
|
+
handleErrorAndBounceBack() {
|
671
|
+
return (source$) => {
|
672
|
+
return source$.pipe(catchError$1(error => {
|
673
|
+
console.error(error);
|
674
|
+
// bounce back if configuration call has failed
|
675
|
+
const state = this.salesTransactionService.state;
|
676
|
+
if (state) {
|
677
|
+
this.salesTransactionService.setState(state);
|
678
|
+
this.updatedSubj$.next();
|
679
|
+
}
|
680
|
+
return throwError(() => error);
|
681
|
+
}));
|
682
|
+
};
|
456
683
|
}
|
457
684
|
}
|
458
|
-
|
459
|
-
|
460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
685
|
+
FlowConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, deps: [{ token: i1.OrchestrationsApiService }, { token: SalesTransactionService }, { token: FlowInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
|
686
|
+
FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
|
687
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
|
461
688
|
type: Injectable
|
462
|
-
}], ctorParameters: function () { return [{ type:
|
689
|
+
}], ctorParameters: function () { return [{ type: i1.OrchestrationsApiService }, { type: SalesTransactionService }, { type: FlowInfoService }]; } });
|
463
690
|
|
464
691
|
class FlowStateService {
|
465
|
-
constructor(
|
466
|
-
this.contextService = contextService;
|
467
|
-
this.quoteDraftService = quoteDraftService;
|
468
|
-
this.flowInfoService = flowInfoService;
|
692
|
+
constructor(flowConfiguration, flowInfoService, flowStateApiService, processorsApiService, salesTransactionApiService, salesTransactionService, toastService, customizationService) {
|
469
693
|
this.flowConfiguration = flowConfiguration;
|
470
|
-
this.
|
694
|
+
this.flowInfoService = flowInfoService;
|
471
695
|
this.flowStateApiService = flowStateApiService;
|
472
|
-
this.
|
696
|
+
this.processorsApiService = processorsApiService;
|
697
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
698
|
+
this.salesTransactionService = salesTransactionService;
|
473
699
|
this.toastService = toastService;
|
474
700
|
this.customizationService = customizationService;
|
475
701
|
this.NOT_INITIALIZED = Symbol();
|
@@ -486,68 +712,22 @@ class FlowStateService {
|
|
486
712
|
this.cleanup$ = new Subject();
|
487
713
|
this.statefulExecutionRequest$ = this.initBufferedRequest$();
|
488
714
|
/*
|
489
|
-
In stateless mode watch
|
490
|
-
all subscriptions get their updates according to updated
|
715
|
+
In stateless mode watch State changes and call executeRequest so that
|
716
|
+
all subscriptions get their updates according to updated State
|
491
717
|
*/
|
492
718
|
this.isInitialized$()
|
493
|
-
.pipe(filter
|
719
|
+
.pipe(filter(Boolean), filter(() => !this.flowInfoService.flow.properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
|
494
720
|
.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
721
|
}
|
540
722
|
init$() {
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
}
|
548
|
-
}));
|
723
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
724
|
+
return this.initProcessors$().pipe(switchMap(() => this.initStateful$()));
|
725
|
+
}
|
726
|
+
else {
|
727
|
+
return forkJoin([this.initStateless$(), this.initProcessors$()]).pipe(map(noop));
|
728
|
+
}
|
549
729
|
}
|
550
|
-
|
730
|
+
reset() {
|
551
731
|
Object.values(this.subscriptions).forEach(({ data$ }) => data$.complete());
|
552
732
|
this.subscriptions = {};
|
553
733
|
if (this.stateId$.value) {
|
@@ -559,9 +739,9 @@ class FlowStateService {
|
|
559
739
|
this.cleanup$.next();
|
560
740
|
}
|
561
741
|
get hasUnsavedChanges() {
|
562
|
-
return this.
|
742
|
+
return this.flowInfoService.flow.properties.stateful
|
563
743
|
? Array.from(this.trackedStatefulChangesMap.values()).some(Boolean)
|
564
|
-
: this.
|
744
|
+
: this.salesTransactionService.hasUnsavedChanges;
|
565
745
|
}
|
566
746
|
get stateId() {
|
567
747
|
return this.stateId$.value;
|
@@ -570,14 +750,14 @@ class FlowStateService {
|
|
570
750
|
return this.executionInProgress$.asObservable();
|
571
751
|
}
|
572
752
|
isInitialized$() {
|
573
|
-
return combineLatest([this.stateId$, this.
|
753
|
+
return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map(values => values.some(Boolean)));
|
574
754
|
}
|
575
755
|
isInitialized() {
|
576
|
-
return Boolean(this.stateId$.value) || this.
|
756
|
+
return Boolean(this.stateId$.value) || this.salesTransactionService.isInitialized;
|
577
757
|
}
|
578
758
|
execute$(scope, exec) {
|
579
759
|
const request = this.execToRequest(scope, exec);
|
580
|
-
return this.executeRequest$(request).pipe(map
|
760
|
+
return this.executeRequest$(request).pipe(map(result => {
|
581
761
|
// Keep only requested results
|
582
762
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
583
763
|
if (exec.selectors?.[requestId]) {
|
@@ -593,7 +773,7 @@ class FlowStateService {
|
|
593
773
|
actions: [{ name: action, inputData }],
|
594
774
|
};
|
595
775
|
const request = this.execToRequest(scope, exec);
|
596
|
-
return this.executeRequest$(request).pipe(map
|
776
|
+
return this.executeRequest$(request).pipe(map(noop));
|
597
777
|
}
|
598
778
|
select$(scope, selectorName, inputData) {
|
599
779
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -605,7 +785,7 @@ class FlowStateService {
|
|
605
785
|
},
|
606
786
|
},
|
607
787
|
});
|
608
|
-
return this.executeRequest$(request).pipe(map
|
788
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
609
789
|
}
|
610
790
|
subscribe$(scope, selectorName, inputData, options) {
|
611
791
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -631,16 +811,16 @@ class FlowStateService {
|
|
631
811
|
this.executeRequest$(request).subscribe();
|
632
812
|
}
|
633
813
|
}
|
634
|
-
return subscription.data$.pipe(filter
|
814
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), finalize$1(() => {
|
635
815
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
636
816
|
delete this.subscriptions[requestId];
|
637
817
|
}
|
638
818
|
}));
|
639
819
|
}
|
640
820
|
save$() {
|
641
|
-
if (this.
|
821
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
642
822
|
if (this.stateId$.value) {
|
643
|
-
return this.flowStateApiService.save(this.stateId$.value).pipe(tap
|
823
|
+
return this.flowStateApiService.save(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })), tap(() => {
|
644
824
|
Array.from(this.trackedStatefulChangesMap.keys()).forEach(key => {
|
645
825
|
this.trackedStatefulChangesMap.set(key, false);
|
646
826
|
});
|
@@ -648,30 +828,26 @@ class FlowStateService {
|
|
648
828
|
}
|
649
829
|
}
|
650
830
|
else {
|
651
|
-
const
|
652
|
-
if (
|
653
|
-
return this.
|
654
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
655
|
-
}));
|
831
|
+
const state = this.salesTransactionService.state;
|
832
|
+
if (state) {
|
833
|
+
return this.salesTransactionApiService.upsert(state);
|
656
834
|
}
|
657
835
|
}
|
658
|
-
return of({
|
836
|
+
return of({ id: '' });
|
659
837
|
}
|
660
838
|
submit$() {
|
661
|
-
if (this.
|
839
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
662
840
|
if (this.stateId$.value) {
|
663
|
-
return this.flowStateApiService.submit(this.stateId$.value);
|
841
|
+
return this.flowStateApiService.submit(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })));
|
664
842
|
}
|
665
843
|
}
|
666
844
|
else {
|
667
|
-
const
|
668
|
-
if (
|
669
|
-
return this.
|
670
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
671
|
-
}));
|
845
|
+
const state = this.salesTransactionService.state;
|
846
|
+
if (state) {
|
847
|
+
return this.salesTransactionApiService.submit(state);
|
672
848
|
}
|
673
849
|
}
|
674
|
-
return of({
|
850
|
+
return of({ id: '' });
|
675
851
|
}
|
676
852
|
getFlowStore() {
|
677
853
|
return this.flowStore;
|
@@ -709,10 +885,10 @@ class FlowStateService {
|
|
709
885
|
fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
|
710
886
|
}
|
711
887
|
}
|
712
|
-
const execution$ = this.
|
888
|
+
const execution$ = this.flowInfoService.flow.properties.stateful
|
713
889
|
? this.executeStateful$(fullRequest)
|
714
890
|
: this.executeStateless$(fullRequest);
|
715
|
-
return execution$.pipe(tap
|
891
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
716
892
|
}
|
717
893
|
handleSelectorsResponse(selectors) {
|
718
894
|
Object.entries(selectors).forEach(([requestId, selectorResult]) => {
|
@@ -727,31 +903,21 @@ class FlowStateService {
|
|
727
903
|
});
|
728
904
|
}
|
729
905
|
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
906
|
const processorsList = flatten(Object.values(this.processors).map(ownerMap => Object.values(ownerMap ?? {})));
|
739
907
|
const processors = processorsList.length ? processorsList : undefined;
|
740
908
|
const selectors = Object.values(this.subscriptions)
|
741
909
|
.map(({ request }) => request.selectors)
|
742
910
|
.filter(isDefined)
|
743
911
|
.reduce((trunk, selectors) => ({ ...trunk, ...selectors }), {});
|
744
|
-
const request = this.getDefaultExecutionRequestDTO();
|
745
912
|
return this.flowStateApiService
|
746
913
|
.init({
|
747
|
-
quoteId: this.
|
748
|
-
params: this.flowInfoService.
|
914
|
+
quoteId: this.flowInfoService.context.headerId,
|
915
|
+
params: this.flowInfoService.context,
|
749
916
|
actionsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.ACTION),
|
750
917
|
selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
|
751
|
-
selectors:
|
752
|
-
actions: request.actions,
|
918
|
+
selectors: selectors,
|
753
919
|
})
|
754
|
-
.pipe(map
|
920
|
+
.pipe(map(({ stateId, selectors }) => {
|
755
921
|
this.handleSelectorsResponse(selectors);
|
756
922
|
this.stateId$.next(stateId);
|
757
923
|
}));
|
@@ -771,1095 +937,170 @@ class FlowStateService {
|
|
771
937
|
};
|
772
938
|
this.executionInProgress$.next(true);
|
773
939
|
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 => {
|
940
|
+
}), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
835
941
|
this.executionInProgress$.next(false);
|
836
942
|
return throwError(() => e);
|
837
943
|
}));
|
838
944
|
}
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
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;
|
1653
|
-
}
|
1654
|
-
applyChargeUpdate(lineItem, update) {
|
1655
|
-
const foundCharge = lineItem.chargeItems.find(({ id }) => id === update.id);
|
1656
|
-
if (!foundCharge) {
|
1657
|
-
return false;
|
1658
|
-
}
|
1659
|
-
if (update.attributeType === 'PRICE_ADJUSTMENT') {
|
1660
|
-
foundCharge.priceAdjustment = update.newValue;
|
1661
|
-
}
|
1662
|
-
else if (update.attributeType === 'LIST_PRICE_ADJUSTMENT') {
|
1663
|
-
foundCharge.listPriceAdjustment = update.newValue;
|
1664
|
-
}
|
1665
|
-
else {
|
1666
|
-
throw new Error(`Not suppored AttributeType for Charge Item update: ${update.attributeType}`);
|
1667
|
-
}
|
1668
|
-
return true;
|
945
|
+
executeStateful$(request) {
|
946
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
947
|
+
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
948
|
+
combineLatest([
|
949
|
+
this.statefulExecutionRequest$,
|
950
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
951
|
+
])), map(([response]) => response), take(1));
|
1669
952
|
}
|
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;
|
953
|
+
initStateless$() {
|
954
|
+
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
955
|
}
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
this.
|
1702
|
-
|
956
|
+
executeStateless$(request) {
|
957
|
+
this.executionInProgress$.next(true);
|
958
|
+
return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
|
959
|
+
/*
|
960
|
+
Skip price calculation in case
|
961
|
+
1. No actions in the request
|
962
|
+
2. Initialization process execution (state not initialized yet)
|
963
|
+
*/
|
964
|
+
const { state } = this.salesTransactionService;
|
965
|
+
if (!state || !request.actions?.length || !this.isInitialized()) {
|
966
|
+
return of(undefined);
|
967
|
+
}
|
968
|
+
else {
|
969
|
+
return this.flowConfiguration.calculate$(state);
|
970
|
+
}
|
971
|
+
}), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
972
|
+
this.executionInProgress$.next(false);
|
973
|
+
return throwError(() => e);
|
974
|
+
}));
|
1703
975
|
}
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
976
|
+
executeStatelessActions(request) {
|
977
|
+
const state = this.salesTransactionService.state;
|
978
|
+
if (!state || !request.actions?.length) {
|
979
|
+
return;
|
980
|
+
}
|
981
|
+
let flowState = state;
|
982
|
+
request.actions.forEach(action => {
|
983
|
+
try {
|
984
|
+
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
985
|
+
}
|
986
|
+
catch (e) {
|
987
|
+
console.error(e);
|
988
|
+
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
989
|
+
throw e;
|
990
|
+
}
|
991
|
+
});
|
992
|
+
this.salesTransactionService.setState(flowState);
|
1713
993
|
}
|
1714
|
-
|
1715
|
-
this.
|
994
|
+
executeStatelessSelectors(request) {
|
995
|
+
if (!this.salesTransactionService.state) {
|
996
|
+
throw 'State is not initialized';
|
997
|
+
}
|
998
|
+
const flowState = this.salesTransactionService.state;
|
999
|
+
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
1000
|
+
try {
|
1001
|
+
result.selectors[key] = {
|
1002
|
+
success: true,
|
1003
|
+
result: this.executeSelectorScript(flowState, selector),
|
1004
|
+
};
|
1005
|
+
}
|
1006
|
+
catch (e) {
|
1007
|
+
console.error(e);
|
1008
|
+
result.selectors[key] = {
|
1009
|
+
success: false,
|
1010
|
+
errorMessage: String(e),
|
1011
|
+
};
|
1012
|
+
}
|
1013
|
+
return result;
|
1014
|
+
}, { stateId: '', selectors: {} });
|
1716
1015
|
}
|
1717
|
-
|
1718
|
-
const
|
1719
|
-
if (!
|
1720
|
-
|
1016
|
+
initProcessors$() {
|
1017
|
+
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
1018
|
+
if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
|
1019
|
+
// Skip initialization as backend will take processors from SF
|
1020
|
+
return of(undefined);
|
1721
1021
|
}
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
return of(null);
|
1022
|
+
const owners$ = Object.values(this.flowInfoService.templates)
|
1023
|
+
.map(template => {
|
1024
|
+
if (!template) {
|
1025
|
+
return;
|
1026
|
+
}
|
1027
|
+
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
1028
|
+
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
|
1029
|
+
const processorsMap = processors.reduce((acc, p) => {
|
1030
|
+
acc[p.apiName] = p;
|
1031
|
+
return acc;
|
1032
|
+
}, {});
|
1033
|
+
this.processors[template.id] = processorsMap;
|
1034
|
+
}));
|
1035
|
+
})
|
1036
|
+
.filter(isDefined);
|
1037
|
+
if (!owners$.length) {
|
1038
|
+
return of(undefined);
|
1740
1039
|
}
|
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());
|
1746
|
-
}
|
1747
|
-
revert(lineItemId) {
|
1748
|
-
this.revert$(lineItemId).subscribe();
|
1040
|
+
return forkJoin(owners$).pipe(map(noop));
|
1749
1041
|
}
|
1750
|
-
|
1751
|
-
const
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1042
|
+
executeActionScript(request, executable) {
|
1043
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1044
|
+
if (!configurationProcessor?.script) {
|
1045
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1046
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1047
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1755
1048
|
}
|
1756
|
-
return
|
1757
|
-
}
|
1758
|
-
delete(ids) {
|
1759
|
-
this.delete$(ids).subscribe();
|
1049
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1760
1050
|
}
|
1761
|
-
|
1762
|
-
const
|
1763
|
-
if (!
|
1764
|
-
|
1051
|
+
executeSelectorScript(request, executable) {
|
1052
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1053
|
+
if (!configurationProcessor?.script) {
|
1054
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1055
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1056
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1765
1057
|
}
|
1766
|
-
|
1767
|
-
return of([]).pipe(switchMap(() => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
1058
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1768
1059
|
}
|
1769
|
-
|
1770
|
-
const
|
1771
|
-
|
1772
|
-
|
1060
|
+
executeProcessorScript(request, configurationProcessor, inputData) {
|
1061
|
+
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
1062
|
+
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
1063
|
+
if (!functionToExecute) {
|
1064
|
+
const script = `${configurationProcessor.script}\nreturn transform;`;
|
1065
|
+
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
1066
|
+
functionToExecute = new Function(script + sourceMap)();
|
1067
|
+
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
1773
1068
|
}
|
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$();
|
1069
|
+
return functionToExecute({
|
1070
|
+
request,
|
1071
|
+
inputData,
|
1072
|
+
flowStore: this.flowStore,
|
1073
|
+
});
|
1810
1074
|
}
|
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
|
-
};
|
1075
|
+
generateRequestId(scope, selectorName, inputData) {
|
1076
|
+
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
1077
|
+
return `${scope}/${selectorName}/${inputDataHash}`;
|
1824
1078
|
}
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1079
|
+
checkStatefulChanges(requestId, selectorResult) {
|
1080
|
+
if (this.trackedStatefulChangesMap.has(requestId)) {
|
1081
|
+
if (!this.initialStatefulData[requestId]) {
|
1082
|
+
this.initialStatefulData[requestId] = selectorResult;
|
1083
|
+
}
|
1084
|
+
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
1085
|
+
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
1830
1086
|
}
|
1831
|
-
return this.proceduresApiService.apply$(request);
|
1832
1087
|
}
|
1833
1088
|
}
|
1834
|
-
|
1835
|
-
|
1836
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1089
|
+
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 });
|
1090
|
+
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
1091
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
1837
1092
|
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
|
-
}] });
|
1093
|
+
}], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i3.FlowStateApiService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
1094
|
+
type: Optional
|
1095
|
+
}, {
|
1096
|
+
type: Inject,
|
1097
|
+
args: [FLOW_CUSTOMIZATION]
|
1098
|
+
}] }]; } });
|
1852
1099
|
|
1853
1100
|
class FlowStateConfigurationService {
|
1854
|
-
constructor(flowInfoService,
|
1101
|
+
constructor(flowInfoService, flowStateService) {
|
1855
1102
|
this.flowInfoService = flowInfoService;
|
1856
|
-
this.flowConfigurationService = flowConfigurationService;
|
1857
|
-
this.flowStateApiService = flowStateApiService;
|
1858
1103
|
this.flowStateService = flowStateService;
|
1859
|
-
this.configurationStateId$ = new BehaviorSubject(null);
|
1860
|
-
}
|
1861
|
-
get configurationStateId() {
|
1862
|
-
return this.configurationStateId$.value;
|
1863
1104
|
}
|
1864
1105
|
addToCart$(props) {
|
1865
1106
|
let request$;
|
@@ -1870,26 +1111,22 @@ class FlowStateConfigurationService {
|
|
1870
1111
|
request$ = of();
|
1871
1112
|
}
|
1872
1113
|
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
|
-
}));
|
1114
|
+
// TODO: Implement
|
1115
|
+
request$ = of();
|
1880
1116
|
}
|
1881
1117
|
}
|
1882
1118
|
else {
|
1883
|
-
|
1119
|
+
// TODO: Implement
|
1120
|
+
request$ = of();
|
1884
1121
|
}
|
1885
|
-
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map
|
1122
|
+
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1886
1123
|
}
|
1887
1124
|
}
|
1888
|
-
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token:
|
1125
|
+
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
1126
|
FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
|
1890
1127
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
|
1891
1128
|
type: Injectable
|
1892
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type:
|
1129
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }]; } });
|
1893
1130
|
|
1894
1131
|
class IntegrationState {
|
1895
1132
|
constructor() {
|
@@ -1909,12 +1146,12 @@ class IntegrationState {
|
|
1909
1146
|
this.action$.next(action);
|
1910
1147
|
}
|
1911
1148
|
listen$(actionType) {
|
1912
|
-
return this.action$.pipe(filter
|
1149
|
+
return this.action$.pipe(filter(action => action.type === actionType), map(action => action.payload));
|
1913
1150
|
}
|
1914
1151
|
listenAll$() {
|
1915
1152
|
return this.action$.asObservable();
|
1916
1153
|
}
|
1917
|
-
|
1154
|
+
reset() {
|
1918
1155
|
this.stateSubj$.next({});
|
1919
1156
|
}
|
1920
1157
|
}
|
@@ -1925,8 +1162,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1925
1162
|
}] });
|
1926
1163
|
|
1927
1164
|
class ProductImagesService {
|
1928
|
-
constructor(
|
1929
|
-
this.
|
1165
|
+
constructor(productsAdminApiService) {
|
1166
|
+
this.productsAdminApiService = productsAdminApiService;
|
1930
1167
|
this.imagesMap$ = new BehaviorSubject({});
|
1931
1168
|
}
|
1932
1169
|
getImageUrl$(productId) {
|
@@ -1934,172 +1171,53 @@ class ProductImagesService {
|
|
1934
1171
|
this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
|
1935
1172
|
this.fetchProductImage(productId);
|
1936
1173
|
}
|
1937
|
-
return this.imagesMap$.pipe(map
|
1174
|
+
return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
|
1938
1175
|
}
|
1939
1176
|
fetchProductImage(productId) {
|
1940
|
-
this.
|
1177
|
+
this.productsAdminApiService
|
1941
1178
|
.fetchImage$(productId)
|
1942
|
-
.pipe(map
|
1179
|
+
.pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
|
1943
1180
|
.subscribe();
|
1944
1181
|
}
|
1945
1182
|
}
|
1946
|
-
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.
|
1183
|
+
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
1184
|
ProductImagesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService });
|
1948
1185
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, decorators: [{
|
1949
1186
|
type: Injectable
|
1950
|
-
}], ctorParameters: function () { return [{ type: i1.
|
1187
|
+
}], ctorParameters: function () { return [{ type: i1.ProductsAdminApiService }]; } });
|
1951
1188
|
|
1952
|
-
class
|
1953
|
-
constructor(
|
1954
|
-
this.
|
1955
|
-
|
1956
|
-
getRuntimeContext(productId, offeringId, defaultUIDefinitionId, requiredUIDefinitionId) {
|
1957
|
-
return this.configurationApiService
|
1958
|
-
.getRuntimeDataByProductId(productId, offeringId, defaultUIDefinitionId, requiredUIDefinitionId)
|
1959
|
-
.pipe(map(runtimeData => {
|
1960
|
-
const uiDefinitionContainer = this.getUIDefinitionContainer(runtimeData);
|
1961
|
-
const runtimeModel = RuntimeModel.create(runtimeData.types, runtimeData.products);
|
1962
|
-
const { productName, properties } = Array.from(runtimeModel.components.values()).find(c => c.productId === productId) ?? {};
|
1963
|
-
const uiDefinitionProperties = uiDefinitionContainer?.source.properties;
|
1964
|
-
return {
|
1965
|
-
modelId: runtimeData.modelId,
|
1966
|
-
uiDefinitionContainer: uiDefinitionContainer,
|
1967
|
-
runtimeModel: runtimeModel,
|
1968
|
-
runtimeMode: RuntimeMode.PROD,
|
1969
|
-
productId: productId,
|
1970
|
-
productType: properties?.['displayName'] || productName,
|
1971
|
-
offeringId: offeringId,
|
1972
|
-
properties: {
|
1973
|
-
PricingEnabled: uiDefinitionProperties?.pricingEnabled ? 'true' : 'false',
|
1974
|
-
PriceListId: uiDefinitionProperties?.priceList,
|
1975
|
-
},
|
1976
|
-
};
|
1977
|
-
}));
|
1978
|
-
}
|
1979
|
-
getUIDefinitionContainer(runtimeData) {
|
1980
|
-
const containers = runtimeData.uiDefinitions.filter(container => isNotLegacyUIDefinition(container.source));
|
1981
|
-
return containers.find(container => container.source.primary) ?? containers[0];
|
1189
|
+
class CatalogProductsService {
|
1190
|
+
constructor() {
|
1191
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
1192
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
1982
1193
|
}
|
1983
|
-
|
1984
|
-
|
1985
|
-
RuntimeContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService });
|
1986
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, decorators: [{
|
1987
|
-
type: Injectable
|
1988
|
-
}], ctorParameters: function () { return [{ type: i1.ConfigurationApiService }]; } });
|
1989
|
-
|
1990
|
-
class ConfigurationRuntimeService {
|
1991
|
-
constructor(apiService, contextService, runtimeContextService) {
|
1992
|
-
this.apiService = apiService;
|
1993
|
-
this.contextService = contextService;
|
1994
|
-
this.runtimeContextService = runtimeContextService;
|
1995
|
-
this._isInitialized = false;
|
1996
|
-
this.uiDefinitionProperties = {};
|
1194
|
+
get state() {
|
1195
|
+
return this.stateSubj$.getValue();
|
1997
1196
|
}
|
1998
1197
|
reset() {
|
1999
|
-
this.
|
2000
|
-
this._runtimeContext = undefined;
|
2001
|
-
this.initializationProps = undefined;
|
2002
|
-
this.uiDefinitionProperties = {};
|
2003
|
-
}
|
2004
|
-
initTestMode(uiDefinitionContainer) {
|
2005
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
2006
|
-
const uiDefinitionExternals = uiDefinitionContainer.source.externals ?? {};
|
2007
|
-
return combineLatest([
|
2008
|
-
this.apiService.getRuntimeDataByModelId(uiDefinitionContainer.modelId),
|
2009
|
-
this.contextService.initTestMode(),
|
2010
|
-
]).pipe(first(), map(([runtimeData, context]) => {
|
2011
|
-
this.contextService.update({
|
2012
|
-
properties: {
|
2013
|
-
...this.runtimeContext?.properties,
|
2014
|
-
...context.properties,
|
2015
|
-
ModelId: uiDefinitionContainer.modelId,
|
2016
|
-
PricingEnabled: this.uiDefinitionProperties.pricingEnabled ? 'true' : 'false',
|
2017
|
-
PriceListId: this.uiDefinitionProperties.priceList,
|
2018
|
-
offeringId: this.uiDefinitionProperties.offeringId,
|
2019
|
-
...uiDefinitionExternals,
|
2020
|
-
},
|
2021
|
-
});
|
2022
|
-
this._runtimeContext = {
|
2023
|
-
modelId: uiDefinitionContainer.modelId,
|
2024
|
-
runtimeModel: RuntimeModel.create(runtimeData.types, runtimeData.products),
|
2025
|
-
runtimeMode: RuntimeMode.TEST,
|
2026
|
-
uiDefinitionContainer,
|
2027
|
-
};
|
2028
|
-
return this._runtimeContext;
|
2029
|
-
}), tap(() => (this._isInitialized = true)));
|
2030
|
-
}
|
2031
|
-
init(props) {
|
2032
|
-
this.initializationProps = props;
|
2033
|
-
const context = this.contextService.resolve();
|
2034
|
-
return this.runtimeContextService
|
2035
|
-
.getRuntimeContext(props.productId, props.offeringId, props.defaultUIDefinitionId, props.requiredUIDefinitionId)
|
2036
|
-
.pipe(tap(runtimeContext => {
|
2037
|
-
this.uiDefinitionProperties = runtimeContext.uiDefinitionContainer?.source.properties ?? {};
|
2038
|
-
const { PriceListId } = context.properties ?? {};
|
2039
|
-
const mergeContext = {
|
2040
|
-
...runtimeContext,
|
2041
|
-
properties: {
|
2042
|
-
...runtimeContext.properties,
|
2043
|
-
...context.properties,
|
2044
|
-
PricingEnabled: PriceListId ? 'true' : 'false',
|
2045
|
-
},
|
2046
|
-
};
|
2047
|
-
this.id15to18('AccountId', mergeContext.properties);
|
2048
|
-
this._runtimeContext = mergeContext;
|
2049
|
-
if (context.properties && this._runtimeContext.properties?.StartDate) {
|
2050
|
-
this.contextService.update({
|
2051
|
-
properties: {
|
2052
|
-
...this._runtimeContext.properties,
|
2053
|
-
...context.properties,
|
2054
|
-
},
|
2055
|
-
});
|
2056
|
-
}
|
2057
|
-
return this._runtimeContext;
|
2058
|
-
}), tap(() => (this._isInitialized = true)));
|
2059
|
-
}
|
2060
|
-
overrideUIDefinition(uiDefinitionContainer) {
|
2061
|
-
if (!this._runtimeContext) {
|
2062
|
-
return;
|
2063
|
-
}
|
2064
|
-
this._runtimeContext.uiDefinitionContainer = uiDefinitionContainer;
|
2065
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
2066
|
-
}
|
2067
|
-
id15to18(propertyName, source) {
|
2068
|
-
if (!source) {
|
2069
|
-
return;
|
2070
|
-
}
|
2071
|
-
const value = source[propertyName];
|
2072
|
-
if (typeof value === 'string' && value.length === 15) {
|
2073
|
-
source[propertyName] = SalesforceIdUtils.generateId18FromId15(value);
|
2074
|
-
}
|
2075
|
-
}
|
2076
|
-
get isInitialized() {
|
2077
|
-
return this._isInitialized;
|
2078
|
-
}
|
2079
|
-
get runtimeModel() {
|
2080
|
-
return this.runtimeContext?.runtimeModel;
|
1198
|
+
this.stateSubj$.next(null);
|
2081
1199
|
}
|
2082
|
-
|
2083
|
-
|
1200
|
+
setState(state) {
|
1201
|
+
this.stateSubj$.next(state);
|
2084
1202
|
}
|
2085
1203
|
}
|
2086
|
-
|
2087
|
-
|
2088
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1204
|
+
CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1205
|
+
CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
|
1206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
|
2089
1207
|
type: Injectable
|
2090
|
-
}]
|
1208
|
+
}] });
|
2091
1209
|
|
2092
1210
|
class ConfigurationStateService {
|
2093
|
-
constructor(configurationRuntimeService, configurationService,
|
1211
|
+
constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService) {
|
2094
1212
|
this.configurationRuntimeService = configurationRuntimeService;
|
2095
1213
|
this.configurationService = configurationService;
|
2096
|
-
this.quoteDraftService = quoteDraftService;
|
2097
|
-
this.toastService = toastService;
|
2098
1214
|
this.flowStateService = flowStateService;
|
2099
1215
|
this.flowInfoService = flowInfoService;
|
2100
1216
|
this.flowConfigurationService = flowConfigurationService;
|
2101
1217
|
this.flowStateApiService = flowStateApiService;
|
2102
|
-
this.
|
1218
|
+
this.salesTransactionService = salesTransactionService;
|
1219
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
1220
|
+
this.toastService = toastService;
|
2103
1221
|
this.isInitialized$ = new BehaviorSubject(false);
|
2104
1222
|
this.canceledConfiguration$ = new Subject();
|
2105
1223
|
this.NOT_INITIALIZED = Symbol();
|
@@ -2123,9 +1241,9 @@ class ConfigurationStateService {
|
|
2123
1241
|
request$ = this.initStateful$();
|
2124
1242
|
}
|
2125
1243
|
else {
|
2126
|
-
request$ = this.
|
1244
|
+
request$ = this.configurationService.init$();
|
2127
1245
|
}
|
2128
|
-
return request$.pipe(
|
1246
|
+
return request$.pipe(take(1), tap(() => {
|
2129
1247
|
this.isInitialized$.next(true);
|
2130
1248
|
this.canceledConfiguration$ = new Subject();
|
2131
1249
|
}));
|
@@ -2139,10 +1257,11 @@ class ConfigurationStateService {
|
|
2139
1257
|
this.configurationStore = {};
|
2140
1258
|
this.executedFunctions = {};
|
2141
1259
|
this.configurationService.reset();
|
1260
|
+
this.configurationRuntimeService.reset();
|
2142
1261
|
}
|
2143
1262
|
execute$(exec) {
|
2144
1263
|
const request = this.execToRequest(exec);
|
2145
|
-
return this.executeRequest$(request).pipe(map
|
1264
|
+
return this.executeRequest$(request).pipe(map(result => {
|
2146
1265
|
// Keep only requested results
|
2147
1266
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
2148
1267
|
if (exec.selectors?.[requestId]) {
|
@@ -2164,7 +1283,7 @@ class ConfigurationStateService {
|
|
2164
1283
|
}
|
2165
1284
|
// prevent parallel configuration requests in stateless mode
|
2166
1285
|
if (!this.statelessExecutionRequest$) {
|
2167
|
-
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay
|
1286
|
+
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
|
2168
1287
|
}
|
2169
1288
|
return this.statelessExecutionRequest$;
|
2170
1289
|
}
|
@@ -2178,7 +1297,7 @@ class ConfigurationStateService {
|
|
2178
1297
|
},
|
2179
1298
|
},
|
2180
1299
|
});
|
2181
|
-
return this.executeRequest$(request).pipe(map
|
1300
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
2182
1301
|
}
|
2183
1302
|
subscribe$(selectorName, inputData = {}, options) {
|
2184
1303
|
const requestId = UUID.UUID();
|
@@ -2201,56 +1320,46 @@ class ConfigurationStateService {
|
|
2201
1320
|
this.executeRequest$(request).subscribe();
|
2202
1321
|
}
|
2203
1322
|
}
|
2204
|
-
return subscription.data$.pipe(filter
|
1323
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
|
2205
1324
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
2206
1325
|
delete this.subscriptions[requestId];
|
2207
1326
|
}
|
2208
1327
|
}), takeUntil(this.canceledConfiguration$));
|
2209
1328
|
}
|
2210
|
-
saveConfiguration(
|
1329
|
+
saveConfiguration() {
|
2211
1330
|
if (this.isStatefulConfiguration) {
|
2212
|
-
return this.flowStateApiService
|
2213
|
-
|
2214
|
-
|
1331
|
+
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
|
1332
|
+
}
|
1333
|
+
const state = this.salesTransactionService.state;
|
1334
|
+
if (!state) {
|
1335
|
+
return of({ id: '' });
|
1336
|
+
}
|
1337
|
+
const { standalone } = this.flowInfoService.flow.properties;
|
1338
|
+
if (standalone) {
|
1339
|
+
return this.salesTransactionApiService.upsert(state);
|
1340
|
+
}
|
1341
|
+
const transactionContext = this.salesTransactionService.state;
|
1342
|
+
const configurationRoot = this.configurationService.root;
|
1343
|
+
if (!transactionContext || !configurationRoot) {
|
1344
|
+
return of({ id: '' });
|
1345
|
+
}
|
1346
|
+
const stateItems = transactionContext.salesTransaction.salesTransactionItems;
|
1347
|
+
const isNewTransactionItem = stateItems.every(ti => ti.id !== configurationRoot.id);
|
1348
|
+
let salesTransactionItems;
|
1349
|
+
if (isNewTransactionItem) {
|
1350
|
+
salesTransactionItems = [...stateItems, configurationRoot];
|
2215
1351
|
}
|
2216
1352
|
else {
|
2217
|
-
|
2218
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
2219
|
-
if (!quoteDraft) {
|
2220
|
-
return of({ quoteId: '' });
|
2221
|
-
}
|
2222
|
-
const rootLineItem = this.configurationService.getSnapshot();
|
2223
|
-
const asset = this.configurationService.getAsset();
|
2224
|
-
const currentState = rootLineItem ? [rootLineItem] : [];
|
2225
|
-
const initialState = asset ? [asset] : [];
|
2226
|
-
return this.quoteApiService.upsertQuote({ ...quoteDraft, currentState, initialState });
|
2227
|
-
}
|
2228
|
-
else {
|
2229
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
2230
|
-
const lineItem = this.configurationService.getSnapshot();
|
2231
|
-
if (!quoteDraft || !lineItem) {
|
2232
|
-
return of({ quoteId: '' });
|
2233
|
-
}
|
2234
|
-
const isNewLineItem = quoteDraft.currentState.every(li => li.id !== lineItem.id);
|
2235
|
-
let currentState;
|
2236
|
-
if (isNewLineItem) {
|
2237
|
-
currentState = [...quoteDraft.currentState, lineItem];
|
2238
|
-
}
|
2239
|
-
else {
|
2240
|
-
currentState = quoteDraft.currentState.map(li => (li.id === lineItem.id ? lineItem : li));
|
2241
|
-
}
|
2242
|
-
const asset = this.configurationService.getAsset();
|
2243
|
-
const initialState = [...(this.quoteDraftService.quoteDraft?.initialState ?? [])];
|
2244
|
-
if (asset) {
|
2245
|
-
if (!initialState.some(li => li.id === asset.id)) {
|
2246
|
-
initialState.push(asset);
|
2247
|
-
}
|
2248
|
-
}
|
2249
|
-
return this.flowConfigurationService
|
2250
|
-
.calculate$({ ...quoteDraft, currentState, initialState })
|
2251
|
-
.pipe(map$1(() => ({ quoteId: '' })));
|
2252
|
-
}
|
1353
|
+
salesTransactionItems = stateItems.map(ti => (ti.id === configurationRoot.id ? configurationRoot : ti));
|
2253
1354
|
}
|
1355
|
+
const newState = {
|
1356
|
+
...transactionContext,
|
1357
|
+
salesTransaction: {
|
1358
|
+
...transactionContext.salesTransaction,
|
1359
|
+
salesTransactionItems,
|
1360
|
+
},
|
1361
|
+
};
|
1362
|
+
return this.flowConfigurationService.calculate$(newState).pipe(map(() => ({ id: '' })));
|
2254
1363
|
}
|
2255
1364
|
cancelConfiguration() {
|
2256
1365
|
if (!this.isInitialized$.value) {
|
@@ -2269,36 +1378,32 @@ class ConfigurationStateService {
|
|
2269
1378
|
return this.flowInfoService.flow?.properties.stateful ?? false;
|
2270
1379
|
}
|
2271
1380
|
initStateful$() {
|
2272
|
-
this.ownerId = this.configurationRuntimeService.
|
2273
|
-
const
|
2274
|
-
if (!this.flowStateService.stateId) {
|
1381
|
+
this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
|
1382
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
1383
|
+
if (!productId || !this.flowStateService.stateId) {
|
2275
1384
|
return of(undefined);
|
2276
1385
|
}
|
2277
|
-
const container = this.configurationRuntimeService.
|
2278
|
-
const lineItem = this.configurationService.generateLineItem();
|
1386
|
+
const container = this.configurationRuntimeService.uiDefinitionContainer;
|
2279
1387
|
let request$;
|
2280
|
-
if (!
|
1388
|
+
if (!transactionItemId) {
|
2281
1389
|
request$ = this.flowStateApiService.newConfiguration(this.flowStateService.stateId, {
|
2282
|
-
|
1390
|
+
transactionItem: generateTransactionItem(productId),
|
2283
1391
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2284
1392
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2285
1393
|
});
|
2286
1394
|
}
|
2287
1395
|
else {
|
2288
1396
|
request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
|
2289
|
-
|
1397
|
+
transactionItemId,
|
2290
1398
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2291
1399
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2292
1400
|
});
|
2293
1401
|
}
|
2294
|
-
return request$.pipe(map
|
1402
|
+
return request$.pipe(map(r => {
|
2295
1403
|
this.stateId = r.stateId;
|
2296
1404
|
return undefined;
|
2297
1405
|
}));
|
2298
1406
|
}
|
2299
|
-
initStateless$() {
|
2300
|
-
return this.configurationService.configure().pipe(map$1(() => undefined));
|
2301
|
-
}
|
2302
1407
|
execToRequest(exec) {
|
2303
1408
|
return {
|
2304
1409
|
actions: exec.actions?.map(action => ({
|
@@ -2338,37 +1443,35 @@ class ConfigurationStateService {
|
|
2338
1443
|
else {
|
2339
1444
|
execution$ = this.executeStateless$(fullRequest);
|
2340
1445
|
}
|
2341
|
-
return execution$.pipe(tap
|
1446
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
2342
1447
|
}
|
2343
1448
|
executeStateless$(request) {
|
2344
1449
|
this.executionInProgress$.next(true);
|
2345
|
-
return
|
1450
|
+
return this.configurationService.state$.pipe(first(), switchMap(state => {
|
2346
1451
|
// Apply actions and execute configuration/price call
|
2347
1452
|
// No need to run configuration if no actions in the request
|
2348
1453
|
if (!request.actions?.length) {
|
2349
1454
|
return of(undefined);
|
2350
1455
|
}
|
2351
|
-
let configurationRequest = this.configurationService.generateRequest(false);
|
2352
1456
|
request.actions.forEach(action => {
|
2353
|
-
|
1457
|
+
state = this.executeActionScript(state, action) ?? state;
|
2354
1458
|
});
|
2355
|
-
|
2356
|
-
|
2357
|
-
}), map$1(() => {
|
1459
|
+
return this.configurationService.configureRequest$(state);
|
1460
|
+
}), map(() => {
|
2358
1461
|
// Run selectors and apply them to the state
|
2359
|
-
const configurationState = this.configurationService.
|
1462
|
+
const configurationState = this.configurationService.state;
|
2360
1463
|
if (!configurationState) {
|
2361
1464
|
return { stateId: '', selectors: {} };
|
2362
1465
|
}
|
2363
1466
|
return this.runStatelessSelectors(request, configurationState);
|
2364
|
-
}), tap
|
2365
|
-
const configurationState = this.configurationService.
|
1467
|
+
}), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
|
1468
|
+
const configurationState = this.configurationService.previousState;
|
2366
1469
|
if (configurationState) {
|
2367
1470
|
const selectorsResult = this.runStatelessSelectors(request, configurationState);
|
2368
1471
|
this.handleSelectorsResponse(selectorsResult.selectors);
|
2369
1472
|
}
|
2370
1473
|
this.executionInProgress$.next(false);
|
2371
|
-
if (!this.configurationRuntimeService.
|
1474
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
2372
1475
|
this.toastService.add({ severity: ToastType.error, summary: String(error) });
|
2373
1476
|
}
|
2374
1477
|
return throwError(() => error);
|
@@ -2389,21 +1492,21 @@ class ConfigurationStateService {
|
|
2389
1492
|
};
|
2390
1493
|
this.executionInProgress$.next(true);
|
2391
1494
|
return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
|
2392
|
-
}), tap
|
1495
|
+
}), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
2393
1496
|
this.executionInProgress$.next(false);
|
2394
1497
|
return throwError(() => e);
|
2395
1498
|
}));
|
2396
1499
|
}
|
2397
1500
|
executeStateful$(request) {
|
2398
|
-
return this.executionInProgress$.pipe(filter
|
1501
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
2399
1502
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
2400
1503
|
combineLatest([
|
2401
1504
|
this.statefulExecutionRequest$,
|
2402
|
-
of(undefined).pipe(tap
|
2403
|
-
])), map
|
1505
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1506
|
+
])), map(([response]) => response), take(1));
|
2404
1507
|
}
|
2405
1508
|
executeActionScript(request, processor) {
|
2406
|
-
const { actions } = this.configurationRuntimeService.
|
1509
|
+
const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2407
1510
|
const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
|
2408
1511
|
if (!configurationProcessor?.script) {
|
2409
1512
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2411,7 +1514,7 @@ class ConfigurationStateService {
|
|
2411
1514
|
return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
|
2412
1515
|
}
|
2413
1516
|
executeSelectorScript(request, processor) {
|
2414
|
-
const { selectors } = this.configurationRuntimeService.
|
1517
|
+
const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2415
1518
|
const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
|
2416
1519
|
if (!configurationProcessor?.script) {
|
2417
1520
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2452,25 +1555,52 @@ class ConfigurationStateService {
|
|
2452
1555
|
}, { stateId: '', selectors: {} });
|
2453
1556
|
}
|
2454
1557
|
}
|
2455
|
-
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token:
|
1558
|
+
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token: FlowStateService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i3.FlowStateApiService }, { token: SalesTransactionService }, { token: i1.SalesTransactionApiService }, { token: i6.ToastService }], target: i0.ɵɵFactoryTarget.Injectable });
|
2456
1559
|
ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
|
2457
1560
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
|
2458
1561
|
type: Injectable
|
2459
|
-
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type:
|
1562
|
+
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type: FlowStateService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i3.FlowStateApiService }, { type: SalesTransactionService }, { type: i1.SalesTransactionApiService }, { type: i6.ToastService }]; } });
|
2460
1563
|
|
2461
1564
|
class ConfigurationModule {
|
2462
1565
|
}
|
2463
1566
|
ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2464
1567
|
ConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, imports: [ConfirmationDialogModule, ApiModule] });
|
2465
|
-
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1568
|
+
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1569
|
+
ConfigurationService,
|
1570
|
+
ConfigurationStateService,
|
1571
|
+
ConfigurationRuntimeService,
|
1572
|
+
TestModeConfigurationService,
|
1573
|
+
], imports: [ConfirmationDialogModule, ApiModule] });
|
2466
1574
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
|
2467
1575
|
type: NgModule,
|
2468
1576
|
args: [{
|
2469
1577
|
imports: [ConfirmationDialogModule, ApiModule],
|
2470
|
-
providers: [
|
1578
|
+
providers: [
|
1579
|
+
ConfigurationService,
|
1580
|
+
ConfigurationStateService,
|
1581
|
+
ConfigurationRuntimeService,
|
1582
|
+
TestModeConfigurationService,
|
1583
|
+
],
|
1584
|
+
}]
|
1585
|
+
}] });
|
1586
|
+
|
1587
|
+
class FlowConfigurationModule {
|
1588
|
+
}
|
1589
|
+
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
1590
|
+
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
1591
|
+
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
|
1592
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
1593
|
+
type: NgModule,
|
1594
|
+
args: [{
|
1595
|
+
imports: [ApiModule],
|
1596
|
+
providers: [FlowConfigurationService],
|
2471
1597
|
}]
|
2472
1598
|
}] });
|
2473
1599
|
|
1600
|
+
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
1601
|
+
|
1602
|
+
const UI_DEFINITION_VERSION = 3;
|
1603
|
+
|
2474
1604
|
const DEFAULT_FORMATTING_SETTINGS = {
|
2475
1605
|
currencySymbol: DEFAULT_CURRENCY_SYMBOL,
|
2476
1606
|
decimalsCount: DEFAULT_DECIMALS_COUNT,
|
@@ -2484,14 +1614,14 @@ class SdkCoreModule {
|
|
2484
1614
|
SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2485
1615
|
SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
|
2486
1616
|
SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
|
2487
|
-
ContextService,
|
2488
1617
|
FlowInfoService,
|
2489
|
-
QuoteDraftService,
|
2490
1618
|
ProductImagesService,
|
2491
1619
|
IntegrationState,
|
2492
1620
|
FlowStateService,
|
2493
1621
|
FlowStateConfigurationService,
|
2494
1622
|
RuntimeSettingsService,
|
1623
|
+
SalesTransactionService,
|
1624
|
+
CatalogProductsService,
|
2495
1625
|
{
|
2496
1626
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2497
1627
|
useExisting: RuntimeSettingsService,
|
@@ -2502,14 +1632,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2502
1632
|
args: [{
|
2503
1633
|
imports: [ConfigurationModule, FlowConfigurationModule],
|
2504
1634
|
providers: [
|
2505
|
-
ContextService,
|
2506
1635
|
FlowInfoService,
|
2507
|
-
QuoteDraftService,
|
2508
1636
|
ProductImagesService,
|
2509
1637
|
IntegrationState,
|
2510
1638
|
FlowStateService,
|
2511
1639
|
FlowStateConfigurationService,
|
2512
1640
|
RuntimeSettingsService,
|
1641
|
+
SalesTransactionService,
|
1642
|
+
CatalogProductsService,
|
2513
1643
|
{
|
2514
1644
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2515
1645
|
useExisting: RuntimeSettingsService,
|
@@ -2565,6 +1695,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2565
1695
|
}]
|
2566
1696
|
}] });
|
2567
1697
|
|
1698
|
+
function filterSuccessfulExecute() {
|
1699
|
+
return (source) => source.pipe(filter((result) => result.success), map(r => r.result));
|
1700
|
+
}
|
1701
|
+
|
2568
1702
|
class DatePipe {
|
2569
1703
|
constructor() {
|
2570
1704
|
this.locale = inject(LOCALE_ID);
|
@@ -2684,5 +1818,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2684
1818
|
* Generated bundle index. Do not edit.
|
2685
1819
|
*/
|
2686
1820
|
|
2687
|
-
export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService,
|
1821
|
+
export { ActionCodePipe, CalendarDirective, CatalogProductsService, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService, DEFAULT_FORMATTING_SETTINGS, DatePipe, FLOW_CUSTOMIZATION, FORMATTING_SETTINGS_TOKEN, FlowConfigurationService, FlowInfoService, FlowStateConfigurationService, FlowStateService, IntegrationState, NumberPipe, PricePipe, ProductImagesService, RuntimeSettingsService, SalesTransactionService, SdkCoreModule, SdkDirectivesModule, SdkPipesModule, TestModeConfigurationService, TransactionItemWorker, UI_DEFINITION_VERSION, extractMetadata, filterSuccessfulExecute, findTransactionItem, findTransactionItemWithComparator, generateTransactionItem, insertTransactionItem, removeTransactionItem, replaceTransactionItem };
|
2688
1822
|
//# sourceMappingURL=veloceapps-sdk-core.mjs.map
|