Example #1
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);
            }
        }
        public async Task <MiniShoppingCartModel> Handle(GetMiniShoppingCart request, CancellationToken cancellationToken)
        {
            var model = new MiniShoppingCartModel {
                ShowProductImages         = _shoppingCartSettings.ShowProductImagesInMiniShoppingCart,
                DisplayShoppingCartButton = true,
                CurrentCustomerIsGuest    = request.Customer.IsGuest(),
                AnonymousCheckoutAllowed  = _orderSettings.AnonymousCheckoutAllowed,
            };

            if (request.Customer.ShoppingCartItems.Any())
            {
                var shoppingCartTypes = new List <ShoppingCartType>();
                shoppingCartTypes.Add(ShoppingCartType.ShoppingCart);
                shoppingCartTypes.Add(ShoppingCartType.Auctions);
                if (_shoppingCartSettings.AllowOnHoldCart)
                {
                    shoppingCartTypes.Add(ShoppingCartType.OnHoldCart);
                }

                var cart = _shoppingCartService.GetShoppingCart(request.Store.Id, shoppingCartTypes.ToArray());
                model.TotalProducts = cart.Sum(x => x.Quantity);
                if (cart.Any())
                {
                    //subtotal
                    var subTotalIncludingTax = request.TaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal;
                    var shoppingCartSubTotal = await _orderTotalCalculationService.GetShoppingCartSubTotal(cart, subTotalIncludingTax);

                    decimal orderSubTotalDiscountAmountBase = shoppingCartSubTotal.discountAmount;
                    List <AppliedDiscount> orderSubTotalAppliedDiscounts = shoppingCartSubTotal.appliedDiscounts;

                    model.SubTotal = _priceFormatter.FormatPrice(shoppingCartSubTotal.subTotalWithoutDiscount, false, request.Currency, request.Language, subTotalIncludingTax);

                    var requiresShipping        = cart.RequiresShipping();
                    var checkoutAttributesExist = (await _checkoutAttributeService.GetAllCheckoutAttributes(request.Store.Id, !requiresShipping)).Any();

                    var minOrderSubtotalAmountOk = await _mediator.Send(new ValidateMinShoppingCartSubtotalAmountCommand()
                    {
                        Customer = request.Customer,
                        Cart     = cart.Where
                                       (x => x.ShoppingCartType == ShoppingCartType.ShoppingCart || x.ShoppingCartType == ShoppingCartType.Auctions).ToList()
                    });

                    model.DisplayCheckoutButton = !_orderSettings.TermsOfServiceOnShoppingCartPage &&
                                                  minOrderSubtotalAmountOk &&
                                                  !checkoutAttributesExist;

                    //products. sort descending (recently added products)
                    foreach (var sci in cart
                             .OrderByDescending(x => x.Id)
                             .Take(_shoppingCartSettings.MiniShoppingCartProductNumber)
                             .ToList())
                    {
                        var product = await _productService.GetProductById(sci.ProductId);

                        if (product == null)
                        {
                            continue;
                        }

                        var cartItemModel = new MiniShoppingCartModel.ShoppingCartItemModel {
                            Id            = sci.Id,
                            ProductId     = product.Id,
                            ProductName   = product.GetLocalized(x => x.Name, request.Language.Id),
                            ProductSeName = product.GetSeName(request.Language.Id),
                            Quantity      = sci.Quantity,
                            AttributeInfo = await _productAttributeFormatter.FormatAttributes(product, sci.AttributesXml)
                        };
                        if (product.ProductType == ProductType.Reservation)
                        {
                            var reservation = "";
                            if (sci.RentalEndDateUtc == default(DateTime) || sci.RentalEndDateUtc == null)
                            {
                                reservation = string.Format(_localizationService.GetResource("ShoppingCart.Reservation.StartDate"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat));
                            }
                            else
                            {
                                reservation = string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Date"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat), sci.RentalEndDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat));
                            }

                            if (!string.IsNullOrEmpty(sci.Parameter))
                            {
                                reservation += "<br>" + string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Option"), sci.Parameter);
                            }
                            if (!string.IsNullOrEmpty(sci.Duration))
                            {
                                reservation += "<br>" + string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Duration"), sci.Duration);
                            }
                            if (string.IsNullOrEmpty(cartItemModel.AttributeInfo))
                            {
                                cartItemModel.AttributeInfo = reservation;
                            }
                            else
                            {
                                cartItemModel.AttributeInfo += "<br>" + reservation;
                            }
                        }
                        //unit prices
                        if (product.CallForPrice)
                        {
                            cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice");
                        }
                        else
                        {
                            var productprices = await _taxService.GetProductPrice(product, (await _priceCalculationService.GetUnitPrice(sci, product)).unitprice);

                            decimal taxRate = productprices.taxRate;
                            cartItemModel.UnitPrice = _priceFormatter.FormatPrice(productprices.productprice);
                        }

                        //picture
                        if (_shoppingCartSettings.ShowProductImagesInMiniShoppingCart)
                        {
                            cartItemModel.Picture = await PrepareCartItemPicture(request, product, sci.AttributesXml);
                        }

                        model.Items.Add(cartItemModel);
                    }
                }
            }

            return(model);
        }
        public async Task <MiniShoppingCartModel> Handle(GetMiniShoppingCart request, CancellationToken cancellationToken)
        {
            var model = new MiniShoppingCartModel {
                ShowProductImages         = _shoppingCartSettings.ShowProductImagesInMiniShoppingCart,
                DisplayShoppingCartButton = true,
                CurrentCustomerIsGuest    = request.Customer.IsGuest(),
                AnonymousCheckoutAllowed  = _orderSettings.AnonymousCheckoutAllowed,
            };

            if (request.Customer.ShoppingCartItems.Any())
            {
                var shoppingCartTypes = new List <ShoppingCartType>();
                shoppingCartTypes.Add(ShoppingCartType.ShoppingCart);
                shoppingCartTypes.Add(ShoppingCartType.Auctions);
                if (_shoppingCartSettings.AllowOnHoldCart)
                {
                    shoppingCartTypes.Add(ShoppingCartType.OnHoldCart);
                }

                var cart = _shoppingCartService.GetShoppingCart(request.Store.Id, shoppingCartTypes.ToArray());
                model.TotalProducts = cart.Sum(x => x.Quantity);
                if (cart.Any())
                {
                    //subtotal
                    var subTotalIncludingTax = request.TaxDisplayType == TaxDisplayType.IncludingTax && !_taxSettings.ForceTaxExclusionFromOrderSubtotal;
                    var shoppingCartSubTotal = await _orderTotalCalculationService.GetShoppingCartSubTotal(cart, subTotalIncludingTax);

                    decimal orderSubTotalDiscountAmountBase = shoppingCartSubTotal.discountAmount;
                    List <AppliedDiscount> orderSubTotalAppliedDiscounts = shoppingCartSubTotal.appliedDiscounts;
                    decimal subTotalWithoutDiscountBase = shoppingCartSubTotal.subTotalWithoutDiscount;
                    decimal subTotalWithDiscountBase    = shoppingCartSubTotal.subTotalWithDiscount;
                    decimal subtotalBase = subTotalWithoutDiscountBase;
                    decimal subtotal     = await _currencyService.ConvertFromPrimaryStoreCurrency(subtotalBase, request.Currency);

                    model.SubTotal = _priceFormatter.FormatPrice(subtotal, false, request.Currency, request.Language, subTotalIncludingTax);

                    var requiresShipping = cart.RequiresShipping();
                    //a customer should visit the shopping cart page (hide checkout button) before going to checkout if:
                    //1. "terms of service" are enabled
                    //2. min order sub-total is OK
                    //3. we have at least one checkout attribute
                    var checkoutAttributesExistCacheKey = string.Format(ModelCacheEventConst.CHECKOUTATTRIBUTES_EXIST_KEY,
                                                                        request.Store.Id, requiresShipping);
                    var checkoutAttributesExist = await _cacheManager.GetAsync(checkoutAttributesExistCacheKey, async() =>
                    {
                        var checkoutAttributes = await _checkoutAttributeService.GetAllCheckoutAttributes(request.Store.Id, !requiresShipping);
                        return(checkoutAttributes.Any());
                    });

                    bool minOrderSubtotalAmountOk = await _orderProcessingService.ValidateMinOrderSubtotalAmount(cart.Where
                                                                                                                 (x => x.ShoppingCartType == ShoppingCartType.ShoppingCart || x.ShoppingCartType == ShoppingCartType.Auctions).ToList());

                    model.DisplayCheckoutButton = !_orderSettings.TermsOfServiceOnShoppingCartPage &&
                                                  minOrderSubtotalAmountOk &&
                                                  !checkoutAttributesExist;

                    //products. sort descending (recently added products)
                    foreach (var sci in cart
                             .OrderByDescending(x => x.Id)
                             .Take(_shoppingCartSettings.MiniShoppingCartProductNumber)
                             .ToList())
                    {
                        var product = await _productService.GetProductById(sci.ProductId);

                        if (product == null)
                        {
                            continue;
                        }

                        var cartItemModel = new MiniShoppingCartModel.ShoppingCartItemModel {
                            Id            = sci.Id,
                            ProductId     = product.Id,
                            ProductName   = product.GetLocalized(x => x.Name, request.Language.Id),
                            ProductSeName = product.GetSeName(request.Language.Id),
                            Quantity      = sci.Quantity,
                            AttributeInfo = await _productAttributeFormatter.FormatAttributes(product, sci.AttributesXml)
                        };
                        if (product.ProductType == ProductType.Reservation)
                        {
                            var reservation = "";
                            if (sci.RentalEndDateUtc == default(DateTime) || sci.RentalEndDateUtc == null)
                            {
                                reservation = string.Format(_localizationService.GetResource("ShoppingCart.Reservation.StartDate"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat));
                            }
                            else
                            {
                                reservation = string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Date"), sci.RentalStartDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat), sci.RentalEndDateUtc?.ToString(_shoppingCartSettings.ReservationDateFormat));
                            }

                            if (!string.IsNullOrEmpty(sci.Parameter))
                            {
                                reservation += "<br>" + string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Option"), sci.Parameter);
                            }
                            if (!string.IsNullOrEmpty(sci.Duration))
                            {
                                reservation += "<br>" + string.Format(_localizationService.GetResource("ShoppingCart.Reservation.Duration"), sci.Duration);
                            }
                            if (string.IsNullOrEmpty(cartItemModel.AttributeInfo))
                            {
                                cartItemModel.AttributeInfo = reservation;
                            }
                            else
                            {
                                cartItemModel.AttributeInfo += "<br>" + reservation;
                            }
                        }
                        //unit prices
                        if (product.CallForPrice)
                        {
                            cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice");
                        }
                        else
                        {
                            var productprices = await _taxService.GetProductPrice(product, (await _priceCalculationService.GetUnitPrice(sci)).unitprice);

                            decimal taxRate = productprices.taxRate;
                            decimal shoppingCartUnitPriceWithDiscountBase = productprices.productprice;
                            decimal shoppingCartUnitPriceWithDiscount     = await _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, request.Currency);

                            cartItemModel.UnitPrice = _priceFormatter.FormatPrice(shoppingCartUnitPriceWithDiscount);
                        }

                        //picture
                        if (_shoppingCartSettings.ShowProductImagesInMiniShoppingCart)
                        {
                            cartItemModel.Picture = await PrepareCartItemPicture(request, product, sci.AttributesXml);
                        }

                        model.Items.Add(cartItemModel);
                    }
                }
            }

            return(model);
        }