Guest User

ShoppingCartController.cs

a guest
Jan 16th, 2014
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 129.42 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Web;
  7. using System.Web.Mvc;
  8. using System.Web.Routing;
  9. using Nop.Core;
  10. using Nop.Core.Caching;
  11. using Nop.Core.Domain.Catalog;
  12. using Nop.Core.Domain.Common;
  13. using Nop.Core.Domain.Customers;
  14. using Nop.Core.Domain.Directory;
  15. using Nop.Core.Domain.Discounts;
  16. using Nop.Core.Domain.Media;
  17. using Nop.Core.Domain.Orders;
  18. using Nop.Core.Domain.Shipping;
  19. using Nop.Core.Domain.Tax;
  20. using Nop.Services.Catalog;
  21. using Nop.Services.Common;
  22. using Nop.Services.Customers;
  23. using Nop.Services.Directory;
  24. using Nop.Services.Discounts;
  25. using Nop.Services.Localization;
  26. using Nop.Services.Media;
  27. using Nop.Services.Messages;
  28. using Nop.Services.Orders;
  29. using Nop.Services.Payments;
  30. using Nop.Services.Security;
  31. using Nop.Services.Seo;
  32. using Nop.Services.Shipping;
  33. using Nop.Services.Tax;
  34. using Nop.Web.Extensions;
  35. using Nop.Web.Framework.Controllers;
  36. using Nop.Web.Framework.Security;
  37. using Nop.Web.Framework.UI.Captcha;
  38. using Nop.Web.Infrastructure.Cache;
  39. using Nop.Web.Models.Media;
  40. using Nop.Web.Models.ShoppingCart;
  41. using Nop.Services.Logging;
  42. using System.Configuration;
  43.  
  44. namespace Nop.Web.Controllers
  45. {
  46.     public partial class ShoppingCartController : BaseNopController
  47.     {
  48.         #region Fields
  49.  
  50.         private readonly IProductService _productService;
  51.         private readonly IWorkContext _workContext;
  52.         private readonly IStoreContext _storeContext;
  53.         private readonly IShoppingCartService _shoppingCartService;
  54.         private readonly IPictureService _pictureService;
  55.         private readonly ILocalizationService _localizationService;
  56.         private readonly IProductAttributeService _productAttributeService;
  57.         private readonly IProductAttributeFormatter _productAttributeFormatter;
  58.         private readonly IProductAttributeParser _productAttributeParser;
  59.         private readonly ITaxService _taxService;
  60.         private readonly ICurrencyService _currencyService;
  61.         private readonly IPriceCalculationService _priceCalculationService;
  62.         private readonly IPriceFormatter _priceFormatter;
  63.         private readonly ICheckoutAttributeParser _checkoutAttributeParser;
  64.         private readonly ICheckoutAttributeFormatter _checkoutAttributeFormatter;
  65.         private readonly IOrderProcessingService _orderProcessingService;
  66.         private readonly IDiscountService _discountService;
  67.         private readonly ICustomerService _customerService;
  68.         private readonly IGiftCardService _giftCardService;
  69.         private readonly ICountryService _countryService;
  70.         private readonly IStateProvinceService _stateProvinceService;
  71.         private readonly IShippingService _shippingService;
  72.         private readonly IOrderTotalCalculationService _orderTotalCalculationService;
  73.         private readonly ICheckoutAttributeService _checkoutAttributeService;
  74.         private readonly IPaymentService _paymentService;
  75.         private readonly IWorkflowMessageService _workflowMessageService;
  76.         private readonly IPermissionService _permissionService;
  77.         private readonly IDownloadService _downloadService;
  78.         private readonly ICacheManager _cacheManager;
  79.         private readonly IWebHelper _webHelper;
  80.         private readonly ICustomerActivityService _customerActivityService;
  81.         private readonly IGenericAttributeService _genericAttributeService;
  82.  
  83.         private readonly MediaSettings _mediaSettings;
  84.         private readonly ShoppingCartSettings _shoppingCartSettings;
  85.         private readonly CatalogSettings _catalogSettings;
  86.         private readonly OrderSettings _orderSettings;
  87.         private readonly ShippingSettings _shippingSettings;
  88.         private readonly TaxSettings _taxSettings;
  89.         private readonly CaptchaSettings _captchaSettings;
  90.         private readonly AddressSettings _addressSettings;
  91.  
  92.         private ILogger _logger;
  93.  
  94.         #endregion
  95.  
  96.         #region Constructors
  97.  
  98.         public ShoppingCartController(IProductService productService,
  99.             IStoreContext storeContext,
  100.             IWorkContext workContext,
  101.             IShoppingCartService shoppingCartService,
  102.             IPictureService pictureService,
  103.             ILocalizationService localizationService,
  104.             IProductAttributeService productAttributeService,
  105.             IProductAttributeFormatter productAttributeFormatter,
  106.             IProductAttributeParser productAttributeParser,
  107.             ITaxService taxService, ICurrencyService currencyService,
  108.             IPriceCalculationService priceCalculationService,
  109.             IPriceFormatter priceFormatter,
  110.             ICheckoutAttributeParser checkoutAttributeParser,
  111.             ICheckoutAttributeFormatter checkoutAttributeFormatter,
  112.             IOrderProcessingService orderProcessingService,
  113.             IDiscountService discountService,
  114.             ICustomerService customerService,
  115.             IGiftCardService giftCardService,
  116.             ICountryService countryService,
  117.             IStateProvinceService stateProvinceService,
  118.             IShippingService shippingService,
  119.             IOrderTotalCalculationService orderTotalCalculationService,
  120.             ICheckoutAttributeService checkoutAttributeService,
  121.             IPaymentService paymentService,
  122.             IWorkflowMessageService workflowMessageService,
  123.             IPermissionService permissionService,
  124.             IDownloadService downloadService,
  125.             ICacheManager cacheManager,
  126.             IWebHelper webHelper,
  127.             ICustomerActivityService customerActivityService,
  128.             IGenericAttributeService genericAttributeService,
  129.             MediaSettings mediaSettings,
  130.             ShoppingCartSettings shoppingCartSettings,
  131.             CatalogSettings catalogSettings,
  132.             OrderSettings orderSettings,
  133.             ShippingSettings shippingSettings,
  134.             TaxSettings taxSettings,
  135.             CaptchaSettings captchaSettings,
  136.             AddressSettings addressSettings,
  137.             ILogger logger)
  138.         {
  139.             this._productService = productService;
  140.             this._workContext = workContext;
  141.             this._storeContext = storeContext;
  142.             this._shoppingCartService = shoppingCartService;
  143.             this._pictureService = pictureService;
  144.             this._localizationService = localizationService;
  145.             this._productAttributeService = productAttributeService;
  146.             this._productAttributeFormatter = productAttributeFormatter;
  147.             this._productAttributeParser = productAttributeParser;
  148.             this._taxService = taxService;
  149.             this._currencyService = currencyService;
  150.             this._priceCalculationService = priceCalculationService;
  151.             this._priceFormatter = priceFormatter;
  152.             this._checkoutAttributeParser = checkoutAttributeParser;
  153.             this._checkoutAttributeFormatter = checkoutAttributeFormatter;
  154.             this._orderProcessingService = orderProcessingService;
  155.             this._discountService = discountService;
  156.             this._customerService = customerService;
  157.             this._giftCardService = giftCardService;
  158.             this._countryService = countryService;
  159.             this._stateProvinceService = stateProvinceService;
  160.             this._shippingService = shippingService;
  161.             this._orderTotalCalculationService = orderTotalCalculationService;
  162.             this._checkoutAttributeService = checkoutAttributeService;
  163.             this._paymentService = paymentService;
  164.             this._workflowMessageService = workflowMessageService;
  165.             this._permissionService = permissionService;
  166.             this._downloadService = downloadService;
  167.             this._cacheManager = cacheManager;
  168.             this._webHelper = webHelper;
  169.             this._customerActivityService = customerActivityService;
  170.             this._genericAttributeService = genericAttributeService;
  171.            
  172.             this._mediaSettings = mediaSettings;
  173.             this._shoppingCartSettings = shoppingCartSettings;
  174.             this._catalogSettings = catalogSettings;
  175.             this._orderSettings = orderSettings;
  176.             this._shippingSettings = shippingSettings;
  177.             this._taxSettings = taxSettings;
  178.             this._captchaSettings = captchaSettings;
  179.             this._addressSettings = addressSettings;
  180.  
  181.             this._logger = logger;
  182.  
  183.         }
  184.  
  185.         #endregion
  186.  
  187.         #region Utilities
  188.  
  189.         [NonAction]
  190.         protected PictureModel PrepareCartItemPictureModel(ProductVariant productVariant,
  191.             int pictureSize, bool showDefaultPicture, string productName)
  192.         {
  193.             if (productVariant == null)
  194.                 throw new ArgumentNullException("productVariant");
  195.  
  196.             var pictureCacheKey = string.Format(ModelCacheEventConsumer.CART_PICTURE_MODEL_KEY, productVariant.Id, pictureSize, true, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured());
  197.             var model = _cacheManager.Get(pictureCacheKey, () =>
  198.             {
  199.                 //first try to load product variant piture
  200.                 var picture = _pictureService.GetPictureById(productVariant.PictureId);
  201.                 if (picture == null)
  202.                 {
  203.                     //if product variant doesn't have any picture assigned, then load product picture
  204.                     picture = _pictureService.GetPicturesByProductId(productVariant.Product.Id, 1).FirstOrDefault();
  205.                 }
  206.                 return new PictureModel()
  207.                 {
  208.                     ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize, showDefaultPicture),
  209.                     Title = string.Format(_localizationService.GetResource("Media.Product.ImageLinkTitleFormat"), productName),
  210.                     AlternateText = string.Format(_localizationService.GetResource("Media.Product.ImageAlternateTextFormat"), productName),
  211.                 };
  212.             });
  213.             return model;
  214.         }
  215.  
  216.         /// <summary>
  217.         /// Prepare shopping cart model
  218.         /// </summary>
  219.         /// <param name="model">Model instance</param>
  220.         /// <param name="cart">Shopping cart</param>
  221.         /// <param name="isEditable">A value indicating whether cart is editable</param>
  222.         /// <param name="validateCheckoutAttributes">A value indicating whether we should validate checkout attributes when preparing the model</param>
  223.         /// <param name="prepareEstimateShippingIfEnabled">A value indicating whether we should prepare "Estimate shipping" model</param>
  224.         /// <param name="setEstimateShippingDefaultAddress">A value indicating whether we should prefill "Estimate shipping" model with the default customer address</param>
  225.         /// <param name="prepareAndDisplayOrderReviewData">A value indicating whether we should prepare review data (such as billing/shipping address, payment or shipping data entered during checkout)</param>
  226.         /// <returns>Model</returns>
  227.         [NonAction]
  228.         protected void PrepareShoppingCartModel(ShoppingCartModel model,
  229.             IList<ShoppingCartItem> cart, bool isEditable = true,
  230.             bool validateCheckoutAttributes = false,
  231.             bool prepareEstimateShippingIfEnabled = true, bool setEstimateShippingDefaultAddress = true,
  232.             bool prepareAndDisplayOrderReviewData = false)
  233.         {
  234.             if (cart == null)
  235.                 throw new ArgumentNullException("cart");
  236.  
  237.             if (model == null)
  238.                 throw new ArgumentNullException("model");
  239.  
  240.             if (cart.Count == 0)
  241.                 return;
  242.            
  243.             #region Simple properties
  244.  
  245.             model.IsEditable = isEditable;
  246.             model.ShowProductImages = _shoppingCartSettings.ShowProductImagesOnShoppingCart;
  247.             model.ShowSku = _catalogSettings.ShowProductSku;
  248.             var checkoutAttributesXml = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService);
  249.             model.CheckoutAttributeInfo = _checkoutAttributeFormatter.FormatAttributes(checkoutAttributesXml, _workContext.CurrentCustomer);
  250.             bool minOrderSubtotalAmountOk = _orderProcessingService.ValidateMinOrderSubtotalAmount(cart);
  251.             if (!minOrderSubtotalAmountOk)
  252.             {
  253.                 decimal minOrderSubtotalAmount = _currencyService.ConvertFromPrimaryStoreCurrency(_orderSettings.MinOrderSubtotalAmount, _workContext.WorkingCurrency);
  254.                 model.MinOrderSubtotalWarning = string.Format(_localizationService.GetResource("Checkout.MinOrderSubtotalAmount"), _priceFormatter.FormatPrice(minOrderSubtotalAmount, true, false));
  255.             }
  256.             model.TermsOfServiceEnabled = _orderSettings.TermsOfServiceEnabled;
  257.  
  258.             //gift card and gift card boxes
  259.             model.DiscountBox.Display= _shoppingCartSettings.ShowDiscountBox;
  260.             var discountCouponCode = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode);
  261.             var discount = _discountService.GetDiscountByCouponCode(discountCouponCode);
  262.             if (discount != null &&
  263.                 discount.RequiresCouponCode &&
  264.                 _discountService.IsDiscountValid(discount, _workContext.CurrentCustomer))
  265.                 model.DiscountBox.CurrentCode = discount.CouponCode;
  266.             model.GiftCardBox.Display = _shoppingCartSettings.ShowGiftCardBox;
  267.  
  268.             //cart warnings
  269.             var cartWarnings = _shoppingCartService.GetShoppingCartWarnings(cart, checkoutAttributesXml, validateCheckoutAttributes);
  270.             foreach (var warning in cartWarnings)
  271.                 model.Warnings.Add(warning);
  272.            
  273.             #endregion
  274.  
  275.             #region Checkout attributes
  276.  
  277.             var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes();
  278.             if (!cart.RequiresShipping())
  279.             {
  280.                 //remove attributes which require shippable products
  281.                 checkoutAttributes = checkoutAttributes.RemoveShippableAttributes();
  282.             }
  283.             foreach (var attribute in checkoutAttributes)
  284.             {
  285.                 var caModel = new ShoppingCartModel.CheckoutAttributeModel()
  286.                 {
  287.                     Id = attribute.Id,
  288.                     Name = attribute.GetLocalized(x => x.Name),
  289.                     TextPrompt = attribute.GetLocalized(x => x.TextPrompt),
  290.                     IsRequired = attribute.IsRequired,
  291.                     AttributeControlType = attribute.AttributeControlType
  292.                 };
  293.  
  294.                 if (attribute.ShouldHaveValues())
  295.                 {
  296.                     //values
  297.                     var caValues = _checkoutAttributeService.GetCheckoutAttributeValues(attribute.Id);
  298.                     foreach (var caValue in caValues)
  299.                     {
  300.                         var pvaValueModel = new ShoppingCartModel.CheckoutAttributeValueModel()
  301.                         {
  302.                             Id = caValue.Id,
  303.                             Name = caValue.GetLocalized(x => x.Name),
  304.                             ColorSquaresRgb = caValue.ColorSquaresRgb,
  305.                             IsPreSelected = caValue.IsPreSelected
  306.                         };
  307.                         caModel.Values.Add(pvaValueModel);
  308.  
  309.                         //display price if allowed
  310.                         if (_permissionService.Authorize(StandardPermissionProvider.DisplayPrices))
  311.                         {
  312.                             decimal priceAdjustmentBase = _taxService.GetCheckoutAttributePrice(caValue);
  313.                             decimal priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency);
  314.                             if (priceAdjustmentBase > decimal.Zero)
  315.                                 pvaValueModel.PriceAdjustment = "+" + _priceFormatter.FormatPrice(priceAdjustment);
  316.                             else if (priceAdjustmentBase < decimal.Zero)
  317.                                 pvaValueModel.PriceAdjustment = "-" + _priceFormatter.FormatPrice(-priceAdjustment);
  318.                         }
  319.                     }
  320.                 }
  321.  
  322.  
  323.  
  324.                 //set already selected attributes
  325.                 string selectedCheckoutAttributes = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService);
  326.                 switch (attribute.AttributeControlType)
  327.                 {
  328.                     case AttributeControlType.DropdownList:
  329.                     case AttributeControlType.RadioList:
  330.                     case AttributeControlType.Checkboxes:
  331.                     case AttributeControlType.ColorSquares:
  332.                         {
  333.                             if (!String.IsNullOrEmpty(selectedCheckoutAttributes))
  334.                             {
  335.                                 //clear default selection
  336.                                 foreach (var item in caModel.Values)
  337.                                     item.IsPreSelected = false;
  338.  
  339.                                 //select new values
  340.                                 var selectedCaValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(selectedCheckoutAttributes);
  341.                                 foreach (var caValue in selectedCaValues)
  342.                                     foreach (var item in caModel.Values)
  343.                                         if (caValue.Id == item.Id)
  344.                                             item.IsPreSelected = true;
  345.                             }
  346.                         }
  347.                         break;
  348.                     case AttributeControlType.TextBox:
  349.                     case AttributeControlType.MultilineTextbox:
  350.                         {
  351.                             if (!String.IsNullOrEmpty(selectedCheckoutAttributes))
  352.                             {
  353.                                 var enteredText = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, attribute.Id);
  354.                                 if (enteredText.Count > 0)
  355.                                     caModel.DefaultValue = enteredText[0];
  356.                             }
  357.                         }
  358.                         break;
  359.                     case AttributeControlType.Datepicker:
  360.                         {
  361.                             //keep in mind my that the code below works only in the current culture
  362.                             var selectedDateStr = _checkoutAttributeParser.ParseValues(selectedCheckoutAttributes, attribute.Id);
  363.                             if (selectedDateStr.Count > 0)
  364.                             {
  365.                                 DateTime selectedDate;
  366.                                 if (DateTime.TryParseExact(selectedDateStr[0], "D", CultureInfo.CurrentCulture,
  367.                                                        DateTimeStyles.None, out selectedDate))
  368.                                 {
  369.                                     //successfully parsed
  370.                                     caModel.SelectedDay = selectedDate.Day;
  371.                                     caModel.SelectedMonth = selectedDate.Month;
  372.                                     caModel.SelectedYear = selectedDate.Year;
  373.                                 }
  374.                             }
  375.                            
  376.                         }
  377.                         break;
  378.                     default:
  379.                         break;
  380.                 }
  381.  
  382.                 model.CheckoutAttributes.Add(caModel);
  383.             }
  384.  
  385.             #endregion
  386.  
  387.             #region Estimate shipping
  388.  
  389.             if (prepareEstimateShippingIfEnabled)
  390.             {
  391.                 model.EstimateShipping.Enabled = cart.Count > 0 && cart.RequiresShipping() && _shippingSettings.EstimateShippingEnabled;
  392.                 if (model.EstimateShipping.Enabled)
  393.                 {
  394.                     //countries
  395.                     int? defaultEstimateCountryId = (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null) ? _workContext.CurrentCustomer.ShippingAddress.CountryId : model.EstimateShipping.CountryId;
  396.                     model.EstimateShipping.AvailableCountries.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.SelectCountry"), Value = "0" });
  397.                     foreach (var c in _countryService.GetAllCountriesForShipping())
  398.                         model.EstimateShipping.AvailableCountries.Add(new SelectListItem()
  399.                         {
  400.                             Text = c.GetLocalized(x => x.Name),
  401.                             Value = c.Id.ToString(),
  402.                             Selected = c.Id == defaultEstimateCountryId
  403.                         });
  404.                     //states
  405.                     int? defaultEstimateStateId = (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null) ? _workContext.CurrentCustomer.ShippingAddress.StateProvinceId : model.EstimateShipping.StateProvinceId;
  406.                     var states = defaultEstimateCountryId.HasValue ? _stateProvinceService.GetStateProvincesByCountryId(defaultEstimateCountryId.Value).ToList() : new List<StateProvince>();
  407.                     if (states.Count > 0)
  408.                         foreach (var s in states)
  409.                             model.EstimateShipping.AvailableStates.Add(new SelectListItem()
  410.                             {
  411.                                 Text = s.GetLocalized(x => x.Name),
  412.                                 Value = s.Id.ToString(),
  413.                                 Selected = s.Id == defaultEstimateStateId
  414.                             });
  415.                     else
  416.                         model.EstimateShipping.AvailableStates.Add(new SelectListItem() { Text = _localizationService.GetResource("Address.OtherNonUS"), Value = "0" });
  417.  
  418.                     if (setEstimateShippingDefaultAddress && _workContext.CurrentCustomer.ShippingAddress != null)
  419.                         model.EstimateShipping.ZipPostalCode = _workContext.CurrentCustomer.ShippingAddress.ZipPostalCode;
  420.                 }
  421.             }
  422.  
  423.             #endregion
  424.  
  425.             #region Cart items
  426.  
  427.             // Change by Beach Hut Software for Punch out integration
  428.             // ( plus adding Attributes line into cartItemModel below )
  429.  
  430.             Extensions.PunchOut punchOut = new Extensions.PunchOut(_logger);
  431.  
  432.             // End
  433.  
  434.             foreach (var sci in cart)
  435.             {
  436.                 var cartItemModel = new ShoppingCartModel.ShoppingCartItemModel()
  437.                 {
  438.                     Id = sci.Id,
  439.                     Sku = sci.ProductVariant.FormatSku(sci.AttributesXml, _productAttributeParser),
  440.                     ProductId = sci.ProductVariant.ProductId,
  441.                     ProductSeName = sci.ProductVariant.Product.GetSeName(),
  442.                     Quantity = sci.Quantity,
  443.                     AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.ProductVariant, sci.AttributesXml),
  444.                     Attributes = punchOut.FormatAsList(sci.AttributesXml),
  445.                 };
  446.  
  447.                 cartItemModel.AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.ProductVariant, sci.AttributesXml);
  448.                 //allowed quantities
  449.                 var allowedQuantities = sci.ProductVariant.ParseAllowedQuatities();
  450.                 foreach (var qty in allowedQuantities)
  451.                 {
  452.                     cartItemModel.AllowedQuantities.Add(new SelectListItem()
  453.                     {
  454.                         Text = qty.ToString(),
  455.                         Value = qty.ToString(),
  456.                         Selected = sci.Quantity == qty
  457.                     });
  458.                 }
  459.                
  460.                 //recurring info
  461.                 if (sci.ProductVariant.IsRecurring)
  462.                     cartItemModel.RecurringInfo = string.Format(_localizationService.GetResource("ShoppingCart.RecurringPeriod"), sci.ProductVariant.RecurringCycleLength, sci.ProductVariant.RecurringCyclePeriod.GetLocalizedEnum(_localizationService, _workContext));
  463.  
  464.                 //unit prices
  465.                 if (sci.ProductVariant.CallForPrice)
  466.                 {
  467.                     cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice");
  468.                 }
  469.                 else
  470.                 {
  471.                     decimal taxRate = decimal.Zero;
  472.                     decimal shoppingCartUnitPriceWithDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetUnitPrice(sci, true), out taxRate);
  473.                     decimal shoppingCartUnitPriceWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, _workContext.WorkingCurrency);
  474.                     cartItemModel.UnitPrice = _priceFormatter.FormatPrice(shoppingCartUnitPriceWithDiscount);
  475.                 }
  476.                 //subtotal, discount
  477.                 if (sci.ProductVariant.CallForPrice)
  478.                 {
  479.                     cartItemModel.SubTotal = _localizationService.GetResource("Products.CallForPrice");
  480.                 }
  481.                 else
  482.                 {
  483.                     //sub total
  484.                     decimal taxRate = decimal.Zero;
  485.                     decimal shoppingCartItemSubTotalWithDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetSubTotal(sci, true), out taxRate);
  486.                     decimal shoppingCartItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemSubTotalWithDiscountBase, _workContext.WorkingCurrency);
  487.                     cartItemModel.SubTotal = _priceFormatter.FormatPrice(shoppingCartItemSubTotalWithDiscount);
  488.  
  489.                     //display an applied discount amount
  490.                     decimal shoppingCartItemSubTotalWithoutDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetSubTotal(sci, false), out taxRate);
  491.                     decimal shoppingCartItemDiscountBase = shoppingCartItemSubTotalWithoutDiscountBase - shoppingCartItemSubTotalWithDiscountBase;
  492.                     if (shoppingCartItemDiscountBase > decimal.Zero)
  493.                     {
  494.                         decimal shoppingCartItemDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemDiscountBase, _workContext.WorkingCurrency);
  495.                         cartItemModel.Discount = _priceFormatter.FormatPrice(shoppingCartItemDiscount);
  496.                     }
  497.                 }
  498.  
  499.                 //product name
  500.                 if (!String.IsNullOrEmpty(sci.ProductVariant.GetLocalized(x=>x.Name)))
  501.                     cartItemModel.ProductName = string.Format("{0} ({1})",sci.ProductVariant.Product.GetLocalized(x=>x.Name), sci.ProductVariant.GetLocalized(x=>x.Name));
  502.                 else
  503.                     cartItemModel.ProductName = sci.ProductVariant.Product.GetLocalized(x=>x.Name);
  504.                
  505.                 //picture
  506.                 if (_shoppingCartSettings.ShowProductImagesOnShoppingCart)
  507.                 {
  508.                     cartItemModel.Picture = PrepareCartItemPictureModel(sci.ProductVariant,
  509.                         _mediaSettings.CartThumbPictureSize, true, cartItemModel.ProductName);
  510.                 }
  511.  
  512.                 //item warnings
  513.                 var itemWarnings = _shoppingCartService.GetShoppingCartItemWarnings(
  514.                     _workContext.CurrentCustomer,
  515.                     sci.ShoppingCartType,
  516.                     sci.ProductVariant,
  517.                     sci.StoreId,
  518.                     sci.AttributesXml,
  519.                     sci.CustomerEnteredPrice,
  520.                     sci.Quantity,
  521.                     false);
  522.                 foreach (var warning in itemWarnings)
  523.                     cartItemModel.Warnings.Add(warning);
  524.  
  525.                 model.Items.Add(cartItemModel);
  526.             }
  527.  
  528.             #endregion
  529.  
  530.             #region Button payment methods
  531.  
  532.             var boundPaymentMethods = _paymentService
  533.                 .LoadActivePaymentMethods(_workContext.CurrentCustomer.Id)
  534.                 .Where(pm => pm.PaymentMethodType == PaymentMethodType.Button)
  535.                 .ToList();
  536.             foreach (var pm in boundPaymentMethods)
  537.             {
  538.                 if (cart.IsRecurring() && pm.RecurringPaymentType == RecurringPaymentType.NotSupported)
  539.                     continue;
  540.  
  541.                 string actionName;
  542.                 string controllerName;
  543.                 RouteValueDictionary routeValues;
  544.                 pm.GetPaymentInfoRoute(out actionName, out controllerName, out routeValues);
  545.  
  546.                 model.ButtonPaymentMethodActionNames.Add(actionName);
  547.                 model.ButtonPaymentMethodControllerNames.Add(controllerName);
  548.                 model.ButtonPaymentMethodRouteValues.Add(routeValues);
  549.             }
  550.  
  551.             #endregion
  552.  
  553.             #region Order review data
  554.  
  555.             if (prepareAndDisplayOrderReviewData)
  556.             {
  557.                 model.OrderReviewData.Display = true;
  558.  
  559.                 //billing info
  560.                 var billingAddress = _workContext.CurrentCustomer.BillingAddress;
  561.                 if (billingAddress != null)
  562.                     model.OrderReviewData.BillingAddress.PrepareModel(billingAddress, false, _addressSettings);
  563.                
  564.                 //shipping info
  565.                 if (cart.RequiresShipping())
  566.                 {
  567.                     model.OrderReviewData.IsShippable = true;
  568.  
  569.                     var shippingAddress = _workContext.CurrentCustomer.ShippingAddress;
  570.                     if (shippingAddress != null)
  571.                         model.OrderReviewData.ShippingAddress.PrepareModel(shippingAddress, false, _addressSettings);
  572.                    
  573.                     //selected shipping method
  574.                     var shippingOption = _workContext.CurrentCustomer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);
  575.                     if (shippingOption != null)
  576.                         model.OrderReviewData.ShippingMethod = shippingOption.Name;
  577.                 }
  578.                 //payment info
  579.                 var selectedPaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>(
  580.                     SystemCustomerAttributeNames.SelectedPaymentMethod, _storeContext.CurrentStore.Id);
  581.                 var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(selectedPaymentMethodSystemName);
  582.                 model.OrderReviewData.PaymentMethod = paymentMethod != null ? paymentMethod.GetLocalizedFriendlyName(_localizationService, _workContext.WorkingLanguage.Id) : "";
  583.             }
  584.             #endregion
  585.  
  586.             if (_storeContext.CurrentStore.Name == ConfigurationManager.AppSettings["AgentStoreName"])
  587.             {
  588.                 model.IsAgentStore = true;
  589.             }
  590.         }
  591.  
  592.         [NonAction]
  593.         protected void PrepareWishlistModel(WishlistModel model,
  594.             IList<ShoppingCartItem> cart, bool isEditable = true)
  595.         {
  596.             if (cart == null)
  597.                 throw new ArgumentNullException("cart");
  598.  
  599.             if (model == null)
  600.                 throw new ArgumentNullException("model");
  601.  
  602.             model.EmailWishlistEnabled = _shoppingCartSettings.EmailWishlistEnabled;
  603.             model.IsEditable = isEditable;
  604.             model.DisplayAddToCart = _permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart);
  605.  
  606.             if (cart.Count == 0)
  607.                 return;
  608.  
  609.             #region Simple properties
  610.  
  611.             var customer = cart.FirstOrDefault().Customer;
  612.             model.CustomerGuid = customer.CustomerGuid;
  613.             model.CustomerFullname = customer.GetFullName();
  614.             model.ShowProductImages = _shoppingCartSettings.ShowProductImagesOnShoppingCart;
  615.             model.ShowSku = _catalogSettings.ShowProductSku;
  616.            
  617.             //cart warnings
  618.             var cartWarnings = _shoppingCartService.GetShoppingCartWarnings(cart, "", false);
  619.             foreach (var warning in cartWarnings)
  620.                 model.Warnings.Add(warning);
  621.  
  622.             #endregion
  623.            
  624.             #region Cart items
  625.  
  626.             foreach (var sci in cart)
  627.             {
  628.                 var cartItemModel = new WishlistModel.ShoppingCartItemModel()
  629.                 {
  630.                     Id = sci.Id,
  631.                     Sku = sci.ProductVariant.FormatSku(sci.AttributesXml, _productAttributeParser),
  632.                     ProductId = sci.ProductVariant.ProductId,
  633.                     ProductSeName = sci.ProductVariant.Product.GetSeName(),
  634.                     Quantity = sci.Quantity,
  635.                     AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.ProductVariant, sci.AttributesXml),
  636.                 };
  637.  
  638.                 //allowed quantities
  639.                 var allowedQuantities = sci.ProductVariant.ParseAllowedQuatities();
  640.                 foreach (var qty in allowedQuantities)
  641.                 {
  642.                     cartItemModel.AllowedQuantities.Add(new SelectListItem()
  643.                     {
  644.                         Text = qty.ToString(),
  645.                         Value = qty.ToString(),
  646.                         Selected = sci.Quantity == qty
  647.                     });
  648.                 }
  649.                
  650.  
  651.                 //recurring info
  652.                 if (sci.ProductVariant.IsRecurring)
  653.                     cartItemModel.RecurringInfo = string.Format(_localizationService.GetResource("ShoppingCart.RecurringPeriod"), sci.ProductVariant.RecurringCycleLength, sci.ProductVariant.RecurringCyclePeriod.GetLocalizedEnum(_localizationService, _workContext));
  654.  
  655.                 //unit prices
  656.                 if (sci.ProductVariant.CallForPrice)
  657.                 {
  658.                     cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice");
  659.                 }
  660.                 else
  661.                 {
  662.                     decimal taxRate = decimal.Zero;
  663.                     decimal shoppingCartUnitPriceWithDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetUnitPrice(sci, true), out taxRate);
  664.                     decimal shoppingCartUnitPriceWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, _workContext.WorkingCurrency);
  665.                     cartItemModel.UnitPrice = _priceFormatter.FormatPrice(shoppingCartUnitPriceWithDiscount);
  666.                 }
  667.                 //subtotal, discount
  668.                 if (sci.ProductVariant.CallForPrice)
  669.                 {
  670.                     cartItemModel.SubTotal = _localizationService.GetResource("Products.CallForPrice");
  671.                 }
  672.                 else
  673.                 {
  674.                     //sub total
  675.                     decimal taxRate = decimal.Zero;
  676.                     decimal shoppingCartItemSubTotalWithDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetSubTotal(sci, true), out taxRate);
  677.                     decimal shoppingCartItemSubTotalWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemSubTotalWithDiscountBase, _workContext.WorkingCurrency);
  678.                     cartItemModel.SubTotal = _priceFormatter.FormatPrice(shoppingCartItemSubTotalWithDiscount);
  679.  
  680.                     //display an applied discount amount
  681.                     decimal shoppingCartItemSubTotalWithoutDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetSubTotal(sci, false), out taxRate);
  682.                     decimal shoppingCartItemDiscountBase = shoppingCartItemSubTotalWithoutDiscountBase - shoppingCartItemSubTotalWithDiscountBase;
  683.                     if (shoppingCartItemDiscountBase > decimal.Zero)
  684.                     {
  685.                         decimal shoppingCartItemDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartItemDiscountBase, _workContext.WorkingCurrency);
  686.                         cartItemModel.Discount = _priceFormatter.FormatPrice(shoppingCartItemDiscount);
  687.                     }
  688.                 }
  689.  
  690.                 //product name
  691.                 if (!String.IsNullOrEmpty(sci.ProductVariant.GetLocalized(x => x.Name)))
  692.                     cartItemModel.ProductName = string.Format("{0} ({1})", sci.ProductVariant.Product.GetLocalized(x => x.Name), sci.ProductVariant.GetLocalized(x => x.Name));
  693.                 else
  694.                     cartItemModel.ProductName = sci.ProductVariant.Product.GetLocalized(x => x.Name);
  695.  
  696.                 //picture
  697.                 if (_shoppingCartSettings.ShowProductImagesOnShoppingCart)
  698.                 {
  699.                     cartItemModel.Picture = PrepareCartItemPictureModel(sci.ProductVariant,
  700.                         _mediaSettings.CartThumbPictureSize, true, cartItemModel.ProductName);
  701.                 }
  702.  
  703.                 //item warnings
  704.                 var itemWarnings = _shoppingCartService.GetShoppingCartItemWarnings(_workContext.CurrentCustomer,
  705.                             sci.ShoppingCartType,
  706.                             sci.ProductVariant,
  707.                             sci.StoreId,
  708.                             sci.AttributesXml,
  709.                             sci.CustomerEnteredPrice,
  710.                             sci.Quantity, false);
  711.                 foreach (var warning in itemWarnings)
  712.                     cartItemModel.Warnings.Add(warning);
  713.  
  714.                 model.Items.Add(cartItemModel);
  715.             }
  716.  
  717.             #endregion
  718.         }
  719.  
  720.         [NonAction]
  721.         protected MiniShoppingCartModel PrepareMiniShoppingCartModel()
  722.         {
  723.             var model = new MiniShoppingCartModel()
  724.             {
  725.                 ShowProductImages = _shoppingCartSettings.ShowProductImagesInMiniShoppingCart,
  726.                 //let's always display it
  727.                 DisplayShoppingCartButton = true,
  728.                 CurrentCustomerIsGuest = _workContext.CurrentCustomer.IsGuest(),
  729.                 AnonymousCheckoutAllowed = _orderSettings.AnonymousCheckoutAllowed,
  730.             };
  731.  
  732.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  733.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  734.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  735.                 .ToList();
  736.             model.TotalProducts = cart.GetTotalProducts();
  737.             if (cart.Count > 0)
  738.             {
  739.                 //subtotal
  740.                 decimal subtotalBase = decimal.Zero;
  741.                 decimal orderSubTotalDiscountAmountBase = decimal.Zero;
  742.                 Discount orderSubTotalAppliedDiscount = null;
  743.                 decimal subTotalWithoutDiscountBase = decimal.Zero;
  744.                 decimal subTotalWithDiscountBase = decimal.Zero;
  745.                 _orderTotalCalculationService.GetShoppingCartSubTotal(cart,
  746.                     out orderSubTotalDiscountAmountBase, out orderSubTotalAppliedDiscount,
  747.                     out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);
  748.                 subtotalBase = subTotalWithoutDiscountBase;
  749.                 decimal subtotal = _currencyService.ConvertFromPrimaryStoreCurrency(subtotalBase, _workContext.WorkingCurrency);
  750.                 model.SubTotal = _priceFormatter.FormatPrice(subtotal);
  751.  
  752.                 //a customer should visit the shopping cart page before going to checkout if:
  753.                 //1. "terms of services" are enabled
  754.                 //2. we have at least one checkout attribute
  755.                 //3. min order sub-total is OK
  756.                 var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes();
  757.                 if (!cart.RequiresShipping())
  758.                 {
  759.                     //remove attributes which require shippable products
  760.                     checkoutAttributes = checkoutAttributes.RemoveShippableAttributes();
  761.                 }
  762.                 bool minOrderSubtotalAmountOk = _orderProcessingService.ValidateMinOrderSubtotalAmount(cart);
  763.                 model.DisplayCheckoutButton = !_orderSettings.TermsOfServiceEnabled &&
  764.                     checkoutAttributes.Count == 0 &&
  765.                     minOrderSubtotalAmountOk;
  766.  
  767.                 //products. sort descending (recently added products)
  768.                 foreach (var sci in cart
  769.                     .OrderByDescending(x => x.Id)
  770.                     .Take(_shoppingCartSettings.MiniShoppingCartProductNumber)
  771.                     .ToList())
  772.                 {
  773.                     var cartItemModel = new MiniShoppingCartModel.ShoppingCartItemModel()
  774.                     {
  775.                         Id = sci.Id,
  776.                         ProductId = sci.ProductVariant.ProductId,
  777.                         ProductSeName = sci.ProductVariant.Product.GetSeName(),
  778.                         Quantity = sci.Quantity,
  779.                         AttributeInfo = _productAttributeFormatter.FormatAttributes(sci.ProductVariant, sci.AttributesXml)
  780.                     };
  781.  
  782.                     //product name
  783.                     if (!String.IsNullOrEmpty(sci.ProductVariant.GetLocalized(x => x.Name)))
  784.                         cartItemModel.ProductName = string.Format("{0} ({1})", sci.ProductVariant.Product.GetLocalized(x => x.Name), sci.ProductVariant.GetLocalized(x => x.Name));
  785.                     else
  786.                         cartItemModel.ProductName = sci.ProductVariant.Product.GetLocalized(x => x.Name);
  787.  
  788.                     //unit prices
  789.                     if (sci.ProductVariant.CallForPrice)
  790.                     {
  791.                         cartItemModel.UnitPrice = _localizationService.GetResource("Products.CallForPrice");
  792.                     }
  793.                     else
  794.                     {
  795.                         decimal taxRate = decimal.Zero;
  796.                         decimal shoppingCartUnitPriceWithDiscountBase = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetUnitPrice(sci, true), out taxRate);
  797.                         decimal shoppingCartUnitPriceWithDiscount = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartUnitPriceWithDiscountBase, _workContext.WorkingCurrency);
  798.                         cartItemModel.UnitPrice = _priceFormatter.FormatPrice(shoppingCartUnitPriceWithDiscount);
  799.                     }
  800.  
  801.                     //picture
  802.                     if (_shoppingCartSettings.ShowProductImagesInMiniShoppingCart)
  803.                     {
  804.                         cartItemModel.Picture = PrepareCartItemPictureModel(sci.ProductVariant,
  805.                             _mediaSettings.MiniCartThumbPictureSize, true, cartItemModel.ProductName);
  806.                     }
  807.  
  808.                     model.Items.Add(cartItemModel);
  809.                 }
  810.             }
  811.            
  812.             return model;
  813.         }
  814.  
  815.         [NonAction]
  816.         protected void ParseAndSaveCheckoutAttributes(List<ShoppingCartItem> cart, FormCollection form)
  817.         {
  818.             string selectedAttributes = "";
  819.             var checkoutAttributes = _checkoutAttributeService.GetAllCheckoutAttributes();
  820.             if (!cart.RequiresShipping())
  821.             {
  822.                 //remove attributes which require shippable products
  823.                 checkoutAttributes = checkoutAttributes.RemoveShippableAttributes();
  824.             }
  825.             foreach (var attribute in checkoutAttributes)
  826.             {
  827.                 string controlId = string.Format("checkout_attribute_{0}", attribute.Id);
  828.                 switch (attribute.AttributeControlType)
  829.                 {
  830.                     case AttributeControlType.DropdownList:
  831.                     case AttributeControlType.RadioList:
  832.                     case AttributeControlType.ColorSquares:
  833.                         {
  834.                             var ctrlAttributes = form[controlId];
  835.                             if (!String.IsNullOrEmpty(ctrlAttributes))
  836.                             {
  837.                                 int selectedAttributeId = int.Parse(ctrlAttributes);
  838.                                 if (selectedAttributeId > 0)
  839.                                     selectedAttributes = _checkoutAttributeParser.AddCheckoutAttribute(selectedAttributes,
  840.                                         attribute, selectedAttributeId.ToString());
  841.                             }
  842.                         }
  843.                         break;
  844.                     case AttributeControlType.Checkboxes:
  845.                         {
  846.                             var cblAttributes = form[controlId];
  847.                             if (!String.IsNullOrEmpty(cblAttributes))
  848.                             {
  849.                                 foreach (var item in cblAttributes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
  850.                                 {
  851.                                     int selectedAttributeId = int.Parse(item);
  852.                                     if (selectedAttributeId > 0)
  853.                                         selectedAttributes = _checkoutAttributeParser.AddCheckoutAttribute(selectedAttributes,
  854.                                             attribute, selectedAttributeId.ToString());
  855.                                 }
  856.                             }
  857.                         }
  858.                         break;
  859.                     case AttributeControlType.TextBox:
  860.                     case AttributeControlType.MultilineTextbox:
  861.                         {
  862.                             var ctrlAttributes = form[controlId];
  863.                             if (!String.IsNullOrEmpty(ctrlAttributes))
  864.                             {
  865.                                 string enteredText = ctrlAttributes.Trim();
  866.                                 selectedAttributes = _checkoutAttributeParser.AddCheckoutAttribute(selectedAttributes,
  867.                                     attribute, enteredText);
  868.                             }
  869.                         }
  870.                         break;
  871.                     case AttributeControlType.Datepicker:
  872.                         {
  873.                             var date = form[controlId + "_day"];
  874.                             var month = form[controlId + "_month"];
  875.                             var year = form[controlId + "_year"];
  876.                             DateTime? selectedDate = null;
  877.                             try
  878.                             {
  879.                                 selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(date));
  880.                             }
  881.                             catch { }
  882.                             if (selectedDate.HasValue)
  883.                             {
  884.                                 selectedAttributes = _checkoutAttributeParser.AddCheckoutAttribute(selectedAttributes,
  885.                                     attribute, selectedDate.Value.ToString("D"));
  886.                             }
  887.                         }
  888.                         break;
  889.                     case AttributeControlType.FileUpload:
  890.                         {
  891.                             var httpPostedFile = this.Request.Files[controlId];
  892.                             if ((httpPostedFile != null) && (!String.IsNullOrEmpty(httpPostedFile.FileName)))
  893.                             {
  894.                                 int fileMaxSize = _catalogSettings.FileUploadMaximumSizeBytes;
  895.                                 if (httpPostedFile.ContentLength > fileMaxSize)
  896.                                 {
  897.                                     //TODO display warning
  898.                                     //warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumUploadedFileSize"), (int)(fileMaxSize / 1024)));
  899.                                 }
  900.                                 else
  901.                                 {
  902.                                     //save an uploaded file
  903.                                     var download = new Download()
  904.                                     {
  905.                                         DownloadGuid = Guid.NewGuid(),
  906.                                         UseDownloadUrl = false,
  907.                                         DownloadUrl = "",
  908.                                         DownloadBinary = httpPostedFile.GetDownloadBits(),
  909.                                         ContentType = httpPostedFile.ContentType,
  910.                                         Filename = System.IO.Path.GetFileNameWithoutExtension(httpPostedFile.FileName),
  911.                                         Extension = System.IO.Path.GetExtension(httpPostedFile.FileName),
  912.                                         IsNew = true
  913.                                     };
  914.                                     _downloadService.InsertDownload(download);
  915.                                     //save attribute
  916.                                     selectedAttributes = _checkoutAttributeParser.AddCheckoutAttribute(selectedAttributes,
  917.                                         attribute, download.DownloadGuid.ToString());
  918.                                 }
  919.                             }
  920.                         }
  921.                         break;
  922.                     default:
  923.                         break;
  924.                 }
  925.             }
  926.  
  927.             //save checkout attributes
  928.             _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.CheckoutAttributes, selectedAttributes);
  929.         }
  930.  
  931.         #endregion
  932.  
  933.         #region Shopping cart
  934.        
  935.         //add product (not product variant) to cart using AJAX
  936.         //currently we use this method on catalog pages (category/manufacturer/etc)
  937.         [HttpPost]
  938.         public ActionResult AddProductToCart(int productId, int shoppingCartTypeId,
  939.             int quantity, bool forceredirection = false)
  940.         {
  941.             var cartType = (ShoppingCartType)shoppingCartTypeId;
  942.  
  943.             var product = _productService.GetProductById(productId);
  944.             if (product == null)
  945.                 //no product found
  946.                 return Json(new
  947.                 {
  948.                     success = false,
  949.                     message = "No product found with the specified ID"
  950.                 });
  951.  
  952.             var productVariants = _productService.GetProductVariantsByProductId(productId);
  953.             if (productVariants.Count != 1)
  954.             {
  955.                 //we can add a product to the cart only if it has exactly one product variant
  956.                 return Json(new
  957.                 {
  958.                     redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName() }),
  959.                 });
  960.             }
  961.  
  962.             //get default product variant
  963.             var productVariant = productVariants[0];
  964.             if (productVariant.CustomerEntersPrice)
  965.             {
  966.                 //cannot be added to the cart (requires a customer to enter price)
  967.                 return Json(new
  968.                 {
  969.                     redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName() }),
  970.                 });
  971.             }
  972.  
  973.             var allowedQuantities = productVariant.ParseAllowedQuatities();
  974.             if (allowedQuantities.Length > 0)
  975.             {
  976.                 //cannot be added to the cart (requires a customer to select a quantity from dropdownlist)
  977.                 return Json(new
  978.                 {
  979.                     redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName() }),
  980.                 });
  981.             }
  982.  
  983.             //get standard warnings without attribute validations
  984.             //first, try to find existing shopping cart item
  985.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  986.                 .Where(sci => sci.ShoppingCartType == cartType)
  987.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  988.                 .ToList();
  989.             var shoppingCartItem = _shoppingCartService.FindShoppingCartItemInTheCart(cart, cartType, productVariant);
  990.             //if we already have the same product variant in the cart, then use the total quantity to validate
  991.             var quantityToValidate = shoppingCartItem != null ? shoppingCartItem.Quantity + quantity : quantity;
  992.             var addToCartWarnings = _shoppingCartService
  993.                 .GetShoppingCartItemWarnings(_workContext.CurrentCustomer, cartType,
  994.                 productVariant, _storeContext.CurrentStore.Id, string.Empty,
  995.                 decimal.Zero, quantityToValidate, false, true, false, false, false);
  996.             if (addToCartWarnings.Count > 0)
  997.             {
  998.                 //cannot be added to the cart
  999.                 //let's display standard warnings
  1000.                 return Json(new
  1001.                 {
  1002.                     success = false,
  1003.                     message = addToCartWarnings.ToArray()
  1004.                 });
  1005.             }
  1006.  
  1007.             //now let's try adding product to the cart (now including product attribute validation, etc)
  1008.             addToCartWarnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
  1009.                 productVariant, cartType, _storeContext.CurrentStore.Id,
  1010.                 string.Empty, decimal.Zero, quantity, true);
  1011.             if (addToCartWarnings.Count > 0)
  1012.             {
  1013.                 //cannot be added to the cart
  1014.                 //but we do not display attribute and gift card warnings here. let's do it on the product details page
  1015.                 return Json(new
  1016.                 {
  1017.                     redirect = Url.RouteUrl("Product", new { SeName = product.GetSeName() }),
  1018.                 });
  1019.             }
  1020.  
  1021.             //added to the cart/wishlist
  1022.             switch (cartType)
  1023.             {
  1024.                 case ShoppingCartType.Wishlist:
  1025.                     {
  1026.                         //activity log
  1027.                         _customerActivityService.InsertActivity("PublicStore.AddToWishlist", _localizationService.GetResource("ActivityLog.PublicStore.AddToWishlist"), productVariant.FullProductName);
  1028.  
  1029.                         if (_shoppingCartSettings.DisplayWishlistAfterAddingProduct || forceredirection)
  1030.                         {
  1031.                             //redirect to the wishlist page
  1032.                             return Json(new
  1033.                             {
  1034.                                 redirect = Url.RouteUrl("Wishlist"),
  1035.                             });
  1036.                         }
  1037.                         else
  1038.                         {
  1039.                             //display notification message and update appropriate blocks
  1040.                             var updatetopwishlistsectionhtml = string.Format(_localizationService.GetResource("Wishlist.HeaderQuantity"),
  1041.                                  _workContext.CurrentCustomer.ShoppingCartItems
  1042.                                  .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  1043.                                  .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1044.                                  .ToList()
  1045.                                  .GetTotalProducts());
  1046.                             return Json(new
  1047.                             {
  1048.                                 success = true,
  1049.                                 message = string.Format(_localizationService.GetResource("Products.ProductHasBeenAddedToTheWishlist.Link"), Url.RouteUrl("Wishlist")),
  1050.                                 updatetopwishlistsectionhtml = updatetopwishlistsectionhtml,
  1051.                             });
  1052.                         }
  1053.                     }
  1054.                 case ShoppingCartType.ShoppingCart:
  1055.                 default:
  1056.                     {
  1057.                         //activity log
  1058.                         _customerActivityService.InsertActivity("PublicStore.AddToShoppingCart", _localizationService.GetResource("ActivityLog.PublicStore.AddToShoppingCart"), productVariant.FullProductName);
  1059.  
  1060.                         if (_shoppingCartSettings.DisplayCartAfterAddingProduct || forceredirection)
  1061.                         {
  1062.                             //redirect to the shopping cart page
  1063.                             return Json(new
  1064.                             {
  1065.                                 redirect = Url.RouteUrl("ShoppingCart"),
  1066.                             });
  1067.                         }
  1068.                         else
  1069.                         {
  1070.  
  1071.                             //display notification message and update appropriate blocks
  1072.                             var updatetopcartsectionhtml = string.Format(_localizationService.GetResource("ShoppingCart.HeaderQuantity"),
  1073.                                  _workContext.CurrentCustomer.ShoppingCartItems
  1074.                                  .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1075.                                  .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1076.                                  .ToList()
  1077.                                  .GetTotalProducts());
  1078.                             var updateflyoutcartsectionhtml = _shoppingCartSettings.MiniShoppingCartEnabled
  1079.                                 ? this.RenderPartialViewToString("FlyoutShoppingCart", PrepareMiniShoppingCartModel())
  1080.                                 : "";
  1081.  
  1082.                             return Json(new
  1083.                             {
  1084.                                 success = true,
  1085.                                 message = string.Format(_localizationService.GetResource("Products.ProductHasBeenAddedToTheCart.Link"), Url.RouteUrl("ShoppingCart")),
  1086.                                 updatetopcartsectionhtml = updatetopcartsectionhtml,
  1087.                                 updateflyoutcartsectionhtml = updateflyoutcartsectionhtml
  1088.                             });
  1089.                         }
  1090.                     }
  1091.             }
  1092.         }
  1093.  
  1094.         //add product variant to cart using AJAX
  1095.         //currently we use this method only for desktop version
  1096.         //mobile version uses HTTP POST version of this method (CatalogController.AddProductVariantToCart)
  1097.         [HttpPost]
  1098.         [ValidateInput(false)]
  1099.         public ActionResult AddProductVariantToCart(int productVariantId, int shoppingCartTypeId, FormCollection form)
  1100.         {
  1101.             var productVariant = _productService.GetProductVariantById(productVariantId);
  1102.             if (productVariant == null)
  1103.             {
  1104.                 return Json(new
  1105.                 {
  1106.                     redirect = Url.RouteUrl("HomePage"),
  1107.                 });
  1108.             }
  1109.  
  1110.             #region Customer entered price
  1111.             decimal customerEnteredPriceConverted = decimal.Zero;
  1112.             if (productVariant.CustomerEntersPrice)
  1113.             {
  1114.                 foreach (string formKey in form.AllKeys)
  1115.                 {
  1116.                     if (formKey.Equals(string.Format("addtocart_{0}.CustomerEnteredPrice", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1117.                     {
  1118.                         decimal customerEnteredPrice = decimal.Zero;
  1119.                         if (decimal.TryParse(form[formKey], out customerEnteredPrice))
  1120.                             customerEnteredPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(customerEnteredPrice, _workContext.WorkingCurrency);
  1121.                         break;
  1122.                     }
  1123.                 }
  1124.             }
  1125.             #endregion
  1126.  
  1127.             #region Quantity
  1128.  
  1129.             int quantity = 1;
  1130.             foreach (string formKey in form.AllKeys)
  1131.                 if (formKey.Equals(string.Format("addtocart_{0}.EnteredQuantity", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1132.                 {
  1133.                     int.TryParse(form[formKey], out quantity);
  1134.                     break;
  1135.                 }
  1136.  
  1137.             #endregion
  1138.  
  1139.             var addToCartWarnings = new List<string>();
  1140.             string attributes = "";
  1141.  
  1142.             #region Product attributes
  1143.             string selectedAttributes = string.Empty;
  1144.             var productVariantAttributes = _productAttributeService.GetProductVariantAttributesByProductVariantId(productVariant.Id);
  1145.             foreach (var attribute in productVariantAttributes)
  1146.             {
  1147.                 string controlId = string.Format("product_attribute_{0}_{1}_{2}", attribute.ProductVariantId, attribute.ProductAttributeId, attribute.Id);
  1148.                 switch (attribute.AttributeControlType)
  1149.                 {
  1150.                     case AttributeControlType.DropdownList:
  1151.                     case AttributeControlType.RadioList:
  1152.                     case AttributeControlType.ColorSquares:
  1153.                         {
  1154.                             var ctrlAttributes = form[controlId];
  1155.                             if (!String.IsNullOrEmpty(ctrlAttributes))
  1156.                             {
  1157.                                 int selectedAttributeId = int.Parse(ctrlAttributes);
  1158.                                 if (selectedAttributeId > 0)
  1159.                                     selectedAttributes = _productAttributeParser.AddProductAttribute(selectedAttributes,
  1160.                                         attribute, selectedAttributeId.ToString());
  1161.                             }
  1162.                         }
  1163.                         break;
  1164.                     case AttributeControlType.Checkboxes:
  1165.                         {
  1166.                             var ctrlAttributes = form[controlId];
  1167.                             if (!String.IsNullOrEmpty(ctrlAttributes))
  1168.                             {
  1169.                                 foreach (var item in ctrlAttributes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
  1170.                                 {
  1171.                                     int selectedAttributeId = int.Parse(item);
  1172.                                     if (selectedAttributeId > 0)
  1173.                                         selectedAttributes = _productAttributeParser.AddProductAttribute(selectedAttributes,
  1174.                                             attribute, selectedAttributeId.ToString());
  1175.                                 }
  1176.                             }
  1177.                         }
  1178.                         break;
  1179.                     case AttributeControlType.TextBox:
  1180.                     case AttributeControlType.MultilineTextbox:
  1181.                         {
  1182.                             var ctrlAttributes = form[controlId];
  1183.                             if (!String.IsNullOrEmpty(ctrlAttributes))
  1184.                             {
  1185.                                 string enteredText = ctrlAttributes.Trim();
  1186.                                 selectedAttributes = _productAttributeParser.AddProductAttribute(selectedAttributes,
  1187.                                     attribute, enteredText);
  1188.                             }
  1189.                         }
  1190.                         break;
  1191.                     case AttributeControlType.Datepicker:
  1192.                         {
  1193.                             var day = form[controlId + "_day"];
  1194.                             var month = form[controlId + "_month"];
  1195.                             var year = form[controlId + "_year"];
  1196.                             DateTime? selectedDate = null;
  1197.                             try
  1198.                             {
  1199.                                 selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day));
  1200.                             }
  1201.                             catch { }
  1202.                             if (selectedDate.HasValue)
  1203.                             {
  1204.                                 selectedAttributes = _productAttributeParser.AddProductAttribute(selectedAttributes,
  1205.                                     attribute, selectedDate.Value.ToString("D"));
  1206.                             }
  1207.                         }
  1208.                         break;
  1209.                     case AttributeControlType.FileUpload:
  1210.                         {
  1211.                             Guid downloadGuid;
  1212.                             Guid.TryParse(form[controlId], out downloadGuid);
  1213.                             var download = _downloadService.GetDownloadByGuid(downloadGuid);
  1214.                             if (download != null)
  1215.                             {
  1216.                                 selectedAttributes = _productAttributeParser.AddProductAttribute(selectedAttributes,
  1217.                                         attribute, download.DownloadGuid.ToString());
  1218.                             }
  1219.                         }
  1220.                         break;
  1221.                     default:
  1222.                         break;
  1223.                 }
  1224.             }
  1225.             attributes = selectedAttributes;
  1226.  
  1227.             #endregion
  1228.  
  1229.             #region Gift cards
  1230.  
  1231.             if (productVariant.IsGiftCard)
  1232.             {
  1233.                 string recipientName = "";
  1234.                 string recipientEmail = "";
  1235.                 string senderName = "";
  1236.                 string senderEmail = "";
  1237.                 string giftCardMessage = "";
  1238.                 foreach (string formKey in form.AllKeys)
  1239.                 {
  1240.                     if (formKey.Equals(string.Format("giftcard_{0}.RecipientName", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1241.                     {
  1242.                         recipientName = form[formKey];
  1243.                         continue;
  1244.                     }
  1245.                     if (formKey.Equals(string.Format("giftcard_{0}.RecipientEmail", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1246.                     {
  1247.                         recipientEmail = form[formKey];
  1248.                         continue;
  1249.                     }
  1250.                     if (formKey.Equals(string.Format("giftcard_{0}.SenderName", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1251.                     {
  1252.                         senderName = form[formKey];
  1253.                         continue;
  1254.                     }
  1255.                     if (formKey.Equals(string.Format("giftcard_{0}.SenderEmail", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1256.                     {
  1257.                         senderEmail = form[formKey];
  1258.                         continue;
  1259.                     }
  1260.                     if (formKey.Equals(string.Format("giftcard_{0}.Message", productVariantId), StringComparison.InvariantCultureIgnoreCase))
  1261.                     {
  1262.                         giftCardMessage = form[formKey];
  1263.                         continue;
  1264.                     }
  1265.                 }
  1266.  
  1267.                 attributes = _productAttributeParser.AddGiftCardAttribute(attributes,
  1268.                     recipientName, recipientEmail, senderName, senderEmail, giftCardMessage);
  1269.             }
  1270.  
  1271.             #endregion
  1272.  
  1273.             #region Punch-out
  1274.  
  1275.             // Change 1/7/2013 by Beach Hut to link to punch out module
  1276.            
  1277.             Extensions.PunchOut punchOut = new Extensions.PunchOut(_logger);
  1278.  
  1279.             Boolean isPunchOut;
  1280.             String id = productVariant.Sku;
  1281.             String ticketId = null;
  1282.  
  1283.             // Check that the product supports Punch out integration
  1284.  
  1285.             if (String.IsNullOrWhiteSpace(id))
  1286.             {
  1287.                 isPunchOut = false;
  1288.             }
  1289.             else
  1290.             {
  1291.                 //CT002
  1292.                 isPunchOut = (id.Substring(0, 9) == ConfigurationManager.AppSettings["PunchOutOnSKUPrefix"]);
  1293.                 //isPunchOut = ConfigurationManager.AppSettings["PunchOutOnSKUPrefix"].Split(',').Any(s => id.StartsWith(s));
  1294.                 //CT002
  1295.             }
  1296.  
  1297.             if (isPunchOut)
  1298.             {
  1299.                 ticketId = punchOut.CreatePunchOutReference(id, Url, Request);
  1300.  
  1301.                 if (!string.IsNullOrEmpty(ticketId))
  1302.                 {
  1303.                     // save the reference from punch out into a custom attribute
  1304.                     // which is saved in the basket item
  1305.                     var attribute = new ProductVariantAttribute();
  1306.                     int punchOutAttributeId;
  1307.                     Int32.TryParse(ConfigurationManager.AppSettings["PunchOutAttributeId"], out punchOutAttributeId);
  1308.                     attribute.Id = punchOutAttributeId;
  1309.                     // add this to the product attributes
  1310.                     attributes = _productAttributeParser.AddProductAttribute(selectedAttributes, attribute, ticketId);
  1311.                 }
  1312.                 else
  1313.                 {
  1314.                     // we haven't got a valid response
  1315.                     addToCartWarnings.Add("The item cannot be added as no valid ticket was received");
  1316.                 }
  1317.             }
  1318.  
  1319.             #endregion
  1320.  
  1321.             //save item
  1322.             var cartType = (ShoppingCartType)shoppingCartTypeId;
  1323.             addToCartWarnings.AddRange(_shoppingCartService.AddToCart(_workContext.CurrentCustomer,
  1324.                 productVariant, cartType, _storeContext.CurrentStore.Id,
  1325.                 attributes, customerEnteredPriceConverted, quantity, true));
  1326.  
  1327.             #region Return result
  1328.  
  1329.             if (addToCartWarnings.Count > 0)
  1330.             {
  1331.                 //cannot be added to the cart/wishlist
  1332.                 //let's display warnings
  1333.                 return Json(new
  1334.                 {
  1335.                     success = false,
  1336.                     message = addToCartWarnings.ToArray()
  1337.                 });
  1338.             }
  1339.  
  1340.             //added to the cart/wishlist
  1341.             switch (cartType)
  1342.             {
  1343.                 case ShoppingCartType.Wishlist:
  1344.                     {
  1345.                         //activity log
  1346.                         _customerActivityService.InsertActivity("PublicStore.AddToWishlist", _localizationService.GetResource("ActivityLog.PublicStore.AddToWishlist"), productVariant.FullProductName);
  1347.  
  1348.                         if (_shoppingCartSettings.DisplayWishlistAfterAddingProduct)
  1349.                         {
  1350.                             //redirect to the wishlist page
  1351.                             return Json(new
  1352.                             {
  1353.                                 redirect = Url.RouteUrl("Wishlist"),
  1354.                             });
  1355.                         }
  1356.                         else
  1357.                         {
  1358.                             //display notification message and update appropriate blocks
  1359.                             var updatetopwishlistsectionhtml = string.Format(_localizationService.GetResource("Wishlist.HeaderQuantity"),
  1360.                                  _workContext.CurrentCustomer.ShoppingCartItems
  1361.                                  .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  1362.                                  .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1363.                                  .ToList()
  1364.                                  .GetTotalProducts());
  1365.                             return Json(new
  1366.                             {
  1367.                                 success = true,
  1368.                                 message = string.Format(_localizationService.GetResource("Products.ProductHasBeenAddedToTheWishlist.Link"), Url.RouteUrl("Wishlist")),
  1369.                                 updatetopwishlistsectionhtml = updatetopwishlistsectionhtml,
  1370.                             });
  1371.                         }
  1372.                     }
  1373.                 case ShoppingCartType.ShoppingCart:
  1374.                 default:
  1375.                     {
  1376.                         //activity log
  1377.                         _customerActivityService.InsertActivity("PublicStore.AddToShoppingCart", _localizationService.GetResource("ActivityLog.PublicStore.AddToShoppingCart"), productVariant.FullProductName);
  1378.  
  1379.                         UrlHelper helper;
  1380.  
  1381.                         if (isPunchOut && !string.IsNullOrEmpty(ticketId))
  1382.                         {
  1383.                             string url = punchOut.CreatePunchOutUrl(ticketId);
  1384.                             return Json(new
  1385.                             {
  1386.                                 redirect = url
  1387.                             });
  1388.                         }
  1389.                         else
  1390.                         {
  1391.  
  1392.                             if (_shoppingCartSettings.DisplayCartAfterAddingProduct)
  1393.                             {
  1394.                                 //redirect to the shopping cart page
  1395.                                 return Json(new
  1396.                                 {
  1397.                                     redirect = Url.RouteUrl("ShoppingCart"),
  1398.                                 });
  1399.                             }
  1400.                             else
  1401.                             {
  1402.  
  1403.                                 //display notification message and update appropriate blocks
  1404.                                 var updatetopcartsectionhtml = string.Format(_localizationService.GetResource("ShoppingCart.HeaderQuantity"),
  1405.                                      _workContext.CurrentCustomer.ShoppingCartItems
  1406.                                      .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1407.                                      .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1408.                                      .ToList()
  1409.                                      .GetTotalProducts());
  1410.                                 var updateflyoutcartsectionhtml = _shoppingCartSettings.MiniShoppingCartEnabled
  1411.                                     ? this.RenderPartialViewToString("FlyoutShoppingCart", PrepareMiniShoppingCartModel())
  1412.                                     : "";
  1413.  
  1414.                                 return Json(new
  1415.                                 {
  1416.                                     success = true,
  1417.                                     message = string.Format(_localizationService.GetResource("Products.ProductHasBeenAddedToTheCart.Link"), Url.RouteUrl("ShoppingCart")),
  1418.                                     updatetopcartsectionhtml = updatetopcartsectionhtml,
  1419.                                     updateflyoutcartsectionhtml = updateflyoutcartsectionhtml
  1420.                                 });
  1421.                             }
  1422.                         }
  1423.                     }
  1424.             }
  1425.  
  1426.  
  1427.             #endregion
  1428.         }
  1429.  
  1430.         [HttpPost]
  1431.         public ActionResult UploadFileProductAttribute(int productVariantId, int productAttributeId)
  1432.         {
  1433.             var productVariant = _productService.GetProductVariantById(productVariantId);
  1434.             if (productVariant == null ||
  1435.                 !productVariant.Published ||
  1436.                 productVariant.Deleted ||
  1437.                 productVariant.Product == null ||
  1438.                 !productVariant.Product.Published ||
  1439.                 productVariant.Product.Deleted)
  1440.             {
  1441.                 return Json(new
  1442.                 {
  1443.                     success = false,
  1444.                     downloadGuid = Guid.Empty,
  1445.                 }, "text/plain");
  1446.             }
  1447.             //ensure that this attribute belong to this product variant and has "file upload" type
  1448.             var pva = _productAttributeService
  1449.                 .GetProductVariantAttributesByProductVariantId(productVariantId)
  1450.                 .FirstOrDefault(pa => pa.ProductAttributeId == productAttributeId);
  1451.             if (pva == null || pva.AttributeControlType != AttributeControlType.FileUpload)
  1452.             {
  1453.                 return Json(new
  1454.                 {
  1455.                     success = false,
  1456.                     downloadGuid = Guid.Empty,
  1457.                 }, "text/plain");
  1458.             }
  1459.  
  1460.             //we process it distinct ways based on a browser
  1461.             //find more info here http://stackoverflow.com/questions/4884920/mvc3-valums-ajax-file-upload
  1462.             Stream stream = null;
  1463.             var fileName = "";
  1464.             var contentType = "";
  1465.             if (String.IsNullOrEmpty(Request["qqfile"]))
  1466.             {
  1467.                 // IE
  1468.                 HttpPostedFileBase httpPostedFile = Request.Files[0];
  1469.                 if (httpPostedFile == null)
  1470.                     throw new ArgumentException("No file uploaded");
  1471.                 stream = httpPostedFile.InputStream;
  1472.                 fileName = Path.GetFileName(httpPostedFile.FileName);
  1473.                 contentType = httpPostedFile.ContentType;
  1474.             }
  1475.             else
  1476.             {
  1477.                 //Webkit, Mozilla
  1478.                 stream = Request.InputStream;
  1479.                 fileName = Request["qqfile"];
  1480.             }
  1481.  
  1482.             var fileBinary = new byte[stream.Length];
  1483.             stream.Read(fileBinary, 0, fileBinary.Length);
  1484.  
  1485.             var fileExtension = Path.GetExtension(fileName);
  1486.             if (!String.IsNullOrEmpty(fileExtension))
  1487.                 fileExtension = fileExtension.ToLowerInvariant();
  1488.  
  1489.             int fileMaxSize = _catalogSettings.FileUploadMaximumSizeBytes;
  1490.             if (fileBinary.Length > fileMaxSize)
  1491.             {
  1492.                 //when returning JSON the mime-type must be set to text/plain
  1493.                 //otherwise some browsers will pop-up a "Save As" dialog.
  1494.                 return Json(new
  1495.                 {
  1496.                     success = false,
  1497.                     message = string.Format(_localizationService.GetResource("ShoppingCart.MaximumUploadedFileSize"), (int)(fileMaxSize / 1024)),
  1498.                     downloadGuid = Guid.Empty,
  1499.                 }, "text/plain");
  1500.             }
  1501.  
  1502.             var download = new Download()
  1503.             {
  1504.                 DownloadGuid = Guid.NewGuid(),
  1505.                 UseDownloadUrl = false,
  1506.                 DownloadUrl = "",
  1507.                 DownloadBinary = fileBinary,
  1508.                 ContentType = contentType,
  1509.                 //we store filename without extension for downloads
  1510.                 Filename = Path.GetFileNameWithoutExtension(fileName),
  1511.                 Extension = fileExtension,
  1512.                 IsNew = true
  1513.             };
  1514.             _downloadService.InsertDownload(download);
  1515.  
  1516.             //when returning JSON the mime-type must be set to text/plain
  1517.             //otherwise some browsers will pop-up a "Save As" dialog.
  1518.             return Json(new
  1519.             {
  1520.                 success = true,
  1521.                 message = _localizationService.GetResource("ShoppingCart.FileUploaded"),
  1522.                 downloadGuid = download.DownloadGuid,
  1523.             }, "text/plain");
  1524.         }
  1525.  
  1526.  
  1527.         [NopHttpsRequirement(SslRequirement.Yes)]
  1528.         public ActionResult Cart()
  1529.         {
  1530.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  1531.                 return RedirectToRoute("HomePage");
  1532.  
  1533.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1534.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1535.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1536.                 .ToList();
  1537.             var model = new ShoppingCartModel();
  1538.             PrepareShoppingCartModel(model, cart);
  1539.             return View(model);
  1540.         }
  1541.  
  1542.         [ChildActionOnly]
  1543.         public ActionResult OrderSummary(bool? prepareAndDisplayOrderReviewData)
  1544.         {
  1545.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1546.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1547.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1548.                 .ToList();
  1549.             var model = new ShoppingCartModel();
  1550.             PrepareShoppingCartModel(model, cart,
  1551.                 isEditable: false,
  1552.                 prepareEstimateShippingIfEnabled: false,
  1553.                 prepareAndDisplayOrderReviewData: prepareAndDisplayOrderReviewData.HasValue ? prepareAndDisplayOrderReviewData.Value : false);
  1554.  
  1555.             return PartialView(model);
  1556.         }
  1557.  
  1558.         //update all shopping cart items on the page
  1559.         [ValidateInput(false)]
  1560.         [HttpPost, ActionName("Cart")]
  1561.         [FormValueRequired("updatecart")]
  1562.         public ActionResult UpdateCartAll(FormCollection form)
  1563.         {
  1564.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  1565.                 return RedirectToRoute("HomePage");
  1566.  
  1567.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1568.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1569.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1570.                 .ToList();
  1571.  
  1572.             var allIdsToRemove = form["removefromcart"] != null ? form["removefromcart"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList() : new List<int>();
  1573.  
  1574.             //current warnings <cart item identifier, warnings>
  1575.             var innerWarnings = new Dictionary<int, IList<string>>();
  1576.             foreach (var sci in cart)
  1577.             {
  1578.                 bool remove = allIdsToRemove.Contains(sci.Id);
  1579.                 if (remove)
  1580.                     _shoppingCartService.DeleteShoppingCartItem(sci, ensureOnlyActiveCheckoutAttributes: true);
  1581.                 else
  1582.                 {
  1583.                     foreach (string formKey in form.AllKeys)
  1584.                         if (formKey.Equals(string.Format("itemquantity{0}", sci.Id), StringComparison.InvariantCultureIgnoreCase))
  1585.                         {
  1586.                             int newQuantity = sci.Quantity;
  1587.                             if (int.TryParse(form[formKey], out newQuantity))
  1588.                             {
  1589.                                 var currSciWarnings = _shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer,
  1590.                                     sci.Id, newQuantity, true);
  1591.                                 innerWarnings.Add(sci.Id, currSciWarnings);
  1592.                             }
  1593.                             break;
  1594.                         }
  1595.                 }
  1596.             }
  1597.  
  1598.             //updated cart
  1599.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  1600.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1601.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1602.                 .ToList();
  1603.             var model = new ShoppingCartModel();
  1604.             PrepareShoppingCartModel(model, cart);
  1605.             //update current warnings
  1606.             foreach (var kvp in innerWarnings)
  1607.             {
  1608.                 //kvp = <cart item identifier, warnings>
  1609.                 var sciId = kvp.Key;
  1610.                 var warnings = kvp.Value;
  1611.                 //find model
  1612.                 var sciModel = model.Items.FirstOrDefault(x => x.Id == sciId);
  1613.                 if (sciModel != null)
  1614.                     foreach (var w in warnings)
  1615.                         if (!sciModel.Warnings.Contains(w))
  1616.                             sciModel.Warnings.Add(w);
  1617.             }
  1618.             return View(model);
  1619.         }
  1620.  
  1621.         //update a certain shopping cart item on the page
  1622.         [ValidateInput(false)]
  1623.         [HttpPost, ActionName("Cart")]
  1624.         [FormValueRequired(FormValueRequirement.StartsWith, "updatecartitem-")]
  1625.         public ActionResult UpdateCartItem(FormCollection form)
  1626.         {
  1627.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  1628.                 return RedirectToRoute("HomePage");
  1629.  
  1630.             //get shopping cart item identifier
  1631.             int sciId = 0;
  1632.             foreach (var formValue in form.AllKeys)
  1633.                 if (formValue.StartsWith("updatecartitem-", StringComparison.InvariantCultureIgnoreCase))
  1634.                     sciId = Convert.ToInt32(formValue.Substring("updatecartitem-".Length));
  1635.             //get shopping cart item
  1636.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1637.                 .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1638.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  1639.                 .ToList();
  1640.             var sci = cart.FirstOrDefault(x => x.Id == sciId);
  1641.             if (sci == null)
  1642.             {
  1643.                 return RedirectToRoute("ShoppingCart");
  1644.             }
  1645.  
  1646.             //update the cart item
  1647.             var warnings = new List<string>();
  1648.             foreach (string formKey in form.AllKeys)
  1649.                 if (formKey.Equals(string.Format("itemquantity{0}", sci.Id), StringComparison.InvariantCultureIgnoreCase))
  1650.                 {
  1651.                     int newQuantity = sci.Quantity;
  1652.                     if (int.TryParse(form[formKey], out newQuantity))
  1653.                     {
  1654.                         warnings.AddRange(_shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer,
  1655.                             sci.Id, newQuantity, true));
  1656.                     }
  1657.                     break;
  1658.                 }
  1659.                
  1660.  
  1661.             //updated cart
  1662.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  1663.                 .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1664.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  1665.                 .ToList();
  1666.             var model = new ShoppingCartModel();
  1667.             PrepareShoppingCartModel(model, cart);
  1668.             //update current warnings
  1669.             //find model
  1670.             var sciModel = model.Items.FirstOrDefault(x => x.Id == sciId);
  1671.             if (sciModel != null)
  1672.                 foreach (var w in warnings)
  1673.                     if (!sciModel.Warnings.Contains(w))
  1674.                         sciModel.Warnings.Add(w);
  1675.             return View(model);
  1676.         }
  1677.  
  1678.         //remove a certain shopping cart item on the page
  1679.         [ValidateInput(false)]
  1680.         [HttpPost, ActionName("Cart")]
  1681.         [FormValueRequired(FormValueRequirement.StartsWith, "removefromcart-")]
  1682.         public ActionResult RemoveCartItem(FormCollection form)
  1683.         {
  1684.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  1685.                 return RedirectToRoute("HomePage");
  1686.  
  1687.             //get shopping cart item identifier
  1688.             int sciId = 0;
  1689.             foreach (var formValue in form.AllKeys)
  1690.                 if (formValue.StartsWith("removefromcart-", StringComparison.InvariantCultureIgnoreCase))
  1691.                     sciId = Convert.ToInt32(formValue.Substring("removefromcart-".Length));
  1692.             //get shopping cart item
  1693.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1694.                 .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1695.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  1696.                 .ToList();
  1697.             var sci = cart.FirstOrDefault(x => x.Id == sciId);
  1698.             if (sci == null)
  1699.             {
  1700.                 return RedirectToRoute("ShoppingCart");
  1701.             }
  1702.  
  1703.             //remove the cart item
  1704.             _shoppingCartService.DeleteShoppingCartItem(sci, ensureOnlyActiveCheckoutAttributes: true);
  1705.  
  1706.  
  1707.             //updated cart
  1708.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  1709.                 .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1710.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  1711.                 .ToList();
  1712.             var model = new ShoppingCartModel();
  1713.             PrepareShoppingCartModel(model, cart);
  1714.             return View(model);
  1715.         }
  1716.  
  1717.         [ValidateInput(false)]
  1718.         [HttpPost, ActionName("Cart")]
  1719.         [FormValueRequired("continueshopping")]
  1720.         public ActionResult ContinueShopping()
  1721.         {
  1722.             string returnUrl = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.LastContinueShoppingPage, _storeContext.CurrentStore.Id);
  1723.             if (!String.IsNullOrEmpty(returnUrl))
  1724.             {
  1725.                 return Redirect(returnUrl);
  1726.             }
  1727.             else
  1728.             {
  1729.                 return RedirectToRoute("HomePage");
  1730.             }
  1731.         }
  1732.        
  1733.         [ValidateInput(false)]
  1734.         [HttpPost, ActionName("Cart")]
  1735.         [FormValueRequired("startcheckout")]
  1736.         public ActionResult StartCheckout(FormCollection form)
  1737.         {
  1738.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1739.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1740.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1741.                 .ToList();
  1742.  
  1743.             //parse and save checkout attributes
  1744.             ParseAndSaveCheckoutAttributes(cart, form);
  1745.  
  1746.             //validate attributes
  1747.             string checkoutAttributes = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService);
  1748.             var checkoutAttributeWarnings = _shoppingCartService.GetShoppingCartWarnings(cart, checkoutAttributes, true);
  1749.             if (checkoutAttributeWarnings.Count > 0)
  1750.             {
  1751.                 //something wrong, redisplay the page with warnings
  1752.                 var model = new ShoppingCartModel();
  1753.                 PrepareShoppingCartModel(model, cart, validateCheckoutAttributes: true);
  1754.                 return View(model);
  1755.             }
  1756.  
  1757.             //everything is OK
  1758.             if (_workContext.CurrentCustomer.IsGuest())
  1759.             {
  1760.                 if (_orderSettings.AnonymousCheckoutAllowed)
  1761.                 {
  1762.                     return RedirectToRoute("LoginCheckoutAsGuest", new {returnUrl = Url.RouteUrl("ShoppingCart")});
  1763.                 }
  1764.                 else
  1765.                 {
  1766.                     return new HttpUnauthorizedResult();
  1767.                 }
  1768.             }
  1769.             else
  1770.             {
  1771.                 return RedirectToRoute("Checkout");
  1772.             }
  1773.         }
  1774.  
  1775.         [ValidateInput(false)]
  1776.         [HttpPost, ActionName("Cart")]
  1777.         [FormValueRequired("applydiscountcouponcode")]
  1778.         public ActionResult ApplyDiscountCoupon(string discountcouponcode, FormCollection form)
  1779.         {
  1780.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1781.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1782.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1783.                 .ToList();
  1784.            
  1785.             //parse and save checkout attributes
  1786.             ParseAndSaveCheckoutAttributes(cart, form);
  1787.            
  1788.             var model = new ShoppingCartModel();
  1789.             if (!String.IsNullOrWhiteSpace(discountcouponcode))
  1790.             {
  1791.                 var discount = _discountService.GetDiscountByCouponCode(discountcouponcode);
  1792.                 bool isDiscountValid = discount != null &&
  1793.                     discount.RequiresCouponCode &&
  1794.                     _discountService.IsDiscountValid(discount, _workContext.CurrentCustomer, discountcouponcode);
  1795.                 if (isDiscountValid)
  1796.                 {
  1797.                     _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer,
  1798.                         SystemCustomerAttributeNames.DiscountCouponCode, discountcouponcode);
  1799.                     model.DiscountBox.Message = _localizationService.GetResource("ShoppingCart.DiscountCouponCode.Applied");
  1800.                 }
  1801.                 else
  1802.                 {
  1803.                     model.DiscountBox.Message = _localizationService.GetResource("ShoppingCart.DiscountCouponCode.WrongDiscount");
  1804.                 }
  1805.             }
  1806.             else
  1807.                 model.DiscountBox.Message = _localizationService.GetResource("ShoppingCart.DiscountCouponCode.WrongDiscount");
  1808.  
  1809.             PrepareShoppingCartModel(model, cart);
  1810.             return View(model);
  1811.         }
  1812.  
  1813.         [ValidateInput(false)]
  1814.         [HttpPost, ActionName("Cart")]
  1815.         [FormValueRequired("applygiftcardcouponcode")]
  1816.         public ActionResult ApplyGiftCard(string giftcardcouponcode, FormCollection form)
  1817.         {
  1818.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1819.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1820.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1821.                 .ToList();
  1822.  
  1823.             //parse and save checkout attributes
  1824.             ParseAndSaveCheckoutAttributes(cart, form);
  1825.            
  1826.             var model = new ShoppingCartModel();
  1827.             if (!cart.IsRecurring())
  1828.             {
  1829.                 if (!String.IsNullOrWhiteSpace(giftcardcouponcode))
  1830.                 {
  1831.                     var giftCard = _giftCardService.GetAllGiftCards(null, null,
  1832.                         null, null, giftcardcouponcode, 0, int.MaxValue).FirstOrDefault();
  1833.                     bool isGiftCardValid = giftCard != null && giftCard.IsGiftCardValid();
  1834.                     if (isGiftCardValid)
  1835.                     {
  1836.                         _workContext.CurrentCustomer.ApplyGiftCardCouponCode(giftcardcouponcode);
  1837.                         _customerService.UpdateCustomer(_workContext.CurrentCustomer);
  1838.                         model.GiftCardBox.Message = _localizationService.GetResource("ShoppingCart.GiftCardCouponCode.Applied");
  1839.                     }
  1840.                     else
  1841.                         model.GiftCardBox.Message = _localizationService.GetResource("ShoppingCart.GiftCardCouponCode.WrongGiftCard");
  1842.                 }
  1843.                 else
  1844.                     model.GiftCardBox.Message = _localizationService.GetResource("ShoppingCart.GiftCardCouponCode.WrongGiftCard");
  1845.             }
  1846.             else
  1847.                 model.GiftCardBox.Message = _localizationService.GetResource("ShoppingCart.GiftCardCouponCode.DontWorkWithAutoshipProducts");
  1848.  
  1849.             PrepareShoppingCartModel(model, cart);
  1850.             return View(model);
  1851.         }
  1852.        
  1853.         [ValidateInput(false)]
  1854.         [HttpPost, ActionName("Cart")]
  1855.         [FormValueRequired("estimateshipping")]
  1856.         public ActionResult GetEstimateShipping(EstimateShippingModel shippingModel, FormCollection form)
  1857.         {
  1858.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1859.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1860.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1861.                 .ToList();
  1862.            
  1863.             //parse and save checkout attributes
  1864.             ParseAndSaveCheckoutAttributes(cart, form);
  1865.            
  1866.             var model = new ShoppingCartModel();
  1867.             model.EstimateShipping.CountryId = shippingModel.CountryId;
  1868.             model.EstimateShipping.StateProvinceId = shippingModel.StateProvinceId;
  1869.             model.EstimateShipping.ZipPostalCode = shippingModel.ZipPostalCode;
  1870.             PrepareShoppingCartModel(model, cart,setEstimateShippingDefaultAddress: false);
  1871.  
  1872.             if (cart.RequiresShipping())
  1873.             {
  1874.                 var address = new Address()
  1875.                 {
  1876.                     CountryId = shippingModel.CountryId,
  1877.                     Country = shippingModel.CountryId.HasValue ? _countryService.GetCountryById(shippingModel.CountryId.Value) : null,
  1878.                     StateProvinceId  = shippingModel.StateProvinceId,
  1879.                     StateProvince = shippingModel.StateProvinceId.HasValue ? _stateProvinceService.GetStateProvinceById(shippingModel.StateProvinceId.Value) : null,
  1880.                     ZipPostalCode = shippingModel.ZipPostalCode,
  1881.                 };
  1882.                 GetShippingOptionResponse getShippingOptionResponse = _shippingService.GetShippingOptions(cart, address);
  1883.                 if (!getShippingOptionResponse.Success)
  1884.                 {
  1885.                     foreach (var error in getShippingOptionResponse.Errors)
  1886.                         model.EstimateShipping.Warnings.Add(error);
  1887.                 }
  1888.                 else
  1889.                 {
  1890.                     if (getShippingOptionResponse.ShippingOptions.Count > 0)
  1891.                     {
  1892.                         foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
  1893.                         {
  1894.                             var soModel = new EstimateShippingModel.ShippingOptionModel()
  1895.                             {
  1896.                                 Name = shippingOption.Name,
  1897.                                 Description = shippingOption.Description,
  1898.  
  1899.                             };
  1900.                             //calculate discounted and taxed rate
  1901.                             Discount appliedDiscount = null;
  1902.                             decimal shippingTotal = _orderTotalCalculationService.AdjustShippingRate(shippingOption.Rate,
  1903.                                 cart, out appliedDiscount);
  1904.  
  1905.                             decimal rateBase = _taxService.GetShippingPrice(shippingTotal, _workContext.CurrentCustomer);
  1906.                             decimal rate = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency);
  1907.                             soModel.Price = _priceFormatter.FormatShippingPrice(rate, true);
  1908.                             model.EstimateShipping.ShippingOptions.Add(soModel);
  1909.                         }
  1910.                     }
  1911.                     else
  1912.                     {
  1913.                        model.EstimateShipping.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
  1914.                     }
  1915.                 }
  1916.             }
  1917.  
  1918.             return View(model);
  1919.         }
  1920.  
  1921.         [ChildActionOnly]
  1922.         public ActionResult OrderTotals(bool isEditable)
  1923.         {
  1924.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  1925.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  1926.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  1927.                 .ToList();
  1928.             var model = new OrderTotalsModel();
  1929.             model.IsEditable = isEditable;
  1930.  
  1931.             if (cart.Count > 0)
  1932.             {
  1933.                 //subtotal
  1934.                 decimal subtotalBase = decimal.Zero;
  1935.                 decimal orderSubTotalDiscountAmountBase = decimal.Zero;
  1936.                 Discount orderSubTotalAppliedDiscount = null;
  1937.                 decimal subTotalWithoutDiscountBase = decimal.Zero;
  1938.                 decimal subTotalWithDiscountBase = decimal.Zero;
  1939.                 _orderTotalCalculationService.GetShoppingCartSubTotal(cart,
  1940.                     out orderSubTotalDiscountAmountBase, out orderSubTotalAppliedDiscount,
  1941.                     out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);
  1942.                 subtotalBase = subTotalWithoutDiscountBase;
  1943.                     decimal subtotal = _currencyService.ConvertFromPrimaryStoreCurrency(subtotalBase, _workContext.WorkingCurrency);
  1944.                     model.SubTotal = _priceFormatter.FormatPrice(subtotal);
  1945.                     if (orderSubTotalDiscountAmountBase > decimal.Zero)
  1946.                     {
  1947.                         decimal orderSubTotalDiscountAmount = _currencyService.ConvertFromPrimaryStoreCurrency(orderSubTotalDiscountAmountBase, _workContext.WorkingCurrency);
  1948.                         model.SubTotalDiscount = _priceFormatter.FormatPrice(-orderSubTotalDiscountAmount);
  1949.                         model.AllowRemovingSubTotalDiscount = orderSubTotalAppliedDiscount != null &&
  1950.                             orderSubTotalAppliedDiscount.RequiresCouponCode &&
  1951.                             !String.IsNullOrEmpty(orderSubTotalAppliedDiscount.CouponCode) &&
  1952.                             model.IsEditable;
  1953.                     }
  1954.                
  1955.  
  1956.                 //shipping info
  1957.                 model.RequiresShipping = cart.RequiresShipping();
  1958.                 if (model.RequiresShipping)
  1959.                 {
  1960.                     decimal? shoppingCartShippingBase = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart);
  1961.                     if (shoppingCartShippingBase.HasValue)
  1962.                     {
  1963.                         decimal shoppingCartShipping = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartShippingBase.Value, _workContext.WorkingCurrency);
  1964.                         model.Shipping = _priceFormatter.FormatShippingPrice(shoppingCartShipping, true);
  1965.  
  1966.                         //selected shipping method
  1967.                         var shippingOption = _workContext.CurrentCustomer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);
  1968.                         if (shippingOption != null)
  1969.                             model.SelectedShippingMethod = shippingOption.Name;
  1970.                     }
  1971.                 }
  1972.  
  1973.                 //payment method fee
  1974.                 string paymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute<string>(
  1975.                     SystemCustomerAttributeNames.SelectedPaymentMethod, _storeContext.CurrentStore.Id);
  1976.                 decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, paymentMethodSystemName);
  1977.                 decimal paymentMethodAdditionalFeeWithTaxBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer);
  1978.                 if (paymentMethodAdditionalFeeWithTaxBase > decimal.Zero)
  1979.                 {
  1980.                     decimal paymentMethodAdditionalFeeWithTax = _currencyService.ConvertFromPrimaryStoreCurrency(paymentMethodAdditionalFeeWithTaxBase, _workContext.WorkingCurrency);
  1981.                     model.PaymentMethodAdditionalFee = _priceFormatter.FormatPaymentMethodAdditionalFee(paymentMethodAdditionalFeeWithTax, true);
  1982.                 }
  1983.  
  1984.                 //tax
  1985.                 bool displayTax = true;
  1986.                 bool displayTaxRates = true;
  1987.                 if (_taxSettings.HideTaxInOrderSummary && _workContext.TaxDisplayType == TaxDisplayType.IncludingTax)
  1988.                 {
  1989.                     displayTax = false;
  1990.                     displayTaxRates = false;
  1991.                 }
  1992.                 else
  1993.                 {
  1994.                     SortedDictionary<decimal, decimal> taxRates = null;
  1995.                     decimal shoppingCartTaxBase = _orderTotalCalculationService.GetTaxTotal(cart, out taxRates);
  1996.                     decimal shoppingCartTax = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartTaxBase, _workContext.WorkingCurrency);
  1997.  
  1998.                         if (shoppingCartTaxBase == 0 && _taxSettings.HideZeroTax)
  1999.                         {
  2000.                             displayTax = false;
  2001.                             displayTaxRates = false;
  2002.                         }
  2003.                         else
  2004.                         {
  2005.                             displayTaxRates = _taxSettings.DisplayTaxRates && taxRates.Count > 0;
  2006.                             displayTax = !displayTaxRates;
  2007.  
  2008.                             model.Tax = _priceFormatter.FormatPrice(shoppingCartTax, true, false);
  2009.                             foreach (var tr in taxRates)
  2010.                             {
  2011.                                 model.TaxRates.Add(new OrderTotalsModel.TaxRate()
  2012.                                     {
  2013.                                         Rate = _priceFormatter.FormatTaxRate(tr.Key),
  2014.                                         Value = _priceFormatter.FormatPrice(_currencyService.ConvertFromPrimaryStoreCurrency(tr.Value, _workContext.WorkingCurrency), true, false),
  2015.                                     });
  2016.                             }
  2017.                         }
  2018.                 }
  2019.                 model.DisplayTaxRates = displayTaxRates;
  2020.                 model.DisplayTax = displayTax;
  2021.  
  2022.                 //total
  2023.                 decimal orderTotalDiscountAmountBase = decimal.Zero;
  2024.                 Discount orderTotalAppliedDiscount = null;
  2025.                 List<AppliedGiftCard> appliedGiftCards = null;
  2026.                 int redeemedRewardPoints = 0;
  2027.                 decimal redeemedRewardPointsAmount = decimal.Zero;
  2028.                 decimal? shoppingCartTotalBase = _orderTotalCalculationService.GetShoppingCartTotal(cart,
  2029.                     out orderTotalDiscountAmountBase, out orderTotalAppliedDiscount,
  2030.                     out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount);
  2031.                 if (shoppingCartTotalBase.HasValue)
  2032.                 {
  2033.                     decimal shoppingCartTotal = _currencyService.ConvertFromPrimaryStoreCurrency(shoppingCartTotalBase.Value, _workContext.WorkingCurrency);
  2034.                     model.OrderTotal = _priceFormatter.FormatPrice(shoppingCartTotal, true, false);
  2035.                 }
  2036.  
  2037.                 //discount
  2038.                 if (orderTotalDiscountAmountBase > decimal.Zero)
  2039.                 {
  2040.                     decimal orderTotalDiscountAmount = _currencyService.ConvertFromPrimaryStoreCurrency(orderTotalDiscountAmountBase, _workContext.WorkingCurrency);
  2041.                     model.OrderTotalDiscount = _priceFormatter.FormatPrice(-orderTotalDiscountAmount, true, false);
  2042.                     model.AllowRemovingOrderTotalDiscount = orderTotalAppliedDiscount != null &&
  2043.                         orderTotalAppliedDiscount.RequiresCouponCode &&
  2044.                         !String.IsNullOrEmpty(orderTotalAppliedDiscount.CouponCode) &&
  2045.                         model.IsEditable;
  2046.                 }
  2047.  
  2048.                 //gift cards
  2049.                 if (appliedGiftCards != null && appliedGiftCards.Count > 0)
  2050.                 {
  2051.                     foreach (var appliedGiftCard in appliedGiftCards)
  2052.                     {
  2053.                         var gcModel = new OrderTotalsModel.GiftCard()
  2054.                             {
  2055.                                 Id = appliedGiftCard.GiftCard.Id,
  2056.                                 CouponCode =  appliedGiftCard.GiftCard.GiftCardCouponCode,
  2057.                             };
  2058.                         decimal amountCanBeUsed = _currencyService.ConvertFromPrimaryStoreCurrency(appliedGiftCard.AmountCanBeUsed, _workContext.WorkingCurrency);
  2059.                         gcModel.Amount = _priceFormatter.FormatPrice(-amountCanBeUsed, true, false);
  2060.  
  2061.                         decimal remainingAmountBase = appliedGiftCard.GiftCard.GetGiftCardRemainingAmount() - appliedGiftCard.AmountCanBeUsed;
  2062.                         decimal remainingAmount = _currencyService.ConvertFromPrimaryStoreCurrency(remainingAmountBase, _workContext.WorkingCurrency);
  2063.                         gcModel.Remaining = _priceFormatter.FormatPrice(remainingAmount, true, false);
  2064.                        
  2065.                         model.GiftCards.Add(gcModel);
  2066.                     }
  2067.                 }
  2068.  
  2069.                 //reward points
  2070.                 if (redeemedRewardPointsAmount > decimal.Zero)
  2071.                 {
  2072.                     decimal redeemedRewardPointsAmountInCustomerCurrency = _currencyService.ConvertFromPrimaryStoreCurrency(redeemedRewardPointsAmount, _workContext.WorkingCurrency);
  2073.                     model.RedeemedRewardPoints = redeemedRewardPoints;
  2074.                     model.RedeemedRewardPointsAmount = _priceFormatter.FormatPrice(-redeemedRewardPointsAmountInCustomerCurrency, true, false);
  2075.                 }
  2076.             }
  2077.  
  2078.  
  2079.             return PartialView(model);
  2080.         }
  2081.  
  2082.         [ValidateInput(false)]
  2083.         [HttpPost, ActionName("Cart")]
  2084.         [FormValueRequired("removesubtotaldiscount", "removeordertotaldiscount", "removediscountcouponcode")]
  2085.         public ActionResult RemoveDiscountCoupon()
  2086.         {
  2087.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2088.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  2089.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2090.                 .ToList();
  2091.             var model = new ShoppingCartModel();
  2092.  
  2093.             _genericAttributeService.SaveAttribute<string>(_workContext.CurrentCustomer,
  2094.                 SystemCustomerAttributeNames.DiscountCouponCode, null);
  2095.  
  2096.             PrepareShoppingCartModel(model, cart);
  2097.             return View(model);
  2098.         }
  2099.  
  2100.         [ValidateInput(false)]
  2101.         [HttpPost, ActionName("Cart")]
  2102.         [FormValueRequired("removegiftcard")]
  2103.         public ActionResult RemoveGiftardCode(int giftCardId)
  2104.         {
  2105.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2106.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  2107.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2108.                 .ToList();
  2109.             var model = new ShoppingCartModel();
  2110.  
  2111.             var gc = _giftCardService.GetGiftCardById(giftCardId);
  2112.             if (gc != null)
  2113.             {
  2114.                 _workContext.CurrentCustomer.RemoveGiftCardCouponCode(gc.GiftCardCouponCode);
  2115.                 _customerService.UpdateCustomer(_workContext.CurrentCustomer);
  2116.             }
  2117.  
  2118.             PrepareShoppingCartModel(model, cart);
  2119.             return View(model);
  2120.         }
  2121.  
  2122.         [ChildActionOnly]
  2123.         public ActionResult FlyoutShoppingCart()
  2124.         {
  2125.             if (!_shoppingCartSettings.MiniShoppingCartEnabled)
  2126.                 return Content("");
  2127.  
  2128.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  2129.                 return Content("");
  2130.  
  2131.             var model = PrepareMiniShoppingCartModel();
  2132.             return PartialView(model);
  2133.         }
  2134.  
  2135.         #endregion
  2136.  
  2137.         #region Wishlist
  2138.  
  2139.         [NopHttpsRequirement(SslRequirement.Yes)]
  2140.         public ActionResult Wishlist(Guid? customerGuid)
  2141.         {
  2142.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2143.                 return RedirectToRoute("HomePage");
  2144.  
  2145.             Customer customer = customerGuid.HasValue ?
  2146.                 _customerService.GetCustomerByGuid(customerGuid.Value)
  2147.                 : _workContext.CurrentCustomer;
  2148.             if (customer == null)
  2149.                 return RedirectToRoute("HomePage");
  2150.             var cart = customer.ShoppingCartItems
  2151.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2152.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2153.                 .ToList();
  2154.             var model = new WishlistModel();
  2155.             PrepareWishlistModel(model, cart, !customerGuid.HasValue);
  2156.             return View(model);
  2157.         }
  2158.  
  2159.         //update all wishlist cart items on the page
  2160.         [ValidateInput(false)]
  2161.         [HttpPost, ActionName("Wishlist")]
  2162.         [FormValueRequired("updatecart")]
  2163.         public ActionResult UpdateWishlistAll(FormCollection form)
  2164.         {
  2165.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2166.                 return RedirectToRoute("HomePage");
  2167.  
  2168.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2169.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2170.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2171.                 .ToList();
  2172.  
  2173.             var allIdsToRemove = form["removefromcart"] != null ? form["removefromcart"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList() : new List<int>();
  2174.  
  2175.             //current warnings <cart item identifier, warnings>
  2176.             var innerWarnings = new Dictionary<int, IList<string>>();
  2177.             foreach (var sci in cart)
  2178.             {
  2179.                 bool remove = allIdsToRemove.Contains(sci.Id);
  2180.                 if (remove)
  2181.                     _shoppingCartService.DeleteShoppingCartItem(sci);
  2182.                 else
  2183.                 {
  2184.                     foreach (string formKey in form.AllKeys)
  2185.                         if (formKey.Equals(string.Format("itemquantity{0}", sci.Id), StringComparison.InvariantCultureIgnoreCase))
  2186.                         {
  2187.                             int newQuantity = sci.Quantity;
  2188.                             if (int.TryParse(form[formKey], out newQuantity))
  2189.                             {
  2190.                                 var currSciWarnings = _shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer,
  2191.                                     sci.Id, newQuantity, true);
  2192.                                 innerWarnings.Add(sci.Id, currSciWarnings);
  2193.                             }
  2194.                             break;
  2195.                         }
  2196.                 }
  2197.             }
  2198.  
  2199.             //updated wishlist
  2200.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  2201.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2202.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2203.                 .ToList();
  2204.             var model = new WishlistModel();
  2205.             PrepareWishlistModel(model, cart);
  2206.             //update current warnings
  2207.             foreach (var kvp in innerWarnings)
  2208.             {
  2209.                 //kvp = <cart item identifier, warnings>
  2210.                 var sciId = kvp.Key;
  2211.                 var warnings = kvp.Value;
  2212.                 //find model
  2213.                 var sciModel = model.Items.FirstOrDefault(x => x.Id == sciId);
  2214.                 if (sciModel != null)
  2215.                     foreach (var w in warnings)
  2216.                         if (!sciModel.Warnings.Contains(w))
  2217.                             sciModel.Warnings.Add(w);
  2218.             }
  2219.             return View(model);
  2220.         }
  2221.  
  2222.         //update a certain wishlist cart item on the page
  2223.         [ValidateInput(false)]
  2224.         [HttpPost, ActionName("Wishlist")]
  2225.         [FormValueRequired(FormValueRequirement.StartsWith, "updatecartitem-")]
  2226.         public ActionResult UpdateWishlistItem(FormCollection form)
  2227.         {
  2228.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2229.                 return RedirectToRoute("HomePage");
  2230.  
  2231.             //get wishlist cart item identifier
  2232.             int sciId = 0;
  2233.             foreach (var formValue in form.AllKeys)
  2234.                 if (formValue.StartsWith("updatecartitem-", StringComparison.InvariantCultureIgnoreCase))
  2235.                     sciId = Convert.ToInt32(formValue.Substring("updatecartitem-".Length));
  2236.             //get shopping cart item
  2237.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2238.                 .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2239.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2240.                 .ToList();
  2241.             var sci = cart.FirstOrDefault(x => x.Id == sciId);
  2242.             if (sci == null)
  2243.             {
  2244.                 return RedirectToRoute("Wishlist");
  2245.             }
  2246.  
  2247.             //update the wishlist cart item
  2248.             var warnings = new List<string>();
  2249.             foreach (string formKey in form.AllKeys)
  2250.                 if (formKey.Equals(string.Format("itemquantity{0}", sci.Id), StringComparison.InvariantCultureIgnoreCase))
  2251.                 {
  2252.                     int newQuantity = sci.Quantity;
  2253.                     if (int.TryParse(form[formKey], out newQuantity))
  2254.                     {
  2255.                         warnings.AddRange(_shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer,
  2256.                             sci.Id, newQuantity, true));
  2257.                     }
  2258.                     break;
  2259.                 }
  2260.  
  2261.  
  2262.             //updated wishlist
  2263.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  2264.                 .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2265.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2266.                 .ToList();
  2267.             var model = new WishlistModel();
  2268.             PrepareWishlistModel(model, cart);
  2269.             //update current warnings
  2270.             //find model
  2271.             var sciModel = model.Items.FirstOrDefault(x => x.Id == sciId);
  2272.             if (sciModel != null)
  2273.                 foreach (var w in warnings)
  2274.                     if (!sciModel.Warnings.Contains(w))
  2275.                         sciModel.Warnings.Add(w);
  2276.             return View(model);
  2277.         }
  2278.  
  2279.         //remove a certain wishlist cart item on the page
  2280.         [ValidateInput(false)]
  2281.         [HttpPost, ActionName("Wishlist")]
  2282.         [FormValueRequired(FormValueRequirement.StartsWith, "removefromcart-")]
  2283.         public ActionResult RemoveWishlistItem(FormCollection form)
  2284.         {
  2285.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2286.                 return RedirectToRoute("HomePage");
  2287.  
  2288.             //get wishlist cart item identifier
  2289.             int sciId = 0;
  2290.             foreach (var formValue in form.AllKeys)
  2291.                 if (formValue.StartsWith("removefromcart-", StringComparison.InvariantCultureIgnoreCase))
  2292.                     sciId = Convert.ToInt32(formValue.Substring("removefromcart-".Length));
  2293.             //get wishlist cart item
  2294.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2295.                 .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2296.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2297.                 .ToList();
  2298.             var sci = cart.FirstOrDefault(x => x.Id == sciId);
  2299.             if (sci == null)
  2300.             {
  2301.                 return RedirectToRoute("Wishlist");
  2302.             }
  2303.  
  2304.             //remove the wishlist cart item
  2305.             _shoppingCartService.DeleteShoppingCartItem(sci);
  2306.  
  2307.  
  2308.             //updated wishlist
  2309.             cart = _workContext.CurrentCustomer.ShoppingCartItems
  2310.                 .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2311.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2312.                 .ToList();
  2313.             var model = new WishlistModel();
  2314.             PrepareWishlistModel(model, cart);
  2315.             return View(model);
  2316.         }
  2317.  
  2318.         [ValidateInput(false)]
  2319.         [HttpPost, ActionName("Wishlist")]
  2320.         [FormValueRequired("addtocartbutton")]
  2321.         public ActionResult AddItemstoCartFromWishlist(Guid? customerGuid, FormCollection form)
  2322.         {
  2323.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  2324.                 return RedirectToRoute("HomePage");
  2325.  
  2326.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2327.                 return RedirectToRoute("HomePage");
  2328.  
  2329.             var pageCustomer = customerGuid.HasValue
  2330.                 ? _customerService.GetCustomerByGuid(customerGuid.Value)
  2331.                 : _workContext.CurrentCustomer;
  2332.             if (pageCustomer == null)
  2333.                 return RedirectToRoute("HomePage");
  2334.  
  2335.             var pageCart = pageCustomer.ShoppingCartItems
  2336.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2337.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2338.                 .ToList();
  2339.  
  2340.             var allWarnings = new List<string>();
  2341.             var numberOfAddedItems = 0;
  2342.             var allIdsToAdd = form["addtocart"] != null ? form["addtocart"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList() : new List<int>();
  2343.             foreach (var sci in pageCart)
  2344.             {
  2345.                 if (allIdsToAdd.Contains(sci.Id))
  2346.                 {
  2347.                     var warnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
  2348.                         sci.ProductVariant, ShoppingCartType.ShoppingCart,
  2349.                         _storeContext.CurrentStore.Id,
  2350.                         sci.AttributesXml, sci.CustomerEnteredPrice, sci.Quantity, true);
  2351.                     if (warnings.Count == 0)
  2352.                         numberOfAddedItems++;
  2353.                     if (_shoppingCartSettings.MoveItemsFromWishlistToCart && //settings enabled
  2354.                         !customerGuid.HasValue && //own wishlist
  2355.                         warnings.Count == 0) //no warnings ( already in the cart)
  2356.                     {
  2357.                         //let's remove the item from wishlist
  2358.                         _shoppingCartService.DeleteShoppingCartItem(sci);
  2359.                     }
  2360.                     allWarnings.AddRange(warnings);
  2361.                 }
  2362.             }
  2363.  
  2364.             if (numberOfAddedItems > 0)
  2365.             {
  2366.                 //redirect to the shopping cart page
  2367.                 return RedirectToRoute("ShoppingCart");
  2368.             }
  2369.             else
  2370.             {
  2371.                 //no items added. redisplay the wishlist page
  2372.                 var cart = pageCustomer.ShoppingCartItems
  2373.                     .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2374.                     .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2375.                     .ToList();
  2376.                 var model = new WishlistModel();
  2377.                 PrepareWishlistModel(model, cart, !customerGuid.HasValue);
  2378.                 return View(model);
  2379.             }
  2380.         }
  2381.  
  2382.         //add a certain wishlist cart item on the page to the shopping cart
  2383.         [ValidateInput(false)]
  2384.         [HttpPost, ActionName("Wishlist")]
  2385.         [FormValueRequired(FormValueRequirement.StartsWith, "addtocart-")]
  2386.         public ActionResult AddOneItemtoCartFromWishlist(Guid? customerGuid, FormCollection form)
  2387.         {
  2388.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableShoppingCart))
  2389.                 return RedirectToRoute("HomePage");
  2390.  
  2391.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist))
  2392.                 return RedirectToRoute("HomePage");
  2393.  
  2394.             //get wishlist cart item identifier
  2395.             int sciId = 0;
  2396.             foreach (var formValue in form.AllKeys)
  2397.                 if (formValue.StartsWith("addtocart-", StringComparison.InvariantCultureIgnoreCase))
  2398.                     sciId = Convert.ToInt32(formValue.Substring("addtocart-".Length));
  2399.             //get wishlist cart item
  2400.             var pageCustomer = customerGuid.HasValue
  2401.                 ? _customerService.GetCustomerByGuid(customerGuid.Value)
  2402.                 : _workContext.CurrentCustomer;
  2403.             if (pageCustomer == null)
  2404.                 return RedirectToRoute("HomePage");
  2405.  
  2406.             var pageCart = pageCustomer.ShoppingCartItems
  2407.                 .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2408.                 .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2409.                 .ToList();
  2410.  
  2411.             var sci = pageCart.FirstOrDefault(x => x.Id == sciId);
  2412.             if (sci == null)
  2413.             {
  2414.                 return RedirectToRoute("Wishlist");
  2415.             }
  2416.             var warnings = _shoppingCartService.AddToCart(_workContext.CurrentCustomer,
  2417.                                            sci.ProductVariant, ShoppingCartType.ShoppingCart,
  2418.                                            _storeContext.CurrentStore.Id,
  2419.                                            sci.AttributesXml, sci.CustomerEnteredPrice, sci.Quantity, true);
  2420.             if (_shoppingCartSettings.MoveItemsFromWishlistToCart && //settings enabled
  2421.                         !customerGuid.HasValue && //own wishlist
  2422.                         warnings.Count == 0) //no warnings ( already in the cart)
  2423.             {
  2424.                 //let's remove the item from wishlist
  2425.                 _shoppingCartService.DeleteShoppingCartItem(sci);
  2426.             }
  2427.  
  2428.             if (warnings.Count == 0)
  2429.             {
  2430.                 //redirect to the shopping cart page
  2431.                 return RedirectToRoute("ShoppingCart");
  2432.             }
  2433.             else
  2434.             {
  2435.                 //no items added. redisplay the wishlist page
  2436.                 var cart = pageCustomer.ShoppingCartItems
  2437.                     .Where(x => x.ShoppingCartType == ShoppingCartType.Wishlist)
  2438.                     .Where(x => x.StoreId == _storeContext.CurrentStore.Id)
  2439.                     .ToList();
  2440.                 var model = new WishlistModel();
  2441.                 PrepareWishlistModel(model, cart, !customerGuid.HasValue);
  2442.                 return View(model);
  2443.             }
  2444.         }
  2445.  
  2446.         [NopHttpsRequirement(SslRequirement.Yes)]
  2447.         public ActionResult EmailWishlist()
  2448.         {
  2449.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !_shoppingCartSettings.EmailWishlistEnabled)
  2450.                 return RedirectToRoute("HomePage");
  2451.  
  2452.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2453.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2454.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2455.                 .ToList();
  2456.  
  2457.             if (cart.Count == 0)
  2458.                 return RedirectToRoute("HomePage");
  2459.  
  2460.             var model = new WishlistEmailAFriendModel()
  2461.             {
  2462.                 YourEmailAddress = _workContext.CurrentCustomer.Email,
  2463.                 DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnEmailWishlistToFriendPage
  2464.             };
  2465.             return View(model);
  2466.         }
  2467.  
  2468.         [HttpPost, ActionName("EmailWishlist")]
  2469.         [FormValueRequired("send-email")]
  2470.         [CaptchaValidator]
  2471.         public ActionResult EmailWishlistSend(WishlistEmailAFriendModel model, bool captchaValid)
  2472.         {
  2473.             if (!_permissionService.Authorize(StandardPermissionProvider.EnableWishlist) || !_shoppingCartSettings.EmailWishlistEnabled)
  2474.                 return RedirectToRoute("HomePage");
  2475.  
  2476.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2477.                 .Where(sci => sci.ShoppingCartType == ShoppingCartType.Wishlist)
  2478.                 .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2479.                 .ToList();
  2480.             if (cart.Count == 0)
  2481.                 return RedirectToRoute("HomePage");
  2482.  
  2483.             //validate CAPTCHA
  2484.             if (_captchaSettings.Enabled && _captchaSettings.ShowOnEmailWishlistToFriendPage && !captchaValid)
  2485.             {
  2486.                 ModelState.AddModelError("", _localizationService.GetResource("Common.WrongCaptcha"));
  2487.             }
  2488.  
  2489.             //check whether the current customer is guest and ia allowed to email wishlist
  2490.             if (_workContext.CurrentCustomer.IsGuest() && !_shoppingCartSettings.AllowAnonymousUsersToEmailWishlist)
  2491.             {
  2492.                 ModelState.AddModelError("", _localizationService.GetResource("Wishlist.EmailAFriend.OnlyRegisteredUsers"));
  2493.             }
  2494.  
  2495.             if (ModelState.IsValid)
  2496.             {
  2497.                 //email
  2498.                 _workflowMessageService.SendWishlistEmailAFriendMessage(_workContext.CurrentCustomer,
  2499.                         _workContext.WorkingLanguage.Id, model.YourEmailAddress,
  2500.                         model.FriendEmail, Core.Html.HtmlHelper.FormatText(model.PersonalMessage, false, true, false, false, false, false));
  2501.  
  2502.                 model.SuccessfullySent = true;
  2503.                 model.Result = _localizationService.GetResource("Wishlist.EmailAFriend.SuccessfullySent");
  2504.  
  2505.                 return View(model);
  2506.             }
  2507.  
  2508.             //If we got this far, something failed, redisplay form
  2509.             model.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnEmailWishlistToFriendPage;
  2510.             return View(model);
  2511.         }
  2512.  
  2513.         #endregion
  2514.  
  2515.         #region Punch-out interface
  2516.  
  2517.         [HttpPost]
  2518.         public ActionResult PunchOut(string documentId)
  2519.         {
  2520.             Extensions.PunchOut punchOut = new Extensions.PunchOut(_logger);
  2521.  
  2522.             // Get a ticket for the edit of an existing document
  2523.  
  2524.             string ticketId = punchOut.EditPunchOutReference(documentId, Url, Request);
  2525.  
  2526.             // Create an instance of the punchout module
  2527.  
  2528.             string url = punchOut.CreatePunchOutUrl(ticketId);
  2529.  
  2530.             var js = Json(new
  2531.             {
  2532.                 redirect = url
  2533.             });
  2534.  
  2535.             return js;
  2536.         }
  2537.  
  2538.         public ActionResult PunchOutBasket(string docId)
  2539.         {
  2540.             // save the doc id - put into last item in the basket
  2541.             // save the reference from punch out into a custom attribute
  2542.             // which is saved in the basket item
  2543.  
  2544.             // get the cart
  2545.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2546.                 .Where(x => x.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();
  2547.  
  2548.             if (cart.Count > 0)
  2549.             {
  2550.                 int punchOutDocumentId;
  2551.                 Int32.TryParse(ConfigurationManager.AppSettings["PunchOutDocumentId"], out punchOutDocumentId);
  2552.                        
  2553.                 var item = FindItemFromDocumentId(docId,cart,punchOutDocumentId);
  2554.  
  2555.                 if (item == null)
  2556.                 {
  2557.                     // this wasn't an existing document so the new document id needs stamping on the last item
  2558.                     item = cart.Last();
  2559.  
  2560.                     if (docId != null)
  2561.                     {
  2562.                         var attribute = new ProductVariantAttribute();
  2563.                         attribute.Id = punchOutDocumentId;
  2564.  
  2565.                         // add this to the product attributes
  2566.                         item.AttributesXml = _productAttributeParser.AddProductAttribute(item.AttributesXml, attribute, docId);
  2567.  
  2568.                         _shoppingCartService.UpdateShoppingCartItemAttributes(_workContext.CurrentCustomer, item.Id, item.AttributesXml);
  2569.                     }
  2570.                     else
  2571.                     {
  2572.                         // The user quit punch out without saving
  2573.                         _shoppingCartService.DeleteShoppingCartItem(item);
  2574.                     }
  2575.                 }
  2576.                 //Response.Redirect(Url.RouteUrl("ShoppingCart"));
  2577.             }
  2578.  
  2579.             return View();
  2580.         }
  2581.  
  2582.         private ShoppingCartItem FindItemFromDocumentId(string documentId,IEnumerable<ShoppingCartItem> cart,int attributeId)
  2583.         {
  2584.             ShoppingCartItem r = null;
  2585.  
  2586.             if (cart != null && documentId != null)
  2587.             {
  2588.                 foreach (var item in cart)
  2589.                 {
  2590.                     if (!string.IsNullOrEmpty(item.AttributesXml))
  2591.                     {
  2592.                         var document = System.Xml.Linq.XDocument.Parse(item.AttributesXml);
  2593.  
  2594.                         var attribute= document.Element("Attributes").Elements("ProductVariantAttribute").Where(e =>e.Attribute("ID")!=null && e.Attribute("ID").Value == attributeId.ToString()).FirstOrDefault();
  2595.  
  2596.                         if (attribute != null)
  2597.                         {
  2598.                             var value = attribute.Descendants("Value").FirstOrDefault();
  2599.  
  2600.                             if (value != null && value.Value.ToLower() == documentId.ToLower())
  2601.                             {
  2602.                                 return item;
  2603.                             }
  2604.                         }
  2605.                     }
  2606.                 }
  2607.             }
  2608.  
  2609.             return r;
  2610.         }
  2611.  
  2612.         #endregion
  2613.  
  2614.         public ActionResult AgentOrderSummary()
  2615.         {
  2616.             var cart = _workContext.CurrentCustomer.ShoppingCartItems
  2617.                    .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
  2618.                    .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
  2619.                    .ToList();
  2620.  
  2621.             var model = new ShoppingCartModel();
  2622.             PrepareShoppingCartModel(model, cart,
  2623.                 isEditable: false,
  2624.                 prepareEstimateShippingIfEnabled: false
  2625.                 );
  2626.  
  2627.            
  2628.             return PartialView(model);
  2629.         }
  2630.     }
  2631. }
Advertisement
Add Comment
Please, Sign In to add comment