@veloceapps/sdk 11.0.0-8 → 11.0.0-80

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