Close

March 13, 2015

Magento Quick Product Ship Cost Tool

Recently, Google has started to require that shipping costs be consistent between what is estimated for the product and the final shipping cost. When you setup your Google Merchant Feed you have to setup your shipping costs to adequately reflect what you charge on your site. Debugging issues between your costs and what Google sees can be quite a challenge, so we put together a quick script to make the process easier.

If you are trying to debug why Google has flagged a shipping cost on your site, it can be a bit difficult. You have to add the product to your cart, go to the checkout, change the zip code to the one that Google tried, and update the shipping on your site. We built a quick tool with a lot of thanks from a StackOverflow Article. Essentially its a just a very simple hidden webform (password protect it using an .htaccess file). You enter the sku, zip, state and quantity. The form then calls your current Magento site (similar to a customer) and gets all the shipping rates that are presently enabled for a basic user (not based on the current user’s group).

While not packed with features, it gets the job done quickly and efficiently. This has helped us debug issues with the Google Merchant feeds in a very quick turnaround.
skucost

Code Listed Below:

	<style>
	.formy{
		width:25%;
	}
	div.row {border:none;margin:0 0 5px 0;float:left;width:100%;padding:6px 0;}
	div.row label {float:left;display:block;width:15em;font-weight:bold;padding:0 6px;}
	div.row label:hover {background:#FFFF66;cursor:pointer;}
	div.row fieldset {border:1px solid gray;margin:0 6px;}
	div.row fieldset span {display:block;}
	div.row fieldset span label {float:none;display:inline;}
	div.row fieldset legend {font-weight:bold;}
	div.requiredRow {border:2px solid #049;}
	</style>
<?
require_once('app/Mage.php');
error_reporting(E_ALL);
umask(0);
ini_set('display_errors',true); #Mage::setIsDeveloperMode(true);
Mage::app();
 
 
$sku=$_REQUEST['txt_sku'];
$zip=$_REQUEST['txt_zip'];
$state=$_REQUEST['region_id'];
$amount=$_REQUEST['txt_amount'];
 
if($sku==''):
	$sku='';
	$zip='10011';
	$state=41;
endif;
if($sku != ''): //we GOT ONNEEEEEEEE
	// product id, quantity, country, postcode
	$estobj=getShippingEstimate($sku,$amount,"US",$zip);
endif;
	//quick and dirty form by Accessify: http://www.accessify.com/tools-and-wizards/accessibility-tools/quick-form-builder/
?>
 
<div class='formy'>
		<form method="get" name="skugetter">
 
<div class="row requiredRow">
			<label for="txt_sku" id="sku-ariaLabel">Product Sku For Shipping</label>
			<input id="txt_sku" name="txt_sku" type="text" aria-labelledby="sku-ariaLabel" class="required" title="sku. This is a required field">
</div>
 
 
<div class="row requiredRow">
			<label for="txt_zip" id="zip-ariaLabel">Ship to Zipcode</label>
			<input id="txt_zip" name="txt_zip" type="text" value='19438' aria-labelledby="zip-ariaLabel" class="required" title="Your Zip">
</div>
 
 
 
<div class="row requiredRow">
			<label for="country">State</label>
 
                    <label for="region_id">State/Province</label>
                    <select class="required-entry validate-select validation-passed" defaultvalue="41" id="region_id" name="region_id" title="State/Province" style="">
 
<option value="">Please select region, state or province</option>
 
<option title="Alabama" value="1">Alabama</option>
<option title="Alaska" value="2">Alaska</option>
<option title="American Samoa" value="3">American Samoa</option>
<option title="Arizona" value="4">Arizona</option>
<option title="Arkansas" value="5">Arkansas</option>
<option title="Armed Forces Africa" value="6">Armed Forces Africa</option>
<option title="Armed Forces Americas" value="7">Armed Forces Americas</option>
<option title="Armed Forces Canada" value="8">Armed Forces Canada</option>
<option title="Armed Forces Europe" value="9">Armed Forces Europe</option>
<option title="Armed Forces Middle East" value="10">Armed Forces Middle East</option>
<option title="Armed Forces Pacific" value="11">Armed Forces Pacific</option>
<option title="California" value="12">California</option>
<option title="Colorado" value="13">Colorado</option>
<option title="Connecticut" value="14">Connecticut</option>
<option title="Delaware" value="15">Delaware</option>
<option title="District of Columbia" value="16">District of Columbia</option>
<option title="Federated States Of Micronesia" value="17">Federated States Of Micronesia</option>
<option title="Florida" value="18">Florida</option>
<option title="Georgia" value="19">Georgia</option>
<option title="Guam" value="20">Guam</option>
<option title="Hawaii" value="21">Hawaii</option>
<option title="Idaho" value="22">Idaho</option>
<option title="Illinois" value="23">Illinois</option>
<option title="Indiana" value="24">Indiana</option>
<option title="Iowa" value="25">Iowa</option>
<option title="Kansas" value="26">Kansas</option>
<option title="Kentucky" value="27">Kentucky</option>
<option title="Louisiana" value="28">Louisiana</option>
<option title="Maine" value="29">Maine</option>
<option title="Marshall Islands" value="30">Marshall Islands</option>
<option title="Maryland" value="31">Maryland</option>
<option title="Massachusetts" value="32">Massachusetts</option>
<option title="Michigan" value="33">Michigan</option>
<option title="Minnesota" value="34">Minnesota</option>
<option title="Mississippi" value="35">Mississippi</option>
<option title="Missouri" value="36">Missouri</option>
<option title="Montana" value="37">Montana</option>
<option title="Nebraska" value="38">Nebraska</option>
<option title="Nevada" value="39">Nevada</option>
<option title="New Hampshire" value="40">New Hampshire</option>
<option title="New Jersey" value="41" >New Jersey</option>
<option title="New Mexico" value="42">New Mexico</option>
<option title="New York" value="43">New York</option>
<option title="North Carolina" value="44">North Carolina</option>
<option title="North Dakota" value="45">North Dakota</option>
<option title="Northern Mariana Islands" value="46">Northern Mariana Islands</option>
<option title="Ohio" value="47">Ohio</option>
<option title="Oklahoma" value="48">Oklahoma</option>
<option title="Oregon" value="49">Oregon</option>
<option title="Palau" value="50">Palau</option>
<option title="Pennsylvania" value="51">Pennsylvania</option>
<option title="Puerto Rico" value="52">Puerto Rico</option>
<option title="Rhode Island" value="53">Rhode Island</option>
<option title="South Carolina" value="54">South Carolina</option>
<option title="South Dakota" value="55">South Dakota</option>
<option title="Tennessee" value="56">Tennessee</option>
<option title="Texas" value="57">Texas</option>
<option title="Utah" value="58">Utah</option>
<option title="Vermont" value="59">Vermont</option>
<option title="Virgin Islands" value="60">Virgin Islands</option>
<option title="Virginia" value="61">Virginia</option>
<option title="Washington" value="62">Washington</option>
<option title="West Virginia" value="63">West Virginia</option>
<option title="Wisconsin" value="64">Wisconsin</option>
<option title="Wyoming" value="65">Wyoming</option>
 
</select>
 
 
</div>
 
 
<div class="row requiredRow">
			<label for="txt_zip" id="zip-ariaLabel">How many?</label>
			<input id="txt_amount" name="txt_amount" type="text" value='1' aria-labelledby="zip-ariaLabel" class="required" title="How Many?">
</div>
 
 
 
<div class="row">
		<input type="submit" value="Lookup Lowest Rate">
</div>
 
		</form>
</div>
 
<?
if (isset($estobj)):
 
		usort($estobj,'boomcmp');
	?>
 
<div style="clear:both;padding-top:20px">
 
<h2> Rates from lowest to highest</h2>
 
 
	<? foreach($estobj as $ar):
			print "
 $".$ar['Price']."&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>".$ar['Title']."</strong>";
		endforeach;
 
 
	?>
</div>
 
<?	
endif;
function boomcmp($a,$b){
	  if ($a == $b) {
        return 0;
    }
    if($a['Price']==$b['Price']) return 0;
 
	return ($a['Price']<$b['Price'])? -1: 1;
 
}
 
//Borrowed from William: http://stackoverflow.com/questions/12952870/get-magento-shipping-quote-rates-list-from-external-code
function getShippingEstimate($sku,$productQty,$countryId,$postcode ) {
 
    $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore('default')->getId());
    $product = Mage::getModel('catalog/product')->getCollection()
		/* Remember, you can load/find product via any attribute, better if its attribute with unique value */
		->addAttributeToFilter('sku', $sku)
		->addAttributeToSelect('*')
		->getFirstItem();
    $_product = Mage::getModel('catalog/product')->load($product->getId());
    $_product->getStockItem()->setUseConfigManageStock(false);
    $_product->getStockItem()->setManageStock(false);
    $quote->addProduct($_product, $productQty);
    $quote->getShippingAddress()->setCountryId($countryId)->setPostcode($postcode); 
    $quote->getShippingAddress()->collectTotals();
    $quote->getShippingAddress()->setCollectShippingRates(true);
    $quote->getShippingAddress()->collectShippingRates();
 
    $_rates = $quote->getShippingAddress()->getShippingRatesCollection();
 
    $shippingRates = array();
    foreach ($_rates as $_rate):
            if($_rate->getPrice() > 0) {
                $shippingRates[] =  array("Title" => $_rate->getMethodTitle(), "Price" => $_rate->getPrice());
            }
    endforeach;
 
    return $shippingRates;
 
}
?>