Custom Shipping Rate Based on Product Category

rainleaderrainleader Member
in Help edited November 2012
I need to implement a custom shipping rate based on whether an order contains items of a certain category. If it doesn't, a standard flat-rate will apply.

Specifics:

If the order includes any items within the "coffee" category, the shipping price should be calculated as follows: 1 coffee item = $5 flat rate, <=5 coffee items = $11 flat rate, >6 coffee items = free. Note: This shipping rate applies to the entire, so ordering 6 coffee items makes the entire purchase (including non-coffee items) ship free-of-charge.

If the order does not include any items within the "coffee" category, the order should have a $12 flat-rate charge.

Any help implementing this would be much appreciated.

Here's the code:
/* BEGIN CUSTOM SHIPPING LOGIC */
jQuery(document).ready(function() {
var hasCoffee = false;
var amount = fc_json.product_count;
for (var p in fc_json.products) {
if (fc_json.products[p].category == "coffee") {
hasCoffee = true;
}
}
if (hasCoffee) {
if (amount == 1) {
  shippingCost += 5 ; // $5 for one coffee product
} else if (amount < 6) {
  shippingCost += 11; // $11 for less than 6 coffee products
} else { // free for more than 6 coffee products
  shippingCost = 0; // Free shipping because they bought so much
}
}
});

  /* END CUSTOM SHIPPING LOGIC */
Comments
  • fc_adamfc_adam FoxyCart Team
    edited November 2012
    Hi @rainleader,

    I'd modify your script as follows:
    /* BEGIN CUSTOM SHIPPING LOGIC */
    shippingCost = 12;
    
    var coffeeProducts = 0;
    for (var p in fc_json.products) {
    	if (fc_json.products[p].category == "coffee") {
    		coffeeProducts += fc_json.products[p].quantity;
    
    	}
    }
    
    if (coffeeProducts > 0) {
    	if (coffeeProducts == 1) {
    		shippingCost = 5 ; // $5 for one coffee product
    	} else if (coffeeProducts < 6) {
    		shippingCost = 11; // $11 for less than 6 coffee products
    	} else { // free for more than 6 coffee products
    		shippingCost = 0; // Free shipping because they bought so much
    	}
    }
    /* END CUSTOM SHIPPING LOGIC */
    

    And follow the instructions on this page, using the above as your custom logic when required: http://wiki.foxycart.com/snippets/shipping/tiered_flat_rate_shipping
  • rainleaderrainleader Member
    edited November 2012
    Thanks! That worked perfectly. I'm really impressed with the FC support.

    So, if these rates should be adjusted based on whether the shipping address is within the US or Canada, do I just create another conditional statement?
  • fc_adamfc_adam FoxyCart Team
    @rainleader,

    Yeah, you'd add an if/else block as required.
  • Thanks!
  • rainleaderrainleader Member
    edited November 2012
    I did two things: (a) added an if statement to set the shipping to a flat rate if a coupon is used and (b) added custom a custom country code switch statement. The first one (a) works, the second one (b) does not.

    Any thoughts?

    Here is my code:
    /* BEGIN CUSTOM SHIPPING LOGIC */
    shippingCost = 12;
     
    var coffeeProducts = 0;
    for (var p in fc_json.products) {
    	if (fc_json.products[p].category == "coffee") {
    		coffeeProducts += fc_json.products[p].quantity;
     
    	}
    }
     
    if (coffeeProducts > 0) {
    	if (coffeeProducts == 1) {
    		shippingCost = 5 ; // $5 for one coffee product
    	} else if (coffeeProducts < 6) {
    		shippingCost = 11; // $11 for less than 6 coffee products
    	} else { // free for more than 6 coffee products
    		shippingCost = 0; // Free shipping because they bought so much
    	}
    }
    
    if (fc_json.hasOwnProperty('coupons')) {
            shippingCost = 11;
    }
    
    if (typeof(country_code) === "undefined") {country_code = "";}
    new_country_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_country").val() : $("#customer_country").val());
    if (country_code != new_country_code) { // The shipping country has changed!
      country_code = new_country_code;
      switch (country_code) {
        case "CA":
          shippingCost = 32.95;
          break;
        default:
          shippingCost = shippingCost;
      }
    }
    
    /* END CUSTOM SHIPPING LOGIC */
    
  • fc_joshfc_josh FoxyCart Team
    Hey rainleader.
    Just wanted to let you know that we are looking at your code to see why it is not fully working. Some of our team is on the road today, but someone will respond soon.

    Thanks,
    Josh
  • rainleaderrainleader Member
    edited November 2012
    Thanks for the update.
  • fc_adamfc_adam FoxyCart Team
    @rainleader,

    Could you link us to your checkout where this is included please? I'd like to see it in action how you've included it if possible.
  • Sent via whisper.
  • fc_adamfc_adam FoxyCart Team
    @rainleader,

    So the issue is that the code doesn't know to run when the location changes. In your code, set the "onLocationChange" variable to true. That should work fine for you, but I'd suggest switching your country code to this:
    country_code = (jQuery("#use_different_addresses").is(":checked") ? $("#shipping_country").val() : $("#customer_country").val());
    console.log(country_code);
    switch (country_code) {
    	case "CA":
      		shippingCost = 32.95;
      		break;
    }
    

    That just simplifies it a bit for what you need.
  • Worked like a charm, thanks!
  • This is an older thread, but I've been using it to try and figure out how to do something similar with two categories instead of one. My shipping is free for everything else except the posters & stickers categories.

    For posters; $5 shipping for one poster, $3 shipping per poster if you buy 2 or more.
    For stickers; $1.50 shipping per stickers (we actually sell them in three sticker packs, but consider that one sticker product)

    I've tried pulling the quantities for each individual category, multiple the category quantity by the category price, and then tried adding the two separate category prices together to equal the total shippingCost.

    I'm also a complete javascript noob and have to bumble my way through it to try to get it to work, so bare with me.

    here's what I have... and it doesn't work

    :
    /* BEGIN CUSTOM SHIPPING LOGIC */
    
    var posterProducts = 0;
    var posterAmount = 0;
    var posterShipping = 0;
    var stickerProducts = 0;
    var stickerAmount = 0;
    var stickerShipping = 0;
    
    for (var p in fc_json.products) {
    	if (fc_json.products[p].category == "posters") {
    		posterProducts += fc_json.products[p].quantity;
    		posterAmount += fc_json.products[p].quantity;
    	} 
    }
    
    for (var p in fc_json.products) {
    	if (fc_json.products[p].category == "stickers") {
    		stickerProducts += fc_json.products[p].quantity;
    		stickerAmount += fc_json.products[p].quantity;
    	} 
    }
    
    if (posterProducts > 0) {
    	if (posterProducts == 1) {
    		posterShipping = 5; // $5 for one poster
    	} else if (posterProducts > 1) {
    		posterShipping = 3 * posterAmount; // $3 for each poster
    	} 
    }
    
    if (stickerProducts > 0) {
    	stickerShipping = 1.5 * stickerAmount;
    )
    
    shippingCost = paseFloat(posterShipping) + parseFloat(stickerShipping);
    
    /* END CUSTOM SHIPPING LOGIC */
    

    Any help would be greatly appreciated.
  • fc_adamfc_adam FoxyCart Team
    @CPavel,

    You can simplify what you had to this:
    /* BEGIN CUSTOM SHIPPING LOGIC */
     
    var posterProducts = 0;
    var stickerProducts = 0;
     
    for (var p in fc_json.products) {
    	if (fc_json.products[p].category == "posters") {
    		posterProducts += fc_json.products[p].quantity;
    	} 
    
    	if (fc_json.products[p].category == "stickers") {
    		stickerProducts += fc_json.products[p].quantity;
    	} 
    }
     
    if (posterProducts > 0) {
    	if (posterProducts == 1) {
    		shippingCost += 5; // $5 for one poster
    	} else if (posterProducts > 1) {
    		shippingCost += 3 * posterProducts; // $3 for each poster
    	} 
    }
     
    shippingCost += 1.5 * stickerProducts;
     
    /* END CUSTOM SHIPPING LOGIC */
    

    But what you had should be working fine as well - could you link me to your site so I can see it in action please?
  • Thanks for the super quick response! I just implemented the code you posted and it works!

    I think I had goofed something on the actual cart page and didn't have the exact code that I pasted in the forum.
  • fc_adamfc_adam FoxyCart Team
    edited March 2013
    @CPavel,

    Awesome - glad it worked! Great looking site too!
Sign In or Register to comment.