Esempio n. 1
0
        /// <summary>
        /// Gets the final price for a child product by running a nested calculation pipeline.
        /// </summary>
        /// <param name="childProduct">
        /// The child product (e.g. associated product of a grouped product or a bundle item part) to calculate price for.
        /// Must not be the same product as <see cref="PriceCalculationContext.Product"/>.
        /// </param>
        /// <param name="context">The calculator context of the root pipeline.</param>
        /// <param name="childContextConfigurer">An optional configurer action for the child context.</param>
        /// <returns>The nested calculator context.</returns>
        protected async Task <CalculatorContext> CalculateChildPriceAsync(Product childProduct, CalculatorContext context, Action <CalculatorContext> childContextConfigurer = null)
        {
            if (context.Product == childProduct)
            {
                throw new InvalidOperationException("The product of a nested calculation pipeline cannot be the same as that of the root pipeline. It would result in a deadlock.");
            }

            var childCalculatorContext = new CalculatorContext(context, childProduct.Price)
            {
                Product = childProduct
            };

            childContextConfigurer?.Invoke(childCalculatorContext);

            // INFO: we know that options have been cloned.
            if (context.Options.ChildProductsBatchContext != null)
            {
                childCalculatorContext.Options.BatchContext = context.Options.ChildProductsBatchContext;
            }

            // Get calculators for child product context
            var calculators = _calculatorFactory.GetCalculators(childCalculatorContext);

            // Run calculators
            await _calculatorFactory.RunCalculators(calculators, childCalculatorContext);

            return(childCalculatorContext);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the final price for a child product by running a nested calculation pipeline.
        /// </summary>
        /// <param name="childProduct">
        /// The child product (e.g. associated product of a grouped product or a bundle item part) to calculate price for.
        /// </param>
        /// <param name="context">The calculator context of the root pipeline.</param>
        /// <param name="childContextConfigurer">An optional configurer action for the child context.</param>
        /// <returns>The nested calculator context.</returns>
        protected async Task <CalculatorContext> CalculateChildPriceAsync(Product childProduct, CalculatorContext context, Action <CalculatorContext> childContextConfigurer = null)
        {
            if (context.Product == childProduct)
            {
                // TODO: (core) Decent error message for price calculation deadlocking.
                throw new InvalidOperationException("Deadlock");
            }

            var childCalculatorContext = new CalculatorContext(context, childProduct.Price)
            {
                Product = childProduct
            };

            childContextConfigurer?.Invoke(childCalculatorContext);

            // INFO: we know that options have been cloned.
            if (context.Options.ChildProductsBatchContext != null)
            {
                childCalculatorContext.Options.BatchContext = context.Options.ChildProductsBatchContext;
            }

            // Get calculators for child product context
            var calculators = _calculatorFactory.GetCalculators(childCalculatorContext);

            // Run calculators
            await _calculatorFactory.RunCalculators(calculators, childCalculatorContext);

            return(childCalculatorContext);
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the final price for a child product by running a nested calculation pipeline.
        /// </summary>
        /// <returns>The nested calculator context.</returns>
        protected async Task <CalculatorContext> CalculateChildPriceAsync(Product childProduct, CalculatorContext context)
        {
            if (context.Product == childProduct)
            {
                // TODO: (core) Decent error message for price calculation deadlocking.
                throw new InvalidOperationException("Deadlock");
            }

            var childCalculatorContext = new CalculatorContext(context, childProduct.Price)
            {
                Product  = childProduct,
                Quantity = int.MaxValue
            };

            // INFO: we know that options have been cloned.
            childCalculatorContext.Options.BatchContext          = context.Options.ChildProductsBatchContext;
            childCalculatorContext.Options.IgnoreGroupedProducts = true;
            childCalculatorContext.Options.IgnoreBundles         = true;

            // Get calculators for child product context
            var calculators = _calculatorFactory.GetCalculators(childCalculatorContext);

            // Run calculators
            await _calculatorFactory.RunCalculators(calculators, childCalculatorContext);

            return(childCalculatorContext);
        }
        private async Task <CalculatorContext> RunCalculators(PriceCalculationContext context)
        {
            Guard.NotNull(context, nameof(context));

            // Remember source product.
            var product = context.Product;

            // Collect calculators
            var calculators       = _calculatorFactory.GetCalculators(context);
            var calculatorContext = new CalculatorContext(context, product.Price);

            // Run all collected calculators
            await _calculatorFactory.RunCalculators(calculators, calculatorContext);

            return(calculatorContext);
        }