Ejemplo n.º 1
0
        public PaymentDetailsItemType CreatePaymentItem(ShoppingCartItem item)
        {
            var product = _productService.GetProductById(item.ProductId);

            if (product is null)
            {
                throw new NopException("Product is not found");
            }

            var productPrice = _taxService.GetProductPrice(product,
                                                           _shoppingCartService.GetUnitPrice(item), false,
                                                           _workContext.CurrentCustomer, out _);

            var currencyCodeType       = _payPalCurrencyCodeParser.GetCurrencyCodeType(_workContext.WorkingCurrency);
            var paymentDetailsItemType = new PaymentDetailsItemType
            {
                Name = product.Name,
                //Description = _productAttributeFormatter.FormatAttributes(item.ProductVariant, item.AttributesXml),
                Amount       = productPrice.GetBasicAmountType(currencyCodeType),
                ItemCategory =
                    product.IsDownload
                        ? ItemCategoryType.Digital
                        : ItemCategoryType.Physical,
                Quantity = item.Quantity.ToString()
            };

            return(paymentDetailsItemType);
        }
        private async Task <(string Price, string PriceWithDiscount)> PreparePrice(Product product, GetSearchAutoComplete request)
        {
            string price, priceWithDiscount;

            double finalPriceWithoutDiscount =
                (await(_taxService.GetProductPrice(product,
                                                   (await _pricingService.GetFinalPrice(product, request.Customer, request.Currency, includeDiscounts: false)).finalPrice))).productprice;

            var appliedPrice           = (await _pricingService.GetFinalPrice(product, request.Customer, request.Currency, includeDiscounts: true));
            var finalPriceWithDiscount = (await _taxService.GetProductPrice(product, appliedPrice.finalPrice)).productprice;

            price             = _priceFormatter.FormatPrice(finalPriceWithoutDiscount);
            priceWithDiscount = _priceFormatter.FormatPrice(finalPriceWithDiscount);

            return(price, priceWithDiscount);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the base price info
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="localizationService">Localization service</param>
        /// <param name="priceFormatter">Price formatter</param>
        /// <param name="currencyService">Currency service</param>
        /// <param name="taxService">Tax service</param>
        /// <param name="priceCalculationService">Price calculation service</param>
        /// <param name="currency">Target currency</param>
        /// <param name="priceAdjustment">Price adjustment</param>
        /// <param name="languageInsensitive">Whether the result string should be language insensitive</param>
        /// <returns>The base price info</returns>
        public static string GetBasePriceInfo(this Product product,
                                              ILocalizationService localizationService,
                                              IPriceFormatter priceFormatter,
                                              ICurrencyService currencyService,
                                              ITaxService taxService,
                                              IPriceCalculationService priceCalculationService,
                                              Currency currency,
                                              decimal priceAdjustment  = decimal.Zero,
                                              bool languageInsensitive = false)
        {
            Guard.ArgumentNotNull(() => product);
            Guard.ArgumentNotNull(() => currencyService);
            Guard.ArgumentNotNull(() => taxService);
            Guard.ArgumentNotNull(() => priceCalculationService);
            Guard.ArgumentNotNull(() => currency);

            if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero)
            {
                var workContext = EngineContext.Current.Resolve <IWorkContext>();

                var taxrate      = decimal.Zero;
                var currentPrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, true);
                var price        = taxService.GetProductPrice(product, decimal.Add(currentPrice, priceAdjustment), out taxrate);

                price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency);

                return(product.GetBasePriceInfo(price, localizationService, priceFormatter, currency, languageInsensitive));
            }

            return("");
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the base price info
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="localizationService">Localization service</param>
        /// <param name="priceFormatter">Price formatter</param>
        /// <param name="currencyService">Currency service</param>
        /// <param name="taxService">Tax service</param>
        /// <param name="priceCalculationService">Price calculation service</param>
        /// <param name="customer">Customer</param>
        /// <param name="currency">Target currency</param>
        /// <param name="priceAdjustment">Price adjustment</param>
        /// <returns>The base price info</returns>
        public static string GetBasePriceInfo(this Product product,
                                              ILocalizationService localizationService,
                                              IPriceFormatter priceFormatter,
                                              ICurrencyService currencyService,
                                              ITaxService taxService,
                                              IPriceCalculationService priceCalculationService,
                                              Customer customer,
                                              Currency currency,
                                              decimal priceAdjustment = decimal.Zero)
        {
            Guard.NotNull(product, nameof(product));
            Guard.NotNull(currencyService, nameof(currencyService));
            Guard.NotNull(taxService, nameof(taxService));
            Guard.NotNull(priceCalculationService, nameof(priceCalculationService));
            Guard.NotNull(customer, nameof(customer));
            Guard.NotNull(currency, nameof(currency));

            if (product.BasePriceHasValue && product.BasePriceAmount != decimal.Zero)
            {
                var currentPrice = priceCalculationService.GetFinalPrice(product, customer, true);
                var price        = taxService.GetProductPrice(product, decimal.Add(currentPrice, priceAdjustment), customer, currency, out var taxrate);
                price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency);

                return(product.GetBasePriceInfo(price, localizationService, priceFormatter, currency));
            }

            return(string.Empty);
        }
        public void Can_get_productPrice_priceIncludesTax_includingTax_taxable()
        {
            var customer = new Customer();
            var product  = new Product();

            _taxService.GetProductPrice(product, 0, 1000M, true, customer, true, out decimal taxRate).ShouldEqual(1000);
            _taxService.GetProductPrice(product, 0, 1000M, true, customer, false, out taxRate).ShouldEqual(1100);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, true, out taxRate).ShouldEqual(909.0909090909090909090909091M);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, false, out taxRate).ShouldEqual(1000);
        }
Ejemplo n.º 6
0
        public ActionResult GetCartDetails(int customerId)
        {
            var gridModel = new GridModel <ShoppingCartItemModel>();

            if (Services.Permissions.Authorize(StandardPermissionProvider.ManageOrders))
            {
                decimal taxRate;
                var     customer = _customerService.GetCustomerById(customerId);
                var     cart     = customer.GetCartItems(ShoppingCartType.ShoppingCart);

                gridModel.Data = cart.Select(sci =>
                {
                    var store = Services.StoreService.GetStoreById(sci.Item.StoreId);

                    var sciModel = new ShoppingCartItemModel
                    {
                        Id                   = sci.Item.Id,
                        Store                = store != null ? store.Name : "".NaIfEmpty(),
                        ProductId            = sci.Item.ProductId,
                        Quantity             = sci.Item.Quantity,
                        ProductName          = sci.Item.Product.Name,
                        ProductTypeName      = sci.Item.Product.GetProductTypeLabel(Services.Localization),
                        ProductTypeLabelHint = sci.Item.Product.ProductTypeLabelHint,
                        UnitPrice            = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)),
                        Total                = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)),
                        UpdatedOn            = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc)
                    };

                    return(sciModel);
                });

                gridModel.Total = cart.Count;
            }
            else
            {
                gridModel.Data = Enumerable.Empty <ShoppingCartItemModel>();

                NotifyAccessDenied();
            }

            return(new JsonResult
            {
                Data = gridModel
            });
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Prepare paged shopping cart item list model
        /// </summary>
        /// <param name="searchModel">Shopping cart item search model</param>
        /// <param name="customer">Customer</param>
        /// <returns>Shopping cart item list model</returns>
        public virtual ShoppingCartItemListModel PrepareShoppingCartItemListModel(ShoppingCartItemSearchModel searchModel, Customer customer)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (customer == null)
            {
                throw new ArgumentNullException(nameof(customer));
            }

            //get shopping cart items
            var items = customer.ShoppingCartItems.Where(item => item.ShoppingCartType == searchModel.ShoppingCartType).ToList();

            //prepare list model
            var model = new ShoppingCartItemListModel
            {
                Data = items.PaginationByRequestModel(searchModel).Select(item =>
                {
                    //fill in model values from the entity
                    var itemModel = item.ToModel <ShoppingCartItemModel>();

                    //convert dates to the user time
                    itemModel.UpdatedOn = _dateTimeHelper.ConvertToUserTime(item.UpdatedOnUtc, DateTimeKind.Utc);

                    //fill in additional values (not existing in the entity)
                    itemModel.Store         = _storeService.GetStoreById(item.StoreId)?.Name ?? "Deleted";
                    itemModel.AttributeInfo = _productAttributeFormatter.FormatAttributes(item.Product, item.AttributesXml, item.Customer);
                    var unitPrice           = _priceCalculationService.GetUnitPrice(item);
                    itemModel.UnitPrice     = _priceFormatter.FormatPrice(_taxService.GetProductPrice(item.Product, unitPrice, out var _));
                    var subTotal            = _priceCalculationService.GetSubTotal(item);
                    itemModel.Total         = _priceFormatter.FormatPrice(_taxService.GetProductPrice(item.Product, subTotal, out _));

                    return(itemModel);
                }),
                Total = items.Count
            };

            return(model);
        }

        #endregion
    }
Ejemplo n.º 8
0
        public void CanGetProductPricePriceIncludesTaxIncludingTaxTaxable()
        {
            var customer = new Customer();
            var product  = new Product();

            _taxService.GetProductPrice(product, 0, 1000M, true, customer, true, out _).Should().Be(1000);
            _taxService.GetProductPrice(product, 0, 1000M, true, customer, false, out _).Should().Be(1100);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, true, out _).Should()
            .Be(909.0909090909090909090909091M);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, false, out _).Should().Be(1000);
        }
Ejemplo n.º 9
0
        private async Task <(string Price, string PriceWithDiscount)> PreparePrice(Product product, GetSearchAutoComplete request)
        {
            string price, priceWithDiscount;

            decimal finalPriceWithoutDiscountBase =
                (await(_taxService.GetProductPrice(product,
                                                   (await _priceCalculationService.GetFinalPrice(product, request.Customer, includeDiscounts: false)).finalPrice))).productprice;

            var appliedPrice = (await _priceCalculationService.GetFinalPrice(product, request.Customer, includeDiscounts: true));
            var finalPriceWithDiscountBase = (await _taxService.GetProductPrice(product, appliedPrice.finalPrice)).productprice;

            var finalPriceWithoutDiscount = await _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceWithoutDiscountBase, request.Currency);

            var finalPriceWithDiscount = await _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceWithDiscountBase, request.Currency);

            price             = _priceFormatter.FormatPrice(finalPriceWithoutDiscount);
            priceWithDiscount = _priceFormatter.FormatPrice(finalPriceWithDiscount);

            return(price, priceWithDiscount);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Prepare paged shopping cart item list model
        /// </summary>
        /// <param name="searchModel">Shopping cart item search model</param>
        /// <param name="customer">Customer</param>
        /// <returns>Shopping cart item list model</returns>
        public virtual ShoppingCartItemListModel PrepareShoppingCartItemListModel(ShoppingCartItemSearchModel searchModel, Customer customer)
        {
            if (searchModel == null)
            {
                throw new ArgumentNullException(nameof(searchModel));
            }

            if (customer == null)
            {
                throw new ArgumentNullException(nameof(customer));
            }

            //get shopping cart items
            var items = _shoppingCartService.GetShoppingCart(customer, searchModel.ShoppingCartType,
                                                             searchModel.StoreId, searchModel.ProductId, searchModel.StartDate, searchModel.EndDate).ToPagedList(searchModel);

            //prepare list model
            var model = new ShoppingCartItemListModel().PrepareToGrid(searchModel, items, () =>
            {
                return(items.Select(item =>
                {
                    //fill in model values from the entity
                    var itemModel = item.ToModel <ShoppingCartItemModel>();

                    //convert dates to the user time
                    itemModel.UpdatedOn = _dateTimeHelper.ConvertToUserTime(item.UpdatedOnUtc, DateTimeKind.Utc);

                    //fill in additional values (not existing in the entity)
                    itemModel.Store = _storeService.GetStoreById(item.StoreId)?.Name ?? "Deleted";
                    itemModel.AttributeInfo = _productAttributeFormatter.FormatAttributes(item.Product, item.AttributesXml, item.Customer);
                    var unitPrice = _priceCalculationService.GetUnitPrice(item);
                    itemModel.UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(item.Product, unitPrice, out var _));
                    var subTotal = _priceCalculationService.GetSubTotal(item);
                    itemModel.Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(item.Product, subTotal, out _));

                    //set product name since it does not survive mapping
                    itemModel.ProductName = item?.Product?.Name;

                    return itemModel;
                }));
            });
Ejemplo n.º 11
0
        public HttpResponseMessage GetCartDetails(HttpRequestMessage request, int customerId)
        {
            return(CreateHttpResponse(request, () =>
            {
                HttpResponseMessage response = request.CreateErrorResponse(HttpStatusCode.NotFound, "No items found");
                if (true)
                {
                    var customer = _customerService.GetCustomerById(customerId);
                    var cart = customer.ShoppingCartItems.Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();

                    var gridModel = new DataSourceResult
                    {
                        Data = cart.Select(sci =>
                        {
                            decimal taxRate;
                            var store = _storeService.GetStoreById(sci.StoreId);
                            var sciModel = new ShoppingCartItemVM
                            {
                                Id = sci.Id,
                                Store = store != null ? store.Name : "Unknown",
                                ProductId = sci.ProductId,
                                Quantity = sci.Quantity,
                                ProductName = sci.Product.Name,
                                AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.Product, sci.AttributesXml, sci.Customer),
                                UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Product, _priceCalculationService.GetUnitPrice(sci), out taxRate)),
                                Total = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Product, _priceCalculationService.GetSubTotal(sci), out taxRate)),
                                UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.UpdatedOnUtc, DateTimeKind.Utc)
                            };
                            return sciModel;
                        }),
                        Total = cart.Count
                    };
                    response = request.CreateResponse <DataSourceResult>(HttpStatusCode.OK, gridModel);
                }
                else
                {
                    response = request.CreateResponse(HttpStatusCode.Unauthorized, "Unauthorized user");
                }
                return response;
            }));
        }
Ejemplo n.º 12
0
        public ActionResult GetCartDetails(int customerId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCurrentCarts))
            {
                return(AccessDeniedView());
            }

            var customer = _customerService.GetCustomerById(customerId);
            var cart     = customer.ShoppingCartItems.Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();

            var gridModel = new DataSourceResult
            {
                Data = cart.Select(sci =>
                {
                    decimal taxRate;
                    var store    = _storeService.GetStoreById(sci.StoreId);
                    var sciModel = new ShoppingCartItemModel()
                    {
                        Id          = sci.Id,
                        Store       = store != null ? store.Name : "Unknown",
                        ProductId   = sci.ProductId,
                        Quantity    = sci.Quantity,
                        ProductName = sci.Product.Name,
                        UnitPrice   = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)),
                        Total       = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)),
                        UpdatedOn   = _dateTimeHelper.ConvertToUserTime(sci.UpdatedOnUtc, DateTimeKind.Utc)
                    };
                    return(sciModel);
                }),
                Total = cart.Count
            };

            return(Json(gridModel));
        }
        /// <summary>
        /// Get transaction line items
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="storeId">Store identifier</param>
        /// <returns>List of transaction items</returns>
        private List <BasketItem> GetItems(Core.Domain.Customers.Customer customer, int storeId)
        {
            var items = new List <BasketItem>();

            //get current shopping cart
            var shoppingCart = _shoppingCartService.GetShoppingCart(customer, ShoppingCartType.ShoppingCart, storeId);

            //define function to create item
            BasketItem createItem(decimal price, string productId, string productName, string categoryName, BasketItemType itemType = BasketItemType.PHYSICAL)
            {
                return(new BasketItem
                {
                    Id = productId,
                    Name = productName,
                    Category1 = categoryName,
                    ItemType = itemType.ToString(),
                    Price = Convert.ToDecimal(price, CultureInfo.InvariantCulture).ToString("f8", CultureInfo.InvariantCulture),
                });
            }

            items.AddRange(shoppingCart.Select(sci =>
            {
                var product = _productService.GetProductById(sci.ProductId);

                var shoppingCartUnitPriceWithDiscountBase = _taxService.GetProductPrice(product, _shoppingCartService.GetUnitPrice(sci), out var _);
                var shoppingCartUnitPriceWithDiscount     = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, _workContext.WorkingCurrency);

                return(createItem(shoppingCartUnitPriceWithDiscount * sci.Quantity,
                                  product.Id.ToString(),
                                  product.Name,
                                  _categoryService.GetProductCategoriesByProductId(sci.ProductId).Aggregate(",", (all, pc) =>
                {
                    var res = _categoryService.GetCategoryById(pc.CategoryId).Name;
                    res = all == "," ? res : all + ", " + res;
                    return res;
                })));
            }));

            //shipping without tax
            var shoppingCartShipping = _orderTotalCalculationService.GetShoppingCartShippingTotal(shoppingCart, false);

            if (shoppingCartShipping.HasValue && shoppingCartShipping.Value != 0)
            {
                items.Add(createItem(shoppingCartShipping ?? 0,
                                     Guid.NewGuid().ToString(),
                                     "Shipping",
                                     "Shipping",
                                     BasketItemType.VIRTUAL));
            }

            return(items);
        }
        public ActionResult GetCartDetails(int customerId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders))
            {
                return(AccessDeniedView());
            }

            var customer = _customerService.GetCustomerById(customerId);
            var cart     = customer.GetCartItems(ShoppingCartType.ShoppingCart);

            var gridModel = new GridModel <ShoppingCartItemModel>()
            {
                Data = cart.Select(sci =>
                {
                    decimal taxRate;
                    var store    = _storeService.GetStoreById(sci.Item.StoreId);
                    var sciModel = new ShoppingCartItemModel()
                    {
                        Id                   = sci.Item.Id,
                        Store                = store != null ? store.Name : "Unknown",
                        ProductId            = sci.Item.ProductId,
                        Quantity             = sci.Item.Quantity,
                        ProductName          = sci.Item.Product.Name,
                        ProductTypeName      = sci.Item.Product.GetProductTypeLabel(_localizationService),
                        ProductTypeLabelHint = sci.Item.Product.ProductTypeLabelHint,
                        UnitPrice            = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)),
                        Total                = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetSubTotal(sci, true), out taxRate)),
                        UpdatedOn            = _dateTimeHelper.ConvertToUserTime(sci.Item.UpdatedOnUtc, DateTimeKind.Utc)
                    };
                    return(sciModel);
                }),
                Total = cart.Count
            };

            return(new JsonResult
            {
                Data = gridModel
            });
        }
        public ActionResult GetCartDetails(int customerId)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageOrders))
            {
                return(AccessDeniedView());
            }

            var customer = _customerService.GetCustomerById(customerId);
            var cart     = customer.ShoppingCartItems.Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();

            var gridModel = new GridModel <ShoppingCartItemModel>()
            {
                Data = cart.Select(sci =>
                {
                    decimal taxRate;
                    var sciModel = new ShoppingCartItemModel()
                    {
                        Id               = sci.Id,
                        Store            = sci.Store != null ? sci.Store.Name : "Unknown",
                        ProductVariantId = sci.ProductVariantId,
                        Quantity         = sci.Quantity,
                        FullProductName  = !String.IsNullOrEmpty(sci.ProductVariant.Name) ?
                                           string.Format("{0} ({1})", sci.ProductVariant.Product.Name, sci.ProductVariant.Name) :
                                           sci.ProductVariant.Product.Name,
                        UnitPrice = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetUnitPrice(sci, true), out taxRate)),
                        Total     = _priceFormatter.FormatPrice(_taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetSubTotal(sci, true), out taxRate)),
                        UpdatedOn = _dateTimeHelper.ConvertToUserTime(sci.UpdatedOnUtc, DateTimeKind.Utc)
                    };
                    return(sciModel);
                }),
                Total = cart.Count
            };

            return(new JsonResult
            {
                Data = gridModel
            });
        }
Ejemplo n.º 16
0
        private bool CheckCurrentSubTotalRequirement(CheckDiscountRequirementRequest request, bool includingDiscount = true)
        {
            var cartItems = request.Customer.GetCartItems(ShoppingCartType.ShoppingCart, request.Store.Id);

            decimal spentAmount = decimal.Zero;
            decimal taxRate     = decimal.Zero;

            foreach (var sci in cartItems)
            {
                spentAmount += sci.Item.Quantity * _taxService.GetProductPrice(sci.Item.Product, _priceCalculationService.GetUnitPrice(sci, includingDiscount), out taxRate);
            }

            return(spentAmount >= request.DiscountRequirement.SpentAmount);
        }
        private OrderItem PrepareDefaultOrderItemFromProduct(Order order, Product product)
        {
            var presetQty   = 1;
            var presetPrice = _priceCalculationService.GetFinalPrice(product, order.Customer, decimal.Zero, true, presetQty);

            decimal taxRate;
            decimal presetPriceInclTax = _taxService.GetProductPrice(product, presetPrice, true, order.Customer, out taxRate);
            decimal presetPriceExclTax = _taxService.GetProductPrice(product, presetPrice, false, order.Customer, out taxRate);

            OrderItem orderItem = new OrderItem()
            {
                OrderItemGuid       = new Guid(),
                UnitPriceExclTax    = presetPriceExclTax,
                UnitPriceInclTax    = presetPriceInclTax,
                PriceInclTax        = presetPriceInclTax,
                PriceExclTax        = presetPriceExclTax,
                OriginalProductCost = _priceCalculationService.GetProductCost(product, null),
                Quantity            = presetQty,
                Product             = product,
                Order = order
            };

            return(orderItem);
        }
Ejemplo n.º 18
0
        public void Can_get_productPrice_priceIncludesTax_includingTax_taxable()
        {
            var customer = new Customer();
            var product  = new Product();

            var serviceProvider = new FakeServiceProvider(_genericAttributeService.Object, _taxService, _taxSettings);
            var nopEngine       = new FakeNopEngine(serviceProvider);

            EngineContext.Replace(nopEngine);

            _taxService.GetProductPrice(product, 0, 1000M, true, customer, true, out _).Should().Be(1000);
            _taxService.GetProductPrice(product, 0, 1000M, true, customer, false, out _).Should().Be(1100);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, true, out _).Should()
            .Be(909.0909090909090909090909091M);
            _taxService.GetProductPrice(product, 0, 1000M, false, customer, false, out _).Should().Be(1000);

            EngineContext.Replace(null);
        }
Ejemplo n.º 19
0
        public ActionResult ProductTierPrices(int productId)
        {
            if (!_services.Permissions.Authorize(StandardPermissionProvider.DisplayPrices))
            {
                return(Content(""));
            }

            var product = _productService.GetProductById(productId);

            if (product == null)
            {
                throw new ArgumentException(T("Products.NotFound", productId));
            }


            if (!product.HasTierPrices)
            {
                // No tier prices
                return(Content(""));
            }

            var model = product.TierPrices
                        .OrderBy(x => x.Quantity)
                        .FilterByStore(_services.StoreContext.CurrentStore.Id)
                        .FilterForCustomer(_services.WorkContext.CurrentCustomer)
                        .ToList()
                        .RemoveDuplicatedQuantities()
                        .Select(tierPrice =>
            {
                var m = new ProductDetailsModel.TierPriceModel
                {
                    Quantity = tierPrice.Quantity,
                };
                decimal taxRate   = decimal.Zero;
                decimal priceBase = _taxService.GetProductPrice(product, _priceCalculationService.GetFinalPrice(product, _services.WorkContext.CurrentCustomer, decimal.Zero, _catalogSettings.DisplayTierPricesWithDiscounts, tierPrice.Quantity), out taxRate);
                decimal price     = _currencyService.ConvertFromPrimaryStoreCurrency(priceBase, _services.WorkContext.WorkingCurrency);
                m.Price           = _priceFormatter.FormatPrice(price, true, false);
                return(m);
            })
                        .ToList();

            return(PartialView("Product.TierPrices", model));
        }
Ejemplo n.º 20
0
        public PaymentDetailsItemType CreatePaymentItem(ShoppingCartItem item)
        {
            decimal taxRate;
            var     productPrice = _taxService.GetProductPrice(item.Product,
                                                               _priceCalculationService.GetUnitPrice(item, true), false,
                                                               _workContext.CurrentCustomer, out taxRate);

            var currencyCodeType       = _payPalCurrencyCodeParser.GetCurrencyCodeType(_workContext.WorkingCurrency);
            var paymentDetailsItemType = new PaymentDetailsItemType
            {
                Name = item.Product.Name,
                //Description = _productAttributeFormatter.FormatAttributes(item.ProductVariant, item.AttributesXml),
                Amount       = productPrice.GetBasicAmountType(currencyCodeType),
                ItemCategory =
                    item.Product.IsDownload
                                                         ? ItemCategoryType.Digital
                                                         : ItemCategoryType.Physical,
                Quantity = item.Quantity.ToString()
            };

            return(paymentDetailsItemType);
        }
Ejemplo n.º 21
0
        private bool CheckCurrentSubTotalRequirement(CheckDiscountRequirementRequest request)
        {
            var spentAmount = decimal.Zero;

            try
            {
                var taxRate   = decimal.Zero;
                var cartItems = request.Customer.GetCartItems(ShoppingCartType.ShoppingCart, request.Store.Id);

                foreach (var cartItem in cartItems)
                {
                    var product = cartItem.Item.Product;
                    Dictionary <string, object> mergedValuesClone = null;

                    // we must reapply merged values because CheckCurrentSubTotalRequirement uses price calculation and is called by it itself.
                    // this can cause wrong discount calculation if the cart contains a product several times.
                    if (product.MergedDataValues != null)
                    {
                        mergedValuesClone = new Dictionary <string, object>(product.MergedDataValues);
                    }

                    // includeDiscounts == true produces a stack overflow!
                    spentAmount += cartItem.Item.Quantity * _taxService.GetProductPrice(product, _priceCalculationService.GetUnitPrice(cartItem, false), out taxRate);

                    if (mergedValuesClone != null)
                    {
                        product.MergedDataValues = new Dictionary <string, object>(mergedValuesClone);
                    }
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception);
                return(false);
            }

            return(spentAmount >= request.DiscountRequirement.SpentAmount);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Gets the base price
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="localizationService">Localization service</param>
        /// <param name="priceFormatter">Price formatter</param>
        /// <param name="currencyService">Currency service</param>
        /// <param name="taxService">Tax service</param>
        /// <param name="priceCalculationService">Price calculation service</param>
        /// <param name="currency">Target currency</param>
        /// <param name="priceAdjustment">Price adjustment</param>
        /// <param name="languageIndependent">Whether the result string should be language independent</param>
        /// <returns>The base price</returns>
        public static string GetBasePriceInfo(this Product product, ILocalizationService localizationService, IPriceFormatter priceFormatter,
                                              ICurrencyService currencyService, ITaxService taxService, IPriceCalculationService priceCalculationService,
                                              Currency currency, decimal priceAdjustment = decimal.Zero, bool languageIndependent = false)
        {
            if (product == null)
            {
                throw new ArgumentNullException("product");
            }

            if (localizationService == null && !languageIndependent)
            {
                throw new ArgumentNullException("localizationService");
            }

            if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero)
            {
                var workContext = EngineContext.Current.Resolve <IWorkContext>();

                var     taxrate      = decimal.Zero;
                var     currentPrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, true);
                decimal price        = taxService.GetProductPrice(product, decimal.Add(currentPrice, priceAdjustment), out taxrate);

                price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency);

                decimal basePriceValue = Convert.ToDecimal((price / product.BasePriceAmount) * product.BasePriceBaseAmount);

                string basePrice = priceFormatter.FormatPrice(basePriceValue, true, currency);
                string unit      = "{0} {1}".FormatWith(product.BasePriceBaseAmount, product.BasePriceMeasureUnit);

                if (languageIndependent)
                {
                    return("{0} / {1}".FormatWith(basePrice, unit));
                }

                return(localizationService.GetResource("Products.BasePriceInfo").FormatWith(basePrice, unit));
            }
            return("");
        }
        /// <summary>
        /// Create items from shopping cart
        /// </summary>
        /// <param name="shoppingCart">Shopping cart</param>
        /// <returns>Collection of PayPal items</returns>
        protected IEnumerable <Item> CreateItems(IEnumerable <ShoppingCartItem> shoppingCart)
        {
            return(shoppingCart.Select(shoppingCartItem =>
            {
                if (shoppingCartItem.Product == null)
                {
                    return null;
                }

                var item = new Item
                {
                    //name
                    name = shoppingCartItem.Product.Name
                };

                //SKU
                if (!string.IsNullOrEmpty(shoppingCartItem.AttributesXml))
                {
                    var combination = _productAttributeParser.FindProductAttributeCombination(shoppingCartItem.Product, shoppingCartItem.AttributesXml);
                    item.sku = combination != null && !string.IsNullOrEmpty(combination.Sku) ? combination.Sku : shoppingCartItem.Product.Sku;
                }
                else
                {
                    item.sku = shoppingCartItem.Product.Sku;
                }

                //item price
                var unitPrice = _priceCalculationService.GetUnitPrice(shoppingCartItem);
                var price = _taxService.GetProductPrice(shoppingCartItem.Product, unitPrice, false, shoppingCartItem.Customer, out decimal _);
                item.price = price.ToString("N", new CultureInfo("en-US"));

                //quantity
                item.quantity = shoppingCartItem.Quantity.ToString();

                return item;
            }));
        }
        public static IEnumerable<ProductOverviewModel> PrepareProductOverviewModels(this Controller controller,
            IWorkContext workContext,
            IStoreContext storeContext,
            ICategoryService categoryService,
            IProductService productService,
            ISpecificationAttributeService specificationAttributeService,
            IPriceCalculationService priceCalculationService,
            IPriceFormatter priceFormatter,
            IPermissionService permissionService,
            ILocalizationService localizationService,
            ITaxService taxService,
            ICurrencyService currencyService,
            IPictureService pictureService,
            IWebHelper webHelper,
            ICacheManager cacheManager,
            CatalogSettings catalogSettings,
            MediaSettings mediaSettings,
            IEnumerable<Product> products,
            bool preparePriceModel = true, bool preparePictureModel = true,
            int? productThumbPictureSize = null, bool prepareSpecificationAttributes = false,
            bool forceRedirectionAfterAddingToCart = false)
        {
            if (products == null)
                throw new ArgumentNullException("products");

            var models = new List<ProductOverviewModel>();
            foreach (var product in products)
            {
                var model = new ProductOverviewModel
                {
                    Id = product.Id,
                    Name = product.GetLocalized(x => x.Name),
                    ShortDescription = product.GetLocalized(x => x.ShortDescription),
                    FullDescription = product.GetLocalized(x => x.FullDescription),
                    SeName = product.GetSeName(),
                };
                //price
                if (preparePriceModel)
                {
                    #region Prepare product price

                    var priceModel = new ProductOverviewModel.ProductPriceModel
                    {
                        ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart
                    };

                    switch (product.ProductType)
                    {
                        case ProductType.GroupedProduct:
                            {
                                #region Grouped product

                                var associatedProducts = productService.GetAssociatedProducts(product.Id, storeContext.CurrentStore.Id);

                                switch (associatedProducts.Count)
                                {
                                    case 0:
                                        {
                                            //no associated products
                                            //priceModel.DisableBuyButton = true;
                                            //priceModel.DisableWishlistButton = true;
                                            //compare products
                                            priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;
                                            //priceModel.AvailableForPreOrder = false;
                                        }
                                        break;
                                    default:
                                        {
                                            //we have at least one associated product
                                            //priceModel.DisableBuyButton = true;
                                            //priceModel.DisableWishlistButton = true;
                                            //compare products
                                            priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;
                                            //priceModel.AvailableForPreOrder = false;

                                            if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                                            {
                                                //find a minimum possible price
                                                decimal? minPossiblePrice = null;
                                                Product minPriceProduct = null;
                                                foreach (var associatedProduct in associatedProducts)
                                                {
                                                    //calculate for the maximum quantity (in case if we have tier prices)
                                                    var tmpPrice = priceCalculationService.GetFinalPrice(associatedProduct,
                                                        workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue);
                                                    if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value)
                                                    {
                                                        minPriceProduct = associatedProduct;
                                                        minPossiblePrice = tmpPrice;
                                                    }
                                                }
                                                if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice)
                                                {
                                                    if (minPriceProduct.CallForPrice)
                                                    {
                                                        priceModel.OldPrice = null;
                                                        priceModel.Price = localizationService.GetResource("Products.CallForPrice");
                                                    }
                                                    else if (minPossiblePrice.HasValue)
                                                    {
                                                        //calculate prices
                                                        decimal taxRate;
                                                        decimal finalPriceBase = taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate);
                                                        decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency);

                                                        priceModel.OldPrice = null;
                                                        priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice));

                                                    }
                                                    else
                                                    {
                                                        //Actually it's not possible (we presume that minimalPrice always has a value)
                                                        //We never should get here
                                                        Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id);
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                //hide prices
                                                priceModel.OldPrice = null;
                                                priceModel.Price = null;
                                            }
                                        }
                                        break;
                                }

                                #endregion
                            }
                            break;
                        case ProductType.SimpleProduct:
                        default:
                            {
                                #region Simple product

                                //add to cart button
                                priceModel.DisableBuyButton = product.DisableBuyButton ||
                                    !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) ||
                                    !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);

                                //add to wishlist button
                                priceModel.DisableWishlistButton = product.DisableWishlistButton ||
                                    !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) ||
                                    !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);
                                //compare products
                                priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;

                                //rental
                                priceModel.IsRental = product.IsRental;

                                //pre-order
                                if (product.AvailableForPreOrder)
                                {
                                    priceModel.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue ||
                                        product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow;
                                    priceModel.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc;
                                }

                                //prices
                                if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                                {
                                    if (!product.CustomerEntersPrice)
                                    {
                                        if (product.CallForPrice)
                                        {
                                            //call for price
                                            priceModel.OldPrice = null;
                                            priceModel.Price = localizationService.GetResource("Products.CallForPrice");
                                        }
                                        else
                                        {
                                            //prices

                                            //calculate for the maximum quantity (in case if we have tier prices)
                                            decimal minPossiblePrice = priceCalculationService.GetFinalPrice(product,
                                                workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue);

                                            decimal taxRate;
                                            decimal oldPriceBase = taxService.GetProductPrice(product, product.OldPrice, out taxRate);
                                            decimal finalPriceBase = taxService.GetProductPrice(product, minPossiblePrice, out taxRate);

                                            decimal oldPrice = currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workContext.WorkingCurrency);
                                            decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency);

                                            //do we have tier prices configured?
                                            var tierPrices = new List<TierPrice>();
                                            if (product.HasTierPrices)
                                            {
                                                tierPrices.AddRange(product.TierPrices
                                                    .OrderBy(tp => tp.Quantity)
                                                    .ToList()
                                                    .FilterByStore(storeContext.CurrentStore.Id)
                                                    .FilterForCustomer(workContext.CurrentCustomer)
                                                    .RemoveDuplicatedQuantities());
                                            }
                                            //When there is just one tier (with  qty 1),
                                            //there are no actual savings in the list.
                                            bool displayFromMessage = tierPrices.Count > 0 &&
                                                !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1);
                                            if (displayFromMessage)
                                            {
                                                priceModel.OldPrice = null;
                                                priceModel.Price = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice));
                                            }
                                            else
                                            {
                                                if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero)
                                                {
                                                    priceModel.OldPrice = priceFormatter.FormatPrice(oldPrice);
                                                    priceModel.Price = priceFormatter.FormatPrice(finalPrice);
                                                }
                                                else
                                                {
                                                    priceModel.OldPrice = null;
                                                    priceModel.Price = priceFormatter.FormatPrice(finalPrice);
                                                }
                                            }
                                            if (product.IsRental)
                                            {
                                                //rental product
                                                priceModel.OldPrice = priceFormatter.FormatRentalProductPeriod(product, priceModel.OldPrice);
                                                priceModel.Price = priceFormatter.FormatRentalProductPeriod(product, priceModel.Price);
                                            }

                                            //property for German market
                                            //we display tax/shipping info only with "shipping enabled" for this product
                                            //we also ensure this it's not free shipping
                                            priceModel.DisplayTaxShippingInfo = catalogSettings.DisplayTaxShippingInfoProductBoxes
                                                && product.IsShipEnabled &&
                                                !product.IsFreeShipping;
                                        }
                                    }
                                }
                                else
                                {
                                    //hide prices
                                    priceModel.OldPrice = null;
                                    priceModel.Price = null;
                                }

                                #endregion
                            }
                            break;
                    }

                    model.ProductPrice = priceModel;

                    #endregion
                }

                //picture
                if (preparePictureModel)
                {
                    #region Prepare product picture

                    //If a size has been set in the view, we use it in priority
                    int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : mediaSettings.ProductThumbPictureSize;
                    //prepare picture model
                    var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true, workContext.WorkingLanguage.Id, webHelper.IsCurrentConnectionSecured(), storeContext.CurrentStore.Id);
                    model.DefaultPictureModel = cacheManager.Get(defaultProductPictureCacheKey, () =>
                    {
                        var picture = pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault();
                        var pictureModel = new PictureModel
                        {
                            ImageUrl = pictureService.GetPictureUrl(picture, pictureSize),
                            FullSizeImageUrl = pictureService.GetPictureUrl(picture)
                        };
                        //"title" attribute
                        pictureModel.Title = (picture != null && !string.IsNullOrEmpty(picture.TitleAttribute)) ?
                            picture.TitleAttribute :
                            string.Format(localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name);
                        //"alt" attribute
                        pictureModel.AlternateText = (picture != null && !string.IsNullOrEmpty(picture.AltAttribute)) ?
                            picture.AltAttribute :
                            string.Format(localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name);

                        return pictureModel;
                    });

                    #endregion
                }

                //specs
                if (prepareSpecificationAttributes)
                {
                    model.SpecificationAttributeModels = PrepareProductSpecificationModel(controller, workContext,
                         specificationAttributeService, cacheManager, product);
                }

                //reviews
                model.ReviewOverviewModel = new ProductReviewOverviewModel
                {
                    ProductId = product.Id,
                    RatingSum = product.ApprovedRatingSum,
                    TotalReviews = product.ApprovedTotalReviews,
                    AllowCustomerReviews = product.AllowCustomerReviews
                };

                models.Add(model);
            }
            return models;
        }
Ejemplo n.º 25
0
        public static IEnumerable <ProductOverviewModel> PrepareProductOverviewModels(this Controller controller,
                                                                                      IWorkContext workContext,
                                                                                      IStoreContext storeContext,
                                                                                      ICategoryService categoryService,
                                                                                      IProductService productService,
                                                                                      ISpecificationAttributeService specificationAttributeService,
                                                                                      IPriceCalculationService priceCalculationService,
                                                                                      IPriceFormatter priceFormatter,
                                                                                      IPermissionService permissionService,
                                                                                      ILocalizationService localizationService,
                                                                                      ITaxService taxService,
                                                                                      ICurrencyService currencyService,
                                                                                      IPictureService pictureService,
                                                                                      IWebHelper webHelper,
                                                                                      ICacheManager cacheManager,
                                                                                      CatalogSettings catalogSettings,
                                                                                      MediaSettings mediaSettings,
                                                                                      IEnumerable <Product> products,
                                                                                      bool preparePriceModel                 = true, bool preparePictureModel = true,
                                                                                      int?productThumbPictureSize            = null, bool prepareSpecificationAttributes = false,
                                                                                      bool forceRedirectionAfterAddingToCart = false)
        {
            if (products == null)
            {
                throw new ArgumentNullException("products");
            }

            var models = new List <ProductOverviewModel>();

            foreach (var product in products)
            {
                var model = new ProductOverviewModel
                {
                    Id               = product.Id,
                    Name             = product.GetLocalized(x => x.Name),
                    ShortDescription = product.GetLocalized(x => x.ShortDescription),
                    FullDescription  = product.GetLocalized(x => x.FullDescription),
                    SeName           = product.GetSeName(),
                    ProductType      = product.ProductType,
                    MarkAsNew        = product.MarkAsNew &&
                                       (!product.MarkAsNewStartDateTimeUtc.HasValue || product.MarkAsNewStartDateTimeUtc.Value < DateTime.UtcNow) &&
                                       (!product.MarkAsNewEndDateTimeUtc.HasValue || product.MarkAsNewEndDateTimeUtc.Value > DateTime.UtcNow)
                };
                //price
                if (preparePriceModel)
                {
                    #region Prepare product price

                    var priceModel = new ProductOverviewModel.ProductPriceModel
                    {
                        ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart
                    };

                    switch (product.ProductType)
                    {
                    case ProductType.GroupedProduct:
                    {
                        #region Grouped product

                        var associatedProducts = productService.GetAssociatedProducts(product.Id, storeContext.CurrentStore.Id);

                        //add to cart button (ignore "DisableBuyButton" property for grouped products)
                        priceModel.DisableBuyButton = !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) ||
                                                      !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);

                        //add to wishlist button (ignore "DisableWishlistButton" property for grouped products)
                        priceModel.DisableWishlistButton = !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) ||
                                                           !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);

                        //compare products
                        priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;
                        switch (associatedProducts.Count)
                        {
                        case 0:
                        {
                            //no associated products
                        }
                        break;

                        default:
                        {
                            //we have at least one associated product
                            //compare products
                            priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;
                            //priceModel.AvailableForPreOrder = false;

                            if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                            {
                                //find a minimum possible price
                                decimal?minPossiblePrice = null;
                                Product minPriceProduct  = null;
                                foreach (var associatedProduct in associatedProducts)
                                {
                                    //calculate for the maximum quantity (in case if we have tier prices)
                                    var tmpPrice = priceCalculationService.GetFinalPrice(associatedProduct,
                                                                                         workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue);
                                    if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value)
                                    {
                                        minPriceProduct  = associatedProduct;
                                        minPossiblePrice = tmpPrice;
                                    }
                                }
                                if (minPriceProduct != null && !minPriceProduct.CustomerEntersPrice)
                                {
                                    if (minPriceProduct.CallForPrice)
                                    {
                                        priceModel.OldPrice = null;
                                        priceModel.Price    = localizationService.GetResource("Products.CallForPrice");
                                    }
                                    else if (minPossiblePrice.HasValue)
                                    {
                                        //calculate prices
                                        decimal taxRate;
                                        decimal finalPriceBase = taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, out taxRate);
                                        decimal finalPrice     = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency);

                                        priceModel.OldPrice   = null;
                                        priceModel.Price      = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice));
                                        priceModel.PriceValue = finalPrice;
                                    }
                                    else
                                    {
                                        //Actually it's not possible (we presume that minimalPrice always has a value)
                                        //We never should get here
                                        Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id);
                                    }
                                }
                            }
                            else
                            {
                                //hide prices
                                priceModel.OldPrice = null;
                                priceModel.Price    = null;
                            }
                        }
                        break;
                        }

                        #endregion
                    }
                    break;

                    case ProductType.SimpleProduct:
                    default:
                    {
                        #region Simple product

                        //add to cart button
                        priceModel.DisableBuyButton = product.DisableBuyButton ||
                                                      !permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart) ||
                                                      !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);

                        //add to wishlist button
                        priceModel.DisableWishlistButton = product.DisableWishlistButton ||
                                                           !permissionService.Authorize(StandardPermissionProvider.EnableWishlist) ||
                                                           !permissionService.Authorize(StandardPermissionProvider.DisplayPrices);
                        //compare products
                        priceModel.DisableAddToCompareListButton = !catalogSettings.CompareProductsEnabled;

                        //rental
                        priceModel.IsRental = product.IsRental;

                        //pre-order
                        if (product.AvailableForPreOrder)
                        {
                            priceModel.AvailableForPreOrder = !product.PreOrderAvailabilityStartDateTimeUtc.HasValue ||
                                                              product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow;
                            priceModel.PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc;
                        }

                        //prices
                        if (permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
                        {
                            if (!product.CustomerEntersPrice)
                            {
                                if (product.CallForPrice)
                                {
                                    //call for price
                                    priceModel.OldPrice = null;
                                    priceModel.Price    = localizationService.GetResource("Products.CallForPrice");
                                }
                                else
                                {
                                    //prices

                                    //calculate for the maximum quantity (in case if we have tier prices)
                                    decimal minPossiblePrice = priceCalculationService.GetFinalPrice(product,
                                                                                                     workContext.CurrentCustomer, decimal.Zero, true, int.MaxValue);

                                    decimal taxRate;
                                    decimal oldPriceBase   = taxService.GetProductPrice(product, product.OldPrice, out taxRate);
                                    decimal finalPriceBase = taxService.GetProductPrice(product, minPossiblePrice, out taxRate);

                                    decimal oldPrice   = currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, workContext.WorkingCurrency);
                                    decimal finalPrice = currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, workContext.WorkingCurrency);

                                    //do we have tier prices configured?
                                    var tierPrices = new List <TierPrice>();
                                    if (product.HasTierPrices)
                                    {
                                        tierPrices.AddRange(product.TierPrices
                                                            .OrderBy(tp => tp.Quantity)
                                                            .ToList()
                                                            .FilterByStore(storeContext.CurrentStore.Id)
                                                            .FilterForCustomer(workContext.CurrentCustomer)
                                                            .RemoveDuplicatedQuantities());
                                    }
                                    //When there is just one tier (with  qty 1),
                                    //there are no actual savings in the list.
                                    bool displayFromMessage = tierPrices.Count > 0 &&
                                                              !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1);
                                    if (displayFromMessage)
                                    {
                                        priceModel.OldPrice   = null;
                                        priceModel.Price      = String.Format(localizationService.GetResource("Products.PriceRangeFrom"), priceFormatter.FormatPrice(finalPrice));
                                        priceModel.PriceValue = finalPrice;
                                    }
                                    else
                                    {
                                        if (finalPriceBase != oldPriceBase && oldPriceBase != decimal.Zero)
                                        {
                                            priceModel.OldPrice   = priceFormatter.FormatPrice(oldPrice);
                                            priceModel.Price      = priceFormatter.FormatPrice(finalPrice);
                                            priceModel.PriceValue = finalPrice;
                                        }
                                        else
                                        {
                                            priceModel.OldPrice   = null;
                                            priceModel.Price      = priceFormatter.FormatPrice(finalPrice);
                                            priceModel.PriceValue = finalPrice;
                                        }
                                    }
                                    if (product.IsRental)
                                    {
                                        //rental product
                                        priceModel.OldPrice = priceFormatter.FormatRentalProductPeriod(product, priceModel.OldPrice);
                                        priceModel.Price    = priceFormatter.FormatRentalProductPeriod(product, priceModel.Price);
                                    }


                                    //property for German market
                                    //we display tax/shipping info only with "shipping enabled" for this product
                                    //we also ensure this it's not free shipping
                                    priceModel.DisplayTaxShippingInfo = catalogSettings.DisplayTaxShippingInfoProductBoxes &&
                                                                        product.IsShipEnabled &&
                                                                        !product.IsFreeShipping;
                                }
                            }
                        }
                        else
                        {
                            //hide prices
                            priceModel.OldPrice = null;
                            priceModel.Price    = null;
                        }

                        #endregion
                    }
                    break;
                    }

                    model.ProductPrice = priceModel;

                    #endregion
                }

                //picture
                if (preparePictureModel)
                {
                    #region Prepare product picture

                    //If a size has been set in the view, we use it in priority
                    int pictureSize = productThumbPictureSize.HasValue ? productThumbPictureSize.Value : mediaSettings.ProductThumbPictureSize;
                    //prepare picture model
                    var defaultProductPictureCacheKey = string.Format(ModelCacheEventConsumer.PRODUCT_DEFAULTPICTURE_MODEL_KEY, product.Id, pictureSize, true, workContext.WorkingLanguage.Id, webHelper.IsCurrentConnectionSecured(), storeContext.CurrentStore.Id);
                    model.DefaultPictureModel = cacheManager.Get(defaultProductPictureCacheKey, () =>
                    {
                        var picture      = pictureService.GetPicturesByProductId(product.Id, 1).FirstOrDefault();
                        var pictureModel = new PictureModel
                        {
                            ImageUrl         = pictureService.GetPictureUrl(picture, pictureSize),
                            FullSizeImageUrl = pictureService.GetPictureUrl(picture)
                        };
                        //"title" attribute
                        pictureModel.Title = (picture != null && !string.IsNullOrEmpty(picture.TitleAttribute)) ?
                                             picture.TitleAttribute :
                                             string.Format(localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), model.Name);
                        //"alt" attribute
                        pictureModel.AlternateText = (picture != null && !string.IsNullOrEmpty(picture.AltAttribute)) ?
                                                     picture.AltAttribute :
                                                     string.Format(localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), model.Name);

                        return(pictureModel);
                    });

                    #endregion
                }

                //specs
                if (prepareSpecificationAttributes)
                {
                    model.SpecificationAttributeModels = PrepareProductSpecificationModel(controller, workContext,
                                                                                          specificationAttributeService, cacheManager, product);
                }

                //reviews
                model.ReviewOverviewModel = controller.PrepareProductReviewOverviewModel(storeContext, catalogSettings, cacheManager, product);

                models.Add(model);
            }
            return(models);
        }
        private async Task <StringBuilder> PrepareFormattedAttribute(Product product, string attributesXml, string langId,
                                                                     string serapator, bool htmlEncode, bool renderPrices,
                                                                     bool allowHyperlinks, bool showInAdmin)
        {
            var result     = new StringBuilder();
            var attributes = _productAttributeParser.ParseProductAttributeMappings(product, attributesXml);

            for (int i = 0; i < attributes.Count; i++)
            {
                var productAttribute = await _productAttributeService.GetProductAttributeById(attributes[i].ProductAttributeId);

                var attribute = attributes[i];
                var valuesStr = _productAttributeParser.ParseValues(attributesXml, attribute.Id);
                for (int j = 0; j < valuesStr.Count; j++)
                {
                    string valueStr           = valuesStr[j];
                    string formattedAttribute = string.Empty;
                    if (!attribute.ShouldHaveValues())
                    {
                        //no values
                        if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox)
                        {
                            //multiline textbox
                            var attributeName = productAttribute.GetLocalized(a => a.Name, langId);
                            //encode (if required)
                            if (htmlEncode)
                            {
                                attributeName = WebUtility.HtmlEncode(attributeName);
                            }
                            formattedAttribute = string.Format("{0}: {1}", attributeName, HtmlHelper.FormatText(valueStr));
                            //we never encode multiline textbox input
                        }
                        else if (attribute.AttributeControlType == AttributeControlType.FileUpload)
                        {
                            //file upload
                            Guid downloadGuid;
                            Guid.TryParse(valueStr, out downloadGuid);
                            var download = await _downloadService.GetDownloadByGuid(downloadGuid);

                            if (download != null)
                            {
                                //TODO add a method for getting URL (use routing because it handles all SEO friendly URLs)
                                string attributeText = "";
                                var    fileName      = string.Format("{0}{1}",
                                                                     download.Filename ?? download.DownloadGuid.ToString(),
                                                                     download.Extension);
                                //encode (if required)
                                if (htmlEncode)
                                {
                                    fileName = WebUtility.HtmlEncode(fileName);
                                }
                                if (allowHyperlinks)
                                {
                                    //hyperlinks are allowed
                                    var downloadLink = string.Format("{0}download/getfileupload/?downloadId={1}", _webHelper.GetStoreLocation(false), download.DownloadGuid);
                                    attributeText = string.Format("<a href=\"{0}\" class=\"fileuploadattribute\">{1}</a>", downloadLink, fileName);
                                }
                                else
                                {
                                    //hyperlinks aren't allowed
                                    attributeText = fileName;
                                }
                                var attributeName = productAttribute.GetLocalized(a => a.Name, langId);
                                //encode (if required)
                                if (htmlEncode)
                                {
                                    attributeName = WebUtility.HtmlEncode(attributeName);
                                }
                                formattedAttribute = string.Format("{0}: {1}", attributeName, attributeText);
                            }
                        }
                        else
                        {
                            //other attributes (textbox, datepicker)
                            formattedAttribute = string.Format("{0}: {1}", productAttribute.GetLocalized(a => a.Name, langId), valueStr);
                            //encode (if required)
                            if (htmlEncode)
                            {
                                formattedAttribute = WebUtility.HtmlEncode(formattedAttribute);
                            }
                        }
                    }
                    else
                    {
                        //attributes with values
                        if (product.ProductAttributeMappings.Where(x => x.Id == attributes[i].Id).FirstOrDefault() != null)
                        {
                            var attributeValue = product.ProductAttributeMappings.Where(x => x.Id == attributes[i].Id).FirstOrDefault().ProductAttributeValues.Where(x => x.Id == valueStr).FirstOrDefault();
                            if (attributeValue != null)
                            {
                                formattedAttribute = string.Format("{0}: {1}", productAttribute.GetLocalized(a => a.Name, langId), attributeValue.GetLocalized(a => a.Name, langId));

                                if (renderPrices)
                                {
                                    decimal attributeValuePriceAdjustment = await _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue);

                                    var prices = await _taxService.GetProductPrice(product, attributeValuePriceAdjustment, _workContext.CurrentCustomer);

                                    decimal priceAdjustmentBase = prices.productprice;
                                    decimal taxRate             = prices.taxRate;
                                    decimal priceAdjustment     = await _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency);

                                    if (priceAdjustmentBase > 0)
                                    {
                                        string priceAdjustmentStr = _priceFormatter.FormatPrice(priceAdjustment, false, false);
                                        formattedAttribute += string.Format(" [+{0}]", priceAdjustmentStr);
                                    }
                                    else if (priceAdjustmentBase < decimal.Zero)
                                    {
                                        string priceAdjustmentStr = _priceFormatter.FormatPrice(-priceAdjustment, false, false);
                                        formattedAttribute += string.Format(" [-{0}]", priceAdjustmentStr);
                                    }
                                }

                                //display quantity
                                if (_shoppingCartSettings.RenderAssociatedAttributeValueQuantity &&
                                    attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct)
                                {
                                    //render only when more than 1
                                    if (attributeValue.Quantity > 1)
                                    {
                                        //TODO localize resource
                                        formattedAttribute += string.Format(" - qty {0}", attributeValue.Quantity);
                                    }
                                }
                            }
                            else
                            {
                                if (showInAdmin)
                                {
                                    formattedAttribute += string.Format("{0}: {1}", productAttribute.GetLocalized(a => a.Name, langId), "");
                                }
                            }

                            //encode (if required)
                            if (htmlEncode)
                            {
                                formattedAttribute = WebUtility.HtmlEncode(formattedAttribute);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(formattedAttribute))
                    {
                        if (i != 0 || j != 0)
                        {
                            result.Append(serapator);
                        }
                        result.Append(formattedAttribute);
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Generate a feed
        /// </summary>
        /// <param name="stream">Stream</param>
        /// <param name="store">Store</param>
        /// <returns>Generated feed</returns>
        public void GenerateFeed(Stream stream, Store store)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }

            const string googleBaseNamespace = "http://base.google.com/ns/1.0";

            var settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8
            };

            var googleShoppingSettings = _settingService.LoadSetting <GoogleShoppingSettings>(store.Id);

            //language
            var languageId = 0;
            var languages  = _languageService.GetAllLanguages(storeId: store.Id);

            //if we have only one language, let's use it
            if (languages.Count == 1)
            {
                //let's use the first one
                var language = languages.FirstOrDefault();
                languageId = language != null ? language.Id : 0;
            }
            //otherwise, use the current one
            if (languageId == 0)
            {
                languageId = _workContext.WorkingLanguage.Id;
            }

            //we load all Google products here using one SQL request (performance optimization)
            var allGoogleProducts = _googleService.GetAll();

            using (var writer = XmlWriter.Create(stream, settings))
            {
                //Generate feed according to the following specs: http://www.google.com/support/merchants/bin/answer.py?answer=188494&expand=GB
                writer.WriteStartDocument();
                writer.WriteStartElement("rss");
                writer.WriteAttributeString("version", "2.0");
                writer.WriteAttributeString("xmlns", "g", null, googleBaseNamespace);
                writer.WriteStartElement("channel");
                writer.WriteElementString("title", "Google Base feed");
                writer.WriteElementString("link", "http://base.google.com/base/");
                writer.WriteElementString("description", "Information about products");

                var products1 = _productService.SearchProducts(storeId: store.Id, visibleIndividuallyOnly: true);
                foreach (var product1 in products1)
                {
                    var productsToProcess = new List <Product>();
                    switch (product1.ProductType)
                    {
                    case ProductType.SimpleProduct:
                    {
                        //simple product doesn't have child products
                        productsToProcess.Add(product1);
                    }
                    break;

                    case ProductType.GroupedProduct:
                    {
                        //grouped products could have several child products
                        var associatedProducts = _productService.GetAssociatedProducts(product1.Id, store.Id);
                        productsToProcess.AddRange(associatedProducts);
                    }
                    break;

                    default:
                        continue;
                    }
                    foreach (var product in productsToProcess)
                    {
                        writer.WriteStartElement("item");

                        #region Basic Product Information

                        //id [id]- An identifier of the item
                        writer.WriteElementString("g", "id", googleBaseNamespace, product.Id.ToString());

                        //title [title] - Title of the item
                        writer.WriteStartElement("title");
                        var title = _localizationService.GetLocalized(product, x => x.Name, languageId);
                        //title should be not longer than 70 characters
                        if (title.Length > 70)
                        {
                            title = title.Substring(0, 70);
                        }
                        writer.WriteCData(title);
                        writer.WriteEndElement(); // title

                        //description [description] - Description of the item
                        writer.WriteStartElement("description");
                        var description = _localizationService.GetLocalized(product, x => x.FullDescription, languageId);
                        if (string.IsNullOrEmpty(description))
                        {
                            description = _localizationService.GetLocalized(product, x => x.ShortDescription, languageId);
                        }
                        if (string.IsNullOrEmpty(description))
                        {
                            description = _localizationService.GetLocalized(product, x => x.Name, languageId); //description is required
                        }
                        //resolving character encoding issues in your data feed
                        description = StripInvalidChars(description, true);
                        writer.WriteCData(description);
                        writer.WriteEndElement(); // description

                        //google product category [google_product_category] - Google's category of the item
                        //the category of the product according to Google’s product taxonomy. http://www.google.com/support/merchants/bin/answer.py?answer=160081
                        var googleProductCategory = "";
                        //var googleProduct = _googleService.GetByProductId(product.Id);
                        var googleProduct = allGoogleProducts.FirstOrDefault(x => x.ProductId == product.Id);
                        if (googleProduct != null)
                        {
                            googleProductCategory = googleProduct.Taxonomy;
                        }
                        if (string.IsNullOrEmpty(googleProductCategory))
                        {
                            googleProductCategory = googleShoppingSettings.DefaultGoogleCategory;
                        }
                        if (string.IsNullOrEmpty(googleProductCategory))
                        {
                            throw new NopException("Default Google category is not set");
                        }
                        writer.WriteStartElement("g", "google_product_category", googleBaseNamespace);
                        writer.WriteCData(googleProductCategory);
                        writer.WriteFullEndElement(); // g:google_product_category

                        //product type [product_type] - Your category of the item
                        var defaultProductCategory = _categoryService
                                                     .GetProductCategoriesByProductId(product.Id, store.Id)
                                                     .FirstOrDefault();
                        if (defaultProductCategory != null)
                        {
                            //TODO localize categories
                            var category = _categoryService.GetFormattedBreadCrumb(defaultProductCategory.Category, separator: ">", languageId: languageId);
                            if (!string.IsNullOrEmpty(category))
                            {
                                writer.WriteStartElement("g", "product_type", googleBaseNamespace);
                                writer.WriteCData(category);
                                writer.WriteFullEndElement(); // g:product_type
                            }
                        }

                        //link [link] - URL directly linking to your item's page on your website
                        var productUrl = GetUrlHelper().RouteUrl("Product", new { SeName = _urlRecordService.GetSeName(product) }, GetHttpProtocol());
                        writer.WriteElementString("link", productUrl);

                        //image link [image_link] - URL of an image of the item
                        //additional images [additional_image_link]
                        //up to 10 pictures
                        const int maximumPictures = 10;
                        var       storeLocation   = _webHelper.GetStoreLocation(_securitySettings.ForceSslForAllPages);
                        var       pictures        = _pictureService.GetPicturesByProductId(product.Id, maximumPictures);
                        for (var i = 0; i < pictures.Count; i++)
                        {
                            var picture  = pictures[i];
                            var imageUrl = _pictureService.GetPictureUrl(picture,
                                                                         googleShoppingSettings.ProductPictureSize,
                                                                         storeLocation: storeLocation);

                            if (i == 0)
                            {
                                //default image
                                writer.WriteElementString("g", "image_link", googleBaseNamespace, imageUrl);
                            }
                            else
                            {
                                //additional image
                                writer.WriteElementString("g", "additional_image_link", googleBaseNamespace, imageUrl);
                            }
                        }
                        if (!pictures.Any())
                        {
                            //no picture? submit a default one
                            var imageUrl = _pictureService.GetDefaultPictureUrl(googleShoppingSettings.ProductPictureSize, storeLocation: storeLocation);
                            writer.WriteElementString("g", "image_link", googleBaseNamespace, imageUrl);
                        }

                        //condition [condition] - Condition or state of the item
                        writer.WriteElementString("g", "condition", googleBaseNamespace, "new");

                        writer.WriteElementString("g", "expiration_date", googleBaseNamespace, DateTime.Now.AddDays(googleShoppingSettings.ExpirationNumberOfDays).ToString("yyyy-MM-dd"));

                        #endregion

                        #region Availability & Price

                        //availability [availability] - Availability status of the item
                        var availability = "in stock"; //in stock by default
                        if (product.ManageInventoryMethod == ManageInventoryMethod.ManageStock &&
                            product.BackorderMode == BackorderMode.NoBackorders &&
                            _productService.GetTotalStockQuantity(product) <= 0)
                        {
                            availability = "out of stock";
                        }
                        //uncomment th code below in order to support "preorder" value for "availability"
                        //if (product.AvailableForPreOrder &&
                        //    (!product.PreOrderAvailabilityStartDateTimeUtc.HasValue ||
                        //    product.PreOrderAvailabilityStartDateTimeUtc.Value >= DateTime.UtcNow))
                        //{
                        //    availability = "preorder";
                        //}
                        writer.WriteElementString("g", "availability", googleBaseNamespace, availability);

                        //price [price] - Price of the item
                        var     currency = GetUsedCurrency();
                        decimal finalPriceBase;
                        if (googleShoppingSettings.PricesConsiderPromotions)
                        {
                            var minPossiblePrice = _priceCalculationService.GetFinalPrice(product, _workContext.CurrentCustomer);

                            if (product.HasTierPrices)
                            {
                                //calculate price for the maximum quantity if we have tier prices, and choose minimal
                                minPossiblePrice = Math.Min(minPossiblePrice,
                                                            _priceCalculationService.GetFinalPrice(product, _workContext.CurrentCustomer, quantity: int.MaxValue));
                            }

                            finalPriceBase = _taxService.GetProductPrice(product, minPossiblePrice, out var _);
                        }
                        else
                        {
                            finalPriceBase = product.Price;
                        }
                        var price = _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceBase, currency);
                        //round price now so it matches the product details page
                        price = _priceCalculationService.RoundPrice(price);

                        writer.WriteElementString("g", "price", googleBaseNamespace,
                                                  price.ToString(new CultureInfo("en-US", false).NumberFormat) + " " +
                                                  currency.CurrencyCode);

                        #endregion

                        #region Unique Product Identifiers

                        /* Unique product identifiers such as UPC, EAN, JAN or ISBN allow us to show your listing on the appropriate product page. If you don't provide the required unique product identifiers, your store may not appear on product pages, and all your items may be removed from Product Search.
                         * We require unique product identifiers for all products - except for custom made goods. For apparel, you must submit the 'brand' attribute. For media (such as books, movies, music and video games), you must submit the 'gtin' attribute. In all cases, we recommend you submit all three attributes.
                         * You need to submit at least two attributes of 'brand', 'gtin' and 'mpn', but we recommend that you submit all three if available. For media (such as books, movies, music and video games), you must submit the 'gtin' attribute, but we recommend that you include 'brand' and 'mpn' if available.
                         */

                        //GTIN [gtin] - GTIN
                        var gtin = product.Gtin;
                        if (!string.IsNullOrEmpty(gtin))
                        {
                            writer.WriteStartElement("g", "gtin", googleBaseNamespace);
                            writer.WriteCData(gtin);
                            writer.WriteFullEndElement(); // g:gtin
                        }

                        //brand [brand] - Brand of the item
                        var defaultManufacturer = _manufacturerService.GetProductManufacturersByProductId(product.Id).FirstOrDefault();
                        if (defaultManufacturer != null)
                        {
                            writer.WriteStartElement("g", "brand", googleBaseNamespace);
                            writer.WriteCData(defaultManufacturer.Manufacturer.Name);
                            writer.WriteFullEndElement(); // g:brand
                        }

                        //mpn [mpn] - Manufacturer Part Number (MPN) of the item
                        var mpn = product.ManufacturerPartNumber;
                        if (!string.IsNullOrEmpty(mpn))
                        {
                            writer.WriteStartElement("g", "mpn", googleBaseNamespace);
                            writer.WriteCData(mpn);
                            writer.WriteFullEndElement(); // g:mpn
                        }

                        //identifier exists [identifier_exists] - Submit custom goods
                        if (googleProduct != null && googleProduct.CustomGoods)
                        {
                            writer.WriteElementString("g", "identifier_exists", googleBaseNamespace, "FALSE");
                        }

                        #endregion

                        #region Apparel Products

                        /* Apparel includes all products that fall under 'Apparel & Accessories' (including all sub-categories)
                         * in Google’s product taxonomy.
                         */

                        //gender [gender] - Gender of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Gender))
                        {
                            writer.WriteStartElement("g", "gender", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Gender);
                            writer.WriteFullEndElement(); // g:gender
                        }

                        //age group [age_group] - Target age group of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.AgeGroup))
                        {
                            writer.WriteStartElement("g", "age_group", googleBaseNamespace);
                            writer.WriteCData(googleProduct.AgeGroup);
                            writer.WriteFullEndElement(); // g:age_group
                        }

                        //color [color] - Color of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Color))
                        {
                            writer.WriteStartElement("g", "color", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Color);
                            writer.WriteFullEndElement(); // g:color
                        }

                        //size [size] - Size of the item
                        if (googleProduct != null && !string.IsNullOrEmpty(googleProduct.Size))
                        {
                            writer.WriteStartElement("g", "size", googleBaseNamespace);
                            writer.WriteCData(googleProduct.Size);
                            writer.WriteFullEndElement(); // g:size
                        }

                        #endregion

                        #region Tax & Shipping

                        //tax [tax]
                        //The tax attribute is an item-level override for merchant-level tax settings as defined in your Google Merchant Center account. This attribute is only accepted in the US, if your feed targets a country outside of the US, please do not use this attribute.
                        //IMPORTANT NOTE: Set tax in your Google Merchant Center account settings

                        //IMPORTANT NOTE: Set shipping in your Google Merchant Center account settings

                        //shipping weight [shipping_weight] - Weight of the item for shipping
                        //We accept only the following units of weight: lb, oz, g, kg.
                        if (googleShoppingSettings.PassShippingInfoWeight)
                        {
                            string weightName;
                            var    shippingWeight   = product.Weight;
                            var    weightSystemName = _measureService.GetMeasureWeightById(_measureSettings.BaseWeightId).SystemKeyword;
                            switch (weightSystemName)
                            {
                            case "ounce":
                                weightName = "oz";
                                break;

                            case "lb":
                                weightName = "lb";
                                break;

                            case "grams":
                                weightName = "g";
                                break;

                            case "kg":
                                weightName = "kg";
                                break;

                            default:
                                //unknown weight
                                throw new Exception("Not supported weight. Google accepts the following units: lb, oz, g, kg.");
                            }
                            writer.WriteElementString("g", "shipping_weight", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", shippingWeight.ToString(new CultureInfo("en-US", false).NumberFormat), weightName));
                        }

                        //shipping length [shipping_length] - Length of the item for shipping
                        //shipping width [shipping_width] - Width of the item for shipping
                        //shipping height [shipping_height] - Height of the item for shipping
                        //We accept only the following units of length: in, cm
                        if (googleShoppingSettings.PassShippingInfoDimensions)
                        {
                            string dimensionName;
                            var    length = product.Length;
                            var    width  = product.Width;
                            var    height = product.Height;
                            var    dimensionSystemName = _measureService.GetMeasureDimensionById(_measureSettings.BaseDimensionId).SystemKeyword;
                            switch (dimensionSystemName)
                            {
                            case "inches":
                                dimensionName = "in";
                                break;

                            //TODO support other dimensions (convert to cm)
                            default:
                                //unknown dimension
                                throw new Exception("Not supported dimension. Google accepts the following units: in, cm.");
                            }
                            writer.WriteElementString("g", "shipping_length", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", length.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                            writer.WriteElementString("g", "shipping_width", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", width.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                            writer.WriteElementString("g", "shipping_height", googleBaseNamespace, string.Format(CultureInfo.InvariantCulture, "{0} {1}", height.ToString(new CultureInfo("en-US", false).NumberFormat), dimensionName));
                        }

                        #endregion

                        writer.WriteEndElement(); // item
                    }
                }

                writer.WriteEndElement(); // channel
                writer.WriteEndElement(); // rss
                writer.WriteEndDocument();
            }
        }
        public async Task <ProductDetailsAttributeChangeModel> Handle(GetProductDetailsAttributeChange request, CancellationToken cancellationToken)
        {
            var model = new ProductDetailsAttributeChangeModel();

            string attributeXml = await _mediator.Send(new GetParseProductAttributes()
            {
                Product = request.Product, Form = request.Form
            });

            string warehouseId = _shoppingCartSettings.AllowToSelectWarehouse ?
                                 request.Form["WarehouseId"].ToString() :
                                 request.Product.UseMultipleWarehouses ? request.Store.DefaultWarehouseId :
                                 (string.IsNullOrEmpty(request.Store.DefaultWarehouseId) ? request.Product.WarehouseId : request.Store.DefaultWarehouseId);

            //rental attributes
            DateTime?rentalStartDate = null;
            DateTime?rentalEndDate   = null;

            if (request.Product.ProductType == ProductType.Reservation)
            {
                request.Product.ParseReservationDates(request.Form, out rentalStartDate, out rentalEndDate);
            }

            model.Sku  = request.Product.FormatSku(attributeXml, _productAttributeParser);
            model.Mpn  = request.Product.FormatMpn(attributeXml, _productAttributeParser);
            model.Gtin = request.Product.FormatGtin(attributeXml, _productAttributeParser);

            if (await _permissionService.Authorize(StandardPermissionProvider.DisplayPrices) && !request.Product.CustomerEntersPrice && request.Product.ProductType != ProductType.Auction)
            {
                //we do not calculate price of "customer enters price" option is enabled
                var unitprice = await _priceCalculationService.GetUnitPrice(request.Product,
                                                                            request.Customer,
                                                                            ShoppingCartType.ShoppingCart,
                                                                            1, attributeXml, 0,
                                                                            rentalStartDate, rentalEndDate,
                                                                            true);

                decimal discountAmount             = unitprice.discountAmount;
                List <AppliedDiscount> scDiscounts = unitprice.appliedDiscounts;
                decimal finalPrice   = unitprice.unitprice;
                var     productprice = await _taxService.GetProductPrice(request.Product, finalPrice);

                decimal finalPriceWithDiscountBase = productprice.productprice;
                decimal taxRate = productprice.taxRate;
                decimal finalPriceWithDiscount = await _currencyService.ConvertFromPrimaryStoreCurrency(finalPriceWithDiscountBase, request.Currency);

                model.Price = _priceFormatter.FormatPrice(finalPriceWithDiscount);
            }
            //stock
            model.StockAvailability = request.Product.FormatStockMessage(warehouseId, attributeXml, _localizationService, _productAttributeParser);

            //back in stock subscription
            if ((request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStockByAttributes ||
                 request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStock) &&
                request.Product.BackorderMode == BackorderMode.NoBackorders &&
                request.Product.AllowBackInStockSubscriptions)
            {
                var combination = _productAttributeParser.FindProductAttributeCombination(request.Product, attributeXml);

                if (combination != null)
                {
                    if (request.Product.GetTotalStockQuantityForCombination(combination, warehouseId: request.Store.DefaultWarehouseId) <= 0)
                    {
                        model.DisplayBackInStockSubscription = true;
                    }
                }

                if (request.Product.ManageInventoryMethod == ManageInventoryMethod.ManageStock)
                {
                    model.DisplayBackInStockSubscription = request.Product.AllowBackInStockSubscriptions;
                    attributeXml = "";
                }

                var subscription = await _backInStockSubscriptionService
                                   .FindSubscription(request.Customer.Id,
                                                     request.Product.Id, attributeXml, request.Store.Id, warehouseId);

                if (subscription != null)
                {
                    model.ButtonTextBackInStockSubscription = _localizationService.GetResource("BackInStockSubscriptions.DeleteNotifyWhenAvailable");
                }
                else
                {
                    model.ButtonTextBackInStockSubscription = _localizationService.GetResource("BackInStockSubscriptions.NotifyMeWhenAvailable");
                }
            }


            //conditional attributes
            if (request.ValidateAttributeConditions)
            {
                var attributes = request.Product.ProductAttributeMappings;
                foreach (var attribute in attributes)
                {
                    var conditionMet = _productAttributeParser.IsConditionMet(request.Product, attribute, attributeXml);
                    if (conditionMet.HasValue)
                    {
                        if (conditionMet.Value)
                        {
                            model.EnabledAttributeMappingIds.Add(attribute.Id);
                        }
                        else
                        {
                            model.DisabledAttributeMappingids.Add(attribute.Id);
                        }
                    }
                }
            }
            //picture. used when we want to override a default product picture when some attribute is selected
            if (request.LoadPicture)
            {
                //first, try to get product attribute combination picture
                var pictureId = request.Product.ProductAttributeCombinations.Where(x => x.AttributesXml == attributeXml).FirstOrDefault()?.PictureId ?? "";
                //then, let's see whether we have attribute values with pictures
                if (string.IsNullOrEmpty(pictureId))
                {
                    pictureId = _productAttributeParser.ParseProductAttributeValues(request.Product, attributeXml)
                                .FirstOrDefault(attributeValue => !string.IsNullOrEmpty(attributeValue.PictureId))?.PictureId ?? "";
                }

                if (!string.IsNullOrEmpty(pictureId))
                {
                    var pictureModel = new PictureModel {
                        Id = pictureId,
                        FullSizeImageUrl = await _pictureService.GetPictureUrl(pictureId),
                        ImageUrl         = await _pictureService.GetPictureUrl(pictureId, _mediaSettings.ProductDetailsPictureSize)
                    };
                    model.PictureFullSizeUrl    = pictureModel.FullSizeImageUrl;
                    model.PictureDefaultSizeUrl = pictureModel.ImageUrl;
                }
            }
            return(model);
        }
Ejemplo n.º 29
0
        public PayPalResponse CreatePayment(
            PayPalApiSettingsBase settings,
            PayPalSessionData session,
            List <OrganizedShoppingCartItem> cart,
            string providerSystemName,
            string returnUrl,
            string cancelUrl)
        {
            var store        = _services.StoreContext.CurrentStore;
            var customer     = _services.WorkContext.CurrentCustomer;
            var language     = _services.WorkContext.WorkingLanguage;
            var currencyCode = store.PrimaryStoreCurrency.CurrencyCode;

            var dateOfBirth = customer.GetAttribute <DateTime?>(SystemCustomerAttributeNames.DateOfBirth);

            Discount orderAppliedDiscount;
            List <AppliedGiftCard> appliedGiftCards;
            int     redeemedRewardPoints = 0;
            decimal redeemedRewardPointsAmount;
            decimal orderDiscountInclTax;
            decimal totalOrderItems = decimal.Zero;

            var includingTax = (_services.WorkContext.GetTaxDisplayTypeFor(customer, store.Id) == TaxDisplayType.IncludingTax);

            var shipping = (_orderTotalCalculationService.GetShoppingCartShippingTotal(cart) ?? decimal.Zero);

            var paymentFee = _paymentService.GetAdditionalHandlingFee(cart, providerSystemName);

            var total = (_orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountInclTax, out orderAppliedDiscount, out appliedGiftCards,
                                                                            out redeemedRewardPoints, out redeemedRewardPointsAmount) ?? decimal.Zero);

            var data          = new Dictionary <string, object>();
            var redirectUrls  = new Dictionary <string, object>();
            var payer         = new Dictionary <string, object>();
            var payerInfo     = new Dictionary <string, object>();
            var transaction   = new Dictionary <string, object>();
            var amount        = new Dictionary <string, object>();
            var amountDetails = new Dictionary <string, object>();
            var items         = new List <Dictionary <string, object> >();
            var itemList      = new Dictionary <string, object>();

            // "PayPal PLUS only supports transaction type “Sale” (instant settlement)"
            if (providerSystemName == PayPalPlusProvider.SystemName)
            {
                data.Add("intent", "sale");
            }
            else
            {
                data.Add("intent", settings.TransactMode == TransactMode.AuthorizeAndCapture ? "sale" : "authorize");
            }

            if (settings.ExperienceProfileId.HasValue())
            {
                data.Add("experience_profile_id", settings.ExperienceProfileId);
            }

            // redirect urls
            if (returnUrl.HasValue())
            {
                redirectUrls.Add("return_url", returnUrl);
            }

            if (cancelUrl.HasValue())
            {
                redirectUrls.Add("cancel_url", cancelUrl);
            }

            if (redirectUrls.Any())
            {
                data.Add("redirect_urls", redirectUrls);
            }

            // payer, payer_info
            if (dateOfBirth.HasValue)
            {
                payerInfo.Add("birth_date", dateOfBirth.Value.ToString("yyyy-MM-dd"));
            }
            if (customer.BillingAddress != null)
            {
                payerInfo.Add("billing_address", CreateAddress(customer.BillingAddress, false));
            }

            payer.Add("payment_method", "paypal");
            payer.Add("payer_info", payerInfo);
            data.Add("payer", payer);

            // line items
            foreach (var item in cart)
            {
                decimal unitPriceTaxRate = decimal.Zero;
                decimal unitPrice        = _priceCalculationService.GetUnitPrice(item, true);
                decimal productPrice     = _taxService.GetProductPrice(item.Item.Product, unitPrice, includingTax, customer, out unitPriceTaxRate);

                var line = new Dictionary <string, object>();
                line.Add("quantity", item.Item.Quantity);
                line.Add("name", item.Item.Product.GetLocalized(x => x.Name, language.Id, true, false).Truncate(127));
                line.Add("price", productPrice.FormatInvariant());
                line.Add("currency", currencyCode);
                line.Add("sku", item.Item.Product.Sku.Truncate(50));
                items.Add(line);

                totalOrderItems += (productPrice * item.Item.Quantity);
            }

            var itemsPlusMisc = (totalOrderItems + shipping + paymentFee);

            if (total != itemsPlusMisc)
            {
                var line = new Dictionary <string, object>();
                line.Add("quantity", "1");
                line.Add("name", T("Plugins.SmartStore.PayPal.Other").Text.Truncate(127));
                line.Add("price", (total - itemsPlusMisc).FormatInvariant());
                line.Add("currency", currencyCode);
                items.Add(line);

                totalOrderItems += (total - itemsPlusMisc);
            }

            itemList.Add("items", items);
            if (customer.ShippingAddress != null)
            {
                itemList.Add("shipping_address", CreateAddress(customer.ShippingAddress, true));
            }

            // transactions
            amountDetails.Add("shipping", shipping.FormatInvariant());
            amountDetails.Add("subtotal", totalOrderItems.FormatInvariant());
            if (!includingTax)
            {
                // "To avoid rounding errors we recommend not submitting tax amounts on line item basis.
                // Calculated tax amounts for the entire shopping basket may be submitted in the amount objects.
                // In this case the item amounts will be treated as amounts excluding tax.
                // In a B2C scenario, where taxes are included, no taxes should be submitted to PayPal."

                SortedDictionary <decimal, decimal> taxRates = null;
                var taxTotal = _orderTotalCalculationService.GetTaxTotal(cart, out taxRates);

                amountDetails.Add("tax", taxTotal.FormatInvariant());
            }
            if (paymentFee != decimal.Zero)
            {
                amountDetails.Add("handling_fee", paymentFee.FormatInvariant());
            }

            amount.Add("total", total.FormatInvariant());
            amount.Add("currency", currencyCode);
            amount.Add("details", amountDetails);

            transaction.Add("amount", amount);
            transaction.Add("item_list", itemList);
            transaction.Add("invoice_number", session.OrderGuid.ToString());

            data.Add("transactions", new List <Dictionary <string, object> > {
                transaction
            });

            var result = CallApi("POST", "/v1/payments/payment", session.AccessToken, settings, JsonConvert.SerializeObject(data));

            if (result.Success && result.Json != null)
            {
                result.Id = (string)result.Json.id;
            }

            //Logger.InsertLog(LogLevel.Information, "PayPal PLUS", JsonConvert.SerializeObject(data, Formatting.Indented) + "\r\n\r\n" + (result.Json != null ? result.Json.ToString() : ""));

            return(result);
        }
        protected virtual decimal GetPreselectedPrice(Product product, PriceCalculationContext context, ProductBundleItemData bundleItem, IEnumerable <ProductBundleItemData> bundleItems)
        {
            var taxRate = decimal.Zero;
            var attributesTotalPriceBase       = decimal.Zero;
            var preSelectedPriceAdjustmentBase = decimal.Zero;
            var isBundle            = (product.ProductType == ProductType.BundledProduct);
            var isBundleItemPricing = (bundleItem != null && bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var isBundlePricing     = (bundleItem != null && !bundleItem.Item.BundleProduct.BundlePerItemPricing);
            var bundleItemId        = (bundleItem == null ? 0 : bundleItem.Item.Id);

            var selectedAttributes      = new NameValueCollection();
            var selectedAttributeValues = new List <ProductVariantAttributeValue>();
            var attributes = context.Attributes.Load(product.Id);

            // 1. fill selectedAttributes with initially selected attributes
            foreach (var attribute in attributes.Where(x => x.ProductVariantAttributeValues.Count > 0 && x.ShouldHaveValues()))
            {
                int preSelectedValueId = 0;
                ProductVariantAttributeValue defaultValue = null;
                var selectedValueIds = new List <int>();
                var pvaValues        = attribute.ProductVariantAttributeValues;

                foreach (var pvaValue in pvaValues)
                {
                    ProductBundleItemAttributeFilter attributeFilter = null;

                    if (bundleItem.FilterOut(pvaValue, out attributeFilter))
                    {
                        continue;
                    }

                    if (preSelectedValueId == 0 && attributeFilter != null && attributeFilter.IsPreSelected)
                    {
                        preSelectedValueId = attributeFilter.AttributeValueId;
                    }

                    if (!isBundlePricing && pvaValue.IsPreSelected)
                    {
                        decimal attributeValuePriceAdjustment = GetProductVariantAttributeValuePriceAdjustment(pvaValue);
                        decimal priceAdjustmentBase           = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, out taxRate);

                        preSelectedPriceAdjustmentBase = decimal.Add(preSelectedPriceAdjustmentBase, priceAdjustmentBase);
                    }
                }

                // value pre-selected by a bundle item filter discards the default pre-selection
                if (preSelectedValueId != 0 && (defaultValue = pvaValues.FirstOrDefault(x => x.Id == preSelectedValueId)) != null)
                {
                    //defaultValue.IsPreSelected = true;
                    selectedAttributeValues.Add(defaultValue);
                    selectedAttributes.AddProductAttribute(attribute.ProductAttributeId, attribute.Id, defaultValue.Id, product.Id, bundleItemId);
                }
                else
                {
                    foreach (var value in pvaValues.Where(x => x.IsPreSelected))
                    {
                        selectedAttributeValues.Add(value);
                        selectedAttributes.AddProductAttribute(attribute.ProductAttributeId, attribute.Id, value.Id, product.Id, bundleItemId);
                    }
                }
            }

            // 2. find attribute combination for selected attributes and merge it
            if (!isBundle && selectedAttributes.Count > 0)
            {
                var attributeXml = selectedAttributes.CreateSelectedAttributesXml(product.Id, attributes, _productAttributeParser, _services.Localization,
                                                                                  _downloadService, _catalogSettings, _httpRequestBase, new List <string>(), true, bundleItemId);

                var combinations = context.AttributeCombinations.Load(product.Id);

                var selectedCombination = combinations.FirstOrDefault(x => _productAttributeParser.AreProductAttributesEqual(x.AttributesXml, attributeXml));

                if (selectedCombination != null && selectedCombination.IsActive && selectedCombination.Price.HasValue)
                {
                    product.MergedDataValues = new Dictionary <string, object> {
                        { "Price", selectedCombination.Price.Value }
                    };
                }
            }

            if (_catalogSettings.EnableDynamicPriceUpdate && !isBundlePricing)
            {
                if (selectedAttributeValues.Count > 0)
                {
                    selectedAttributeValues.Each(x => attributesTotalPriceBase += GetProductVariantAttributeValuePriceAdjustment(x));
                }
                else
                {
                    attributesTotalPriceBase = preSelectedPriceAdjustmentBase;
                }
            }

            if (bundleItem != null)
            {
                bundleItem.AdditionalCharge = attributesTotalPriceBase;
            }

            var result = GetFinalPrice(product, bundleItems, _services.WorkContext.CurrentCustomer, attributesTotalPriceBase, true, 1, bundleItem, context);

            return(result);
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Formats attributes
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="attributesXml">Attributes in XML format</param>
        /// <param name="customer">Customer</param>
        /// <param name="separator">Separator</param>
        /// <param name="htmlEncode">A value indicating whether to encode (HTML) values</param>
        /// <param name="renderPrices">A value indicating whether to render prices</param>
        /// <param name="renderProductAttributes">A value indicating whether to render product attributes</param>
        /// <param name="renderGiftCardAttributes">A value indicating whether to render gift card attributes</param>
        /// <param name="allowHyperlinks">A value indicating whether to HTML hyperink tags could be rendered (if required)</param>
        /// <returns>Attributes</returns>
        public virtual string FormatAttributes(Product product, string attributesXml,
                                               Customer customer, string separator = "<br />", bool htmlEncode           = true, bool renderPrices = true,
                                               bool renderProductAttributes        = true, bool renderGiftCardAttributes = true,
                                               bool allowHyperlinks = true)
        {
            var result = new StringBuilder();

            //attributes
            if (renderProductAttributes)
            {
                foreach (var attribute in _productAttributeParser.ParseProductAttributeMappings(attributesXml))
                {
                    //attributes without values
                    if (!attribute.ShouldHaveValues())
                    {
                        foreach (var value in _productAttributeParser.ParseValues(attributesXml, attribute.Id))
                        {
                            var formattedAttribute = string.Empty;
                            if (attribute.AttributeControlType == AttributeControlType.MultilineTextbox)
                            {
                                //multiline textbox
                                var attributeName = _localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id);

                                //encode (if required)
                                if (htmlEncode)
                                {
                                    attributeName = WebUtility.HtmlEncode(attributeName);
                                }

                                //we never encode multiline textbox input
                                formattedAttribute = $"{attributeName}: {HtmlHelper.FormatText(value, false, true, false, false, false, false)}";
                            }
                            else if (attribute.AttributeControlType == AttributeControlType.FileUpload)
                            {
                                //file upload
                                Guid.TryParse(value, out var downloadGuid);
                                var download = _downloadService.GetDownloadByGuid(downloadGuid);
                                if (download != null)
                                {
                                    var fileName = $"{download.Filename ?? download.DownloadGuid.ToString()}{download.Extension}";

                                    //encode (if required)
                                    if (htmlEncode)
                                    {
                                        fileName = WebUtility.HtmlEncode(fileName);
                                    }

                                    //TODO add a method for getting URL (use routing because it handles all SEO friendly URLs)
                                    var attributeText = allowHyperlinks ? $"<a href=\"{_webHelper.GetStoreLocation(false)}download/getfileupload/?downloadId={download.DownloadGuid}\" class=\"fileuploadattribute\">{fileName}</a>"
                                        : fileName;

                                    var attributeName = _localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id);

                                    //encode (if required)
                                    if (htmlEncode)
                                    {
                                        attributeName = WebUtility.HtmlEncode(attributeName);
                                    }

                                    formattedAttribute = $"{attributeName}: {attributeText}";
                                }
                            }
                            else
                            {
                                //other attributes (textbox, datepicker)
                                formattedAttribute = $"{_localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id)}: {value}";

                                //encode (if required)
                                if (htmlEncode)
                                {
                                    formattedAttribute = WebUtility.HtmlEncode(formattedAttribute);
                                }
                            }

                            if (string.IsNullOrEmpty(formattedAttribute))
                            {
                                continue;
                            }

                            if (result.Length > 0)
                            {
                                result.Append(separator);
                            }
                            result.Append(formattedAttribute);
                        }
                    }
                    //product attribute values
                    else
                    {
                        foreach (var attributeValue in _productAttributeParser.ParseProductAttributeValues(attributesXml, attribute.Id))
                        {
                            var formattedAttribute = $"{_localizationService.GetLocalized(attribute.ProductAttribute, a => a.Name, _workContext.WorkingLanguage.Id)}: {_localizationService.GetLocalized(attributeValue, a => a.Name, _workContext.WorkingLanguage.Id)}";

                            if (renderPrices)
                            {
                                if (attributeValue.PriceAdjustmentUsePercentage)
                                {
                                    if (attributeValue.PriceAdjustment > decimal.Zero)
                                    {
                                        formattedAttribute += string.Format(
                                            _localizationService.GetResource("FormattedAttributes.PriceAdjustment"),
                                            "+", attributeValue.PriceAdjustment.ToString("G29"), "%");
                                    }
                                    else if (attributeValue.PriceAdjustment < decimal.Zero)
                                    {
                                        formattedAttribute += string.Format(
                                            _localizationService.GetResource("FormattedAttributes.PriceAdjustment"),
                                            string.Empty, attributeValue.PriceAdjustment.ToString("G29"), "%");
                                    }
                                }
                                else
                                {
                                    var attributeValuePriceAdjustment = _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue, customer);
                                    var priceAdjustmentBase           = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out var _);
                                    var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency);

                                    if (priceAdjustmentBase > decimal.Zero)
                                    {
                                        formattedAttribute += string.Format(
                                            _localizationService.GetResource("FormattedAttributes.PriceAdjustment"),
                                            "+", _priceFormatter.FormatPrice(priceAdjustment, false, false), string.Empty);
                                    }
                                    else if (priceAdjustmentBase < decimal.Zero)
                                    {
                                        formattedAttribute += string.Format(
                                            _localizationService.GetResource("FormattedAttributes.PriceAdjustment"),
                                            "-", _priceFormatter.FormatPrice(-priceAdjustment, false, false), string.Empty);
                                    }
                                }
                            }

                            //display quantity
                            if (_shoppingCartSettings.RenderAssociatedAttributeValueQuantity && attributeValue.AttributeValueType == AttributeValueType.AssociatedToProduct)
                            {
                                //render only when more than 1
                                if (attributeValue.Quantity > 1)
                                {
                                    formattedAttribute += string.Format(_localizationService.GetResource("ProductAttributes.Quantity"), attributeValue.Quantity);
                                }
                            }

                            //encode (if required)
                            if (htmlEncode)
                            {
                                formattedAttribute = WebUtility.HtmlEncode(formattedAttribute);
                            }

                            if (string.IsNullOrEmpty(formattedAttribute))
                            {
                                continue;
                            }

                            if (result.Length > 0)
                            {
                                result.Append(separator);
                            }
                            result.Append(formattedAttribute);
                        }
                    }
                }
            }

            //gift cards
            if (!renderGiftCardAttributes)
            {
                return(result.ToString());
            }

            if (!product.IsGiftCard)
            {
                return(result.ToString());
            }

            _productAttributeParser.GetGiftCardAttribute(attributesXml, out var giftCardRecipientName, out var giftCardRecipientEmail, out var giftCardSenderName, out var giftCardSenderEmail, out var _);

            //sender
            var giftCardFrom = product.GiftCardType == GiftCardType.Virtual ?
                               string.Format(_localizationService.GetResource("GiftCardAttribute.From.Virtual"), giftCardSenderName, giftCardSenderEmail) :
                               string.Format(_localizationService.GetResource("GiftCardAttribute.From.Physical"), giftCardSenderName);
            //recipient
            var giftCardFor = product.GiftCardType == GiftCardType.Virtual ?
                              string.Format(_localizationService.GetResource("GiftCardAttribute.For.Virtual"), giftCardRecipientName, giftCardRecipientEmail) :
                              string.Format(_localizationService.GetResource("GiftCardAttribute.For.Physical"), giftCardRecipientName);

            //encode (if required)
            if (htmlEncode)
            {
                giftCardFrom = WebUtility.HtmlEncode(giftCardFrom);
                giftCardFor  = WebUtility.HtmlEncode(giftCardFor);
            }

            if (!string.IsNullOrEmpty(result.ToString()))
            {
                result.Append(separator);
            }

            result.Append(giftCardFrom);
            result.Append(separator);
            result.Append(giftCardFor);

            return(result.ToString());
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Gets the base price
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="localizationService">Localization service</param>
        /// <param name="priceFormatter">Price formatter</param>
        /// <param name="priceAdjustment">Price adjustment</param>
        /// <param name="languageIndependent">Whether the result string should be language independent</param>
        /// <returns>The base price</returns>
        public static string GetBasePriceInfo(this Product product, ILocalizationService localizationService, IPriceFormatter priceFormatter,
            ICurrencyService currencyService, ITaxService taxService, IPriceCalculationService priceCalculationService,
            Currency currency, decimal priceAdjustment = decimal.Zero, bool languageIndependent = false)
        {
            if (product == null)
                throw new ArgumentNullException("product");

            if (localizationService == null && !languageIndependent)
                throw new ArgumentNullException("localizationService");

            if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero)
            {
                var workContext = EngineContext.Current.Resolve<IWorkContext>();

                var taxrate = decimal.Zero;
                var currentPrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, true);
                decimal price = taxService.GetProductPrice(product, decimal.Add(currentPrice, priceAdjustment), out taxrate);

                price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency);

                decimal basePriceValue = Convert.ToDecimal((price / product.BasePriceAmount) * product.BasePriceBaseAmount);

                string basePrice = priceFormatter.FormatPrice(basePriceValue, true, currency);
                string unit = "{0} {1}".FormatWith(product.BasePriceBaseAmount, product.BasePriceMeasureUnit);

                if (languageIndependent)
                {
                    return "{0} / {1}".FormatWith(basePrice, unit);
                }

                return localizationService.GetResource("Products.BasePriceInfo").FormatWith(basePrice, unit);
            }
            return "";
        }
        /// <summary>
        /// Gets the base price info
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="localizationService">Localization service</param>
        /// <param name="priceFormatter">Price formatter</param>
        /// <param name="currencyService">Currency service</param>
        /// <param name="taxService">Tax service</param>
        /// <param name="priceCalculationService">Price calculation service</param>
        /// <param name="currency">Target currency</param>
        /// <param name="priceAdjustment">Price adjustment</param>
        /// <param name="languageInsensitive">Whether the result string should be language insensitive</param>
        /// <returns>The base price info</returns>
        public static string GetBasePriceInfo(this Product product,
			ILocalizationService localizationService,
			IPriceFormatter priceFormatter,
            ICurrencyService currencyService,
			ITaxService taxService,
			IPriceCalculationService priceCalculationService,
            Currency currency,
			decimal priceAdjustment = decimal.Zero,
			bool languageInsensitive = false)
        {
            Guard.ArgumentNotNull(() => product);
            Guard.ArgumentNotNull(() => currencyService);
            Guard.ArgumentNotNull(() => taxService);
            Guard.ArgumentNotNull(() => priceCalculationService);
            Guard.ArgumentNotNull(() => currency);

            if (product.BasePriceHasValue && product.BasePriceAmount != Decimal.Zero)
            {
                var workContext = EngineContext.Current.Resolve<IWorkContext>();

                var taxrate = decimal.Zero;
                var currentPrice = priceCalculationService.GetFinalPrice(product, workContext.CurrentCustomer, true);
                var price = taxService.GetProductPrice(product, decimal.Add(currentPrice, priceAdjustment), out taxrate);

                price = currencyService.ConvertFromPrimaryStoreCurrency(price, currency);

                return product.GetBasePriceInfo(price, localizationService, priceFormatter, currency, languageInsensitive);
            }

            return "";
        }