@veloceapps/sdk 11.0.0-8 → 11.0.0-81
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 +12 -24
- 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 +69 -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 +58 -180
- 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 -1663
- 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 +860 -1732
- 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,16 @@ class FlowStateService {
|
|
648
828
|
}
|
649
829
|
}
|
650
830
|
else {
|
651
|
-
const
|
652
|
-
if (
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
return of({ quoteId: '' });
|
659
|
-
}
|
660
|
-
submit$() {
|
661
|
-
if (this.getFlowSafe().properties.stateful) {
|
662
|
-
if (this.stateId$.value) {
|
663
|
-
return this.flowStateApiService.submit(this.stateId$.value);
|
664
|
-
}
|
665
|
-
}
|
666
|
-
else {
|
667
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
668
|
-
if (quoteDraft) {
|
669
|
-
return this.quoteApiService.submitQuote(quoteDraft).pipe(tap$1(({ versionId }) => {
|
670
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
671
|
-
}));
|
831
|
+
const state = this.salesTransactionService.state;
|
832
|
+
if (state) {
|
833
|
+
const request = {
|
834
|
+
transactionContext: state,
|
835
|
+
flowId: this.flowInfoService.flow.id,
|
836
|
+
};
|
837
|
+
return this.salesTransactionApiService.upsert(request).pipe(map(id => ({ id })));
|
672
838
|
}
|
673
839
|
}
|
674
|
-
return of({
|
840
|
+
return of({ id: '' });
|
675
841
|
}
|
676
842
|
getFlowStore() {
|
677
843
|
return this.flowStore;
|
@@ -709,10 +875,10 @@ class FlowStateService {
|
|
709
875
|
fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
|
710
876
|
}
|
711
877
|
}
|
712
|
-
const execution$ = this.
|
878
|
+
const execution$ = this.flowInfoService.flow.properties.stateful
|
713
879
|
? this.executeStateful$(fullRequest)
|
714
880
|
: this.executeStateless$(fullRequest);
|
715
|
-
return execution$.pipe(tap
|
881
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
716
882
|
}
|
717
883
|
handleSelectorsResponse(selectors) {
|
718
884
|
Object.entries(selectors).forEach(([requestId, selectorResult]) => {
|
@@ -727,31 +893,21 @@ class FlowStateService {
|
|
727
893
|
});
|
728
894
|
}
|
729
895
|
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
896
|
const processorsList = flatten(Object.values(this.processors).map(ownerMap => Object.values(ownerMap ?? {})));
|
739
897
|
const processors = processorsList.length ? processorsList : undefined;
|
740
898
|
const selectors = Object.values(this.subscriptions)
|
741
899
|
.map(({ request }) => request.selectors)
|
742
900
|
.filter(isDefined)
|
743
901
|
.reduce((trunk, selectors) => ({ ...trunk, ...selectors }), {});
|
744
|
-
const request = this.getDefaultExecutionRequestDTO();
|
745
902
|
return this.flowStateApiService
|
746
903
|
.init({
|
747
|
-
quoteId: this.
|
748
|
-
params: this.flowInfoService.
|
904
|
+
quoteId: this.flowInfoService.context.headerId,
|
905
|
+
params: this.flowInfoService.context,
|
749
906
|
actionsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.ACTION),
|
750
907
|
selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
|
751
|
-
selectors:
|
752
|
-
actions: request.actions,
|
908
|
+
selectors: selectors,
|
753
909
|
})
|
754
|
-
.pipe(map
|
910
|
+
.pipe(map(({ stateId, selectors }) => {
|
755
911
|
this.handleSelectorsResponse(selectors);
|
756
912
|
this.stateId$.next(stateId);
|
757
913
|
}));
|
@@ -771,1095 +927,170 @@ class FlowStateService {
|
|
771
927
|
};
|
772
928
|
this.executionInProgress$.next(true);
|
773
929
|
return this.flowStateApiService.execute(this.stateId$.value, request);
|
774
|
-
}), tap
|
930
|
+
}), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
775
931
|
this.executionInProgress$.next(false);
|
776
932
|
return throwError(() => e);
|
777
933
|
}));
|
778
934
|
}
|
779
935
|
executeStateful$(request) {
|
780
|
-
return this.executionInProgress$.pipe(filter
|
936
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
781
937
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
782
938
|
combineLatest([
|
783
939
|
this.statefulExecutionRequest$,
|
784
|
-
of(undefined).pipe(tap
|
785
|
-
])), map
|
940
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
941
|
+
])), map(([response]) => response), take(1));
|
786
942
|
}
|
787
943
|
initStateless$() {
|
788
|
-
|
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);
|
944
|
+
return this.salesTransactionService.init(this.flowInfoService.context.headerId, this.flowInfoService.context).pipe(switchMap(state => this.flowConfiguration.calculate$(state)), tap(() => this.salesTransactionService.finalizeInit()), map(noop));
|
819
945
|
}
|
820
946
|
executeStateless$(request) {
|
821
947
|
this.executionInProgress$.next(true);
|
822
|
-
return of(undefined).pipe(tap
|
948
|
+
return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
|
823
949
|
/*
|
824
950
|
Skip price calculation in case
|
825
951
|
1. No actions in the request
|
826
952
|
2. Initialization process execution (state not initialized yet)
|
827
953
|
*/
|
828
|
-
|
954
|
+
const { state } = this.salesTransactionService;
|
955
|
+
if (!state || !request.actions?.length || !this.isInitialized()) {
|
829
956
|
return of(undefined);
|
830
957
|
}
|
831
|
-
else {
|
832
|
-
return this.calculate$();
|
833
|
-
}
|
834
|
-
}), map$1(() => this.executeStatelessSelectors(request)), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
|
835
|
-
this.executionInProgress$.next(false);
|
836
|
-
return throwError(() => e);
|
837
|
-
}));
|
838
|
-
}
|
839
|
-
executeStatelessActions(request) {
|
840
|
-
if (!this.quoteDraftService.quoteDraft || !request.actions?.length) {
|
841
|
-
return;
|
842
|
-
}
|
843
|
-
let flowState = this.quoteDraftService.quoteDraft;
|
844
|
-
request.actions.forEach(action => {
|
845
|
-
try {
|
846
|
-
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
847
|
-
}
|
848
|
-
catch (e) {
|
849
|
-
console.error(e);
|
850
|
-
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
851
|
-
throw e;
|
852
|
-
}
|
853
|
-
});
|
854
|
-
this.quoteDraftService.updateQuoteDraft(flowState);
|
855
|
-
}
|
856
|
-
executeStatelessSelectors(request) {
|
857
|
-
if (!this.quoteDraftService.quoteDraft) {
|
858
|
-
throw 'QuoteDraft is not initialized';
|
859
|
-
}
|
860
|
-
const flowState = this.quoteDraftService.quoteDraft;
|
861
|
-
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
862
|
-
try {
|
863
|
-
result.selectors[key] = {
|
864
|
-
success: true,
|
865
|
-
result: this.executeSelectorScript(flowState, selector),
|
866
|
-
};
|
867
|
-
}
|
868
|
-
catch (e) {
|
869
|
-
console.error(e);
|
870
|
-
result.selectors[key] = {
|
871
|
-
success: false,
|
872
|
-
errorMessage: String(e),
|
873
|
-
};
|
874
|
-
}
|
875
|
-
return result;
|
876
|
-
}, { stateId: '', selectors: {} });
|
877
|
-
}
|
878
|
-
getFlowSafe() {
|
879
|
-
if (!this.flowInfoService.flow) {
|
880
|
-
throw 'Flow is not defined';
|
881
|
-
}
|
882
|
-
return this.flowInfoService.flow;
|
883
|
-
}
|
884
|
-
initProcessors$() {
|
885
|
-
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
886
|
-
const flow = this.getFlowSafe();
|
887
|
-
if (flow.properties.stateful && !hasOverrides) {
|
888
|
-
// Skip initialization as backend will take processors from SF
|
889
|
-
return of(undefined);
|
890
|
-
}
|
891
|
-
const owners$ = Object.values(this.flowInfoService.templates)
|
892
|
-
.map(template => {
|
893
|
-
if (!template) {
|
894
|
-
return;
|
895
|
-
}
|
896
|
-
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
897
|
-
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap$1(processors => {
|
898
|
-
const processorsMap = processors.reduce((acc, p) => {
|
899
|
-
acc[p.apiName] = p;
|
900
|
-
return acc;
|
901
|
-
}, {});
|
902
|
-
this.processors[template.id] = processorsMap;
|
903
|
-
}));
|
904
|
-
})
|
905
|
-
.filter(isDefined);
|
906
|
-
if (!owners$.length) {
|
907
|
-
return of(undefined);
|
908
|
-
}
|
909
|
-
return forkJoin(owners$).pipe(map$1(noop));
|
910
|
-
}
|
911
|
-
executeActionScript(request, executable) {
|
912
|
-
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
913
|
-
if (!configurationProcessor?.script) {
|
914
|
-
const scope = this.getScopeByOwnerId(executable.ownerId);
|
915
|
-
const scopeText = scope ? ` in ${scope}` : '';
|
916
|
-
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
917
|
-
}
|
918
|
-
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
919
|
-
}
|
920
|
-
executeSelectorScript(request, executable) {
|
921
|
-
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
922
|
-
if (!configurationProcessor?.script) {
|
923
|
-
const scope = this.getScopeByOwnerId(executable.ownerId);
|
924
|
-
const scopeText = scope ? ` in ${scope}` : '';
|
925
|
-
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
926
|
-
}
|
927
|
-
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
928
|
-
}
|
929
|
-
executeProcessorScript(request, configurationProcessor, inputData) {
|
930
|
-
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
931
|
-
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
932
|
-
if (!functionToExecute) {
|
933
|
-
const script = `${configurationProcessor.script}\nreturn transform;`;
|
934
|
-
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
935
|
-
functionToExecute = new Function(script + sourceMap)();
|
936
|
-
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
937
|
-
}
|
938
|
-
return functionToExecute({
|
939
|
-
request,
|
940
|
-
inputData,
|
941
|
-
flowStore: this.flowStore,
|
942
|
-
});
|
943
|
-
}
|
944
|
-
generateRequestId(scope, selectorName, inputData) {
|
945
|
-
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
946
|
-
return `${scope}/${selectorName}/${inputDataHash}`;
|
947
|
-
}
|
948
|
-
getDefaultExecutionRequestDTO() {
|
949
|
-
const request = {
|
950
|
-
actions: [],
|
951
|
-
selectors: {},
|
952
|
-
};
|
953
|
-
if (this.getFlowSafe().properties.standalone) {
|
954
|
-
return request;
|
955
|
-
}
|
956
|
-
const flowEngineTemplateId = this.getOwnerIdByScope(UITemplateType.FLOW_ENGINE);
|
957
|
-
request.actions?.push({
|
958
|
-
apiName: 'UPDATE_CONTEXT_PROPERTIES',
|
959
|
-
ownerId: flowEngineTemplateId,
|
960
|
-
inputData: this.contextService.resolve().properties,
|
961
|
-
});
|
962
|
-
return request;
|
963
|
-
}
|
964
|
-
checkStatefulChanges(requestId, selectorResult) {
|
965
|
-
if (this.trackedStatefulChangesMap.has(requestId)) {
|
966
|
-
if (!this.initialStatefulData[requestId]) {
|
967
|
-
this.initialStatefulData[requestId] = selectorResult;
|
968
|
-
}
|
969
|
-
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
970
|
-
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
971
|
-
}
|
972
|
-
}
|
973
|
-
}
|
974
|
-
FlowStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, deps: [{ token: ContextService }, { token: QuoteDraftService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.ConfigurationProcessorsApiService }, { token: i1.FlowStateApiService }, { token: i1.QuoteApiService }, { token: i6.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
975
|
-
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
976
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
977
|
-
type: Injectable
|
978
|
-
}], ctorParameters: function () { return [{ type: ContextService }, { type: QuoteDraftService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.FlowStateApiService }, { type: i1.QuoteApiService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
979
|
-
type: Optional
|
980
|
-
}, {
|
981
|
-
type: Inject,
|
982
|
-
args: [FLOW_CUSTOMIZATION]
|
983
|
-
}] }]; } });
|
984
|
-
|
985
|
-
const findLineItem = (id, lineItems) => {
|
986
|
-
return findLineItemWithComparator(lineItems, (li) => li.id === id);
|
987
|
-
};
|
988
|
-
const findLineItemWithComparator = (lineItems, comparator) => {
|
989
|
-
let currentLevel = lineItems;
|
990
|
-
while (currentLevel.length) {
|
991
|
-
const found = currentLevel.find(comparator);
|
992
|
-
if (found) {
|
993
|
-
return found;
|
994
|
-
}
|
995
|
-
currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
|
996
|
-
}
|
997
|
-
return;
|
998
|
-
};
|
999
|
-
const insertLineItem = (lineItem, parentId, toInsert) => {
|
1000
|
-
const insertData = lineItem.id === parentId ? [toInsert] : [];
|
1001
|
-
return {
|
1002
|
-
...lineItem,
|
1003
|
-
lineItems: [
|
1004
|
-
...insertData,
|
1005
|
-
...lineItem.lineItems.map(li => {
|
1006
|
-
return insertLineItem(li, parentId, toInsert);
|
1007
|
-
}),
|
1008
|
-
],
|
1009
|
-
};
|
1010
|
-
};
|
1011
|
-
const removeLineItem = (lineItem, idToRemove) => {
|
1012
|
-
return {
|
1013
|
-
...lineItem,
|
1014
|
-
lineItems: lineItem.lineItems
|
1015
|
-
.map(li => {
|
1016
|
-
if (li.id === idToRemove) {
|
1017
|
-
return;
|
1018
|
-
}
|
1019
|
-
else if (li.lineItems.length) {
|
1020
|
-
return removeLineItem(li, idToRemove);
|
1021
|
-
}
|
1022
|
-
return li;
|
1023
|
-
})
|
1024
|
-
.filter(r => !!r),
|
1025
|
-
};
|
1026
|
-
};
|
1027
|
-
const replaceLineItem = (lineItem, replaceTo, skipCardinalityCalculation = false) => {
|
1028
|
-
if (lineItem.id === replaceTo.id) {
|
1029
|
-
if (!skipCardinalityCalculation) {
|
1030
|
-
return { ...recalculateCardinalityVariables(lineItem, replaceTo) };
|
1031
|
-
}
|
1032
|
-
else {
|
1033
|
-
return { ...replaceTo };
|
1034
|
-
}
|
1035
|
-
}
|
1036
|
-
return {
|
1037
|
-
...lineItem,
|
1038
|
-
lineItems: lineItem.lineItems.map(li => replaceLineItem(li, replaceTo, skipCardinalityCalculation)),
|
1039
|
-
};
|
1040
|
-
};
|
1041
|
-
const collectCardinalityComputations = (portDomains) => {
|
1042
|
-
const cardinalityComputations = new Map();
|
1043
|
-
entries(portDomains).forEach(([key, portDomain]) => {
|
1044
|
-
cardinalityComputations.set(key, portDomain.properties['cardinalityComputation'] === 'true');
|
1045
|
-
});
|
1046
|
-
return cardinalityComputations;
|
1047
|
-
};
|
1048
|
-
const calculateCardinalityVariables = (lineItems, cardinalityComputations) => {
|
1049
|
-
const cardVars = new Map();
|
1050
|
-
lineItems
|
1051
|
-
.filter(({ port, type }) => !!port && !!type)
|
1052
|
-
.forEach(li => {
|
1053
|
-
if (cardinalityComputations.get(`${li.port}`)) {
|
1054
|
-
const cardinalityVariableName = `#CV-${li.type}@${li.port}`;
|
1055
|
-
cardVars.set(cardinalityVariableName, (cardVars.get(cardinalityVariableName) ?? 0) + li.qty);
|
1056
|
-
}
|
1057
|
-
});
|
1058
|
-
return cardVars;
|
1059
|
-
};
|
1060
|
-
const cardinalityRegexp = new RegExp('#CV-[a-zA-Z0-9_]+@(?<portName>[a-zA-Z0-9_]+)');
|
1061
|
-
const recalculateCardinalityVariables = (original, updated) => {
|
1062
|
-
const cardinalityComputations = collectCardinalityComputations(updated.portDomains ?? original.portDomains ?? {});
|
1063
|
-
const cardinalityVariables = calculateCardinalityVariables(updated.lineItems, cardinalityComputations);
|
1064
|
-
const originalCardinalityVariables = calculateCardinalityVariables(original.lineItems, cardinalityComputations);
|
1065
|
-
originalCardinalityVariables.forEach((value, key) => {
|
1066
|
-
const execArray = cardinalityRegexp.exec(key);
|
1067
|
-
const portName = execArray?.groups?.['portName'];
|
1068
|
-
if (!portName || cardinalityComputations.get(portName)) {
|
1069
|
-
if (cardinalityVariables.get(key) === value) {
|
1070
|
-
// no need to update cardinality if no changes
|
1071
|
-
cardinalityVariables.delete(key);
|
1072
|
-
}
|
1073
|
-
else if (!cardinalityVariables.has(key)) {
|
1074
|
-
// remove last item from port
|
1075
|
-
cardinalityVariables.set(key, 0);
|
1076
|
-
}
|
1077
|
-
}
|
1078
|
-
});
|
1079
|
-
return {
|
1080
|
-
...updated,
|
1081
|
-
attributes: upsertAttributes(updated.attributes, [...cardinalityVariables].map(([name, value]) => ({ name, value, cfgStatus: 'Changed' }))),
|
1082
|
-
};
|
1083
|
-
};
|
1084
|
-
const mapAttributes = (attributes) => {
|
1085
|
-
return attributes.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
|
1086
|
-
};
|
1087
|
-
const getAttributes = (attributes, names = []) => {
|
1088
|
-
const filtered = attributes.filter(({ name }) => names.includes(name));
|
1089
|
-
return sortBy(filtered, [({ name }) => names.indexOf(name)]);
|
1090
|
-
};
|
1091
|
-
const upsertAttributes = (originalAttributes, attributesToUpsert) => {
|
1092
|
-
return attributesToUpsert.reduce((acc, { name, value }) => {
|
1093
|
-
const [origAttr] = getAttributes(acc, [name]);
|
1094
|
-
return [
|
1095
|
-
...acc.filter(attr => attr.name !== name),
|
1096
|
-
{ ...(origAttr ?? { name, type: '' }), cfgStatus: origAttr ? 'Changed' : 'User', value },
|
1097
|
-
];
|
1098
|
-
}, originalAttributes);
|
1099
|
-
};
|
1100
|
-
const patchAttributes = (rootLineItem, id, attrs, skipCardinalityCalculation = false) => {
|
1101
|
-
const lineItem = findLineItem(id, [rootLineItem]);
|
1102
|
-
if (!lineItem) {
|
1103
|
-
return rootLineItem;
|
1104
|
-
}
|
1105
|
-
const attributes = upsertAttributes(lineItem.attributes, attrs);
|
1106
|
-
return replaceLineItem(rootLineItem, { ...lineItem, attributes }, skipCardinalityCalculation);
|
1107
|
-
};
|
1108
|
-
const getAttributeValue = (attributes, name) => attributes.find(attr => attr.name === name)?.value;
|
1109
|
-
const generateLineItem = (port, type, parentId, attributes = [], lineItems = []) => {
|
1110
|
-
return {
|
1111
|
-
id: UUID.UUID(),
|
1112
|
-
port,
|
1113
|
-
type,
|
1114
|
-
actionCode: 'ADD',
|
1115
|
-
cfgStatus: 'New',
|
1116
|
-
attributes: attributes.map(({ name, value }) => ({ cfgStatus: 'User', name, value })),
|
1117
|
-
lineItems,
|
1118
|
-
parentId,
|
1119
|
-
qty: 1,
|
1120
|
-
};
|
1121
|
-
};
|
1122
|
-
const getRecommendedPrices = (portDomain, type) => {
|
1123
|
-
const domainType = portDomain.domainTypes.find(({ name }) => name === type);
|
1124
|
-
const [net, list] = domainType?.recommendedPrices
|
1125
|
-
?.filter(({ chargeMethod }) => chargeMethod === 'ONE_TIME')
|
1126
|
-
.reduce((acc, rp) => {
|
1127
|
-
const [netPrice, listPrice] = acc;
|
1128
|
-
return [netPrice + rp.netPrice, listPrice + rp.listPrice];
|
1129
|
-
}, [0, 0]) ?? [0, 0];
|
1130
|
-
return { net, list };
|
1131
|
-
};
|
1132
|
-
const getOriginParent = (lineItems, currentLineItem) => {
|
1133
|
-
let target = currentLineItem;
|
1134
|
-
while (target && target.rampInstanceId) {
|
1135
|
-
target = lineItems.find(sub => sub.id === currentLineItem.rampInstanceId);
|
1136
|
-
}
|
1137
|
-
return target;
|
1138
|
-
};
|
1139
|
-
const assetPredicateFn = (lineItem, assetId) => {
|
1140
|
-
if (!assetId) {
|
1141
|
-
return false;
|
1142
|
-
}
|
1143
|
-
return lineItem.assetId === assetId || lineItem.openOrderLineItemId === assetId;
|
1144
|
-
};
|
1145
|
-
const multiplyLineItems = (lineItem, qty, split) => {
|
1146
|
-
if (split) {
|
1147
|
-
const unifyIds = (lineItem) => ({
|
1148
|
-
...lineItem,
|
1149
|
-
id: UUID.UUID(),
|
1150
|
-
lineItems: lineItem.lineItems.map(unifyIds),
|
1151
|
-
});
|
1152
|
-
return map$2(new Array(qty), () => unifyIds(lineItem));
|
1153
|
-
}
|
1154
|
-
else {
|
1155
|
-
return [
|
1156
|
-
{
|
1157
|
-
...lineItem,
|
1158
|
-
qty: qty,
|
1159
|
-
},
|
1160
|
-
];
|
1161
|
-
}
|
1162
|
-
};
|
1163
|
-
const isTechnicalAttribute = (name) => {
|
1164
|
-
return name.startsWith('#') || name.startsWith('$');
|
1165
|
-
};
|
1166
|
-
const filterOutTechnicalAttributes = (attributes) => {
|
1167
|
-
return attributes.filter(({ name }) => !isTechnicalAttribute(name));
|
1168
|
-
};
|
1169
|
-
|
1170
|
-
var lineItem_utils = /*#__PURE__*/Object.freeze({
|
1171
|
-
__proto__: null,
|
1172
|
-
assetPredicateFn: assetPredicateFn,
|
1173
|
-
filterOutTechnicalAttributes: filterOutTechnicalAttributes,
|
1174
|
-
findLineItem: findLineItem,
|
1175
|
-
findLineItemWithComparator: findLineItemWithComparator,
|
1176
|
-
generateLineItem: generateLineItem,
|
1177
|
-
getAttributeValue: getAttributeValue,
|
1178
|
-
getAttributes: getAttributes,
|
1179
|
-
getOriginParent: getOriginParent,
|
1180
|
-
getRecommendedPrices: getRecommendedPrices,
|
1181
|
-
insertLineItem: insertLineItem,
|
1182
|
-
isTechnicalAttribute: isTechnicalAttribute,
|
1183
|
-
mapAttributes: mapAttributes,
|
1184
|
-
multiplyLineItems: multiplyLineItems,
|
1185
|
-
patchAttributes: patchAttributes,
|
1186
|
-
recalculateCardinalityVariables: recalculateCardinalityVariables,
|
1187
|
-
removeLineItem: removeLineItem,
|
1188
|
-
replaceLineItem: replaceLineItem,
|
1189
|
-
upsertAttributes: upsertAttributes
|
1190
|
-
});
|
1191
|
-
|
1192
|
-
class RuntimeSettingsService {
|
1193
|
-
constructor(configurationSettingsApiService) {
|
1194
|
-
this.configurationSettingsApiService = configurationSettingsApiService;
|
1195
|
-
this.configurationSettings$ = new BehaviorSubject({});
|
1196
|
-
this.currencySettings$ = new BehaviorSubject({
|
1197
|
-
iso: DEFAULT_CURRENCY_ISO_CODE,
|
1198
|
-
symbol: DEFAULT_CURRENCY_SYMBOL,
|
1199
|
-
});
|
1200
|
-
this.shoppingCartSettings$ = new BehaviorSubject([]);
|
1201
|
-
this.getCurrencySymbol = (locale, currency) => {
|
1202
|
-
return (0)
|
1203
|
-
.toLocaleString(locale, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 0 })
|
1204
|
-
.replace(/\d/g, '')
|
1205
|
-
.trim();
|
1206
|
-
};
|
1207
|
-
}
|
1208
|
-
create() {
|
1209
|
-
return this.configurationSettingsApiService.fetchSettings().pipe(map$1(settings => this.parseConfigurationSettings(settings)), tap$1(configurationSettings => {
|
1210
|
-
this.configurationSettings$.next(configurationSettings);
|
1211
|
-
this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
|
1212
|
-
this.formattingSettings = this.getFormattingSettings();
|
1213
|
-
}), map$1(() => undefined));
|
1214
|
-
}
|
1215
|
-
initCurrency(iso) {
|
1216
|
-
if (iso) {
|
1217
|
-
const symbol = this.getCurrencySymbol('en-US', iso);
|
1218
|
-
this.currencySettings$.next({ iso, symbol });
|
1219
|
-
if (this.formattingSettings) {
|
1220
|
-
this.formattingSettings.currencySymbol = symbol;
|
1221
|
-
}
|
1222
|
-
}
|
1223
|
-
}
|
1224
|
-
getFormattingSettings() {
|
1225
|
-
if (this.formattingSettings) {
|
1226
|
-
return this.formattingSettings;
|
1227
|
-
}
|
1228
|
-
const shoppingCartSettings = this.getConfigurationSettings()['shopping-cart']?.reduce((acc, setting) => {
|
1229
|
-
return { ...acc, [setting.id]: setting.properties };
|
1230
|
-
}, {});
|
1231
|
-
const currencySettings = this.getCurrencySettings();
|
1232
|
-
const dateFormat = (validateDateFormat(shoppingCartSettings?.DATE_FORMAT ?? '') && shoppingCartSettings?.DATE_FORMAT) ||
|
1233
|
-
DEFAULT_DATE_FORMAT;
|
1234
|
-
const decimalSeparator = shoppingCartSettings?.DECIMAL_SEPARATOR;
|
1235
|
-
const thousandsSeparator = shoppingCartSettings?.THOUSANDS_SEPARATOR;
|
1236
|
-
// the number of decimal places can be 0
|
1237
|
-
const priceScale = shoppingCartSettings?.PRICE_SCALE;
|
1238
|
-
const decimalsCount = priceScale !== null && priceScale !== '' && !isNaN(Number(priceScale)) && Number(priceScale) >= 0
|
1239
|
-
? Number(priceScale)
|
1240
|
-
: DEFAULT_DECIMALS_COUNT;
|
1241
|
-
const actionCodeSettings = shoppingCartSettings?.STATUS_LABEL;
|
1242
|
-
return {
|
1243
|
-
currencySymbol: currencySettings.symbol,
|
1244
|
-
dateFormats: getSupportedDateFormats(dateFormat),
|
1245
|
-
decimalsCount,
|
1246
|
-
decimalSeparator: decimalSeparator !== undefined && ['.', ','].includes(decimalSeparator)
|
1247
|
-
? decimalSeparator
|
1248
|
-
: DEFAULT_DECIMAL_SEPARATOR,
|
1249
|
-
// thousands separator can be a blank value, so it can also be null
|
1250
|
-
thousandsSeparator: thousandsSeparator !== undefined && ['.', ',', '', null].includes(thousandsSeparator)
|
1251
|
-
? thousandsSeparator || ''
|
1252
|
-
: DEFAULT_THOUSANDS_SEPARATOR,
|
1253
|
-
actionCodeLabels: actionCodeSettings?.length
|
1254
|
-
? actionCodeSettings.reduce((result, setting) => ({ ...result, [setting.status_label]: setting.custom_label }), {})
|
1255
|
-
: DEFAULT_ACTION_CODE_LABELS,
|
1256
|
-
};
|
1257
|
-
}
|
1258
|
-
getConfigurationSettings() {
|
1259
|
-
return this.configurationSettings$.value;
|
1260
|
-
}
|
1261
|
-
getShoppingCartSettings() {
|
1262
|
-
return this.shoppingCartSettings$.value;
|
1263
|
-
}
|
1264
|
-
getCurrencySettings() {
|
1265
|
-
return this.currencySettings$.value;
|
1266
|
-
}
|
1267
|
-
parseConfigurationSettings(settings) {
|
1268
|
-
return settings.reduce((acc, setting) => {
|
1269
|
-
switch (setting.key) {
|
1270
|
-
case 'shopping-cart':
|
1271
|
-
acc['shopping-cart'] = parseJsonSafely(setting.value, []);
|
1272
|
-
break;
|
1273
|
-
case 'navigation':
|
1274
|
-
acc.navigation = parseJsonSafely(setting.value, {});
|
1275
|
-
break;
|
1276
|
-
case 'flows':
|
1277
|
-
acc.flows = parseJsonSafely(setting.value, []);
|
1278
|
-
break;
|
1279
|
-
default:
|
1280
|
-
acc[setting.key] = setting.value;
|
1281
|
-
}
|
1282
|
-
return acc;
|
1283
|
-
}, {});
|
1284
|
-
}
|
1285
|
-
addShoppingCartSettings(settings) {
|
1286
|
-
// uniqBy removes items with the biggest index
|
1287
|
-
const newSettings = uniqBy([...settings, ...this.shoppingCartSettings$.value], 'id');
|
1288
|
-
this.shoppingCartSettings$.next(newSettings);
|
1289
|
-
}
|
1290
|
-
}
|
1291
|
-
RuntimeSettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, deps: [{ token: i1.ConfigurationSettingsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1292
|
-
RuntimeSettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService });
|
1293
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, decorators: [{
|
1294
|
-
type: Injectable
|
1295
|
-
}], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
|
1296
|
-
|
1297
|
-
class LineItemWorker {
|
1298
|
-
constructor(src) {
|
1299
|
-
this.li = { ...src };
|
1300
|
-
}
|
1301
|
-
insert(parentId, toInsert) {
|
1302
|
-
return new LineItemWorker(insertLineItem(this.li, parentId, toInsert));
|
1303
|
-
}
|
1304
|
-
remove(id) {
|
1305
|
-
return new LineItemWorker(removeLineItem(this.li, id));
|
1306
|
-
}
|
1307
|
-
replace(toReplace, skipCardinalityCalculation = false) {
|
1308
|
-
return new LineItemWorker(replaceLineItem(this.li, toReplace, skipCardinalityCalculation));
|
1309
|
-
}
|
1310
|
-
patchAttribute(attrs, id, skipCardinalityCalculation = false) {
|
1311
|
-
return new LineItemWorker(patchAttributes(this.li, id ?? this.li.id, attrs, skipCardinalityCalculation));
|
1312
|
-
}
|
1313
|
-
}
|
1314
|
-
|
1315
|
-
function extractMetadata(uiDefinition) {
|
1316
|
-
return omit(uiDefinition, [
|
1317
|
-
'children',
|
1318
|
-
'pages',
|
1319
|
-
'components',
|
1320
|
-
]);
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
class ConfigurationService {
|
1324
|
-
constructor(quoteDraftService, runtimeService, contextService, configurationApiService, messageService, dialogService, runtimeSettings) {
|
1325
|
-
this.quoteDraftService = quoteDraftService;
|
1326
|
-
this.runtimeService = runtimeService;
|
1327
|
-
this.contextService = contextService;
|
1328
|
-
this.configurationApiService = configurationApiService;
|
1329
|
-
this.messageService = messageService;
|
1330
|
-
this.dialogService = dialogService;
|
1331
|
-
this.runtimeSettings = runtimeSettings;
|
1332
|
-
this.mode = ConfigurationMode.SEARCH;
|
1333
|
-
this.configurationState = new BehaviorSubject(null);
|
1334
|
-
this.previousConfigurationState = new BehaviorSubject(null);
|
1335
|
-
this.isLoadingSubj$ = new BehaviorSubject(false);
|
1336
|
-
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
1337
|
-
this.hasUnsavedChanges = false;
|
1338
|
-
}
|
1339
|
-
reset() {
|
1340
|
-
this.hasUnsavedChanges = false;
|
1341
|
-
this.runtimeService.reset();
|
1342
|
-
this.configurableRamp = undefined;
|
1343
|
-
this.configurationState.next(null);
|
1344
|
-
this.previousConfigurationState.next(null);
|
1345
|
-
}
|
1346
|
-
patch$(lineItem, options) {
|
1347
|
-
const source = this.getSnapshot();
|
1348
|
-
if (!source) {
|
1349
|
-
return throwError(() => new Error(`Source LineItem not found`));
|
1350
|
-
}
|
1351
|
-
const skipCardinalityCalculation = options?.skipCardinalityCalculation || this.contextSnapshot.properties['#skipCardinalityCalculation'] === 'true';
|
1352
|
-
this.configurableRamp = new LineItemWorker(source).replace(lineItem, skipCardinalityCalculation).li;
|
1353
|
-
return this.configure().pipe(catchError$1(error => {
|
1354
|
-
console.error(error);
|
1355
|
-
if (!this.runtimeService.uiDefinitionProperties.suppressToastMessages) {
|
1356
|
-
this.messageService.add({ severity: 'error', summary: error });
|
1357
|
-
}
|
1358
|
-
// bounce back if configuration call has failed
|
1359
|
-
const prevState = this.configurationState.value;
|
1360
|
-
this.configurationState.next(prevState ? { ...prevState } : null);
|
1361
|
-
return throwError(() => error);
|
1362
|
-
}), tap(() => {
|
1363
|
-
if (!this.hasUnsavedChanges) {
|
1364
|
-
this.hasUnsavedChanges = true;
|
1365
|
-
}
|
1366
|
-
}));
|
1367
|
-
}
|
1368
|
-
patch(lineItem, options) {
|
1369
|
-
this.patch$(lineItem, options).subscribe();
|
1370
|
-
}
|
1371
|
-
setConfigurableRamp(lineItem) {
|
1372
|
-
this.configurableRamp = lineItem;
|
1373
|
-
}
|
1374
|
-
get() {
|
1375
|
-
return this.configurationState.pipe(map(state => state?.lineItem), shareReplay$1());
|
1376
|
-
}
|
1377
|
-
getSnapshot() {
|
1378
|
-
return this.configurationState.value?.lineItem ? { ...this.configurationState.value?.lineItem } : undefined;
|
1379
|
-
}
|
1380
|
-
getRuntimeModel() {
|
1381
|
-
const runtimeModel = this.runtimeService.runtimeModel;
|
1382
|
-
if (!runtimeModel) {
|
1383
|
-
throw new Error('Runtime model not initialized');
|
1384
|
-
}
|
1385
|
-
return runtimeModel;
|
1386
|
-
}
|
1387
|
-
getRuntimeContext() {
|
1388
|
-
const runtimeContext = this.runtimeService.runtimeContext;
|
1389
|
-
if (!runtimeContext) {
|
1390
|
-
throw new Error('Runtime context not initialized');
|
1391
|
-
}
|
1392
|
-
return runtimeContext;
|
1393
|
-
}
|
1394
|
-
get state$() {
|
1395
|
-
return this.configurationState.asObservable();
|
1396
|
-
}
|
1397
|
-
get stateSnapshot() {
|
1398
|
-
return this.configurationState.value;
|
1399
|
-
}
|
1400
|
-
get previousStateSnapshot() {
|
1401
|
-
return this.previousConfigurationState.value;
|
1402
|
-
}
|
1403
|
-
get contextSnapshot() {
|
1404
|
-
return this.contextService.resolve();
|
1405
|
-
}
|
1406
|
-
get context$() {
|
1407
|
-
return this.contextService.resolve$();
|
1408
|
-
}
|
1409
|
-
get charges$() {
|
1410
|
-
return this.configurationState.pipe(map(state => state?.charges ?? {}));
|
1411
|
-
}
|
1412
|
-
get chargesSnapshot() {
|
1413
|
-
return this.configurationState.value?.charges ?? {};
|
1414
|
-
}
|
1415
|
-
get pricePlans$() {
|
1416
|
-
return this.configurationState.pipe(map(state => state?.pricePlans ?? {}));
|
1417
|
-
}
|
1418
|
-
get pricePlansSnapshot() {
|
1419
|
-
return this.configurationState.value?.pricePlans ?? {};
|
1420
|
-
}
|
1421
|
-
get procedureContext$() {
|
1422
|
-
return this.configurationState.pipe(map(state => state?.procedureContext ?? {}));
|
1423
|
-
}
|
1424
|
-
get procedureContextSnapshot() {
|
1425
|
-
return this.configurationState.value?.procedureContext ?? {};
|
1426
|
-
}
|
1427
|
-
configure() {
|
1428
|
-
return this.configureRequest$(this.generateRequest());
|
1429
|
-
}
|
1430
|
-
configureRequest$(configurationRequest) {
|
1431
|
-
const runtimeContext = this.getRuntimeContext();
|
1432
|
-
const runtimeModel = this.getRuntimeModel();
|
1433
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1434
|
-
const mainPricingEnabled = runtimeContext.properties?.PricingEnabled;
|
1435
|
-
const pricingEnabled = mainPricingEnabled ? mainPricingEnabled === 'true' : uiDefinitionProperties.pricingEnabled;
|
1436
|
-
const customPriceApi = this.runtimeSettings.getConfigurationSettings()['CUSTOM_PRICE_API'];
|
1437
|
-
this.isLoadingSubj$.next(true);
|
1438
|
-
const configure$ = pricingEnabled && customPriceApi
|
1439
|
-
? this.configurationApiService.customConfigurePrice({ url: customPriceApi, configurationRequest, runtimeModel })
|
1440
|
-
: this.configurationApiService.configureLineItem({
|
1441
|
-
configurationRequest,
|
1442
|
-
runtimeModel,
|
1443
|
-
pricingEnabled,
|
1444
|
-
});
|
1445
|
-
return configure$.pipe(tap(result => {
|
1446
|
-
this.contextService.update(result.context);
|
1447
|
-
this.configurationState.next(result);
|
1448
|
-
this.previousConfigurationState.next(cloneDeep(result));
|
1449
|
-
if (result.deletedLineItems?.length) {
|
1450
|
-
this.showInactiveProductsConfirmation();
|
1451
|
-
}
|
1452
|
-
this.configurableRamp = result.lineItem;
|
1453
|
-
}), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => {
|
1454
|
-
const resetState = this.previousConfigurationState.value;
|
1455
|
-
if (resetState) {
|
1456
|
-
this.previousConfigurationState.next(cloneDeep(resetState));
|
1457
|
-
this.configurationState.next(resetState);
|
1458
|
-
}
|
1459
|
-
if (error.error) {
|
1460
|
-
return extractErrorDetails(error.error).join('. ');
|
1461
|
-
}
|
1462
|
-
return error.message || JSON.stringify(error);
|
1463
|
-
})), finalize$1(() => this.isLoadingSubj$.next(false)));
|
1464
|
-
}
|
1465
|
-
configureExternal$(props) {
|
1466
|
-
return this.runtimeService
|
1467
|
-
.init({ productId: props.productId, defaultQty: props.qty, attributesMap: props.attributesMap })
|
1468
|
-
.pipe(switchMap$1(() => this.configure()), first(), catchError$1(error => {
|
1469
|
-
this.messageService.add({ severity: ToastType.error, summary: error });
|
1470
|
-
throw error;
|
1471
|
-
}), finalize$1(() => this.reset()));
|
1472
|
-
}
|
1473
|
-
configureGuidedSelling$(data) {
|
1474
|
-
return this.configurationApiService
|
1475
|
-
.configureLineItem({
|
1476
|
-
configurationRequest: getGuidedSellingConfigurationRequest(data, this.contextService.resolve()),
|
1477
|
-
})
|
1478
|
-
.pipe(catchError$1(error => {
|
1479
|
-
if (error instanceof HttpErrorResponse) {
|
1480
|
-
this.messageService.add({ severity: ToastType.error, summary: error.error.message || error.error });
|
1481
|
-
}
|
1482
|
-
throw error;
|
1483
|
-
}));
|
1484
|
-
}
|
1485
|
-
generateRequest(lightMode = true) {
|
1486
|
-
const lineItem = this.generateLineItem();
|
1487
|
-
let request = {
|
1488
|
-
lineItem,
|
1489
|
-
mode: this.mode,
|
1490
|
-
step: !this.configurationState.value?.lineItem ? RuntimeStep.START : RuntimeStep.UPDATE,
|
1491
|
-
attributeDomainMode: 'ALL',
|
1492
|
-
context: this.contextService.resolve(),
|
1493
|
-
lineItems: this.quoteDraftService.quoteDraft?.currentState || [],
|
1494
|
-
asset: this.getAsset(),
|
1495
|
-
};
|
1496
|
-
if (lightMode) {
|
1497
|
-
request = ConfigurationTranslatorUtils.lightenConfigurationRequest(request);
|
1498
|
-
}
|
1499
|
-
return request;
|
1500
|
-
}
|
1501
|
-
generateLineItem() {
|
1502
|
-
const runtimeContext = this.getRuntimeContext();
|
1503
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1504
|
-
let lineItem = this.configurableRamp;
|
1505
|
-
if (!lineItem) {
|
1506
|
-
const { initializationProps } = this.runtimeService ?? {};
|
1507
|
-
lineItem = getDefaultLineItem(runtimeContext, uiDefinitionProperties, initializationProps?.defaultQty);
|
1508
|
-
// Set default attributes
|
1509
|
-
if (initializationProps?.attributesMap) {
|
1510
|
-
const attributes = transform(initializationProps?.attributesMap, (acc, value, name) => acc.push({ name, value }), []);
|
1511
|
-
lineItem = new LineItemWorker(lineItem).patchAttribute(attributes).li;
|
1512
|
-
}
|
1513
|
-
}
|
1514
|
-
return lineItem;
|
1515
|
-
}
|
1516
|
-
getAsset() {
|
1517
|
-
const lineItem = this.configurableRamp;
|
1518
|
-
if (!lineItem) {
|
1519
|
-
return;
|
1520
|
-
}
|
1521
|
-
const assetId = lineItem.assetId ?? lineItem.openOrderLineItemId;
|
1522
|
-
return this.quoteDraftService.assetsState?.initialState.find(li => assetPredicateFn(li, assetId));
|
1523
|
-
}
|
1524
|
-
getUIDefinitionProperties() {
|
1525
|
-
return {
|
1526
|
-
...(this.getRuntimeContext().uiDefinitionContainer?.source.properties ?? {}),
|
1527
|
-
...(this.runtimeService.uiDefinitionProperties ?? {}),
|
1528
|
-
};
|
1529
|
-
}
|
1530
|
-
showInactiveProductsConfirmation() {
|
1531
|
-
const confirmationConfig = {
|
1532
|
-
title: ' ',
|
1533
|
-
description: 'This quote contains inactive products. Do you want to remove them?',
|
1534
|
-
primaryButtonLabel: 'Remove products',
|
1535
|
-
secondaryButtonLabel: 'Back to Quote',
|
1536
|
-
};
|
1537
|
-
this.dialogService
|
1538
|
-
.open(ConfirmationComponent, {
|
1539
|
-
dismissableMask: false,
|
1540
|
-
closeOnEscape: false,
|
1541
|
-
closable: false,
|
1542
|
-
showHeader: true,
|
1543
|
-
header: `Inactive Products in Quote`,
|
1544
|
-
width: '440px',
|
1545
|
-
data: { confirmationConfig },
|
1546
|
-
})
|
1547
|
-
.onClose.subscribe(result => {
|
1548
|
-
if (!result) {
|
1549
|
-
const context = this.contextService.resolve();
|
1550
|
-
window['VELO_BACK_FN'].apply(null, [context.headerId]);
|
1551
|
-
}
|
1552
|
-
});
|
1553
|
-
}
|
1554
|
-
}
|
1555
|
-
ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, deps: [{ token: QuoteDraftService }, { token: ConfigurationRuntimeService }, { token: ContextService }, { token: i1.ConfigurationApiService }, { token: i5.MessageService }, { token: i6$1.DialogService }, { token: RuntimeSettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1556
|
-
ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
|
1557
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
|
1558
|
-
type: Injectable
|
1559
|
-
}], ctorParameters: function () { return [{ type: QuoteDraftService }, { type: ConfigurationRuntimeService }, { type: ContextService }, { type: i1.ConfigurationApiService }, { type: i5.MessageService }, { type: i6$1.DialogService }, { type: RuntimeSettingsService }]; } });
|
1560
|
-
|
1561
|
-
class FlowUpdateService {
|
1562
|
-
update(rootLineItems, updates, charges) {
|
1563
|
-
let remainingUpdates = [...updates];
|
1564
|
-
let currentLevel = rootLineItems;
|
1565
|
-
while (currentLevel.length && remainingUpdates.length) {
|
1566
|
-
currentLevel.forEach(li => {
|
1567
|
-
const unhandledUpdates = [];
|
1568
|
-
remainingUpdates.forEach(update => {
|
1569
|
-
let updated = false;
|
1570
|
-
switch (update.dataType) {
|
1571
|
-
case 'LINEITEM':
|
1572
|
-
updated = this.applyLineItemUpdate(li, update, charges);
|
1573
|
-
break;
|
1574
|
-
case 'CHARGE':
|
1575
|
-
updated = this.applyChargeUpdate(li, update);
|
1576
|
-
break;
|
1577
|
-
case 'GROUP_CHARGE':
|
1578
|
-
updated = this.applyChargeGroupUpdate(li, update);
|
1579
|
-
break;
|
1580
|
-
default:
|
1581
|
-
// Unknown dataType. Do not try to handle it anymore
|
1582
|
-
updated = true;
|
1583
|
-
}
|
1584
|
-
if (!updated) {
|
1585
|
-
unhandledUpdates.push(update);
|
1586
|
-
}
|
1587
|
-
});
|
1588
|
-
remainingUpdates = unhandledUpdates;
|
1589
|
-
});
|
1590
|
-
currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
|
1591
|
-
}
|
1592
|
-
}
|
1593
|
-
delete(lineItems, id) {
|
1594
|
-
const idsToRemove = [id];
|
1595
|
-
const topLevelLineItem = lineItems.find(li => li.id === id);
|
1596
|
-
if (topLevelLineItem) {
|
1597
|
-
// find term-related line items (which are only top level)
|
1598
|
-
// expired term line items won't be deleted
|
1599
|
-
let foundTermLineItem = topLevelLineItem;
|
1600
|
-
while (foundTermLineItem) {
|
1601
|
-
foundTermLineItem = lineItems.find(li => foundTermLineItem && li.rampInstanceId === foundTermLineItem.id);
|
1602
|
-
if (foundTermLineItem) {
|
1603
|
-
idsToRemove.push(foundTermLineItem.id);
|
1604
|
-
}
|
958
|
+
else {
|
959
|
+
return this.flowConfiguration.calculate$(state);
|
1605
960
|
}
|
1606
|
-
}
|
1607
|
-
|
1608
|
-
|
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;
|
961
|
+
}), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
962
|
+
this.executionInProgress$.next(false);
|
963
|
+
return throwError(() => e);
|
964
|
+
}));
|
1653
965
|
}
|
1654
|
-
|
1655
|
-
const
|
1656
|
-
if (!
|
1657
|
-
return
|
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}`);
|
966
|
+
executeStatelessActions(request) {
|
967
|
+
const state = this.salesTransactionService.state;
|
968
|
+
if (!state || !request.actions?.length) {
|
969
|
+
return;
|
1667
970
|
}
|
1668
|
-
|
971
|
+
let flowState = state;
|
972
|
+
request.actions.forEach(action => {
|
973
|
+
try {
|
974
|
+
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
975
|
+
}
|
976
|
+
catch (e) {
|
977
|
+
console.error(e);
|
978
|
+
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
979
|
+
throw e;
|
980
|
+
}
|
981
|
+
});
|
982
|
+
this.salesTransactionService.setState(flowState);
|
1669
983
|
}
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
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}`);
|
984
|
+
executeStatelessSelectors(request) {
|
985
|
+
if (!this.salesTransactionService.state) {
|
986
|
+
throw 'State is not initialized';
|
1683
987
|
}
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
this.updatedSubj$ = new Subject();
|
1702
|
-
this.updated$ = this.updatedSubj$.asObservable();
|
1703
|
-
}
|
1704
|
-
calculate$(quoteDraft) {
|
1705
|
-
return this.extendedApply$(quoteDraft).pipe(tap$1(result => {
|
1706
|
-
// sort the result current state based on the quote draft initial state
|
1707
|
-
const initialStateIds = quoteDraft.initialState.map(lineItem => lineItem.integrationId);
|
1708
|
-
result.currentState = result.currentState
|
1709
|
-
.slice()
|
1710
|
-
.sort((a, b) => initialStateIds.indexOf(a.integrationId) - initialStateIds.indexOf(b.integrationId));
|
1711
|
-
this.quoteDraftService.updateQuoteDraft(result);
|
1712
|
-
}), map$1(noop));
|
1713
|
-
}
|
1714
|
-
calculate(quoteDraft) {
|
1715
|
-
this.calculate$(quoteDraft).subscribe();
|
988
|
+
const flowState = this.salesTransactionService.state;
|
989
|
+
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
990
|
+
try {
|
991
|
+
result.selectors[key] = {
|
992
|
+
success: true,
|
993
|
+
result: this.executeSelectorScript(flowState, selector),
|
994
|
+
};
|
995
|
+
}
|
996
|
+
catch (e) {
|
997
|
+
console.error(e);
|
998
|
+
result.selectors[key] = {
|
999
|
+
success: false,
|
1000
|
+
errorMessage: String(e),
|
1001
|
+
};
|
1002
|
+
}
|
1003
|
+
return result;
|
1004
|
+
}, { stateId: '', selectors: {} });
|
1716
1005
|
}
|
1717
|
-
|
1718
|
-
const
|
1719
|
-
if (!
|
1720
|
-
|
1006
|
+
initProcessors$() {
|
1007
|
+
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
1008
|
+
if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
|
1009
|
+
// Skip initialization as backend will take processors from SF
|
1010
|
+
return of(undefined);
|
1721
1011
|
}
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
return of(null);
|
1012
|
+
const owners$ = Object.values(this.flowInfoService.templates)
|
1013
|
+
.map(template => {
|
1014
|
+
if (!template) {
|
1015
|
+
return;
|
1016
|
+
}
|
1017
|
+
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
1018
|
+
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
|
1019
|
+
const processorsMap = processors.reduce((acc, p) => {
|
1020
|
+
acc[p.apiName] = p;
|
1021
|
+
return acc;
|
1022
|
+
}, {});
|
1023
|
+
this.processors[template.id] = processorsMap;
|
1024
|
+
}));
|
1025
|
+
})
|
1026
|
+
.filter(isDefined);
|
1027
|
+
if (!owners$.length) {
|
1028
|
+
return of(undefined);
|
1740
1029
|
}
|
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();
|
1030
|
+
return forkJoin(owners$).pipe(map(noop));
|
1749
1031
|
}
|
1750
|
-
|
1751
|
-
const
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1032
|
+
executeActionScript(request, executable) {
|
1033
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1034
|
+
if (!configurationProcessor?.script) {
|
1035
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1036
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1037
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1755
1038
|
}
|
1756
|
-
return
|
1757
|
-
}
|
1758
|
-
delete(ids) {
|
1759
|
-
this.delete$(ids).subscribe();
|
1039
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1760
1040
|
}
|
1761
|
-
|
1762
|
-
const
|
1763
|
-
if (!
|
1764
|
-
|
1041
|
+
executeSelectorScript(request, executable) {
|
1042
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
1043
|
+
if (!configurationProcessor?.script) {
|
1044
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
1045
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
1046
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
1765
1047
|
}
|
1766
|
-
|
1767
|
-
return of([]).pipe(switchMap(() => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
1048
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1768
1049
|
}
|
1769
|
-
|
1770
|
-
const
|
1771
|
-
|
1772
|
-
|
1050
|
+
executeProcessorScript(request, configurationProcessor, inputData) {
|
1051
|
+
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
1052
|
+
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
1053
|
+
if (!functionToExecute) {
|
1054
|
+
const script = `${configurationProcessor.script}\nreturn transform;`;
|
1055
|
+
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
1056
|
+
functionToExecute = new Function(script + sourceMap)();
|
1057
|
+
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
1773
1058
|
}
|
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$();
|
1059
|
+
return functionToExecute({
|
1060
|
+
request,
|
1061
|
+
inputData,
|
1062
|
+
flowStore: this.flowStore,
|
1063
|
+
});
|
1810
1064
|
}
|
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
|
-
};
|
1065
|
+
generateRequestId(scope, selectorName, inputData) {
|
1066
|
+
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
1067
|
+
return `${scope}/${selectorName}/${inputDataHash}`;
|
1824
1068
|
}
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1069
|
+
checkStatefulChanges(requestId, selectorResult) {
|
1070
|
+
if (this.trackedStatefulChangesMap.has(requestId)) {
|
1071
|
+
if (!this.initialStatefulData[requestId]) {
|
1072
|
+
this.initialStatefulData[requestId] = selectorResult;
|
1073
|
+
}
|
1074
|
+
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
1075
|
+
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
1830
1076
|
}
|
1831
|
-
return this.proceduresApiService.apply$(request);
|
1832
1077
|
}
|
1833
1078
|
}
|
1834
|
-
|
1835
|
-
|
1836
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1079
|
+
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 });
|
1080
|
+
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
1081
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
1837
1082
|
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
|
-
}] });
|
1083
|
+
}], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i3.FlowStateApiService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
1084
|
+
type: Optional
|
1085
|
+
}, {
|
1086
|
+
type: Inject,
|
1087
|
+
args: [FLOW_CUSTOMIZATION]
|
1088
|
+
}] }]; } });
|
1852
1089
|
|
1853
1090
|
class FlowStateConfigurationService {
|
1854
|
-
constructor(flowInfoService,
|
1091
|
+
constructor(flowInfoService, flowStateService) {
|
1855
1092
|
this.flowInfoService = flowInfoService;
|
1856
|
-
this.flowConfigurationService = flowConfigurationService;
|
1857
|
-
this.flowStateApiService = flowStateApiService;
|
1858
1093
|
this.flowStateService = flowStateService;
|
1859
|
-
this.configurationStateId$ = new BehaviorSubject(null);
|
1860
|
-
}
|
1861
|
-
get configurationStateId() {
|
1862
|
-
return this.configurationStateId$.value;
|
1863
1094
|
}
|
1864
1095
|
addToCart$(props) {
|
1865
1096
|
let request$;
|
@@ -1870,26 +1101,22 @@ class FlowStateConfigurationService {
|
|
1870
1101
|
request$ = of();
|
1871
1102
|
}
|
1872
1103
|
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
|
-
}));
|
1104
|
+
// TODO: Implement
|
1105
|
+
request$ = of();
|
1880
1106
|
}
|
1881
1107
|
}
|
1882
1108
|
else {
|
1883
|
-
|
1109
|
+
// TODO: Implement
|
1110
|
+
request$ = of();
|
1884
1111
|
}
|
1885
|
-
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map
|
1112
|
+
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1886
1113
|
}
|
1887
1114
|
}
|
1888
|
-
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token:
|
1115
|
+
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
1116
|
FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
|
1890
1117
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
|
1891
1118
|
type: Injectable
|
1892
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type:
|
1119
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }]; } });
|
1893
1120
|
|
1894
1121
|
class IntegrationState {
|
1895
1122
|
constructor() {
|
@@ -1909,12 +1136,12 @@ class IntegrationState {
|
|
1909
1136
|
this.action$.next(action);
|
1910
1137
|
}
|
1911
1138
|
listen$(actionType) {
|
1912
|
-
return this.action$.pipe(filter
|
1139
|
+
return this.action$.pipe(filter(action => action.type === actionType), map(action => action.payload));
|
1913
1140
|
}
|
1914
1141
|
listenAll$() {
|
1915
1142
|
return this.action$.asObservable();
|
1916
1143
|
}
|
1917
|
-
|
1144
|
+
reset() {
|
1918
1145
|
this.stateSubj$.next({});
|
1919
1146
|
}
|
1920
1147
|
}
|
@@ -1925,8 +1152,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1925
1152
|
}] });
|
1926
1153
|
|
1927
1154
|
class ProductImagesService {
|
1928
|
-
constructor(
|
1929
|
-
this.
|
1155
|
+
constructor(productsAdminApiService) {
|
1156
|
+
this.productsAdminApiService = productsAdminApiService;
|
1930
1157
|
this.imagesMap$ = new BehaviorSubject({});
|
1931
1158
|
}
|
1932
1159
|
getImageUrl$(productId) {
|
@@ -1934,172 +1161,53 @@ class ProductImagesService {
|
|
1934
1161
|
this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
|
1935
1162
|
this.fetchProductImage(productId);
|
1936
1163
|
}
|
1937
|
-
return this.imagesMap$.pipe(map
|
1164
|
+
return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
|
1938
1165
|
}
|
1939
1166
|
fetchProductImage(productId) {
|
1940
|
-
this.
|
1167
|
+
this.productsAdminApiService
|
1941
1168
|
.fetchImage$(productId)
|
1942
|
-
.pipe(map
|
1169
|
+
.pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
|
1943
1170
|
.subscribe();
|
1944
1171
|
}
|
1945
1172
|
}
|
1946
|
-
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.
|
1173
|
+
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
1174
|
ProductImagesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService });
|
1948
1175
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, decorators: [{
|
1949
1176
|
type: Injectable
|
1950
|
-
}], ctorParameters: function () { return [{ type: i1.
|
1177
|
+
}], ctorParameters: function () { return [{ type: i1.ProductsAdminApiService }]; } });
|
1951
1178
|
|
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];
|
1179
|
+
class CatalogProductsService {
|
1180
|
+
constructor() {
|
1181
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
1182
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
1982
1183
|
}
|
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 = {};
|
1184
|
+
get state() {
|
1185
|
+
return this.stateSubj$.getValue();
|
1997
1186
|
}
|
1998
1187
|
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;
|
1188
|
+
this.stateSubj$.next(null);
|
2081
1189
|
}
|
2082
|
-
|
2083
|
-
|
1190
|
+
setState(state) {
|
1191
|
+
this.stateSubj$.next(state);
|
2084
1192
|
}
|
2085
1193
|
}
|
2086
|
-
|
2087
|
-
|
2088
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1194
|
+
CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1195
|
+
CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
|
1196
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
|
2089
1197
|
type: Injectable
|
2090
|
-
}]
|
1198
|
+
}] });
|
2091
1199
|
|
2092
1200
|
class ConfigurationStateService {
|
2093
|
-
constructor(configurationRuntimeService, configurationService,
|
1201
|
+
constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService) {
|
2094
1202
|
this.configurationRuntimeService = configurationRuntimeService;
|
2095
1203
|
this.configurationService = configurationService;
|
2096
|
-
this.quoteDraftService = quoteDraftService;
|
2097
|
-
this.toastService = toastService;
|
2098
1204
|
this.flowStateService = flowStateService;
|
2099
1205
|
this.flowInfoService = flowInfoService;
|
2100
1206
|
this.flowConfigurationService = flowConfigurationService;
|
2101
1207
|
this.flowStateApiService = flowStateApiService;
|
2102
|
-
this.
|
1208
|
+
this.salesTransactionService = salesTransactionService;
|
1209
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
1210
|
+
this.toastService = toastService;
|
2103
1211
|
this.isInitialized$ = new BehaviorSubject(false);
|
2104
1212
|
this.canceledConfiguration$ = new Subject();
|
2105
1213
|
this.NOT_INITIALIZED = Symbol();
|
@@ -2123,9 +1231,9 @@ class ConfigurationStateService {
|
|
2123
1231
|
request$ = this.initStateful$();
|
2124
1232
|
}
|
2125
1233
|
else {
|
2126
|
-
request$ = this.
|
1234
|
+
request$ = this.configurationService.init$();
|
2127
1235
|
}
|
2128
|
-
return request$.pipe(
|
1236
|
+
return request$.pipe(take(1), tap(() => {
|
2129
1237
|
this.isInitialized$.next(true);
|
2130
1238
|
this.canceledConfiguration$ = new Subject();
|
2131
1239
|
}));
|
@@ -2139,10 +1247,11 @@ class ConfigurationStateService {
|
|
2139
1247
|
this.configurationStore = {};
|
2140
1248
|
this.executedFunctions = {};
|
2141
1249
|
this.configurationService.reset();
|
1250
|
+
this.configurationRuntimeService.reset();
|
2142
1251
|
}
|
2143
1252
|
execute$(exec) {
|
2144
1253
|
const request = this.execToRequest(exec);
|
2145
|
-
return this.executeRequest$(request).pipe(map
|
1254
|
+
return this.executeRequest$(request).pipe(map(result => {
|
2146
1255
|
// Keep only requested results
|
2147
1256
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
2148
1257
|
if (exec.selectors?.[requestId]) {
|
@@ -2164,7 +1273,7 @@ class ConfigurationStateService {
|
|
2164
1273
|
}
|
2165
1274
|
// prevent parallel configuration requests in stateless mode
|
2166
1275
|
if (!this.statelessExecutionRequest$) {
|
2167
|
-
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay
|
1276
|
+
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
|
2168
1277
|
}
|
2169
1278
|
return this.statelessExecutionRequest$;
|
2170
1279
|
}
|
@@ -2178,7 +1287,7 @@ class ConfigurationStateService {
|
|
2178
1287
|
},
|
2179
1288
|
},
|
2180
1289
|
});
|
2181
|
-
return this.executeRequest$(request).pipe(map
|
1290
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
2182
1291
|
}
|
2183
1292
|
subscribe$(selectorName, inputData = {}, options) {
|
2184
1293
|
const requestId = UUID.UUID();
|
@@ -2201,56 +1310,50 @@ class ConfigurationStateService {
|
|
2201
1310
|
this.executeRequest$(request).subscribe();
|
2202
1311
|
}
|
2203
1312
|
}
|
2204
|
-
return subscription.data$.pipe(filter
|
1313
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
|
2205
1314
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
2206
1315
|
delete this.subscriptions[requestId];
|
2207
1316
|
}
|
2208
1317
|
}), takeUntil(this.canceledConfiguration$));
|
2209
1318
|
}
|
2210
|
-
saveConfiguration(
|
1319
|
+
saveConfiguration() {
|
2211
1320
|
if (this.isStatefulConfiguration) {
|
2212
|
-
return this.flowStateApiService
|
2213
|
-
|
2214
|
-
|
1321
|
+
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
|
1322
|
+
}
|
1323
|
+
const state = this.salesTransactionService.state;
|
1324
|
+
if (!state) {
|
1325
|
+
return of({ id: '' });
|
1326
|
+
}
|
1327
|
+
const { standalone } = this.flowInfoService.flow.properties;
|
1328
|
+
if (standalone) {
|
1329
|
+
const request = {
|
1330
|
+
transactionContext: state,
|
1331
|
+
flowId: this.flowInfoService.flow.id,
|
1332
|
+
};
|
1333
|
+
return this.salesTransactionApiService.upsert(request).pipe(map(id => ({ id })));
|
1334
|
+
}
|
1335
|
+
const transactionContext = this.salesTransactionService.state;
|
1336
|
+
const configurationRoot = this.configurationService.root;
|
1337
|
+
if (!transactionContext || !configurationRoot) {
|
1338
|
+
return of({ id: '' });
|
1339
|
+
}
|
1340
|
+
const stateItems = transactionContext.salesTransaction.salesTransactionItems;
|
1341
|
+
const isNewTransactionItem = stateItems.every(ti => ti.id !== configurationRoot.id);
|
1342
|
+
let salesTransactionItems;
|
1343
|
+
if (isNewTransactionItem) {
|
1344
|
+
salesTransactionItems = [...stateItems, configurationRoot];
|
2215
1345
|
}
|
2216
1346
|
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
|
-
}
|
1347
|
+
salesTransactionItems = stateItems.map(ti => (ti.id === configurationRoot.id ? configurationRoot : ti));
|
2253
1348
|
}
|
1349
|
+
const newState = {
|
1350
|
+
...transactionContext,
|
1351
|
+
salesTransaction: {
|
1352
|
+
...transactionContext.salesTransaction,
|
1353
|
+
salesTransactionItems,
|
1354
|
+
},
|
1355
|
+
};
|
1356
|
+
return this.flowConfigurationService.calculate$(newState).pipe(map(() => ({ id: '' })));
|
2254
1357
|
}
|
2255
1358
|
cancelConfiguration() {
|
2256
1359
|
if (!this.isInitialized$.value) {
|
@@ -2269,36 +1372,32 @@ class ConfigurationStateService {
|
|
2269
1372
|
return this.flowInfoService.flow?.properties.stateful ?? false;
|
2270
1373
|
}
|
2271
1374
|
initStateful$() {
|
2272
|
-
this.ownerId = this.configurationRuntimeService.
|
2273
|
-
const
|
2274
|
-
if (!this.flowStateService.stateId) {
|
1375
|
+
this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
|
1376
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
1377
|
+
if (!productId || !this.flowStateService.stateId) {
|
2275
1378
|
return of(undefined);
|
2276
1379
|
}
|
2277
|
-
const container = this.configurationRuntimeService.
|
2278
|
-
const lineItem = this.configurationService.generateLineItem();
|
1380
|
+
const container = this.configurationRuntimeService.uiDefinitionContainer;
|
2279
1381
|
let request$;
|
2280
|
-
if (!
|
1382
|
+
if (!transactionItemId) {
|
2281
1383
|
request$ = this.flowStateApiService.newConfiguration(this.flowStateService.stateId, {
|
2282
|
-
|
1384
|
+
transactionItem: generateTransactionItem(productId),
|
2283
1385
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2284
1386
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2285
1387
|
});
|
2286
1388
|
}
|
2287
1389
|
else {
|
2288
1390
|
request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
|
2289
|
-
|
1391
|
+
transactionItemId,
|
2290
1392
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2291
1393
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2292
1394
|
});
|
2293
1395
|
}
|
2294
|
-
return request$.pipe(map
|
1396
|
+
return request$.pipe(map(r => {
|
2295
1397
|
this.stateId = r.stateId;
|
2296
1398
|
return undefined;
|
2297
1399
|
}));
|
2298
1400
|
}
|
2299
|
-
initStateless$() {
|
2300
|
-
return this.configurationService.configure().pipe(map$1(() => undefined));
|
2301
|
-
}
|
2302
1401
|
execToRequest(exec) {
|
2303
1402
|
return {
|
2304
1403
|
actions: exec.actions?.map(action => ({
|
@@ -2338,37 +1437,35 @@ class ConfigurationStateService {
|
|
2338
1437
|
else {
|
2339
1438
|
execution$ = this.executeStateless$(fullRequest);
|
2340
1439
|
}
|
2341
|
-
return execution$.pipe(tap
|
1440
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
2342
1441
|
}
|
2343
1442
|
executeStateless$(request) {
|
2344
1443
|
this.executionInProgress$.next(true);
|
2345
|
-
return
|
1444
|
+
return this.configurationService.state$.pipe(first(), switchMap(state => {
|
2346
1445
|
// Apply actions and execute configuration/price call
|
2347
1446
|
// No need to run configuration if no actions in the request
|
2348
1447
|
if (!request.actions?.length) {
|
2349
1448
|
return of(undefined);
|
2350
1449
|
}
|
2351
|
-
let configurationRequest = this.configurationService.generateRequest(false);
|
2352
1450
|
request.actions.forEach(action => {
|
2353
|
-
|
1451
|
+
state = this.executeActionScript(state, action) ?? state;
|
2354
1452
|
});
|
2355
|
-
|
2356
|
-
|
2357
|
-
}), map$1(() => {
|
1453
|
+
return this.configurationService.configureRequest$(state);
|
1454
|
+
}), map(() => {
|
2358
1455
|
// Run selectors and apply them to the state
|
2359
|
-
const configurationState = this.configurationService.
|
1456
|
+
const configurationState = this.configurationService.state;
|
2360
1457
|
if (!configurationState) {
|
2361
1458
|
return { stateId: '', selectors: {} };
|
2362
1459
|
}
|
2363
1460
|
return this.runStatelessSelectors(request, configurationState);
|
2364
|
-
}), tap
|
2365
|
-
const configurationState = this.configurationService.
|
1461
|
+
}), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
|
1462
|
+
const configurationState = this.configurationService.previousState;
|
2366
1463
|
if (configurationState) {
|
2367
1464
|
const selectorsResult = this.runStatelessSelectors(request, configurationState);
|
2368
1465
|
this.handleSelectorsResponse(selectorsResult.selectors);
|
2369
1466
|
}
|
2370
1467
|
this.executionInProgress$.next(false);
|
2371
|
-
if (!this.configurationRuntimeService.
|
1468
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
2372
1469
|
this.toastService.add({ severity: ToastType.error, summary: String(error) });
|
2373
1470
|
}
|
2374
1471
|
return throwError(() => error);
|
@@ -2389,21 +1486,21 @@ class ConfigurationStateService {
|
|
2389
1486
|
};
|
2390
1487
|
this.executionInProgress$.next(true);
|
2391
1488
|
return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
|
2392
|
-
}), tap
|
1489
|
+
}), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
2393
1490
|
this.executionInProgress$.next(false);
|
2394
1491
|
return throwError(() => e);
|
2395
1492
|
}));
|
2396
1493
|
}
|
2397
1494
|
executeStateful$(request) {
|
2398
|
-
return this.executionInProgress$.pipe(filter
|
1495
|
+
return this.executionInProgress$.pipe(filter(inProgress => !inProgress), take(1), switchMap(() =>
|
2399
1496
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
2400
1497
|
combineLatest([
|
2401
1498
|
this.statefulExecutionRequest$,
|
2402
|
-
of(undefined).pipe(tap
|
2403
|
-
])), map
|
1499
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1500
|
+
])), map(([response]) => response), take(1));
|
2404
1501
|
}
|
2405
1502
|
executeActionScript(request, processor) {
|
2406
|
-
const { actions } = this.configurationRuntimeService.
|
1503
|
+
const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2407
1504
|
const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
|
2408
1505
|
if (!configurationProcessor?.script) {
|
2409
1506
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2411,7 +1508,7 @@ class ConfigurationStateService {
|
|
2411
1508
|
return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
|
2412
1509
|
}
|
2413
1510
|
executeSelectorScript(request, processor) {
|
2414
|
-
const { selectors } = this.configurationRuntimeService.
|
1511
|
+
const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2415
1512
|
const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
|
2416
1513
|
if (!configurationProcessor?.script) {
|
2417
1514
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2452,25 +1549,52 @@ class ConfigurationStateService {
|
|
2452
1549
|
}, { stateId: '', selectors: {} });
|
2453
1550
|
}
|
2454
1551
|
}
|
2455
|
-
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token:
|
1552
|
+
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
1553
|
ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
|
2457
1554
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
|
2458
1555
|
type: Injectable
|
2459
|
-
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type:
|
1556
|
+
}], 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
1557
|
|
2461
1558
|
class ConfigurationModule {
|
2462
1559
|
}
|
2463
1560
|
ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2464
1561
|
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: [
|
1562
|
+
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1563
|
+
ConfigurationService,
|
1564
|
+
ConfigurationStateService,
|
1565
|
+
ConfigurationRuntimeService,
|
1566
|
+
TestModeConfigurationService,
|
1567
|
+
], imports: [ConfirmationDialogModule, ApiModule] });
|
2466
1568
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
|
2467
1569
|
type: NgModule,
|
2468
1570
|
args: [{
|
2469
1571
|
imports: [ConfirmationDialogModule, ApiModule],
|
2470
|
-
providers: [
|
1572
|
+
providers: [
|
1573
|
+
ConfigurationService,
|
1574
|
+
ConfigurationStateService,
|
1575
|
+
ConfigurationRuntimeService,
|
1576
|
+
TestModeConfigurationService,
|
1577
|
+
],
|
1578
|
+
}]
|
1579
|
+
}] });
|
1580
|
+
|
1581
|
+
class FlowConfigurationModule {
|
1582
|
+
}
|
1583
|
+
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
1584
|
+
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
1585
|
+
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
|
1586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
1587
|
+
type: NgModule,
|
1588
|
+
args: [{
|
1589
|
+
imports: [ApiModule],
|
1590
|
+
providers: [FlowConfigurationService],
|
2471
1591
|
}]
|
2472
1592
|
}] });
|
2473
1593
|
|
1594
|
+
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
1595
|
+
|
1596
|
+
const UI_DEFINITION_VERSION = 3;
|
1597
|
+
|
2474
1598
|
const DEFAULT_FORMATTING_SETTINGS = {
|
2475
1599
|
currencySymbol: DEFAULT_CURRENCY_SYMBOL,
|
2476
1600
|
decimalsCount: DEFAULT_DECIMALS_COUNT,
|
@@ -2484,14 +1608,14 @@ class SdkCoreModule {
|
|
2484
1608
|
SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2485
1609
|
SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
|
2486
1610
|
SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
|
2487
|
-
ContextService,
|
2488
1611
|
FlowInfoService,
|
2489
|
-
QuoteDraftService,
|
2490
1612
|
ProductImagesService,
|
2491
1613
|
IntegrationState,
|
2492
1614
|
FlowStateService,
|
2493
1615
|
FlowStateConfigurationService,
|
2494
1616
|
RuntimeSettingsService,
|
1617
|
+
SalesTransactionService,
|
1618
|
+
CatalogProductsService,
|
2495
1619
|
{
|
2496
1620
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2497
1621
|
useExisting: RuntimeSettingsService,
|
@@ -2502,14 +1626,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2502
1626
|
args: [{
|
2503
1627
|
imports: [ConfigurationModule, FlowConfigurationModule],
|
2504
1628
|
providers: [
|
2505
|
-
ContextService,
|
2506
1629
|
FlowInfoService,
|
2507
|
-
QuoteDraftService,
|
2508
1630
|
ProductImagesService,
|
2509
1631
|
IntegrationState,
|
2510
1632
|
FlowStateService,
|
2511
1633
|
FlowStateConfigurationService,
|
2512
1634
|
RuntimeSettingsService,
|
1635
|
+
SalesTransactionService,
|
1636
|
+
CatalogProductsService,
|
2513
1637
|
{
|
2514
1638
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2515
1639
|
useExisting: RuntimeSettingsService,
|
@@ -2565,6 +1689,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2565
1689
|
}]
|
2566
1690
|
}] });
|
2567
1691
|
|
1692
|
+
function filterSuccessfulExecute() {
|
1693
|
+
return (source) => source.pipe(filter((result) => result.success), map(r => r.result));
|
1694
|
+
}
|
1695
|
+
|
2568
1696
|
class DatePipe {
|
2569
1697
|
constructor() {
|
2570
1698
|
this.locale = inject(LOCALE_ID);
|
@@ -2684,5 +1812,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2684
1812
|
* Generated bundle index. Do not edit.
|
2685
1813
|
*/
|
2686
1814
|
|
2687
|
-
export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService,
|
1815
|
+
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
1816
|
//# sourceMappingURL=veloceapps-sdk-core.mjs.map
|