@veloceapps/sdk 9.0.0-2 → 9.0.0-20

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,11 @@
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, 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, ConfigurationTranslatorUtils, ChargeGroupUtils, RuntimeModel, isNotLegacyUIDefinition, SalesforceIdUtils, DEFAULT_TIME_FORMAT, formatNumber } from '@veloceapps/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
4
  import * as i1 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, of, forkJoin, zip, combineLatest, Subject, filter as filter$1, shareReplay as shareReplay$1, finalize, takeUntil, buffer, debounceTime, share, take as take$1, distinctUntilChanged } from 'rxjs';
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
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, isEmpty, isEqual, cloneDeep, assign, flatten, entries, sortBy, map as map$2, uniqBy, omit, transform } from 'lodash';
8
+ import { merge, isEqual, cloneDeep, assign, flatten, entries, sortBy, map as map$2, uniqBy, omit, transform } from 'lodash';
9
9
  import * as i6 from '@veloceapps/components';
10
10
  import { ToastType, ConfirmationComponent, ConfirmationDialogModule } from '@veloceapps/components';
11
11
  import { HttpErrorResponse } from '@angular/common/http';
@@ -230,9 +230,6 @@ class FlowInfoService {
230
230
  this.templates = {};
231
231
  }
232
232
  initFlowTemplates$(flow) {
233
- if (isEmpty(flow.properties.templates)) {
234
- return of(undefined);
235
- }
236
233
  return forkJoin([
237
234
  this.templatesApiService.fetchTemplates$(),
238
235
  this.customizationService?.getTemplates?.() ?? of([]),
@@ -320,8 +317,9 @@ class QuoteDraftService {
320
317
  get assetsState() {
321
318
  return this.assetsSubj$.value;
322
319
  }
323
- constructor(context, accountApiService, quoteApiService) {
320
+ constructor(context, flowInfoService, accountApiService, quoteApiService) {
324
321
  this.context = context;
322
+ this.flowInfoService = flowInfoService;
325
323
  this.accountApiService = accountApiService;
326
324
  this.quoteApiService = quoteApiService;
327
325
  this.quoteSubj$ = new BehaviorSubject(null);
@@ -344,13 +342,21 @@ class QuoteDraftService {
344
342
  }
345
343
  init(headerId, params) {
346
344
  const ctx = this.context.resolve();
347
- const accountId = this.context.mode === ConfigurationContextMode.ACCOUNT ? headerId : ctx.properties.AccountId;
348
- return zip(accountId ? this.accountApiService.getAssetsState(accountId, params) : of(null), this.quoteApiService.getQuoteState(headerId, params)).pipe(tap(([assets, quote]) => {
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]) => {
349
350
  if (assets) {
350
351
  this.assetsSubj$.next(assets);
351
352
  }
352
353
  this.quoteSubj$.next(quote);
353
- this.context.update(quote.context);
354
+ if (assets && isAccountMode) {
355
+ this.context.update(assets.context);
356
+ }
357
+ else {
358
+ this.context.update(quote.context);
359
+ }
354
360
  }), map(() => noop()), take(1));
355
361
  }
356
362
  finalizeInit() {
@@ -419,10 +425,10 @@ class QuoteDraftService {
419
425
  return this.quoteDraft?.currentState ?? [];
420
426
  }
421
427
  get isStandalone() {
422
- return this.context.resolve().properties.standalone === 'true';
428
+ return this.flowInfoService.flow?.properties.standalone ?? false;
423
429
  }
424
430
  get isStandalone$() {
425
- return this.context.resolve$().pipe(map(() => this.isStandalone));
431
+ return this.flowInfoService.flow$.pipe(map(() => this.isStandalone));
426
432
  }
427
433
  getInitialCurrentState() {
428
434
  return this.initialCurrentState;
@@ -449,11 +455,11 @@ class QuoteDraftService {
449
455
  }
450
456
  }
451
457
  }
452
- QuoteDraftService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService, deps: [{ token: ContextService }, { token: i1.AccountApiService }, { token: i1.QuoteApiService }], target: i0.ɵɵFactoryTarget.Injectable });
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 });
453
459
  QuoteDraftService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService });
454
460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: QuoteDraftService, decorators: [{
455
461
  type: Injectable
456
- }], ctorParameters: function () { return [{ type: ContextService }, { type: i1.AccountApiService }, { type: i1.QuoteApiService }]; } });
462
+ }], ctorParameters: function () { return [{ type: ContextService }, { type: FlowInfoService }, { type: i1.AccountApiService }, { type: i1.QuoteApiService }]; } });
457
463
 
458
464
  class FlowStateService {
459
465
  constructor(contextService, quoteDraftService, flowInfoService, flowConfiguration, processorsApiService, flowStateApiService, quoteApiService, toastService, customizationService) {
@@ -474,7 +480,7 @@ class FlowStateService {
474
480
  this.processors = {};
475
481
  this.subscriptions = {};
476
482
  this.flowStore = {};
477
- this.statefulExecutionInProgress$ = new BehaviorSubject(false);
483
+ this.executionInProgress$ = new BehaviorSubject(false);
478
484
  this.statefulRequestStream$ = new Subject();
479
485
  this.cleanup$ = new Subject();
480
486
  this.statefulExecutionRequest$ = this.initBufferedRequest$();
@@ -560,7 +566,7 @@ class FlowStateService {
560
566
  return this.stateId$.value;
561
567
  }
562
568
  get isExecutionInProgress$() {
563
- return this.statefulExecutionInProgress$.asObservable();
569
+ return this.executionInProgress$.asObservable();
564
570
  }
565
571
  isInitialized$() {
566
572
  return combineLatest([this.stateId$, this.quoteDraftService.isInitialized$]).pipe(map$1(values => values.some(Boolean)));
@@ -754,15 +760,15 @@ class FlowStateService {
754
760
  .filter(isDefined)
755
761
  .reduce((acc, selectorsMap) => Object.assign(acc, selectorsMap), {}),
756
762
  };
757
- this.statefulExecutionInProgress$.next(true);
763
+ this.executionInProgress$.next(true);
758
764
  return this.flowStateApiService.execute(this.stateId$.value, request);
759
- }), tap$1(({ stateId }) => this.stateId$.next(stateId)), share(), tap$1(() => this.statefulExecutionInProgress$.next(false)), catchError(e => {
760
- this.statefulExecutionInProgress$.next(false);
765
+ }), tap$1(({ stateId }) => this.stateId$.next(stateId)), share(), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
766
+ this.executionInProgress$.next(false);
761
767
  return throwError(() => e);
762
768
  }));
763
769
  }
764
770
  executeStateful$(request) {
765
- return this.statefulExecutionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
771
+ return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
766
772
  // make sure stream switches to statefulExecutionRequest$ before pushing an execution request
767
773
  combineLatest([
768
774
  this.statefulExecutionRequest$,
@@ -803,6 +809,7 @@ class FlowStateService {
803
809
  return this.flowConfiguration.calculate$(flowState);
804
810
  }
805
811
  executeStateless$(request) {
812
+ this.executionInProgress$.next(true);
806
813
  return of(undefined).pipe(tap$1(() => this.executeStatelessActions(request)), switchMap(() => {
807
814
  /*
808
815
  Skip price calculation in case
@@ -815,7 +822,10 @@ class FlowStateService {
815
822
  else {
816
823
  return this.calculate$();
817
824
  }
818
- }), map$1(() => this.executeStatelessSelectors(request)));
825
+ }), map$1(() => this.executeStatelessSelectors(request)), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
826
+ this.executionInProgress$.next(false);
827
+ return throwError(() => e);
828
+ }));
819
829
  }
820
830
  executeStatelessActions(request) {
821
831
  if (!this.quoteDraftService.quoteDraft || !request.actions?.length) {
@@ -1416,7 +1426,12 @@ class ConfigurationService {
1416
1426
  this.showInactiveProductsConfirmation();
1417
1427
  }
1418
1428
  this.configurableRamp = result.lineItem;
1419
- }), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => new Error(error.error?.message || error.message || JSON.stringify(error)))), finalize$1(() => this.isLoadingSubj$.next(false)));
1429
+ }), map(({ lineItem }) => lineItem), catchError$1(error => throwError(() => {
1430
+ if (error.error) {
1431
+ return extractErrorDetails(error.error).join('. ');
1432
+ }
1433
+ return error.message || JSON.stringify(error);
1434
+ })), finalize$1(() => this.isLoadingSubj$.next(false)));
1420
1435
  }
1421
1436
  configureExternal$(props) {
1422
1437
  return this.runtimeService
@@ -2052,10 +2067,13 @@ class ConfigurationStateService {
2052
2067
  this.ownerId = '';
2053
2068
  this.subscriptions = {};
2054
2069
  this.configurationStore = {};
2055
- this.statefulExecutionInProgress$ = new BehaviorSubject(false);
2070
+ this.executionInProgress$ = new BehaviorSubject(false);
2056
2071
  this.statefulRequestStream$ = new Subject();
2057
2072
  this.statefulExecutionRequest$ = this.initBufferedRequest$();
2058
2073
  }
2074
+ get isExecutionInProgress$() {
2075
+ return this.executionInProgress$.asObservable();
2076
+ }
2059
2077
  init$() {
2060
2078
  let request$;
2061
2079
  if (this.flowStateService.stateId && this.isStatefulConfiguration) {
@@ -2079,68 +2097,57 @@ class ConfigurationStateService {
2079
2097
  this.executedFunctions = {};
2080
2098
  this.configurationService.reset();
2081
2099
  }
2082
- execute$(req, forceSubscriptions) {
2083
- const fullRequest = cloneDeep(req);
2084
- if (fullRequest.actions?.length || forceSubscriptions) {
2085
- for (const subscription of Object.values(this.subscriptions)) {
2086
- fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
2087
- }
2088
- }
2089
- let execution$;
2090
- if (this.isStatefulConfiguration) {
2091
- execution$ = this.executeStateful$(fullRequest);
2092
- }
2093
- else {
2094
- execution$ = this.executeStateless$(fullRequest);
2095
- }
2096
- return execution$.pipe(tap$1(result => this.handleSelectorsResponse(result.selectors)));
2097
- }
2098
- handleSelectorsResponse(selectors) {
2099
- Object.entries(selectors).forEach(([requestId, selectorResult]) => {
2100
- if (!selectorResult.success) {
2101
- this.toastService.add({ severity: ToastType.error, summary: selectorResult.errorMessage });
2102
- }
2103
- const subscription$ = this.subscriptions[requestId]?.data$;
2104
- if (subscription$) {
2105
- subscription$.next(selectorResult);
2106
- }
2107
- });
2100
+ execute$(exec) {
2101
+ const request = this.execToRequest(exec);
2102
+ return this.executeRequest$(request).pipe(map$1(result => {
2103
+ // Keep only requested results
2104
+ const actualSelectors = Object.entries(result.selectors).reduce((trunk, [requestId, result]) => {
2105
+ if (exec.selectors?.[requestId]) {
2106
+ trunk[requestId] = result;
2107
+ }
2108
+ return trunk;
2109
+ }, {});
2110
+ return actualSelectors;
2111
+ }));
2108
2112
  }
2109
2113
  dispatch$(actionName, inputData = {}) {
2110
- return this.execute$({ actions: [{ apiName: actionName, inputData, ownerId: this.ownerId }] });
2114
+ const exec = {
2115
+ actions: [{ name: actionName, inputData }],
2116
+ };
2117
+ const request = this.execToRequest(exec);
2118
+ return this.executeRequest$(request);
2111
2119
  }
2112
2120
  select$(selectorName, inputData = {}) {
2113
2121
  const requestId = UUID.UUID();
2114
- return this.execute$({
2122
+ const request = this.execToRequest({
2115
2123
  selectors: {
2116
2124
  [requestId]: {
2117
- apiName: selectorName,
2125
+ name: selectorName,
2118
2126
  inputData,
2119
- ownerId: this.ownerId,
2120
2127
  },
2121
2128
  },
2122
- }).pipe(map$1(response => response.selectors[requestId]));
2129
+ });
2130
+ return this.executeRequest$(request).pipe(map$1(response => response.selectors[requestId]));
2123
2131
  }
2124
2132
  subscribe$(selectorName, inputData = {}, options) {
2125
2133
  const requestId = UUID.UUID();
2126
2134
  let subscription = this.subscriptions[requestId];
2127
2135
  if (!subscription) {
2128
- const request = {
2136
+ const request = this.execToRequest({
2129
2137
  selectors: {
2130
2138
  [requestId]: {
2131
- apiName: selectorName,
2139
+ name: selectorName,
2132
2140
  inputData,
2133
- ownerId: this.ownerId,
2134
2141
  },
2135
2142
  },
2136
- };
2143
+ });
2137
2144
  subscription = {
2138
2145
  request,
2139
2146
  data$: new BehaviorSubject(this.NOT_INITIALIZED),
2140
2147
  };
2141
2148
  this.subscriptions[requestId] = subscription;
2142
2149
  if (!options?.cold) {
2143
- this.execute$(request).subscribe();
2150
+ this.executeRequest$(request).subscribe();
2144
2151
  }
2145
2152
  }
2146
2153
  return subscription.data$.pipe(filter$1(data => data != this.NOT_INITIALIZED), map$1(data => data), distinctUntilChanged(), finalize(() => {
@@ -2149,7 +2156,8 @@ class ConfigurationStateService {
2149
2156
  }
2150
2157
  }), takeUntil(this.canceledConfiguration$));
2151
2158
  }
2152
- saveConfiguration(quoteId, flow) {
2159
+ saveConfiguration(first, second) {
2160
+ const flow = typeof first === 'boolean' ? first : second;
2153
2161
  if (this.isStatefulConfiguration) {
2154
2162
  return this.flowStateApiService
2155
2163
  .saveConfiguration(this.flowStateService.stateId ?? '', this.stateId ?? '')
@@ -2157,16 +2165,15 @@ class ConfigurationStateService {
2157
2165
  }
2158
2166
  else {
2159
2167
  if (!flow) {
2160
- if (!quoteId) {
2168
+ const quoteDraft = this.quoteDraftService.quoteDraft;
2169
+ if (!quoteDraft) {
2161
2170
  return of({ quoteId: '' });
2162
2171
  }
2163
2172
  const rootLineItem = this.configurationService.getSnapshot();
2164
2173
  const asset = this.configurationService.getAsset();
2165
2174
  const currentState = rootLineItem ? [rootLineItem] : [];
2166
2175
  const initialState = asset ? [asset] : [];
2167
- return this.quoteApiService
2168
- .getQuoteState(quoteId)
2169
- .pipe(switchMap(quoteDraft => this.quoteApiService.upsertQuote({ ...quoteDraft, currentState, initialState })));
2176
+ return this.quoteApiService.upsertQuote({ ...quoteDraft, currentState, initialState });
2170
2177
  }
2171
2178
  else {
2172
2179
  const quoteDraft = this.quoteDraftService.quoteDraft;
@@ -2242,7 +2249,49 @@ class ConfigurationStateService {
2242
2249
  initStateless$() {
2243
2250
  return this.configurationService.configure().pipe(map$1(() => undefined));
2244
2251
  }
2252
+ execToRequest(exec) {
2253
+ return {
2254
+ actions: exec.actions?.map(action => ({
2255
+ apiName: action.name,
2256
+ ownerId: this.ownerId,
2257
+ inputData: action.inputData ?? {},
2258
+ })),
2259
+ selectors: exec.selectors &&
2260
+ Object.entries(exec.selectors).reduce((trunk, [key, selector]) => ({
2261
+ ...trunk,
2262
+ [key]: { apiName: selector.name, ownerId: this.ownerId, inputData: selector.inputData ?? {} },
2263
+ }), {}),
2264
+ };
2265
+ }
2266
+ handleSelectorsResponse(selectors) {
2267
+ Object.entries(selectors).forEach(([requestId, selectorResult]) => {
2268
+ if (!selectorResult.success) {
2269
+ this.toastService.add({ severity: ToastType.error, summary: selectorResult.errorMessage });
2270
+ }
2271
+ const subscription$ = this.subscriptions[requestId]?.data$;
2272
+ if (subscription$) {
2273
+ subscription$.next(selectorResult);
2274
+ }
2275
+ });
2276
+ }
2277
+ executeRequest$(req, forceSubscriptions) {
2278
+ const fullRequest = cloneDeep(req);
2279
+ if (fullRequest.actions?.length || forceSubscriptions) {
2280
+ for (const subscription of Object.values(this.subscriptions)) {
2281
+ fullRequest.selectors = assign(fullRequest.selectors, subscription.request.selectors);
2282
+ }
2283
+ }
2284
+ let execution$;
2285
+ if (this.isStatefulConfiguration) {
2286
+ execution$ = this.executeStateful$(fullRequest);
2287
+ }
2288
+ else {
2289
+ execution$ = this.executeStateless$(fullRequest);
2290
+ }
2291
+ return execution$.pipe(tap$1(result => this.handleSelectorsResponse(result.selectors)));
2292
+ }
2245
2293
  executeStateless$(request) {
2294
+ this.executionInProgress$.next(true);
2246
2295
  return of(undefined).pipe(switchMap(() => {
2247
2296
  // Apply actions and execute configuration/price call
2248
2297
  // No need to run configuration if no actions in the request
@@ -2253,6 +2302,7 @@ class ConfigurationStateService {
2253
2302
  request.actions.forEach(action => {
2254
2303
  configurationRequest = this.executeActionScript(configurationRequest, action) ?? configurationRequest;
2255
2304
  });
2305
+ configurationRequest = ConfigurationTranslatorUtils.lightenConfigurationRequest(configurationRequest);
2256
2306
  return this.configurationService.configureRequest$(configurationRequest);
2257
2307
  }), map$1(() => {
2258
2308
  // Run selectors and apply them to the state
@@ -2277,7 +2327,8 @@ class ConfigurationStateService {
2277
2327
  return result;
2278
2328
  }, { stateId: '', selectors: {} });
2279
2329
  return selectorsResult;
2280
- }), catchError(error => {
2330
+ }), tap$1(() => this.executionInProgress$.next(false)), catchError(error => {
2331
+ this.executionInProgress$.next(false);
2281
2332
  if (!this.configurationRuntimeService.uiDefinitionProperties.suppressToastMessages) {
2282
2333
  this.toastService.add({ severity: ToastType.error, summary: String(error) });
2283
2334
  }
@@ -2297,15 +2348,15 @@ class ConfigurationStateService {
2297
2348
  .filter(isDefined)
2298
2349
  .reduce((acc, selectorsMap) => Object.assign(acc, selectorsMap), {}),
2299
2350
  };
2300
- this.statefulExecutionInProgress$.next(true);
2351
+ this.executionInProgress$.next(true);
2301
2352
  return this.flowStateApiService.executeConfiguration(this.flowStateService.stateId, this.stateId, request);
2302
- }), tap$1(({ stateId }) => (this.stateId = stateId)), share(), tap$1(() => this.statefulExecutionInProgress$.next(false)), catchError(e => {
2303
- this.statefulExecutionInProgress$.next(false);
2353
+ }), tap$1(({ stateId }) => (this.stateId = stateId)), share(), tap$1(() => this.executionInProgress$.next(false)), catchError(e => {
2354
+ this.executionInProgress$.next(false);
2304
2355
  return throwError(() => e);
2305
2356
  }));
2306
2357
  }
2307
2358
  executeStateful$(request) {
2308
- return this.statefulExecutionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
2359
+ return this.executionInProgress$.pipe(filter$1(inProgress => !inProgress), take$1(1), switchMap(() =>
2309
2360
  // make sure stream switches to statefulExecutionRequest$ before pushing an execution request
2310
2361
  combineLatest([
2311
2362
  this.statefulExecutionRequest$,