Пример #1
0
        public Product Build(IProductBuilder builder)
        {
            builder.BuildAttribute1();
            builder.BuildAttribute2();
            builder.BuildAttribute3();
            builder.BuildAttribute4();
            builder.BuildAttribute5();
            builder.BuildAttribute6();

            return(builder.Build());
        }
Пример #2
0
        public IEnumerable <ProductViewModel> Get(long consumption)
        {
            if (consumption < 0)
            {
                throw new BadRequestException("Consumption have to be positive number");
            }

            _productBuilder.SetConsumption(consumption);
            var products = _productBuilder.Build();

            Array.Sort(products, _productComparer);

            return(_mapper.Map <IEnumerable <ProductViewModel> >(products));
        }
Пример #3
0
        public void NotifyUserForStock()
        {
            var items = _stockNotificationRepository.TableNoTracking
                        .Join(_productPriceRepository.Table, s => s.ProductId, pp => pp.ProductId, (s, pp) => new { s, pp })
                        .Join(_productRepository.Table, x => x.s.ProductId, p => p.Id, (x, p) => new { x.s, p, x.pp })
                        .Where(x => x.s.Notified == false)
                        .Where(x => x.p.Enabled == true)
                        .Where(x => x.pp.Stock > 0)
                        .Where(x => x.pp.Enabled == true)
                        .Select(x => new { x.s, x.p })
                        .ToList()
                        .Select(x => new { x.s, p = _productBuilder.Build(x.p) })
                        .ToList();

            foreach (var item in items)
            {
                var option  = string.Empty;
                var proceed = false;

                if (item.s.ProductPriceId > 0 && item.p.ProductPrices.Where(x => x.Id == item.s.ProductPriceId).Any())
                {
                    option  = item.p.ProductPrices.Where(x => x.Id == item.s.ProductPriceId).Select(x => x.Option).FirstOrDefault();
                    proceed = true;
                }
                else if (item.s.ProductPriceId == 0)
                {
                    proceed = true;
                }

                if (proceed)
                {
                    item.s.Notified      = true;
                    item.s.UpdatedOnDate = DateTime.Now;
                    _emailManager.SendBackInStockEmail(item.s.Email, item.p.Name, item.p.UrlRewrite, option, item.p.ProductMedias[0].MediaFilename);

                    _stockNotificationRepository.Update(item.s);
                }
            }
        }
Пример #4
0
        public CartOffer ProcessCartOfferAction(int profileId, IList <CartItem> items, string shippingCountryCode, OfferRule offerRule, OfferAction action, CartOffer cartOffer)
        {
            if (action == null)
            {
                return(cartOffer);
            }

            List <CartItem> list;
            decimal         matchedAmount = 0M;
            decimal         discount      = 0M;
            int             steps         = 0;
            Country         country       = _countryRepository.Table.Where(x => x.ISO3166Code == shippingCountryCode).FirstOrDefault();

            cartOffer.FreeDelivery = action.FreeShipping;
            cartOffer.RewardPoint += action.RewardPoint;

            switch (action.OfferActionAttributeId)
            {
                #region FIXED_PERCENT_DISCOUNT_FOR_PRODUCT_SUBSELECTION

            case FIXED_PERCENT_DISCOUNT_FOR_PRODUCT_SUBSELECTION:
                // Run acton condition first
                if (offerRule.Action.Condition != null && offerRule.Action.Condition.ChildOfferConditions.Count > 0)
                {
                    matchedAmount = CalculateActionMatchedAmount(items, offerRule, action.Condition, country.IsEC);
                }
                else     // Else use condition from offer rule..
                {
                    matchedAmount = CalculateActionMatchedAmount(items, offerRule, offerRule.Condition, country.IsEC);
                }

                discount = matchedAmount / 100M * action.DiscountAmount.Value;
                cartOffer.Discounts.Add(offerRule.Id, discount);
                cartOffer.DiscountAmount += discount;
                cartOffer.IsValid         = true;
                break;

                #endregion

                #region FIXED_PERCENT_DISCOUNT_FOR_WHOLE_CART

            case FIXED_PERCENT_DISCOUNT_FOR_WHOLE_CART:
                if (country.IsEC)
                {
                    discount = items.Select(x => x.ProductPrice.OfferPriceInclTax * x.Quantity)
                               .DefaultIfEmpty(0).Sum() * Convert.ToInt32(action.DiscountAmount.Value) / 100;
                }
                else
                {
                    discount = items.Select(x => x.ProductPrice.OfferPriceExclTax * x.Quantity)
                               .DefaultIfEmpty(0).Sum() * Convert.ToInt32(action.DiscountAmount.Value) / 100;
                }

                cartOffer.DiscountAmount += discount;
                cartOffer.Discounts.Add(offerRule.Id, discount);

                cartOffer.IsValid = true;
                break;

                #endregion

                #region FIXED_AMOUNT_DISCOUNT_FOR_WHOLE_CART

            case FIXED_AMOUNT_DISCOUNT_FOR_WHOLE_CART:
                cartOffer.DiscountAmount += action.DiscountAmount.Value;
                cartOffer.Discounts.Add(offerRule.Id, action.DiscountAmount.Value);
                cartOffer.IsValid = true;
                break;

                #endregion

                #region FREE_ITEM_OFFER

            case FREE_ITEM_OFFER:
                bool proceed = false;

                if (action.MinimumAmount.HasValue)
                {
                    if (action.Condition == null)
                    {
                        proceed = true;
                    }
                    else
                    {
                        proceed = CalculateActionMatchedAmount(items, offerRule, action.Condition, country.IsEC) > action.MinimumAmount.Value;
                    }
                }
                else
                {
                    proceed = true;
                }

                int qtyStep  = 1;
                int qtyFound = 1;

                if (action.DiscountQtyStep.HasValue && proceed)
                {
                    // To calculate how many free items need to be added
                    qtyStep = action.DiscountQtyStep.Value;

                    if (action.Condition == null || action.Condition.ChildOfferConditions.Count == 0)
                    {
                        qtyFound = CalculateActionMatchedQty(items, offerRule, offerRule.Condition);
                    }
                    else
                    {
                        qtyFound = CalculateActionMatchedQty(items, offerRule, action.Condition);
                    }

                    proceed = qtyFound > 0;
                }

                bool isByOption = action.OptionOperator != null;

                var foundList = new List <CartItem>();

                // If there is an action condition
                if (offerRule.Action.Condition != null && offerRule.Action.Condition.ChildOfferConditions.Count > 0)
                {
                    foundList = GetActionMatchedItems(items, offerRule, action.Condition);
                }
                else     // Else use condition from offer rule
                {
                    foundList = GetActionMatchedItems(items, offerRule, offerRule.Condition);
                }

                list = new List <CartItem>();

                if (isByOption)
                {
                    for (int i = 0; i < foundList.Count; i++)
                    {
                        if (foundList[i].ProductPrice.OfferRuleId <= 0)
                        {
                            string targetOption = foundList[i].ProductPrice.Option;
                            bool   isOkay       = _attributeUtility.ValidateAttribute(targetOption, action.OptionOperator.Operator, action.OptionOperand);

                            if (isOkay)
                            {
                                list.Add(foundList[i]);
                            }
                        }
                    }

                    if (list.Count > 0)
                    {
                        proceed = true;
                    }
                }
                else
                {
                    list = foundList;
                }

                if (proceed)
                {
                    // TODO: Do we need to prevent other process?
                    // Flag item with offer rule id to prevent other process
                    //FlagOfferRuleIdInBasket(action.OfferRuleId, list.Select(x => x.Id).ToList());

                    // Add free item
                    if (action.FreeProductItself.Value)
                    {
                        for (int i = 0; i < list.Count; i++)
                        {
                            if (list[i].Product == null)
                            {
                                _logger.InsertLog(LogLevel.Warning, string.Format("Free item could not be loaded. Product ID={{{0}}}", list[i].ProductId));
                                break;
                            }

                            if (list[i].ProductPrice == null)
                            {
                                _logger.InsertLog(LogLevel.Warning, string.Format("Product price for free item could not be loaded. Product Price ID={{{0}}}", list[i].ProductPriceId));
                                break;
                            }

                            if (list[i].Product.Brand == null)
                            {
                                _logger.InsertLog(LogLevel.Warning, string.Format("Brand for free item could not be loaded. Brand ID={{{0}}}", list[i].Product.BrandId));
                                break;
                            }

                            var message = _cartValidator.ValidateCartItem(
                                profileId,
                                list[i].ProductId,
                                list[i].Product.BrandId,
                                shippingCountryCode,
                                list[i].Product.IsPharmaceutical,
                                list[i].Product.Discontinued,
                                list[i].ProductPrice.Stock,
                                list[i].Product.Name,
                                list[i].Product.EnforceStockCount,
                                list[i].Product.Brand.EnforceStockCount,
                                list[i].Product.Enabled,
                                list[i].ProductPrice.Enabled,
                                list[i].Quantity,
                                list[i].Quantity / qtyStep,
                                list[i].Product.StepQuantity,
                                list[i].Product.IsPhoneOrder,
                                list[i].ProductPrice.OfferPriceExclTax,
                                allowZeroPrice: true);

                            // Empty message is ok status from cart item validation
                            if (string.IsNullOrEmpty(message))
                            {
                                var cartItem = new CartItem
                                {
                                    ProfileId      = profileId,
                                    ProductPriceId = list[i].ProductPriceId,
                                    ProductId      = list[i].ProductId,
                                    Quantity       = list[i].Quantity / qtyStep,
                                    Product        = list[i].Product,
                                    ProductPrice   = list[i].ProductPrice,
                                    CartItemMode   = (int)CartItemMode.FreeItem
                                };

                                items.Add(cartItem);
                            }
                        }
                    }
                    else
                    {
                        // Load free item
                        var freeItem = _productBuilder.Build(action.FreeProductId.Value);
                        if (freeItem == null)
                        {
                            _logger.InsertLog(LogLevel.Warning, string.Format("Free item could not be loaded. Product ID={{{0}}}", action.FreeProductId.Value));
                            break;
                        }

                        var freeItemPriceOption = freeItem.ProductPrices.Where(x => x.Id == action.FreeProductPriceId).FirstOrDefault();
                        if (freeItemPriceOption == null)
                        {
                            _logger.InsertLog(LogLevel.Warning, string.Format("Product price for free item could not be loaded. Product Price ID={{{0}}}", action.FreeProductPriceId));
                            break;
                        }

                        if (freeItem.Brand == null)
                        {
                            _logger.InsertLog(LogLevel.Warning, string.Format("Brand for free item could not be loaded. Brand ID={{{0}}}", freeItem.BrandId));
                            break;
                        }

                        // While stock lasts
                        if (freeItemPriceOption.Stock > 0)
                        {
                            var message = _cartValidator.ValidateCartItem(
                                profileId,
                                freeItem.Id,
                                freeItem.BrandId,
                                shippingCountryCode,
                                freeItem.IsPharmaceutical,
                                freeItem.Discontinued,
                                freeItemPriceOption.Stock,
                                freeItem.Name,
                                freeItem.EnforceStockCount,
                                freeItem.Brand.EnforceStockCount,
                                freeItem.Enabled,
                                freeItemPriceOption.Enabled,
                                0,
                                action.FreeProductQty.Value * (qtyFound / qtyStep),
                                freeItem.StepQuantity,
                                freeItem.IsPhoneOrder,
                                freeItemPriceOption.OfferPriceExclTax,
                                allowZeroPrice: true);

                            // Empty message is ok status from cart item validation
                            if (string.IsNullOrEmpty(message))
                            {
                                var cartItem = new CartItem
                                {
                                    ProfileId      = profileId,
                                    ProductPriceId = freeItemPriceOption.Id,
                                    ProductId      = freeItem.Id,
                                    Quantity       = action.FreeProductQty.Value * (qtyFound / qtyStep),
                                    Product        = freeItem,
                                    ProductPrice   = freeItemPriceOption,
                                    CartItemMode   = (int)CartItemMode.FreeItem
                                };

                                items.Add(cartItem);
                            }
                        }
                    }
                }

                cartOffer.IsValid = true;

                break;

                #endregion

                #region DO_NOTHING

            case DO_NOTHING:
                // do nothing
                cartOffer.IsValid = true;
                break;

                #endregion

                #region BUY_X_QUANTITY_FOR_Y_QUANTITY

            case BUY_X_QUANTITY_FOR_Y_QUANTITY:

                // Must have X quantity
                // Must have Y quantity
                // X > Y
                if (offerRule.Action.XValue.HasValue && offerRule.Action.YValue.HasValue &&
                    offerRule.Action.XValue > offerRule.Action.YValue)
                {
                    list = new List <CartItem>();

                    if (offerRule.Action.Condition != null && offerRule.Action.Condition.ChildOfferConditions.Count > 0)     // If there is condition for action
                    {
                        list = GetActionMatchedItems(items, offerRule, action.Condition);
                    }
                    else     // Else use condition from offer rule..
                    {
                        list = GetActionMatchedItems(items, offerRule, offerRule.Condition);
                    }

                    // Revert to old price if necessary
                    if (offerRule.UseInitialPrice)
                    {
                        SetToUseInitialPrice(list);
                    }

                    // List down individual price
                    List <decimal> listIndividualPrice = new List <decimal>();

                    for (int i = 0; i < list.Count; i++)
                    {
                        for (int j = 0; j < list[i].Quantity; j++)
                        {
                            if (country.IsEC)
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceInclTax);
                            }
                            else
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceExclTax);
                            }
                        }
                    }

                    // Calculate how many steps for X quantity
                    steps = listIndividualPrice.Count / offerRule.Action.XValue.Value;

                    // Find quantity X of total value
                    decimal totalXValue = 0M;

                    for (int i = 0; i < offerRule.Action.XValue.Value; i++)
                    {
                        if (i < listIndividualPrice.Count)
                        {
                            totalXValue += listIndividualPrice[i];
                        }
                    }

                    // Find quantity Y of total value
                    decimal totalYValue = 0M;

                    for (int i = 0; i < offerRule.Action.YValue.Value; i++)
                    {
                        if (i < listIndividualPrice.Count)
                        {
                            totalYValue += listIndividualPrice[i];
                        }
                    }

                    // Get the difference
                    decimal differenceValue = totalXValue - totalYValue;

                    discount = steps * differenceValue;

                    cartOffer.DiscountAmount += discount;
                    cartOffer.Discounts.Add(offerRule.Id, discount);
                }

                cartOffer.IsValid = true;
                break;

                #endregion

                #region BUY_X_QUANTITY_FOR_Y_PRICE

            case BUY_X_QUANTITY_FOR_Y_PRICE:

                // Must have X quantity
                // Must have Y price
                if (offerRule.Action.XValue.HasValue && offerRule.Action.YValue.HasValue)
                {
                    list = new List <CartItem>();

                    if (offerRule.Action.Condition != null && offerRule.Action.Condition.ChildOfferConditions.Count > 0)     // If there is condition for action
                    {
                        list = GetActionMatchedItems(items, offerRule, action.Condition);
                    }
                    else     // Else use condition from offer rule..
                    {
                        list = GetActionMatchedItems(items, offerRule, offerRule.Condition);
                    }

                    // Revert to old price if necessary
                    if (offerRule.UseInitialPrice)
                    {
                        SetToUseInitialPrice(list);
                    }

                    // List down individual price
                    List <decimal> listIndividualPrice = new List <decimal>();
                    decimal        totalValue          = 0M;

                    for (int i = 0; i < list.Count; i++)
                    {
                        for (int j = 0; j < list[i].Quantity; j++)
                        {
                            if (country.IsEC)
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceInclTax);
                                totalValue += list[i].ProductPrice.OfferPriceInclTax;
                            }
                            else
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceExclTax);
                                totalValue += list[i].ProductPrice.OfferPriceExclTax;
                            }
                        }
                    }

                    // Calculate how many steps for X quantity
                    steps = listIndividualPrice.Count / offerRule.Action.XValue.Value;

                    // Find total value
                    int lastRemoveCount = listIndividualPrice.Count % offerRule.Action.XValue.Value;

                    if (lastRemoveCount != 0)
                    {
                        for (int i = 0; i < lastRemoveCount; i++)
                        {
                            totalValue -= listIndividualPrice[listIndividualPrice.Count - 1 - i];
                        }
                    }

                    // Find total value of Y in current currency
                    decimal totalYValue = steps * (offerRule.Action.YValue.Value);

                    // Get the difference
                    discount = totalValue - totalYValue;

                    cartOffer.DiscountAmount += discount;
                    cartOffer.Discounts.Add(offerRule.Id, discount);
                }

                cartOffer.IsValid = true;

                break;

                #endregion

                #region BUY_X_QUANTITY_CHEAPEST_FREE

            case BUY_X_QUANTITY_CHEAPEST_FREE:

                // Must have X quantity
                if (offerRule.Action.XValue.HasValue)
                {
                    list = new List <CartItem>();

                    if (offerRule.Action.Condition != null && offerRule.Action.Condition.ChildOfferConditions.Count > 0)     // If there is condition for action
                    {
                        list = GetActionMatchedItems(items, offerRule, action.Condition);
                    }
                    else     // Else use condition from offer rule..
                    {
                        list = GetActionMatchedItems(items, offerRule, offerRule.Condition);
                    }

                    // List down individual price
                    List <decimal> listIndividualPrice = new List <decimal>();
                    decimal        totalValue          = 0M;

                    for (int i = 0; i < list.Count; i++)
                    {
                        for (int j = 0; j < list[i].Quantity; j++)
                        {
                            if (country.IsEC)
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceInclTax);
                                totalValue += list[i].ProductPrice.OfferPriceInclTax;
                            }
                            else
                            {
                                listIndividualPrice.Add(list[i].ProductPrice.OfferPriceExclTax);
                                totalValue += list[i].ProductPrice.OfferPriceExclTax;
                            }
                        }
                    }

                    // Calculate how many steps for X quantity
                    steps = listIndividualPrice.Count / offerRule.Action.XValue.Value;

                    // Get the smallest price
                    listIndividualPrice.Sort(delegate(decimal price1, decimal price2)
                    {
                        return(price1.CompareTo(price2));
                    });

                    for (int i = 0; i < steps; i++)
                    {
                        discount += listIndividualPrice[i];
                    }

                    cartOffer.DiscountAmount += discount;
                    cartOffer.Discounts.Add(offerRule.Id, discount);
                }

                cartOffer.IsValid = true;
                break;

                #endregion
            }

            cartOffer.DiscountAmount = Math.Round(cartOffer.DiscountAmount, 2, MidpointRounding.AwayFromZero);

            return(cartOffer);
        }
Пример #5
0
        public string ProcessItemAddition(
            int profileId,
            int productId,
            int productPriceId,
            string shippingCountryCode,
            int quantity,
            int testOfferRuleId         = 0,
            bool disablePhoneOrderCheck = false)
        {
            var message = string.Empty;

            try
            {
                var product = _productBuilder.Build(productId);
                if (product == null)
                {
                    throw new ApolloException("Product could not be loaded. Product ID={{{0}}}", productId);
                }

                var productPrice = product.ProductPrices.Where(x => x.Id == productPriceId).FirstOrDefault();
                if (productPrice == null)
                {
                    throw new ApolloException("Product price could not be loaded. Product ID={{{0}}}, Product Price ID={{{0}}}", productId, productPriceId);
                }

                // Validate cart item first
                var quantityInCart = _cartItemRepository.Table
                                     .Where(c => c.ProfileId == profileId)
                                     .Where(c => c.ProductPriceId == productPriceId)
                                     .Where(c => c.CartItemMode != (int)CartItemMode.FreeItem)
                                     .Select(c => c.Quantity)
                                     .DefaultIfEmpty(0)
                                     .Sum();

                message = _cartValidator.ValidateCartItem(profileId,
                                                          productId,
                                                          product.Brand.Id,
                                                          shippingCountryCode,
                                                          product.IsPharmaceutical,
                                                          product.Discontinued,
                                                          productPrice.Stock,
                                                          product.Name,
                                                          product.EnforceStockCount,
                                                          product.Brand.EnforceStockCount,
                                                          product.Enabled,
                                                          productPrice.Enabled,
                                                          quantityInCart,
                                                          quantity,
                                                          product.StepQuantity,
                                                          disablePhoneOrderCheck ? false : product.IsPhoneOrder,
                                                          productPrice.OfferPriceExclTax,
                                                          product.Id == 0);

                // Empty message is ok status from cart item validation
                if (string.IsNullOrEmpty(message))
                {
                    var status = false;
                    message = "Sorry, an error occurred while creating/updating item.";

                    var cartItem = new CartItem
                    {
                        ProfileId      = profileId,
                        ProductPriceId = productPriceId,
                        ProductId      = productId,
                        Quantity       = quantity
                    };

                    status = EditCartItem(profileId, cartItem);

                    if (status)
                    {
                        message = string.Empty;
                        ProcessCartOfferByProfileId(profileId, shippingCountryCode, testOfferRuleId);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.InsertLog(LogLevel.Error, "Error occurred while creating/updating item. " + ex.Message, ex);
                message = "Sorry, an error occurred while creating/updating item.";
            }

            return(message);
        }