private async Task PreparePickupPoints(CheckoutShippingAddressModel model, GetShippingAddress request)
        {
            var pickupPoints = await _shippingService.LoadActivePickupPoints(request.Store.Id);

            if (pickupPoints.Any())
            {
                foreach (var pickupPoint in pickupPoints)
                {
                    var pickupPointModel = new CheckoutPickupPointModel()
                    {
                        Id          = pickupPoint.Id,
                        Name        = pickupPoint.Name,
                        Description = pickupPoint.Description,
                        Address     = pickupPoint.Address,
                    };
                    if (pickupPoint.PickupFee > 0)
                    {
                        var amount = (await _taxService.GetShippingPrice(pickupPoint.PickupFee, request.Customer)).shippingPrice;
                        amount = await _currencyService.ConvertFromPrimaryStoreCurrency(amount, request.Currency);

                        pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(amount, true);
                    }
                    model.PickupPoints.Add(pickupPointModel);
                }
            }

            if (!(await _shippingService.LoadActiveShippingRateComputationMethods(request.Store.Id)).Any())
            {
                if (!pickupPoints.Any())
                {
                    model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                    model.Warnings.Add(_localizationService.GetResource("Checkout.PickupPoints.NotAvailable"));
                }
                model.PickUpInStoreOnly = true;
                model.PickUpInStore     = true;
            }
        }
        /// <summary>
        /// Prepare shipping address model
        /// </summary>
        /// <param name="selectedCountryId">Selected country identifier</param>
        /// <param name="prePopulateNewAddressWithCustomerFields">Pre populate new address with customer fields</param>
        /// <param name="overrideAttributesXml">Override attributes xml</param>
        /// <returns>Shipping address model</returns>
        public virtual CheckoutShippingAddressModel PrepareShippingAddressModel(int?selectedCountryId = null,
                                                                                bool prePopulateNewAddressWithCustomerFields = false, string overrideAttributesXml = "")
        {
            var model = new CheckoutShippingAddressModel();

            //allow pickup in store?
            model.AllowPickUpInStore = _shippingSettings.AllowPickUpInStore;
            if (model.AllowPickUpInStore)
            {
                model.DisplayPickupPointsOnMap = _shippingSettings.DisplayPickupPointsOnMap;
                model.GoogleMapsApiKey         = _shippingSettings.GoogleMapsApiKey;
                var pickupPointProviders = _shippingService.LoadActivePickupPointProviders(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id);
                if (pickupPointProviders.Any())
                {
                    var pickupPointsResponse = _shippingService.GetPickupPoints(_workContext.CurrentCustomer.BillingAddress,
                                                                                _workContext.CurrentCustomer, storeId: _storeContext.CurrentStore.Id);
                    if (pickupPointsResponse.Success)
                    {
                        model.PickupPoints = pickupPointsResponse.PickupPoints.Select(x =>
                        {
                            var country          = _countryService.GetCountryByTwoLetterIsoCode(x.CountryCode);
                            var state            = _stateProvinceService.GetStateProvinceByAbbreviation(x.StateAbbreviation);
                            var pickupPointModel = new CheckoutPickupPointModel
                            {
                                Id                 = x.Id,
                                Name               = x.Name,
                                Description        = x.Description,
                                ProviderSystemName = x.ProviderSystemName,
                                Address            = x.Address,
                                City               = x.City,
                                StateName          = state != null ? state.Name : string.Empty,
                                CountryName        = country != null ? country.Name : string.Empty,
                                ZipPostalCode      = x.ZipPostalCode,
                                Latitude           = x.Latitude,
                                Longitude          = x.Longitude,
                                OpeningHours       = x.OpeningHours
                            };
                            if (x.PickupFee > 0)
                            {
                                var amount = _taxService.GetShippingPrice(x.PickupFee, _workContext.CurrentCustomer);
                                amount     = _currencyService.ConvertFromPrimaryStoreCurrency(amount, _workContext.WorkingCurrency);
                                pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(amount, true);
                            }

                            return(pickupPointModel);
                        }).ToList();
                    }
                    else
                    {
                        foreach (var error in pickupPointsResponse.Errors)
                        {
                            model.Warnings.Add(error);
                        }
                    }
                }

                //only available pickup points
                if (!_shippingService.LoadActiveShippingRateComputationMethods(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id).Any())
                {
                    if (!pickupPointProviders.Any())
                    {
                        model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                        model.Warnings.Add(_localizationService.GetResource("Checkout.PickupPoints.NotAvailable"));
                    }
                    model.PickUpInStoreOnly = true;
                    model.PickUpInStore     = true;
                    return(model);
                }
            }

            //existing addresses
            var addresses = _workContext.CurrentCustomer.Addresses
                            .Where(a => a.Country == null ||
                                   (//published
                                       a.Country.Published &&
                                       //allow shipping
                                       a.Country.AllowsShipping &&
                                       //enabled for the current store
                                       _storeMappingService.Authorize(a.Country)))
                            .ToList();

            foreach (var address in addresses)
            {
                var addressModel = new AddressModel();
                _addressModelFactory.PrepareAddressModel(addressModel,
                                                         address: address,
                                                         excludeProperties: false,
                                                         addressSettings: _addressSettings);
                model.ExistingAddresses.Add(addressModel);
            }

            //new address
            model.NewAddress.CountryId = selectedCountryId;
            _addressModelFactory.PrepareAddressModel(model.NewAddress,
                                                     address: null,
                                                     excludeProperties: false,
                                                     addressSettings: _addressSettings,
                                                     loadCountries: () => _countryService.GetAllCountriesForShipping(_workContext.WorkingLanguage.Id),
                                                     prePopulateWithCustomerFields: prePopulateNewAddressWithCustomerFields,
                                                     customer: _workContext.CurrentCustomer,
                                                     overrideAttributesXml: overrideAttributesXml);

            return(model);
        }
        public async Task <CheckoutShippingMethodModel> Handle(GetShippingMethod request, CancellationToken cancellationToken)
        {
            var model = new CheckoutShippingMethodModel();

            var getShippingOptionResponse = await _shippingService
                                            .GetShippingOptions(request.Customer, request.Cart, request.ShippingAddress,
                                                                "", request.Store);

            if (getShippingOptionResponse.Success)
            {
                //performance optimization. cache returned shipping options.
                //we'll use them later (after a customer has selected an option).
                await _genericAttributeService.SaveAttribute(request.Customer,
                                                             SystemCustomerAttributeNames.OfferedShippingOptions,
                                                             getShippingOptionResponse.ShippingOptions,
                                                             request.Store.Id);

                foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                {
                    var soModel = new CheckoutShippingMethodModel.ShippingMethodModel {
                        Name        = shippingOption.Name,
                        Description = shippingOption.Description,
                        ShippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName,
                        ShippingOption = shippingOption,
                    };

                    //adjust rate
                    var shippingTotal = (await _orderTotalCalculationService.AdjustShippingRate(
                                             shippingOption.Rate, request.Cart)).shippingRate;

                    decimal rateBase = (await _taxService.GetShippingPrice(shippingTotal, request.Customer)).shippingPrice;
                    decimal rate     = await _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, request.Currency);

                    soModel.Fee = _priceFormatter.FormatShippingPrice(rate, true);

                    model.ShippingMethods.Add(soModel);
                }

                //find a selected (previously) shipping method
                var selectedShippingOption = request.Customer.GetAttributeFromEntity <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, request.Store.Id);
                if (selectedShippingOption != null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.ToList()
                                                 .Find(so =>
                                                       !String.IsNullOrEmpty(so.Name) &&
                                                       so.Name.Equals(selectedShippingOption.Name, StringComparison.OrdinalIgnoreCase) &&
                                                       !String.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName) &&
                                                       so.ShippingRateComputationMethodSystemName.Equals(selectedShippingOption.ShippingRateComputationMethodSystemName, StringComparison.OrdinalIgnoreCase));
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }
                //if no option has been selected, let's do it for the first one
                if (model.ShippingMethods.FirstOrDefault(so => so.Selected) == null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.FirstOrDefault();
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }

                //notify about shipping from multiple locations
                if (_shippingSettings.NotifyCustomerAboutShippingFromMultipleLocations)
                {
                    model.NotifyCustomerAboutShippingFromMultipleLocations = getShippingOptionResponse.ShippingFromMultipleLocations;
                }
            }
            else
            {
                foreach (var error in getShippingOptionResponse.Errors)
                {
                    model.Warnings.Add(error);
                }
            }

            return(model);
        }
        /// <summary>
        /// Post cart to google
        /// </summary>
        /// <param name="req">Pre-generated request</param>
        /// <param name="cart">Shopping cart</param>
        /// <returns>Response</returns>
        public GCheckoutResponse PostCartToGoogle(CheckoutShoppingCartRequest req,
                                                  IList <Core.Domain.Orders.ShoppingCartItem> cart)
        {
            //there's no need to round prices (Math.Round(,2)) because GCheckout library does it for us
            //items
            foreach (Core.Domain.Orders.ShoppingCartItem sci in cart)
            {
                var productVariant = sci.ProductVariant;
                if (productVariant != null)
                {
                    decimal taxRate     = decimal.Zero;
                    string  description = _productAttributeFormatter.FormatAttributes(productVariant, sci.AttributesXml, _workContext.CurrentCustomer, ", ", false);
                    string  fullName    = "";
                    if (!String.IsNullOrEmpty(sci.ProductVariant.GetLocalized(x => x.Name)))
                    {
                        fullName = string.Format("{0} ({1})", sci.ProductVariant.Product.GetLocalized(x => x.Name), sci.ProductVariant.GetLocalized(x => x.Name));
                    }
                    else
                    {
                        fullName = sci.ProductVariant.Product.GetLocalized(x => x.Name);
                    }
                    decimal unitPrice = _taxService.GetProductPrice(sci.ProductVariant, _priceCalculationService.GetUnitPrice(sci, true), out taxRate);
                    req.AddItem(fullName, description, sci.Id.ToString(), unitPrice, sci.Quantity);
                }
            }

            if (cart.RequiresShipping())
            {
                //AddMerchantCalculatedShippingMethod
                //AddCarrierCalculatedShippingOption
                var shippingOptions = _shippingService.GetShippingOptions(cart, null);
                foreach (ShippingOption shippingOption in shippingOptions.ShippingOptions)
                {
                    req.AddFlatRateShippingMethod(shippingOption.Name, _taxService.GetShippingPrice(shippingOption.Rate, _workContext.CurrentCustomer));
                }
            }

            //add only US, GB states
            //CountryCollection countries = IoC.Resolve<ICountryService>().GetAllCountries();
            //foreach (Country country in countries)
            //{
            //    foreach (StateProvince state in country.StateProvinces)
            //    {
            //        TaxByStateProvinceCollection taxByStateProvinceCollection = TaxByIoC.Resolve<IStateProvinceService>().GetAllByStateProvinceID(state.StateProvinceID);
            //        foreach (TaxByStateProvince taxByStateProvince in taxByStateProvinceCollection)
            //        {
            //            if (!String.IsNullOrEmpty(state.Abbreviation))
            //            {
            //                Req.AddStateTaxRule(state.Abbreviation, (double)taxByStateProvince.Percentage, false);
            //            }
            //        }
            //    }
            //}

            //if (subTotalDiscountBase > decimal.Zero)
            //{
            //    req.AddItem("Discount", string.Empty, string.Empty, (decimal)(-1.0) * subTotalDiscountBase, 1);
            //}

            //foreach (AppliedGiftCard agc in appliedGiftCards)
            //{
            //    req.AddItem(string.Format("Gift Card - {0}", agc.GiftCard.GiftCardCouponCode), string.Empty, string.Empty, (decimal)(-1.0) * agc.AmountCanBeUsed, 1);
            //}

            var        customerInfoDoc = new XmlDocument();
            XmlElement customerInfo    = customerInfoDoc.CreateElement("CustomerInfo");

            customerInfo.SetAttribute("CustomerID", _workContext.CurrentCustomer.Id.ToString());
            customerInfo.SetAttribute("CustomerLanguageID", _workContext.WorkingLanguage.Id.ToString());
            customerInfo.SetAttribute("CustomerCurrencyID", _workContext.WorkingCurrency.Id.ToString());
            req.AddMerchantPrivateDataNode(customerInfo);

            req.ContinueShoppingUrl = _webHelper.GetStoreLocation(false);
            req.EditCartUrl         = _webHelper.GetStoreLocation(false) + "cart";

            GCheckoutResponse resp = req.Send();

            return(resp);
        }
        public async Task <EstimateShippingResultModel> Handle(GetEstimateShippingResult request, CancellationToken cancellationToken)
        {
            var model = new EstimateShippingResultModel();

            if (request.Cart.RequiresShipping())
            {
                var address = new Address {
                    CountryId       = request.CountryId,
                    StateProvinceId = request.StateProvinceId,
                    ZipPostalCode   = request.ZipPostalCode,
                };
                GetShippingOptionResponse getShippingOptionResponse = await _shippingService
                                                                      .GetShippingOptions(request.Customer, request.Cart, address, "", request.Store);

                if (!getShippingOptionResponse.Success)
                {
                    foreach (var error in getShippingOptionResponse.Errors)
                    {
                        model.Warnings.Add(error);
                    }
                }
                else
                {
                    if (getShippingOptionResponse.ShippingOptions.Any())
                    {
                        foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                        {
                            var soModel = new EstimateShippingResultModel.ShippingOptionModel {
                                Name        = shippingOption.Name,
                                Description = shippingOption.Description,
                            };

                            //calculate discounted and taxed rate
                            var total = await _orderTotalCalculationService.AdjustShippingRate(shippingOption.Rate, request.Cart);

                            List <AppliedDiscount> appliedDiscounts = total.appliedDiscounts;
                            decimal shippingTotal = total.shippingRate;

                            decimal rateBase = (await _taxService.GetShippingPrice(shippingTotal, request.Customer)).shippingPrice;
                            decimal rate     = await _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, request.Currency);

                            soModel.Price = _priceFormatter.FormatShippingPrice(rate, true);
                            model.ShippingOptions.Add(soModel);
                        }

                        //pickup in store?
                        if (_shippingSettings.AllowPickUpInStore)
                        {
                            var pickupPoints = await _shippingService.GetAllPickupPoints();

                            if (pickupPoints.Count > 0)
                            {
                                var soModel = new EstimateShippingResultModel.ShippingOptionModel {
                                    Name        = _localizationService.GetResource("Checkout.PickUpInStore"),
                                    Description = _localizationService.GetResource("Checkout.PickUpInStore.Description"),
                                };

                                decimal shippingTotal = pickupPoints.Max(x => x.PickupFee);
                                decimal rateBase      = (await _taxService.GetShippingPrice(shippingTotal, request.Customer)).shippingPrice;
                                decimal rate          = await _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, request.Currency);

                                soModel.Price = _priceFormatter.FormatShippingPrice(rate, true);
                                model.ShippingOptions.Add(soModel);
                            }
                        }
                    }
                    else
                    {
                        model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                    }
                }
            }
            return(model);
        }
        /// <summary>
        /// Gets shopping cart shipping total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="includingTax">A value indicating whether calculated price should include tax</param>
        /// <param name="taxRate">Applied tax rate</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping total</returns>
        public virtual decimal?GetShoppingCartShippingTotal(IList <ShoppingCartItem> cart, bool includingTax,
                                                            out decimal taxRate, out Discount appliedDiscount)
        {
            decimal?shippingTotal      = null;
            decimal?shippingTotalTaxed = null;

            appliedDiscount = null;
            taxRate         = decimal.Zero;

            var customer = cart.GetCustomer();

            bool isFreeShipping = IsFreeShipping(cart);

            if (isFreeShipping)
            {
                return(decimal.Zero);
            }

            ShippingOption shippingOption = null;

            if (customer != null)
            {
                shippingOption = customer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _genericAttributeService, _storeContext.CurrentStore.Id);
            }

            if (shippingOption != null)
            {
                //use last shipping option (get from cache)

                var pickUpInStore = _shippingSettings.AllowPickUpInStore &&
                                    customer.GetAttribute <bool>(SystemCustomerAttributeNames.SelectedPickUpInStore, _storeContext.CurrentStore.Id);
                if (pickUpInStore)
                {
                    //"pick up in store" fee
                    //we do not adjust shipping rate ("AdjustShippingRate" method) for pickup in store
                    shippingTotal = _shippingSettings.PickUpInStoreFee;
                }
                else
                {
                    //adjust shipping rate
                    shippingTotal = AdjustShippingRate(shippingOption.Rate, cart, out appliedDiscount);
                }
            }
            else
            {
                //use fixed rate (if possible)
                Address shippingAddress = null;
                if (customer != null)
                {
                    shippingAddress = customer.ShippingAddress;
                }

                var shippingRateComputationMethods = _shippingService.LoadActiveShippingRateComputationMethods(_storeContext.CurrentStore.Id);
                if (shippingRateComputationMethods == null || shippingRateComputationMethods.Count == 0)
                {
                    throw new NopException("Shipping rate computation method could not be loaded");
                }

                if (shippingRateComputationMethods.Count == 1)
                {
                    var shippingRateComputationMethod = shippingRateComputationMethods[0];

                    var     shippingOptionRequests = _shippingService.CreateShippingOptionRequests(cart, shippingAddress);
                    decimal?fixedRate = null;
                    foreach (var shippingOptionRequest in shippingOptionRequests)
                    {
                        //calculate fixed rates for each request-package
                        var fixedRateTmp = shippingRateComputationMethod.GetFixedRate(shippingOptionRequest);
                        if (fixedRateTmp.HasValue)
                        {
                            if (!fixedRate.HasValue)
                            {
                                fixedRate = decimal.Zero;
                            }

                            fixedRate += fixedRateTmp.Value;
                        }
                    }

                    if (fixedRate.HasValue)
                    {
                        //adjust shipping rate
                        shippingTotal = AdjustShippingRate(fixedRate.Value, cart, out appliedDiscount);
                    }
                }
            }

            if (shippingTotal.HasValue)
            {
                if (shippingTotal.Value < decimal.Zero)
                {
                    shippingTotal = decimal.Zero;
                }

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotal = RoundingHelper.RoundPrice(shippingTotal.Value);
                }

                shippingTotalTaxed = _taxService.GetShippingPrice(shippingTotal.Value,
                                                                  includingTax,
                                                                  customer,
                                                                  out taxRate);

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotalTaxed = RoundingHelper.RoundPrice(shippingTotalTaxed.Value);
                }
            }

            return(shippingTotalTaxed);
        }
Esempio n. 7
0
        public CheckoutShippingMethodModel PrepareShippingMethodModel(IList <ShoppingCartItem> cart)
        {
            var model = new CheckoutShippingMethodModel();

            var shippingAddress = _addressService.GetAddressById(_workContext.CurrentCustomer.ShippingAddressId ?? 0);

            var getShippingOptionResponse = _shippingService.GetShippingOptions(cart, shippingAddress);

            if (getShippingOptionResponse.Success)
            {
                //performance optimization. cache returned shipping options.
                //we'll use them later (after a customer has selected an option).
                _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer,
                                                       NopCustomerDefaults.OfferedShippingOptionsAttribute,
                                                       getShippingOptionResponse.ShippingOptions,
                                                       _storeContext.CurrentStore.Id);

                foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                {
                    var soModel = new CheckoutShippingMethodModel.ShippingMethodModel
                    {
                        Name        = shippingOption.Name,
                        Description = shippingOption.Description,
                        ShippingRateComputationMethodSystemName =
                            shippingOption.ShippingRateComputationMethodSystemName
                    };

                    //adjust rate
                    var shippingTotal = _orderTotalCalculationService.AdjustShippingRate(
                        shippingOption.Rate, cart, out _);

                    var rateBase = _taxService.GetShippingPrice(shippingTotal, _workContext.CurrentCustomer);
                    var rate     =
                        _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency);
                    soModel.Fee = _priceFormatter.FormatShippingPrice(rate, true);

                    model.ShippingMethods.Add(soModel);
                }

                //find a selected (previously) shipping method
                var selectedShippingOption = _genericAttributeService.GetAttribute <ShippingOption>(_workContext.CurrentCustomer, NopCustomerDefaults.SelectedShippingOptionAttribute, _storeContext.CurrentStore.Id);

                CheckoutShippingMethodModel.ShippingMethodModel shippingOptionToSelect;

                if (selectedShippingOption != null)
                {
                    shippingOptionToSelect = model.ShippingMethods.ToList()
                                             .Find(so => !string.IsNullOrEmpty(so.Name) && so.Name.Equals(selectedShippingOption.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                                   !string.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName) && so.ShippingRateComputationMethodSystemName.Equals(selectedShippingOption.ShippingRateComputationMethodSystemName, StringComparison.InvariantCultureIgnoreCase));
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }

                //if no option has been selected, let's do it for the first one
                if (model.ShippingMethods.FirstOrDefault(so => so.Selected) != null)
                {
                    return(model);
                }

                shippingOptionToSelect = model.ShippingMethods.FirstOrDefault();
                if (shippingOptionToSelect != null)
                {
                    shippingOptionToSelect.Selected = true;
                }
            }
            else
            {
                foreach (var error in getShippingOptionResponse.Errors)
                {
                    model.Warnings.Add(error);
                }
            }

            return(model);
        }
Esempio n. 8
0
 /// <summary>
 /// Gets shipping price
 /// </summary>
 /// <param name="price">Price</param>
 /// <param name="customer">Customer</param>
 /// <returns>Price</returns>
 public decimal GetShippingPrice(decimal price, Customer customer)
 {
     return(_taxService.GetShippingPrice(price, customer));
 }
Esempio n. 9
0
        public IActionResult GetShippings([FromBody] ShippingsParametersModel parameters)
        {
            var consumerKey    = Request.Headers.GetInstantCheckoutConsumerKey();
            var consumerSecret = Request.Headers.GetInstantCheckoutConsumerSecret();

            if (consumerKey == Guid.Empty || consumerSecret == Guid.Empty)
            {
                return(Unauthorized());
            }

            var storeScope = _storeContext.ActiveStoreScopeConfiguration;
            var instantCheckoutSettings = _settingService.LoadSetting <InstantCheckoutSettings>(storeScope);

            if (consumerKey != instantCheckoutSettings.ConsumerKey &&
                consumerSecret != instantCheckoutSettings.ConsumerSecret)
            {
                return(Unauthorized());
            }

            if (parameters.Ids == null && parameters.Ids.Any(x => x <= 0))
            {
                return(Error(HttpStatusCode.BadRequest, "id", "invalid id"));
            }

            var allProducts = _productApiService.GetProducts(parameters.Ids)
                              .Where(p => _storeMappingService.Authorize(p));

            var cart = new List <ShoppingCartItem> {
            };

            foreach (var product in allProducts)
            {
                cart.Add(new ShoppingCartItem
                {
                    Customer   = _workContext.CurrentCustomer,
                    CustomerId = _workContext.CurrentCustomer.Id,
                    ProductId  = product.Id,
                    Product    = product,
                    Quantity   = 1 //TODO ADD Proper Quantity by Product Check Shipping By Weight
                });
            }

            var model = new ShippingOptionsViewModel();


            var country = _countryService.GetCountryByTwoLetterIsoCode(parameters.CountryCode);
            var state   = _stateProvinceService.GetStateProvinceByAbbreviation(parameters.StateCode);
            var address = new Address
            {
                CountryId       = country.Id,
                Country         = country,
                StateProvinceId = state != null ? state.Id : 0,
                StateProvince   = state != null ? state : null,
                ZipPostalCode   = parameters.ZipCode,
            };

            var getShippingOptionResponse = _shippingService.GetShippingOptions(cart, address, _workContext.CurrentCustomer, storeId: _storeContext.CurrentStore.Id);

            if (getShippingOptionResponse.Success)
            {
                if (getShippingOptionResponse.ShippingOptions.Any())
                {
                    foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                    {
                        //calculate discounted and taxed rate
                        var shippingRate = _orderTotalCalculationService.AdjustShippingRate(shippingOption.Rate, cart, out var _);
                        shippingRate = _taxService.GetShippingPrice(shippingRate, _workContext.CurrentCustomer);
                        shippingRate = _currencyService.ConvertFromPrimaryStoreCurrency(shippingRate, _workContext.WorkingCurrency);

                        model.ShippingOptions.Add(new ShippingOptionModel
                        {
                            Name        = shippingOption.Name,
                            Description = shippingOption.Description,
                            Price       = shippingRate,
                            Plugin      = shippingOption.ShippingRateComputationMethodSystemName
                        });
                    }
                }
            }
            else
            {
                foreach (var error in getShippingOptionResponse.Errors)
                {
                    model.Warnings.Add(error);
                }
            }

            if (_shippingSettings.AllowPickupInStore)
            {
                var pickupPointsResponse = _shippingService.GetPickupPoints(address, _workContext.CurrentCustomer, storeId: _storeContext.CurrentStore.Id);
                if (pickupPointsResponse.Success)
                {
                    if (pickupPointsResponse.PickupPoints.Any())
                    {
                        var soModel = new ShippingOptionModel
                        {
                            Name        = _localizationService.GetResource("Checkout.PickupPoints"),
                            Description = _localizationService.GetResource("Checkout.PickupPoints.Description"),
                        };
                        var pickupFee = pickupPointsResponse.PickupPoints.Min(x => x.PickupFee);
                        if (pickupFee > 0)
                        {
                            pickupFee = _taxService.GetShippingPrice(pickupFee, _workContext.CurrentCustomer);
                            pickupFee = _currencyService.ConvertFromPrimaryStoreCurrency(pickupFee, _workContext.WorkingCurrency);
                        }
                        soModel.Price  = pickupFee;
                        soModel.Plugin = "Pickup.PickupInStore";
                        model.ShippingOptions.Add(soModel);
                    }
                }
                else
                {
                    foreach (var error in pickupPointsResponse.Errors)
                    {
                        model.Warnings.Add(error);
                    }
                }
            }

            return(Ok(model));
        }
        /// <summary>
        /// Gets shopping cart shipping total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="includingTax">A value indicating whether calculated price should include tax</param>
        /// <param name="taxRate">Applied tax rate</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping total</returns>
        public virtual async Task <(decimal?shoppingCartShippingTotal, decimal taxRate, List <ApplyDiscount> appliedDiscounts)> GetShoppingCartShippingTotal(IList <ShoppingCartItem> cart, bool includingTax)
        {
            decimal?shippingTotal      = null;
            decimal?shippingTotalTaxed = null;
            var     appliedDiscounts   = new List <ApplyDiscount>();
            var     taxRate            = decimal.Zero;

            var customer = _workContext.CurrentCustomer;
            var currency = await _currencyService.GetPrimaryExchangeRateCurrency();

            bool isFreeShipping = await IsFreeShipping(cart);

            if (isFreeShipping)
            {
                return(decimal.Zero, taxRate, appliedDiscounts);
            }

            ShippingOption shippingOption = null;

            if (customer != null)
            {
                shippingOption = customer.GetUserFieldFromEntity <ShippingOption>(SystemCustomerFieldNames.SelectedShippingOption, _workContext.CurrentStore.Id);
            }

            if (shippingOption != null)
            {
                var rate = shippingOption.Rate;
                var adjustshipingRate = await AdjustShippingRate(rate, cart);

                shippingTotal    = adjustshipingRate.shippingRate;
                appliedDiscounts = adjustshipingRate.appliedDiscounts;
            }
            else
            {
                //use fixed rate (if possible)
                Address shippingAddress = null;
                if (customer != null)
                {
                    shippingAddress = customer.ShippingAddress;
                }

                var shippingRateMethods = await _shippingService.LoadActiveShippingRateCalculationProviders(_workContext.CurrentCustomer, _workContext.CurrentStore.Id, cart);

                if (!shippingRateMethods.Any() && !_shippingSettings.AllowPickUpInStore)
                {
                    throw new GrandException("Shipping rate  method could not be loaded");
                }

                if (shippingRateMethods.Count == 1)
                {
                    var shippingRateMethod = shippingRateMethods[0];

                    var shippingOptionRequests = await _shippingService.CreateShippingOptionRequests(customer, cart,
                                                                                                     shippingAddress,
                                                                                                     _workContext.CurrentStore);

                    decimal?fixedRate = null;
                    foreach (var shippingOptionRequest in shippingOptionRequests)
                    {
                        //calculate fixed rates for each request-package
                        var fixedRateTmp = await shippingRateMethod.GetFixedRate(shippingOptionRequest);

                        if (fixedRateTmp.HasValue)
                        {
                            if (!fixedRate.HasValue)
                            {
                                fixedRate = decimal.Zero;
                            }

                            fixedRate += fixedRateTmp.Value;
                        }
                    }

                    if (fixedRate.HasValue)
                    {
                        //adjust shipping rate
                        var adjustShippingRate = await AdjustShippingRate(fixedRate.Value, cart);

                        shippingTotal    = adjustShippingRate.shippingRate;
                        appliedDiscounts = adjustShippingRate.appliedDiscounts;
                    }
                }
            }

            if (shippingTotal.HasValue)
            {
                if (shippingTotal.Value < decimal.Zero)
                {
                    shippingTotal = decimal.Zero;
                }

                //round
                if (_shoppingCartSettings.RoundPrices)
                {
                    shippingTotal = RoundingHelper.RoundPrice(shippingTotal.Value, currency);
                }

                var shippingPrice = await _taxService.GetShippingPrice(shippingTotal.Value, includingTax, customer);

                shippingTotalTaxed = shippingPrice.shippingPrice;
                taxRate            = shippingPrice.taxRate;

                //round
                if (_shoppingCartSettings.RoundPrices)
                {
                    shippingTotalTaxed = RoundingHelper.RoundPrice(shippingTotalTaxed.Value, currency);
                }
            }

            return(shippingTotalTaxed, taxRate, appliedDiscounts);
        }
        /// <summary>
        /// Prepares the checkout pickup points model
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <returns>The checkout pickup points model</returns>
        protected virtual CheckoutPickupPointsModel PrepareCheckoutPickupPointsModel(IList <ShoppingCartItem> cart)
        {
            var model = new CheckoutPickupPointsModel()
            {
                AllowPickupInStore = _shippingSettings.AllowPickupInStore
            };

            if (model.AllowPickupInStore)
            {
                model.DisplayPickupPointsOnMap = _shippingSettings.DisplayPickupPointsOnMap;
                model.GoogleMapsApiKey         = _shippingSettings.GoogleMapsApiKey;
                var pickupPointProviders = _pickupPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id);
                if (pickupPointProviders.Any())
                {
                    var languageId           = _workContext.WorkingLanguage.Id;
                    var pickupPointsResponse = _shippingService.GetPickupPoints(_workContext.CurrentCustomer.BillingAddressId ?? 0,
                                                                                _workContext.CurrentCustomer, storeId: _storeContext.CurrentStore.Id);
                    if (pickupPointsResponse.Success)
                    {
                        model.PickupPoints = pickupPointsResponse.PickupPoints.Select(point =>
                        {
                            var country = _countryService.GetCountryByTwoLetterIsoCode(point.CountryCode);
                            var state   = _stateProvinceService.GetStateProvinceByAbbreviation(point.StateAbbreviation, country?.Id);

                            var pickupPointModel = new CheckoutPickupPointModel
                            {
                                Id                 = point.Id,
                                Name               = point.Name,
                                Description        = point.Description,
                                ProviderSystemName = point.ProviderSystemName,
                                Address            = point.Address,
                                City               = point.City,
                                County             = point.County,
                                StateName          = state != null ? _localizationService.GetLocalized(state, x => x.Name, languageId) : string.Empty,
                                CountryName        = country != null ? _localizationService.GetLocalized(country, x => x.Name, languageId) : string.Empty,
                                ZipPostalCode      = point.ZipPostalCode,
                                Latitude           = point.Latitude,
                                Longitude          = point.Longitude,
                                OpeningHours       = point.OpeningHours
                            };

                            var cart   = _shoppingCartService.GetShoppingCart(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id);
                            var amount = _orderTotalCalculationService.IsFreeShipping(cart) ? 0 : point.PickupFee;

                            if (amount > 0)
                            {
                                amount = _taxService.GetShippingPrice(amount, _workContext.CurrentCustomer);
                                amount = _currencyService.ConvertFromPrimaryStoreCurrency(amount, _workContext.WorkingCurrency);
                                pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(amount, true);
                            }

                            //adjust rate
                            var shippingTotal          = _orderTotalCalculationService.AdjustShippingRate(point.PickupFee, cart, out var _, true);
                            var rateBase               = _taxService.GetShippingPrice(shippingTotal, _workContext.CurrentCustomer);
                            var rate                   = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency);
                            pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(rate, true);

                            return(pickupPointModel);
                        }).ToList();
                    }
                    else
                    {
                        foreach (var error in pickupPointsResponse.Errors)
                        {
                            model.Warnings.Add(error);
                        }
                    }
                }

                //only available pickup points
                var shippingProviders = _shippingPluginManager.LoadActivePlugins(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id);
                if (!shippingProviders.Any())
                {
                    if (!pickupPointProviders.Any())
                    {
                        model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                        model.Warnings.Add(_localizationService.GetResource("Checkout.PickupPoints.NotAvailable"));
                    }
                    model.PickupInStoreOnly = true;
                    model.PickupInStore     = true;
                    return(model);
                }
            }

            return(model);
        }
Esempio n. 12
0
        /// <summary>
        /// Gets shopping cart shipping total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="includingTax">A value indicating whether calculated price should include tax</param>
        /// <param name="taxRate">Applied tax rate</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping total</returns>
        public virtual decimal?GetShoppingCartShippingTotal(IList <ShoppingCartItem> cart, bool includingTax,
                                                            out decimal taxRate, out List <Discount> appliedDiscounts)
        {
            decimal?shippingTotal      = null;
            decimal?shippingTotalTaxed = null;

            appliedDiscounts = new List <Discount>();
            taxRate          = decimal.Zero;

            var customer = cart.GetCustomer();

            bool isFreeShipping = IsFreeShipping(cart);

            if (isFreeShipping)
            {
                return(decimal.Zero);
            }

            ShippingOption shippingOption = null;

            if (customer != null)
            {
                shippingOption = customer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);
            }

            if (shippingOption != null)
            {
                shippingTotal = AdjustShippingRate(shippingOption.Rate, cart, out appliedDiscounts);
            }
            else
            {
                //use fixed rate (if possible)
                Address shippingAddress = null;
                if (customer != null)
                {
                    shippingAddress = customer.ShippingAddress;
                }

                var shippingRateComputationMethods = _shippingService.LoadActiveShippingRateComputationMethods(_storeContext.CurrentStore.Id, cart);

                if (!shippingRateComputationMethods.Any() && !_shippingSettings.AllowPickUpInStore)
                {
                    throw new GrandException("Shipping rate computation method could not be loaded");
                }

                if (shippingRateComputationMethods.Count == 1)
                {
                    var shippingRateComputationMethod = shippingRateComputationMethods[0];

                    bool shippingFromMultipleLocations;
                    var  shippingOptionRequests = _shippingService.CreateShippingOptionRequests(cart,
                                                                                                shippingAddress,
                                                                                                _storeContext.CurrentStore.Id,
                                                                                                out shippingFromMultipleLocations);
                    decimal?fixedRate = null;
                    foreach (var shippingOptionRequest in shippingOptionRequests)
                    {
                        //calculate fixed rates for each request-package
                        var fixedRateTmp = shippingRateComputationMethod.GetFixedRate(shippingOptionRequest);
                        if (fixedRateTmp.HasValue)
                        {
                            if (!fixedRate.HasValue)
                            {
                                fixedRate = decimal.Zero;
                            }

                            fixedRate += fixedRateTmp.Value;
                        }
                    }

                    if (fixedRate.HasValue)
                    {
                        //adjust shipping rate
                        shippingTotal = AdjustShippingRate(fixedRate.Value, cart, out appliedDiscounts);
                    }
                }
            }

            if (shippingTotal.HasValue)
            {
                if (shippingTotal.Value < decimal.Zero)
                {
                    shippingTotal = decimal.Zero;
                }

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotal = RoundingHelper.RoundPrice(shippingTotal.Value);
                }

                shippingTotalTaxed = _taxService.GetShippingPrice(shippingTotal.Value,
                                                                  includingTax,
                                                                  customer,
                                                                  out taxRate);

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotalTaxed = RoundingHelper.RoundPrice(shippingTotalTaxed.Value);
                }
            }

            return(shippingTotalTaxed);
        }
        public virtual CheckoutShippingAddressModel PrepareShippingAddress(string selectedCountryId = null,
                                                                           bool prePopulateNewAddressWithCustomerFields = false, string overrideAttributesXml = "")
        {
            var model = new CheckoutShippingAddressModel();

            //allow pickup in store?
            model.AllowPickUpInStore = _shippingSettings.AllowPickUpInStore;
            if (model.AllowPickUpInStore)
            {
                var pickupPoints = _shippingService.LoadActivePickupPoints(_storeContext.CurrentStore.Id);

                if (pickupPoints.Any())
                {
                    model.PickupPoints = pickupPoints.Select(x =>
                    {
                        var pickupPointModel = new CheckoutPickupPointModel()
                        {
                            Id          = x.Id,
                            Name        = x.Name,
                            Description = x.Description,
                            Address     = x.Address,
                        };
                        if (x.PickupFee > 0)
                        {
                            var amount = _taxService.GetShippingPrice(x.PickupFee, _workContext.CurrentCustomer);
                            amount     = _currencyService.ConvertFromPrimaryStoreCurrency(amount, _workContext.WorkingCurrency);
                            pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(amount, true);
                        }
                        return(pickupPointModel);
                    }).ToList();
                }

                if (!_shippingService.LoadActiveShippingRateComputationMethods(_storeContext.CurrentStore.Id).Any())
                {
                    if (!pickupPoints.Any())
                    {
                        model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                        model.Warnings.Add(_localizationService.GetResource("Checkout.PickupPoints.NotAvailable"));
                    }
                    model.PickUpInStoreOnly = true;
                    model.PickUpInStore     = true;
                    return(model);
                }
            }
            //existing addresses
            var addresses = _workContext.CurrentCustomer.Addresses
                            //allow shipping
                            .Where(a => a.CountryId == "" ||
                                   (_countryService.GetCountryById(a.CountryId) != null ? _countryService.GetCountryById(a.CountryId).AllowsShipping : false)
                                   //a.Country.AllowsShipping
                                   )
                            //enabled for the current store
                            .Where(a => a.CountryId == "" ||
                                   _storeMappingService.Authorize(_countryService.GetCountryById(a.CountryId)))
                            .ToList();

            foreach (var address in addresses)
            {
                var addressModel = new AddressModel();
                _addressViewModelService.PrepareModel(model: addressModel,
                                                      address: address,
                                                      excludeProperties: false);

                model.ExistingAddresses.Add(addressModel);
            }

            //new address
            model.NewAddress.CountryId = selectedCountryId;
            _addressViewModelService.PrepareModel(model: model.NewAddress,
                                                  address: null,
                                                  excludeProperties: false,
                                                  loadCountries: () => _countryService.GetAllCountriesForShipping(),
                                                  prePopulateWithCustomerFields: prePopulateNewAddressWithCustomerFields,
                                                  customer: _workContext.CurrentCustomer,
                                                  overrideAttributesXml: overrideAttributesXml);
            return(model);
        }
        public async Task <CheckoutShippingMethodModel> Handle(GetShippingMethod request, CancellationToken cancellationToken)
        {
            var model = new CheckoutShippingMethodModel();

            var getShippingOptionResponse = await _shippingService
                                            .GetShippingOptions(request.Customer, request.Cart, request.ShippingAddress,
                                                                "", request.Store);

            if (getShippingOptionResponse.Success)
            {
                //performance optimization. cache returned shipping options.
                //we'll use them later (after a customer has selected an option).
                await _userFieldService.SaveField(request.Customer,
                                                  SystemCustomerFieldNames.OfferedShippingOptions,
                                                  getShippingOptionResponse.ShippingOptions,
                                                  request.Store.Id);

                foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                {
                    var soModel = new CheckoutShippingMethodModel.ShippingMethodModel
                    {
                        Name        = shippingOption.Name,
                        Description = shippingOption.Description,
                        ShippingRateProviderSystemName = shippingOption.ShippingRateProviderSystemName,
                        ShippingOption = shippingOption,
                    };

                    //adjust rate
                    var shippingTotal = (await _orderTotalCalculationService.AdjustShippingRate(
                                             shippingOption.Rate, request.Cart)).shippingRate;

                    double rateBase = (await _taxService.GetShippingPrice(shippingTotal, request.Customer)).shippingPrice;
                    soModel.Fee = _priceFormatter.FormatShippingPrice(rateBase);

                    model.ShippingMethods.Add(soModel);
                }

                //find a selected (previously) shipping method
                var selectedShippingOption = request.Customer.GetUserFieldFromEntity <ShippingOption>(SystemCustomerFieldNames.SelectedShippingOption, request.Store.Id);
                if (selectedShippingOption != null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.ToList()
                                                 .Find(so =>
                                                       !String.IsNullOrEmpty(so.Name) &&
                                                       so.Name.Equals(selectedShippingOption.Name, StringComparison.OrdinalIgnoreCase) &&
                                                       !String.IsNullOrEmpty(so.ShippingRateProviderSystemName) &&
                                                       so.ShippingRateProviderSystemName.Equals(selectedShippingOption.ShippingRateProviderSystemName, StringComparison.OrdinalIgnoreCase));
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }
                //if no option has been selected, do it for the first one
                if (model.ShippingMethods.FirstOrDefault(so => so.Selected) == null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.FirstOrDefault();
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }
            }
            else
            {
                foreach (var error in getShippingOptionResponse.Errors)
                {
                    model.Warnings.Add(error);
                }
            }

            return(model);
        }
        public virtual async Task <CheckoutShippingAddressModel> PrepareShippingAddress(string selectedCountryId = null,
                                                                                        bool prePopulateNewAddressWithCustomerFields = false, string overrideAttributesXml = "")
        {
            var model = new CheckoutShippingAddressModel();

            //allow pickup in store?
            model.AllowPickUpInStore = _shippingSettings.AllowPickUpInStore;
            if (model.AllowPickUpInStore)
            {
                var pickupPoints = await _shippingService.LoadActivePickupPoints(_storeContext.CurrentStore.Id);

                if (pickupPoints.Any())
                {
                    foreach (var pickupPoint in pickupPoints)
                    {
                        var pickupPointModel = new CheckoutPickupPointModel()
                        {
                            Id          = pickupPoint.Id,
                            Name        = pickupPoint.Name,
                            Description = pickupPoint.Description,
                            Address     = pickupPoint.Address,
                        };
                        if (pickupPoint.PickupFee > 0)
                        {
                            var amount = (await _taxService.GetShippingPrice(pickupPoint.PickupFee, _workContext.CurrentCustomer)).shippingPrice;
                            amount = await _currencyService.ConvertFromPrimaryStoreCurrency(amount, _workContext.WorkingCurrency);

                            pickupPointModel.PickupFee = _priceFormatter.FormatShippingPrice(amount, true);
                        }
                        model.PickupPoints.Add(pickupPointModel);
                    }
                }

                if (!(await _shippingService.LoadActiveShippingRateComputationMethods(_storeContext.CurrentStore.Id)).Any())
                {
                    if (!pickupPoints.Any())
                    {
                        model.Warnings.Add(_localizationService.GetResource("Checkout.ShippingIsNotAllowed"));
                        model.Warnings.Add(_localizationService.GetResource("Checkout.PickupPoints.NotAvailable"));
                    }
                    model.PickUpInStoreOnly = true;
                    model.PickUpInStore     = true;
                    return(model);
                }
            }
            //existing addresses
            var addresses = new List <Address>();

            foreach (var item in _workContext.CurrentCustomer.Addresses)
            {
                if (string.IsNullOrEmpty(item.CountryId))
                {
                    addresses.Add(item);
                    continue;
                }
                var country = await _countryService.GetCountryById(item.CountryId);

                if (country == null || (country.AllowsShipping && _storeMappingService.Authorize(country)))
                {
                    addresses.Add(item);
                    continue;
                }
            }
            foreach (var address in addresses)
            {
                var addressModel = new AddressModel();
                await _addressViewModelService.PrepareModel(model : addressModel,
                                                            address : address,
                                                            excludeProperties : false);

                model.ExistingAddresses.Add(addressModel);
            }

            //new address
            model.NewAddress.CountryId = selectedCountryId;
            var countries = await _countryService.GetAllCountriesForShipping();

            await _addressViewModelService.PrepareModel(model : model.NewAddress,
                                                        address : null,
                                                        excludeProperties : false,
                                                        loadCountries : () => countries,
                                                        prePopulateWithCustomerFields : prePopulateNewAddressWithCustomerFields,
                                                        customer : _workContext.CurrentCustomer,
                                                        overrideAttributesXml : overrideAttributesXml);

            return(model);
        }
Esempio n. 16
0
        /// <summary>
        /// Gets shopping cart shipping total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="includingTax">A value indicating whether calculated price should include tax</param>
        /// <param name="taxRate">Applied tax rate</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping total</returns>
        public virtual decimal?GetShoppingCartShippingTotal(IList <ShoppingCartItem> cart, bool includingTax,
                                                            out decimal taxRate, out Discount appliedDiscount)
        {
            decimal?shippingTotal      = null;
            decimal?shippingTotalTaxed = null;

            appliedDiscount = null;
            taxRate         = decimal.Zero;

            var customer = cart.GetCustomer();

            bool isFreeShipping = IsFreeShipping(cart);

            if (isFreeShipping)
            {
                return(decimal.Zero);
            }

            ShippingOption shippingOption = null;

            if (customer != null)
            {
                shippingOption = customer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _genericAttributeService, _storeContext.CurrentStore.Id);
            }

            if (shippingOption != null)
            {
                //use last shipping option (get from cache)

                //adjust shipping rate
                shippingTotal = AdjustShippingRate(shippingOption.Rate, cart, out appliedDiscount);
            }
            else
            {
                //use fixed rate (if possible)
                Address shippingAddress = null;
                if (customer != null)
                {
                    shippingAddress = customer.ShippingAddress;
                }

                var shippingRateComputationMethods = _shippingService.LoadActiveShippingRateComputationMethods();
                if (shippingRateComputationMethods == null || shippingRateComputationMethods.Count == 0)
                {
                    throw new NasException("Shipping rate computation method could not be loaded");
                }

                if (shippingRateComputationMethods.Count == 1)
                {
                    var getShippingOptionRequest = _shippingService.CreateShippingOptionRequest(cart, shippingAddress);

                    var     shippingRateComputationMethod = shippingRateComputationMethods[0];
                    decimal?fixedRate = shippingRateComputationMethod.GetFixedRate(getShippingOptionRequest);
                    if (fixedRate.HasValue)
                    {
                        //adjust shipping rate
                        shippingTotal = AdjustShippingRate(fixedRate.Value, cart, out appliedDiscount);
                    }
                }
            }

            if (shippingTotal.HasValue)
            {
                if (shippingTotal.Value < decimal.Zero)
                {
                    shippingTotal = decimal.Zero;
                }

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotal = Math.Round(shippingTotal.Value, 2);
                }

                shippingTotalTaxed = _taxService.GetShippingPrice(shippingTotal.Value,
                                                                  includingTax,
                                                                  customer,
                                                                  out taxRate);

                //round
                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotalTaxed = Math.Round(shippingTotalTaxed.Value, 2);
                }
            }

            return(shippingTotalTaxed);
        }
Esempio n. 17
0
        protected CheckoutShippingMethodModel PrepareShippingMethodModel(IList <OrganizedShoppingCartItem> cart)
        {
            var model = new CheckoutShippingMethodModel();

            var getShippingOptionResponse = _shippingService.GetShippingOptions(cart, _workContext.CurrentCustomer.ShippingAddress, "", _storeContext.CurrentStore.Id);

            if (getShippingOptionResponse.Success)
            {
                //performance optimization. cache returned shipping options.
                //we'll use them later (after a customer has selected an option).
                _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer,
                                                       SystemCustomerAttributeNames.OfferedShippingOptions, getShippingOptionResponse.ShippingOptions, _storeContext.CurrentStore.Id);

                var shippingMethods = _shippingService.GetAllShippingMethods();

                foreach (var shippingOption in getShippingOptionResponse.ShippingOptions)
                {
                    var soModel = new CheckoutShippingMethodModel.ShippingMethodModel()
                    {
                        ShippingMethodId = shippingOption.ShippingMethodId,
                        Name             = shippingOption.Name,
                        Description      = shippingOption.Description,
                        ShippingRateComputationMethodSystemName = shippingOption.ShippingRateComputationMethodSystemName,
                    };

                    var srcmProvider = _shippingService.LoadShippingRateComputationMethodBySystemName(shippingOption.ShippingRateComputationMethodSystemName);
                    if (srcmProvider != null)
                    {
                        soModel.BrandUrl = _pluginMediator.GetBrandImageUrl(srcmProvider.Metadata);
                    }

                    //adjust rate
                    Discount appliedDiscount = null;
                    var      shippingTotal   = _orderTotalCalculationService.AdjustShippingRate(
                        shippingOption.Rate, cart, shippingOption.Name, shippingMethods, out appliedDiscount);

                    decimal rateBase = _taxService.GetShippingPrice(shippingTotal, _workContext.CurrentCustomer);
                    decimal rate     = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency);
                    soModel.FeeRaw = rate;
                    soModel.Fee    = _priceFormatter.FormatShippingPrice(rate, true);

                    model.ShippingMethods.Add(soModel);
                }

                //find a selected (previously) shipping method
                var selectedShippingOption = _workContext.CurrentCustomer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);
                if (selectedShippingOption != null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.ToList()
                                                 .Find(so => !String.IsNullOrEmpty(so.Name) && so.Name.Equals(selectedShippingOption.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                                       !String.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName) &&
                                                       so.ShippingRateComputationMethodSystemName.Equals(selectedShippingOption.ShippingRateComputationMethodSystemName, StringComparison.InvariantCultureIgnoreCase));

                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }
                //if no option has been selected, let's do it for the first one
                if (model.ShippingMethods.Where(so => so.Selected).FirstOrDefault() == null)
                {
                    var shippingOptionToSelect = model.ShippingMethods.FirstOrDefault();
                    if (shippingOptionToSelect != null)
                    {
                        shippingOptionToSelect.Selected = true;
                    }
                }
            }
            else
            {
                foreach (var error in getShippingOptionResponse.Errors)
                {
                    model.Warnings.Add(error);
                }
            }

            return(model);
        }
Esempio n. 18
0
        /// <summary>
        /// Gets shopping cart shipping total
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="includingTax">A value indicating whether calculated price should include tax</param>
        /// <param name="taxRate">Applied tax rate</param>
        /// <param name="appliedDiscount">Applied discount</param>
        /// <returns>Shipping total</returns>
        public virtual decimal?GetShoppingCartShippingTotal(IList <ShoppingCartItem> cart, bool includingTax,
                                                            out decimal taxRate, out Discount appliedDiscount)
        {
            decimal?shippingTotalWithoutDiscount   = null;
            decimal?shippingTotalWithDiscount      = null;
            decimal?shippingTotalWithDiscountTaxed = null;

            appliedDiscount = null;
            taxRate         = decimal.Zero;

            var customer = cart.GetCustomer();

            bool isFreeShipping = _shippingService.IsFreeShipping(cart);

            if (isFreeShipping)
            {
                return(decimal.Zero);
            }


            //free shipping over $X
            if (_shippingSettings.FreeShippingOverXEnabled)
            {
                //check whether we have subtotal enough to have free shipping
                decimal  subTotalDiscountAmount      = decimal.Zero;
                Discount subTotalAppliedDiscount     = null;
                decimal  subTotalWithoutDiscountBase = decimal.Zero;
                decimal  subTotalWithDiscountBase    = decimal.Zero;
                GetShoppingCartSubTotal(cart, includingTax, out subTotalDiscountAmount,
                                        out subTotalAppliedDiscount, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);

                if (subTotalWithDiscountBase > _shippingSettings.FreeShippingOverXValue)
                {
                    return(decimal.Zero);
                }
            }


            ShippingOption lastShippingOption = null;

            if (customer != null)
            {
                lastShippingOption = customer.GetAttribute <ShippingOption>(SystemCustomerAttributeNames.LastShippingOption);
            }

            if (lastShippingOption != null)
            {
                //use last shipping option (get from cache)
                //we have already discounted cache value
                shippingTotalWithoutDiscount = lastShippingOption.Rate;

                //discount
                decimal discountAmount = GetShippingDiscount(customer,
                                                             shippingTotalWithoutDiscount.Value, out appliedDiscount);
                shippingTotalWithDiscount = shippingTotalWithoutDiscount - discountAmount;
                if (shippingTotalWithDiscount < decimal.Zero)
                {
                    shippingTotalWithDiscount = decimal.Zero;
                }

                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotalWithDiscount = Math.Round(shippingTotalWithDiscount.Value, 2);
                }
            }
            else
            {
                //use fixed rate (if possible)
                Address shippingAddress = null;
                if (customer != null)
                {
                    shippingAddress = customer.ShippingAddress;
                }

                var shippingRateComputationMethods = _shippingService.LoadActiveShippingRateComputationMethods();
                if (shippingRateComputationMethods == null || shippingRateComputationMethods.Count == 0)
                {
                    throw new NopException("Shipping rate computation method could not be loaded");
                }

                if (shippingRateComputationMethods.Count == 1)
                {
                    var getShippingOptionRequest = _shippingService.CreateShippingOptionRequest(cart, shippingAddress);

                    var     shippingRateComputationMethod = shippingRateComputationMethods[0];
                    decimal?fixedRate = shippingRateComputationMethod.GetFixedRate(getShippingOptionRequest);
                    if (fixedRate.HasValue)
                    {
                        decimal additionalShippingCharge = _shippingService.GetShoppingCartAdditionalShippingCharge(cart);
                        shippingTotalWithoutDiscount = fixedRate.Value + additionalShippingCharge;
                        if (_shoppingCartSettings.RoundPricesDuringCalculation)
                        {
                            shippingTotalWithoutDiscount = Math.Round(shippingTotalWithoutDiscount.Value, 2);
                        }
                        decimal shippingTotalDiscount = GetShippingDiscount(customer, shippingTotalWithoutDiscount.Value, out appliedDiscount);
                        shippingTotalWithDiscount = shippingTotalWithoutDiscount.Value - shippingTotalDiscount;
                        if (shippingTotalWithDiscount.Value < decimal.Zero)
                        {
                            shippingTotalWithDiscount = decimal.Zero;
                        }
                    }
                }
            }

            if (shippingTotalWithDiscount.HasValue)
            {
                shippingTotalWithDiscountTaxed = _taxService.GetShippingPrice(shippingTotalWithDiscount.Value,
                                                                              includingTax,
                                                                              customer,
                                                                              out taxRate);

                if (_shoppingCartSettings.RoundPricesDuringCalculation)
                {
                    shippingTotalWithDiscountTaxed = Math.Round(shippingTotalWithDiscountTaxed.Value, 2);
                }
            }

            return(shippingTotalWithDiscountTaxed);
        }