@veloceapps/sdk 11.0.0-13 → 11.0.0-130
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 +94 -29
- package/cms/components/element-renderer/element-renderer.component.d.ts +3 -10
- package/cms/components/preview/preview.component.d.ts +5 -6
- package/cms/components/preview/preview.types.d.ts +0 -4
- package/cms/services/element-context.service.d.ts +0 -1
- package/cms/types/common.types.d.ts +2 -0
- package/cms/types/index.d.ts +0 -1
- package/cms/utils/path.utils.d.ts +1 -2
- package/cms/vendor-map.d.ts +21 -40
- package/core/index.d.ts +1 -1
- package/core/modules/configuration/index.d.ts +4 -4
- package/core/modules/configuration/services/configuration-runtime.service.d.ts +8 -17
- package/core/modules/configuration/services/configuration-state.service.d.ts +5 -4
- package/core/modules/configuration/services/configuration.service.d.ts +24 -47
- package/core/modules/configuration/services/guided-selling.service.d.ts +15 -0
- package/core/modules/configuration/services/test-mode-configuration.service.d.ts +26 -0
- package/core/modules/configuration/types/configuration-runtime.types.d.ts +0 -5
- package/core/modules/configuration/types/configuration.types.d.ts +8 -2
- package/core/modules/configuration/types/index.d.ts +2 -0
- package/core/modules/flow-configuration/index.d.ts +0 -3
- package/core/modules/flow-configuration/services/flow-configuration.service.d.ts +11 -17
- package/core/operators/filter-successful-execute.operator.d.ts +3 -0
- package/core/operators/index.d.ts +1 -0
- package/core/services/flow-info.service.d.ts +11 -9
- package/core/services/flow-state-configuration.service.d.ts +14 -8
- package/core/services/flow-state.service.d.ts +6 -15
- package/core/services/index.d.ts +1 -1
- 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 +9 -10
- package/core/types/flow-customization.types.d.ts +2 -2
- package/core/types/index.d.ts +0 -1
- package/core/utils/index.d.ts +3 -2
- package/core/utils/pcm.utils.d.ts +5 -0
- package/core/utils/transaction-item.utils.d.ts +10 -0
- package/core/utils/transaction-item.worker.d.ts +8 -0
- package/esm2020/cms/cms.actions.mjs +93 -71
- package/esm2020/cms/cms.default.mjs +2 -3
- package/esm2020/cms/components/element-renderer/element-renderer.component.mjs +7 -64
- package/esm2020/cms/components/element-tools-panel/element-tools-panel.component.mjs +3 -3
- package/esm2020/cms/components/preview/preview.component.mjs +19 -28
- package/esm2020/cms/components/preview/preview.types.mjs +1 -1
- package/esm2020/cms/services/element-context.service.mjs +1 -1
- package/esm2020/cms/types/common.types.mjs +1 -1
- package/esm2020/cms/types/index.mjs +1 -2
- package/esm2020/cms/utils/element.utils.mjs +3 -3
- package/esm2020/cms/utils/elements-resolver.mjs +16 -5
- package/esm2020/cms/utils/path.utils.mjs +1 -10
- package/esm2020/cms/vendor-map.mjs +21 -18
- package/esm2020/core/core.module.mjs +3 -6
- package/esm2020/core/index.mjs +2 -2
- package/esm2020/core/modules/configuration/configuration.module.mjs +17 -4
- package/esm2020/core/modules/configuration/index.mjs +5 -5
- package/esm2020/core/modules/configuration/services/configuration-runtime.service.mjs +16 -64
- package/esm2020/core/modules/configuration/services/configuration-state.service.mjs +65 -62
- package/esm2020/core/modules/configuration/services/configuration.service.mjs +123 -229
- package/esm2020/core/modules/configuration/services/guided-selling.service.mjs +62 -0
- package/esm2020/core/modules/configuration/services/test-mode-configuration.service.mjs +97 -0
- package/esm2020/core/modules/configuration/types/configuration-runtime.types.mjs +1 -1
- package/esm2020/core/modules/configuration/types/configuration.types.mjs +1 -1
- package/esm2020/core/modules/configuration/types/index.mjs +3 -0
- package/esm2020/core/modules/flow-configuration/flow-configuration.module.mjs +3 -4
- package/esm2020/core/modules/flow-configuration/index.mjs +1 -4
- package/esm2020/core/modules/flow-configuration/services/flow-configuration.service.mjs +31 -39
- package/esm2020/core/operators/filter-successful-execute.operator.mjs +5 -0
- package/esm2020/core/operators/index.mjs +2 -0
- package/esm2020/core/services/flow-info.service.mjs +31 -22
- package/esm2020/core/services/flow-state-configuration.service.mjs +91 -24
- package/esm2020/core/services/flow-state.service.mjs +34 -82
- package/esm2020/core/services/index.mjs +2 -2
- 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 +18 -13
- package/esm2020/core/types/flow-customization.types.mjs +1 -1
- package/esm2020/core/types/index.mjs +1 -2
- package/esm2020/core/utils/index.mjs +4 -3
- package/esm2020/core/utils/pcm.utils.mjs +15 -0
- package/esm2020/core/utils/transaction-item.utils.mjs +136 -0
- package/esm2020/core/utils/transaction-item.worker.mjs +16 -0
- package/esm2020/src/components/flow-header/flow-header.component.mjs +7 -8
- package/esm2020/src/components/guided-selling/guided-selling.component.mjs +7 -8
- package/esm2020/src/flow-routing.module.mjs +10 -8
- package/esm2020/src/guards/flow.guard.mjs +5 -7
- package/esm2020/src/guards/product-unload.guard.mjs +10 -8
- package/esm2020/src/index.mjs +1 -2
- package/esm2020/src/pages/assets/assets.component.mjs +7 -8
- package/esm2020/src/pages/catalog/catalog.component.mjs +7 -8
- package/esm2020/src/pages/debug/debug.component.mjs +12 -17
- package/esm2020/src/pages/product/product.component.mjs +39 -69
- package/esm2020/src/pages/record-not-found/record-not-found.component.mjs +5 -6
- package/esm2020/src/pages/shopping-cart/shopping-cart.component.mjs +7 -8
- package/esm2020/src/resolvers/pcm-model.resolver.mjs +12 -0
- package/esm2020/src/resolvers/sales-transaction.resolver.mjs +64 -0
- package/esm2020/src/resolvers/ui-definition.resolver.mjs +44 -0
- package/esm2020/src/services/flow-dialog.service.mjs +3 -24
- package/esm2020/src/services/flow-router.service.mjs +26 -33
- package/esm2020/src/services/flow.service.mjs +11 -17
- package/esm2020/src/types/index.mjs +2 -3
- package/esm2020/src/types/route.types.mjs +1 -1
- package/fesm2015/veloceapps-sdk-cms.mjs +166 -309
- package/fesm2015/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk-core.mjs +706 -1179
- package/fesm2015/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2015/veloceapps-sdk.mjs +194 -250
- package/fesm2015/veloceapps-sdk.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-cms.mjs +162 -300
- package/fesm2020/veloceapps-sdk-cms.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk-core.mjs +764 -1204
- package/fesm2020/veloceapps-sdk-core.mjs.map +1 -1
- package/fesm2020/veloceapps-sdk.mjs +193 -247
- 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/guards/product-unload.guard.d.ts +3 -3
- package/src/index.d.ts +0 -1
- 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 -4
- package/src/pages/product/product.component.d.ts +14 -13
- 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/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 +3 -5
- package/src/services/flow-router.service.d.ts +8 -8
- package/src/services/flow.service.d.ts +3 -3
- 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 -7
- 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/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 -67
- package/esm2020/core/modules/configuration/services/runtime-context.service.mjs +0 -45
- package/esm2020/core/modules/flow-configuration/services/flow-update.service.mjs +0 -138
- package/esm2020/core/modules/flow-configuration/types/update.types.mjs +0 -2
- package/esm2020/core/services/quote-draft.service.mjs +0 -174
- 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/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 -14
- package/esm2020/src/utils/index.mjs +0 -2
- package/src/resolvers/quote.resolver.d.ts +0 -18
- 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 -1
- package/src/utils/index.d.ts +0 -1
@@ -1,215 +1,44 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import * as
|
2
|
+
import { Injectable, InjectionToken, Optional, Inject, NgModule, inject, Directive, Input, LOCALE_ID, Pipe } from '@angular/core';
|
3
|
+
import { DEFAULT_CURRENCY_ISO_CODE, DEFAULT_CURRENCY_SYMBOL, validateDateFormat, DEFAULT_DATE_FORMAT, DEFAULT_DECIMALS_COUNT, getSupportedDateFormats, DEFAULT_DECIMAL_SEPARATOR, DEFAULT_THOUSANDS_SEPARATOR, DEFAULT_ACTION_CODE_LABELS, parseJsonSafely, isDefined, UITemplateType, SalesforceIdUtils, UUID, extractErrorDetails, ConfigurationProcessorTypes, EntityUtil, DEFAULT_TIME_FORMAT, formatNumber } from '@veloceapps/core';
|
4
|
+
import * as i3 from '@veloceapps/api';
|
5
5
|
import { ApiModule } from '@veloceapps/api';
|
6
|
-
import { map, first, tap, filter as filter$1, switchMap as switchMap$1, skip, take as take$1, shareReplay as shareReplay$1, catchError as catchError$1, finalize as finalize$1 } from 'rxjs/operators';
|
7
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
8
6
|
import * as i6 from '@veloceapps/components';
|
9
|
-
import { ToastType,
|
10
|
-
import
|
11
|
-
import
|
12
|
-
import
|
13
|
-
import
|
14
|
-
import
|
15
|
-
import moment from 'moment';
|
7
|
+
import { ToastType, ConfirmationDialogModule } from '@veloceapps/components';
|
8
|
+
import * as i1 from '@veloceapps/api/v2';
|
9
|
+
import { tap, BehaviorSubject, map, filter, switchMap, of, forkJoin, noop, throwError, Subject, catchError as catchError$1, combineLatest, finalize as finalize$1, buffer, debounceTime, share, take, distinctUntilChanged, shareReplay, takeUntil, first } from 'rxjs';
|
10
|
+
import { uniqBy, flatten, omit, cloneDeep, assign, isEqual } from 'lodash';
|
11
|
+
import * as i2 from 'primeng/api';
|
12
|
+
import { filter as filter$1, map as map$1, tap as tap$1, catchError, finalize } from 'rxjs/operators';
|
16
13
|
import { NgControl } from '@angular/forms';
|
17
14
|
import 'primeng/calendar';
|
18
15
|
import { DATE_PIPE_DEFAULT_OPTIONS, formatDate } from '@angular/common';
|
19
16
|
|
20
|
-
const getDefaultLineItem = (context, uiDefinitionProperties, qty = 1) => {
|
21
|
-
const id = UUID.UUID();
|
22
|
-
const attributes = [];
|
23
|
-
const lineItems = [];
|
24
|
-
return {
|
25
|
-
id,
|
26
|
-
type: uiDefinitionProperties.rootType ?? '',
|
27
|
-
cfgStatus: 'Default',
|
28
|
-
actionCode: 'ADD',
|
29
|
-
qty,
|
30
|
-
attributes,
|
31
|
-
lineItems,
|
32
|
-
productName: context.properties?.['displayName'] || context.productName,
|
33
|
-
productId: context.productId ?? '',
|
34
|
-
...(uiDefinitionProperties.offeringId ? { offeringId: uiDefinitionProperties.offeringId } : {}),
|
35
|
-
};
|
36
|
-
};
|
37
|
-
const generateEmptyContext = () => {
|
38
|
-
return {
|
39
|
-
headerId: '',
|
40
|
-
mode: ConfigurationContextMode.TEST,
|
41
|
-
properties: {},
|
42
|
-
configurationToken: '',
|
43
|
-
};
|
44
|
-
};
|
45
|
-
const getGuidedSellingConfigurationRequest = (data) => {
|
46
|
-
return {
|
47
|
-
mode: 'SEARCH',
|
48
|
-
step: 'START',
|
49
|
-
attributeDomainMode: 'ALL',
|
50
|
-
context: generateEmptyContext(),
|
51
|
-
lineItem: {
|
52
|
-
actionCode: 'ADD',
|
53
|
-
cfgStatus: 'Default',
|
54
|
-
id: UUID.UUID(),
|
55
|
-
qty: 1,
|
56
|
-
type: data.modelType,
|
57
|
-
attributes: Object.entries(data.attributesMap).map(([name, value]) => ({
|
58
|
-
name,
|
59
|
-
value,
|
60
|
-
cfgStatus: 'User',
|
61
|
-
})),
|
62
|
-
},
|
63
|
-
};
|
64
|
-
};
|
65
|
-
const generateConfigurationLineItem = (props, qty = 1) => {
|
66
|
-
const id = UUID.UUID();
|
67
|
-
const attributes = Object.entries(props.attributesMap ?? {}).map(([name, value]) => ({
|
68
|
-
name,
|
69
|
-
value,
|
70
|
-
cfgStatus: 'User',
|
71
|
-
}));
|
72
|
-
const lineItems = [];
|
73
|
-
return {
|
74
|
-
id,
|
75
|
-
type: props.product.typeName ?? '',
|
76
|
-
cfgStatus: 'Default',
|
77
|
-
actionCode: 'ADD',
|
78
|
-
qty,
|
79
|
-
attributes,
|
80
|
-
lineItems,
|
81
|
-
productName: props.product.name,
|
82
|
-
productId: props.product.id ?? '',
|
83
|
-
};
|
84
|
-
};
|
85
|
-
|
86
|
-
const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
|
87
|
-
|
88
|
-
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
89
|
-
|
90
|
-
var RuntimeMode;
|
91
|
-
(function (RuntimeMode) {
|
92
|
-
RuntimeMode[RuntimeMode["TEST"] = 0] = "TEST";
|
93
|
-
RuntimeMode[RuntimeMode["PROD"] = 1] = "PROD";
|
94
|
-
})(RuntimeMode || (RuntimeMode = {}));
|
95
|
-
var RuntimeOperation;
|
96
|
-
(function (RuntimeOperation) {
|
97
|
-
RuntimeOperation["INIT"] = "INIT";
|
98
|
-
RuntimeOperation["UPDATE"] = "UPDATE";
|
99
|
-
})(RuntimeOperation || (RuntimeOperation = {}));
|
100
|
-
var RuntimeStep;
|
101
|
-
(function (RuntimeStep) {
|
102
|
-
RuntimeStep["START"] = "START";
|
103
|
-
RuntimeStep["UPDATE"] = "UPDATE";
|
104
|
-
})(RuntimeStep || (RuntimeStep = {}));
|
105
|
-
|
106
|
-
const UI_DEFINITION_VERSION = 3;
|
107
|
-
|
108
|
-
class RuntimeContextService {
|
109
|
-
constructor(configurationApiService) {
|
110
|
-
this.configurationApiService = configurationApiService;
|
111
|
-
}
|
112
|
-
getRuntimeContext(productId, offeringId, defaultUIDefinitionId, requiredUIDefinitionId) {
|
113
|
-
return this.configurationApiService
|
114
|
-
.getRuntimeDataByProductId(productId, offeringId, defaultUIDefinitionId, requiredUIDefinitionId)
|
115
|
-
.pipe(map(runtimeData => {
|
116
|
-
const uiDefinitionContainer = this.getUIDefinitionContainer(runtimeData);
|
117
|
-
const runtimeModel = RuntimeModel.create(runtimeData.types, runtimeData.products);
|
118
|
-
const { productName, properties } = Array.from(runtimeModel.components.values()).find(c => c.productId === productId) ?? {};
|
119
|
-
const uiDefinitionProperties = uiDefinitionContainer?.source.properties;
|
120
|
-
return {
|
121
|
-
modelId: runtimeData.modelId,
|
122
|
-
uiDefinitionContainer: uiDefinitionContainer,
|
123
|
-
runtimeModel: runtimeModel,
|
124
|
-
runtimeMode: RuntimeMode.PROD,
|
125
|
-
productId: productId,
|
126
|
-
productType: properties?.['displayName'] || productName,
|
127
|
-
offeringId: offeringId,
|
128
|
-
properties: {
|
129
|
-
PricingEnabled: uiDefinitionProperties?.pricingEnabled ? 'true' : 'false',
|
130
|
-
PriceListId: uiDefinitionProperties?.priceList,
|
131
|
-
},
|
132
|
-
};
|
133
|
-
}));
|
134
|
-
}
|
135
|
-
getUIDefinitionContainer(runtimeData) {
|
136
|
-
const containers = runtimeData.uiDefinitions.filter(container => isNotLegacyUIDefinition(container.source));
|
137
|
-
return containers.find(container => container.source.primary) ?? containers[0];
|
138
|
-
}
|
139
|
-
}
|
140
|
-
RuntimeContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, deps: [{ token: i1.ConfigurationApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
141
|
-
RuntimeContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService });
|
142
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: RuntimeContextService, decorators: [{
|
143
|
-
type: Injectable
|
144
|
-
}], ctorParameters: function () { return [{ type: i1.ConfigurationApiService }]; } });
|
145
|
-
|
146
17
|
class ConfigurationRuntimeService {
|
147
|
-
constructor(
|
148
|
-
this.
|
149
|
-
this.
|
150
|
-
|
151
|
-
|
18
|
+
constructor(pcmApiService) {
|
19
|
+
this.pcmApiService = pcmApiService;
|
20
|
+
this.uiDefinitionContainer = null;
|
21
|
+
}
|
22
|
+
get uiDefinitionProps() {
|
23
|
+
return this.uiDefinitionContainer?.source.properties ?? {};
|
152
24
|
}
|
153
25
|
reset() {
|
154
|
-
this.
|
155
|
-
this._runtimeContext = undefined;
|
26
|
+
this.uiDefinitionContainer = null;
|
156
27
|
this.initializationProps = undefined;
|
157
|
-
this.
|
158
|
-
}
|
159
|
-
initTestMode(uiDefinitionContainer) {
|
160
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
161
|
-
return this.apiService.getRuntimeDataByModelId(uiDefinitionContainer.modelId).pipe(first(), map(runtimeData => {
|
162
|
-
this._runtimeContext = {
|
163
|
-
modelId: uiDefinitionContainer.modelId,
|
164
|
-
runtimeModel: RuntimeModel.create(runtimeData.types, runtimeData.products),
|
165
|
-
runtimeMode: RuntimeMode.TEST,
|
166
|
-
uiDefinitionContainer,
|
167
|
-
};
|
168
|
-
return this._runtimeContext;
|
169
|
-
}), tap(() => (this._isInitialized = true)));
|
28
|
+
this.pcmModel = undefined;
|
170
29
|
}
|
171
|
-
init(props) {
|
30
|
+
init$(props) {
|
172
31
|
this.initializationProps = props;
|
173
|
-
return this.
|
174
|
-
.getRuntimeContext(props.productId, props.offeringId, props.defaultUIDefinitionId, props.requiredUIDefinitionId)
|
175
|
-
.pipe(tap(runtimeContext => {
|
176
|
-
this.uiDefinitionProperties = runtimeContext.uiDefinitionContainer?.source.properties ?? {};
|
177
|
-
this.id15to18('AccountId', runtimeContext.properties);
|
178
|
-
this._runtimeContext = runtimeContext;
|
179
|
-
return this._runtimeContext;
|
180
|
-
}), tap(() => (this._isInitialized = true)));
|
181
|
-
}
|
182
|
-
overrideUIDefinition(uiDefinitionContainer) {
|
183
|
-
if (!this._runtimeContext) {
|
184
|
-
return;
|
185
|
-
}
|
186
|
-
this._runtimeContext.uiDefinitionContainer = uiDefinitionContainer;
|
187
|
-
this.uiDefinitionProperties = uiDefinitionContainer.source.properties ?? {};
|
188
|
-
}
|
189
|
-
id15to18(propertyName, source) {
|
190
|
-
if (!source) {
|
191
|
-
return;
|
192
|
-
}
|
193
|
-
const value = source[propertyName];
|
194
|
-
if (typeof value === 'string' && value.length === 15) {
|
195
|
-
source[propertyName] = SalesforceIdUtils.generateId18FromId15(value);
|
196
|
-
}
|
197
|
-
}
|
198
|
-
get isInitialized() {
|
199
|
-
return this._isInitialized;
|
200
|
-
}
|
201
|
-
get runtimeModel() {
|
202
|
-
return this.runtimeContext?.runtimeModel;
|
203
|
-
}
|
204
|
-
get runtimeContext() {
|
205
|
-
return this._runtimeContext;
|
32
|
+
return this.pcmApiService.fetchPCMByProductId(props.productId).pipe(tap(pcmModel => (this.pcmModel = pcmModel)));
|
206
33
|
}
|
207
34
|
}
|
208
|
-
ConfigurationRuntimeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, deps: [{ token: i1.
|
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 });
|
209
36
|
ConfigurationRuntimeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService });
|
210
37
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationRuntimeService, decorators: [{
|
211
38
|
type: Injectable
|
212
|
-
}], ctorParameters: function () { return [{ type: i1.
|
39
|
+
}], ctorParameters: function () { return [{ type: i1.PCMApiService }]; } });
|
40
|
+
|
41
|
+
const FLOW_CUSTOMIZATION = new InjectionToken('FLOW_CUSTOMIZATION');
|
213
42
|
|
214
43
|
class RuntimeSettingsService {
|
215
44
|
constructor(configurationSettingsApiService) {
|
@@ -228,11 +57,11 @@ class RuntimeSettingsService {
|
|
228
57
|
};
|
229
58
|
}
|
230
59
|
create() {
|
231
|
-
return this.configurationSettingsApiService.fetchSettings().pipe(map
|
60
|
+
return this.configurationSettingsApiService.fetchSettings().pipe(map(settings => this.parseConfigurationSettings(settings)), tap(configurationSettings => {
|
232
61
|
this.configurationSettings$.next(configurationSettings);
|
233
62
|
this.addShoppingCartSettings(configurationSettings['shopping-cart'] ?? []);
|
234
63
|
this.formattingSettings = this.getFormattingSettings();
|
235
|
-
}), map
|
64
|
+
}), map(() => undefined));
|
236
65
|
}
|
237
66
|
initCurrency(iso) {
|
238
67
|
if (iso) {
|
@@ -317,6 +146,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
317
146
|
}], ctorParameters: function () { return [{ type: i1.ConfigurationSettingsApiService }]; } });
|
318
147
|
|
319
148
|
class FlowInfoService {
|
149
|
+
constructor(runtimeSettingsService, templatesAdminApiService, customizationService) {
|
150
|
+
this.runtimeSettingsService = runtimeSettingsService;
|
151
|
+
this.templatesAdminApiService = templatesAdminApiService;
|
152
|
+
this.customizationService = customizationService;
|
153
|
+
this.defaultTemplates = {
|
154
|
+
flowEngine: 'Flow Engine',
|
155
|
+
};
|
156
|
+
this.flowSubj$ = new BehaviorSubject(null);
|
157
|
+
this.templatesSubj$ = new BehaviorSubject({});
|
158
|
+
this.contextSubj$ = new BehaviorSubject(null);
|
159
|
+
this.flow$ = this.flowSubj$.asObservable();
|
160
|
+
this.templates$ = this.templatesSubj$.asObservable();
|
161
|
+
}
|
320
162
|
get flow() {
|
321
163
|
if (!this.flowSubj$.value) {
|
322
164
|
throw new Error(`Flow not initialized yet`);
|
@@ -332,29 +174,19 @@ class FlowInfoService {
|
|
332
174
|
}
|
333
175
|
return { ...this.contextSubj$.value };
|
334
176
|
}
|
177
|
+
get context$() {
|
178
|
+
return this.contextSubj$.asObservable().pipe(filter(isDefined));
|
179
|
+
}
|
335
180
|
get templates() {
|
336
181
|
return this.templatesSubj$.value;
|
337
182
|
}
|
338
183
|
get isFlowEngineInitialized$() {
|
339
|
-
return this.templates$.pipe(map
|
184
|
+
return this.templates$.pipe(map(v => Boolean(v.FLOW_ENGINE)));
|
340
185
|
}
|
341
186
|
get isStateful() {
|
342
187
|
return !!this.flow?.properties.stateful;
|
343
188
|
}
|
344
|
-
|
345
|
-
this.runtimeSettingsService = runtimeSettingsService;
|
346
|
-
this.templatesApiService = templatesApiService;
|
347
|
-
this.customizationService = customizationService;
|
348
|
-
this.defaultTemplates = {
|
349
|
-
flowEngine: 'Flow Engine',
|
350
|
-
};
|
351
|
-
this.flowSubj$ = new BehaviorSubject(null);
|
352
|
-
this.templatesSubj$ = new BehaviorSubject({});
|
353
|
-
this.contextSubj$ = new BehaviorSubject(null);
|
354
|
-
this.flow$ = this.flowSubj$.asObservable();
|
355
|
-
this.templates$ = this.templatesSubj$.asObservable();
|
356
|
-
}
|
357
|
-
cleanup() {
|
189
|
+
reset() {
|
358
190
|
this.flowSubj$.next(null);
|
359
191
|
this.templatesSubj$.next({});
|
360
192
|
this.contextSubj$.next(null);
|
@@ -362,6 +194,12 @@ class FlowInfoService {
|
|
362
194
|
init$(flowId, routeQueryParams) {
|
363
195
|
return this.initFlow$(flowId, routeQueryParams).pipe(switchMap(() => this.initFlowTemplates$()));
|
364
196
|
}
|
197
|
+
updateContext(update) {
|
198
|
+
this.contextSubj$.next({
|
199
|
+
...this.context,
|
200
|
+
...update,
|
201
|
+
});
|
202
|
+
}
|
365
203
|
initFlow$(flowId, routeQueryParams) {
|
366
204
|
const flow = this.runtimeSettingsService.getConfigurationSettings()['flows']?.find(({ id }) => flowId === id);
|
367
205
|
if (!flow) {
|
@@ -387,9 +225,9 @@ class FlowInfoService {
|
|
387
225
|
}
|
388
226
|
initFlowTemplates$() {
|
389
227
|
return forkJoin([
|
390
|
-
this.
|
228
|
+
this.templatesAdminApiService.fetchTemplates$(),
|
391
229
|
this.customizationService?.getTemplates?.() ?? of([]),
|
392
|
-
]).pipe(map
|
230
|
+
]).pipe(map(([templates, localTemplates]) => {
|
393
231
|
const newValue = {};
|
394
232
|
Object.entries({ ...this.defaultTemplates, ...(this.flow?.properties.templates ?? {}) }).forEach(([key, name]) => {
|
395
233
|
const type = this.remapTemplateName(key);
|
@@ -433,239 +271,177 @@ class FlowInfoService {
|
|
433
271
|
return objectName.toUpperCase();
|
434
272
|
}
|
435
273
|
}
|
436
|
-
FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token: RuntimeSettingsService }, { token:
|
274
|
+
FlowInfoService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, deps: [{ token: RuntimeSettingsService }, { token: i1.UITemplatesAdminApiService }, { token: FLOW_CUSTOMIZATION, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
437
275
|
FlowInfoService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService });
|
438
276
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowInfoService, decorators: [{
|
439
277
|
type: Injectable
|
440
|
-
}], ctorParameters: function () { return [{ type: RuntimeSettingsService }, { type:
|
278
|
+
}], ctorParameters: function () { return [{ type: RuntimeSettingsService }, { type: i1.UITemplatesAdminApiService }, { type: undefined, decorators: [{
|
441
279
|
type: Optional
|
442
280
|
}, {
|
443
281
|
type: Inject,
|
444
282
|
args: [FLOW_CUSTOMIZATION]
|
445
283
|
}] }]; } });
|
446
284
|
|
447
|
-
|
448
|
-
|
285
|
+
class PCMUtils {
|
286
|
+
static mapByPrcId(pcm) {
|
287
|
+
const map = {};
|
288
|
+
if (pcm.productRelatedComponent) {
|
289
|
+
map[pcm.productRelatedComponent.id] = pcm;
|
290
|
+
}
|
291
|
+
for (const group of pcm.productComponentGroups) {
|
292
|
+
for (const gc of group.components) {
|
293
|
+
Object.assign(map, PCMUtils.mapByPrcId(gc));
|
294
|
+
}
|
295
|
+
}
|
296
|
+
return map;
|
297
|
+
}
|
298
|
+
}
|
299
|
+
|
300
|
+
const findTransactionItem = (id, items) => {
|
301
|
+
return findTransactionItemWithComparator(items, (ti) => ti.id === id);
|
449
302
|
};
|
450
|
-
const
|
451
|
-
let currentLevel =
|
303
|
+
const findTransactionItemWithComparator = (items, comparator) => {
|
304
|
+
let currentLevel = items;
|
452
305
|
while (currentLevel.length) {
|
453
306
|
const found = currentLevel.find(comparator);
|
454
307
|
if (found) {
|
455
308
|
return found;
|
456
309
|
}
|
457
|
-
currentLevel = flatten(currentLevel.map(parent => parent.
|
310
|
+
currentLevel = flatten(currentLevel.map(parent => parent.children));
|
458
311
|
}
|
459
312
|
return;
|
460
313
|
};
|
461
|
-
const
|
462
|
-
const insertData =
|
314
|
+
const insertTransactionItem = (item, parentId, toInsert) => {
|
315
|
+
const insertData = item.id === parentId ? [toInsert] : [];
|
463
316
|
return {
|
464
|
-
...
|
465
|
-
|
317
|
+
...item,
|
318
|
+
children: [
|
466
319
|
...insertData,
|
467
|
-
...
|
468
|
-
return
|
320
|
+
...item.children.map(ti => {
|
321
|
+
return insertTransactionItem(ti, parentId, toInsert);
|
469
322
|
}),
|
470
323
|
],
|
471
324
|
};
|
472
325
|
};
|
473
|
-
const
|
326
|
+
const removeTransactionItem = (item, idToRemove) => {
|
474
327
|
return {
|
475
|
-
...
|
476
|
-
|
477
|
-
.map(
|
478
|
-
if (
|
328
|
+
...item,
|
329
|
+
children: item.children
|
330
|
+
.map(ti => {
|
331
|
+
if (ti.id === idToRemove) {
|
479
332
|
return;
|
480
333
|
}
|
481
|
-
else if (
|
482
|
-
return
|
334
|
+
else if (ti.children.length) {
|
335
|
+
return removeTransactionItem(ti, idToRemove);
|
483
336
|
}
|
484
|
-
return
|
337
|
+
return ti;
|
485
338
|
})
|
486
|
-
.filter(
|
339
|
+
.filter(isDefined),
|
487
340
|
};
|
488
341
|
};
|
489
|
-
const
|
490
|
-
if (
|
491
|
-
|
492
|
-
return { ...recalculateCardinalityVariables(lineItem, replaceTo) };
|
493
|
-
}
|
494
|
-
else {
|
495
|
-
return { ...replaceTo };
|
496
|
-
}
|
342
|
+
const replaceTransactionItem = (item, replaceTo) => {
|
343
|
+
if (item.id === replaceTo.id) {
|
344
|
+
return { ...replaceTo };
|
497
345
|
}
|
498
346
|
return {
|
499
|
-
...
|
500
|
-
|
347
|
+
...item,
|
348
|
+
children: item.children.map(ti => replaceTransactionItem(ti, replaceTo)),
|
501
349
|
};
|
502
350
|
};
|
503
|
-
const
|
504
|
-
const
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
return cardinalityComputations;
|
509
|
-
};
|
510
|
-
const calculateCardinalityVariables = (lineItems, cardinalityComputations) => {
|
511
|
-
const cardVars = new Map();
|
512
|
-
lineItems
|
513
|
-
.filter(({ port, type }) => !!port && !!type)
|
514
|
-
.forEach(li => {
|
515
|
-
if (cardinalityComputations.get(`${li.port}`)) {
|
516
|
-
const cardinalityVariableName = `#CV-${li.type}@${li.port}`;
|
517
|
-
cardVars.set(cardinalityVariableName, (cardVars.get(cardinalityVariableName) ?? 0) + li.qty);
|
518
|
-
}
|
519
|
-
});
|
520
|
-
return cardVars;
|
351
|
+
const generateTransactionItem = (option, salesTransactionId, qty, parentTi) => {
|
352
|
+
const newItem = generateTransactionItemFromPCM(option, salesTransactionId, parentTi);
|
353
|
+
// propagate Proportional quantities to children
|
354
|
+
const updatedNewItem = updateQuantity(newItem, qty ?? newItem.qty, option, parentTi?.qty);
|
355
|
+
return updatedNewItem;
|
521
356
|
};
|
522
|
-
const
|
523
|
-
const
|
524
|
-
const
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
357
|
+
const generateTransactionItemFromPCM = (option, salesTransactionId, parentTi) => {
|
358
|
+
const childId = UUID.UUID();
|
359
|
+
const newItem = {
|
360
|
+
id: childId,
|
361
|
+
productId: option.id,
|
362
|
+
productName: option.name,
|
363
|
+
productCode: option.productCode,
|
364
|
+
productRelatedComponentId: option.productRelatedComponent?.id,
|
365
|
+
stiAttributes: [],
|
366
|
+
attributes: {
|
367
|
+
ParentReference: salesTransactionId,
|
368
|
+
ItemPath: option.id,
|
369
|
+
SalesTransactionItemSource: childId,
|
370
|
+
SalesTransactionItemParent: salesTransactionId,
|
371
|
+
ProductSellingModel: option.productSellingModelOptions?.[0]?.productSellingModel.id,
|
372
|
+
},
|
373
|
+
qty: option.productRelatedComponent?.quantity ?? 1,
|
374
|
+
};
|
375
|
+
if (parentTi) {
|
376
|
+
newItem.parentId = parentTi.id;
|
377
|
+
}
|
378
|
+
newItem.children = option.productComponentGroups.reduce((acc, group) => {
|
379
|
+
group.components.forEach(component => {
|
380
|
+
if (component.productRelatedComponent?.isComponentRequired ||
|
381
|
+
component.productRelatedComponent?.isDefaultComponent) {
|
382
|
+
acc.push(generateTransactionItemFromPCM(component, salesTransactionId, newItem));
|
534
383
|
}
|
535
|
-
|
536
|
-
|
537
|
-
|
384
|
+
});
|
385
|
+
return acc;
|
386
|
+
}, []);
|
387
|
+
return newItem;
|
388
|
+
};
|
389
|
+
const flattenTransactionItem = (ti) => {
|
390
|
+
const result = [];
|
391
|
+
const traverse = (item) => {
|
392
|
+
if (!item)
|
393
|
+
return;
|
394
|
+
result.push(item);
|
395
|
+
if (Array.isArray(item.children) && item.children.length) {
|
396
|
+
for (const child of item.children) {
|
397
|
+
traverse(child);
|
538
398
|
}
|
539
399
|
}
|
540
|
-
});
|
541
|
-
return {
|
542
|
-
...updated,
|
543
|
-
attributes: upsertAttributes(updated.attributes, [...cardinalityVariables].map(([name, value]) => ({ name, value, cfgStatus: 'Changed' }))),
|
544
400
|
};
|
401
|
+
traverse(ti);
|
402
|
+
return result;
|
545
403
|
};
|
546
|
-
const
|
547
|
-
|
548
|
-
|
549
|
-
const
|
550
|
-
|
551
|
-
|
552
|
-
}
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
return [
|
557
|
-
...acc.filter(attr => attr.name !== name),
|
558
|
-
{ ...(origAttr ?? { name, type: '' }), cfgStatus: origAttr ? 'Changed' : 'User', value },
|
559
|
-
];
|
560
|
-
}, originalAttributes);
|
561
|
-
};
|
562
|
-
const patchAttributes = (rootLineItem, id, attrs, skipCardinalityCalculation = false) => {
|
563
|
-
const lineItem = findLineItem(id, [rootLineItem]);
|
564
|
-
if (!lineItem) {
|
565
|
-
return rootLineItem;
|
566
|
-
}
|
567
|
-
const attributes = upsertAttributes(lineItem.attributes, attrs);
|
568
|
-
return replaceLineItem(rootLineItem, { ...lineItem, attributes }, skipCardinalityCalculation);
|
569
|
-
};
|
570
|
-
const getAttributeValue = (attributes, name) => attributes.find(attr => attr.name === name)?.value;
|
571
|
-
const generateLineItem = (port, type, parentId, attributes = [], lineItems = []) => {
|
572
|
-
return {
|
573
|
-
id: UUID.UUID(),
|
574
|
-
port,
|
575
|
-
type,
|
576
|
-
actionCode: 'ADD',
|
577
|
-
cfgStatus: 'New',
|
578
|
-
attributes: attributes.map(({ name, value }) => ({ cfgStatus: 'User', name, value })),
|
579
|
-
lineItems,
|
580
|
-
parentId,
|
581
|
-
qty: 1,
|
404
|
+
const updateQuantity = (ti, qty, pcm, parentQty = 1) => {
|
405
|
+
const pcmMap = PCMUtils.mapByPrcId(pcm);
|
406
|
+
const calcNewQty = (item, parentPrevQty, parentNewQty, parentPcm, inputQty, isDirectChange) => {
|
407
|
+
const scaleMethod = parentPcm?.productRelatedComponent?.quantityScaleMethod;
|
408
|
+
if (isDirectChange) {
|
409
|
+
return scaleMethod === 'Proportional' ? parentPrevQty * inputQty : inputQty;
|
410
|
+
}
|
411
|
+
else {
|
412
|
+
return scaleMethod === 'Proportional' ? (item.qty / parentPrevQty) * parentNewQty : item.qty;
|
413
|
+
}
|
582
414
|
};
|
583
|
-
|
584
|
-
const
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
return target;
|
600
|
-
};
|
601
|
-
const assetPredicateFn = (lineItem, assetId) => {
|
602
|
-
if (!assetId) {
|
603
|
-
return false;
|
604
|
-
}
|
605
|
-
return lineItem.assetId === assetId || lineItem.openOrderLineItemId === assetId;
|
606
|
-
};
|
607
|
-
const multiplyLineItems = (lineItem, qty, split) => {
|
608
|
-
if (split) {
|
609
|
-
const unifyIds = (lineItem) => ({
|
610
|
-
...lineItem,
|
611
|
-
id: UUID.UUID(),
|
612
|
-
lineItems: lineItem.lineItems.map(unifyIds),
|
613
|
-
});
|
614
|
-
return map$2(new Array(qty), () => unifyIds(lineItem));
|
615
|
-
}
|
616
|
-
else {
|
617
|
-
return [
|
618
|
-
{
|
619
|
-
...lineItem,
|
620
|
-
qty: qty,
|
621
|
-
},
|
622
|
-
];
|
623
|
-
}
|
624
|
-
};
|
625
|
-
const isTechnicalAttribute = (name) => {
|
626
|
-
return name.startsWith('#') || name.startsWith('$');
|
627
|
-
};
|
628
|
-
const filterOutTechnicalAttributes = (attributes) => {
|
629
|
-
return attributes.filter(({ name }) => !isTechnicalAttribute(name));
|
415
|
+
const updateItem = (item, parentPrevQty, parentNewQty, isDirectChange) => {
|
416
|
+
const pcm = pcmMap[item.productRelatedComponentId];
|
417
|
+
let nextQty = item.qty;
|
418
|
+
if (item.id === ti.id || isDirectChange) {
|
419
|
+
nextQty = calcNewQty(item, parentPrevQty, parentNewQty, pcm, qty, true);
|
420
|
+
}
|
421
|
+
else if (parentPrevQty !== parentNewQty) {
|
422
|
+
nextQty = calcNewQty(item, parentPrevQty, parentNewQty, pcm, qty, false);
|
423
|
+
}
|
424
|
+
return {
|
425
|
+
...item,
|
426
|
+
qty: nextQty,
|
427
|
+
children: item.children.map(child => updateItem(child, item.qty, nextQty, false)),
|
428
|
+
};
|
429
|
+
};
|
430
|
+
return updateItem(ti, parentQty, parentQty, false);
|
630
431
|
};
|
631
432
|
|
632
|
-
|
633
|
-
__proto__: null,
|
634
|
-
assetPredicateFn: assetPredicateFn,
|
635
|
-
filterOutTechnicalAttributes: filterOutTechnicalAttributes,
|
636
|
-
findLineItem: findLineItem,
|
637
|
-
findLineItemWithComparator: findLineItemWithComparator,
|
638
|
-
generateLineItem: generateLineItem,
|
639
|
-
getAttributeValue: getAttributeValue,
|
640
|
-
getAttributes: getAttributes,
|
641
|
-
getOriginParent: getOriginParent,
|
642
|
-
getRecommendedPrices: getRecommendedPrices,
|
643
|
-
insertLineItem: insertLineItem,
|
644
|
-
isTechnicalAttribute: isTechnicalAttribute,
|
645
|
-
mapAttributes: mapAttributes,
|
646
|
-
multiplyLineItems: multiplyLineItems,
|
647
|
-
patchAttributes: patchAttributes,
|
648
|
-
recalculateCardinalityVariables: recalculateCardinalityVariables,
|
649
|
-
removeLineItem: removeLineItem,
|
650
|
-
replaceLineItem: replaceLineItem,
|
651
|
-
upsertAttributes: upsertAttributes
|
652
|
-
});
|
653
|
-
|
654
|
-
class LineItemWorker {
|
433
|
+
class TransactionItemWorker {
|
655
434
|
constructor(src) {
|
656
|
-
this.
|
435
|
+
this.ti = { ...src };
|
657
436
|
}
|
658
437
|
insert(parentId, toInsert) {
|
659
|
-
return new
|
438
|
+
return new TransactionItemWorker(insertTransactionItem(this.ti, parentId, toInsert));
|
660
439
|
}
|
661
440
|
remove(id) {
|
662
|
-
return new
|
663
|
-
}
|
664
|
-
replace(toReplace, skipCardinalityCalculation = false) {
|
665
|
-
return new LineItemWorker(replaceLineItem(this.li, toReplace, skipCardinalityCalculation));
|
441
|
+
return new TransactionItemWorker(removeTransactionItem(this.ti, id));
|
666
442
|
}
|
667
|
-
|
668
|
-
return new
|
443
|
+
replace(toReplace) {
|
444
|
+
return new TransactionItemWorker(replaceTransactionItem(this.ti, toReplace));
|
669
445
|
}
|
670
446
|
}
|
671
447
|
|
@@ -677,226 +453,203 @@ function extractMetadata(uiDefinition) {
|
|
677
453
|
]);
|
678
454
|
}
|
679
455
|
|
680
|
-
class
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
while (currentLevel.length && remainingUpdates.length) {
|
685
|
-
currentLevel.forEach(li => {
|
686
|
-
const unhandledUpdates = [];
|
687
|
-
remainingUpdates.forEach(update => {
|
688
|
-
let updated = false;
|
689
|
-
switch (update.dataType) {
|
690
|
-
case 'LINEITEM':
|
691
|
-
updated = this.applyLineItemUpdate(li, update, charges);
|
692
|
-
break;
|
693
|
-
case 'CHARGE':
|
694
|
-
updated = this.applyChargeUpdate(li, update);
|
695
|
-
break;
|
696
|
-
case 'GROUP_CHARGE':
|
697
|
-
updated = this.applyChargeGroupUpdate(li, update);
|
698
|
-
break;
|
699
|
-
default:
|
700
|
-
// Unknown dataType. Do not try to handle it anymore
|
701
|
-
updated = true;
|
702
|
-
}
|
703
|
-
if (!updated) {
|
704
|
-
unhandledUpdates.push(update);
|
705
|
-
}
|
706
|
-
});
|
707
|
-
remainingUpdates = unhandledUpdates;
|
708
|
-
});
|
709
|
-
currentLevel = flatten(currentLevel.map(parent => parent.lineItems));
|
710
|
-
}
|
711
|
-
}
|
712
|
-
delete(lineItems, id) {
|
713
|
-
const idsToRemove = [id];
|
714
|
-
const topLevelLineItem = lineItems.find(li => li.id === id);
|
715
|
-
if (topLevelLineItem) {
|
716
|
-
// find term-related line items (which are only top level)
|
717
|
-
// expired term line items won't be deleted
|
718
|
-
let foundTermLineItem = topLevelLineItem;
|
719
|
-
while (foundTermLineItem) {
|
720
|
-
foundTermLineItem = lineItems.find(li => foundTermLineItem && li.rampInstanceId === foundTermLineItem.id);
|
721
|
-
if (foundTermLineItem) {
|
722
|
-
idsToRemove.push(foundTermLineItem.id);
|
723
|
-
}
|
724
|
-
}
|
725
|
-
}
|
726
|
-
const filtered = lineItems.filter(lineItem => !idsToRemove.includes(lineItem.id));
|
727
|
-
return filtered.map(lineItem => new LineItemWorker(lineItem).remove(id).li);
|
456
|
+
class GuidedSellingService {
|
457
|
+
constructor(orchestrationsApiService) {
|
458
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
459
|
+
this.guidedSellingResult$ = new BehaviorSubject({});
|
728
460
|
}
|
729
|
-
|
730
|
-
|
731
|
-
return false;
|
732
|
-
}
|
733
|
-
switch (update.attributeType) {
|
734
|
-
case 'QTY':
|
735
|
-
lineItem.qty = update.newValue;
|
736
|
-
break;
|
737
|
-
case 'EFFECTIVE_START_DATE':
|
738
|
-
lineItem.properties['StartDate'] = moment(update.newValue).format('YYYY-MM-DD');
|
739
|
-
break;
|
740
|
-
case 'END_DATE':
|
741
|
-
lineItem.properties['EndDate'] = moment(update.newValue).format('YYYY-MM-DD');
|
742
|
-
break;
|
743
|
-
case 'PRICE_ADJUSTMENT':
|
744
|
-
{
|
745
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
746
|
-
if (charge) {
|
747
|
-
charge.priceAdjustment = update.newValue;
|
748
|
-
}
|
749
|
-
}
|
750
|
-
break;
|
751
|
-
case 'LIST_PRICE_ADJUSTMENT':
|
752
|
-
case 'MARGIN_ADJUSTMENT':
|
753
|
-
{
|
754
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
755
|
-
if (charge) {
|
756
|
-
charge.listPriceAdjustment = update.newValue;
|
757
|
-
}
|
758
|
-
}
|
759
|
-
break;
|
760
|
-
case 'COST_ADJUSTMENT':
|
761
|
-
{
|
762
|
-
const charge = lineItem.chargeItems.find(charge => (charges || {})[charge.chargeId]?.main);
|
763
|
-
if (charge) {
|
764
|
-
charge.costAdjustment = update.newValue;
|
765
|
-
}
|
766
|
-
}
|
767
|
-
break;
|
768
|
-
default:
|
769
|
-
throw new Error(`Not suppored AttributeType for LineItem update: ${update.attributeType}`);
|
770
|
-
}
|
771
|
-
return true;
|
461
|
+
get guidedSellingResult() {
|
462
|
+
return this.guidedSellingResult$.value;
|
772
463
|
}
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
throw new Error(`Not suppored AttributeType for Charge Item update: ${update.attributeType}`);
|
786
|
-
}
|
787
|
-
return true;
|
464
|
+
configureGuidedSelling$(data) {
|
465
|
+
return this.orchestrationsApiService
|
466
|
+
.apply$({
|
467
|
+
transactionContext: this.getTransactionContext(data.attributesMap),
|
468
|
+
orchestrationName: data.orchestrationName,
|
469
|
+
})
|
470
|
+
.pipe(map(transactionContext => {
|
471
|
+
const guidedSellingNode = transactionContext.nodes['GuidedSelling']?.[0];
|
472
|
+
const guidedSellingResult = guidedSellingNode?.attributes?.['result'] || {};
|
473
|
+
this.guidedSellingResult$.next(guidedSellingResult);
|
474
|
+
return guidedSellingResult;
|
475
|
+
}));
|
788
476
|
}
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
477
|
+
clearGuidedSelling$() {
|
478
|
+
this.guidedSellingResult$.next({});
|
479
|
+
}
|
480
|
+
getTransactionContext(guidedSellingAttributes) {
|
481
|
+
const testTransaction = {
|
482
|
+
id: UUID.UUID(),
|
483
|
+
businessObjectType: 'Quote',
|
484
|
+
salesTransactionItems: [],
|
485
|
+
attributes: {},
|
486
|
+
};
|
487
|
+
return {
|
488
|
+
salesTransaction: testTransaction,
|
489
|
+
transactionId: UUID.UUID(),
|
490
|
+
businessObjectType: 'Quote',
|
491
|
+
nodes: {
|
492
|
+
GuidedSelling: [
|
493
|
+
{
|
494
|
+
id: UUID.UUID(),
|
495
|
+
attributes: {},
|
496
|
+
nodes: {},
|
497
|
+
properties: { guidedSellingAttributes },
|
498
|
+
},
|
499
|
+
],
|
500
|
+
},
|
501
|
+
id: UUID.UUID(),
|
502
|
+
attributes: {},
|
503
|
+
};
|
804
504
|
}
|
805
505
|
}
|
806
|
-
|
807
|
-
|
808
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
506
|
+
GuidedSellingService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: GuidedSellingService, deps: [{ token: i1.OrchestrationsApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
507
|
+
GuidedSellingService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: GuidedSellingService });
|
508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: GuidedSellingService, decorators: [{
|
809
509
|
type: Injectable
|
810
|
-
}] });
|
510
|
+
}], ctorParameters: function () { return [{ type: i1.OrchestrationsApiService }]; } });
|
811
511
|
|
812
|
-
class
|
813
|
-
constructor(
|
814
|
-
// private quoteDraftService: QuoteDraftService,
|
815
|
-
salesTransactionService, updateService, configurationService, flowInfoService) {
|
816
|
-
this.proceduresApiService = proceduresApiService;
|
817
|
-
this.salesTransactionService = salesTransactionService;
|
818
|
-
this.updateService = updateService;
|
819
|
-
this.configurationService = configurationService;
|
512
|
+
class ConfigurationService {
|
513
|
+
constructor(flowInfoService, messageService, configurationRuntimeService, salesTransactionService, orchestrationsApiService, guidedSellingService) {
|
820
514
|
this.flowInfoService = flowInfoService;
|
821
|
-
this.
|
822
|
-
this.
|
515
|
+
this.messageService = messageService;
|
516
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
517
|
+
this.salesTransactionService = salesTransactionService;
|
518
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
519
|
+
this.guidedSellingService = guidedSellingService;
|
520
|
+
this.hasUnsavedChanges = false;
|
521
|
+
this.configurationStateSubj$ = new BehaviorSubject(null);
|
522
|
+
this.previousConfigurationStateSubj$ = new BehaviorSubject(null);
|
523
|
+
this.isLoadingSubj$ = new BehaviorSubject(false);
|
524
|
+
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
823
525
|
}
|
824
|
-
|
825
|
-
return this.
|
526
|
+
get state$() {
|
527
|
+
return this.configurationStateSubj$.asObservable().pipe(filter$1(isDefined));
|
826
528
|
}
|
827
|
-
|
828
|
-
this.
|
529
|
+
get state() {
|
530
|
+
return this.configurationStateSubj$.getValue();
|
829
531
|
}
|
830
|
-
|
831
|
-
|
832
|
-
const initialCurrentState = this.salesTransactionService.getInitialCurrentState();
|
833
|
-
const currentState = state?.salesTransactionItems ?? [];
|
834
|
-
const currentLineItemIndex = currentState.findIndex(({ id }) => id === lineItemId);
|
835
|
-
const currentLineItem = currentState[currentLineItemIndex];
|
836
|
-
const initialLineItem = initialCurrentState.find(({ integrationId }) => integrationId === currentLineItem?.integrationId);
|
837
|
-
if (!state || !currentLineItem || !initialLineItem) {
|
838
|
-
return of(null);
|
839
|
-
}
|
840
|
-
const updatedState = cloneDeep(currentState);
|
841
|
-
updatedState.splice(currentLineItemIndex, 1, initialLineItem);
|
842
|
-
return of([]).pipe(tap$1(() => {
|
843
|
-
this.salesTransactionService.setState({ ...state, salesTransactionItems: updatedState });
|
844
|
-
}), switchMap(() => this.calculate$({ ...state, salesTransactionItems: updatedState })), map$1(() => this.salesTransactionService.state), tap$1(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
532
|
+
get previousState() {
|
533
|
+
return this.previousConfigurationStateSubj$.getValue();
|
845
534
|
}
|
846
|
-
|
847
|
-
this.
|
535
|
+
get root$() {
|
536
|
+
return this.state$.pipe(map$1(state => state.salesTransaction.salesTransactionItems[0]), filter$1(isDefined));
|
848
537
|
}
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
538
|
+
get root() {
|
539
|
+
return this.configurationStateSubj$.getValue()?.salesTransaction.salesTransactionItems[0] ?? null;
|
540
|
+
}
|
541
|
+
reset() {
|
542
|
+
this.hasUnsavedChanges = false;
|
543
|
+
this.configurationStateSubj$.next(null);
|
544
|
+
this.previousConfigurationStateSubj$.next(null);
|
545
|
+
}
|
546
|
+
init$() {
|
547
|
+
const { state } = this.salesTransactionService;
|
548
|
+
const { standalone } = this.flowInfoService.flow.properties;
|
549
|
+
const { productId, transactionItemId, newProductQty } = this.flowInfoService.context;
|
550
|
+
if (!state || !productId) {
|
551
|
+
return of(undefined);
|
552
|
+
}
|
553
|
+
const salesTransactionItems = state?.salesTransaction.salesTransactionItems ?? [];
|
554
|
+
let isRootGenerated = false;
|
555
|
+
let transactionItem = salesTransactionItems.find(item => item.id === transactionItemId);
|
556
|
+
if (!transactionItem && standalone) {
|
557
|
+
transactionItem = salesTransactionItems.find(item => item.productId === productId);
|
558
|
+
}
|
559
|
+
if (!transactionItem) {
|
560
|
+
const quantity = typeof newProductQty === 'number' && newProductQty > 0 ? newProductQty : undefined;
|
561
|
+
transactionItem = generateTransactionItem(this.getPCMModel(), this.state?.salesTransaction.id, quantity);
|
562
|
+
isRootGenerated = true;
|
563
|
+
}
|
564
|
+
const guidedSellingResult = this.guidedSellingService.guidedSellingResult;
|
565
|
+
if (transactionItem && Object.keys(guidedSellingResult).length && isRootGenerated) {
|
566
|
+
transactionItem.stiAttributes = Object.entries(guidedSellingResult).map(([attributeName, value]) => ({
|
567
|
+
attributeName,
|
568
|
+
value,
|
569
|
+
}));
|
853
570
|
}
|
854
|
-
|
571
|
+
const configurationState = {
|
572
|
+
...state,
|
573
|
+
salesTransaction: {
|
574
|
+
...state.salesTransaction,
|
575
|
+
salesTransactionItems: transactionItem ? [transactionItem] : [],
|
576
|
+
},
|
577
|
+
};
|
578
|
+
return (isRootGenerated ? this.configure$(configurationState) : of(configurationState)).pipe(tap$1(configurationState => {
|
579
|
+
this.configurationStateSubj$.next(configurationState);
|
580
|
+
this.previousConfigurationStateSubj$.next(configurationState);
|
581
|
+
}), map$1(noop));
|
855
582
|
}
|
856
|
-
|
857
|
-
this
|
583
|
+
patch$(transactionItem) {
|
584
|
+
const { state, root } = this;
|
585
|
+
if (!state) {
|
586
|
+
return throwError(() => new Error(`Configuration State is not initialized`));
|
587
|
+
}
|
588
|
+
if (!root) {
|
589
|
+
return throwError(() => new Error(`Root SalesTransactionItem not found`));
|
590
|
+
}
|
591
|
+
const newRoot = new TransactionItemWorker(root).replace(transactionItem).ti;
|
592
|
+
const newTransactionContext = {
|
593
|
+
...state,
|
594
|
+
salesTransaction: {
|
595
|
+
...state.salesTransaction,
|
596
|
+
salesTransactionItems: [newRoot],
|
597
|
+
},
|
598
|
+
};
|
599
|
+
return this.configure$(newTransactionContext).pipe(catchError(error => {
|
600
|
+
console.error(error);
|
601
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
602
|
+
this.messageService.add({ severity: 'error', summary: error });
|
603
|
+
}
|
604
|
+
return throwError(() => error);
|
605
|
+
}), tap$1(() => {
|
606
|
+
if (!this.hasUnsavedChanges) {
|
607
|
+
this.hasUnsavedChanges = true;
|
608
|
+
}
|
609
|
+
}), map$1(noop));
|
858
610
|
}
|
859
|
-
|
860
|
-
|
861
|
-
return of(this.salesTransactionService.state);
|
611
|
+
patch(transactionItem) {
|
612
|
+
this.patch$(transactionItem).subscribe();
|
862
613
|
}
|
863
|
-
|
864
|
-
|
865
|
-
return
|
614
|
+
configure$(transactionContext) {
|
615
|
+
this.isLoadingSubj$.next(true);
|
616
|
+
return this.justConfigureRequest$(transactionContext).pipe(tap$1(result => {
|
617
|
+
this.configurationStateSubj$.next(result);
|
618
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(result));
|
619
|
+
}), catchError(e => {
|
620
|
+
const resetState = this.previousConfigurationStateSubj$.getValue();
|
621
|
+
if (resetState) {
|
622
|
+
this.previousConfigurationStateSubj$.next(cloneDeep(resetState));
|
623
|
+
this.configurationStateSubj$.next(resetState);
|
624
|
+
}
|
625
|
+
return throwError(() => e);
|
626
|
+
}), finalize(() => this.isLoadingSubj$.next(false)));
|
866
627
|
}
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
// bounce back if configuration call has failed
|
872
|
-
const state = this.salesTransactionService.state;
|
873
|
-
if (state) {
|
874
|
-
this.salesTransactionService.setState(state);
|
875
|
-
this.updatedSubj$.next();
|
876
|
-
}
|
877
|
-
return throwError(() => error);
|
878
|
-
}));
|
628
|
+
justConfigureRequest$(transactionContext) {
|
629
|
+
const request = {
|
630
|
+
transactionContext,
|
631
|
+
flowId: this.flowInfoService.flow.id,
|
879
632
|
};
|
633
|
+
return this.orchestrationsApiService.apply$(request).pipe(catchError(error => throwError(() => {
|
634
|
+
if (error.error) {
|
635
|
+
return extractErrorDetails(error.error).join('. ');
|
636
|
+
}
|
637
|
+
return error.message || JSON.stringify(error);
|
638
|
+
})));
|
639
|
+
}
|
640
|
+
getPCMModel() {
|
641
|
+
const pcmModel = this.configurationRuntimeService.pcmModel;
|
642
|
+
if (!pcmModel) {
|
643
|
+
throw new Error('PCM model not initialized');
|
644
|
+
}
|
645
|
+
return pcmModel;
|
880
646
|
}
|
881
647
|
}
|
882
|
-
|
883
|
-
|
884
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
648
|
+
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 }, { token: GuidedSellingService }], target: i0.ɵɵFactoryTarget.Injectable });
|
649
|
+
ConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService });
|
650
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationService, decorators: [{
|
885
651
|
type: Injectable
|
886
|
-
}], ctorParameters: function () { return [{ type: i2.
|
887
|
-
|
888
|
-
class FlowConfigurationModule {
|
889
|
-
}
|
890
|
-
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
891
|
-
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
892
|
-
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService, FlowUpdateService], imports: [ApiModule] });
|
893
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
894
|
-
type: NgModule,
|
895
|
-
args: [{
|
896
|
-
imports: [ApiModule],
|
897
|
-
providers: [FlowConfigurationService, FlowUpdateService],
|
898
|
-
}]
|
899
|
-
}] });
|
652
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i2.MessageService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: i1.OrchestrationsApiService }, { type: GuidedSellingService }]; } });
|
900
653
|
|
901
654
|
class SalesTransactionService {
|
902
655
|
get isInitialized$() {
|
@@ -908,7 +661,7 @@ class SalesTransactionService {
|
|
908
661
|
set hasUnsavedChanges(value) {
|
909
662
|
this.hasUnsavedChangesSubj$.next(value);
|
910
663
|
if (!this.hasUnsavedChanges) {
|
911
|
-
this.
|
664
|
+
this.initialState = this.state?.salesTransaction.salesTransactionItems ?? [];
|
912
665
|
}
|
913
666
|
}
|
914
667
|
get hasUnsavedChanges() {
|
@@ -917,18 +670,25 @@ class SalesTransactionService {
|
|
917
670
|
get state() {
|
918
671
|
return this.stateSubj$.getValue();
|
919
672
|
}
|
920
|
-
|
921
|
-
this.
|
673
|
+
get hasProducts() {
|
674
|
+
return Boolean(this.state?.salesTransaction.salesTransactionItems.length);
|
675
|
+
}
|
676
|
+
constructor(salesTransactionApiService) {
|
922
677
|
this.salesTransactionApiService = salesTransactionApiService;
|
923
678
|
this.stateSubj$ = new BehaviorSubject(null);
|
924
679
|
this.isInitializedSubj$ = new BehaviorSubject(false);
|
925
680
|
this.hasUnsavedChangesSubj$ = new BehaviorSubject(false);
|
926
|
-
this.
|
681
|
+
this.initialState = [];
|
927
682
|
this.hasUnsavedChanges$ = this.hasUnsavedChangesSubj$.asObservable();
|
928
683
|
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
929
684
|
}
|
930
685
|
init(headerId, params) {
|
931
|
-
return this.salesTransactionApiService.
|
686
|
+
return this.salesTransactionApiService.query(headerId, params).pipe(tap(res => {
|
687
|
+
if (!res.salesTransaction) {
|
688
|
+
throw new Error('SalesTransaction is not defined. Please check Query Orchestration.');
|
689
|
+
}
|
690
|
+
this.stateSubj$.next(res);
|
691
|
+
}));
|
932
692
|
}
|
933
693
|
finalizeInit() {
|
934
694
|
this.isInitializedSubj$.next(true);
|
@@ -939,27 +699,182 @@ class SalesTransactionService {
|
|
939
699
|
this.isInitializedSubj$.next(false);
|
940
700
|
this.hasUnsavedChangesSubj$.next(false);
|
941
701
|
}
|
942
|
-
|
943
|
-
return this.
|
702
|
+
getInitialState() {
|
703
|
+
return this.initialState;
|
944
704
|
}
|
945
705
|
setState(state) {
|
946
706
|
this.stateSubj$.next(state);
|
947
707
|
}
|
948
708
|
}
|
949
|
-
SalesTransactionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, deps: [{ token:
|
709
|
+
SalesTransactionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, deps: [{ token: i1.SalesTransactionApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
950
710
|
SalesTransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService });
|
951
711
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SalesTransactionService, decorators: [{
|
952
712
|
type: Injectable
|
953
|
-
}], ctorParameters: function () { return [{ type:
|
713
|
+
}], ctorParameters: function () { return [{ type: i1.SalesTransactionApiService }]; } });
|
954
714
|
|
955
|
-
class
|
956
|
-
constructor(salesTransactionService, flowInfoService
|
715
|
+
class FlowConfigurationService {
|
716
|
+
constructor(orchestrationsApiService, salesTransactionService, flowInfoService) {
|
717
|
+
this.orchestrationsApiService = orchestrationsApiService;
|
957
718
|
this.salesTransactionService = salesTransactionService;
|
958
719
|
this.flowInfoService = flowInfoService;
|
720
|
+
this.updatedSubj$ = new Subject();
|
721
|
+
this.updated$ = this.updatedSubj$.asObservable();
|
722
|
+
}
|
723
|
+
calculate$(state) {
|
724
|
+
return this.orchestrationsApiService
|
725
|
+
.apply$({ transactionContext: state, flowId: this.flowInfoService.flow.id })
|
726
|
+
.pipe(tap(result => this.salesTransactionService.setState(result)), map(noop));
|
727
|
+
}
|
728
|
+
calculate(state) {
|
729
|
+
this.calculate$(state).subscribe();
|
730
|
+
}
|
731
|
+
revert$(transactionItemId) {
|
732
|
+
const state = this.salesTransactionService.state;
|
733
|
+
const initialState = this.salesTransactionService.getInitialState();
|
734
|
+
const currentState = state?.salesTransaction.salesTransactionItems ?? [];
|
735
|
+
const currentItemIndex = currentState.findIndex(({ id }) => id === transactionItemId);
|
736
|
+
const currentItem = currentState[currentItemIndex];
|
737
|
+
const initialItem = initialState.find(({ integrationId }) => integrationId === currentItem?.integrationId);
|
738
|
+
if (!state || !currentItem || !initialItem) {
|
739
|
+
return of(null);
|
740
|
+
}
|
741
|
+
const updatedState = cloneDeep(currentState);
|
742
|
+
updatedState.splice(currentItemIndex, 1, initialItem);
|
743
|
+
return of([]).pipe(map(() => ({
|
744
|
+
...state,
|
745
|
+
salesTransaction: { ...state.salesTransaction, salesTransactionItems: updatedState },
|
746
|
+
})), tap(newState => this.salesTransactionService.setState(newState)), switchMap(newState => this.calculate$(newState)), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
747
|
+
}
|
748
|
+
revert(transactionItemId) {
|
749
|
+
this.revert$(transactionItemId).subscribe();
|
750
|
+
}
|
751
|
+
delete$(ids) {
|
752
|
+
const state = this.salesTransactionService.state;
|
753
|
+
if (!state) {
|
754
|
+
return of(null);
|
755
|
+
}
|
756
|
+
return of([]).pipe(map(() => state.salesTransaction.salesTransactionItems.filter(({ id }) => !ids.includes(id))), switchMap(updatedState => this.calculate$({
|
757
|
+
...state,
|
758
|
+
salesTransaction: { ...state.salesTransaction, salesTransactionItems: updatedState },
|
759
|
+
})), map(() => this.salesTransactionService.state), tap(() => this.updatedSubj$.next()), this.handleErrorAndBounceBack());
|
760
|
+
}
|
761
|
+
delete(ids) {
|
762
|
+
this.delete$(ids).subscribe();
|
763
|
+
}
|
764
|
+
handleErrorAndBounceBack() {
|
765
|
+
return (source$) => {
|
766
|
+
return source$.pipe(catchError$1(error => {
|
767
|
+
console.error(error);
|
768
|
+
// bounce back if configuration call has failed
|
769
|
+
const state = this.salesTransactionService.state;
|
770
|
+
if (state) {
|
771
|
+
this.salesTransactionService.setState(state);
|
772
|
+
this.updatedSubj$.next();
|
773
|
+
}
|
774
|
+
return throwError(() => error);
|
775
|
+
}));
|
776
|
+
};
|
777
|
+
}
|
778
|
+
}
|
779
|
+
FlowConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, deps: [{ token: i1.OrchestrationsApiService }, { token: SalesTransactionService }, { token: FlowInfoService }], target: i0.ɵɵFactoryTarget.Injectable });
|
780
|
+
FlowConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService });
|
781
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationService, decorators: [{
|
782
|
+
type: Injectable
|
783
|
+
}], ctorParameters: function () { return [{ type: i1.OrchestrationsApiService }, { type: SalesTransactionService }, { type: FlowInfoService }]; } });
|
784
|
+
|
785
|
+
class TestModeConfigurationService {
|
786
|
+
constructor(flowInfoService, configurationService, configurationRuntimeService, salesTransactionService, runtimeSettingsService, sfApiService) {
|
787
|
+
this.flowInfoService = flowInfoService;
|
788
|
+
this.configurationService = configurationService;
|
789
|
+
this.configurationRuntimeService = configurationRuntimeService;
|
790
|
+
this.salesTransactionService = salesTransactionService;
|
791
|
+
this.runtimeSettingsService = runtimeSettingsService;
|
792
|
+
this.sfApiService = sfApiService;
|
793
|
+
this.isInitialized = false;
|
794
|
+
}
|
795
|
+
initTestMode$(uiDefinitionContainer, options) {
|
796
|
+
this.configurationRuntimeService.uiDefinitionContainer = uiDefinitionContainer;
|
797
|
+
if (this.checkInitialized(uiDefinitionContainer)) {
|
798
|
+
this.configurationRuntimeService.pcmModel = this.pcmModel;
|
799
|
+
return of(undefined);
|
800
|
+
}
|
801
|
+
this.configurationService.reset();
|
802
|
+
const { productId, quoteId, flowId } = uiDefinitionContainer.source.properties ?? {};
|
803
|
+
if (!productId) {
|
804
|
+
return throwError(() => 'Unable to start the Configuration Preview: Product is missing.');
|
805
|
+
}
|
806
|
+
if (!quoteId) {
|
807
|
+
return throwError(() => `Unable to start the Configuration Preview: Quote is missing.`);
|
808
|
+
}
|
809
|
+
if (!flowId) {
|
810
|
+
return throwError(() => `Unable to start the Configuration Preview: Flow is missing.`);
|
811
|
+
}
|
812
|
+
return this.runtimeSettingsService.create().pipe(switchMap(() => this.flowInfoService.init$(flowId, { productId, headerId: quoteId, testMode: true })), switchMap(() => this.configurationRuntimeService.init$({ productId })), tap(pcmModel => (this.pcmModel = pcmModel)), switchMap(() => {
|
813
|
+
if (options?.customizationMode) {
|
814
|
+
return of(undefined);
|
815
|
+
}
|
816
|
+
return this.initConfiguration$(quoteId);
|
817
|
+
}), tap(() => (this.isInitialized = true)), map(noop));
|
818
|
+
}
|
819
|
+
initConfiguration$(quoteId) {
|
820
|
+
return this.getPriceBookId(quoteId).pipe(map(priceBookId => this.getTestTransactionContext(quoteId, priceBookId)), tap(state => this.salesTransactionService.setState(state)), switchMap(() => this.configurationService.init$()), switchMap(() => this.configurationService.state
|
821
|
+
? this.configurationService.configure$(this.configurationService.state)
|
822
|
+
: of(undefined)), map(noop));
|
823
|
+
}
|
824
|
+
getPriceBookId(quoteId) {
|
825
|
+
return this.sfApiService
|
826
|
+
.query({ count: 1, fields: ['Pricebook2Id'], rawCondition: `Id = '${quoteId}'` }, 'Quote')
|
827
|
+
.pipe(map(r => r?.[0]?.Pricebook2Id ?? null));
|
828
|
+
}
|
829
|
+
getTestTransactionContext(quoteId, priceBookId) {
|
830
|
+
const dateStr = new Date().toISOString().split('T')[0] ?? '';
|
831
|
+
const testTransaction = {
|
832
|
+
id: quoteId,
|
833
|
+
businessObjectType: 'Quote',
|
834
|
+
salesTransactionItems: [],
|
835
|
+
salesTransactionName: 'Test Quote',
|
836
|
+
account: '',
|
837
|
+
quoteAccount: '',
|
838
|
+
pricebook: '',
|
839
|
+
status: 'Draft',
|
840
|
+
totalAmount: 0,
|
841
|
+
subtotal: 0,
|
842
|
+
activatedDate: dateStr,
|
843
|
+
effectiveDate: dateStr,
|
844
|
+
startDate: dateStr,
|
845
|
+
attributes: {},
|
846
|
+
nodes: {},
|
847
|
+
};
|
848
|
+
if (priceBookId) {
|
849
|
+
testTransaction.pricebook = priceBookId;
|
850
|
+
}
|
851
|
+
return {
|
852
|
+
salesTransaction: testTransaction,
|
853
|
+
transactionId: quoteId,
|
854
|
+
businessObjectType: 'Quote',
|
855
|
+
nodes: {},
|
856
|
+
id: UUID.UUID(),
|
857
|
+
attributes: {},
|
858
|
+
};
|
859
|
+
}
|
860
|
+
checkInitialized(uiDefinitionContainer) {
|
861
|
+
return this.isInitialized && !!uiDefinitionContainer.source.properties?.persistTestState;
|
862
|
+
}
|
863
|
+
}
|
864
|
+
TestModeConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService, deps: [{ token: FlowInfoService }, { token: ConfigurationService }, { token: ConfigurationRuntimeService }, { token: SalesTransactionService }, { token: RuntimeSettingsService }, { token: i1.SalesforceApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
865
|
+
TestModeConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService });
|
866
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: TestModeConfigurationService, decorators: [{
|
867
|
+
type: Injectable
|
868
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: ConfigurationService }, { type: ConfigurationRuntimeService }, { type: SalesTransactionService }, { type: RuntimeSettingsService }, { type: i1.SalesforceApiService }]; } });
|
869
|
+
|
870
|
+
class FlowStateService {
|
871
|
+
constructor(flowConfiguration, flowInfoService, flowStateApiService, processorsApiService, salesTransactionApiService, salesTransactionService, toastService, customizationService) {
|
959
872
|
this.flowConfiguration = flowConfiguration;
|
960
|
-
this.
|
873
|
+
this.flowInfoService = flowInfoService;
|
961
874
|
this.flowStateApiService = flowStateApiService;
|
875
|
+
this.processorsApiService = processorsApiService;
|
962
876
|
this.salesTransactionApiService = salesTransactionApiService;
|
877
|
+
this.salesTransactionService = salesTransactionService;
|
963
878
|
this.toastService = toastService;
|
964
879
|
this.customizationService = customizationService;
|
965
880
|
this.NOT_INITIALIZED = Symbol();
|
@@ -976,48 +891,22 @@ class FlowStateService {
|
|
976
891
|
this.cleanup$ = new Subject();
|
977
892
|
this.statefulExecutionRequest$ = this.initBufferedRequest$();
|
978
893
|
/*
|
979
|
-
In stateless mode watch
|
980
|
-
all subscriptions get their updates according to updated
|
894
|
+
In stateless mode watch State changes and call executeRequest so that
|
895
|
+
all subscriptions get their updates according to updated State
|
981
896
|
*/
|
982
897
|
this.isInitialized$()
|
983
|
-
.pipe(filter(Boolean), filter(() => !this.
|
898
|
+
.pipe(filter(Boolean), filter(() => !this.flowInfoService.flow.properties.stateful), switchMap(() => this.flowConfiguration.updated$), switchMap(() => this.executeRequest$({}, true)))
|
984
899
|
.subscribe();
|
985
|
-
this.charges$ = this.flowInfoService.isFlowEngineInitialized$.pipe(filter(Boolean), switchMap(() => {
|
986
|
-
return this.subscribe$(UITemplateType.FLOW_ENGINE, 'CHARGES', null, {
|
987
|
-
cold: true,
|
988
|
-
}).pipe(map$1(response => (response.success ? response.result : {})));
|
989
|
-
}), shareReplay(1));
|
990
|
-
this.charges$.subscribe();
|
991
|
-
this.pricePlans$ = this.flowInfoService.isFlowEngineInitialized$.pipe(filter(Boolean), switchMap(() => {
|
992
|
-
return this.subscribe$(UITemplateType.FLOW_ENGINE, 'PRICE_PLANS', null, {
|
993
|
-
cold: true,
|
994
|
-
}).pipe(map$1(response => (response.success ? response.result : {})));
|
995
|
-
}), shareReplay(1));
|
996
|
-
this.pricePlans$.subscribe();
|
997
|
-
this.activeMetrics$ = this.flowInfoService.isFlowEngineInitialized$.pipe(filter(Boolean), switchMap(() => {
|
998
|
-
return this.subscribe$(UITemplateType.FLOW_ENGINE, 'ACTIVE_METRICS', null, {
|
999
|
-
cold: true,
|
1000
|
-
}).pipe(map$1(response => (response.success ? response.result : [])));
|
1001
|
-
}), shareReplay(1));
|
1002
|
-
this.activeMetrics$.subscribe();
|
1003
|
-
this.isPriceListLocked$ = this.flowInfoService.isFlowEngineInitialized$.pipe(filter(Boolean), switchMap(() => {
|
1004
|
-
return this.subscribe$(UITemplateType.FLOW_ENGINE, 'IS_PRICE_LIST_LOCKED', null, {
|
1005
|
-
cold: true,
|
1006
|
-
}).pipe(map$1(response => (response.success ? response.result : false)));
|
1007
|
-
}), shareReplay(1));
|
1008
|
-
this.isPriceListLocked$.subscribe();
|
1009
900
|
}
|
1010
901
|
init$() {
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
}
|
1018
|
-
}));
|
902
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
903
|
+
return this.initProcessors$().pipe(switchMap(() => this.initStateful$()));
|
904
|
+
}
|
905
|
+
else {
|
906
|
+
return forkJoin([this.initStateless$(), this.initProcessors$()]).pipe(map(noop));
|
907
|
+
}
|
1019
908
|
}
|
1020
|
-
|
909
|
+
reset() {
|
1021
910
|
Object.values(this.subscriptions).forEach(({ data$ }) => data$.complete());
|
1022
911
|
this.subscriptions = {};
|
1023
912
|
if (this.stateId$.value) {
|
@@ -1029,7 +918,7 @@ class FlowStateService {
|
|
1029
918
|
this.cleanup$.next();
|
1030
919
|
}
|
1031
920
|
get hasUnsavedChanges() {
|
1032
|
-
return this.
|
921
|
+
return this.flowInfoService.flow.properties.stateful
|
1033
922
|
? Array.from(this.trackedStatefulChangesMap.values()).some(Boolean)
|
1034
923
|
: this.salesTransactionService.hasUnsavedChanges;
|
1035
924
|
}
|
@@ -1040,14 +929,14 @@ class FlowStateService {
|
|
1040
929
|
return this.executionInProgress$.asObservable();
|
1041
930
|
}
|
1042
931
|
isInitialized$() {
|
1043
|
-
return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map
|
932
|
+
return combineLatest([this.stateId$, this.salesTransactionService.isInitialized$]).pipe(map(values => values.some(Boolean)));
|
1044
933
|
}
|
1045
934
|
isInitialized() {
|
1046
935
|
return Boolean(this.stateId$.value) || this.salesTransactionService.isInitialized;
|
1047
936
|
}
|
1048
937
|
execute$(scope, exec) {
|
1049
938
|
const request = this.execToRequest(scope, exec);
|
1050
|
-
return this.executeRequest$(request).pipe(map
|
939
|
+
return this.executeRequest$(request).pipe(map(result => {
|
1051
940
|
// Keep only requested results
|
1052
941
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
1053
942
|
if (exec.selectors?.[requestId]) {
|
@@ -1063,7 +952,7 @@ class FlowStateService {
|
|
1063
952
|
actions: [{ name: action, inputData }],
|
1064
953
|
};
|
1065
954
|
const request = this.execToRequest(scope, exec);
|
1066
|
-
return this.executeRequest$(request).pipe(map
|
955
|
+
return this.executeRequest$(request).pipe(map(noop));
|
1067
956
|
}
|
1068
957
|
select$(scope, selectorName, inputData) {
|
1069
958
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -1075,7 +964,7 @@ class FlowStateService {
|
|
1075
964
|
},
|
1076
965
|
},
|
1077
966
|
});
|
1078
|
-
return this.executeRequest$(request).pipe(map
|
967
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
1079
968
|
}
|
1080
969
|
subscribe$(scope, selectorName, inputData, options) {
|
1081
970
|
const requestId = this.generateRequestId(scope, selectorName, inputData);
|
@@ -1101,16 +990,16 @@ class FlowStateService {
|
|
1101
990
|
this.executeRequest$(request).subscribe();
|
1102
991
|
}
|
1103
992
|
}
|
1104
|
-
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map
|
993
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), finalize$1(() => {
|
1105
994
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
1106
995
|
delete this.subscriptions[requestId];
|
1107
996
|
}
|
1108
997
|
}));
|
1109
998
|
}
|
1110
999
|
save$() {
|
1111
|
-
if (this.
|
1000
|
+
if (this.flowInfoService.flow.properties.stateful) {
|
1112
1001
|
if (this.stateId$.value) {
|
1113
|
-
return this.flowStateApiService.save(this.stateId$.value).pipe(map
|
1002
|
+
return this.flowStateApiService.save(this.stateId$.value).pipe(map(({ quoteId }) => ({ id: quoteId })), tap(() => {
|
1114
1003
|
Array.from(this.trackedStatefulChangesMap.keys()).forEach(key => {
|
1115
1004
|
this.trackedStatefulChangesMap.set(key, false);
|
1116
1005
|
});
|
@@ -1120,21 +1009,11 @@ class FlowStateService {
|
|
1120
1009
|
else {
|
1121
1010
|
const state = this.salesTransactionService.state;
|
1122
1011
|
if (state) {
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
submit$() {
|
1129
|
-
if (this.getFlowSafe().properties.stateful) {
|
1130
|
-
if (this.stateId$.value) {
|
1131
|
-
return this.flowStateApiService.submit(this.stateId$.value).pipe(map$1(({ quoteId }) => ({ id: quoteId })));
|
1132
|
-
}
|
1133
|
-
}
|
1134
|
-
else {
|
1135
|
-
const state = this.salesTransactionService.state;
|
1136
|
-
if (state) {
|
1137
|
-
return this.salesTransactionApiService.submit(state);
|
1012
|
+
const request = {
|
1013
|
+
transactionContext: state,
|
1014
|
+
flowId: this.flowInfoService.flow.id,
|
1015
|
+
};
|
1016
|
+
return this.salesTransactionApiService.save(request).pipe(map(id => ({ id })));
|
1138
1017
|
}
|
1139
1018
|
}
|
1140
1019
|
return of({ id: '' });
|
@@ -1175,10 +1054,10 @@ class FlowStateService {
|
|
1175
1054
|
fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
|
1176
1055
|
}
|
1177
1056
|
}
|
1178
|
-
const execution$ = this.
|
1057
|
+
const execution$ = this.flowInfoService.flow.properties.stateful
|
1179
1058
|
? this.executeStateful$(fullRequest)
|
1180
1059
|
: this.executeStateless$(fullRequest);
|
1181
|
-
return execution$.pipe(tap
|
1060
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
1182
1061
|
}
|
1183
1062
|
handleSelectorsResponse(selectors) {
|
1184
1063
|
Object.entries(selectors).forEach(([requestId, selectorResult]) => {
|
@@ -1207,7 +1086,7 @@ class FlowStateService {
|
|
1207
1086
|
selectorsOverride: processors?.filter(processor => processor.type === ConfigurationProcessorTypes.SELECTOR),
|
1208
1087
|
selectors: selectors,
|
1209
1088
|
})
|
1210
|
-
.pipe(map
|
1089
|
+
.pipe(map(({ stateId, selectors }) => {
|
1211
1090
|
this.handleSelectorsResponse(selectors);
|
1212
1091
|
this.stateId$.next(stateId);
|
1213
1092
|
}));
|
@@ -1227,7 +1106,7 @@ class FlowStateService {
|
|
1227
1106
|
};
|
1228
1107
|
this.executionInProgress$.next(true);
|
1229
1108
|
return this.flowStateApiService.execute(this.stateId$.value, request);
|
1230
|
-
}), tap
|
1109
|
+
}), tap(({ stateId }) => this.stateId$.next(stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
1231
1110
|
this.executionInProgress$.next(false);
|
1232
1111
|
return throwError(() => e);
|
1233
1112
|
}));
|
@@ -1237,20 +1116,15 @@ class FlowStateService {
|
|
1237
1116
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
1238
1117
|
combineLatest([
|
1239
1118
|
this.statefulExecutionRequest$,
|
1240
|
-
of(undefined).pipe(tap
|
1241
|
-
])), map
|
1119
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1120
|
+
])), map(([response]) => response), take(1));
|
1242
1121
|
}
|
1243
1122
|
initStateless$() {
|
1244
|
-
return this.salesTransactionService.init(this.flowInfoService.context.headerId, this.flowInfoService.context).pipe(
|
1245
|
-
const assets = this.salesTransactionService.state?.assets;
|
1246
|
-
if (assets) {
|
1247
|
-
this.flowStore = { ...this.flowStore, assets };
|
1248
|
-
}
|
1249
|
-
}), switchMap(state => this.flowConfiguration.calculate$(state)), tap$1(() => this.salesTransactionService.finalizeInit()), map$1(noop));
|
1123
|
+
return this.salesTransactionService.init(this.flowInfoService.context.headerId, this.flowInfoService.context).pipe(switchMap(state => this.flowConfiguration.calculate$(state)), tap(() => this.salesTransactionService.finalizeInit()), map(noop));
|
1250
1124
|
}
|
1251
1125
|
executeStateless$(request) {
|
1252
1126
|
this.executionInProgress$.next(true);
|
1253
|
-
return of(undefined).pipe(tap
|
1127
|
+
return of(undefined).pipe(tap(() => this.executeStatelessActions(request)), switchMap(() => {
|
1254
1128
|
/*
|
1255
1129
|
Skip price calculation in case
|
1256
1130
|
1. No actions in the request
|
@@ -1263,7 +1137,7 @@ class FlowStateService {
|
|
1263
1137
|
else {
|
1264
1138
|
return this.flowConfiguration.calculate$(state);
|
1265
1139
|
}
|
1266
|
-
}), map
|
1140
|
+
}), map(() => this.executeStatelessSelectors(request)), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
1267
1141
|
this.executionInProgress$.next(false);
|
1268
1142
|
return throwError(() => e);
|
1269
1143
|
}));
|
@@ -1288,7 +1162,7 @@ class FlowStateService {
|
|
1288
1162
|
}
|
1289
1163
|
executeStatelessSelectors(request) {
|
1290
1164
|
if (!this.salesTransactionService.state) {
|
1291
|
-
throw '
|
1165
|
+
throw 'State is not initialized';
|
1292
1166
|
}
|
1293
1167
|
const flowState = this.salesTransactionService.state;
|
1294
1168
|
return EntityUtil.entries(request.selectors ?? {}).reduce((result, [key, selector]) => {
|
@@ -1308,16 +1182,9 @@ class FlowStateService {
|
|
1308
1182
|
return result;
|
1309
1183
|
}, { stateId: '', selectors: {} });
|
1310
1184
|
}
|
1311
|
-
getFlowSafe() {
|
1312
|
-
if (!this.flowInfoService.flow) {
|
1313
|
-
throw 'Flow is not defined';
|
1314
|
-
}
|
1315
|
-
return this.flowInfoService.flow;
|
1316
|
-
}
|
1317
1185
|
initProcessors$() {
|
1318
1186
|
const hasOverrides = Boolean(this.customizationService?.getTemplateConfigurationProcessors);
|
1319
|
-
|
1320
|
-
if (flow.properties.stateful && !hasOverrides) {
|
1187
|
+
if (this.flowInfoService.flow.properties.stateful && !hasOverrides) {
|
1321
1188
|
// Skip initialization as backend will take processors from SF
|
1322
1189
|
return of(undefined);
|
1323
1190
|
}
|
@@ -1327,7 +1194,7 @@ class FlowStateService {
|
|
1327
1194
|
return;
|
1328
1195
|
}
|
1329
1196
|
const localProcessors$ = this.customizationService?.getTemplateConfigurationProcessors?.(template.name) ?? of(null);
|
1330
|
-
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap
|
1197
|
+
return localProcessors$.pipe(switchMap(processors => processors ? of(processors) : this.processorsApiService.fetchConfigurationProcessors$(template.id)), tap(processors => {
|
1331
1198
|
const processorsMap = processors.reduce((acc, p) => {
|
1332
1199
|
acc[p.apiName] = p;
|
1333
1200
|
return acc;
|
@@ -1339,7 +1206,7 @@ class FlowStateService {
|
|
1339
1206
|
if (!owners$.length) {
|
1340
1207
|
return of(undefined);
|
1341
1208
|
}
|
1342
|
-
return forkJoin(owners$).pipe(map
|
1209
|
+
return forkJoin(owners$).pipe(map(noop));
|
1343
1210
|
}
|
1344
1211
|
executeActionScript(request, executable) {
|
1345
1212
|
const configurationProcessor = this.processors[executable.ownerId]?.[executable.apiName];
|
@@ -1388,11 +1255,11 @@ class FlowStateService {
|
|
1388
1255
|
}
|
1389
1256
|
}
|
1390
1257
|
}
|
1391
|
-
FlowStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, deps: [{ token:
|
1258
|
+
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 });
|
1392
1259
|
FlowStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService });
|
1393
1260
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateService, decorators: [{
|
1394
1261
|
type: Injectable
|
1395
|
-
}], ctorParameters: function () { return [{ type:
|
1262
|
+
}], ctorParameters: function () { return [{ type: FlowConfigurationService }, { type: FlowInfoService }, { type: i3.FlowStateApiService }, { type: i1.ConfigurationProcessorsApiService }, { type: i1.SalesTransactionApiService }, { type: SalesTransactionService }, { type: i6.ToastService }, { type: undefined, decorators: [{
|
1396
1263
|
type: Optional
|
1397
1264
|
}, {
|
1398
1265
|
type: Inject,
|
@@ -1400,15 +1267,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1400
1267
|
}] }]; } });
|
1401
1268
|
|
1402
1269
|
class FlowStateConfigurationService {
|
1403
|
-
constructor(flowInfoService,
|
1270
|
+
constructor(flowInfoService, flowStateService, configurationService, salesTransactionService, flowConfigurationService, pcmApiService) {
|
1404
1271
|
this.flowInfoService = flowInfoService;
|
1405
|
-
this.flowConfigurationService = flowConfigurationService;
|
1406
|
-
this.flowStateApiService = flowStateApiService;
|
1407
1272
|
this.flowStateService = flowStateService;
|
1408
|
-
this.
|
1273
|
+
this.configurationService = configurationService;
|
1274
|
+
this.salesTransactionService = salesTransactionService;
|
1275
|
+
this.flowConfigurationService = flowConfigurationService;
|
1276
|
+
this.pcmApiService = pcmApiService;
|
1277
|
+
this.pcmCache = {};
|
1409
1278
|
}
|
1410
|
-
|
1411
|
-
|
1279
|
+
updateQuantity$(props) {
|
1280
|
+
const allItems = this.salesTransactionService.state?.salesTransaction?.salesTransactionItems ?? [];
|
1281
|
+
const ti = allItems.find(item => item.id === props.id);
|
1282
|
+
if (!ti) {
|
1283
|
+
return of(undefined);
|
1284
|
+
}
|
1285
|
+
return this.getPCMProduct$(ti.productId).pipe(map(pcm => updateQuantity(ti, props.qty, pcm)), switchMap(updatedTi => {
|
1286
|
+
const state = this.salesTransactionService.state;
|
1287
|
+
if (!state) {
|
1288
|
+
return of(undefined);
|
1289
|
+
}
|
1290
|
+
const updatedState = {
|
1291
|
+
...state,
|
1292
|
+
salesTransaction: {
|
1293
|
+
...state.salesTransaction,
|
1294
|
+
salesTransactionItems: state.salesTransaction.salesTransactionItems.map(item => {
|
1295
|
+
return updatedTi.id === item.id ? updatedTi : item;
|
1296
|
+
}),
|
1297
|
+
},
|
1298
|
+
};
|
1299
|
+
return this.flowConfigurationService.calculate$(updatedState);
|
1300
|
+
}), switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1412
1301
|
}
|
1413
1302
|
addToCart$(props) {
|
1414
1303
|
let request$;
|
@@ -1419,26 +1308,67 @@ class FlowStateConfigurationService {
|
|
1419
1308
|
request$ = of();
|
1420
1309
|
}
|
1421
1310
|
else {
|
1422
|
-
|
1423
|
-
request$ =
|
1424
|
-
if (!this.configurationStateId) {
|
1425
|
-
return of();
|
1426
|
-
}
|
1427
|
-
return this.flowStateApiService.saveConfiguration(stateId, this.configurationStateId).pipe(tap$1(() => this.configurationStateId$.next(null)), map$1(noop));
|
1428
|
-
}));
|
1311
|
+
// TODO: Implement
|
1312
|
+
request$ = of();
|
1429
1313
|
}
|
1430
1314
|
}
|
1431
1315
|
else {
|
1432
|
-
request$ = this.
|
1316
|
+
request$ = this.configureExternal$(props);
|
1317
|
+
}
|
1318
|
+
return request$.pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(noop));
|
1319
|
+
}
|
1320
|
+
configureExternal$(props) {
|
1321
|
+
return this.getPCMProduct$(props.productId).pipe(switchMap(pcm => {
|
1322
|
+
const { state } = this.salesTransactionService;
|
1323
|
+
if (!state) {
|
1324
|
+
return of();
|
1325
|
+
}
|
1326
|
+
const stateToConfigure = {
|
1327
|
+
...state,
|
1328
|
+
salesTransaction: {
|
1329
|
+
...state.salesTransaction,
|
1330
|
+
salesTransactionItems: [
|
1331
|
+
{
|
1332
|
+
...generateTransactionItem(pcm, this.configurationService.state?.salesTransaction.id, props.qty ?? 1),
|
1333
|
+
stiAttributes: Object.entries(props.attributesMap ?? {}).map(([attributeName, value]) => ({
|
1334
|
+
attributeName,
|
1335
|
+
value,
|
1336
|
+
})),
|
1337
|
+
},
|
1338
|
+
],
|
1339
|
+
},
|
1340
|
+
};
|
1341
|
+
return this.configurationService.justConfigureRequest$(stateToConfigure).pipe(switchMap(configurationResult => {
|
1342
|
+
const state = this.salesTransactionService.state;
|
1343
|
+
const addedProduct = configurationResult.salesTransaction.salesTransactionItems[0];
|
1344
|
+
if (!state || !addedProduct) {
|
1345
|
+
return of();
|
1346
|
+
}
|
1347
|
+
return this.flowConfigurationService.calculate$({
|
1348
|
+
...state,
|
1349
|
+
salesTransaction: {
|
1350
|
+
...state.salesTransaction,
|
1351
|
+
salesTransactionItems: [...state.salesTransaction.salesTransactionItems, addedProduct],
|
1352
|
+
},
|
1353
|
+
});
|
1354
|
+
}));
|
1355
|
+
}));
|
1356
|
+
}
|
1357
|
+
getPCMProduct$(productId) {
|
1358
|
+
const cached = this.pcmCache[productId];
|
1359
|
+
if (cached) {
|
1360
|
+
return of(cached);
|
1433
1361
|
}
|
1434
|
-
return
|
1362
|
+
return this.pcmApiService
|
1363
|
+
.fetchPCMByProductId(productId)
|
1364
|
+
.pipe(tap(pcmProduct => (this.pcmCache[productId] = pcmProduct)));
|
1435
1365
|
}
|
1436
1366
|
}
|
1437
|
-
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token:
|
1367
|
+
FlowStateConfigurationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, deps: [{ token: FlowInfoService }, { token: FlowStateService }, { token: ConfigurationService }, { token: SalesTransactionService }, { token: FlowConfigurationService }, { token: i1.PCMApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1438
1368
|
FlowStateConfigurationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService });
|
1439
1369
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowStateConfigurationService, decorators: [{
|
1440
1370
|
type: Injectable
|
1441
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type:
|
1371
|
+
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: FlowStateService }, { type: ConfigurationService }, { type: SalesTransactionService }, { type: FlowConfigurationService }, { type: i1.PCMApiService }]; } });
|
1442
1372
|
|
1443
1373
|
class IntegrationState {
|
1444
1374
|
constructor() {
|
@@ -1458,12 +1388,12 @@ class IntegrationState {
|
|
1458
1388
|
this.action$.next(action);
|
1459
1389
|
}
|
1460
1390
|
listen$(actionType) {
|
1461
|
-
return this.action$.pipe(filter(action => action.type === actionType), map
|
1391
|
+
return this.action$.pipe(filter(action => action.type === actionType), map(action => action.payload));
|
1462
1392
|
}
|
1463
1393
|
listenAll$() {
|
1464
1394
|
return this.action$.asObservable();
|
1465
1395
|
}
|
1466
|
-
|
1396
|
+
reset() {
|
1467
1397
|
this.stateSubj$.next({});
|
1468
1398
|
}
|
1469
1399
|
}
|
@@ -1474,8 +1404,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
1474
1404
|
}] });
|
1475
1405
|
|
1476
1406
|
class ProductImagesService {
|
1477
|
-
constructor(
|
1478
|
-
this.
|
1407
|
+
constructor(productsAdminApiService) {
|
1408
|
+
this.productsAdminApiService = productsAdminApiService;
|
1479
1409
|
this.imagesMap$ = new BehaviorSubject({});
|
1480
1410
|
}
|
1481
1411
|
getImageUrl$(productId) {
|
@@ -1483,439 +1413,54 @@ class ProductImagesService {
|
|
1483
1413
|
this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: '' });
|
1484
1414
|
this.fetchProductImage(productId);
|
1485
1415
|
}
|
1486
|
-
return this.imagesMap$.pipe(map
|
1416
|
+
return this.imagesMap$.pipe(map(imagesMap => imagesMap[productId] ?? null), distinctUntilChanged());
|
1487
1417
|
}
|
1488
1418
|
fetchProductImage(productId) {
|
1489
|
-
this.
|
1419
|
+
this.productsAdminApiService
|
1490
1420
|
.fetchImage$(productId)
|
1491
|
-
.pipe(map
|
1421
|
+
.pipe(map(file => URL.createObjectURL(file)), catchError$1(() => of('')), tap(url => this.imagesMap$.next({ ...this.imagesMap$.value, [productId]: url })))
|
1492
1422
|
.subscribe();
|
1493
1423
|
}
|
1494
1424
|
}
|
1495
|
-
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.
|
1425
|
+
ProductImagesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, deps: [{ token: i1.ProductsAdminApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
1496
1426
|
ProductImagesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService });
|
1497
1427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ProductImagesService, decorators: [{
|
1498
1428
|
type: Injectable
|
1499
|
-
}], ctorParameters: function () { return [{ type: i1.
|
1429
|
+
}], ctorParameters: function () { return [{ type: i1.ProductsAdminApiService }]; } });
|
1500
1430
|
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
get isInitialized$() {
|
1506
|
-
return this.isInitializedSubj$.asObservable();
|
1507
|
-
}
|
1508
|
-
get isInitialized() {
|
1509
|
-
return this.isInitializedSubj$.getValue();
|
1510
|
-
}
|
1511
|
-
set isInitialized(value) {
|
1512
|
-
if (this.isInitialized !== value) {
|
1513
|
-
this.isInitializedSubj$.next(value);
|
1514
|
-
}
|
1515
|
-
}
|
1516
|
-
get hasUnsavedChanges() {
|
1517
|
-
return this._hasUnsavedChanges;
|
1518
|
-
}
|
1519
|
-
set hasUnsavedChanges(value) {
|
1520
|
-
this._hasUnsavedChanges = value;
|
1521
|
-
if (!this._hasUnsavedChanges) {
|
1522
|
-
this.initialCurrentState = this.quoteDraft?.currentState ?? [];
|
1523
|
-
}
|
1524
|
-
}
|
1525
|
-
get hasProducts$() {
|
1526
|
-
return this.quoteSubj$.pipe(map(() => this.hasProducts));
|
1527
|
-
}
|
1528
|
-
get hasProducts() {
|
1529
|
-
return Boolean(this.quoteSubj$.value?.currentState.length);
|
1530
|
-
}
|
1531
|
-
get hasAssets$() {
|
1532
|
-
return this.assetsSubj$.pipe(map(() => this.hasAssets));
|
1533
|
-
}
|
1534
|
-
get hasAssets() {
|
1535
|
-
return Boolean(this.assetsSubj$.value?.currentState.length);
|
1536
|
-
}
|
1537
|
-
get assetsState() {
|
1538
|
-
return this.assetsSubj$.value;
|
1539
|
-
}
|
1540
|
-
constructor(flowInfoService, accountApiService) {
|
1541
|
-
this.flowInfoService = flowInfoService;
|
1542
|
-
this.accountApiService = accountApiService;
|
1543
|
-
this.quoteSubj$ = new BehaviorSubject(null);
|
1544
|
-
this.assetsSubj$ = new BehaviorSubject(null);
|
1545
|
-
this.resetSubj$ = new BehaviorSubject(true);
|
1546
|
-
this.isInitializedSubj$ = new BehaviorSubject(false);
|
1547
|
-
this.initialCurrentState = [];
|
1548
|
-
this._hasUnsavedChanges = false;
|
1549
|
-
this.reset$ = this.resetSubj$.asObservable();
|
1550
|
-
this.isInitializedSubj$
|
1551
|
-
.pipe(filter$1(isInitialized => isInitialized), switchMap$1(() => this.quoteSubj$.asObservable()), skip(1), tap(quote => this.markAsUpdated(quote)))
|
1552
|
-
.subscribe();
|
1553
|
-
}
|
1554
|
-
reset() {
|
1555
|
-
this.resetSubj$.next(true);
|
1556
|
-
this.quoteSubj$.next(null);
|
1557
|
-
this.assetsSubj$.next(null);
|
1558
|
-
this.isInitialized = false;
|
1559
|
-
this.hasUnsavedChanges = false;
|
1560
|
-
}
|
1561
|
-
init(headerId, params) {
|
1562
|
-
const isAccountMode = this.flowInfoService.context.mode === ConfigurationContextMode.ACCOUNT;
|
1563
|
-
const accountId = isAccountMode ? headerId : this.flowInfoService.context['accountId'];
|
1564
|
-
return zip(accountId ? this.accountApiService.getAssetsState(accountId, params) : of(null), isAccountMode
|
1565
|
-
? of(QuoteDraft.emptyQuote(ConfigurationContextMode.ACCOUNT))
|
1566
|
-
: of(QuoteDraft.emptyQuote(ConfigurationContextMode.QUOTE))).pipe(tap(([assets, quote]) => {
|
1567
|
-
if (assets) {
|
1568
|
-
this.assetsSubj$.next(assets);
|
1569
|
-
}
|
1570
|
-
this.quoteSubj$.next(quote);
|
1571
|
-
}), map(() => noop()), take$1(1));
|
1572
|
-
}
|
1573
|
-
finalizeInit() {
|
1574
|
-
this.isInitialized = true;
|
1575
|
-
this.hasUnsavedChanges = false;
|
1576
|
-
}
|
1577
|
-
setCurrentLineItemState(lineItems) {
|
1578
|
-
const quoteDraft = this.quoteSubj$.value;
|
1579
|
-
if (!quoteDraft) {
|
1580
|
-
return;
|
1581
|
-
}
|
1582
|
-
this.quoteSubj$.next({
|
1583
|
-
...quoteDraft,
|
1584
|
-
currentState: lineItems,
|
1585
|
-
});
|
1586
|
-
}
|
1587
|
-
updateQuoteDraft(update) {
|
1588
|
-
const quoteDraft = this.quoteSubj$.value;
|
1589
|
-
if (!quoteDraft) {
|
1590
|
-
return;
|
1591
|
-
}
|
1592
|
-
this.quoteSubj$.next({
|
1593
|
-
...quoteDraft,
|
1594
|
-
...update,
|
1595
|
-
});
|
1596
|
-
}
|
1597
|
-
updateByPriceSummary(priceSummary) {
|
1598
|
-
const quoteDraft = this.quoteSubj$.value;
|
1599
|
-
if (!quoteDraft) {
|
1600
|
-
return;
|
1601
|
-
}
|
1602
|
-
const updatedCurrentState = this.currentState.map(lineItem => {
|
1603
|
-
const updated = priceSummary.lineItems.find(li => li.id === lineItem.id);
|
1604
|
-
return updated ?? lineItem;
|
1605
|
-
});
|
1606
|
-
this.quoteSubj$.next({
|
1607
|
-
...quoteDraft,
|
1608
|
-
currentState: updatedCurrentState,
|
1609
|
-
totalPrices: priceSummary.totalPrices,
|
1610
|
-
approvalItems: priceSummary.approvalItems,
|
1611
|
-
});
|
1612
|
-
}
|
1613
|
-
setAssetsState(assetsState) {
|
1614
|
-
this.assetsSubj$.next(assetsState);
|
1615
|
-
}
|
1616
|
-
get quoteDraft$() {
|
1617
|
-
return this.quoteSubj$.pipe(map(() => this.quoteDraft), filter$1((quote) => Boolean(quote)), shareReplay$1());
|
1618
|
-
}
|
1619
|
-
get quoteDraft() {
|
1620
|
-
return this.quoteSubj$.value;
|
1621
|
-
}
|
1622
|
-
get currentState$() {
|
1623
|
-
return this.quoteDraft$.pipe(map(quote => quote.currentState));
|
1624
|
-
}
|
1625
|
-
get currentState() {
|
1626
|
-
return this.quoteDraft?.currentState ?? [];
|
1627
|
-
}
|
1628
|
-
get isStandalone() {
|
1629
|
-
return this.flowInfoService.flow?.properties.standalone ?? false;
|
1630
|
-
}
|
1631
|
-
get isStandalone$() {
|
1632
|
-
return this.flowInfoService.flow$.pipe(map(() => this.isStandalone));
|
1633
|
-
}
|
1634
|
-
getInitialCurrentState() {
|
1635
|
-
return this.initialCurrentState;
|
1636
|
-
}
|
1637
|
-
isEditMode$() {
|
1638
|
-
return this.quoteDraft$.pipe(map(() => this.isEditMode()));
|
1639
|
-
}
|
1640
|
-
isEditMode() {
|
1641
|
-
const context = this.quoteDraft?.context;
|
1642
|
-
if (context?.mode === ConfigurationContextMode.ACCOUNT) {
|
1643
|
-
return true;
|
1644
|
-
}
|
1645
|
-
if (context?.mode === ConfigurationContextMode.QUOTE) {
|
1646
|
-
return context.properties.Status === 'Draft';
|
1647
|
-
}
|
1648
|
-
return false;
|
1649
|
-
}
|
1650
|
-
markAsUpdated(quote) {
|
1651
|
-
if (quote?.context.properties['#mode'] === ConfigurationContextMode.ACCOUNT) {
|
1652
|
-
this.hasUnsavedChanges = !!quote && !quote.currentState.every(li => li.actionCode === 'EXIST');
|
1653
|
-
}
|
1654
|
-
else {
|
1655
|
-
this.hasUnsavedChanges = !isEqual(this.initialCurrentState, quote?.currentState);
|
1656
|
-
}
|
1431
|
+
class CatalogProductsService {
|
1432
|
+
constructor() {
|
1433
|
+
this.stateSubj$ = new BehaviorSubject(null);
|
1434
|
+
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
1657
1435
|
}
|
1658
|
-
|
1659
|
-
|
1660
|
-
QuoteDraftService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService });
|
1661
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService, decorators: [{
|
1662
|
-
type: Injectable
|
1663
|
-
}], ctorParameters: function () { return [{ type: FlowInfoService }, { type: i1.AccountApiService }]; } });
|
1664
|
-
|
1665
|
-
class ConfigurationService {
|
1666
|
-
constructor(quoteDraftService, runtimeService, configurationApiService, messageService, dialogService, runtimeSettings, flowInfoService) {
|
1667
|
-
this.quoteDraftService = quoteDraftService;
|
1668
|
-
this.runtimeService = runtimeService;
|
1669
|
-
this.configurationApiService = configurationApiService;
|
1670
|
-
this.messageService = messageService;
|
1671
|
-
this.dialogService = dialogService;
|
1672
|
-
this.runtimeSettings = runtimeSettings;
|
1673
|
-
this.flowInfoService = flowInfoService;
|
1674
|
-
this.mode = ConfigurationMode.SEARCH;
|
1675
|
-
this.configurationState = new BehaviorSubject(null);
|
1676
|
-
this.previousConfigurationState = new BehaviorSubject(null);
|
1677
|
-
this.isLoadingSubj$ = new BehaviorSubject(false);
|
1678
|
-
this.isLoading$ = this.isLoadingSubj$.asObservable();
|
1679
|
-
this.hasUnsavedChanges = false;
|
1436
|
+
get state() {
|
1437
|
+
return this.stateSubj$.getValue();
|
1680
1438
|
}
|
1681
1439
|
reset() {
|
1682
|
-
this.
|
1683
|
-
this.runtimeService.reset();
|
1684
|
-
this.configurableRamp = undefined;
|
1685
|
-
this.configurationState.next(null);
|
1686
|
-
this.previousConfigurationState.next(null);
|
1687
|
-
}
|
1688
|
-
patch$(lineItem) {
|
1689
|
-
const source = this.getSnapshot();
|
1690
|
-
if (!source) {
|
1691
|
-
return throwError(() => new Error(`Source LineItem not found`));
|
1692
|
-
}
|
1693
|
-
this.configurableRamp = new LineItemWorker(source).replace(lineItem).li;
|
1694
|
-
return this.configure().pipe(catchError$1(error => {
|
1695
|
-
console.error(error);
|
1696
|
-
if (!this.runtimeService.uiDefinitionProperties.suppressToastMessages) {
|
1697
|
-
this.messageService.add({ severity: 'error', summary: error });
|
1698
|
-
}
|
1699
|
-
// bounce back if configuration call has failed
|
1700
|
-
const prevState = this.configurationState.value;
|
1701
|
-
this.configurationState.next(prevState ? { ...prevState } : null);
|
1702
|
-
return throwError(() => error);
|
1703
|
-
}), tap(() => {
|
1704
|
-
if (!this.hasUnsavedChanges) {
|
1705
|
-
this.hasUnsavedChanges = true;
|
1706
|
-
}
|
1707
|
-
}));
|
1708
|
-
}
|
1709
|
-
patch(lineItem) {
|
1710
|
-
this.patch$(lineItem).subscribe();
|
1711
|
-
}
|
1712
|
-
setConfigurableRamp(lineItem) {
|
1713
|
-
this.configurableRamp = lineItem;
|
1714
|
-
}
|
1715
|
-
get() {
|
1716
|
-
return this.configurationState.pipe(map(state => state?.lineItem), shareReplay());
|
1717
|
-
}
|
1718
|
-
getSnapshot() {
|
1719
|
-
return this.configurationState.value?.lineItem ? { ...this.configurationState.value?.lineItem } : undefined;
|
1720
|
-
}
|
1721
|
-
getRuntimeModel() {
|
1722
|
-
const runtimeModel = this.runtimeService.runtimeModel;
|
1723
|
-
if (!runtimeModel) {
|
1724
|
-
throw new Error('Runtime model not initialized');
|
1725
|
-
}
|
1726
|
-
return runtimeModel;
|
1727
|
-
}
|
1728
|
-
getRuntimeContext() {
|
1729
|
-
const runtimeContext = this.runtimeService.runtimeContext;
|
1730
|
-
if (!runtimeContext) {
|
1731
|
-
throw new Error('Runtime context not initialized');
|
1732
|
-
}
|
1733
|
-
return runtimeContext;
|
1734
|
-
}
|
1735
|
-
get state$() {
|
1736
|
-
return this.configurationState.asObservable();
|
1737
|
-
}
|
1738
|
-
get stateSnapshot() {
|
1739
|
-
return this.configurationState.value;
|
1740
|
-
}
|
1741
|
-
get previousStateSnapshot() {
|
1742
|
-
return this.previousConfigurationState.value;
|
1743
|
-
}
|
1744
|
-
get charges$() {
|
1745
|
-
return this.configurationState.pipe(map(state => state?.charges ?? {}));
|
1746
|
-
}
|
1747
|
-
get chargesSnapshot() {
|
1748
|
-
return this.configurationState.value?.charges ?? {};
|
1749
|
-
}
|
1750
|
-
get pricePlans$() {
|
1751
|
-
return this.configurationState.pipe(map(state => state?.pricePlans ?? {}));
|
1752
|
-
}
|
1753
|
-
get pricePlansSnapshot() {
|
1754
|
-
return this.configurationState.value?.pricePlans ?? {};
|
1755
|
-
}
|
1756
|
-
get procedureContext$() {
|
1757
|
-
return this.configurationState.pipe(map(state => state?.procedureContext ?? {}));
|
1758
|
-
}
|
1759
|
-
get procedureContextSnapshot() {
|
1760
|
-
return this.configurationState.value?.procedureContext ?? {};
|
1761
|
-
}
|
1762
|
-
configure() {
|
1763
|
-
return this.configureRequest$(this.generateRequest());
|
1764
|
-
}
|
1765
|
-
configureRequest$(configurationRequest) {
|
1766
|
-
const runtimeContext = this.getRuntimeContext();
|
1767
|
-
const runtimeModel = this.getRuntimeModel();
|
1768
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1769
|
-
const mainPricingEnabled = runtimeContext.properties?.PricingEnabled;
|
1770
|
-
const pricingEnabled = mainPricingEnabled ? mainPricingEnabled === 'true' : uiDefinitionProperties.pricingEnabled;
|
1771
|
-
const customPriceApi = this.runtimeSettings.getConfigurationSettings()['CUSTOM_PRICE_API'];
|
1772
|
-
this.isLoadingSubj$.next(true);
|
1773
|
-
const configure$ = pricingEnabled && customPriceApi
|
1774
|
-
? this.configurationApiService.customConfigurePrice({
|
1775
|
-
url: customPriceApi,
|
1776
|
-
configurationRequest,
|
1777
|
-
runtimeModel,
|
1778
|
-
})
|
1779
|
-
: this.extendedConfigureLineItem$({
|
1780
|
-
configurationRequest,
|
1781
|
-
runtimeModel,
|
1782
|
-
pricingEnabled,
|
1783
|
-
});
|
1784
|
-
return configure$.pipe(tap(result => {
|
1785
|
-
this.configurationState.next(result);
|
1786
|
-
this.previousConfigurationState.next(cloneDeep(result));
|
1787
|
-
if (result.deletedLineItems?.length) {
|
1788
|
-
this.showInactiveProductsConfirmation();
|
1789
|
-
}
|
1790
|
-
this.configurableRamp = result.lineItem;
|
1791
|
-
}), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => {
|
1792
|
-
const resetState = this.previousConfigurationState.value;
|
1793
|
-
if (resetState) {
|
1794
|
-
this.previousConfigurationState.next(cloneDeep(resetState));
|
1795
|
-
this.configurationState.next(resetState);
|
1796
|
-
}
|
1797
|
-
if (error.error) {
|
1798
|
-
return extractErrorDetails(error.error).join('. ');
|
1799
|
-
}
|
1800
|
-
return error.message || JSON.stringify(error);
|
1801
|
-
})), finalize$1(() => this.isLoadingSubj$.next(false)));
|
1802
|
-
}
|
1803
|
-
configureExternal$(props) {
|
1804
|
-
return this.runtimeService
|
1805
|
-
.init({ productId: props.productId, defaultQty: props.qty, attributesMap: props.attributesMap })
|
1806
|
-
.pipe(switchMap$1(() => this.configure()), first(), catchError$1(error => {
|
1807
|
-
this.messageService.add({ severity: ToastType.error, summary: error });
|
1808
|
-
throw error;
|
1809
|
-
}), finalize$1(() => this.reset()));
|
1810
|
-
}
|
1811
|
-
configureGuidedSelling$(data) {
|
1812
|
-
return this.extendedConfigureLineItem$({
|
1813
|
-
configurationRequest: getGuidedSellingConfigurationRequest(data),
|
1814
|
-
}).pipe(catchError$1(error => {
|
1815
|
-
if (error instanceof HttpErrorResponse) {
|
1816
|
-
this.messageService.add({ severity: ToastType.error, summary: error.error.message || error.error });
|
1817
|
-
}
|
1818
|
-
throw error;
|
1819
|
-
}));
|
1820
|
-
}
|
1821
|
-
generateRequest(lightMode = true) {
|
1822
|
-
const lineItem = this.generateLineItem();
|
1823
|
-
let request = {
|
1824
|
-
lineItem,
|
1825
|
-
mode: this.mode,
|
1826
|
-
step: !this.configurationState.value?.lineItem ? RuntimeStep.START : RuntimeStep.UPDATE,
|
1827
|
-
attributeDomainMode: 'ALL',
|
1828
|
-
context: this.quoteDraftService.quoteDraft?.context ?? generateEmptyContext(),
|
1829
|
-
lineItems: this.quoteDraftService.quoteDraft?.currentState || [],
|
1830
|
-
asset: this.getAsset(),
|
1831
|
-
};
|
1832
|
-
if (lightMode) {
|
1833
|
-
request = ConfigurationTranslatorUtils.lightenConfigurationRequest(request);
|
1834
|
-
}
|
1835
|
-
return request;
|
1836
|
-
}
|
1837
|
-
generateLineItem() {
|
1838
|
-
const runtimeContext = this.getRuntimeContext();
|
1839
|
-
const uiDefinitionProperties = this.getUIDefinitionProperties();
|
1840
|
-
let lineItem = this.configurableRamp;
|
1841
|
-
if (!lineItem) {
|
1842
|
-
const { initializationProps } = this.runtimeService ?? {};
|
1843
|
-
lineItem = getDefaultLineItem(runtimeContext, uiDefinitionProperties, initializationProps?.defaultQty);
|
1844
|
-
// Set default attributes
|
1845
|
-
if (initializationProps?.attributesMap) {
|
1846
|
-
const attributes = transform(initializationProps?.attributesMap, (acc, value, name) => acc.push({ name, value }), []);
|
1847
|
-
lineItem = new LineItemWorker(lineItem).patchAttribute(attributes).li;
|
1848
|
-
}
|
1849
|
-
}
|
1850
|
-
return lineItem;
|
1851
|
-
}
|
1852
|
-
getAsset() {
|
1853
|
-
const lineItem = this.configurableRamp;
|
1854
|
-
if (!lineItem) {
|
1855
|
-
return;
|
1856
|
-
}
|
1857
|
-
const assetId = lineItem.assetId ?? lineItem.openOrderLineItemId;
|
1858
|
-
return this.quoteDraftService.assetsState?.initialState.find(li => assetPredicateFn(li, assetId));
|
1859
|
-
}
|
1860
|
-
getUIDefinitionProperties() {
|
1861
|
-
return {
|
1862
|
-
...(this.getRuntimeContext().uiDefinitionContainer?.source.properties ?? {}),
|
1863
|
-
...(this.runtimeService.uiDefinitionProperties ?? {}),
|
1864
|
-
};
|
1865
|
-
}
|
1866
|
-
showInactiveProductsConfirmation() {
|
1867
|
-
const confirmationConfig = {
|
1868
|
-
title: ' ',
|
1869
|
-
description: 'This quote contains inactive products. Do you want to remove them?',
|
1870
|
-
primaryButtonLabel: 'Remove products',
|
1871
|
-
secondaryButtonLabel: 'Back to Quote',
|
1872
|
-
};
|
1873
|
-
this.dialogService
|
1874
|
-
.open(ConfirmationComponent, {
|
1875
|
-
dismissableMask: false,
|
1876
|
-
closeOnEscape: false,
|
1877
|
-
closable: false,
|
1878
|
-
showHeader: true,
|
1879
|
-
header: `Inactive Products in Quote`,
|
1880
|
-
width: '440px',
|
1881
|
-
data: { confirmationConfig },
|
1882
|
-
})
|
1883
|
-
.onClose.subscribe(result => {
|
1884
|
-
if (!result) {
|
1885
|
-
const Id = this.quoteDraftService.quoteDraft?.context.properties.Id ?? '';
|
1886
|
-
window['VELO_BACK_FN'].apply(null, [Id]);
|
1887
|
-
}
|
1888
|
-
});
|
1440
|
+
this.stateSubj$.next(null);
|
1889
1441
|
}
|
1890
|
-
|
1891
|
-
|
1892
|
-
configurationRequest: configurationRequest,
|
1893
|
-
runtimeModel,
|
1894
|
-
pricingEnabled,
|
1895
|
-
});
|
1442
|
+
setState(state) {
|
1443
|
+
this.stateSubj$.next(state);
|
1896
1444
|
}
|
1897
1445
|
}
|
1898
|
-
|
1899
|
-
|
1900
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type:
|
1446
|
+
CatalogProductsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
1447
|
+
CatalogProductsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService });
|
1448
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: CatalogProductsService, decorators: [{
|
1901
1449
|
type: Injectable
|
1902
|
-
}]
|
1450
|
+
}] });
|
1903
1451
|
|
1904
1452
|
class ConfigurationStateService {
|
1905
|
-
constructor(configurationRuntimeService, configurationService,
|
1906
|
-
// private quoteDraftService: QuoteDraftService,
|
1907
|
-
salesTransactionService, toastService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService,
|
1908
|
-
// private quoteApiService: QuoteApiService,
|
1909
|
-
salesTransactionApiService) {
|
1453
|
+
constructor(configurationRuntimeService, configurationService, flowStateService, flowInfoService, flowConfigurationService, flowStateApiService, salesTransactionService, salesTransactionApiService, toastService, pcmApiService) {
|
1910
1454
|
this.configurationRuntimeService = configurationRuntimeService;
|
1911
1455
|
this.configurationService = configurationService;
|
1912
|
-
this.salesTransactionService = salesTransactionService;
|
1913
|
-
this.toastService = toastService;
|
1914
1456
|
this.flowStateService = flowStateService;
|
1915
1457
|
this.flowInfoService = flowInfoService;
|
1916
1458
|
this.flowConfigurationService = flowConfigurationService;
|
1917
1459
|
this.flowStateApiService = flowStateApiService;
|
1460
|
+
this.salesTransactionService = salesTransactionService;
|
1918
1461
|
this.salesTransactionApiService = salesTransactionApiService;
|
1462
|
+
this.toastService = toastService;
|
1463
|
+
this.pcmApiService = pcmApiService;
|
1919
1464
|
this.isInitialized$ = new BehaviorSubject(false);
|
1920
1465
|
this.canceledConfiguration$ = new Subject();
|
1921
1466
|
this.NOT_INITIALIZED = Symbol();
|
@@ -1939,9 +1484,9 @@ class ConfigurationStateService {
|
|
1939
1484
|
request$ = this.initStateful$();
|
1940
1485
|
}
|
1941
1486
|
else {
|
1942
|
-
request$ =
|
1487
|
+
request$ = this.configurationService.init$();
|
1943
1488
|
}
|
1944
|
-
return request$.pipe(take(1), tap
|
1489
|
+
return request$.pipe(take(1), tap(() => {
|
1945
1490
|
this.isInitialized$.next(true);
|
1946
1491
|
this.canceledConfiguration$ = new Subject();
|
1947
1492
|
}));
|
@@ -1955,10 +1500,11 @@ class ConfigurationStateService {
|
|
1955
1500
|
this.configurationStore = {};
|
1956
1501
|
this.executedFunctions = {};
|
1957
1502
|
this.configurationService.reset();
|
1503
|
+
this.configurationRuntimeService.reset();
|
1958
1504
|
}
|
1959
1505
|
execute$(exec) {
|
1960
1506
|
const request = this.execToRequest(exec);
|
1961
|
-
return this.executeRequest$(request).pipe(map
|
1507
|
+
return this.executeRequest$(request).pipe(map(result => {
|
1962
1508
|
// Keep only requested results
|
1963
1509
|
const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
|
1964
1510
|
if (exec.selectors?.[requestId]) {
|
@@ -1980,7 +1526,7 @@ class ConfigurationStateService {
|
|
1980
1526
|
}
|
1981
1527
|
// prevent parallel configuration requests in stateless mode
|
1982
1528
|
if (!this.statelessExecutionRequest$) {
|
1983
|
-
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize(() => (this.statelessExecutionRequest$ = null)));
|
1529
|
+
this.statelessExecutionRequest$ = executionRequest$.pipe(shareReplay(), take(1), finalize$1(() => (this.statelessExecutionRequest$ = null)));
|
1984
1530
|
}
|
1985
1531
|
return this.statelessExecutionRequest$;
|
1986
1532
|
}
|
@@ -1994,7 +1540,7 @@ class ConfigurationStateService {
|
|
1994
1540
|
},
|
1995
1541
|
},
|
1996
1542
|
});
|
1997
|
-
return this.executeRequest$(request).pipe(map
|
1543
|
+
return this.executeRequest$(request).pipe(map(response => response.selectors[requestId]));
|
1998
1544
|
}
|
1999
1545
|
subscribe$(selectorName, inputData = {}, options) {
|
2000
1546
|
const requestId = UUID.UUID();
|
@@ -2017,7 +1563,7 @@ class ConfigurationStateService {
|
|
2017
1563
|
this.executeRequest$(request).subscribe();
|
2018
1564
|
}
|
2019
1565
|
}
|
2020
|
-
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map
|
1566
|
+
return subscription.data$.pipe(filter(data => data != this.NOT_INITIALIZED), map(data => data), distinctUntilChanged(), finalize$1(() => {
|
2021
1567
|
if (!this.subscriptions[requestId]?.data$.observed) {
|
2022
1568
|
delete this.subscriptions[requestId];
|
2023
1569
|
}
|
@@ -2025,37 +1571,42 @@ class ConfigurationStateService {
|
|
2025
1571
|
}
|
2026
1572
|
saveConfiguration() {
|
2027
1573
|
if (this.isStatefulConfiguration) {
|
2028
|
-
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map
|
1574
|
+
return this.flowStateApiService.saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '').pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(r => ({ id: r.quoteId })));
|
2029
1575
|
}
|
2030
1576
|
const state = this.salesTransactionService.state;
|
2031
1577
|
if (!state) {
|
2032
1578
|
return of({ id: '' });
|
2033
1579
|
}
|
2034
1580
|
const { standalone } = this.flowInfoService.flow.properties;
|
1581
|
+
const transactionContext = this.salesTransactionService.state;
|
1582
|
+
const configurationRoot = this.configurationService.root;
|
1583
|
+
if (!transactionContext || !configurationRoot) {
|
1584
|
+
return of({ id: '' });
|
1585
|
+
}
|
1586
|
+
const stateItems = transactionContext.salesTransaction.salesTransactionItems;
|
1587
|
+
const isNewTransactionItem = stateItems.every(ti => ti.id !== configurationRoot.id);
|
1588
|
+
let salesTransactionItems;
|
1589
|
+
if (isNewTransactionItem) {
|
1590
|
+
salesTransactionItems = [...stateItems, configurationRoot];
|
1591
|
+
}
|
1592
|
+
else {
|
1593
|
+
salesTransactionItems = stateItems.map(ti => (ti.id === configurationRoot.id ? configurationRoot : ti));
|
1594
|
+
}
|
1595
|
+
const newState = {
|
1596
|
+
...transactionContext,
|
1597
|
+
salesTransaction: {
|
1598
|
+
...transactionContext.salesTransaction,
|
1599
|
+
salesTransactionItems,
|
1600
|
+
},
|
1601
|
+
};
|
2035
1602
|
if (standalone) {
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
// let currentState: LineItem[];
|
2044
|
-
// if (isNewLineItem) {
|
2045
|
-
// currentState = [...quoteDraft.currentState, lineItem];
|
2046
|
-
// } else {
|
2047
|
-
// currentState = quoteDraft.currentState.map(li => (li.id === lineItem.id ? lineItem : li));
|
2048
|
-
// }
|
2049
|
-
// const asset = this.configurationService.getAsset();
|
2050
|
-
// const initialState = [...(this.quoteDraftService.quoteDraft?.initialState ?? [])];
|
2051
|
-
// if (asset) {
|
2052
|
-
// if (!initialState.some(li => li.id === asset.id)) {
|
2053
|
-
// initialState.push(asset);
|
2054
|
-
// }
|
2055
|
-
// }
|
2056
|
-
// TODO: adjust the logic for ShoppingCart
|
2057
|
-
const newState = { ...state };
|
2058
|
-
return this.flowConfigurationService.calculate$(newState).pipe(map$1(() => ({ id: '' })));
|
1603
|
+
const request = {
|
1604
|
+
transactionContext: newState,
|
1605
|
+
flowId: this.flowInfoService.flow.id,
|
1606
|
+
};
|
1607
|
+
return this.salesTransactionApiService.save(request).pipe(switchMap(r => this.flowStateService.executeRequest$({}, true).pipe(map(() => r))), map(id => ({ id })));
|
1608
|
+
}
|
1609
|
+
return this.flowConfigurationService.calculate$(newState).pipe(switchMap(() => this.flowStateService.executeRequest$({}, true)), map(() => ({ id: '' })));
|
2059
1610
|
}
|
2060
1611
|
cancelConfiguration() {
|
2061
1612
|
if (!this.isInitialized$.value) {
|
@@ -2074,29 +1625,30 @@ class ConfigurationStateService {
|
|
2074
1625
|
return this.flowInfoService.flow?.properties.stateful ?? false;
|
2075
1626
|
}
|
2076
1627
|
initStateful$() {
|
2077
|
-
this.ownerId = this.configurationRuntimeService.
|
2078
|
-
const
|
2079
|
-
if (!this.flowStateService.stateId) {
|
1628
|
+
this.ownerId = this.configurationRuntimeService.uiDefinitionContainer?.id ?? '';
|
1629
|
+
const { productId, transactionItemId } = this.flowInfoService.context;
|
1630
|
+
if (!productId || !this.flowStateService.stateId) {
|
2080
1631
|
return of(undefined);
|
2081
1632
|
}
|
2082
|
-
const container = this.configurationRuntimeService.
|
2083
|
-
const lineItem = this.configurationService.generateLineItem();
|
1633
|
+
const container = this.configurationRuntimeService.uiDefinitionContainer;
|
2084
1634
|
let request$;
|
2085
|
-
if (!
|
2086
|
-
request$ = this.
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
1635
|
+
if (!transactionItemId) {
|
1636
|
+
request$ = this.pcmApiService.fetchPCMByProductId(productId).pipe(switchMap(pcm => {
|
1637
|
+
return this.flowStateApiService.newConfiguration(this.flowStateService.stateId || '', {
|
1638
|
+
transactionItem: generateTransactionItem(pcm, this.configurationService.state?.salesTransaction.id),
|
1639
|
+
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
1640
|
+
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
1641
|
+
});
|
1642
|
+
}));
|
2091
1643
|
}
|
2092
1644
|
else {
|
2093
1645
|
request$ = this.flowStateApiService.startConfiguration(this.flowStateService.stateId, {
|
2094
|
-
|
1646
|
+
transactionItemId,
|
2095
1647
|
actionsOverride: container?.actions?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2096
1648
|
selectorsOverride: container?.selectors?.map(processor => ({ ...processor, ownerId: this.ownerId })),
|
2097
1649
|
});
|
2098
1650
|
}
|
2099
|
-
return request$.pipe(map
|
1651
|
+
return request$.pipe(map(r => {
|
2100
1652
|
this.stateId = r.stateId;
|
2101
1653
|
return undefined;
|
2102
1654
|
}));
|
@@ -2140,37 +1692,35 @@ class ConfigurationStateService {
|
|
2140
1692
|
else {
|
2141
1693
|
execution$ = this.executeStateless$(fullRequest);
|
2142
1694
|
}
|
2143
|
-
return execution$.pipe(tap
|
1695
|
+
return execution$.pipe(tap(result => this.handleSelectorsResponse(result.selectors)));
|
2144
1696
|
}
|
2145
1697
|
executeStateless$(request) {
|
2146
1698
|
this.executionInProgress$.next(true);
|
2147
|
-
return
|
1699
|
+
return this.configurationService.state$.pipe(first(), switchMap(state => {
|
2148
1700
|
// Apply actions and execute configuration/price call
|
2149
1701
|
// No need to run configuration if no actions in the request
|
2150
1702
|
if (!request.actions?.length) {
|
2151
1703
|
return of(undefined);
|
2152
1704
|
}
|
2153
|
-
let configurationRequest = this.configurationService.generateRequest(false);
|
2154
1705
|
request.actions.forEach(action => {
|
2155
|
-
|
1706
|
+
state = this.executeActionScript(state, action) ?? state;
|
2156
1707
|
});
|
2157
|
-
|
2158
|
-
|
2159
|
-
}), map$1(() => {
|
1708
|
+
return this.configurationService.configure$(state);
|
1709
|
+
}), map(() => {
|
2160
1710
|
// Run selectors and apply them to the state
|
2161
|
-
const configurationState = this.configurationService.
|
1711
|
+
const configurationState = this.configurationService.state;
|
2162
1712
|
if (!configurationState) {
|
2163
1713
|
return { stateId: '', selectors: {} };
|
2164
1714
|
}
|
2165
1715
|
return this.runStatelessSelectors(request, configurationState);
|
2166
|
-
}), tap
|
2167
|
-
const configurationState = this.configurationService.
|
1716
|
+
}), tap(() => this.executionInProgress$.next(false)), catchError$1(error => {
|
1717
|
+
const configurationState = this.configurationService.previousState;
|
2168
1718
|
if (configurationState) {
|
2169
1719
|
const selectorsResult = this.runStatelessSelectors(request, configurationState);
|
2170
1720
|
this.handleSelectorsResponse(selectorsResult.selectors);
|
2171
1721
|
}
|
2172
1722
|
this.executionInProgress$.next(false);
|
2173
|
-
if (!this.configurationRuntimeService.
|
1723
|
+
if (!this.configurationRuntimeService.uiDefinitionProps.suppressToastMessages) {
|
2174
1724
|
this.toastService.add({ severity: ToastType.error, summary: String(error) });
|
2175
1725
|
}
|
2176
1726
|
return throwError(() => error);
|
@@ -2191,7 +1741,7 @@ class ConfigurationStateService {
|
|
2191
1741
|
};
|
2192
1742
|
this.executionInProgress$.next(true);
|
2193
1743
|
return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
|
2194
|
-
}), tap
|
1744
|
+
}), tap(({ stateId }) => (this.stateId = stateId)), share(), tap(() => this.executionInProgress$.next(false)), catchError$1(e => {
|
2195
1745
|
this.executionInProgress$.next(false);
|
2196
1746
|
return throwError(() => e);
|
2197
1747
|
}));
|
@@ -2201,11 +1751,11 @@ class ConfigurationStateService {
|
|
2201
1751
|
// make sure stream switches to statefulExecutionRequest$ before pushing an execution request
|
2202
1752
|
combineLatest([
|
2203
1753
|
this.statefulExecutionRequest$,
|
2204
|
-
of(undefined).pipe(tap
|
2205
|
-
])), map
|
1754
|
+
of(undefined).pipe(tap(() => this.statefulRequestStream$.next(request))),
|
1755
|
+
])), map(([response]) => response), take(1));
|
2206
1756
|
}
|
2207
1757
|
executeActionScript(request, processor) {
|
2208
|
-
const { actions } = this.configurationRuntimeService.
|
1758
|
+
const { actions } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2209
1759
|
const configurationProcessor = actions?.find(action => action.apiName === processor.apiName);
|
2210
1760
|
if (!configurationProcessor?.script) {
|
2211
1761
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2213,7 +1763,7 @@ class ConfigurationStateService {
|
|
2213
1763
|
return this.executeProcessorScript(request, configurationProcessor, processor.inputData);
|
2214
1764
|
}
|
2215
1765
|
executeSelectorScript(request, processor) {
|
2216
|
-
const { selectors } = this.configurationRuntimeService.
|
1766
|
+
const { selectors } = this.configurationRuntimeService.uiDefinitionContainer ?? {};
|
2217
1767
|
const configurationProcessor = selectors?.find(selector => selector.apiName === processor.apiName);
|
2218
1768
|
if (!configurationProcessor?.script) {
|
2219
1769
|
throw `ConfigurationProcessor ${processor.apiName} not found`;
|
@@ -2254,46 +1804,54 @@ class ConfigurationStateService {
|
|
2254
1804
|
}, { stateId: '', selectors: {} });
|
2255
1805
|
}
|
2256
1806
|
}
|
2257
|
-
ConfigurationStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, deps: [{ token: ConfigurationRuntimeService }, { token: ConfigurationService }, { token:
|
1807
|
+
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 }, { token: i1.PCMApiService }], target: i0.ɵɵFactoryTarget.Injectable });
|
2258
1808
|
ConfigurationStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService });
|
2259
1809
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationStateService, decorators: [{
|
2260
1810
|
type: Injectable
|
2261
|
-
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type:
|
1811
|
+
}], ctorParameters: function () { return [{ type: ConfigurationRuntimeService }, { type: ConfigurationService }, { type: FlowStateService }, { type: FlowInfoService }, { type: FlowConfigurationService }, { type: i3.FlowStateApiService }, { type: SalesTransactionService }, { type: i1.SalesTransactionApiService }, { type: i6.ToastService }, { type: i1.PCMApiService }]; } });
|
2262
1812
|
|
2263
1813
|
class ConfigurationModule {
|
2264
1814
|
}
|
2265
1815
|
ConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
2266
1816
|
ConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, imports: [ConfirmationDialogModule, ApiModule] });
|
2267
|
-
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1817
|
+
ConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, providers: [
|
1818
|
+
ConfigurationService,
|
1819
|
+
ConfigurationStateService,
|
1820
|
+
ConfigurationRuntimeService,
|
1821
|
+
TestModeConfigurationService,
|
1822
|
+
GuidedSellingService,
|
1823
|
+
], imports: [ConfirmationDialogModule, ApiModule] });
|
2268
1824
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ConfigurationModule, decorators: [{
|
2269
1825
|
type: NgModule,
|
2270
1826
|
args: [{
|
2271
1827
|
imports: [ConfirmationDialogModule, ApiModule],
|
2272
|
-
providers: [
|
1828
|
+
providers: [
|
1829
|
+
ConfigurationService,
|
1830
|
+
ConfigurationStateService,
|
1831
|
+
ConfigurationRuntimeService,
|
1832
|
+
TestModeConfigurationService,
|
1833
|
+
GuidedSellingService,
|
1834
|
+
],
|
2273
1835
|
}]
|
2274
1836
|
}] });
|
2275
1837
|
|
2276
|
-
class
|
2277
|
-
constructor() {
|
2278
|
-
this.stateSubj$ = new BehaviorSubject(null);
|
2279
|
-
this.state$ = this.stateSubj$.asObservable().pipe(filter(isDefined));
|
2280
|
-
}
|
2281
|
-
get state() {
|
2282
|
-
return this.stateSubj$.getValue();
|
2283
|
-
}
|
2284
|
-
reset() {
|
2285
|
-
this.stateSubj$.next(null);
|
2286
|
-
}
|
2287
|
-
setState(state) {
|
2288
|
-
this.stateSubj$.next(state);
|
2289
|
-
}
|
1838
|
+
class FlowConfigurationModule {
|
2290
1839
|
}
|
2291
|
-
|
2292
|
-
|
2293
|
-
i0.ɵɵ
|
2294
|
-
|
1840
|
+
FlowConfigurationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
1841
|
+
FlowConfigurationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, imports: [ApiModule] });
|
1842
|
+
FlowConfigurationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, providers: [FlowConfigurationService], imports: [ApiModule] });
|
1843
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FlowConfigurationModule, decorators: [{
|
1844
|
+
type: NgModule,
|
1845
|
+
args: [{
|
1846
|
+
imports: [ApiModule],
|
1847
|
+
providers: [FlowConfigurationService],
|
1848
|
+
}]
|
2295
1849
|
}] });
|
2296
1850
|
|
1851
|
+
const FORMATTING_SETTINGS_TOKEN = new InjectionToken('Summary of formatting settings for variant types of data, e.g. numbers, text, dates, etc');
|
1852
|
+
|
1853
|
+
const UI_DEFINITION_VERSION = 3;
|
1854
|
+
|
2297
1855
|
const DEFAULT_FORMATTING_SETTINGS = {
|
2298
1856
|
currencySymbol: DEFAULT_CURRENCY_SYMBOL,
|
2299
1857
|
decimalsCount: DEFAULT_DECIMALS_COUNT,
|
@@ -2308,7 +1866,6 @@ SdkCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2308
1866
|
SdkCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, imports: [ConfigurationModule, FlowConfigurationModule] });
|
2309
1867
|
SdkCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SdkCoreModule, providers: [
|
2310
1868
|
FlowInfoService,
|
2311
|
-
QuoteDraftService,
|
2312
1869
|
ProductImagesService,
|
2313
1870
|
IntegrationState,
|
2314
1871
|
FlowStateService,
|
@@ -2327,7 +1884,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2327
1884
|
imports: [ConfigurationModule, FlowConfigurationModule],
|
2328
1885
|
providers: [
|
2329
1886
|
FlowInfoService,
|
2330
|
-
QuoteDraftService,
|
2331
1887
|
ProductImagesService,
|
2332
1888
|
IntegrationState,
|
2333
1889
|
FlowStateService,
|
@@ -2390,6 +1946,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2390
1946
|
}]
|
2391
1947
|
}] });
|
2392
1948
|
|
1949
|
+
function filterSuccessfulExecute() {
|
1950
|
+
return (source) => source.pipe(filter((result) => result.success), map(r => r.result));
|
1951
|
+
}
|
1952
|
+
|
2393
1953
|
class DatePipe {
|
2394
1954
|
constructor() {
|
2395
1955
|
this.locale = inject(LOCALE_ID);
|
@@ -2509,5 +2069,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
2509
2069
|
* Generated bundle index. Do not edit.
|
2510
2070
|
*/
|
2511
2071
|
|
2512
|
-
export { ActionCodePipe, CalendarDirective, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService, DEFAULT_FORMATTING_SETTINGS, DatePipe, FLOW_CUSTOMIZATION, FORMATTING_SETTINGS_TOKEN,
|
2072
|
+
export { ActionCodePipe, CalendarDirective, CatalogProductsService, ConfigurationRuntimeService, ConfigurationService, ConfigurationStateService, DEFAULT_FORMATTING_SETTINGS, DatePipe, FLOW_CUSTOMIZATION, FORMATTING_SETTINGS_TOKEN, FlowConfigurationService, FlowInfoService, FlowStateConfigurationService, FlowStateService, GuidedSellingService, IntegrationState, NumberPipe, PCMUtils, PricePipe, ProductImagesService, RuntimeSettingsService, SalesTransactionService, SdkCoreModule, SdkDirectivesModule, SdkPipesModule, TestModeConfigurationService, TransactionItemWorker, UI_DEFINITION_VERSION, extractMetadata, filterSuccessfulExecute, findTransactionItem, findTransactionItemWithComparator, flattenTransactionItem, generateTransactionItem, generateTransactionItemFromPCM, insertTransactionItem, removeTransactionItem, replaceTransactionItem, updateQuantity };
|
2513
2073
|
//# sourceMappingURL=veloceapps-sdk-core.mjs.map
|