예제 #1
0
        /// <summary>
        /// Fetches the shipping options.
        /// </summary>
        /// <param name="order">The Order</param>
        /// <returns></returns>
        public static ShippingOptionCollection FetchShippingOptions(Order order)
        {
            ShippingService          shippingService          = new ShippingService();
            ShippingOptionCollection shippingOptionCollection = shippingService.GetShippingOptions(order);

            return(shippingOptionCollection);
        }
예제 #2
0
        /// <summary>
        /// Fetches the shipping options.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public static ShippingOptionCollection FetchShippingOptions(string userName)
        {
            Order                    order                    = new OrderController().FetchOrder(userName);
            ShippingService          shippingService          = new ShippingService();
            ShippingOptionCollection shippingOptionCollection = shippingService.GetShippingOptions(order);

            return(shippingOptionCollection);
        }
        public void NoSuitableShippingMethodYieldsEmptySet()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub {
                    Weight = 1
                })
            };
            var shippingMethods = new[] {
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 3, minimumWeight: 0.4, maximumWeight: 0.6),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 7, minimumWeight: 1.1)
            };

            Assert.IsFalse(ShippingService.GetShippingOptions(shippingMethods, cart, null, null, null).Any());
        }
        public void OneSuitableShippingMethodGetsSelected()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub {
                    Weight = 2
                })
            };
            var shippingMethods = new[] {
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 3, minimumWeight: 0, maximumWeight: 1),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 7, minimumWeight: 1, maximumWeight: 5),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 11, minimumWeight: 5)
            };
            var validMethods = ShippingService.GetShippingOptions(shippingMethods, cart, null, null, null).ToList();

            Assert.AreEqual(1, validMethods.Count());
            Assert.AreEqual(7, validMethods.First().Price);
        }
예제 #5
0
        public void DuplicateMethodDoesNotYieldDuplicateOptions()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub {
                    Weight = 3
                })
            };

            var shippingMethod1 = ShippingHelpers.BuildWeightBasedShippingMethod(price: 3);
            var shippingMethod2 = ShippingHelpers.BuildWeightBasedShippingMethod(price: 3);

            var shippingMethods = new[] { shippingMethod1, shippingMethod2 };

            var validMethods = ShippingService.GetShippingOptions(shippingMethods, cart, null, null, null).ToList();

            Assert.AreEqual(1, validMethods.Count());
        }
        public void OverlappingMethodsGetSelected()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub {
                    Weight = 1
                })
            };
            var shippingMethods = new[] {
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 3, minimumWeight: 0, maximumWeight: 1),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 4, minimumWeight: 0.5, maximumWeight: 1.5),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 7, minimumWeight: 1, maximumWeight: 5),
                ShippingHelpers.BuildWeightBasedShippingMethod(price: 11, minimumWeight: 5)
            };
            var validMethods = ShippingService.GetShippingOptions(shippingMethods, cart, null, null, null).ToList();

            Assert.AreEqual(3, validMethods.Count());
            Assert.AreEqual(14, validMethods.Sum(m => m.Price));
        }
예제 #7
0
        public void GetShippingOptionsEnumeratesOptions()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub {
                    Weight = 3
                })
            };

            var shippingMethod1 = ShippingHelpers.BuildWeightBasedShippingMethod(price: 3);

            shippingMethod1.Name                  = "Shipping method 1";
            shippingMethod1.ShippingCompany       = "Vandelay Import/Export";
            shippingMethod1.ExcludedShippingAreas = "a,b";
            shippingMethod1.IncludedShippingAreas = "c,d,e";

            var shippingMethod2 = ShippingHelpers.BuildWeightBasedShippingMethod(price: 7);

            shippingMethod2.Name                  = "Shipping method 2";
            shippingMethod2.ShippingCompany       = "Northwind Shipping";
            shippingMethod2.ExcludedShippingAreas = "f,g,h";
            shippingMethod2.IncludedShippingAreas = "i,j";

            var shippingMethods = new[] { shippingMethod1, shippingMethod2 };

            var validMethods = ShippingService.GetShippingOptions(shippingMethods, cart, null, null, null).ToList();

            Assert.AreEqual(2, validMethods.Count());
            var firstOption = validMethods.First();

            Assert.That(firstOption.Description, Is.EqualTo(shippingMethod1.Name));
            Assert.That(firstOption.Price, Is.EqualTo(3));
            Assert.That(firstOption.ShippingCompany, Is.EqualTo(shippingMethod1.ShippingCompany));
            Assert.That(String.Join(",", firstOption.ExcludedShippingAreas), Is.EqualTo(shippingMethod1.ExcludedShippingAreas));
            Assert.That(String.Join(",", firstOption.IncludedShippingAreas), Is.EqualTo(shippingMethod1.IncludedShippingAreas));
            var secondOption = validMethods.Skip(1).First();

            Assert.That(secondOption.Description, Is.EqualTo(shippingMethod2.Name));
            Assert.That(secondOption.Price, Is.EqualTo(7));
            Assert.That(secondOption.ShippingCompany, Is.EqualTo(shippingMethod2.ShippingCompany));
            Assert.That(String.Join(",", secondOption.ExcludedShippingAreas), Is.EqualTo(shippingMethod2.ExcludedShippingAreas));
            Assert.That(String.Join(",", secondOption.IncludedShippingAreas), Is.EqualTo(shippingMethod2.IncludedShippingAreas));
        }
예제 #8
0
        public void InternationalSelectsInternationalPrices()
        {
            var cart = new[] {
                new ShoppingCartQuantityProduct(1, new ProductStub()),
                new ShoppingCartQuantityProduct(2, new ProductStub())
            };
            var domesticShippingMethod      = ShippingHelpers.BuildUspsShippingMethod();
            var internationalShippingMethod = ShippingHelpers.BuildUspsShippingMethod();

            internationalShippingMethod.Markup        = 7;
            internationalShippingMethod.International = true;
            var wca = ShippingHelpers.GetUspsWorkContextAccessor("foo", false, false, 3);

            var internationalPrices = ShippingService.GetShippingOptions(
                new IShippingMethod[] { domesticShippingMethod, internationalShippingMethod },
                cart, "France", "78400", wca).ToList();

            Assert.That(internationalPrices.Count, Is.EqualTo(1));
            Assert.That(internationalPrices.First().Price, Is.EqualTo(10));
        }
예제 #9
0
        public ActionResult Shipping(CheckoutViewModel model)
        {
            // In this step the user will select the shipping method from a list
            var user = _workContextAccessor.GetContext().CurrentUser;

            if (!_checkoutHelperService.UserMayCheckout(user, out ActionResult redirect))
            {
                if (redirect != null)
                {
                    return(redirect);
                }
                return(Redirect(RedirectUrl));
            }
            // Try to fetch the model from TempData to handle the case where we have been
            // redirected here.
            if (TempData.ContainsKey("CheckoutViewModel"))
            {
                model = (CheckoutViewModel)TempData["CheckoutViewModel"];
            }

            // Check if the mail returned an error: "A shipment has not been selected"
            if (TempData.ContainsKey("ShippingError"))
            {
                ModelState.AddModelError("_FORM", TempData["ShippingError"].ToString());
            }

            // deserialize addresses
            ReinflateViewModelAddresses(model);

            model.ShippingRequired = IsShippingRequired();
            if (model.ShippingAddressVM != null)
            {
                var productQuantities = _shoppingCart
                                        .GetProducts()
                                        .Where(p => p.Quantity > 0)
                                        .ToList();
                // Hack: based on the address coming in model.ShippingAddressVM, we can
                // compute the actual destinations to be used at this stage
                var country = _addressConfigurationService
                              ?.GetCountry(model.ShippingAddressVM.CountryId);
                var countryName = country
                                  ?.Record?.TerritoryInternalRecord.Name;
                // we should make sure that the country name is filled in for the shipping
                // address view model, so we can display it.
                if (string.IsNullOrWhiteSpace(model.ShippingAddressVM.Country))
                {
                    model.ShippingAddressVM.Country = _contentManager.GetItemMetadata(country).DisplayText;
                }
                // get all possible providers for shipping methods
                var shippingMethods = _shippingMethodProviders
                                      .SelectMany(p => p.GetShippingMethods())
                                      .ToList();
                // Test those providers with nwazet's default interface.
                var allShippingOptions = ShippingService
                                         .GetShippingOptions(
                    shippingMethods,
                    productQuantities,
                    countryName,
                    model.ShippingAddressVM.PostalCode,
                    _workContextAccessor).ToList();
                // Those tests done like that cannot be very reliable with respect to
                // territories' configuration, unless we configure a hierarchy of postal
                // codes. Rather than do that, we are going to do an hack on the PostalCode
                // that will let a shipping criterion parse out the territory Ids.
                allShippingOptions
                .AddRange(ShippingService
                          .GetShippingOptions(
                              shippingMethods,
                              productQuantities,
                              countryName,
                              $"{model.ShippingAddressVM.PostalCode};" +
                              $"{model.ShippingAddressVM.CountryId};" +
                              $"{model.ShippingAddressVM.ProvinceId};" +
                              $"{model.ShippingAddressVM.CityId}",
                              _workContextAccessor));
                // remove duplicate shipping options
                model.AvailableShippingOptions = allShippingOptions.Distinct(new ShippingOption.ShippingOptionComparer()).ToList();
                // See whether we are trying to short circuit the checkout steps
                if (model.UseDefaultShipping)
                {
                    // if there is no option selected, and there is only one possible option, we can skip
                    // the selection. If the user is trying to reset their selection, there is a selected
                    // option so it should not trigger this condition
                    if (string.IsNullOrWhiteSpace(model.ShippingOption) && model.AvailableShippingOptions.Count == 1)
                    {
                        model.ShippingOption = model.AvailableShippingOptions.First().FormValue;
                        return(ShippingPOST(model));
                    }
                }
                // to correctly display prices, the view will need the currency provider
                model.CurrencyProvider = _currencyProvider;
                // encode addresses so we can hide them in the form
                model.EncodeAddresses();
                // make sure services are injected so they may be used
                InjectServices(model);
                return(View(model));
            }
            // to get here something must have gone very wrong. Perhaps the user
            // is trying to select a shipping method where no shipping is required.
            // More likely, a refresh of the shipping page messed things up for us.
            // Either way, go through the index in an attempt to properly repopulate
            // the addresses
            model.UseDefaultAddress = true;
            // Put the model in TempData so it can be reused in the next action.
            TempData["CheckoutViewModel"] = model;
            return(RedirectToAction("Index"));
        }
        private dynamic BuildCartShape(
            bool isSummary = false,
            string country = null,
            string zipCode = null,
            ShippingOption shippingOption = null)
        {
            var shape = _shapeFactory.ShoppingCart();

            if (shippingOption != null)
            {
                shape.ReadOnly       = true;
                shape.ShippingOption = shippingOption;
            }

            var productQuantities = _shoppingCart
                                    .GetProducts()
                                    .Where(p => p.Quantity > 0)
                                    .ToList();
            var productShapes = GetProductShapesFromQuantities(productQuantities);

            shape.ShopItems = productShapes;

            var shopItemsAllDigital = !(productQuantities.Any(pq => !(pq.Product.IsDigital)));

            shape.ShopItemsAllDigital = shopItemsAllDigital;

            var custom =
                _extraCartInfoProviders == null
                    ? null
                    : _extraCartInfoProviders
                .SelectMany(p => p.GetExtraCartInfo())
                .ToList();

            if ((country == Country.UnitedStates && !string.IsNullOrWhiteSpace(zipCode)) ||
                (!String.IsNullOrWhiteSpace(country) && country != Country.UnitedStates))
            {
                shape.Country = country;
                shape.ZipCode = zipCode;

                if (!shopItemsAllDigital)
                {
                    if (!isSummary && shippingOption == null)
                    {
                        var shippingMethods = _shippingMethodProviders
                                              .SelectMany(p => p.GetShippingMethods())
                                              .ToList();
                        shape.ShippingOptions =
                            ShippingService
                            .GetShippingOptions(
                                shippingMethods, productQuantities, country, zipCode, _wca).ToList();
                    }
                }
            }

            var subtotal = _shoppingCart.Subtotal();
            var taxes    = _shoppingCart.Taxes(subtotal);

            // Check to see if any of the products require the user to be authenticated
            var shopItemsAuthenticationRequired = productQuantities.Any(pq => pq.Product.AuthenticationRequired);

            shape.ShopItemsAuthenticationRequired = shopItemsAuthenticationRequired;

            var displayCheckoutButtons = productQuantities.Any();
            var currentUser            = _wca.GetContext().CurrentUser;

            if (currentUser == null)
            {
                if (shopItemsAuthenticationRequired)
                {
                    displayCheckoutButtons = false;
                }
            }

            if (displayCheckoutButtons)
            {
                var checkoutShapes = _checkoutServices.Select(
                    service => service.BuildCheckoutButtonShape(
                        productShapes,
                        productQuantities,
                        new[] { shippingOption },
                        taxes,
                        country,
                        zipCode,
                        custom)).ToList();
                shape.CheckoutButtons = checkoutShapes;
            }

            shape.Subtotal = subtotal;
            shape.Taxes    = taxes;
            shape.Total    = _shoppingCart.Total(subtotal, taxes);
            if (isSummary)
            {
                shape.Metadata.Alternates.Add("ShoppingCart_Summary");
            }
            return(shape);
        }