Shipping Address Validators

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 年 前
Not sure if anyone can help me with this one. My client does not want to use One Page Checkout anymore.

I used to have a validation for Shipping Address though in OPC: If ShippinAddress was Hawaii, Alaska or Puerto Rico, throw an exception message.


public ActionResult OpcSaveShipping(FormCollection form)
        {
            try
            {
                //validation
                var cart = _workContext.CurrentCustomer.ShoppingCartItems.Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart).ToList();
                if (cart.Count == 0)
                    throw new Exception("Your cart is empty");

                if (!UseOnePageCheckout())
                    throw new Exception("One page checkout is disabled");

                if ((_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed))
                    throw new Exception("Anonymous checkout is not allowed");

                if (!cart.RequiresShipping())
                    throw new Exception("Shipping is not required");

                int shippingAddressId = 0;
                int.TryParse(form["shipping_address_id"], out shippingAddressId);

                if (shippingAddressId > 0)
                {
                    //existing address
                    var address = _workContext.CurrentCustomer.Addresses.Where(a => a.Id == shippingAddressId).FirstOrDefault();
                    if (address == null)
                        throw new Exception("Address can't be loaded");
                    if (address.StateProvinceId == 4 || address.StateProvinceId == 18 || address.StateProvinceId == 49)
                        throw new Exception("We cannot ship ground to Alaska, Hawaii or Puerto Rico.");

                    _workContext.CurrentCustomer.SetShippingAddress(address);
                    _customerService.UpdateCustomer(_workContext.CurrentCustomer);
                }
                else
                {
                    //new address
                    var model = new CheckoutShippingAddressModel();
                    TryUpdateModel(model.NewAddress, "ShippingNewAddress");
                    //validate model
                    TryValidateModel(model.NewAddress);
                    if (!ModelState.IsValid)
                    {
                        //model is not valid. redisplay the form with errors
                        var shippingAddressModel = PrepareShippingAddressModel(model.NewAddress.CountryId);
                        shippingAddressModel.NewAddressPreselected = true;
                        return Json(new
                        {
                            update_section = new UpdateSectionJsonModel()
                            {
                                name = "shipping",
                                html = RenderPartialViewToString("OpcShippingAddress", shippingAddressModel)
                            }
                        });
                    }

                    //try to find an address with the same values (don't duplicate records)
                    var address = _workContext.CurrentCustomer.Addresses.ToList().FindAddress(
                        model.NewAddress.FirstName, model.NewAddress.LastName, model.NewAddress.PhoneNumber,
                        model.NewAddress.Email, model.NewAddress.FaxNumber, model.NewAddress.Company,
                        model.NewAddress.Address1, model.NewAddress.Address2, model.NewAddress.City,
                        model.NewAddress.StateProvinceId, model.NewAddress.ZipPostalCode, model.NewAddress.CountryId);
                    if (address == null)
                    {
                        address = model.NewAddress.ToEntity();
                        address.CreatedOnUtc = DateTime.UtcNow;
                        //some validation
                        if (address.StateProvinceId == 4 || address.StateProvinceId == 18 || address.StateProvinceId == 49)
                            throw new Exception("We cannot ship ground to Alaska, Hawaii or Puerto Rico.");

                        if (address.CountryId == 0)
                            address.CountryId = null;
                        if (address.StateProvinceId == 0)
                            address.StateProvinceId = null;
                        _workContext.CurrentCustomer.AddAddress(address);
                        
                    }
                    _workContext.CurrentCustomer.SetShippingAddress(address);
                    _customerService.UpdateCustomer(_workContext.CurrentCustomer);
                }

                var shippingMethodModel = PrepareShippingMethodModel(cart);
                return Json(new
                {
                    update_section = new UpdateSectionJsonModel()
                    {
                        name = "shipping-method",
                        html = RenderPartialViewToString("OpcShippingMethods", shippingMethodModel)
                    },
                    goto_section = "shipping_method"
                });
            }
            catch (Exception exc)
            {
                _logger.Warning(exc.Message, exc, _workContext.CurrentCustomer);
                return Json(new { error = 1, message = exc.Message });
            }
        }




I tried using a catch statement for multi-step checkout too, but it doesn't work. How can I try to validate the Shipping Address so that it can display an error if Existing or New Shipping Address has Hawaii, Alaska or Puerto Rico?

When I tried the exact same coding for Multi-Step checkout, I kept getting an error stating the request was being blocked due to sensitive info and that I would need to set JsonResultBehavior to AllowGet.

Any help appreciated! Thanks.
11 年 前
I can think of a few ways to do this besides the controller

1) (Shameless plug :)  Shipping Director  - see blog example Exclude Ground Shipping Based on State
Pros: no coding/testing/debugging
Cons: $79 (but, how much time have you already spent, and how much more time will you spend? :)

2) Create your own Shipping Plugin that can do the check and then call the real shipping plugin you want to use
Pros:  It's a plugin, so no impact on core code.  Also, will always work in the future for OPC, regular checkout, or any checkout mechanism.
Cons: a bit more work to do - need to learn shipping plugin interface,etc.  Either need to hard code the real shipping plug-in to call, or get from a configuration page or a Setting.

3) Nop.Services ShippingService.cs
Pros: probably easy change
Cons: It's core code. (see above)
11 年 前
New York wrote:
I can think of a few ways to do this besides the controller

1) (Shameless plug :)  Shipping Director  - see blog example Exclude Ground Shipping Based on State
Pros: no coding/testing/debugging
Cons: $79 (but, how much time have you already spent, and how much more time will you spend? :)

2) Create your own Shipping Plugin that can do the check and then call the real shipping plugin you want to use
Pros:  It's a plugin, so no impact on core code.  Also, will always work in the future for OPC, regular checkout, or any checkout mechanism.
Cons: a bit more work to do - need to learn shipping plugin interface,etc.  Either need to hard code the real shipping plug-in to call, or get from a configuration page or a Setting.

3) Nop.Services ShippingService.cs
Pros: probably easy change
Cons: It's core code. (see above)


Thanks New York. Yea, I've tried #1 before and works perfectly on internal server but when I attempt to installed and configure with live site, it just won't work . Hosting service has been reluctant to assist. Definitely no shame in using another plugin, that's why they are there!

I wish I was advanced enough to even start #2, maybe one day. Just don't know enough to code that... Still a noob at programming.

#3, I'll have to take a look into that class and maybe go that route. Thanks for the suggestions. I have also been working with another forum member, olandese. Awesome member and assisted me on another project and got my feet wet with pointing me in the right direction too. I still have a lot of work cut out for me. Ultimately though, I would rather code it myself in case of upgrades and so on. Thanks for .02!
11 年 前
What I did for this was replicated the Allows Billing/Shipping columns from the Country object to the StateProvince one.  Then just set those states to false for AllowsShipping and modify the controller to only give the choice of states that are allowed.
11 年 前
So it looks like I did end up having to add in some code to the Shipping.ByWeight plugin. Pretty easy just took me longer as I needed to reload plugins list as well as restart server to ensure it read new compiled code. Once I did that, plugin works as intended! Thanks a bunch for the suggestions guys!
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.