Custom Shipping Options

calibereqcalibereq Member
in Help edited May 2014
I need to know if this situation is possible:

We need to include a category specific shipping option to offer a lift gate truck for customers who don't have a forklift/loading dock on site for large equipment deliveries - this would need to be a required choice made by the customer before checkout could complete, but only applies to certain categories. We are also hoping to set up category specific flat rate shipping that could be adjusted by state.

Based on the Multiple Flat Rates snippet I thought I'd start small with just the loading dock question first - Here is my current code:
var hasCategoryWB = false;
var hasCategoryR = false;
for (p in fc_json.products) {
  switch (fc_json.products[p
].category) {
    case "WB":
      hasCategoryWB = true;
      break;
    case "R":
      hasCategoryR = true;
      break;
  }
}
if (hasCategoryWB) {
addShippingOption(1, 0.00, 'I have a Forklift/Loading Dock On Site');
addShippingOption(2, 125.00, 'I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
} else if (hasCategoryR) {
addShippingOption(1, 0.00, 'I have a Forklift/Loading Dock On Site');
addShippingOption(2, 125.00, 'I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
}	

Which appears to work but checkout can still complete without the customer making a choice - how do I make this required?

I just read on another thread that the admin category flat rate overrides everything so it should be set to 0. I was hoping to set the admin category flat rates to act as a base and add to it, but am I right in understanding this isn't possible and I should build all shipping prices out in the custom section?

If so, I'd love some direction on how best to combine both this required loading dock specification and a category-specific flat rate based on ship to state: both values added together to create a single shipping cost.

As an aside, this php/jquery stuff is starting to make some sense :)
Tagged:
Comments
  • calibereqcalibereq Member
    edited May 2014
    Ok, I've been playing around a bit more and I now have come up with this based off of the Multiple Flat Rates snippet and this thread for shipping country, hoping it could apply to a shipping STATE as well:
    function customShippingLogic() {
    /* BEGIN CUSTOM SHIPPING LOGIC */
    if (typeof(state_code) === "undefined") {state_code = "";}
    new_state_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_state").val() : $("#customer_state").val());
    if (state_code != new_state_code) { // The shipping state has changed!
      state_code = new_state_code;
      removeCustomShippingContainer(); // This call will make sure that when it updates, it starts fresh.
      
      if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) *R CATEGORY SPECIFICATION?* ) {
    	addShippingOption(1, 150.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(2, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) *WB CATEGORY SPECIFICATION?* ) {
    	addShippingOption(3, 250.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(4, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else ( jQuery.inArray(state_code, ["VA","DC","MD"] ) *C CATEGORY SPECIFICATION?* ) {
    	addShippingOption(5, 50.00, 'Flate Rate UPS Shipping');
    }
    /* END CUSTOM SHIPPING LOGIC */
    }
    

    Which seems to me like if I can get it working would cover both my flat rate shipping & loading dock question. I've hit a bit of a wall in my jQuery/php knowledge though, am I headed in the right direction? How can I make this category specific?

    Thanks!
  • fc_adamfc_adam FoxyCart Team
    edited May 2014
    @calibereq,

    Yep - you're heading in the right direction. To make it category specific too, you'd just add in that logic too, like this:
    function customShippingLogic() {
    /* BEGIN CUSTOM SHIPPING LOGIC */
    if (typeof(state_code) === "undefined") {state_code = "";}
    new_state_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_state").val() : $("#customer_state").val());
    if (state_code != new_state_code) { // The shipping state has changed!
      state_code = new_state_code;
      removeCustomShippingContainer(); // This call will make sure that when it updates, it starts fresh.
    
      var hasCategoryWB = false;
      var hasCategoryR = false;
      var hasCategoryC = false;
      for (p in fc_json.products) {
        switch (fc_json.products[p].category) {
          case "WB":
            hasCategoryWB = true;
            break;
          case "R":
            hasCategoryR = true;
            break;
          case "C":
            hasCategoryC = true;
            break;
        }
      }
     
      if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryR ) {
    	addShippingOption(1, 150.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(2, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryWB ) {
    	addShippingOption(3, 250.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(4, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryC ) {
    	addShippingOption(5, 50.00, 'Flate Rate UPS Shipping');
    }
    /* END CUSTOM SHIPPING LOGIC */
    }
    

    Worth noting - if you're wanting to restrict the checkout to just those few states, you can also do that using the snippet available from the wiki: http://wiki.foxycart.com/snippets/start
  • calibereqcalibereq Member
    edited May 2014
    EDIT: I got it working! I was missing a "-1" in my jQuery state arrays, thanks to this pastie google found for me!
    if ( jQuery.inArray(state_code, ["VA","DC","MD"] -1) && hasCategoryR ) {
    	addShippingOption(1, 150.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(2, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else if ( jQuery.inArray(state_code, ["VA","DC","MD"] -1) && hasCategoryWB ) {
    	addShippingOption(3, 250.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(4, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } else if ( jQuery.inArray(state_code, ["VA","DC","MD"] -1) && hasCategoryC ) {
    	addShippingOption(5, 50.00, 'Flat Rate UPS Shipping');
    }
    

    My question though of if the Shipping & Handling charges in Step 3 and under the item total should be updating when a custom shipping option selection is made still stands, as of right now they do not, but I'd very much like them to.

    I'm having trouble getting the combined version of code to work. I have started with the original category-based code from my first post which works fine, but when I add the state-based segments the custom shipping container doesn't appear with any options. I thought I was missing a bracket or maybe my if statements were the problem but nothing seems to be working:
      FC.checkout.config.customShipping = {
        onLoad: true,  // Set to false if you don't want shipping calculated when the checkout loads
        onLocationChange: true, // Set to true if your shipping logic relies on updating whenever the shipping location for the order changes
        onPreSubmit: true // Set to false if you don't want to load shipping if it hasn't already loaded before the user tries to checkout
      };
    
      function customShippingLogic() {
        /* BEGIN CUSTOM SHIPPING LOGIC */
    	
    if (typeof(state_code) === "undefined") {state_code = "";}
    new_state_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_state").val() : $("#customer_state").val());
    if (state_code != new_state_code) { // The shipping state has changed!
      state_code = new_state_code;
      removeCustomShippingContainer(); // This call will make sure that when it updates, it starts fresh.
      
    var hasCategoryWB = false;
    var hasCategoryR = false;
    for (p in fc_json.products) {
      switch (fc_json.products[p
    ].category) {
        case "WB":
          hasCategoryWB = true;
          break;
        case "R":
          hasCategoryR = true;
          break;
      }
    }
    if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryR ) {
    	addShippingOption(1, 150.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(2, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryWB ) {
    	addShippingOption(3, 250.00, 'I have a Forklift/Loading Dock On Site');
    	addShippingOption(4, 375.00, '+$125.00 I do not have a Forklift/Dock On Site - Lift Gate Truck Required');
    } if ( jQuery.inArray(state_code, ["VA","DC","MD"] ) && hasCategoryC ) {
    	addShippingOption(5, 50.00, 'Flate Rate UPS Shipping');
    }
    }
        /* END CUSTOM SHIPPING LOGIC */
      }
    
    Also, when I do have my options working, should "Shipping & Handling" in Step 3 & the Total be updating automatically when a selection is made because right now it isn't and I'd very much like it to!
  • fc_adamfc_adam FoxyCart Team
    @calibereq,

    If I'm understanding you correctly - you're asking if a customer chooses a shipping option, should the shipping cost be updated in the totals - the answer is yes. Could you whisper me your store so I can take a look please?
  • fc_adamfc_adam FoxyCart Team
    @calibereq,

    Ah I see - you're using multiship for your store, but the custom javascript snippet isn't designed to work with multiship.

    Are you actually wanting to use multiship for your store, as in are you actually allowing customers to purchase multiple products in a single order, but send different products to different addresses? If not, you can disable multiship for the store and the snippet will start working.
  • calibereqcalibereq Member
    edited May 2014
    That solved it, thank you!

    I have come across one last concern regarding these options. I wanted to add a header of some sort such as a 'step 2b: Shipping Methods' but then I discovered a bit of code that suggests a header should already be showing:
    jQuery("#fc_custom_shipping_methods_container").html('<h2>Shipping Options</h2><div class="fc_row fc_shipping_methods_container" id="fc_shipping_methods_container"><div class="fc_radio_group_container fc_row fc_shipping_methods" id="fc_shipping_methods"><input type="hidden" value="0" id="shipping_service_id" name="shipping_service_id"><input type="text" style="display:none;" value="" id="shipping_service_description" name="shipping_service_description"><input type="text" value="" id="shipping_details" name="Shipping_Details" style="display:none;" /><div class="fc_shipping_methods_inner" id="fc_shipping_methods_inner"></div><label style="display: none;" class="fc_error" for="fc_shipping_methods">Please select a shipping method.</label></div></div>');
    

    But it is not showing up anywhere. Am I misunderstanding or should <h2>Shipping Options</h2> be displayed above my custom shipping options? If so, what could be breaking it? I've checked and there is no overlapping css for the h2 tag. If it matters, I do have colorbox implemented for my cart display but have my checkout template formatted for a normal page.

    Thanks a million!!
  • fc_adamfc_adam FoxyCart Team
    @calibereq,

    The standard checkout CSS is probably hiding the h2 for you. Check the CSS and see if it's being hidden.
Sign In or Register to comment.