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