Code:
<?php
/*
Freightquote.com Shipping Module for Zen Cart
Copyright (c) 2010 Freightquote.com
Developed by Dynamo Effects - sales [at] dynamoeffects.com
Released under the GNU General Public License v2
*/
class freightquote {
var $code, $title, $description, $sort_order, $icon,
$tax_class, $enabled, $request, $response;
function freightquote() {
global $order, $db;
$this->code = 'freightquote';
$this->title = MODULE_SHIPPING_FREIGHTQUOTE_TEXT_TITLE;
$this->description = MODULE_SHIPPING_FREIGHTQUOTE_TEXT_DESCRIPTION;
$this->sort_order = MODULE_SHIPPING_FREIGHTQUOTE_SORT_ORDER;
$this->icon = '';
$this->tax_class = MODULE_SHIPPING_FREIGHTQUOTE_TAX_CLASS;
if (zen_get_shipping_enabled($this->code)) {
$this->enabled = (MODULE_SHIPPING_FREIGHTQUOTE_STATUS == 'True' ? true : false);
}
if (($this->enabled == true) && ((int)MODULE_SHIPPING_FREIGHTQUOTE_ZONE > 0)) {
$check_flag = false;
$check_query = $db->Execute(
"SELECT zone_id " .
"FROM " . TABLE_ZONES_TO_GEO_ZONES . " " .
"WHERE geo_zone_id = '" . MODULE_SHIPPING_FREIGHTQUOTE_ZONE . "' " .
" AND zone_country_id = '" . $order->delivery['country']['id'] . "' " .
"ORDER BY zone_id"
);
while (!$check_query->EOF) {
if ($check_query->fields['zone_id'] < 1) {
$check_flag = true;
break;
} elseif ($check_query->fields['zone_id'] == $order->delivery['zone_id']) {
$check_flag = true;
break;
}
$check_query->MoveNext();
}
if ($check_flag == false) {
$this->enabled = false;
}
}
}
function quote($method = '') {
global $db, $order, $currencies, $shipping;
//Array used to store data that will be fed into XML template
$shipping_info = array();
//This array will be turned into the XML that is sent to Freightquote.com
$request_xml = array(
'GetRatingEngineQuote' => array(
'request' => array(
'CustomerId' => $_SESSION['customer_id'],
'QuoteType' => 'B2B',
'ServiceType' => MODULE_SHIPPING_FREIGHTQUOTE_SERVICE_TYPE,
'QuoteShipment' => array(
'ShipmentLabel' => MODULE_SHIPPING_FREIGHTQUOTE_TEXT_SHIPMENT_LABEL,
'IsBlind' => (MODULE_SHIPPING_FREIGHTQUOTE_BLIND == 'True' ? 'true' : 'false'),
'ShipmentLocations' => array(
'Location' => array()
),
'ShipmentProducts' => array(
'Product' => array()
)
)
),
'user' => array(
'Name' => MODULE_SHIPPING_FREIGHTQUOTE_USERNAME,
'Password' => MODULE_SHIPPING_FREIGHTQUOTE_PASSWORD
)
)
);
//ZIP Code and country code of the destination address
$dest_zip = $order->delivery['postcode'];
$dest_country = $order->delivery['country']['iso_code_2'];
//Format the ZIP codes for the US and Canada
if ($dest_country == 'US') {
$dest_zip = preg_replace('/[^0-9]/', '', $dest_zip);
$dest_zip = substr($dest_zip, 0, 5);
} elseif ($dest_country == 'CA') {
$dest_zip = preg_replace('/[^0-9A-Z]/', '', strtoupper($dest_zip));
$dest_zip = substr($dest_zip, 0, 6);
}
$ship_country = zen_get_countries(MODULE_SHIPPING_FREIGHTQUOTE_SHIP_COUNTRY, true);
$ship_country = $ship_country['countries_iso_code_2'];
//Retrieve all products in the cart
$products = $_SESSION['cart']->get_products();
//Determine the type of location selected by the customer -- YW BEGIN
//$delivery_location = 1;
if (!isset($delivery_location)) {
switch (MODULE_SHIPPING_FREIGHTQUOTE_DELIVERY_LOCATION) {
case 'Residence':
$delivery_location = 0;
break;
case 'Commercial (with loading dock)':
$delivery_location = 2;
break;
case 'Construction Site':
$delivery_location = 3;
break;
case 'Commercial (no loading dock)':
default:
$delivery_location = 1;
break;
}
}
if (isset($_REQUEST['freightquote_delivery_location'])) {
$delivery_location = (int)$_REQUEST['freightquote_delivery_location'];
}
$delivery_info = array();
switch ($delivery_location) {
case '0':
$delivery_info['residence'] = 'true';
$delivery_info['construction_site'] = 'false';
$delivery_info['loading_dock'] = 'false';
break;
case '2':
$delivery_info['residence'] = 'false';
$delivery_info['construction_site'] = 'false';
$delivery_info['loading_dock'] = 'true';
break;
case '3':
$delivery_info['residence'] = 'false';
$delivery_info['construction_site'] = 'true';
$delivery_info['loading_dock'] = 'false';
break;
case '1':
default:
$delivery_info['residence'] = 'false';
$delivery_info['construction_site'] = 'false';
$delivery_info['loading_dock'] = 'false';
break;
}
$request_xml['GetRatingEngineQuote']['request']['QuoteShipment']['ShipmentLocations']['Location'] = array(
array(
'LocationName' => STORE_NAME,
'LocationType' => 'Origin',
'HasLoadingDock' => strtolower(MODULE_SHIPPING_FREIGHTQUOTE_LOADING_DOCK),
'IsConstructionSite' => strtolower(MODULE_SHIPPING_FREIGHTQUOTE_CONSTRUCTION_SITE),
'IsResidential' => strtolower(MODULE_SHIPPING_FREIGHTQUOTE_RESIDENCE),
'LocationAddress' => array(
'PostalCode' => MODULE_SHIPPING_FREIGHTQUOTE_SHIP_ZIP,
'CountryCode' => $ship_country
)
),
array(
'LocationName' => $order->delivery['firstname'] . ' ' . $order->delivery['lastname'],
'LocationType' => 'Destination',
'HasLoadingDock' => $delivery_info['loading_dock'],
'IsConstructionSite' => $delivery_info['construction_site'],
'IsResidential' => $delivery_info['residence'],
'LocationAddress' => array(
'PostalCode' => $dest_zip,
'CountryCode' => $dest_country
)
)
);
$product_list = array();
$counter = 1;
$excluded_items = 0;
foreach ($products as $product) {
$data = $db->Execute(
"SELECT products_freightquote_enable, products_freightquote_length, products_freightquote_width, " .
" products_freightquote_height, products_freightquote_class, products_freightquote_nmfc, " .
" products_freightquote_hzmt, products_freightquote_content_type, " .
" products_freightquote_package_type, products_freightquote_commodity_type " .
"FROM " . TABLE_PRODUCTS . " " .
"WHERE products_id = " . (int)$product['id'] . " " .
"LIMIT 1"
);
if ($data->fields['products_freightquote_enable'] == '1') {
$product_list[] = array(
'Class' => (zen_not_null($data->fields['products_freightquote_class']) ? $data->fields['products_freightquote_class'] : '50'),
'ProductDescription' => $product['name'],
'Weight' => ceil($product['quantity'] * (int)$product['weight']),
'Length' => ceil($data->fields['products_freightquote_length']),
'Width' => ceil($data->fields['products_freightquote_width']),
'Height' => ceil($data->fields['products_freightquote_height']),
'PackageType' => (zen_not_null($data->fields['products_freightquote_package_type']) ? $data->fields['products_freightquote_package_type'] : 'Boxes'),
'DeclaredValue' => round($product['price']),
'CommodityType' => (zen_not_null($data->fields['products_freightquote_commodity_type']) ? $data->fields['products_freightquote_commodity_type'] : 'GeneralMerchandise'),
'ContentType' => (zen_not_null($data->fields['products_freightquote_content_type']) ? $data->fields['products_freightquote_content_type'] : 'NewCommercialGoods'),
'IsHazardousMaterial' => $data->fields['products_freightquote_hzmt'],
'NMFC' => $data->fields['products_freightquote_nmfc'],
'PieceCount' => $product['quantity'],
'ItemNumber' => $counter
);
$counter++;
} else {
$excluded_items++;
}
}
$total_products = count($product_list);
if (count($total_products) < 1) {
if (MODULE_SHIPPING_FREIGHTQUOTE_DEBUG == 'True') {
return array(
'module' => $this->title,
'error' => "DEBUG: The products in your cart are not configured to be used with Freightquote.com"
);
}
return false;
}
/* Maximum 6 products allowed per query, so repeat the query multiple times if necessary */
$freightquote_queries = array();
$query_string = '';
/*
* Only 6 items allowed per query
*/
for ($x = 0; $x < $total_products; $x+=6) {
$product_request = array();
for ($n = 1; $n <= 6; $n++) {
$ret = ($n + $x) - 1;
if (isset($product_list[$ret])) {
$product_request[] = $product_list[$ret];
}
}
$request_xml['GetRatingEngineQuote']['request']['QuoteShipment']['ShipmentProducts']['Product'] = $product_request;
$request_result = $this->query_rates($request_xml);
if (isset($request_result['error'])) {
return array(
'module' => $this->title,
'error' => $request_result['error']
);
}
$freightquote_queries[] = $request_result['GetRatingEngineQuoteResponse'][0]['GetRatingEngineQuoteResult'][0];
}
$total_shipping_price = array(
'rate' => 0,
'shipment_id' => ''
);
$errors = array();
foreach ($freightquote_queries as $quote) {
if (is_array($quote['QuoteCarrierOptions'])) {
if ($total_shipping_price['shipment_id'] != '') $total_shipping_price['shipment_id'] .= ' & ';
$total_shipping_price['shipment_id'] .= $quote['QuoteId'];
$total_shipping_price['rate'] += preg_replace('/[^0-9\.]/', '', $quote['QuoteCarrierOptions'][0]['CarrierOption'][0]['QuoteAmount']);
} elseif (count($quote['ValidationErrors']) > 0) {
foreach ($quote['ValidationErrors'][0]['B2BError'] as $error_msg) {
$errors[] = $error_msg['ErrorMessage'];
}
}
}
/* If the shipping price is 0 and no errors were returned, don't display this shipping option */
if ($total_shipping_price['rate'] <= 0 && count($errors) < 1) {
if (MODULE_SHIPPING_FREIGHTQUOTE_DEBUG == 'True') {
return array(
'module' => $this->title,
'error' => "DEBUG: No shipping rates or errors were returned from Freightquote.com, so no shipping option is being returned."
);
}
return false;
}
//Add price modifier
if (MODULE_SHIPPING_FREIGHTQUOTE_PRICE_MODIFIER > 0) {
$total_shipping_price['rate'] = $total_shipping_price['rate'] * MODULE_SHIPPING_FREIGHTQUOTE_PRICE_MODIFIER;
}
//Add handling charges
$total_shipping_price['rate'] += MODULE_SHIPPING_FREIGHTQUOTE_HANDLING * $total_products;
$shipping_form = '';
if ($_POST['action'] != 'process') {
$shipping_form = '<table border="0" cellspacing="0" cellpadding="2">';
$shipping_form .= '<tr><td class="main" width="120">Delivery Location:</td><td class="main">';
$shipping_form .= '<select name="freightquote_delivery_location" onchange="window.location.href=\'' . zen_href_link(FILENAME_CHECKOUT_SHIPPING, 'freightquote_delivery_location=') . '\'+this.value">';
$shipping_form .= '<option value="0"' . ($delivery_location == '0' ? ' SELECTED' : '') . '>Residence</option>';
$shipping_form .= '<option value="1"' . (!isset($delivery_location) || $delivery_location == '1' ? ' SELECTED' : '') . '>Commercial (no loading dock)</option>';
$shipping_form .= '<option value="2"' . ($delivery_location == '2' ? ' SELECTED' : '') . '>Commercial (with loading dock)</option>';
$shipping_form .= '<option value="3"' . ($delivery_location == '3' ? ' SELECTED' : '') . '>Construction Site</option>';
$shipping_form .= '</select></td></tr>';
$shipping_form .= '</table>';
} else {
$shipping_form = '<br>Delivery Location: ';
switch ($delivery_location) {
case '0':
$shipping_form .= 'Residence';
break;
case '2':
$shipping_form .= 'Commercial (with loading dock)';
break;
case '3':
$shipping_form .= 'Construction Site';
break;
Bookmarks