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