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