@veloceapps/sdk 11.0.0-3 → 11.0.0-30
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 +1 -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/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 +3 -4
- package/esm2020/core/modules/configuration/index.mjs +2 -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/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 +737 -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 +792 -1744
- 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,357 @@ 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
|
-
|
380
|
-
}
|
381
|
-
if (update.context) {
|
382
|
-
this.context.set(update.context);
|
485
|
+
getPCMModel() {
|
486
|
+
const pcmModel = this.configurationRuntimeService.pcmModel;
|
487
|
+
if (!pcmModel) {
|
488
|
+
throw new Error('PCM model not initialized');
|
383
489
|
}
|
384
|
-
|
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 SalesTransactionService {
|
500
|
+
get isInitialized$() {
|
501
|
+
return this.isInitializedSubj$.asObservable();
|
502
|
+
}
|
503
|
+
get isInitialized() {
|
504
|
+
return this.isInitializedSubj$.getValue();
|
505
|
+
}
|
506
|
+
set hasUnsavedChanges(value) {
|
507
|
+
this.hasUnsavedChangesSubj$.next(value);
|
508
|
+
if (!this.hasUnsavedChanges) {
|
509
|
+
this.initialState = this.state?.salesTransactionItems ?? [];
|
393
510
|
}
|
394
|
-
const updatedCurrentState = this.currentState.map(lineItem => {
|
395
|
-
const updated = priceSummary.lineItems.find(li => li.id === lineItem.id);
|
396
|
-
return updated ?? lineItem;
|
397
|
-
});
|
398
|
-
this.quoteSubj$.next({
|
399
|
-
...quoteDraft,
|
400
|
-
currentState: updatedCurrentState,
|
401
|
-
totalPrices: priceSummary.totalPrices,
|
402
|
-
approvalItems: priceSummary.approvalItems,
|
403
|
-
});
|
404
511
|
}
|
405
|
-
|
406
|
-
this.
|
512
|
+
get hasUnsavedChanges() {
|
513
|
+
return this.hasUnsavedChangesSubj$.getValue();
|
407
514
|
}
|
408
|
-
get
|
409
|
-
return
|
515
|
+
get state() {
|
516
|
+
return this.stateSubj$.getValue();
|
410
517
|
}
|
411
|
-
get
|
412
|
-
|
413
|
-
if (!quote) {
|
414
|
-
return null;
|
415
|
-
}
|
416
|
-
return {
|
417
|
-
...quote,
|
418
|
-
context: this.context.resolve(),
|
419
|
-
};
|
518
|
+
get hasProducts() {
|
519
|
+
return Boolean(this.state?.salesTransactionItems.length);
|
420
520
|
}
|
421
|
-
|
422
|
-
|
521
|
+
constructor(flowInfoService, salesTransactionApiService) {
|
522
|
+
this.flowInfoService = flowInfoService;
|
523
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
524
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
525
|
+
this.isInitializedSubj$ = new BehaviorSubject(false);
|
526
|
+
this.hasUnsavedChangesSubj$ = new BehaviorSubject(false);
|
527
|
+
this.initialState = [];
|
528
|
+
this.hasUnsavedChanges$ = this.hasUnsavedChangesSubj$.asObservable();
|
529
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter$1(isDefined));
|
423
530
|
}
|
424
|
-
|
425
|
-
return this.
|
531
|
+
init(headerId, params) {
|
532
|
+
return this.salesTransactionApiService.getState(headerId, params).pipe(tap(res => this.stateSubj$.next(res.salesTransaction)), map(res => res.salesTransaction));
|
426
533
|
}
|
427
|
-
|
428
|
-
|
534
|
+
finalizeInit() {
|
535
|
+
this.isInitializedSubj$.next(true);
|
536
|
+
this.hasUnsavedChanges = false;
|
429
537
|
}
|
430
|
-
|
431
|
-
|
538
|
+
reset() {
|
539
|
+
this.stateSubj$.next(null);
|
540
|
+
this.isInitializedSubj$.next(false);
|
541
|
+
this.hasUnsavedChangesSubj$.next(false);
|
432
542
|
}
|
433
|
-
|
434
|
-
return this.
|
543
|
+
getInitialState() {
|
544
|
+
return this.initialState;
|
435
545
|
}
|
436
|
-
|
437
|
-
|
546
|
+
setState(state) {
|
547
|
+
this.stateSubj$.next(state);
|
438
548
|
}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
549
|
+
}
|
550
|
+
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 });
|
551
|
+
SalesTransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService });
|
552
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, decorators: [{
|
553
|
+
type: Injectable
|
554
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i1.SalesTransactionApiService }]; } });
|
555
|
+
|
556
|
+
class FlowConfigurationService {
|
557
|
+
constructor(orchestrationsApiService, salesTransactionService) {
|
558
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
559
|
+
this.salesTransactionService = salesTransactionService;
|
560
|
+
this.updatedSubj$ = new Subject();
|
561
|
+
this.updated$ = this.updatedSubj$.asObservable();
|
448
562
|
}
|
449
|
-
|
450
|
-
|
451
|
-
|
563
|
+
calculate$(state) {
|
564
|
+
return this.orchestrationsApiService.apply$({ salesTransaction: state }).pipe(tap(result => this.salesTransactionService.setState(result.salesTransaction)), map(noop));
|
565
|
+
}
|
566
|
+
calculate(state) {
|
567
|
+
this.calculate$(state).subscribe();
|
568
|
+
}
|
569
|
+
revert$(transactionItemId) {
|
570
|
+
const state = this.salesTransactionService.state;
|
571
|
+
const initialState = this.salesTransactionService.getInitialState();
|
572
|
+
const currentState = state?.salesTransactionItems ?? [];
|
573
|
+
const currentItemIndex = currentState.findIndex(({ id }) => id === transactionItemId);
|
574
|
+
const currentItem = currentState[currentItemIndex];
|
575
|
+
const initialItem = initialState.find(({ integrationId }) => integrationId === currentItem?.integrationId);
|
576
|
+
if (!state || !currentItem || !initialItem) {
|
577
|
+
return of(null);
|
452
578
|
}
|
453
|
-
|
454
|
-
|
579
|
+
const updatedState = cloneDeep(currentState);
|
580
|
+
updatedState.splice(currentItemIndex, 1, initialItem);
|
581
|
+
return of([]).pipe(tap(() => {
|
582
|
+
this.salesTransactionService.setState({ ...state, salesTransactionItems: updatedState });
|
583
|
+
}), switchMap(() => this.calculate$({ ...state, salesTransactionItems: updatedState })), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
584
|
+
}
|
585
|
+
revert(transactionItemId) {
|
586
|
+
this.revert$(transactionItemId).subscribe();
|
587
|
+
}
|
588
|
+
delete$(ids) {
|
589
|
+
const state = this.salesTransactionService.state;
|
590
|
+
if (!state) {
|
591
|
+
return of(null);
|
455
592
|
}
|
593
|
+
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());
|
594
|
+
}
|
595
|
+
delete(ids) {
|
596
|
+
this.delete$(ids).subscribe();
|
597
|
+
}
|
598
|
+
handleErrorAndBounceBack() {
|
599
|
+
return (source$) => {
|
600
|
+
return source$.pipe(catchError$1(error => {
|
601
|
+
console.error(error);
|
602
|
+
// bounce back if configuration call has failed
|
603
|
+
const state = this.salesTransactionService.state;
|
604
|
+
if (state) {
|
605
|
+
this.salesTransactionService.setState(state);
|
606
|
+
this.updatedSubj$.next();
|
607
|
+
}
|
608
|
+
return throwError(() => error);
|
609
|
+
}));
|
610
|
+
};
|
456
611
|
}
|
457
612
|
}
|
458
|
-
|
459
|
-
|
460
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
613
|
+
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 });
|
614
|
+
FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
|
615
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
|
461
616
|
type: Injectable
|
462
|
-
}], ctorParameters: function () { return [{ type:
|
617
|
+
}], ctorParameters: function () { return [{ type: i1.OrchestrationsApiService }, { type: SalesTransactionService }]; } });
|
463
618
|
|
464
619
|
class FlowStateService {
|
465
|
-
constructor(
|
466
|
-
this.contextService = contextService;
|
467
|
-
this.quoteDraftService = quoteDraftService;
|
468
|
-
this.flowInfoService = flowInfoService;
|
620
|
+
constructor(flowConfiguration, flowInfoService, flowStateApiService, processorsApiService, salesTransactionApiService, salesTransactionService, toastService, customizationService) {
|
469
621
|
this.flowConfiguration = flowConfiguration;
|
470
|
-
this.
|
622
|
+
this.flowInfoService = flowInfoService;
|
471
623
|
this.flowStateApiService = flowStateApiService;
|
472
|
-
this.
|
624
|
+
this.processorsApiService = processorsApiService;
|
625
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
626
|
+
this.salesTransactionService = salesTransactionService;
|
473
627
|
this.toastService = toastService;
|
474
628
|
this.customizationService = customizationService;
|
475
629
|
this.NOT_INITIALIZED = Symbol();
|
@@ -486,68 +640,22 @@ class FlowStateService {
|
|
486
640
|
this.cleanup$ = new Subject();
|
487
641
|
this.statefulExecutionRequest$ = this.initBufferedRequest$();
|
488
642
|
/*
|
489
|
-
In stateless mode watch
|
490
|
-
all subscriptions get their updates according to updated
|
643
|
+
In stateless mode watch State changes and call executeRequest so that
|
644
|
+
all subscriptions get their updates according to updated State
|
491
645
|
*/
|
492
646
|
this.isInitialized$()
|
493
|
-
.pipe(filter$1(Boolean), filter$1(() => !this.
|
647
|
+
.pipe(filter$1(Boolean), filter$1(() => !this.flowInfoService.flow.properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
|
494
648
|
.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
649
|
}
|
540
650
|
init$() {
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
}
|
548
|
-
}));
|
651
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
652
|
+
return this.initProcessors$().pipe(switchMap(() => this.initStateful$()));
|
653
|
+
}
|
654
|
+
else {
|
655
|
+
return forkJoin([this.initStateless$(), this.initProcessors$()]).pipe(map(noop));
|
656
|
+
}
|
549
657
|
}
|
550
|
-
|
658
|
+
reset() {
|
551
659
|
Object.values(this.subscriptions).forEach(({ data$ }) => data$.complete());
|
552
660
|
this.subscriptions = {};
|
553
661
|
if (this.stateId$.value) {
|
@@ -559,9 +667,9 @@ class FlowStateService {
|
|
559
667
|
this.cleanup$.next();
|
560
668
|
}
|
561
669
|
get hasUnsavedChanges() {
|
562
|
-
return this.
|
670
|
+
return this.flowInfoService.flow.properties.stateful
|
563
671
|
? Array.from(this.trackedStatefulChangesMap.values()).some(Boolean)
|
564
|
-
: this.
|
672
|
+
: this.salesTransactionService.hasUnsavedChanges;
|
565
673
|
}
|
566
674
|
get stateId() {
|
567
675
|
return this.stateId$.value;
|
@@ -570,14 +678,14 @@ class FlowStateService {
|
|
570
678
|
return this.executionInProgress$.asObservable();
|
571
679
|
}
|
572
680
|
isInitialized$() {
|
573
|
-
return combineLatest([this.stateId$, this.
|
681
|
+
return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map(values => values.some(Boolean)));
|
574
682
|
}
|
575
683
|
isInitialized() {
|
576
|
-
return Boolean(this.stateId$.value) || this.
|
684
|
+
return Boolean(this.stateId$.value) || this.salesTransactionService.isInitialized;
|
577
685
|
}
|
578
686
|
execute$(scope, exec) {
|
579
687
|
const request = this.execToRequest(scope, exec);
|
580
|
-
return this.executeRequest$(request).pipe(map
|
688
|
+
return this.executeRequest$(request).pipe(map(result => {
|
581
689
|
// Keep only requested results
|
582
690
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
583
691
|
if (exec.selectors?.[requestId]) {
|
@@ -593,7 +701,7 @@ class FlowStateService {
|
|
593
701
|
actions: [{ name: action, inputData }],
|
594
702
|
};
|
595
703
|
const request = this.execToRequest(scope, exec);
|
596
|
-
return this.executeRequest$(request).pipe(map
|
704
|
+
return this.executeRequest$(request).pipe(map(noop));
|
597
705
|
}
|
598
706
|
select$(scope, selectorName, inputData) {
|
599
707
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -605,7 +713,7 @@ class FlowStateService {
|
|
605
713
|
},
|
606
714
|
},
|
607
715
|
});
|
608
|
-
return this.executeRequest$(request).pipe(map
|
716
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
609
717
|
}
|
610
718
|
subscribe$(scope, selectorName, inputData, options) {
|
611
719
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -631,16 +739,16 @@ class FlowStateService {
|
|
631
739
|
this.executeRequest$(request).subscribe();
|
632
740
|
}
|
633
741
|
}
|
634
|
-
return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map
|
742
|
+
return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map(data => data), finalize$1(() => {
|
635
743
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
636
744
|
delete this.subscriptions[requestId];
|
637
745
|
}
|
638
746
|
}));
|
639
747
|
}
|
640
748
|
save$() {
|
641
|
-
if (this.
|
749
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
642
750
|
if (this.stateId$.value) {
|
643
|
-
return this.flowStateApiService.save(this.stateId$.value).pipe(tap
|
751
|
+
return this.flowStateApiService.save(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })), tap(() => {
|
644
752
|
Array.from(this.trackedStatefulChangesMap.keys()).forEach(key => {
|
645
753
|
this.trackedStatefulChangesMap.set(key, false);
|
646
754
|
});
|
@@ -648,30 +756,26 @@ class FlowStateService {
|
|
648
756
|
}
|
649
757
|
}
|
650
758
|
else {
|
651
|
-
const
|
652
|
-
if (
|
653
|
-
return this.
|
654
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
655
|
-
}));
|
759
|
+
const state = this.salesTransactionService.state;
|
760
|
+
if (state) {
|
761
|
+
return this.salesTransactionApiService.upsert(state);
|
656
762
|
}
|
657
763
|
}
|
658
|
-
return of({
|
764
|
+
return of({ id: '' });
|
659
765
|
}
|
660
766
|
submit$() {
|
661
|
-
if (this.
|
767
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
662
768
|
if (this.stateId$.value) {
|
663
|
-
return this.flowStateApiService.submit(this.stateId$.value);
|
769
|
+
return this.flowStateApiService.submit(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })));
|
664
770
|
}
|
665
771
|
}
|
666
772
|
else {
|
667
|
-
const
|
668
|
-
if (
|
669
|
-
return this.
|
670
|
-
this.contextService.update({ properties: { VELOCE_PRISM__VersionId__c: versionId } });
|
671
|
-
}));
|
773
|
+
const state = this.salesTransactionService.state;
|
774
|
+
if (state) {
|
775
|
+
return this.salesTransactionApiService.submit(state);
|
672
776
|
}
|
673
777
|
}
|
674
|
-
return of({
|
778
|
+
return of({ id: '' });
|
675
779
|
}
|
676
780
|
getFlowStore() {
|
677
781
|
return this.flowStore;
|
@@ -709,10 +813,10 @@ class FlowStateService {
|
|
709
813
|
fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
|
710
814
|
}
|
711
815
|
}
|
712
|
-
const execution$ = this.
|
816
|
+
const execution$ = this.flowInfoService.flow.properties.stateful
|
713
817
|
? this.executeStateful$(fullRequest)
|
714
818
|
: this.executeStateless$(fullRequest);
|
715
|
-
return execution$.pipe(tap
|
819
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
716
820
|
}
|
717
821
|
handleSelectorsResponse(selectors) {
|
718
822
|
Object.entries(selectors).forEach(([requestId, selectorResult]) => {
|
@@ -727,31 +831,21 @@ class FlowStateService {
|
|
727
831
|
});
|
728
832
|
}
|
729
833
|
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
834
|
const processorsList = flatten(Object.values(this.processors).map(ownerMap => Object.values(ownerMap ?? {})));
|
739
835
|
const processors = processorsList.length ? processorsList : undefined;
|
740
836
|
const selectors = Object.values(this.subscriptions)
|
741
837
|
.map(({ request }) => request.selectors)
|
742
838
|
.filter(isDefined)
|
743
839
|
.reduce((trunk, selectors) => ({ ...trunk, ...selectors }), {});
|
744
|
-
const request = this.getDefaultExecutionRequestDTO();
|
745
840
|
return this.flowStateApiService
|
746
841
|
.init({
|
747
|
-
quoteId: this.
|
748
|
-
params: this.flowInfoService.
|
842
|
+
quoteId: this.flowInfoService.context.headerId,
|
843
|
+
params: this.flowInfoService.context,
|
749
844
|
actionsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.ACTION),
|
750
845
|
selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
|
751
|
-
selectors:
|
752
|
-
actions: request.actions,
|
846
|
+
selectors: selectors,
|
753
847
|
})
|
754
|
-
.pipe(map
|
848
|
+
.pipe(map(({ stateId, selectors }) => {
|
755
849
|
this.handleSelectorsResponse(selectors);
|
756
850
|
this.stateId$.next(stateId);
|
757
851
|
}));
|
@@ -771,1095 +865,170 @@ class FlowStateService {
|
|
771
865
|
};
|
772
866
|
this.executionInProgress$.next(true);
|
773
867
|
return this.flowStateApiService.execute(this.stateId$.value, request);
|
774
|
-
}), tap
|
775
|
-
this.executionInProgress$.next(false);
|
776
|
-
return throwError(() => e);
|
777
|
-
}));
|
778
|
-
}
|
779
|
-
executeStateful$(request) {
|
780
|
-
return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
|
781
|
-
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
782
|
-
combineLatest([
|
783
|
-
this.statefulExecutionRequest$,
|
784
|
-
of(undefined).pipe(tap$1(() => this.statefulRequestStream$.next(request))),
|
785
|
-
])), map$1(([response]) => response), take$1(1));
|
786
|
-
}
|
787
|
-
initStateless$() {
|
788
|
-
const { headerId } = this.contextService.resolve();
|
789
|
-
return this.quoteDraftService.init(headerId, this.flowInfoService.params ?? {}).pipe(tap$1(() => {
|
790
|
-
const assets = this.quoteDraftService.assetsState;
|
791
|
-
if (assets) {
|
792
|
-
this.flowStore = { ...this.flowStore, assets };
|
793
|
-
}
|
794
|
-
}), switchMap(() => {
|
795
|
-
if (this.flowInfoService.isLegacy) {
|
796
|
-
return of(null);
|
797
|
-
}
|
798
|
-
return this.executeRequest$(this.getDefaultExecutionRequestDTO());
|
799
|
-
}), switchMap(() => this.calculate$()), tap$1(() => this.quoteDraftService.finalizeInit()), map$1(noop));
|
800
|
-
}
|
801
|
-
calculate$() {
|
802
|
-
const flowState = this.quoteDraftService.quoteDraft;
|
803
|
-
if (!flowState) {
|
804
|
-
return of(undefined);
|
805
|
-
}
|
806
|
-
/*
|
807
|
-
Don't execute procedures when:
|
808
|
-
* Initializing a standalone product configuration UI, as procedure is execute in /price call
|
809
|
-
* Initializing an empty account (account with no assets)
|
810
|
-
*/
|
811
|
-
const isEmptyAccountMode = this.contextService.mode === ConfigurationContextMode.ACCOUNT &&
|
812
|
-
!this.quoteDraftService.hasProducts &&
|
813
|
-
!this.quoteDraftService.hasAssets &&
|
814
|
-
!this.quoteDraftService.quoteDraft?.initialState.length;
|
815
|
-
if (this.quoteDraftService.isStandalone || isEmptyAccountMode) {
|
816
|
-
return of(undefined);
|
817
|
-
}
|
818
|
-
return this.flowConfiguration.calculate$(flowState);
|
819
|
-
}
|
820
|
-
executeStateless$(request) {
|
821
|
-
this.executionInProgress$.next(true);
|
822
|
-
return of(undefined).pipe(tap$1(() => this.executeStatelessActions(request)), switchMap(() => {
|
823
|
-
/*
|
824
|
-
Skip price calculation in case
|
825
|
-
1. No actions in the request
|
826
|
-
2. Initialization process execution (state not initialized yet)
|
827
|
-
*/
|
828
|
-
if (!request.actions?.length || !this.isInitialized()) {
|
829
|
-
return of(undefined);
|
830
|
-
}
|
831
|
-
else {
|
832
|
-
return this.calculate$();
|
833
|
-
}
|
834
|
-
}), map$1(() => this.executeStatelessSelectors(request)), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
|
868
|
+
}), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
835
869
|
this.executionInProgress$.next(false);
|
836
870
|
return throwError(() => e);
|
837
871
|
}));
|
838
872
|
}
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
847
|
-
}
|
848
|
-
catch (e) {
|
849
|
-
console.error(e);
|
850
|
-
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
851
|
-
throw e;
|
852
|
-
}
|
853
|
-
});
|
854
|
-
this.quoteDraftService.updateQuoteDraft(flowState);
|
855
|
-
}
|
856
|
-
executeStatelessSelectors(request) {
|
857
|
-
if (!this.quoteDraftService.quoteDraft) {
|
858
|
-
throw 'QuoteDraft is not initialized';
|
859
|
-
}
|
860
|
-
const flowState = this.quoteDraftService.quoteDraft;
|
861
|
-
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
862
|
-
try {
|
863
|
-
result.selectors[key] = {
|
864
|
-
success: true,
|
865
|
-
result: this.executeSelectorScript(flowState, selector),
|
866
|
-
};
|
867
|
-
}
|
868
|
-
catch (e) {
|
869
|
-
console.error(e);
|
870
|
-
result.selectors[key] = {
|
871
|
-
success: false,
|
872
|
-
errorMessage: String(e),
|
873
|
-
};
|
874
|
-
}
|
875
|
-
return result;
|
876
|
-
}, { stateId: '', selectors: {} });
|
877
|
-
}
|
878
|
-
getFlowSafe() {
|
879
|
-
if (!this.flowInfoService.flow) {
|
880
|
-
throw 'Flow is not defined';
|
881
|
-
}
|
882
|
-
return this.flowInfoService.flow;
|
883
|
-
}
|
884
|
-
initProcessors$() {
|
885
|
-
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
886
|
-
const flow = this.getFlowSafe();
|
887
|
-
if (flow.properties.stateful && !hasOverrides) {
|
888
|
-
// Skip initialization as backend will take processors from SF
|
889
|
-
return of(undefined);
|
890
|
-
}
|
891
|
-
const owners$ = Object.values(this.flowInfoService.templates)
|
892
|
-
.map(template => {
|
893
|
-
if (!template) {
|
894
|
-
return;
|
895
|
-
}
|
896
|
-
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
897
|
-
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap$1(processors => {
|
898
|
-
const processorsMap = processors.reduce((acc, p) => {
|
899
|
-
acc[p.apiName] = p;
|
900
|
-
return acc;
|
901
|
-
}, {});
|
902
|
-
this.processors[template.id] = processorsMap;
|
903
|
-
}));
|
904
|
-
})
|
905
|
-
.filter(isDefined);
|
906
|
-
if (!owners$.length) {
|
907
|
-
return of(undefined);
|
908
|
-
}
|
909
|
-
return forkJoin(owners$).pipe(map$1(noop));
|
910
|
-
}
|
911
|
-
executeActionScript(request, executable) {
|
912
|
-
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
913
|
-
if (!configurationProcessor?.script) {
|
914
|
-
const scope = this.getScopeByOwnerId(executable.ownerId);
|
915
|
-
const scopeText = scope ? ` in ${scope}` : '';
|
916
|
-
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
917
|
-
}
|
918
|
-
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
919
|
-
}
|
920
|
-
executeSelectorScript(request, executable) {
|
921
|
-
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
922
|
-
if (!configurationProcessor?.script) {
|
923
|
-
const scope = this.getScopeByOwnerId(executable.ownerId);
|
924
|
-
const scopeText = scope ? ` in ${scope}` : '';
|
925
|
-
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
926
|
-
}
|
927
|
-
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
928
|
-
}
|
929
|
-
executeProcessorScript(request, configurationProcessor, inputData) {
|
930
|
-
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
931
|
-
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
932
|
-
if (!functionToExecute) {
|
933
|
-
const script = `${configurationProcessor.script}\nreturn transform;`;
|
934
|
-
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
935
|
-
functionToExecute = new Function(script + sourceMap)();
|
936
|
-
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
937
|
-
}
|
938
|
-
return functionToExecute({
|
939
|
-
request,
|
940
|
-
inputData,
|
941
|
-
flowStore: this.flowStore,
|
942
|
-
});
|
943
|
-
}
|
944
|
-
generateRequestId(scope, selectorName, inputData) {
|
945
|
-
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
946
|
-
return `${scope}/${selectorName}/${inputDataHash}`;
|
947
|
-
}
|
948
|
-
getDefaultExecutionRequestDTO() {
|
949
|
-
const request = {
|
950
|
-
actions: [],
|
951
|
-
selectors: {},
|
952
|
-
};
|
953
|
-
if (this.getFlowSafe().properties.standalone) {
|
954
|
-
return request;
|
955
|
-
}
|
956
|
-
const flowEngineTemplateId = this.getOwnerIdByScope(UITemplateType.FLOW_ENGINE);
|
957
|
-
request.actions?.push({
|
958
|
-
apiName: 'UPDATE_CONTEXT_PROPERTIES',
|
959
|
-
ownerId: flowEngineTemplateId,
|
960
|
-
inputData: this.contextService.resolve().properties,
|
961
|
-
});
|
962
|
-
return request;
|
963
|
-
}
|
964
|
-
checkStatefulChanges(requestId, selectorResult) {
|
965
|
-
if (this.trackedStatefulChangesMap.has(requestId)) {
|
966
|
-
if (!this.initialStatefulData[requestId]) {
|
967
|
-
this.initialStatefulData[requestId] = selectorResult;
|
968
|
-
}
|
969
|
-
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
970
|
-
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
971
|
-
}
|
972
|
-
}
|
973
|
-
}
|
974
|
-
FlowStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, deps: [{ token: ContextService }, { token: QuoteDraftService }, { token: FlowInfoService }, { token: FlowConfigurationService }, { token: i1.ConfigurationProcessorsApiService }, { token: i1.FlowStateApiService }, { token: i1.QuoteApiService }, { token: i6.ToastService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
975
|
-
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
976
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
977
|
-
type: Injectable
|
978
|
-
}], ctorParameters: function () { return [{ type: ContextService }, { type: QuoteDraftService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.FlowStateApiService }, { type: i1.QuoteApiService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
979
|
-
type: Optional
|
980
|
-
}, {
|
981
|
-
type: Inject,
|
982
|
-
args: [FLOW_CUSTOMIZATION]
|
983
|
-
}] }]; } });
|
984
|
-
|
985
|
-
const findLineItem = (id, lineItems) => {
|
986
|
-
return findLineItemWithComparator(lineItems, (li) => li.id === id);
|
987
|
-
};
|
988
|
-
const findLineItemWithComparator = (lineItems, comparator) => {
|
989
|
-
let currentLevel = lineItems;
|
990
|
-
while (currentLevel.length) {
|
991
|
-
const found = currentLevel.find(comparator);
|
992
|
-
if (found) {
|
993
|
-
return found;
|
994
|
-
}
|
995
|
-
currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
|
996
|
-
}
|
997
|
-
return;
|
998
|
-
};
|
999
|
-
const insertLineItem = (lineItem, parentId, toInsert) => {
|
1000
|
-
const insertData = lineItem.id === parentId ? [toInsert] : [];
|
1001
|
-
return {
|
1002
|
-
...lineItem,
|
1003
|
-
lineItems: [
|
1004
|
-
...insertData,
|
1005
|
-
...lineItem.lineItems.map(li => {
|
1006
|
-
return insertLineItem(li, parentId, toInsert);
|
1007
|
-
}),
|
1008
|
-
],
|
1009
|
-
};
|
1010
|
-
};
|
1011
|
-
const removeLineItem = (lineItem, idToRemove) => {
|
1012
|
-
return {
|
1013
|
-
...lineItem,
|
1014
|
-
lineItems: lineItem.lineItems
|
1015
|
-
.map(li => {
|
1016
|
-
if (li.id === idToRemove) {
|
1017
|
-
return;
|
1018
|
-
}
|
1019
|
-
else if (li.lineItems.length) {
|
1020
|
-
return removeLineItem(li, idToRemove);
|
1021
|
-
}
|
1022
|
-
return li;
|
1023
|
-
})
|
1024
|
-
.filter(r => !!r),
|
1025
|
-
};
|
1026
|
-
};
|
1027
|
-
const replaceLineItem = (lineItem, replaceTo, skipCardinalityCalculation = false) => {
|
1028
|
-
if (lineItem.id === replaceTo.id) {
|
1029
|
-
if (!skipCardinalityCalculation) {
|
1030
|
-
return { ...recalculateCardinalityVariables(lineItem, replaceTo) };
|
1031
|
-
}
|
1032
|
-
else {
|
1033
|
-
return { ...replaceTo };
|
1034
|
-
}
|
1035
|
-
}
|
1036
|
-
return {
|
1037
|
-
...lineItem,
|
1038
|
-
lineItems: lineItem.lineItems.map(li => replaceLineItem(li, replaceTo, skipCardinalityCalculation)),
|
1039
|
-
};
|
1040
|
-
};
|
1041
|
-
const collectCardinalityComputations = (portDomains) => {
|
1042
|
-
const cardinalityComputations = new Map();
|
1043
|
-
entries(portDomains).forEach(([key, portDomain]) => {
|
1044
|
-
cardinalityComputations.set(key, portDomain.properties['cardinalityComputation'] === 'true');
|
1045
|
-
});
|
1046
|
-
return cardinalityComputations;
|
1047
|
-
};
|
1048
|
-
const calculateCardinalityVariables = (lineItems, cardinalityComputations) => {
|
1049
|
-
const cardVars = new Map();
|
1050
|
-
lineItems
|
1051
|
-
.filter(({ port, type }) => !!port && !!type)
|
1052
|
-
.forEach(li => {
|
1053
|
-
if (cardinalityComputations.get(`${li.port}`)) {
|
1054
|
-
const cardinalityVariableName = `#CV-${li.type}@${li.port}`;
|
1055
|
-
cardVars.set(cardinalityVariableName, (cardVars.get(cardinalityVariableName) ?? 0) + li.qty);
|
1056
|
-
}
|
1057
|
-
});
|
1058
|
-
return cardVars;
|
1059
|
-
};
|
1060
|
-
const cardinalityRegexp = new RegExp('#CV-[a-zA-Z0-9_]+@(?<portName>[a-zA-Z0-9_]+)');
|
1061
|
-
const recalculateCardinalityVariables = (original, updated) => {
|
1062
|
-
const cardinalityComputations = collectCardinalityComputations(updated.portDomains ?? original.portDomains ?? {});
|
1063
|
-
const cardinalityVariables = calculateCardinalityVariables(updated.lineItems, cardinalityComputations);
|
1064
|
-
const originalCardinalityVariables = calculateCardinalityVariables(original.lineItems, cardinalityComputations);
|
1065
|
-
originalCardinalityVariables.forEach((value, key) => {
|
1066
|
-
const execArray = cardinalityRegexp.exec(key);
|
1067
|
-
const portName = execArray?.groups?.['portName'];
|
1068
|
-
if (!portName || cardinalityComputations.get(portName)) {
|
1069
|
-
if (cardinalityVariables.get(key) === value) {
|
1070
|
-
// no need to update cardinality if no changes
|
1071
|
-
cardinalityVariables.delete(key);
|
1072
|
-
}
|
1073
|
-
else if (!cardinalityVariables.has(key)) {
|
1074
|
-
// remove last item from port
|
1075
|
-
cardinalityVariables.set(key, 0);
|
1076
|
-
}
|
1077
|
-
}
|
1078
|
-
});
|
1079
|
-
return {
|
1080
|
-
...updated,
|
1081
|
-
attributes: upsertAttributes(updated.attributes, [...cardinalityVariables].map(([name, value]) => ({ name, value, cfgStatus: 'Changed' }))),
|
1082
|
-
};
|
1083
|
-
};
|
1084
|
-
const mapAttributes = (attributes) => {
|
1085
|
-
return attributes.reduce((acc, { name, value }) => ({ ...acc, [name]: value }), {});
|
1086
|
-
};
|
1087
|
-
const getAttributes = (attributes, names = []) => {
|
1088
|
-
const filtered = attributes.filter(({ name }) => names.includes(name));
|
1089
|
-
return sortBy(filtered, [({ name }) => names.indexOf(name)]);
|
1090
|
-
};
|
1091
|
-
const upsertAttributes = (originalAttributes, attributesToUpsert) => {
|
1092
|
-
return attributesToUpsert.reduce((acc, { name, value }) => {
|
1093
|
-
const [origAttr] = getAttributes(acc, [name]);
|
1094
|
-
return [
|
1095
|
-
...acc.filter(attr => attr.name !== name),
|
1096
|
-
{ ...(origAttr ?? { name, type: '' }), cfgStatus: origAttr ? 'Changed' : 'User', value },
|
1097
|
-
];
|
1098
|
-
}, originalAttributes);
|
1099
|
-
};
|
1100
|
-
const patchAttributes = (rootLineItem, id, attrs, skipCardinalityCalculation = false) => {
|
1101
|
-
const lineItem = findLineItem(id, [rootLineItem]);
|
1102
|
-
if (!lineItem) {
|
1103
|
-
return rootLineItem;
|
1104
|
-
}
|
1105
|
-
const attributes = upsertAttributes(lineItem.attributes, attrs);
|
1106
|
-
return replaceLineItem(rootLineItem, { ...lineItem, attributes }, skipCardinalityCalculation);
|
1107
|
-
};
|
1108
|
-
const getAttributeValue = (attributes, name) => attributes.find(attr => attr.name === name)?.value;
|
1109
|
-
const generateLineItem = (port, type, parentId, attributes = [], lineItems = []) => {
|
1110
|
-
return {
|
1111
|
-
id: UUID.UUID(),
|
1112
|
-
port,
|
1113
|
-
type,
|
1114
|
-
actionCode: 'ADD',
|
1115
|
-
cfgStatus: 'New',
|
1116
|
-
attributes: attributes.map(({ name, value }) => ({ cfgStatus: 'User', name, value })),
|
1117
|
-
lineItems,
|
1118
|
-
parentId,
|
1119
|
-
qty: 1,
|
1120
|
-
};
|
1121
|
-
};
|
1122
|
-
const getRecommendedPrices = (portDomain, type) => {
|
1123
|
-
const domainType = portDomain.domainTypes.find(({ name }) => name === type);
|
1124
|
-
const [net, list] = domainType?.recommendedPrices
|
1125
|
-
?.filter(({ chargeMethod }) => chargeMethod === 'ONE_TIME')
|
1126
|
-
.reduce((acc, rp) => {
|
1127
|
-
const [netPrice, listPrice] = acc;
|
1128
|
-
return [netPrice + rp.netPrice, listPrice + rp.listPrice];
|
1129
|
-
}, [0, 0]) ?? [0, 0];
|
1130
|
-
return { net, list };
|
1131
|
-
};
|
1132
|
-
const getOriginParent = (lineItems, currentLineItem) => {
|
1133
|
-
let target = currentLineItem;
|
1134
|
-
while (target && target.rampInstanceId) {
|
1135
|
-
target = lineItems.find(sub => sub.id === currentLineItem.rampInstanceId);
|
1136
|
-
}
|
1137
|
-
return target;
|
1138
|
-
};
|
1139
|
-
const assetPredicateFn = (lineItem, assetId) => {
|
1140
|
-
if (!assetId) {
|
1141
|
-
return false;
|
1142
|
-
}
|
1143
|
-
return lineItem.assetId === assetId || lineItem.openOrderLineItemId === assetId;
|
1144
|
-
};
|
1145
|
-
const multiplyLineItems = (lineItem, qty, split) => {
|
1146
|
-
if (split) {
|
1147
|
-
const unifyIds = (lineItem) => ({
|
1148
|
-
...lineItem,
|
1149
|
-
id: UUID.UUID(),
|
1150
|
-
lineItems: lineItem.lineItems.map(unifyIds),
|
1151
|
-
});
|
1152
|
-
return map$2(new Array(qty), () => unifyIds(lineItem));
|
1153
|
-
}
|
1154
|
-
else {
|
1155
|
-
return [
|
1156
|
-
{
|
1157
|
-
...lineItem,
|
1158
|
-
qty: qty,
|
1159
|
-
},
|
1160
|
-
];
|
1161
|
-
}
|
1162
|
-
};
|
1163
|
-
const isTechnicalAttribute = (name) => {
|
1164
|
-
return name.startsWith('#') || name.startsWith('$');
|
1165
|
-
};
|
1166
|
-
const filterOutTechnicalAttributes = (attributes) => {
|
1167
|
-
return attributes.filter(({ name }) => !isTechnicalAttribute(name));
|
1168
|
-
};
|
1169
|
-
|
1170
|
-
var lineItem_utils = /*#__PURE__*/Object.freeze({
|
1171
|
-
__proto__: null,
|
1172
|
-
assetPredicateFn: assetPredicateFn,
|
1173
|
-
filterOutTechnicalAttributes: filterOutTechnicalAttributes,
|
1174
|
-
findLineItem: findLineItem,
|
1175
|
-
findLineItemWithComparator: findLineItemWithComparator,
|
1176
|
-
generateLineItem: generateLineItem,
|
1177
|
-
getAttributeValue: getAttributeValue,
|
1178
|
-
getAttributes: getAttributes,
|
1179
|
-
getOriginParent: getOriginParent,
|
1180
|
-
getRecommendedPrices: getRecommendedPrices,
|
1181
|
-
insertLineItem: insertLineItem,
|
1182
|
-
isTechnicalAttribute: isTechnicalAttribute,
|
1183
|
-
mapAttributes: mapAttributes,
|
1184
|
-
multiplyLineItems: multiplyLineItems,
|
1185
|
-
patchAttributes: patchAttributes,
|
1186
|
-
recalculateCardinalityVariables: recalculateCardinalityVariables,
|
1187
|
-
removeLineItem: removeLineItem,
|
1188
|
-
replaceLineItem: replaceLineItem,
|
1189
|
-
upsertAttributes: upsertAttributes
|
1190
|
-
});
|
1191
|
-
|
1192
|
-
class RuntimeSettingsService {
|
1193
|
-
constructor(configurationSettingsApiService) {
|
1194
|
-
this.configurationSettingsApiService = configurationSettingsApiService;
|
1195
|
-
this.configurationSettings$ = new BehaviorSubject({});
|
1196
|
-
this.currencySettings$ = new BehaviorSubject({
|
1197
|
-
iso: DEFAULT_CURRENCY_ISO_CODE,
|
1198
|
-
symbol: DEFAULT_CURRENCY_SYMBOL,
|
1199
|
-
});
|
1200
|
-
this.shoppingCartSettings$ = new BehaviorSubject([]);
|
1201
|
-
this.getCurrencySymbol = (locale, currency) => {
|
1202
|
-
return (0)
|
1203
|
-
.toLocaleString(locale, { style: 'currency', currency, minimumFractionDigits: 0, maximumFractionDigits: 0 })
|
1204
|
-
.replace(/\d/g, '')
|
1205
|
-
.trim();
|
1206
|
-
};
|
1207
|
-
}
|
1208
|
-
create() {
|
1209
|
-
return this.configurationSettingsApiService.fetchSettings().pipe(map$1(settings => this.parseConfigurationSettings(settings)), tap$1(configurationSettings => {
|
1210
|
-
this.configurationSettings$.next(configurationSettings);
|
1211
|
-
this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
|
1212
|
-
this.formattingSettings = this.getFormattingSettings();
|
1213
|
-
}), map$1(() => undefined));
|
1214
|
-
}
|
1215
|
-
initCurrency(iso) {
|
1216
|
-
if (iso) {
|
1217
|
-
const symbol = this.getCurrencySymbol('en-US', iso);
|
1218
|
-
this.currencySettings$.next({ iso, symbol });
|
1219
|
-
if (this.formattingSettings) {
|
1220
|
-
this.formattingSettings.currencySymbol = symbol;
|
1221
|
-
}
|
1222
|
-
}
|
1223
|
-
}
|
1224
|
-
getFormattingSettings() {
|
1225
|
-
if (this.formattingSettings) {
|
1226
|
-
return this.formattingSettings;
|
1227
|
-
}
|
1228
|
-
const shoppingCartSettings = this.getConfigurationSettings()['shopping-cart']?.reduce((acc, setting) => {
|
1229
|
-
return { ...acc, [setting.id]: setting.properties };
|
1230
|
-
}, {});
|
1231
|
-
const currencySettings = this.getCurrencySettings();
|
1232
|
-
const dateFormat = (validateDateFormat(shoppingCartSettings?.DATE_FORMAT ?? '') && shoppingCartSettings?.DATE_FORMAT) ||
|
1233
|
-
DEFAULT_DATE_FORMAT;
|
1234
|
-
const decimalSeparator = shoppingCartSettings?.DECIMAL_SEPARATOR;
|
1235
|
-
const thousandsSeparator = shoppingCartSettings?.THOUSANDS_SEPARATOR;
|
1236
|
-
// the number of decimal places can be 0
|
1237
|
-
const priceScale = shoppingCartSettings?.PRICE_SCALE;
|
1238
|
-
const decimalsCount = priceScale !== null && priceScale !== '' && !isNaN(Number(priceScale)) && Number(priceScale) >= 0
|
1239
|
-
? Number(priceScale)
|
1240
|
-
: DEFAULT_DECIMALS_COUNT;
|
1241
|
-
const actionCodeSettings = shoppingCartSettings?.STATUS_LABEL;
|
1242
|
-
return {
|
1243
|
-
currencySymbol: currencySettings.symbol,
|
1244
|
-
dateFormats: getSupportedDateFormats(dateFormat),
|
1245
|
-
decimalsCount,
|
1246
|
-
decimalSeparator: decimalSeparator !== undefined && ['.', ','].includes(decimalSeparator)
|
1247
|
-
? decimalSeparator
|
1248
|
-
: DEFAULT_DECIMAL_SEPARATOR,
|
1249
|
-
// thousands separator can be a blank value, so it can also be null
|
1250
|
-
thousandsSeparator: thousandsSeparator !== undefined && ['.', ',', '', null].includes(thousandsSeparator)
|
1251
|
-
? thousandsSeparator || ''
|
1252
|
-
: DEFAULT_THOUSANDS_SEPARATOR,
|
1253
|
-
actionCodeLabels: actionCodeSettings?.length
|
1254
|
-
? actionCodeSettings.reduce((result, setting) => ({ ...result, [setting.status_label]: setting.custom_label }), {})
|
1255
|
-
: DEFAULT_ACTION_CODE_LABELS,
|
1256
|
-
};
|
1257
|
-
}
|
1258
|
-
getConfigurationSettings() {
|
1259
|
-
return this.configurationSettings$.value;
|
1260
|
-
}
|
1261
|
-
getShoppingCartSettings() {
|
1262
|
-
return this.shoppingCartSettings$.value;
|
1263
|
-
}
|
1264
|
-
getCurrencySettings() {
|
1265
|
-
return this.currencySettings$.value;
|
1266
|
-
}
|
1267
|
-
parseConfigurationSettings(settings) {
|
1268
|
-
return settings.reduce((acc, setting) => {
|
1269
|
-
switch (setting.key) {
|
1270
|
-
case 'shopping-cart':
|
1271
|
-
acc['shopping-cart'] = parseJsonSafely(setting.value, []);
|
1272
|
-
break;
|
1273
|
-
case 'navigation':
|
1274
|
-
acc.navigation = parseJsonSafely(setting.value, {});
|
1275
|
-
break;
|
1276
|
-
case 'flows':
|
1277
|
-
acc.flows = parseJsonSafely(setting.value, []);
|
1278
|
-
break;
|
1279
|
-
default:
|
1280
|
-
acc[setting.key] = setting.value;
|
1281
|
-
}
|
1282
|
-
return acc;
|
1283
|
-
}, {});
|
1284
|
-
}
|
1285
|
-
addShoppingCartSettings(settings) {
|
1286
|
-
// uniqBy removes items with the biggest index
|
1287
|
-
const newSettings = uniqBy([...settings, ...this.shoppingCartSettings$.value], 'id');
|
1288
|
-
this.shoppingCartSettings$.next(newSettings);
|
1289
|
-
}
|
1290
|
-
}
|
1291
|
-
RuntimeSettingsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, deps: [{ token: i1.ConfigurationSettingsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1292
|
-
RuntimeSettingsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService });
|
1293
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeSettingsService, decorators: [{
|
1294
|
-
type: Injectable
|
1295
|
-
}], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
|
1296
|
-
|
1297
|
-
class LineItemWorker {
|
1298
|
-
constructor(src) {
|
1299
|
-
this.li = { ...src };
|
1300
|
-
}
|
1301
|
-
insert(parentId, toInsert) {
|
1302
|
-
return new LineItemWorker(insertLineItem(this.li, parentId, toInsert));
|
1303
|
-
}
|
1304
|
-
remove(id) {
|
1305
|
-
return new LineItemWorker(removeLineItem(this.li, id));
|
1306
|
-
}
|
1307
|
-
replace(toReplace, skipCardinalityCalculation = false) {
|
1308
|
-
return new LineItemWorker(replaceLineItem(this.li, toReplace, skipCardinalityCalculation));
|
1309
|
-
}
|
1310
|
-
patchAttribute(attrs, id, skipCardinalityCalculation = false) {
|
1311
|
-
return new LineItemWorker(patchAttributes(this.li, id ?? this.li.id, attrs, skipCardinalityCalculation));
|
1312
|
-
}
|
1313
|
-
}
|
1314
|
-
|
1315
|
-
function extractMetadata(uiDefinition) {
|
1316
|
-
return omit(uiDefinition, [
|
1317
|
-
'children',
|
1318
|
-
'pages',
|
1319
|
-
'components',
|
1320
|
-
]);
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
class ConfigurationService {
|
1324
|
-
constructor(quoteDraftService, runtimeService, contextService, configurationApiService, messageService, dialogService, runtimeSettings) {
|
1325
|
-
this.quoteDraftService = quoteDraftService;
|
1326
|
-
this.runtimeService = runtimeService;
|
1327
|
-
this.contextService = contextService;
|
1328
|
-
this.configurationApiService = configurationApiService;
|
1329
|
-
this.messageService = messageService;
|
1330
|
-
this.dialogService = dialogService;
|
1331
|
-
this.runtimeSettings = runtimeSettings;
|
1332
|
-
this.mode = ConfigurationMode.SEARCH;
|
1333
|
-
this.configurationState = new BehaviorSubject(null);
|
1334
|
-
this.previousConfigurationState = new BehaviorSubject(null);
|
1335
|
-
this.isLoadingSubj$ = new BehaviorSubject(false);
|
1336
|
-
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
1337
|
-
this.hasUnsavedChanges = false;
|
1338
|
-
}
|
1339
|
-
reset() {
|
1340
|
-
this.hasUnsavedChanges = false;
|
1341
|
-
this.runtimeService.reset();
|
1342
|
-
this.configurableRamp = undefined;
|
1343
|
-
this.configurationState.next(null);
|
1344
|
-
this.previousConfigurationState.next(null);
|
1345
|
-
}
|
1346
|
-
patch$(lineItem, options) {
|
1347
|
-
const source = this.getSnapshot();
|
1348
|
-
if (!source) {
|
1349
|
-
return throwError(() => new Error(`Source LineItem not found`));
|
1350
|
-
}
|
1351
|
-
const skipCardinalityCalculation = options?.skipCardinalityCalculation || this.contextSnapshot.properties['#skipCardinalityCalculation'] === 'true';
|
1352
|
-
this.configurableRamp = new LineItemWorker(source).replace(lineItem, skipCardinalityCalculation).li;
|
1353
|
-
return this.configure().pipe(catchError$1(error => {
|
1354
|
-
console.error(error);
|
1355
|
-
if (!this.runtimeService.uiDefinitionProperties.suppressToastMessages) {
|
1356
|
-
this.messageService.add({ severity: 'error', summary: error });
|
1357
|
-
}
|
1358
|
-
// bounce back if configuration call has failed
|
1359
|
-
const prevState = this.configurationState.value;
|
1360
|
-
this.configurationState.next(prevState ? { ...prevState } : null);
|
1361
|
-
return throwError(() => error);
|
1362
|
-
}), tap(() => {
|
1363
|
-
if (!this.hasUnsavedChanges) {
|
1364
|
-
this.hasUnsavedChanges = true;
|
1365
|
-
}
|
1366
|
-
}));
|
1367
|
-
}
|
1368
|
-
patch(lineItem, options) {
|
1369
|
-
this.patch$(lineItem, options).subscribe();
|
1370
|
-
}
|
1371
|
-
setConfigurableRamp(lineItem) {
|
1372
|
-
this.configurableRamp = lineItem;
|
1373
|
-
}
|
1374
|
-
get() {
|
1375
|
-
return this.configurationState.pipe(map(state => state?.lineItem), shareReplay$1());
|
1376
|
-
}
|
1377
|
-
getSnapshot() {
|
1378
|
-
return this.configurationState.value?.lineItem ? { ...this.configurationState.value?.lineItem } : undefined;
|
1379
|
-
}
|
1380
|
-
getRuntimeModel() {
|
1381
|
-
const runtimeModel = this.runtimeService.runtimeModel;
|
1382
|
-
if (!runtimeModel) {
|
1383
|
-
throw new Error('Runtime model not initialized');
|
1384
|
-
}
|
1385
|
-
return runtimeModel;
|
1386
|
-
}
|
1387
|
-
getRuntimeContext() {
|
1388
|
-
const runtimeContext = this.runtimeService.runtimeContext;
|
1389
|
-
if (!runtimeContext) {
|
1390
|
-
throw new Error('Runtime context not initialized');
|
1391
|
-
}
|
1392
|
-
return runtimeContext;
|
1393
|
-
}
|
1394
|
-
get state$() {
|
1395
|
-
return this.configurationState.asObservable();
|
1396
|
-
}
|
1397
|
-
get stateSnapshot() {
|
1398
|
-
return this.configurationState.value;
|
1399
|
-
}
|
1400
|
-
get previousStateSnapshot() {
|
1401
|
-
return this.previousConfigurationState.value;
|
1402
|
-
}
|
1403
|
-
get contextSnapshot() {
|
1404
|
-
return this.contextService.resolve();
|
1405
|
-
}
|
1406
|
-
get context$() {
|
1407
|
-
return this.contextService.resolve$();
|
1408
|
-
}
|
1409
|
-
get charges$() {
|
1410
|
-
return this.configurationState.pipe(map(state => state?.charges ?? {}));
|
1411
|
-
}
|
1412
|
-
get chargesSnapshot() {
|
1413
|
-
return this.configurationState.value?.charges ?? {};
|
1414
|
-
}
|
1415
|
-
get pricePlans$() {
|
1416
|
-
return this.configurationState.pipe(map(state => state?.pricePlans ?? {}));
|
1417
|
-
}
|
1418
|
-
get pricePlansSnapshot() {
|
1419
|
-
return this.configurationState.value?.pricePlans ?? {};
|
1420
|
-
}
|
1421
|
-
get procedureContext$() {
|
1422
|
-
return this.configurationState.pipe(map(state => state?.procedureContext ?? {}));
|
1423
|
-
}
|
1424
|
-
get procedureContextSnapshot() {
|
1425
|
-
return this.configurationState.value?.procedureContext ?? {};
|
1426
|
-
}
|
1427
|
-
configure() {
|
1428
|
-
return this.configureRequest$(this.generateRequest());
|
1429
|
-
}
|
1430
|
-
configureRequest$(configurationRequest) {
|
1431
|
-
const runtimeContext = this.getRuntimeContext();
|
1432
|
-
const runtimeModel = this.getRuntimeModel();
|
1433
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1434
|
-
const mainPricingEnabled = runtimeContext.properties?.PricingEnabled;
|
1435
|
-
const pricingEnabled = mainPricingEnabled ? mainPricingEnabled === 'true' : uiDefinitionProperties.pricingEnabled;
|
1436
|
-
const customPriceApi = this.runtimeSettings.getConfigurationSettings()['CUSTOM_PRICE_API'];
|
1437
|
-
this.isLoadingSubj$.next(true);
|
1438
|
-
const configure$ = pricingEnabled && customPriceApi
|
1439
|
-
? this.configurationApiService.customConfigurePrice({ url: customPriceApi, configurationRequest, runtimeModel })
|
1440
|
-
: this.configurationApiService.configureLineItem({
|
1441
|
-
configurationRequest,
|
1442
|
-
runtimeModel,
|
1443
|
-
pricingEnabled,
|
1444
|
-
});
|
1445
|
-
return configure$.pipe(tap(result => {
|
1446
|
-
this.contextService.update(result.context);
|
1447
|
-
this.configurationState.next(result);
|
1448
|
-
this.previousConfigurationState.next(cloneDeep(result));
|
1449
|
-
if (result.deletedLineItems?.length) {
|
1450
|
-
this.showInactiveProductsConfirmation();
|
1451
|
-
}
|
1452
|
-
this.configurableRamp = result.lineItem;
|
1453
|
-
}), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => {
|
1454
|
-
const resetState = this.previousConfigurationState.value;
|
1455
|
-
if (resetState) {
|
1456
|
-
this.previousConfigurationState.next(cloneDeep(resetState));
|
1457
|
-
this.configurationState.next(resetState);
|
1458
|
-
}
|
1459
|
-
if (error.error) {
|
1460
|
-
return extractErrorDetails(error.error).join('. ');
|
1461
|
-
}
|
1462
|
-
return error.message || JSON.stringify(error);
|
1463
|
-
})), finalize$1(() => this.isLoadingSubj$.next(false)));
|
1464
|
-
}
|
1465
|
-
configureExternal$(props) {
|
1466
|
-
return this.runtimeService
|
1467
|
-
.init({ productId: props.productId, defaultQty: props.qty, attributesMap: props.attributesMap })
|
1468
|
-
.pipe(switchMap$1(() => this.configure()), first(), catchError$1(error => {
|
1469
|
-
this.messageService.add({ severity: ToastType.error, summary: error });
|
1470
|
-
throw error;
|
1471
|
-
}), finalize$1(() => this.reset()));
|
1472
|
-
}
|
1473
|
-
configureGuidedSelling$(data) {
|
1474
|
-
return this.configurationApiService
|
1475
|
-
.configureLineItem({
|
1476
|
-
configurationRequest: getGuidedSellingConfigurationRequest(data, this.contextService.resolve()),
|
1477
|
-
})
|
1478
|
-
.pipe(catchError$1(error => {
|
1479
|
-
if (error instanceof HttpErrorResponse) {
|
1480
|
-
this.messageService.add({ severity: ToastType.error, summary: error.error.message || error.error });
|
1481
|
-
}
|
1482
|
-
throw error;
|
1483
|
-
}));
|
1484
|
-
}
|
1485
|
-
generateRequest(lightMode = true) {
|
1486
|
-
const lineItem = this.generateLineItem();
|
1487
|
-
let request = {
|
1488
|
-
lineItem,
|
1489
|
-
mode: this.mode,
|
1490
|
-
step: !this.configurationState.value?.lineItem ? RuntimeStep.START : RuntimeStep.UPDATE,
|
1491
|
-
attributeDomainMode: 'ALL',
|
1492
|
-
context: this.contextService.resolve(),
|
1493
|
-
lineItems: this.quoteDraftService.quoteDraft?.currentState || [],
|
1494
|
-
asset: this.getAsset(),
|
1495
|
-
};
|
1496
|
-
if (lightMode) {
|
1497
|
-
request = ConfigurationTranslatorUtils.lightenConfigurationRequest(request);
|
1498
|
-
}
|
1499
|
-
return request;
|
1500
|
-
}
|
1501
|
-
generateLineItem() {
|
1502
|
-
const runtimeContext = this.getRuntimeContext();
|
1503
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1504
|
-
let lineItem = this.configurableRamp;
|
1505
|
-
if (!lineItem) {
|
1506
|
-
const { initializationProps } = this.runtimeService ?? {};
|
1507
|
-
lineItem = getDefaultLineItem(runtimeContext, uiDefinitionProperties, initializationProps?.defaultQty);
|
1508
|
-
// Set default attributes
|
1509
|
-
if (initializationProps?.attributesMap) {
|
1510
|
-
const attributes = transform(initializationProps?.attributesMap, (acc, value, name) => acc.push({ name, value }), []);
|
1511
|
-
lineItem = new LineItemWorker(lineItem).patchAttribute(attributes).li;
|
1512
|
-
}
|
1513
|
-
}
|
1514
|
-
return lineItem;
|
1515
|
-
}
|
1516
|
-
getAsset() {
|
1517
|
-
const lineItem = this.configurableRamp;
|
1518
|
-
if (!lineItem) {
|
1519
|
-
return;
|
1520
|
-
}
|
1521
|
-
const assetId = lineItem.assetId ?? lineItem.openOrderLineItemId;
|
1522
|
-
return this.quoteDraftService.assetsState?.initialState.find(li => assetPredicateFn(li, assetId));
|
1523
|
-
}
|
1524
|
-
getUIDefinitionProperties() {
|
1525
|
-
return {
|
1526
|
-
...(this.getRuntimeContext().uiDefinitionContainer?.source.properties ?? {}),
|
1527
|
-
...(this.runtimeService.uiDefinitionProperties ?? {}),
|
1528
|
-
};
|
1529
|
-
}
|
1530
|
-
showInactiveProductsConfirmation() {
|
1531
|
-
const confirmationConfig = {
|
1532
|
-
title: ' ',
|
1533
|
-
description: 'This quote contains inactive products. Do you want to remove them?',
|
1534
|
-
primaryButtonLabel: 'Remove products',
|
1535
|
-
secondaryButtonLabel: 'Back to Quote',
|
1536
|
-
};
|
1537
|
-
this.dialogService
|
1538
|
-
.open(ConfirmationComponent, {
|
1539
|
-
dismissableMask: false,
|
1540
|
-
closeOnEscape: false,
|
1541
|
-
closable: false,
|
1542
|
-
showHeader: true,
|
1543
|
-
header: `Inactive Products in Quote`,
|
1544
|
-
width: '440px',
|
1545
|
-
data: { confirmationConfig },
|
1546
|
-
})
|
1547
|
-
.onClose.subscribe(result => {
|
1548
|
-
if (!result) {
|
1549
|
-
const context = this.contextService.resolve();
|
1550
|
-
window['VELO_BACK_FN'].apply(null, [context.headerId]);
|
1551
|
-
}
|
1552
|
-
});
|
1553
|
-
}
|
1554
|
-
}
|
1555
|
-
ConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, deps: [{ token: QuoteDraftService }, { token: ConfigurationRuntimeService }, { token: ContextService }, { token: i1.ConfigurationApiService }, { token: i5.MessageService }, { token: i6$1.DialogService }, { token: RuntimeSettingsService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1556
|
-
ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
|
1557
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
|
1558
|
-
type: Injectable
|
1559
|
-
}], ctorParameters: function () { return [{ type: QuoteDraftService }, { type: ConfigurationRuntimeService }, { type: ContextService }, { type: i1.ConfigurationApiService }, { type: i5.MessageService }, { type: i6$1.DialogService }, { type: RuntimeSettingsService }]; } });
|
1560
|
-
|
1561
|
-
class FlowUpdateService {
|
1562
|
-
update(rootLineItems, updates, charges) {
|
1563
|
-
let remainingUpdates = [...updates];
|
1564
|
-
let currentLevel = rootLineItems;
|
1565
|
-
while (currentLevel.length && remainingUpdates.length) {
|
1566
|
-
currentLevel.forEach(li => {
|
1567
|
-
const unhandledUpdates = [];
|
1568
|
-
remainingUpdates.forEach(update => {
|
1569
|
-
let updated = false;
|
1570
|
-
switch (update.dataType) {
|
1571
|
-
case 'LINEITEM':
|
1572
|
-
updated = this.applyLineItemUpdate(li, update, charges);
|
1573
|
-
break;
|
1574
|
-
case 'CHARGE':
|
1575
|
-
updated = this.applyChargeUpdate(li, update);
|
1576
|
-
break;
|
1577
|
-
case 'GROUP_CHARGE':
|
1578
|
-
updated = this.applyChargeGroupUpdate(li, update);
|
1579
|
-
break;
|
1580
|
-
default:
|
1581
|
-
// Unknown dataType. Do not try to handle it anymore
|
1582
|
-
updated = true;
|
1583
|
-
}
|
1584
|
-
if (!updated) {
|
1585
|
-
unhandledUpdates.push(update);
|
1586
|
-
}
|
1587
|
-
});
|
1588
|
-
remainingUpdates = unhandledUpdates;
|
1589
|
-
});
|
1590
|
-
currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
|
1591
|
-
}
|
1592
|
-
}
|
1593
|
-
delete(lineItems, id) {
|
1594
|
-
const idsToRemove = [id];
|
1595
|
-
const topLevelLineItem = lineItems.find(li => li.id === id);
|
1596
|
-
if (topLevelLineItem) {
|
1597
|
-
// find term-related line items (which are only top level)
|
1598
|
-
// expired term line items won't be deleted
|
1599
|
-
let foundTermLineItem = topLevelLineItem;
|
1600
|
-
while (foundTermLineItem) {
|
1601
|
-
foundTermLineItem = lineItems.find(li => foundTermLineItem && li.rampInstanceId === foundTermLineItem.id);
|
1602
|
-
if (foundTermLineItem) {
|
1603
|
-
idsToRemove.push(foundTermLineItem.id);
|
1604
|
-
}
|
1605
|
-
}
|
1606
|
-
}
|
1607
|
-
const filtered = lineItems.filter(lineItem => !idsToRemove.includes(lineItem.id));
|
1608
|
-
return filtered.map(lineItem => new LineItemWorker(lineItem).remove(id).li);
|
1609
|
-
}
|
1610
|
-
applyLineItemUpdate(lineItem, update, charges) {
|
1611
|
-
if (lineItem.id !== update.id) {
|
1612
|
-
return false;
|
1613
|
-
}
|
1614
|
-
switch (update.attributeType) {
|
1615
|
-
case 'QTY':
|
1616
|
-
lineItem.qty = update.newValue;
|
1617
|
-
break;
|
1618
|
-
case 'EFFECTIVE_START_DATE':
|
1619
|
-
lineItem.properties['StartDate'] = moment(update.newValue).format('YYYY-MM-DD');
|
1620
|
-
break;
|
1621
|
-
case 'END_DATE':
|
1622
|
-
lineItem.properties['EndDate'] = moment(update.newValue).format('YYYY-MM-DD');
|
1623
|
-
break;
|
1624
|
-
case 'PRICE_ADJUSTMENT':
|
1625
|
-
{
|
1626
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
1627
|
-
if (charge) {
|
1628
|
-
charge.priceAdjustment = update.newValue;
|
1629
|
-
}
|
1630
|
-
}
|
1631
|
-
break;
|
1632
|
-
case 'LIST_PRICE_ADJUSTMENT':
|
1633
|
-
case 'MARGIN_ADJUSTMENT':
|
1634
|
-
{
|
1635
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
1636
|
-
if (charge) {
|
1637
|
-
charge.listPriceAdjustment = update.newValue;
|
1638
|
-
}
|
1639
|
-
}
|
1640
|
-
break;
|
1641
|
-
case 'COST_ADJUSTMENT':
|
1642
|
-
{
|
1643
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
1644
|
-
if (charge) {
|
1645
|
-
charge.costAdjustment = update.newValue;
|
1646
|
-
}
|
1647
|
-
}
|
1648
|
-
break;
|
1649
|
-
default:
|
1650
|
-
throw new Error(`Not suppored AttributeType for LineItem update: ${update.attributeType}`);
|
1651
|
-
}
|
1652
|
-
return true;
|
1653
|
-
}
|
1654
|
-
applyChargeUpdate(lineItem, update) {
|
1655
|
-
const foundCharge = lineItem.chargeItems.find(({ id }) => id === update.id);
|
1656
|
-
if (!foundCharge) {
|
1657
|
-
return false;
|
1658
|
-
}
|
1659
|
-
if (update.attributeType === 'PRICE_ADJUSTMENT') {
|
1660
|
-
foundCharge.priceAdjustment = update.newValue;
|
1661
|
-
}
|
1662
|
-
else if (update.attributeType === 'LIST_PRICE_ADJUSTMENT') {
|
1663
|
-
foundCharge.listPriceAdjustment = update.newValue;
|
1664
|
-
}
|
1665
|
-
else {
|
1666
|
-
throw new Error(`Not suppored AttributeType for Charge Item update: ${update.attributeType}`);
|
1667
|
-
}
|
1668
|
-
return true;
|
1669
|
-
}
|
1670
|
-
applyChargeGroupUpdate(lineItem, update) {
|
1671
|
-
const foundChargeGroup = ChargeGroupUtils.findChargeGroupById(update.id, lineItem);
|
1672
|
-
if (!foundChargeGroup) {
|
1673
|
-
return false;
|
1674
|
-
}
|
1675
|
-
if (update.attributeType === 'PRICE_ADJUSTMENT') {
|
1676
|
-
foundChargeGroup.priceAdjustment = update.newValue;
|
1677
|
-
}
|
1678
|
-
else if (update.attributeType === 'LIST_PRICE_ADJUSTMENT') {
|
1679
|
-
foundChargeGroup.listPriceAdjustment = update.newValue;
|
1680
|
-
}
|
1681
|
-
else {
|
1682
|
-
throw new Error(`Not suppored AttributeType for Charge Group Item update: ${update.attributeType}`);
|
1683
|
-
}
|
1684
|
-
return true;
|
1685
|
-
}
|
1686
|
-
}
|
1687
|
-
FlowUpdateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1688
|
-
FlowUpdateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService });
|
1689
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowUpdateService, decorators: [{
|
1690
|
-
type: Injectable
|
1691
|
-
}] });
|
1692
|
-
|
1693
|
-
class FlowConfigurationService {
|
1694
|
-
constructor(proceduresApiService, contextService, quoteDraftService, updateService, configurationService, flowInfoService) {
|
1695
|
-
this.proceduresApiService = proceduresApiService;
|
1696
|
-
this.contextService = contextService;
|
1697
|
-
this.quoteDraftService = quoteDraftService;
|
1698
|
-
this.updateService = updateService;
|
1699
|
-
this.configurationService = configurationService;
|
1700
|
-
this.flowInfoService = flowInfoService;
|
1701
|
-
this.updatedSubj$ = new Subject();
|
1702
|
-
this.updated$ = this.updatedSubj$.asObservable();
|
873
|
+
executeStateful$(request) {
|
874
|
+
return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take(1), switchMap(() =>
|
875
|
+
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
876
|
+
combineLatest([
|
877
|
+
this.statefulExecutionRequest$,
|
878
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
879
|
+
])), map(([response]) => response), take(1));
|
1703
880
|
}
|
1704
|
-
|
1705
|
-
return this.
|
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));
|
881
|
+
initStateless$() {
|
882
|
+
return this.salesTransactionService.init(this.flowInfoService.context.headerId, this.flowInfoService.context).pipe(switchMap(state => this.flowConfiguration.calculate$(state)), tap(() => this.salesTransactionService.finalizeInit()), map(noop));
|
1713
883
|
}
|
1714
|
-
|
1715
|
-
this.
|
884
|
+
executeStateless$(request) {
|
885
|
+
this.executionInProgress$.next(true);
|
886
|
+
return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
|
887
|
+
/*
|
888
|
+
Skip price calculation in case
|
889
|
+
1. No actions in the request
|
890
|
+
2. Initialization process execution (state not initialized yet)
|
891
|
+
*/
|
892
|
+
const { state } = this.salesTransactionService;
|
893
|
+
if (!state || !request.actions?.length || !this.isInitialized()) {
|
894
|
+
return of(undefined);
|
895
|
+
}
|
896
|
+
else {
|
897
|
+
return this.flowConfiguration.calculate$(state);
|
898
|
+
}
|
899
|
+
}), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
900
|
+
this.executionInProgress$.next(false);
|
901
|
+
return throwError(() => e);
|
902
|
+
}));
|
1716
903
|
}
|
1717
|
-
|
1718
|
-
const
|
1719
|
-
if (!
|
1720
|
-
return
|
1721
|
-
}
|
1722
|
-
return of([]).pipe(map$1(() => {
|
1723
|
-
const updatedState = cloneDeep(quoteDraft.currentState);
|
1724
|
-
this.updateService.update(updatedState, updates, quoteDraft.charges);
|
1725
|
-
return updatedState;
|
1726
|
-
}), switchMap(updatedState => this.calculate$({ ...quoteDraft, currentState: updatedState })), map$1(() => this.quoteDraftService.quoteDraft), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
1727
|
-
}
|
1728
|
-
update(updates) {
|
1729
|
-
this.update$(updates).subscribe();
|
1730
|
-
}
|
1731
|
-
revert$(lineItemId) {
|
1732
|
-
const quoteDraft = this.quoteDraftService.quoteDraft;
|
1733
|
-
const initialCurrentState = this.quoteDraftService.getInitialCurrentState();
|
1734
|
-
const currentState = this.quoteDraftService.currentState;
|
1735
|
-
const currentLineItemIndex = currentState.findIndex(({ id }) => id === lineItemId);
|
1736
|
-
const currentLineItem = currentState[currentLineItemIndex];
|
1737
|
-
const initialLineItem = initialCurrentState.find(({ integrationId }) => integrationId === currentLineItem?.integrationId);
|
1738
|
-
if (!quoteDraft || !currentLineItem || !initialLineItem) {
|
1739
|
-
return of(null);
|
904
|
+
executeStatelessActions(request) {
|
905
|
+
const state = this.salesTransactionService.state;
|
906
|
+
if (!state || !request.actions?.length) {
|
907
|
+
return;
|
1740
908
|
}
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
909
|
+
let flowState = state;
|
910
|
+
request.actions.forEach(action => {
|
911
|
+
try {
|
912
|
+
flowState = this.executeActionScript(flowState, action) ?? flowState;
|
913
|
+
}
|
914
|
+
catch (e) {
|
915
|
+
console.error(e);
|
916
|
+
this.toastService.add({ severity: ToastType.error, summary: String(e) });
|
917
|
+
throw e;
|
918
|
+
}
|
919
|
+
});
|
920
|
+
this.salesTransactionService.setState(flowState);
|
1749
921
|
}
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
if (!quoteDraft) {
|
1754
|
-
return of(null);
|
922
|
+
executeStatelessSelectors(request) {
|
923
|
+
if (!this.salesTransactionService.state) {
|
924
|
+
throw 'State is not initialized';
|
1755
925
|
}
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
926
|
+
const flowState = this.salesTransactionService.state;
|
927
|
+
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
928
|
+
try {
|
929
|
+
result.selectors[key] = {
|
930
|
+
success: true,
|
931
|
+
result: this.executeSelectorScript(flowState, selector),
|
932
|
+
};
|
933
|
+
}
|
934
|
+
catch (e) {
|
935
|
+
console.error(e);
|
936
|
+
result.selectors[key] = {
|
937
|
+
success: false,
|
938
|
+
errorMessage: String(e),
|
939
|
+
};
|
940
|
+
}
|
941
|
+
return result;
|
942
|
+
}, { stateId: '', selectors: {} });
|
1760
943
|
}
|
1761
|
-
|
1762
|
-
const
|
1763
|
-
if (!
|
1764
|
-
|
944
|
+
initProcessors$() {
|
945
|
+
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
946
|
+
if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
|
947
|
+
// Skip initialization as backend will take processors from SF
|
948
|
+
return of(undefined);
|
1765
949
|
}
|
1766
|
-
const
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
return of(
|
950
|
+
const owners$ = Object.values(this.flowInfoService.templates)
|
951
|
+
.map(template => {
|
952
|
+
if (!template) {
|
953
|
+
return;
|
954
|
+
}
|
955
|
+
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
956
|
+
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
|
957
|
+
const processorsMap = processors.reduce((acc, p) => {
|
958
|
+
acc[p.apiName] = p;
|
959
|
+
return acc;
|
960
|
+
}, {});
|
961
|
+
this.processors[template.id] = processorsMap;
|
962
|
+
}));
|
963
|
+
})
|
964
|
+
.filter(isDefined);
|
965
|
+
if (!owners$.length) {
|
966
|
+
return of(undefined);
|
1773
967
|
}
|
1774
|
-
return
|
1775
|
-
const model = this.configurationService.getRuntimeModel();
|
1776
|
-
const split = model?.types.find(type => type.name === lineItem.type)?.split ?? false;
|
1777
|
-
const lineItems = multiplyLineItems(lineItem, props.qty ?? 1, split);
|
1778
|
-
return [...quoteDraft.currentState, ...lineItems];
|
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));
|
968
|
+
return forkJoin(owners$).pipe(map(noop));
|
1792
969
|
}
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
return this.
|
1801
|
-
}
|
1802
|
-
get activeMetricsSnapshot() {
|
1803
|
-
return this.quoteDraftService.quoteDraft?.activeMetrics ?? [];
|
970
|
+
executeActionScript(request, executable) {
|
971
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
972
|
+
if (!configurationProcessor?.script) {
|
973
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
974
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
975
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
976
|
+
}
|
977
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1804
978
|
}
|
1805
|
-
|
1806
|
-
|
979
|
+
executeSelectorScript(request, executable) {
|
980
|
+
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
981
|
+
if (!configurationProcessor?.script) {
|
982
|
+
const scope = this.getScopeByOwnerId(executable.ownerId);
|
983
|
+
const scopeText = scope ? ` in ${scope}` : '';
|
984
|
+
throw `ConfigurationProcessor ${executable.apiName}${scopeText} not found`;
|
985
|
+
}
|
986
|
+
return this.executeProcessorScript(request, configurationProcessor, executable.inputData);
|
1807
987
|
}
|
1808
|
-
|
1809
|
-
|
988
|
+
executeProcessorScript(request, configurationProcessor, inputData) {
|
989
|
+
const scope = this.getScopeByOwnerId(configurationProcessor.ownerId ?? '');
|
990
|
+
let functionToExecute = this.executedFunctions[scope + configurationProcessor.apiName];
|
991
|
+
if (!functionToExecute) {
|
992
|
+
const script = `${configurationProcessor.script}\nreturn transform;`;
|
993
|
+
const sourceMap = `\n//# sourceURL=${scope ? scope + '/' : ''}${configurationProcessor.apiName}.js`;
|
994
|
+
functionToExecute = new Function(script + sourceMap)();
|
995
|
+
this.executedFunctions[scope + configurationProcessor.apiName] = functionToExecute;
|
996
|
+
}
|
997
|
+
return functionToExecute({
|
998
|
+
request,
|
999
|
+
inputData,
|
1000
|
+
flowStore: this.flowStore,
|
1001
|
+
});
|
1810
1002
|
}
|
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
|
-
};
|
1003
|
+
generateRequestId(scope, selectorName, inputData) {
|
1004
|
+
const inputDataHash = UUID.hex(JSON.stringify(inputData) || '').slice(0, 8);
|
1005
|
+
return `${scope}/${selectorName}/${inputDataHash}`;
|
1824
1006
|
}
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1007
|
+
checkStatefulChanges(requestId, selectorResult) {
|
1008
|
+
if (this.trackedStatefulChangesMap.has(requestId)) {
|
1009
|
+
if (!this.initialStatefulData[requestId]) {
|
1010
|
+
this.initialStatefulData[requestId] = selectorResult;
|
1011
|
+
}
|
1012
|
+
const hasChanges = !isEqual(this.initialStatefulData[requestId], selectorResult);
|
1013
|
+
this.trackedStatefulChangesMap.set(requestId, hasChanges);
|
1830
1014
|
}
|
1831
|
-
return this.proceduresApiService.apply$(request);
|
1832
1015
|
}
|
1833
1016
|
}
|
1834
|
-
|
1835
|
-
|
1836
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1017
|
+
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 });
|
1018
|
+
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
1019
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
1837
1020
|
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
|
-
}] });
|
1021
|
+
}], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i3.FlowStateApiService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
1022
|
+
type: Optional
|
1023
|
+
}, {
|
1024
|
+
type: Inject,
|
1025
|
+
args: [FLOW_CUSTOMIZATION]
|
1026
|
+
}] }]; } });
|
1852
1027
|
|
1853
1028
|
class FlowStateConfigurationService {
|
1854
|
-
constructor(flowInfoService,
|
1029
|
+
constructor(flowInfoService, flowStateService) {
|
1855
1030
|
this.flowInfoService = flowInfoService;
|
1856
|
-
this.flowConfigurationService = flowConfigurationService;
|
1857
|
-
this.flowStateApiService = flowStateApiService;
|
1858
1031
|
this.flowStateService = flowStateService;
|
1859
|
-
this.configurationStateId$ = new BehaviorSubject(null);
|
1860
|
-
}
|
1861
|
-
get configurationStateId() {
|
1862
|
-
return this.configurationStateId$.value;
|
1863
1032
|
}
|
1864
1033
|
addToCart$(props) {
|
1865
1034
|
let request$;
|
@@ -1870,26 +1039,22 @@ class FlowStateConfigurationService {
|
|
1870
1039
|
request$ = of();
|
1871
1040
|
}
|
1872
1041
|
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
|
-
}));
|
1042
|
+
// TODO: Implement
|
1043
|
+
request$ = of();
|
1880
1044
|
}
|
1881
1045
|
}
|
1882
1046
|
else {
|
1883
|
-
|
1047
|
+
// TODO: Implement
|
1048
|
+
request$ = of();
|
1884
1049
|
}
|
1885
|
-
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map
|
1050
|
+
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1886
1051
|
}
|
1887
1052
|
}
|
1888
|
-
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token:
|
1053
|
+
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
1054
|
FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
|
1890
1055
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
|
1891
1056
|
type: Injectable
|
1892
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type:
|
1057
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }]; } });
|
1893
1058
|
|
1894
1059
|
class IntegrationState {
|
1895
1060
|
constructor() {
|
@@ -1909,12 +1074,12 @@ class IntegrationState {
|
|
1909
1074
|
this.action$.next(action);
|
1910
1075
|
}
|
1911
1076
|
listen$(actionType) {
|
1912
|
-
return this.action$.pipe(filter$1(action => action.type === actionType), map
|
1077
|
+
return this.action$.pipe(filter$1(action => action.type === actionType), map(action => action.payload));
|
1913
1078
|
}
|
1914
1079
|
listenAll$() {
|
1915
1080
|
return this.action$.asObservable();
|
1916
1081
|
}
|
1917
|
-
|
1082
|
+
reset() {
|
1918
1083
|
this.stateSubj$.next({});
|
1919
1084
|
}
|
1920
1085
|
}
|
@@ -1925,8 +1090,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1925
1090
|
}] });
|
1926
1091
|
|
1927
1092
|
class ProductImagesService {
|
1928
|
-
constructor(
|
1929
|
-
this.
|
1093
|
+
constructor(productsAdminApiService) {
|
1094
|
+
this.productsAdminApiService = productsAdminApiService;
|
1930
1095
|
this.imagesMap$ = new BehaviorSubject({});
|
1931
1096
|
}
|
1932
1097
|
getImageUrl$(productId) {
|
@@ -1934,168 +1099,32 @@ class ProductImagesService {
|
|
1934
1099
|
this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
|
1935
1100
|
this.fetchProductImage(productId);
|
1936
1101
|
}
|
1937
|
-
return this.imagesMap$.pipe(map
|
1102
|
+
return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
|
1938
1103
|
}
|
1939
1104
|
fetchProductImage(productId) {
|
1940
|
-
this.
|
1105
|
+
this.productsAdminApiService
|
1941
1106
|
.fetchImage$(productId)
|
1942
|
-
.pipe(map
|
1107
|
+
.pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
|
1943
1108
|
.subscribe();
|
1944
1109
|
}
|
1945
1110
|
}
|
1946
|
-
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.
|
1111
|
+
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
1112
|
ProductImagesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService });
|
1948
1113
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, decorators: [{
|
1949
1114
|
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 }]; } });
|
1115
|
+
}], ctorParameters: function () { return [{ type: i1.ProductsAdminApiService }]; } });
|
2087
1116
|
|
2088
1117
|
class ConfigurationStateService {
|
2089
|
-
constructor(configurationRuntimeService, configurationService,
|
1118
|
+
constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService) {
|
2090
1119
|
this.configurationRuntimeService = configurationRuntimeService;
|
2091
1120
|
this.configurationService = configurationService;
|
2092
|
-
this.quoteDraftService = quoteDraftService;
|
2093
|
-
this.toastService = toastService;
|
2094
1121
|
this.flowStateService = flowStateService;
|
2095
1122
|
this.flowInfoService = flowInfoService;
|
2096
1123
|
this.flowConfigurationService = flowConfigurationService;
|
2097
1124
|
this.flowStateApiService = flowStateApiService;
|
2098
|
-
this.
|
1125
|
+
this.salesTransactionService = salesTransactionService;
|
1126
|
+
this.salesTransactionApiService = salesTransactionApiService;
|
1127
|
+
this.toastService = toastService;
|
2099
1128
|
this.isInitialized$ = new BehaviorSubject(false);
|
2100
1129
|
this.canceledConfiguration$ = new Subject();
|
2101
1130
|
this.NOT_INITIALIZED = Symbol();
|
@@ -2119,9 +1148,9 @@ class ConfigurationStateService {
|
|
2119
1148
|
request$ = this.initStateful$();
|
2120
1149
|
}
|
2121
1150
|
else {
|
2122
|
-
request$ = this.
|
1151
|
+
request$ = this.configurationService.init$();
|
2123
1152
|
}
|
2124
|
-
return request$.pipe(
|
1153
|
+
return request$.pipe(take(1), tap(() => {
|
2125
1154
|
this.isInitialized$.next(true);
|
2126
1155
|
this.canceledConfiguration$ = new Subject();
|
2127
1156
|
}));
|
@@ -2135,10 +1164,11 @@ class ConfigurationStateService {
|
|
2135
1164
|
this.configurationStore = {};
|
2136
1165
|
this.executedFunctions = {};
|
2137
1166
|
this.configurationService.reset();
|
1167
|
+
this.configurationRuntimeService.reset();
|
2138
1168
|
}
|
2139
1169
|
execute$(exec) {
|
2140
1170
|
const request = this.execToRequest(exec);
|
2141
|
-
return this.executeRequest$(request).pipe(map
|
1171
|
+
return this.executeRequest$(request).pipe(map(result => {
|
2142
1172
|
// Keep only requested results
|
2143
1173
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
2144
1174
|
if (exec.selectors?.[requestId]) {
|
@@ -2160,7 +1190,7 @@ class ConfigurationStateService {
|
|
2160
1190
|
}
|
2161
1191
|
// prevent parallel configuration requests in stateless mode
|
2162
1192
|
if (!this.statelessExecutionRequest$) {
|
2163
|
-
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay
|
1193
|
+
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
|
2164
1194
|
}
|
2165
1195
|
return this.statelessExecutionRequest$;
|
2166
1196
|
}
|
@@ -2174,7 +1204,7 @@ class ConfigurationStateService {
|
|
2174
1204
|
},
|
2175
1205
|
},
|
2176
1206
|
});
|
2177
|
-
return this.executeRequest$(request).pipe(map
|
1207
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
2178
1208
|
}
|
2179
1209
|
subscribe$(selectorName, inputData = {}, options) {
|
2180
1210
|
const requestId = UUID.UUID();
|
@@ -2197,56 +1227,42 @@ class ConfigurationStateService {
|
|
2197
1227
|
this.executeRequest$(request).subscribe();
|
2198
1228
|
}
|
2199
1229
|
}
|
2200
|
-
return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map
|
1230
|
+
return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
|
2201
1231
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
2202
1232
|
delete this.subscriptions[requestId];
|
2203
1233
|
}
|
2204
1234
|
}), takeUntil(this.canceledConfiguration$));
|
2205
1235
|
}
|
2206
|
-
saveConfiguration(
|
1236
|
+
saveConfiguration() {
|
2207
1237
|
if (this.isStatefulConfiguration) {
|
2208
|
-
return this.flowStateApiService
|
2209
|
-
|
2210
|
-
|
1238
|
+
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
|
1239
|
+
}
|
1240
|
+
const state = this.salesTransactionService.state;
|
1241
|
+
if (!state) {
|
1242
|
+
return of({ id: '' });
|
1243
|
+
}
|
1244
|
+
const { standalone } = this.flowInfoService.flow.properties;
|
1245
|
+
if (standalone) {
|
1246
|
+
return this.salesTransactionApiService.upsert(state);
|
1247
|
+
}
|
1248
|
+
const salesTransaction = this.salesTransactionService.state;
|
1249
|
+
const configurationRoot = this.configurationService.root;
|
1250
|
+
if (!salesTransaction || !configurationRoot) {
|
1251
|
+
return of({ id: '' });
|
1252
|
+
}
|
1253
|
+
const isNewTransactionItem = salesTransaction.salesTransactionItems.every(li => li.id !== configurationRoot.id);
|
1254
|
+
let salesTransactionItems;
|
1255
|
+
if (isNewTransactionItem) {
|
1256
|
+
salesTransactionItems = [...salesTransaction.salesTransactionItems, configurationRoot];
|
2211
1257
|
}
|
2212
1258
|
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
|
-
}
|
1259
|
+
salesTransactionItems = salesTransaction.salesTransactionItems.map(ti => ti.id === configurationRoot.id ? configurationRoot : ti);
|
2249
1260
|
}
|
1261
|
+
const newState = {
|
1262
|
+
...salesTransaction,
|
1263
|
+
salesTransactionItems,
|
1264
|
+
};
|
1265
|
+
return this.flowConfigurationService.calculate$(newState).pipe(map(() => ({ id: '' })));
|
2250
1266
|
}
|
2251
1267
|
cancelConfiguration() {
|
2252
1268
|
if (!this.isInitialized$.value) {
|
@@ -2265,36 +1281,32 @@ class ConfigurationStateService {
|
|
2265
1281
|
return this.flowInfoService.flow?.properties.stateful ?? false;
|
2266
1282
|
}
|
2267
1283
|
initStateful$() {
|
2268
|
-
this.ownerId = this.configurationRuntimeService.
|
2269
|
-
const
|
2270
|
-
if (!this.flowStateService.stateId) {
|
1284
|
+
this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
|
1285
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
1286
|
+
if (!productId || !this.flowStateService.stateId) {
|
2271
1287
|
return of(undefined);
|
2272
1288
|
}
|
2273
|
-
const container = this.configurationRuntimeService.
|
2274
|
-
const lineItem = this.configurationService.generateLineItem();
|
1289
|
+
const container = this.configurationRuntimeService.uiDefinitionContainer;
|
2275
1290
|
let request$;
|
2276
|
-
if (!
|
1291
|
+
if (!transactionItemId) {
|
2277
1292
|
request$ = this.flowStateApiService.newConfiguration(this.flowStateService.stateId, {
|
2278
|
-
|
1293
|
+
transactionItem: generateTransactionItem(productId),
|
2279
1294
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2280
1295
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2281
1296
|
});
|
2282
1297
|
}
|
2283
1298
|
else {
|
2284
1299
|
request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
|
2285
|
-
|
1300
|
+
transactionItemId,
|
2286
1301
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2287
1302
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2288
1303
|
});
|
2289
1304
|
}
|
2290
|
-
return request$.pipe(map
|
1305
|
+
return request$.pipe(map(r => {
|
2291
1306
|
this.stateId = r.stateId;
|
2292
1307
|
return undefined;
|
2293
1308
|
}));
|
2294
1309
|
}
|
2295
|
-
initStateless$() {
|
2296
|
-
return this.configurationService.configure().pipe(map$1(() => undefined));
|
2297
|
-
}
|
2298
1310
|
execToRequest(exec) {
|
2299
1311
|
return {
|
2300
1312
|
actions: exec.actions?.map(action => ({
|
@@ -2334,37 +1346,35 @@ class ConfigurationStateService {
|
|
2334
1346
|
else {
|
2335
1347
|
execution$ = this.executeStateless$(fullRequest);
|
2336
1348
|
}
|
2337
|
-
return execution$.pipe(tap
|
1349
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
2338
1350
|
}
|
2339
1351
|
executeStateless$(request) {
|
2340
1352
|
this.executionInProgress$.next(true);
|
2341
|
-
return
|
1353
|
+
return this.configurationService.state$.pipe(switchMap(state => {
|
2342
1354
|
// Apply actions and execute configuration/price call
|
2343
1355
|
// No need to run configuration if no actions in the request
|
2344
1356
|
if (!request.actions?.length) {
|
2345
1357
|
return of(undefined);
|
2346
1358
|
}
|
2347
|
-
let configurationRequest = this.configurationService.generateRequest(false);
|
2348
1359
|
request.actions.forEach(action => {
|
2349
|
-
|
1360
|
+
state = this.executeActionScript(state, action) ?? state;
|
2350
1361
|
});
|
2351
|
-
|
2352
|
-
|
2353
|
-
}), map$1(() => {
|
1362
|
+
return this.configurationService.configureRequest$(state);
|
1363
|
+
}), map(() => {
|
2354
1364
|
// Run selectors and apply them to the state
|
2355
|
-
const configurationState = this.configurationService.
|
1365
|
+
const configurationState = this.configurationService.state;
|
2356
1366
|
if (!configurationState) {
|
2357
1367
|
return { stateId: '', selectors: {} };
|
2358
1368
|
}
|
2359
1369
|
return this.runStatelessSelectors(request, configurationState);
|
2360
|
-
}), tap
|
2361
|
-
const configurationState = this.configurationService.
|
1370
|
+
}), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
|
1371
|
+
const configurationState = this.configurationService.previousState;
|
2362
1372
|
if (configurationState) {
|
2363
1373
|
const selectorsResult = this.runStatelessSelectors(request, configurationState);
|
2364
1374
|
this.handleSelectorsResponse(selectorsResult.selectors);
|
2365
1375
|
}
|
2366
1376
|
this.executionInProgress$.next(false);
|
2367
|
-
if (!this.configurationRuntimeService.
|
1377
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
2368
1378
|
this.toastService.add({ severity: ToastType.error, summary: String(error) });
|
2369
1379
|
}
|
2370
1380
|
return throwError(() => error);
|
@@ -2385,21 +1395,21 @@ class ConfigurationStateService {
|
|
2385
1395
|
};
|
2386
1396
|
this.executionInProgress$.next(true);
|
2387
1397
|
return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
|
2388
|
-
}), tap
|
1398
|
+
}), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
2389
1399
|
this.executionInProgress$.next(false);
|
2390
1400
|
return throwError(() => e);
|
2391
1401
|
}));
|
2392
1402
|
}
|
2393
1403
|
executeStateful$(request) {
|
2394
|
-
return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take
|
1404
|
+
return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take(1), switchMap(() =>
|
2395
1405
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
2396
1406
|
combineLatest([
|
2397
1407
|
this.statefulExecutionRequest$,
|
2398
|
-
of(undefined).pipe(tap
|
2399
|
-
])), map
|
1408
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1409
|
+
])), map(([response]) => response), take(1));
|
2400
1410
|
}
|
2401
1411
|
executeActionScript(request, processor) {
|
2402
|
-
const { actions } = this.configurationRuntimeService.
|
1412
|
+
const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2403
1413
|
const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
|
2404
1414
|
if (!configurationProcessor?.script) {
|
2405
1415
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2407,7 +1417,7 @@ class ConfigurationStateService {
|
|
2407
1417
|
return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
|
2408
1418
|
}
|
2409
1419
|
executeSelectorScript(request, processor) {
|
2410
|
-
const { selectors } = this.configurationRuntimeService.
|
1420
|
+
const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2411
1421
|
const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
|
2412
1422
|
if (!configurationProcessor?.script) {
|
2413
1423
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2448,25 +1458,63 @@ class ConfigurationStateService {
|
|
2448
1458
|
}, { stateId: '', selectors: {} });
|
2449
1459
|
}
|
2450
1460
|
}
|
2451
|
-
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token:
|
1461
|
+
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
1462
|
ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
|
2453
1463
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
|
2454
1464
|
type: Injectable
|
2455
|
-
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type:
|
1465
|
+
}], 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
1466
|
|
2457
1467
|
class ConfigurationModule {
|
2458
1468
|
}
|
2459
1469
|
ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2460
1470
|
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: [
|
1471
|
+
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [ConfigurationService, ConfigurationStateService, ConfigurationRuntimeService], imports: [ConfirmationDialogModule, ApiModule] });
|
2462
1472
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
|
2463
1473
|
type: NgModule,
|
2464
1474
|
args: [{
|
2465
1475
|
imports: [ConfirmationDialogModule, ApiModule],
|
2466
|
-
providers: [
|
1476
|
+
providers: [ConfigurationService, ConfigurationStateService, ConfigurationRuntimeService],
|
1477
|
+
}]
|
1478
|
+
}] });
|
1479
|
+
|
1480
|
+
class FlowConfigurationModule {
|
1481
|
+
}
|
1482
|
+
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
1483
|
+
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
1484
|
+
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
|
1485
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
1486
|
+
type: NgModule,
|
1487
|
+
args: [{
|
1488
|
+
imports: [ApiModule],
|
1489
|
+
providers: [FlowConfigurationService],
|
2467
1490
|
}]
|
2468
1491
|
}] });
|
2469
1492
|
|
1493
|
+
class CatalogProductsService {
|
1494
|
+
constructor() {
|
1495
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
1496
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter$1(isDefined));
|
1497
|
+
}
|
1498
|
+
get state() {
|
1499
|
+
return this.stateSubj$.getValue();
|
1500
|
+
}
|
1501
|
+
reset() {
|
1502
|
+
this.stateSubj$.next(null);
|
1503
|
+
}
|
1504
|
+
setState(state) {
|
1505
|
+
this.stateSubj$.next(state);
|
1506
|
+
}
|
1507
|
+
}
|
1508
|
+
CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1509
|
+
CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
|
1510
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
|
1511
|
+
type: Injectable
|
1512
|
+
}] });
|
1513
|
+
|
1514
|
+
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
1515
|
+
|
1516
|
+
const UI_DEFINITION_VERSION = 3;
|
1517
|
+
|
2470
1518
|
const DEFAULT_FORMATTING_SETTINGS = {
|
2471
1519
|
currencySymbol: DEFAULT_CURRENCY_SYMBOL,
|
2472
1520
|
decimalsCount: DEFAULT_DECIMALS_COUNT,
|
@@ -2480,14 +1528,14 @@ class SdkCoreModule {
|
|
2480
1528
|
SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2481
1529
|
SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
|
2482
1530
|
SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
|
2483
|
-
ContextService,
|
2484
1531
|
FlowInfoService,
|
2485
|
-
QuoteDraftService,
|
2486
1532
|
ProductImagesService,
|
2487
1533
|
IntegrationState,
|
2488
1534
|
FlowStateService,
|
2489
1535
|
FlowStateConfigurationService,
|
2490
1536
|
RuntimeSettingsService,
|
1537
|
+
SalesTransactionService,
|
1538
|
+
CatalogProductsService,
|
2491
1539
|
{
|
2492
1540
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2493
1541
|
useExisting: RuntimeSettingsService,
|
@@ -2498,14 +1546,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2498
1546
|
args: [{
|
2499
1547
|
imports: [ConfigurationModule, FlowConfigurationModule],
|
2500
1548
|
providers: [
|
2501
|
-
ContextService,
|
2502
1549
|
FlowInfoService,
|
2503
|
-
QuoteDraftService,
|
2504
1550
|
ProductImagesService,
|
2505
1551
|
IntegrationState,
|
2506
1552
|
FlowStateService,
|
2507
1553
|
FlowStateConfigurationService,
|
2508
1554
|
RuntimeSettingsService,
|
1555
|
+
SalesTransactionService,
|
1556
|
+
CatalogProductsService,
|
2509
1557
|
{
|
2510
1558
|
provide: FORMATTING_SETTINGS_TOKEN,
|
2511
1559
|
useExisting: RuntimeSettingsService,
|
@@ -2680,5 +1728,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2680
1728
|
* Generated bundle index. Do not edit.
|
2681
1729
|
*/
|
2682
1730
|
|
2683
|
-
export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService,
|
1731
|
+
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, TransactionItemWorker, UI_DEFINITION_VERSION, extractMetadata, findTransactionItem, findTransactionItemWithComparator, generateTransactionItem, insertTransactionItem, removeTransactionItem, replaceTransactionItem };
|
2684
1732
|
//# sourceMappingURL=veloceapps-sdk-core.mjs.map
|