Updating Shipping Dropdown from custom address field

For general questions and discussions specific to the AbleCommerce GOLD ASP.Net shopping cart software.
Post Reply
RickSilver
Lieutenant (LT)
Lieutenant (LT)
Posts: 66
Joined: Mon Jun 22, 2009 5:49 pm

Updating Shipping Dropdown from custom address field

Post by RickSilver » Tue Jan 24, 2017 2:45 pm

I couldn't find anyone doing this already in the forum. On the checkout page, I have my own address input fields that change when a user changes a selection from a custom dropdown list. Along with the address change, I also need to recalculate the Shipping options based on what is in those address fields. I don't see a way to do this.

thanks
Rick

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Updating Shipping Dropdown from custom address field

Post by jguengerich » Thu Jan 26, 2017 3:50 am

I have a similar situation. I am using R12 SR 1. Here is some of my code (probably based on code from various other pages). There's some extra stuff in there you probably don't need, for example we have a check box that the customer can choose to have the shipping charges billed to their UPS or FedEx account if we have it on file. Hopefully it gets you going in the right direction though. Note that there is a comment about trying to avoid an occasional error in ShipMethodsList_SelectedIndexChanged; I still haven't figured out the root cause of that error, and I still get it occasionally.

Code: Select all

        protected void ShippingAddress_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = _SortedAddresses.IndexOf(AlwaysConvert.ToInt(ShippingAddress.SelectedValue));
            IBasketService preCheckoutService2 = AbleContext.Resolve<IBasketService>();
            // clear all shipment info, set everything to go to billing address
            preCheckoutService2.Package(AbleContext.Current.User.Basket, true);
            // now that have 1 shipment, set it to address we really want (left foreach loop in, even though there should only be one shipment now)
            Address address = _SortedAddresses[index];
            foreach (BasketShipment shipment in AbleContext.Current.User.Basket.Shipments)
            {
                shipment.Address = address;
            }
            AbleContext.Current.User.Basket.Save();
            CommerceBuilder.Taxes.TaxCalculator.Calculate(AbleContext.Current.User.Basket);
            if (ShippingAddress.Items[0].Value == "Select an address from this list...")
            {
                ShippingAddress.Items.RemoveAt(0);
                ShippingAddress.Font.Bold = false;
            }
            ShippingAddressDisplay.ShipmentId = AbleContext.Current.User.Basket.Shipments.Count > 0 ? AbleContext.Current.User.Basket.Shipments[0].Id : 0;
            if (!ShipMethodsList.Visible)
            {
                ShipMethodsList.Visible = true;
            }
            BindMethods();
            ShipMethodsList_SelectedIndexChanged(null, null);
            ContinueButton.Enabled = true;
        }

        protected void BindMethods(bool includeInstructions = true)
        {
            Basket basket = AbleContext.Current.User.Basket;
            // combine multiple shipments into one
            if (basket.Shipments.Count > 1)
            {
                Address address = basket.Shipments[0].Address;
                IBasketService preCheckoutService2 = AbleContext.Resolve<IBasketService>();
                preCheckoutService2.Package(AbleContext.Current.User.Basket, true); // create one shipment to billing address...
                basket.Shipments[0].Address = address;  // ...then set to shipping address
                basket.Save();
            }
            _ShipmentIndex = 0;
            BasketShipment shipment = basket.Shipments[_ShipmentIndex];
            IShipRateQuoteCalculator shippingCalculator = AbleContext.Resolve<IShipRateQuoteCalculator>();

            ICollection<ShipRateQuote> rateQuotes = shippingCalculator.QuoteForShipment(shipment);
            ShipMethodsList.DataSource = GetShipMethodListDs(rateQuotes, includeInstructions);
            ShipMethodsList.DataBind();

            ListItem foundItem = ShipMethodsList.Items.FindByValue(shipment.ShipMethodId.ToString());   // null if not found
            int listIndex = ShipMethodsList.Items.IndexOf(foundItem);   // -1 if foundItem is null
            ShipMethodsList.SelectedIndex = listIndex >= 0 ? listIndex : 0;  // selects item 0 if listIndex is -1

            if (rateQuotes.Count == 0)
            {
                ShipMethodErrorMessage.Visible = true;
                phNoShippingMethods.Visible = true;
                ShipMethodsList.Visible = false;

                InsuranceCheckBox.Visible = false;
                InsuranceAmountLabel.Visible = false;

                // CHECK IF UPS IS ENABLED
                string classId = Misc.GetClassId(typeof(UPS));
                IList<ShipGateway> gateways = ShipGatewayDataSource.LoadForClassId(classId);
                if (gateways.Count > 0)
                {
                    // CHECK IF PROVIDED ADDRESS IS A PO-BOX ADDRESS
                    if (ValidationHelper.IsPostOfficeBoxAddress(shipment.Address.Address1))
                    {
                        ShipMethodUPSErrorMessage.Visible = true;
                    }
                }

                ContinueButton.Visible = false;
            }
            else
            {
                // IN CASE WE HAVE DISABLED THE CONTINUE BUTTON BEFORE
                ContinueButton.Visible = true;
            }
        }

        protected void ShipMethodsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (AlwaysConvert.ToInt(ShipMethodsList.SelectedValue) != -1)
            {
                Basket basket = AbleContext.Current.User.Basket;
                IList<BasketShipment> shipments = basket.Shipments;
                _ShipmentIndex = 0;
                // if ShipMethod.aspx & .cs exist in Shipping folder, need to specify type as CommerceBuilder.Shipping.ShipMethod instead of just ShipMethod
                CommerceBuilder.Shipping.ShipMethod selectedShipMethod = ShipMethodDataSource.Load(AlwaysConvert.ToInt(ShipMethodsList.SelectedValue));
                CustomFieldHelper.SetBool(basket, "ac_Baskets", "RushStatus", !selectedShipMethod.Name.ToLower().Contains("ground"));

                bool orginalChecked = ChargeMyShippingCheckBox.Checked;
                string shipperShortName = selectedShipMethod.ShipGateway.Name.StartsWith("UPS") ? "UPS" : (selectedShipMethod.ShipGateway.Name.StartsWith("FedEx") ? "FedEx" : string.Empty);
                if (!string.IsNullOrEmpty(shipperShortName))
                {
                    string usersShippingAccount = AbleContext.Current.User.Settings.GetValueByKey(shipperShortName + "Account", string.Empty);
                    if (!string.IsNullOrEmpty(usersShippingAccount))
                    {
                        ChargeMyShippingCheckBox.Text = string.Format("Charge my {0} account # {1}.<br />({0} will bill your account according to your agreed upon rates.)", shipperShortName, usersShippingAccount);
                        ChargeMyShippingCheckBox.Visible = true;
                        if (Page.IsPostBack)
                        {
                            // If "Select a shipping method..." is still at the top of the list (indicated
                            // by Items[0].Value == "-1"), that means this is the first time the user is
                            // choosing a shipping method for this basket.  Therefore, since we have their
                            // account number, we want the initial setting for ChargeMyShipping to be checked.
                            if (ShipMethodsList.Items[0].Value == "-1") ChargeMyShippingCheckBox.Checked = true;
                        }
                    }
                    else
                    {
                        ChargeMyShippingCheckBox.Text = "Charge my " + shipperShortName + " account.";
                        ChargeMyShippingCheckBox.Visible = false;
                        ChargeMyShippingCheckBox.Checked = false;
                    }
                }

                bool allMethodsValid = true;
                foreach (BasketShipment shipment in shipments)
                {
                    shipment.ShipMethod = selectedShipMethod;
                    shipment.ShipMessage = "";
                    shipment.Save();
                    if (shipment.ShipMethod == null) allMethodsValid = false;
                    _ShipmentIndex++;
                }
                if (!allMethodsValid)
                {
                    //HANDLE ERROR MESSAGE (UNEXPECTED)
                    InvalidShipMethodPanel.Visible = true;
                }

                // ChargeMyShippingCheckBox_CheckedChanged calls BindMethods, which potentially changes and saves the basket.  Therefore save/unrefrence it, then get it again after
                // trying this because every once in a while there was an error like this:
                /*
                2015-09-11 15:14:17,588 ERROR AbleCommerce         An error has occured at [the site]
                System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> NHibernate.StaleStateException: Unexpected row count: 0; expected: 1
                   at CommerceBuilder.DomainModel.EntityWithTypedId`1.Delete()
                   at CommerceBuilder.Shipping.ShipRateCalculator.ClearExistingShipping(Basket basket)
                   at CommerceBuilder.Shipping.ShipRateCalculator.Calculate(Basket basket)
                   at CommerceBuilder.Services.Checkout.BasketService.Recalculate(Basket basket)
                   at AbleCommerce.Checkout.Shipping.ShipMethodsList_SelectedIndexChanged(Object sender, EventArgs e)
                   ...etc...
                   (sometimes referred to taxes instead of shipping)
                */
                basket.Save();
                basket = null;
                if (ChargeMyShippingCheckBox.Checked != orginalChecked) ChargeMyShippingCheckBox_CheckedChanged(ChargeMyShippingCheckBox, e);
                basket = AbleContext.Current.User.Basket;

                IBasketService preCheckoutService = AbleContext.Resolve<IBasketService>();
                preCheckoutService.Recalculate(basket);

                if (basket.Items.Count == 0) Response.Redirect(AbleCommerce.Code.NavigationHelper.GetBasketUrl());
                if (!basket.Items.HasShippableProducts()) Response.Redirect("Payment.aspx");
                weightFormat = "{0:0.##} " + AbleContext.Current.Store.WeightUnit;
                if (ShipMethodsList.Items[0].Value == "-1") ShipMethodsList.Items.RemoveAt(0);
                ShipMethodsList.Font.Bold = false;
            }
        }
Jay

RickSilver
Lieutenant (LT)
Lieutenant (LT)
Posts: 66
Joined: Mon Jun 22, 2009 5:49 pm

Re: Updating Shipping Dropdown from custom address field

Post by RickSilver » Thu Jan 26, 2017 3:34 pm

Thanks! I'll check it out.

Post Reply