public override async Task MapAsync(OrganizedShoppingCartItem from, TModel to, dynamic parameters = null)
        {
            Guard.NotNull(from, nameof(from));
            Guard.NotNull(to, nameof(to));

            var item             = from.Item;
            var product          = from.Item.Product;
            var customer         = item.Customer;
            var currency         = _services.WorkContext.WorkingCurrency;
            var shoppingCartType = item.ShoppingCartType;
            var productSeName    = await product.GetActiveSlugAsync();

            var taxFormat    = parameters?.TaxFormat as string;
            var batchContext = parameters?.BatchContext as ProductBatchContext;

            await _productAttributeMaterializer.MergeWithCombinationAsync(product, item.AttributeSelection);

            // General model data.
            to.Id            = item.Id;
            to.Sku           = product.Sku;
            to.ProductId     = product.Id;
            to.ProductName   = product.GetLocalized(x => x.Name);
            to.ProductSeName = productSeName;
            to.ProductUrl    = await ProductUrlHelper.GetProductUrlAsync(productSeName, from);

            to.EnteredQuantity     = item.Quantity;
            to.MinOrderAmount      = product.OrderMinimumQuantity;
            to.MaxOrderAmount      = product.OrderMaximumQuantity;
            to.QuantityStep        = product.QuantityStep > 0 ? product.QuantityStep : 1;
            to.ShortDesc           = product.GetLocalized(x => x.ShortDescription);
            to.ProductType         = product.ProductType;
            to.VisibleIndividually = product.Visibility != ProductVisibility.Hidden;
            to.CreatedOnUtc        = item.UpdatedOnUtc;

            if (item.BundleItem != null)
            {
                to.BundleItem.Id             = item.BundleItem.Id;
                to.BundleItem.DisplayOrder   = item.BundleItem.DisplayOrder;
                to.BundleItem.HideThumbnail  = item.BundleItem.HideThumbnail;
                to.BundlePerItemPricing      = item.BundleItem.BundleProduct.BundlePerItemPricing;
                to.BundlePerItemShoppingCart = item.BundleItem.BundleProduct.BundlePerItemShoppingCart;

                to.AttributeInfo = await ProductAttributeFormatter.FormatAttributesAsync(
                    item.AttributeSelection,
                    product,
                    customer,
                    includePrices : false,
                    includeGiftCardAttributes : true,
                    includeHyperlinks : true,
                    batchContext : batchContext);

                var bundleItemName = item.BundleItem.GetLocalized(x => x.Name);
                if (bundleItemName.Value.HasValue())
                {
                    to.ProductName = bundleItemName;
                }

                var bundleItemShortDescription = item.BundleItem.GetLocalized(x => x.ShortDescription);
                if (bundleItemShortDescription.Value.HasValue())
                {
                    to.ShortDesc = bundleItemShortDescription;
                }

                var calculationOptions = _priceCalculationService.CreateDefaultOptions(false, customer, null, batchContext);
                var calculationContext = await _priceCalculationService.CreateCalculationContextAsync(from, calculationOptions);

                var(bundleItemUnitPrice, bundleItemSubtotal) = await _priceCalculationService.CalculateSubtotalAsync(calculationContext);

                if (to.BundlePerItemPricing && to.BundlePerItemShoppingCart)
                {
                    to.BundleItem.PriceWithDiscount = bundleItemSubtotal.FinalPrice.ToString();
                }

                to.BasePrice = _priceCalculationService.GetBasePriceInfo(product, bundleItemUnitPrice.FinalPrice);
            }
            else
            {
                to.AttributeInfo = await ProductAttributeFormatter.FormatAttributesAsync(item.AttributeSelection, product, customer, batchContext : batchContext);
            }

            var allowedQuantities = product.ParseAllowedQuantities();

            foreach (var quantity in allowedQuantities)
            {
                to.AllowedQuantities.Add(new SelectListItem
                {
                    Text     = quantity.ToString(),
                    Value    = quantity.ToString(),
                    Selected = item.Quantity == quantity
                });
            }

            var quantityUnit = await Db.QuantityUnits.GetQuantityUnitByIdAsync(product.QuantityUnitId ?? 0, _catalogSettings.ShowDefaultQuantityUnit);

            if (quantityUnit != null)
            {
                to.QuantityUnitName = quantityUnit.GetLocalized(x => x.Name);
            }

            if (product.IsRecurring)
            {
                to.RecurringInfo = T("ShoppingCart.RecurringPeriod", product.RecurringCycleLength, product.RecurringCyclePeriod.GetLocalizedEnum());
            }

            if (product.CallForPrice)
            {
                to.UnitPrice = to.UnitPrice.WithPostFormat(T("Products.CallForPrice"));
                to.SubTotal  = to.UnitPrice;
            }
            else if (item.BundleItem == null)
            {
                if (shoppingCartType == ShoppingCartType.ShoppingCart)
                {
                    var subtotal = parameters?.CartSubtotal as ShoppingCartSubtotal;
                    var lineItem = subtotal.LineItems.FirstOrDefault(x => x.Item.Item.Id == item.Id);

                    var unitPrice = CurrencyService.ConvertFromPrimaryCurrency(lineItem.UnitPrice.FinalPrice.Amount, currency);
                    to.UnitPrice = unitPrice.WithPostFormat(taxFormat);

                    var itemSubtotal = CurrencyService.ConvertFromPrimaryCurrency(lineItem.Subtotal.FinalPrice.Amount, currency);
                    to.SubTotal = itemSubtotal.WithPostFormat(taxFormat);

                    if (lineItem.Subtotal.DiscountAmount > 0)
                    {
                        var itemDiscount = CurrencyService.ConvertFromPrimaryCurrency(lineItem.Subtotal.DiscountAmount.Amount, currency);
                        to.Discount = itemDiscount.WithPostFormat(taxFormat);
                    }

                    to.BasePrice = _priceCalculationService.GetBasePriceInfo(product, unitPrice);
                }
                else
                {
                    var calculationOptions = _priceCalculationService.CreateDefaultOptions(false, customer, null, batchContext);
                    var calculationContext = await _priceCalculationService.CreateCalculationContextAsync(from, calculationOptions);

                    var(unitPrice, itemSubtotal) = await _priceCalculationService.CalculateSubtotalAsync(calculationContext);

                    to.UnitPrice = unitPrice.FinalPrice;
                    to.SubTotal  = itemSubtotal.FinalPrice;

                    if (itemSubtotal.DiscountAmount > 0)
                    {
                        to.Discount = itemSubtotal.DiscountAmount;
                    }
                }
            }

            if (item.BundleItem != null)
            {
                if (_shoppingCartSettings.ShowProductBundleImagesOnShoppingCart)
                {
                    await from.MapAsync(to.Image, MediaSettings.CartThumbBundleItemPictureSize, to.ProductName);
                }
            }
            else
            {
                if (_shoppingCartSettings.ShowProductImagesOnShoppingCart)
                {
                    await from.MapAsync(to.Image, MediaSettings.CartThumbPictureSize, to.ProductName);
                }
            }

            var itemWarnings = new List <string>();
            var isValid      = await ShoppingCartValidator.ValidateCartItemsAsync(new[] { from }, itemWarnings);

            if (!isValid)
            {
                to.Warnings.AddRange(itemWarnings);
            }

            var cart = await ShoppingCartService.GetCartItemsAsync(customer, shoppingCartType, _services.StoreContext.CurrentStore.Id);

            var attrWarnings = new List <string>();

            isValid = await ShoppingCartValidator.ValidateProductAttributesAsync(item, cart, attrWarnings);

            if (!isValid)
            {
                to.Warnings.AddRange(attrWarnings);
            }
        }
Example #2
0
        protected async Task <SubmitReturnRequestModel> PrepareReturnRequestModelAsync(SubmitReturnRequestModel model, Order order)
        {
            Guard.NotNull(order, nameof(order));
            Guard.NotNull(model, nameof(model));

            model.OrderId = order.Id;

            var    language             = Services.WorkContext.WorkingLanguage;
            string returnRequestReasons = _orderSettings.GetLocalizedSetting(x => x.ReturnRequestReasons, order.CustomerLanguageId, order.StoreId, true, false);
            string returnRequestActions = _orderSettings.GetLocalizedSetting(x => x.ReturnRequestActions, order.CustomerLanguageId, order.StoreId, true, false);

            // Return reasons.
            var availableReturnReasons = new List <SelectListItem>();

            foreach (var rrr in returnRequestReasons.SplitSafe(","))
            {
                availableReturnReasons.Add(new SelectListItem {
                    Text = rrr, Value = rrr
                });
            }
            ViewBag.AvailableReturnReasons = availableReturnReasons;

            // Return actions.
            var availableReturnActions = new List <SelectListItem>();

            foreach (var rra in returnRequestActions.SplitSafe(","))
            {
                availableReturnActions.Add(new SelectListItem {
                    Text = rra, Value = rra
                });
            }
            ViewBag.AvailableReturnActions = availableReturnActions;

            foreach (var orderItem in order.OrderItems)
            {
                var orderItemModel = new SubmitReturnRequestModel.OrderItemModel
                {
                    Id            = orderItem.Id,
                    ProductId     = orderItem.Product.Id,
                    ProductName   = orderItem.Product.GetLocalized(x => x.Name),
                    ProductSeName = await orderItem.Product.GetActiveSlugAsync(),
                    AttributeInfo = orderItem.AttributeDescription,
                    Quantity      = orderItem.Quantity
                };

                orderItemModel.ProductUrl = await _productUrlHelper.GetProductUrlAsync(orderItemModel.ProductSeName, orderItem);

                // TODO: (mh) (core) Reconsider when pricing is available.
                var customerCurrency = await _db.Currencies
                                       .AsNoTracking()
                                       .Where(x => x.CurrencyCode == order.CustomerCurrencyCode)
                                       .FirstOrDefaultAsync() ?? new Currency
                {
                    CurrencyCode = order.CustomerCurrencyCode
                };

                // Unit price.
                switch (order.CustomerTaxDisplayType)
                {
                case TaxDisplayType.ExcludingTax:
                {
                    // TODO: (mh) (core) _currencyService.ConvertToCurrency doesn't take a rate as paramter.
                    //var unitPriceExclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceExclTax, order.CurrencyRate);
                    //orderItemModel.UnitPrice = _priceFormatter.FormatPrice(unitPriceExclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, false);
                    orderItemModel.UnitPrice = new Money(orderItem.UnitPriceExclTax, customerCurrency);
                }
                break;

                case TaxDisplayType.IncludingTax:
                {
                    //var unitPriceInclTaxInCustomerCurrency = _currencyService.ConvertCurrency(orderItem.UnitPriceInclTax, order.CurrencyRate);
                    //orderItemModel.UnitPrice = _priceFormatter.FormatPrice(unitPriceInclTaxInCustomerCurrency, true, order.CustomerCurrencyCode, language, true);
                    orderItemModel.UnitPrice = new Money(orderItem.UnitPriceInclTax, customerCurrency);
                }
                break;
                }

                model.Items.Add(orderItemModel);
            }

            return(model);
        }
Example #3
0
        private async Task <OrderDetailsModel.OrderItemModel> PrepareOrderItemModelAsync(
            Order order,
            OrderItem orderItem,
            CatalogSettings catalogSettings,
            ShoppingCartSettings shoppingCartSettings,
            MediaSettings mediaSettings,
            Currency customerCurrency)
        {
            var language = _services.WorkContext.WorkingLanguage;

            var attributeCombination = await _productAttributeMaterializer.FindAttributeCombinationAsync(orderItem.ProductId, orderItem.AttributeSelection);

            if (attributeCombination != null)
            {
                orderItem.Product.MergeWithCombination(attributeCombination);
            }

            var model = new OrderDetailsModel.OrderItemModel
            {
                Id            = orderItem.Id,
                Sku           = orderItem.Product.Sku,
                ProductId     = orderItem.Product.Id,
                ProductName   = orderItem.Product.GetLocalized(x => x.Name),
                ProductSeName = await orderItem.Product.GetActiveSlugAsync(),
                ProductType   = orderItem.Product.ProductType,
                Quantity      = orderItem.Quantity,
                AttributeInfo = orderItem.AttributeDescription
            };

            var quantityUnit = await _db.QuantityUnits.FindByIdAsync(orderItem.Product.QuantityUnitId ?? 0, false);

            model.QuantityUnit = quantityUnit == null ? string.Empty : quantityUnit.GetLocalized(x => x.Name);

            if (orderItem.Product.ProductType == ProductType.BundledProduct && orderItem.BundleData.HasValue())
            {
                var bundleData  = orderItem.GetBundleData();
                var bundleItems = new Dictionary <int, ProductBundleItem>();

                if (shoppingCartSettings.ShowProductBundleImagesOnShoppingCart)
                {
                    var bundleProducts = await _db.ProductBundleItem
                                         .AsNoTracking()
                                         .Include(x => x.Product)
                                         .ApplyBundledProductsFilter(new[] { orderItem.ProductId })
                                         .ToListAsync();

                    bundleItems = bundleProducts.ToDictionarySafe(x => x.ProductId);
                }

                model.BundlePerItemPricing      = orderItem.Product.BundlePerItemPricing;
                model.BundlePerItemShoppingCart = bundleData.Any(x => x.PerItemShoppingCart);

                foreach (var bid in bundleData)
                {
                    var bundleItemModel = new OrderDetailsModel.BundleItemModel
                    {
                        Sku                 = bid.Sku,
                        ProductName         = bid.ProductName,
                        ProductSeName       = bid.ProductSeName,
                        VisibleIndividually = bid.VisibleIndividually,
                        Quantity            = bid.Quantity,
                        DisplayOrder        = bid.DisplayOrder,
                        AttributeInfo       = bid.AttributesInfo
                    };

                    bundleItemModel.ProductUrl = await _productUrlHelper.GetProductUrlAsync(bid.ProductId, bundleItemModel.ProductSeName, bid.AttributeSelection);

                    if (model.BundlePerItemShoppingCart)
                    {
                        var priceWithDiscount = _currencyService.ConvertToExchangeRate(bid.PriceWithDiscount, order.CurrencyRate, customerCurrency);
                        bundleItemModel.PriceWithDiscount = priceWithDiscount.ToString();
                    }

                    // Bundle item picture.
                    if (shoppingCartSettings.ShowProductBundleImagesOnShoppingCart && bundleItems.TryGetValue(bid.ProductId, out var bundleItem))
                    {
                        bundleItemModel.HideThumbnail = bundleItem.HideThumbnail;

                        bundleItemModel.Image = await PrepareOrderItemImageModelAsync(
                            bundleItem.Product,
                            mediaSettings.CartThumbBundleItemPictureSize,
                            bid.ProductName,
                            bid.AttributeSelection,
                            catalogSettings);
                    }

                    model.BundleItems.Add(bundleItemModel);
                }
            }

            // Unit price, subtotal.
            switch (order.CustomerTaxDisplayType)
            {
            case TaxDisplayType.ExcludingTax:
            {
                var unitPriceExclTaxInCustomerCurrency = _currencyService.ConvertToExchangeRate(orderItem.UnitPriceExclTax, order.CurrencyRate, customerCurrency);
                model.UnitPrice = unitPriceExclTaxInCustomerCurrency;

                var priceExclTaxInCustomerCurrency = _currencyService.ConvertToExchangeRate(orderItem.PriceExclTax, order.CurrencyRate, customerCurrency);
                model.SubTotal = priceExclTaxInCustomerCurrency.ToString();
            }
            break;

            case TaxDisplayType.IncludingTax:
            {
                var unitPriceInclTaxInCustomerCurrency = _currencyService.ConvertToExchangeRate(orderItem.UnitPriceInclTax, order.CurrencyRate, customerCurrency);
                model.UnitPrice = unitPriceInclTaxInCustomerCurrency;

                var priceInclTaxInCustomerCurrency = _currencyService.ConvertToExchangeRate(orderItem.PriceInclTax, order.CurrencyRate, customerCurrency);
                model.SubTotal = priceInclTaxInCustomerCurrency.ToString();
            }
            break;
            }

            model.ProductUrl = await _productUrlHelper.GetProductUrlAsync(orderItem.ProductId, model.ProductSeName, orderItem.AttributeSelection);

            if (shoppingCartSettings.ShowProductImagesOnShoppingCart)
            {
                model.Image = await PrepareOrderItemImageModelAsync(
                    orderItem.Product,
                    mediaSettings.CartThumbPictureSize,
                    model.ProductName,
                    orderItem.AttributeSelection,
                    catalogSettings);
            }

            return(model);
        }
Example #4
0
        public async Task <IActionResult> Search(CatalogSearchQuery query)
        {
            var model = new SearchResultModel(query);
            CatalogSearchResult result = null;

            if (query.Term == null || query.Term.Length < _searchSettings.InstantSearchTermMinLength)
            {
                model.SearchResult = new CatalogSearchResult(query);
                model.Error        = T("Search.SearchTermMinimumLengthIsNCharacters", _searchSettings.InstantSearchTermMinLength);
                return(View(model));
            }

            Services.WorkContext.CurrentCustomer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false);

            try
            {
                if (_searchSettings.SearchProductByIdentificationNumber)
                {
                    var(product, attributeCombination) = await _productService.Value.GetProductByIdentificationNumberAsync(query.Term);

                    if (product != null)
                    {
                        if (attributeCombination != null)
                        {
                            return(Redirect(await _productUrlHelper.GetProductUrlAsync(product.Id, await product.GetActiveSlugAsync(), attributeCombination.AttributeSelection)));
                        }

                        return(RedirectToRoute("Product", new { SeName = await product.GetActiveSlugAsync() }));
                    }
                }

                result = await _catalogSearchService.SearchAsync(query);
            }
            catch (Exception ex)
            {
                model.Error = ex.ToString();
                result      = new CatalogSearchResult(query);
            }

            if (result.TotalHitsCount == 0 && result.SpellCheckerSuggestions.Any())
            {
                // No matches, but spell checker made a suggestion.
                // We implicitly search again with the first suggested term.
                var oldSuggestions = result.SpellCheckerSuggestions;
                var oldTerm        = query.Term;
                query.Term = oldSuggestions[0];

                result = await _catalogSearchService.SearchAsync(query);

                if (result.TotalHitsCount > 0)
                {
                    model.AttemptedTerm = oldTerm;
                    // Restore the original suggestions.
                    result.SpellCheckerSuggestions = oldSuggestions.Where(x => x != query.Term).ToArray();
                }
                else
                {
                    query.Term = oldTerm;
                }
            }

            model.SearchResult       = result;
            model.Term               = query.Term;
            model.TotalProductsCount = result.TotalHitsCount;

            var mappingSettings = _catalogHelper.GetBestFitProductSummaryMappingSettings(_catalogHelper.GetSearchQueryViewMode(query));
            var summaryModel    = await _catalogHelper.MapProductSummaryModelAsync(await result.GetHitsAsync(), mappingSettings);

            // Prepare paging/sorting/mode stuff.
            _catalogHelper.MapListActions(summaryModel, null, _catalogSettings.DefaultPageSizeOptions);

            // Add product hits.
            model.TopProducts = summaryModel;

            return(View(model));
        }
Example #5
0
        private async Task <WishlistModel.ShoppingCartItemModel> PrepareWishlistCartItemModelAsync(OrganizedShoppingCartItem cartItem)
        {
            Guard.NotNull(cartItem, nameof(cartItem));

            var item     = cartItem.Item;
            var product  = item.Product;
            var customer = item.Customer;
            var currency = Services.WorkContext.WorkingCurrency;

            await _productAttributeMaterializer.MergeWithCombinationAsync(product, item.AttributeSelection);

            var productSeName = await SeoExtensions.GetActiveSlugAsync(product);

            var model = new WishlistModel.ShoppingCartItemModel
            {
                Id                  = item.Id,
                Sku                 = product.Sku,
                ProductId           = product.Id,
                ProductName         = product.GetLocalized(x => x.Name),
                ProductSeName       = productSeName,
                ProductUrl          = await _productUrlHelper.GetProductUrlAsync(productSeName, cartItem),
                EnteredQuantity     = item.Quantity,
                MinOrderAmount      = product.OrderMinimumQuantity,
                MaxOrderAmount      = product.OrderMaximumQuantity,
                QuantityStep        = product.QuantityStep > 0 ? product.QuantityStep : 1,
                ShortDesc           = product.GetLocalized(x => x.ShortDescription),
                ProductType         = product.ProductType,
                VisibleIndividually = product.Visibility != ProductVisibility.Hidden,
                CreatedOnUtc        = item.UpdatedOnUtc,
                DisableBuyButton    = product.DisableBuyButton,
            };

            if (item.BundleItem != null)
            {
                model.BundleItem.Id             = item.BundleItem.Id;
                model.BundleItem.DisplayOrder   = item.BundleItem.DisplayOrder;
                model.BundleItem.HideThumbnail  = item.BundleItem.HideThumbnail;
                model.BundlePerItemPricing      = item.BundleItem.BundleProduct.BundlePerItemPricing;
                model.BundlePerItemShoppingCart = item.BundleItem.BundleProduct.BundlePerItemShoppingCart;
                model.AttributeInfo             = await _productAttributeFormatter.FormatAttributesAsync(item.AttributeSelection, product, customer,
                                                                                                         includePrices : false, includeGiftCardAttributes : false, includeHyperlinks : false);

                var bundleItemName = item.BundleItem.GetLocalized(x => x.Name);
                if (bundleItemName.HasValue())
                {
                    model.ProductName = bundleItemName;
                }

                var bundleItemShortDescription = item.BundleItem.GetLocalized(x => x.ShortDescription);
                if (bundleItemShortDescription.HasValue())
                {
                    model.ShortDesc = bundleItemShortDescription;
                }

                if (model.BundlePerItemPricing && model.BundlePerItemShoppingCart)
                {
                    (var bundleItemPriceBase, var bundleItemTaxRate) = await _taxService.GetProductPriceAsync(product, await _priceCalculationService.GetSubTotalAsync(cartItem, true));

                    var bundleItemPrice = _currencyService.ConvertFromPrimaryCurrency(bundleItemPriceBase.Amount, currency);
                    model.BundleItem.PriceWithDiscount = bundleItemPrice.ToString();
                }
            }
            else
            {
                model.AttributeInfo = await _productAttributeFormatter.FormatAttributesAsync(item.AttributeSelection, product, customer);
            }

            var allowedQuantities = product.ParseAllowedQuantities();

            foreach (var qty in allowedQuantities)
            {
                model.AllowedQuantities.Add(new SelectListItem
                {
                    Text     = qty.ToString(),
                    Value    = qty.ToString(),
                    Selected = item.Quantity == qty
                });
            }

            var quantityUnit = await _db.QuantityUnits.FindByIdAsync(product.QuantityUnitId ?? 0);

            if (quantityUnit != null)
            {
                model.QuantityUnitName = quantityUnit.GetLocalized(x => x.Name);
            }

            if (product.IsRecurring)
            {
                model.RecurringInfo = string.Format(T("ShoppingCart.RecurringPeriod"),
                                                    product.RecurringCycleLength, product.RecurringCyclePeriod.GetLocalizedEnum());
            }

            if (product.CallForPrice)
            {
                model.UnitPrice = T("Products.CallForPrice");
            }
            else
            {
                var unitPriceWithDiscount = await _priceCalculationService.GetUnitPriceAsync(cartItem, true);

                var unitPriceBaseWithDiscount = await _taxService.GetProductPriceAsync(product, unitPriceWithDiscount);

                unitPriceWithDiscount = _currencyService.ConvertFromPrimaryCurrency(unitPriceBaseWithDiscount.Price.Amount, currency);

                model.UnitPrice = unitPriceWithDiscount.ToString();
            }

            // Subtotal and discount.
            if (product.CallForPrice)
            {
                model.SubTotal = T("Products.CallForPrice");
            }
            else
            {
                var cartItemSubTotalWithDiscount = await _priceCalculationService.GetSubTotalAsync(cartItem, true);

                var cartItemSubTotalWithDiscountBase = await _taxService.GetProductPriceAsync(product, cartItemSubTotalWithDiscount);

                cartItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryCurrency(cartItemSubTotalWithDiscountBase.Price.Amount, currency);

                model.SubTotal = cartItemSubTotalWithDiscount.ToString();

                // Display an applied discount amount.
                var cartItemSubTotalWithoutDiscount = await _priceCalculationService.GetSubTotalAsync(cartItem, false);

                var cartItemSubTotalWithoutDiscountBase = await _taxService.GetProductPriceAsync(product, cartItemSubTotalWithoutDiscount);

                var cartItemSubTotalDiscountBase = cartItemSubTotalWithoutDiscountBase.Price - cartItemSubTotalWithDiscountBase.Price;

                if (cartItemSubTotalDiscountBase > decimal.Zero)
                {
                    var shoppingCartItemDiscount = _currencyService.ConvertFromPrimaryCurrency(cartItemSubTotalDiscountBase.Amount, currency);
                    model.Discount = shoppingCartItemDiscount.ToString();
                }
            }

            if (item.BundleItem != null)
            {
                if (_shoppingCartSettings.ShowProductBundleImagesOnShoppingCart)
                {
                    model.Image = await PrepareCartItemPictureModelAsync(product, _mediaSettings.CartThumbBundleItemPictureSize, model.ProductName, item.AttributeSelection);
                }
            }
            else
            {
                if (_shoppingCartSettings.ShowProductImagesOnShoppingCart)
                {
                    model.Image = await PrepareCartItemPictureModelAsync(product, _mediaSettings.CartThumbPictureSize, model.ProductName, item.AttributeSelection);
                }
            }

            var itemWarnings = new List <string>();
            var itemIsValid  = await _shoppingCartValidator.ValidateCartAsync(new List <OrganizedShoppingCartItem> {
                cartItem
            }, itemWarnings);

            if (!itemIsValid)
            {
                model.Warnings.AddRange(itemWarnings);
            }

            if (cartItem.ChildItems != null)
            {
                foreach (var childItem in cartItem.ChildItems.Where(x => x.Item.Id != item.Id))
                {
                    var childModel = await PrepareWishlistCartItemModelAsync(childItem);

                    model.ChildItems.Add(childModel);
                }
            }

            return(model);
        }
        protected async Task <ShipmentDetailsModel> PrepareShipmentDetailsModelAsync(Shipment shipment)
        {
            Guard.NotNull(shipment, nameof(shipment));

            var order = shipment.Order;

            if (order == null)
            {
                throw new SmartException(T("Order.NotFound", shipment.OrderId));
            }

            var currentStore = Services.StoreContext.CurrentStore;
            var store        = currentStore.Id != order.StoreId
                ? (await _db.Stores.FindByIdAsync(order.StoreId, false) ?? currentStore)
                : currentStore;
            var settingFactory  = Services.SettingFactory;
            var catalogSettings = await settingFactory.LoadSettingsAsync <CatalogSettings>(store.Id);

            var shippingSettings = await settingFactory.LoadSettingsAsync <ShippingSettings>(store.Id);

            var model = new ShipmentDetailsModel
            {
                Id                = shipment.Id,
                TrackingNumber    = shipment.TrackingNumber,
                TrackingNumberUrl = shipment.TrackingUrl
            };

            if (shipment.ShippedDateUtc.HasValue)
            {
                model.ShippedDate = _dateTimeHelper.ConvertToUserTime(shipment.ShippedDateUtc.Value, DateTimeKind.Utc);
            }

            if (shipment.DeliveryDateUtc.HasValue)
            {
                model.DeliveryDate = _dateTimeHelper.ConvertToUserTime(shipment.DeliveryDateUtc.Value, DateTimeKind.Utc);
            }

            var srcm = _providerManager.GetProvider <IShippingRateComputationMethod>(order.ShippingRateComputationMethodSystemName, store.Id);

            if (srcm != null && srcm.IsShippingRateComputationMethodActive(shippingSettings))
            {
                var shipmentTracker = srcm.Value.ShipmentTracker;
                if (shipmentTracker != null)
                {
                    // The URL entered by the merchant takes precedence over an automatically generated URL.
                    if (model.TrackingNumberUrl.IsEmpty())
                    {
                        model.TrackingNumberUrl = shipmentTracker.GetUrl(shipment.TrackingNumber);
                    }

                    if (shippingSettings.DisplayShipmentEventsToCustomers)
                    {
                        var shipmentEvents = await shipmentTracker.GetShipmentEventsAsync(shipment.TrackingNumber);

                        if (shipmentEvents != null)
                        {
                            foreach (var shipmentEvent in shipmentEvents)
                            {
                                var shipmentEventCountry = await _db.Countries
                                                           .AsNoTracking()
                                                           .ApplyIsoCodeFilter(shipmentEvent.CountryCode)
                                                           .FirstOrDefaultAsync();

                                var shipmentStatusEventModel = new ShipmentDetailsModel.ShipmentStatusEventModel
                                {
                                    Country                                 = shipmentEventCountry != null?shipmentEventCountry.GetLocalized(x => x.Name) : shipmentEvent.CountryCode,
                                                                  Date      = shipmentEvent.Date,
                                                                  EventName = shipmentEvent.EventName,
                                                                  Location  = shipmentEvent.Location
                                };

                                model.ShipmentStatusEvents.Add(shipmentStatusEventModel);
                            }
                        }
                    }
                }
            }

            // Products in this shipment.
            model.ShowSku = catalogSettings.ShowProductSku;

            foreach (var shipmentItem in shipment.ShipmentItems)
            {
                var orderItem = await _db.OrderItems
                                .Include(x => x.Product)
                                .FindByIdAsync(shipmentItem.OrderItemId, false);

                if (orderItem == null)
                {
                    continue;
                }

                var attributeCombination = await _productAttributeMaterializer.FindAttributeCombinationAsync(orderItem.Product.Id, orderItem.AttributeSelection);

                orderItem.Product.MergeWithCombination(attributeCombination);

                var shipmentItemModel = new ShipmentDetailsModel.ShipmentItemModel
                {
                    Id              = shipmentItem.Id,
                    Sku             = orderItem.Product.Sku,
                    ProductId       = orderItem.Product.Id,
                    ProductName     = orderItem.Product.GetLocalized(x => x.Name),
                    ProductSeName   = await orderItem.Product.GetActiveSlugAsync(),
                    AttributeInfo   = orderItem.AttributeDescription,
                    QuantityOrdered = orderItem.Quantity,
                    QuantityShipped = shipmentItem.Quantity
                };

                shipmentItemModel.ProductUrl = await _productUrlHelper.GetProductUrlAsync(shipmentItemModel.ProductSeName, orderItem);

                model.Items.Add(shipmentItemModel);
            }

            model.Order = await _orderHelper.PrepareOrderDetailsModelAsync(order);

            return(model);
        }
Example #7
0
        public override async Task MapAsync(IEnumerable <OrganizedShoppingCartItem> from, MiniShoppingCartModel to, dynamic parameters = null)
        {
            Guard.NotNull(from, nameof(from));
            Guard.NotNull(to, nameof(to));

            var customer = _services.WorkContext.CurrentCustomer;

            to.ShowProductImages           = _shoppingCartSettings.ShowProductImagesInMiniShoppingCart;
            to.ThumbSize                   = _mediaSettings.MiniCartThumbPictureSize;
            to.CurrentCustomerIsGuest      = customer.IsGuest();
            to.AnonymousCheckoutAllowed    = _orderSettings.AnonymousCheckoutAllowed;
            to.DisplayMoveToWishlistButton = await _services.Permissions.AuthorizeAsync(Permissions.Cart.AccessWishlist);

            to.ShowBasePrice = _shoppingCartSettings.ShowBasePrice;
            to.TotalProducts = from.GetTotalQuantity();

            if (!from.Any())
            {
                return;
            }

            var taxFormat    = _currencyService.GetTaxFormat();
            var batchContext = _productService.CreateProductBatchContext(from.Select(x => x.Item.Product).ToArray(), null, customer, false);

            var subtotal = await _orderCalculationService.GetShoppingCartSubtotalAsync(from.ToList(), null, batchContext);

            var lineItems = subtotal.LineItems.ToDictionarySafe(x => x.Item.Item.Id);

            var currency = _services.WorkContext.WorkingCurrency;
            var subtotalWithoutDiscount = _currencyService.ConvertFromPrimaryCurrency(subtotal.SubtotalWithoutDiscount.Amount, currency);

            to.SubTotal = subtotalWithoutDiscount.WithPostFormat(taxFormat);

            // A customer should visit the shopping cart page before going to checkout if:
            //1. There is at least one checkout attribute that is reqired
            //2. Min order sub total is OK

            var checkoutAttributes = await _checkoutAttributeMaterializer.GetValidCheckoutAttributesAsync(from);

            to.DisplayCheckoutButton = !checkoutAttributes.Any(x => x.IsRequired);

            // Products sort descending (recently added products)
            foreach (var cartItem in from)
            {
                var item          = cartItem.Item;
                var product       = cartItem.Item.Product;
                var productSeName = await product.GetActiveSlugAsync();

                var cartItemModel = new MiniShoppingCartModel.ShoppingCartItemModel
                {
                    Id               = item.Id,
                    ProductId        = product.Id,
                    ProductName      = product.GetLocalized(x => x.Name),
                    ShortDesc        = product.GetLocalized(x => x.ShortDescription),
                    ProductSeName    = productSeName,
                    EnteredQuantity  = item.Quantity,
                    MaxOrderAmount   = product.OrderMaximumQuantity,
                    MinOrderAmount   = product.OrderMinimumQuantity,
                    QuantityStep     = product.QuantityStep > 0 ? product.QuantityStep : 1,
                    CreatedOnUtc     = item.UpdatedOnUtc,
                    ProductUrl       = await _productUrlHelper.GetProductUrlAsync(productSeName, cartItem),
                    QuantityUnitName = null,
                    AttributeInfo    = await _productAttributeFormatter.FormatAttributesAsync(
                        item.AttributeSelection,
                        product,
                        null,
                        ", ",
                        includePrices : false,
                        includeGiftCardAttributes : false,
                        includeHyperlinks : false,
                        batchContext : batchContext)
                };

                if (cartItem.ChildItems != null && _shoppingCartSettings.ShowProductBundleImagesOnShoppingCart)
                {
                    var bundleItems = cartItem.ChildItems.Where(x =>
                                                                x.Item.Id != item.Id &&
                                                                x.Item.BundleItem != null &&
                                                                !x.Item.BundleItem.HideThumbnail);

                    foreach (var bundleItem in bundleItems)
                    {
                        var bundleItemModel = new MiniShoppingCartModel.ShoppingCartItemBundleItem
                        {
                            ProductName   = bundleItem.Item.Product.GetLocalized(x => x.Name),
                            ProductSeName = await bundleItem.Item.Product.GetActiveSlugAsync(),
                        };

                        bundleItemModel.ProductUrl = await _productUrlHelper.GetProductUrlAsync(
                            bundleItem.Item.ProductId,
                            bundleItemModel.ProductSeName,
                            bundleItem.Item.AttributeSelection);

                        var file = await _db.ProductMediaFiles
                                   .AsNoTracking()
                                   .Include(x => x.MediaFile)
                                   .ApplyProductFilter(bundleItem.Item.ProductId)
                                   .FirstOrDefaultAsync();

                        if (file?.MediaFile != null)
                        {
                            var fileInfo = await _mediaService.GetFileByIdAsync(file.MediaFileId, MediaLoadFlags.AsNoTracking);

                            bundleItemModel.ImageModel = new ImageModel
                            {
                                File       = fileInfo,
                                ThumbSize  = MediaSettings.ThumbnailSizeXxs,
                                Title      = file.MediaFile.GetLocalized(x => x.Title)?.Value.NullEmpty() ?? T("Media.Manufacturer.ImageLinkTitleFormat", bundleItemModel.ProductName),
                                Alt        = file.MediaFile.GetLocalized(x => x.Alt)?.Value.NullEmpty() ?? T("Media.Manufacturer.ImageAlternateTextFormat", bundleItemModel.ProductName),
                                NoFallback = _catalogSettings.HideProductDefaultPictures,
                            };
                        }

                        cartItemModel.BundleItems.Add(bundleItemModel);
                    }
                }

                // Unit prices.
                if (product.CallForPrice)
                {
                    cartItemModel.UnitPrice = T("Products.CallForPrice");
                }
                else if (lineItems.TryGetValue(item.Id, out var lineItem))
                {
                    var unitPrice = _currencyService.ConvertFromPrimaryCurrency(lineItem.UnitPrice.FinalPrice.Amount, currency);
                    cartItemModel.UnitPrice = unitPrice.WithPostFormat(taxFormat).ToString(true);

                    if (unitPrice != 0 && to.ShowBasePrice)
                    {
                        cartItemModel.BasePriceInfo = _priceCalculationService.GetBasePriceInfo(item.Product, unitPrice, currency);
                    }
                }

                // Image.
                if (_shoppingCartSettings.ShowProductImagesInMiniShoppingCart)
                {
                    await cartItem.MapAsync(cartItemModel.Image, _mediaSettings.MiniCartThumbPictureSize, cartItemModel.ProductName);
                }

                to.Items.Add(cartItemModel);
            }
        }
Example #8
0
        public override async Task MapAsync(OrganizedShoppingCartItem from, TModel to, dynamic parameters = null)
        {
            Guard.NotNull(from, nameof(from));

            // TODO: (ms) (core) Be certain that product is null if it is removed from cart.
            if (from.Item.Product == null)
            {
                return;
            }

            var item             = from.Item;
            var product          = from.Item.Product;
            var customer         = item.Customer;
            var currency         = _services.WorkContext.WorkingCurrency;
            var shoppingCartType = item.ShoppingCartType;

            await _productAttributeMaterializer.MergeWithCombinationAsync(product, item.AttributeSelection);

            var productSeName = await product.GetActiveSlugAsync();

            // General model data
            to.Id            = item.Id;
            to.Sku           = product.Sku;
            to.ProductId     = product.Id;
            to.ProductName   = product.GetLocalized(x => x.Name);
            to.ProductSeName = productSeName;
            to.ProductUrl    = await _productUrlHelper.GetProductUrlAsync(productSeName, from);

            to.EnteredQuantity     = item.Quantity;
            to.MinOrderAmount      = product.OrderMinimumQuantity;
            to.MaxOrderAmount      = product.OrderMaximumQuantity;
            to.QuantityStep        = product.QuantityStep > 0 ? product.QuantityStep : 1;
            to.ShortDesc           = product.GetLocalized(x => x.ShortDescription);
            to.ProductType         = product.ProductType;
            to.VisibleIndividually = product.Visibility != ProductVisibility.Hidden;
            to.CreatedOnUtc        = item.UpdatedOnUtc;

            if (item.BundleItem != null)
            {
                to.BundleItem.Id             = item.BundleItem.Id;
                to.BundleItem.DisplayOrder   = item.BundleItem.DisplayOrder;
                to.BundleItem.HideThumbnail  = item.BundleItem.HideThumbnail;
                to.BundlePerItemPricing      = item.BundleItem.BundleProduct.BundlePerItemPricing;
                to.BundlePerItemShoppingCart = item.BundleItem.BundleProduct.BundlePerItemShoppingCart;
                to.AttributeInfo             = await _productAttributeFormatter.FormatAttributesAsync(
                    item.AttributeSelection,
                    product,
                    customer,
                    includePrices : false,
                    includeGiftCardAttributes : true,
                    includeHyperlinks : true);

                var bundleItemName = item.BundleItem.GetLocalized(x => x.Name);
                if (bundleItemName.Value.HasValue())
                {
                    to.ProductName = bundleItemName;
                }

                var bundleItemShortDescription = item.BundleItem.GetLocalized(x => x.ShortDescription);
                if (bundleItemShortDescription.Value.HasValue())
                {
                    to.ShortDesc = bundleItemShortDescription;
                }

                if (to.BundlePerItemPricing && to.BundlePerItemShoppingCart)
                {
                    var bundleItemSubTotalWithDiscountBase = await _taxService.GetProductPriceAsync(product, await _priceCalculationService.GetSubTotalAsync(from, true));

                    var bundleItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryCurrency(bundleItemSubTotalWithDiscountBase.Price.Amount, currency);
                    to.BundleItem.PriceWithDiscount = bundleItemSubTotalWithDiscount.ToString();
                }
            }
            else
            {
                to.AttributeInfo = await _productAttributeFormatter.FormatAttributesAsync(item.AttributeSelection, product, customer);
            }

            var allowedQuantities = product.ParseAllowedQuantities();

            foreach (var quantity in allowedQuantities)
            {
                to.AllowedQuantities.Add(new SelectListItem
                {
                    Text     = quantity.ToString(),
                    Value    = quantity.ToString(),
                    Selected = item.Quantity == quantity
                });
            }

            var quantityUnit = await _db.QuantityUnits.GetQuantityUnitByIdAsync(product.QuantityUnitId ?? 0, _catalogSettings.ShowDefaultQuantityUnit);

            if (quantityUnit != null)
            {
                to.QuantityUnitName = quantityUnit.GetLocalized(x => x.Name);
            }

            if (product.IsRecurring)
            {
                to.RecurringInfo = T("ShoppingCart.RecurringPeriod", product.RecurringCycleLength, product.RecurringCyclePeriod.GetLocalizedEnum());
            }

            if (product.CallForPrice)
            {
                to.UnitPrice = T("Products.CallForPrice");
            }
            else
            {
                var unitPriceWithDiscountBase = await _taxService.GetProductPriceAsync(product, await _priceCalculationService.GetUnitPriceAsync(from, true));

                var unitPriceWithDiscount = _currencyService.ConvertFromPrimaryCurrency(unitPriceWithDiscountBase.Price.Amount, currency);
                to.UnitPrice = unitPriceWithDiscount.ToString();
            }

            // Subtotal and discount.
            if (product.CallForPrice)
            {
                to.SubTotal = T("Products.CallForPrice");
            }
            else
            {
                var cartItemSubTotalWithDiscount = await _priceCalculationService.GetSubTotalAsync(from, true);

                var cartItemSubTotalWithDiscountBase = await _taxService.GetProductPriceAsync(product, cartItemSubTotalWithDiscount);

                cartItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryCurrency(cartItemSubTotalWithDiscountBase.Price.Amount, currency);

                to.SubTotal = cartItemSubTotalWithDiscount.ToString();

                // Display an applied discount amount.
                var cartItemSubTotalWithoutDiscount = await _priceCalculationService.GetSubTotalAsync(from, false);

                var cartItemSubTotalWithoutDiscountBase = await _taxService.GetProductPriceAsync(product, cartItemSubTotalWithoutDiscount);

                var cartItemSubTotalDiscountBase = cartItemSubTotalWithoutDiscountBase.Price - cartItemSubTotalWithDiscountBase.Price;

                if (cartItemSubTotalDiscountBase > decimal.Zero)
                {
                    var itemDiscount = _currencyService.ConvertFromPrimaryCurrency(cartItemSubTotalDiscountBase.Amount, currency);
                    to.Discount = itemDiscount.ToString();
                }
            }

            if (item.BundleItem != null)
            {
                if (_shoppingCartSettings.ShowProductBundleImagesOnShoppingCart)
                {
                    await from.MapAsync(to.Image, _mediaSettings.CartThumbBundleItemPictureSize, to.ProductName);
                }
            }
            else
            {
                if (_shoppingCartSettings.ShowProductImagesOnShoppingCart)
                {
                    await from.MapAsync(to.Image, _mediaSettings.CartThumbPictureSize, to.ProductName);
                }
            }

            var itemWarnings = new List <string>();
            var isItemValid  = await _shoppingCartValidator.ValidateCartItemsAsync(new[] { from }, itemWarnings);

            if (!isItemValid)
            {
                itemWarnings.Each(x => to.Warnings.Add(x));
            }
        }