uc_usps.module in Ubercart 6.2
Same filename and directory in other branches
Shipping quote method module that receives quotes from the United States Postal Service via XML web service.
File
shipping/uc_usps/uc_usps.moduleView source
<?php
/**
* @file
* Shipping quote method module that receives quotes from the United States
* Postal Service via XML web service.
*/
/******************************************************************************
* Drupal Hooks *
******************************************************************************/
/**
* Implements hook_menu().
*/
function uc_usps_menu() {
$items = array();
$items['admin/store/settings/quotes/methods/usps'] = array(
'title' => 'USPS',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_usps_admin_settings',
),
'access arguments' => array(
'configure quotes',
),
'type' => MENU_LOCAL_TASK,
'file' => 'uc_usps.admin.inc',
);
return $items;
}
/**
* Implements hook_theme().
*/
function uc_usps_theme() {
return array(
'uc_usps_option_label' => array(
'arguments' => array(
'service' => NULL,
'packages' => NULL,
),
),
);
}
/**
* Implements hook_form_alter().
*
* Add package type to products.
*
* @see uc_product_form()
*/
function uc_usps_form_alter(&$form, $form_state, $form_id) {
if (uc_product_is_product_form($form)) {
$node = $form['#node'];
$enabled = variable_get('uc_quote_enabled', array());
$weight = variable_get('uc_quote_method_weight', array(
'usps' => 0,
'usps_intl' => 1,
));
$form['shipping']['usps'] = array(
'#type' => 'fieldset',
'#title' => t('USPS product description'),
'#collapsible' => TRUE,
'#collapsed' => $enabled['usps'] == FALSE || uc_product_get_shipping_type($node) != 'small_package',
'#weight' => $weight['usps'],
'#tree' => TRUE,
);
$form['shipping']['usps']['container'] = array(
'#type' => 'select',
'#title' => t('Package type'),
'#options' => _uc_usps_pkg_types(),
'#default_value' => isset($node->usps['container']) ? $node->usps['container'] : 'VARIABLE',
);
}
}
/**
* Implements hook_nodeapi().
*/
function uc_usps_nodeapi(&$node, $op) {
if (uc_product_is_product($node->type)) {
switch ($op) {
case 'insert':
case 'update':
if (isset($node->usps)) {
$usps_values = $node->usps;
if (!$node->revision) {
db_query("DELETE FROM {uc_usps_products} WHERE vid = %d", $node->vid);
}
db_query("INSERT INTO {uc_usps_products} (vid, nid, container) VALUES (%d, %d, '%s')", $node->vid, $node->nid, $usps_values['container']);
}
break;
case 'load':
if (uc_product_get_shipping_type($node) == 'small_package') {
return array(
'usps' => db_fetch_array(db_query("SELECT * FROM {uc_usps_products} WHERE vid = %d", $node->vid)),
);
}
break;
case 'delete':
db_query("DELETE FROM {uc_usps_products} WHERE nid = %d", $node->nid);
break;
case 'delete revision':
db_query("DELETE FROM {uc_usps_products} WHERE vid = %d", $node->vid);
break;
}
}
}
/******************************************************************************
* Conditional Actions Hooks *
******************************************************************************/
/**
* Implements hook_ca_predicate().
*
* Connect USPS quote action and event.
*/
function uc_usps_ca_predicate() {
$enabled = variable_get('uc_quote_enabled', array());
$quote_action = array(
'#name' => 'uc_quote_action_get_quote',
'#title' => t('Fetch a shipping quote'),
'#argument_map' => array(
'order' => 'order',
'method' => 'method',
),
);
// Domestic areas include U.S., American Samoa, Guam, Puerto Rico, and the Virgin Islands
$countries = array(
16,
316,
630,
840,
850,
);
$predicates = array(
'uc_usps_get_quote' => array(
'#title' => t('Shipping quote from USPS'),
'#trigger' => 'get_quote_from_usps',
'#class' => 'uc_usps',
'#status' => $enabled['usps'],
'#conditions' => array(
'#operator' => 'AND',
'#conditions' => array(
array(
'#name' => 'uc_order_condition_delivery_country',
'#title' => t('Is in domestic US areas (US, AS, GU, PR, VI)'),
'#argument_map' => array(
'order' => 'order',
),
'#settings' => array(
'countries' => $countries,
),
),
),
),
'#actions' => array(
$quote_action,
),
),
'uc_usps_get_env_quote' => array(
'#title' => t('Shipping quote from USPS'),
'#trigger' => 'get_quote_from_usps_env',
'#class' => 'uc_usps',
'#status' => $enabled['usps_env'],
'#conditions' => array(
'#operator' => 'AND',
'#conditions' => array(
array(
'#name' => 'uc_order_condition_delivery_country',
'#title' => t('Is in domestic US areas (US, AS, GU, PR, VI)'),
'#argument_map' => array(
'order' => 'order',
),
'#settings' => array(
'countries' => $countries,
),
),
),
),
'#actions' => array(
$quote_action,
),
),
'uc_usps_get_intl_quote' => array(
'#title' => t('Shipping quote from USPS Intl.'),
'#trigger' => 'get_quote_from_usps_intl',
'#class' => 'uc_usps',
'#status' => $enabled['usps_intl'],
'#conditions' => array(
'#operator' => 'AND',
'#conditions' => array(
array(
'#name' => 'uc_order_condition_delivery_country',
'#title' => t('Is not in domestic US areas (US, AS, GU, PR, VI)'),
'#argument_map' => array(
'order' => 'order',
),
'#settings' => array(
'negate' => TRUE,
'countries' => $countries,
),
),
),
),
'#actions' => array(
$quote_action,
),
),
'uc_usps_get_intl_env_quote' => array(
'#title' => t('Shipping quote from USPS Intl.'),
'#trigger' => 'get_quote_from_usps_intl_env',
'#class' => 'uc_usps',
'#status' => $enabled['usps_intl_env'],
'#conditions' => array(
'#operator' => 'AND',
'#conditions' => array(
array(
'#name' => 'uc_order_condition_delivery_country',
'#title' => t('Is not in domestic US areas (US, AS, GU, PR, VI)'),
'#argument_map' => array(
'order' => 'order',
),
'#settings' => array(
'negate' => TRUE,
'countries' => $countries,
),
),
),
),
'#actions' => array(
$quote_action,
),
),
);
return $predicates;
}
/******************************************************************************
* Ubercart Hooks *
******************************************************************************/
/**
* Implements hook_shipping_type().
*/
function uc_usps_shipping_type() {
$weight = variable_get('uc_quote_type_weight', array(
'envelope' => -1,
'small_package' => 0,
));
$types = array(
'envelope' => array(
'id' => 'envelope',
'title' => t('Envelope'),
'weight' => $weight['envelope'],
),
'small_package' => array(
'id' => 'small_package',
'title' => t('Small package'),
'weight' => $weight['small_package'],
),
);
return $types;
}
/**
* Implements hook_shipping_method().
*/
function uc_usps_shipping_method() {
$enabled = variable_get('uc_quote_enabled', array());
$weight = variable_get('uc_quote_method_weight', array(
'usps_env' => 0,
'usps' => 0,
'usps_intl_env' => 1,
'usps_intl' => 1,
));
$methods = array(
'usps_env' => array(
'id' => 'usps_env',
'module' => 'uc_usps',
'title' => t('U.S. Postal Service (Envelope)'),
'quote' => array(
'type' => 'envelope',
'callback' => 'uc_usps_quote',
'accessorials' => _uc_usps_env_services(),
),
'enabled' => $enabled['usps_env'],
'weight' => $weight['usps_env'],
),
'usps' => array(
'id' => 'usps',
'module' => 'uc_usps',
'title' => t('U.S. Postal Service (Parcel)'),
'quote' => array(
'type' => 'small_package',
'callback' => 'uc_usps_quote',
'accessorials' => _uc_usps_services(),
),
'enabled' => $enabled['usps'],
'weight' => $weight['usps'],
),
'usps_intl_env' => array(
'id' => 'usps_intl_env',
'module' => 'uc_usps',
'title' => t('U.S. Postal Service (Intl., Envelope)'),
'quote' => array(
'type' => 'envelope',
'callback' => 'uc_usps_quote',
'accessorials' => _uc_usps_intl_env_services(),
),
'enabled' => $enabled['usps_intl_env'],
'weight' => $weight['usps_intl_env'],
),
'usps_intl' => array(
'id' => 'usps_intl',
'module' => 'uc_usps',
'title' => t('U.S. Postal Service (Intl., Parcel)'),
'quote' => array(
'type' => 'small_package',
'callback' => 'uc_usps_quote',
'accessorials' => _uc_usps_intl_services(),
),
'enabled' => $enabled['usps_intl'],
'weight' => $weight['usps_intl'],
),
);
return $methods;
}
/******************************************************************************
* Module Functions *
******************************************************************************/
/**
* Callback for retrieving USPS shipping quote.
*
* @param $products
* Array of cart contents.
* @param $details
* Order details other than product information.
* @param $method
* The shipping method to create the quote.
*
* @return
* JSON object containing rate, error, and debugging information.
*/
function uc_usps_quote($products, $details, $method) {
// The uc_quote AJAX query can fire before the customer has completely
// filled out the destination address, so check to see whether the address
// has all needed fields. If not, abort.
$destination = (object) $details;
// Country code is always needed.
if (empty($destination->country)) {
// Skip this shipping method.
return array();
}
// Shipments to the US also need zone and postal_code.
if ($destination->country == 840 && (empty($destination->zone) || empty($destination->postal_code))) {
// Skip this shipping method.
return array();
}
// USPS Production server.
$connection_url = 'http://production.shippingapis.com/ShippingAPI.dll';
// Initialize $services to prevent PHP notices here and in uc_quote.
$services['data'] = array(
'debug' => NULL,
'error' => '',
);
$addresses = array(
(array) variable_get('uc_quote_store_default_address', new stdClass()),
);
$packages = _uc_usps_package_products($products, $addresses);
if (!count($packages)) {
return array();
}
foreach ($packages as $key => $ship_packages) {
$orig = (object) $addresses[$key];
$orig->email = uc_store_email();
if (strpos($method['id'], 'intl') && $destination->country != 840) {
// Build XML for international rate request
$request = uc_usps_intl_rate_request($ship_packages, $orig, $destination);
}
elseif ($destination->country == 840) {
// Build XML for domestic rate request
$request = uc_usps_rate_request($ship_packages, $orig, $destination);
}
if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) {
$services['data']['debug'] .= htmlentities(urldecode($request)) . "<br />\n";
}
$result = drupal_http_request($connection_url, array(), 'POST', $request);
if (user_access('configure quotes') && variable_get('uc_quote_display_debug', FALSE)) {
$services['data']['debug'] .= htmlentities($result->data) . "<br />\n";
}
$rate_type = variable_get('uc_usps_online_rates', FALSE);
$response = new SimpleXMLElement($result->data);
// Map double-encoded HTML markup in service names to Unicode characters
$service_markup = array(
'<sup>&reg;</sup>' => '®',
'<sup>&trade;</sup>' => '™',
'<sup>®</sup>' => '®',
'<sup>™</sup>' => '™',
'**' => '',
);
// Use this map to fix USPS service names
if (strpos($method['id'], 'intl')) {
// Find and replace markup in International service names
foreach ($response
->xpath('//Service') as $service) {
$service->SvcDescription = str_replace(array_keys($service_markup), $service_markup, $service->SvcDescription);
}
}
else {
// Find and replace markup in Domestic service names
foreach ($response
->xpath('//Postage') as $postage) {
$postage->MailService = str_replace(array_keys($service_markup), $service_markup, $postage->MailService);
}
}
if (isset($response->Package)) {
foreach ($response->Package as $package) {
if (isset($package->Error)) {
$services['data']['error'] .= (string) $package->Error[0]->Description . '<br />';
}
else {
if (strpos($method['id'], 'intl')) {
foreach ($package->Service as $service) {
$id = (string) $service['ID'];
$services[$id]['label'] = t('U.S.P.S. @service', array(
'@service' => (string) $service->SvcDescription,
));
// Markup rate before customer sees it
if (!isset($services[$id]['rate'])) {
$services[$id]['rate'] = 0;
}
$services[$id]['rate'] += uc_usps_markup((string) $service->Postage);
}
}
else {
foreach ($package->Postage as $postage) {
$classid = (string) $postage['CLASSID'];
if ($classid === '0') {
if ((string) $postage->MailService == "First-Class Mail® Parcel") {
$classid = 'zeroParcel';
}
elseif ((string) $postage->MailService == "First-Class Mail® Letter") {
$classid = 'zeroFlat';
}
else {
$classid = 'zero';
}
}
if (!isset($services[$classid]['rate'])) {
$services[$classid]['rate'] = 0;
}
$services[$classid]['label'] = t('U.S.P.S. @service', array(
'@service' => (string) $postage->MailService,
));
// Markup rate before customer sees it
// Rates are stored differently if ONLINE $rate_type is requested.
// First Class doesn't have online rates, so if CommercialRate
// is missing use Rate instead
if ($rate_type && !empty($postage->CommercialRate)) {
$services[$classid]['rate'] += uc_usps_markup((string) $postage->CommercialRate);
}
else {
$services[$classid]['rate'] += uc_usps_markup((string) $postage->Rate);
}
}
}
}
}
}
}
$method_services = 'uc_' . $method['id'] . '_services';
$usps_services = array_filter(variable_get($method_services, array_keys(call_user_func('_' . $method_services))));
foreach ($services as $service => $quote) {
if ($service != 'data' && !in_array($service, $usps_services)) {
unset($services[$service]);
}
}
$context = array(
'revision' => 'themed',
'type' => 'amount',
);
foreach ($services as $key => $quote) {
if (isset($quote['rate'])) {
$context['subject']['quote'] = $quote;
$context['revision'] = 'altered';
$services[$key]['rate'] = uc_price($quote['rate'], $context);
$context['revision'] = 'formatted';
$services[$key]['format'] = uc_price($quote['rate'], $context);
$services[$key]['option_label'] = theme('uc_usps_option_label', $quote['label'], $packages);
}
}
// Separate debug data out of $services. This is necessary because
// $services['data'] is not sortable by a 'rate' key, so it has to be
// kept separate from the reset of the $services array until after the sort.
$debug_data = $services['data'];
unset($services['data']);
uasort($services, 'uc_quote_price_sort');
if (isset($debug_data['debug']) || isset($debug_data['error']) && count($debug_data['error'])) {
$services['data'] = $debug_data;
}
return $services;
}
/**
* Theme function to format the USPS service name and rate amount line-item
* shown to the customer.
*
* @param $service
* The USPS service name.
* @param $packages
* Package information.
*
* @ingroup themeable
*/
function theme_uc_usps_option_label($service, $packages) {
// Start with USPS logo
$output = theme('image', drupal_get_path('module', 'uc_usps') . '/uc_usps_logo.gif', t('U.S.P.S.'), '', array(
'class' => 'usps-logo',
));
// Add USPS service name, removing any 'U.S.P.S.' prefix.
$output .= preg_replace('/^U\\.S\\.P\\.S\\./', '', $service);
// Add package information
$output .= ' (' . format_plural(count($packages), '1 package', '@count packages') . ')';
return $output;
}
/**
* Constructs a quote request for domestic shipments.
*
* @param $packages
* Array of packages received from the cart.
* @param $origin
* Delivery origin address information.
* @param $destination
* Delivery destination address information.
*
* @return
* RateV4Request XML document to send to USPS
*/
function uc_usps_rate_request($packages, $origin, $destination) {
$request = '<RateV4Request USERID="' . variable_get('uc_usps_user_id', '') . '">';
$request .= '<Revision>2</Revision>';
$rate_type = variable_get('uc_usps_online_rates', FALSE);
$package_id = 0;
foreach ($packages as $package) {
$qty = $package->qty;
for ($i = 0; $i < $qty; $i++) {
$request .= '<Package ID="' . $package_id . '">' . '<Service>' . ($rate_type ? 'ONLINE' : 'ALL') . '</Service>' . '<ZipOrigination>' . substr(trim($origin->postal_code), 0, 5) . '</ZipOrigination>' . '<ZipDestination>' . substr(trim($destination->postal_code), 0, 5) . '</ZipDestination>' . '<Pounds>' . intval($package->pounds) . '</Pounds>' . '<Ounces>' . number_format($package->ounces, 1, '.', '') . '</Ounces>' . '<Container>' . $package->container . '</Container>' . '<Size>' . $package->size . '</Size>' . '<Width>' . $package->width . '</Width>' . '<Length>' . $package->length . '</Length>' . '<Height>' . $package->height . '</Height>' . '<Girth>' . $package->girth . '</Girth>' . '<Machinable>' . ($package->machinable ? 'True' : 'False') . '</Machinable>' . '</Package>';
$package_id++;
}
}
$request .= '</RateV4Request>';
return 'API=RateV4&XML=' . drupal_urlencode($request);
}
/**
* Constructs a quote request for international shipments.
*
* @param $packages
* Array of packages received from the cart.
* @param $origin
* Delivery origin address information.
* @param $destination
* Delivery destination address information.
*
* @return
* IntlRateRequest XML document to send to USPS
*/
function uc_usps_intl_rate_request($packages, $origin, $destination) {
module_load_include('inc', 'uc_usps', 'uc_usps.countries');
$request = '<IntlRateV2Request USERID="' . variable_get('uc_usps_user_id', '') . '">';
$request .= '<Revision>2</Revision>';
// USPS does not use ISO 3166 country name in some cases so we
// need to transform ISO country name into one USPS understands.
$shipto_country = uc_usps_country_map($destination->country);
$package_id = 0;
foreach ($packages as $package) {
$qty = $package->qty;
for ($i = 0; $i < $qty; $i++) {
$request .= '<Package ID="' . $package_id . '">' . '<Pounds>' . intval($package->pounds) . '</Pounds>' . '<Ounces>' . ceil($package->ounces) . '</Ounces>' . '<MailType>All</MailType>' . '<ValueOfContents>' . $package->price . '</ValueOfContents>' . '<Country>' . $shipto_country . '</Country>' . '<Container>' . 'RECTANGULAR' . '</Container>' . '<Size>' . 'REGULAR' . '</Size>' . '<Width>' . '</Width>' . '<Length>' . '</Length>' . '<Height>' . '</Height>' . '<Girth>' . '</Girth>' . '<OriginZip>' . substr(trim($origin->postal_code), 0, 5) . '</OriginZip>';
// Check if we need to add any special services to this package
if (variable_get('uc_usps_insurance', FALSE)) {
$request .= '<ExtraServices><ExtraService>1</ExtraService></ExtraServices>';
}
// Close off Package tag
$request .= '</Package>';
$package_id++;
}
}
$request .= '</IntlRateV2Request>';
$request = 'API=IntlRateV2&XML=' . drupal_urlencode($request);
return $request;
}
/**
* Modifies the rate received from USPS before displaying to the customer.
*
* @param $rate
* Shipping rate without any rate markup.
*
* @return
* Shipping rate after markup.
*/
function uc_usps_markup($rate) {
$markup = variable_get('uc_usps_markup', '0');
$type = variable_get('uc_usps_markup_type', 'percentage');
if (is_numeric(trim($markup))) {
switch ($type) {
case 'percentage':
return $rate + $rate * floatval(trim($markup)) / 100;
case 'multiplier':
return $rate * floatval(trim($markup));
case 'currency':
return $rate + floatval(trim($markup));
}
}
else {
return $rate;
}
}
/**
* Organizes products into packages for shipment.
*
* @param $products
* An array of product objects as they are represented in the cart or order.
* @param &$addresses
* Reference to an array of addresses which are the pickup locations of each
* package. They are determined from the shipping addresses of their
* component products.
*
* @return
* Array of packaged products. Packages are separated by shipping address and
* weight or quantity limits imposed by the shipping method or the products.
*/
function _uc_usps_package_products($products, &$addresses) {
$last_key = 0;
$packages = array();
if (variable_get('uc_usps_all_in_one', TRUE) && count($products) > 1) {
// "All in one" packaging strategy
// Only need to do this if more than one product line item in order
foreach ($products as $product) {
if ($product->nid) {
$address = (array) uc_quote_get_default_shipping_address($product->nid);
$key = array_search($address, $addresses);
if ($key === FALSE) {
$addresses[++$last_key] = $address;
$key = $last_key;
$packages[$key][0] = new stdClass();
}
}
$packages[$key][0]->price += $product->price * $product->qty;
$packages[$key][0]->weight += $product->weight * $product->qty * uc_weight_conversion($product->weight_units, 'lb');
}
foreach ($packages as $key => $package) {
$packages[$key][0]->pounds = floor($package[0]->weight);
$packages[$key][0]->ounces = LB_TO_OZ * ($package[0]->weight - $packages[$key][0]->pounds);
$packages[$key][0]->container = 'VARIABLE';
$packages[$key][0]->size = 'REGULAR';
// Packages are "machinable" if heavier than 6oz. and less than 35lbs.
$packages[$key][0]->machinable = ($packages[$key][0]->pounds == 0 ? $packages[$key][0]->ounces >= 6 : TRUE) && $packages[$key][0]->pounds <= 35 && ($packages[$key][0]->pounds == 35 ? $packages[$key][0]->ounces == 0 : TRUE);
$packages[$key][0]->qty = 1;
}
}
else {
// !variable_get('uc_usps_all_in_one', TRUE) || count($products) = 1
// "Each in own" packaging strategy, or only one product line item in order
foreach ($products as $product) {
if ($product->nid) {
$address = (array) uc_quote_get_default_shipping_address($product->nid);
$key = array_search($address, $addresses);
if ($key === FALSE) {
$addresses[++$last_key] = $address;
$key = $last_key;
}
}
if (!$product->pkg_qty) {
$product->pkg_qty = 1;
}
$num_of_pkgs = (int) ($product->qty / $product->pkg_qty);
if ($num_of_pkgs) {
$package = drupal_clone($product);
$package->description = $product->model;
$weight = $product->weight * $product->pkg_qty;
switch ($product->weight_units) {
case 'g':
// Convert to kg and fall through
$weight = $weight * G_TO_KG;
case 'kg':
// Convert to lb and fall through
$weight = $weight * KG_TO_LB;
case 'lb':
$package->pounds = floor($weight);
$package->ounces = LB_TO_OZ * ($weight - $package->pounds);
break;
case 'oz':
$package->pounds = floor($weight * OZ_TO_LB);
$package->ounces = $weight - $package->pounds * LB_TO_OZ;
break;
}
$package->container = $product->usps['container'];
$length_conversion = uc_length_conversion($product->length_units, 'in');
$package->length = max($product->length, $product->width) * $length_conversion;
$package->width = min($product->length, $product->width) * $length_conversion;
$package->height = $product->height * $length_conversion;
if ($package->length < $package->height) {
list($package->length, $package->height) = array(
$package->height,
$package->length,
);
}
$package->girth = 2 * $package->width + 2 * $package->height;
$package->size = $package->length <= 12 ? 'REGULAR' : 'LARGE';
$package->machinable = $package->length >= 6 && $package->length <= 34 && $package->width >= 0.25 && $package->width <= 17 && $package->height >= 3.5 && $package->height <= 17 && ($package->pounds == 0 ? $package->ounces >= 6 : TRUE) && $package->pounds <= 35 && ($package->pounds == 35 ? $package->ounces == 0 : TRUE);
$package->price = $product->price * $product->pkg_qty;
$package->qty = $num_of_pkgs;
$packages[$key][] = $package;
}
$remaining_qty = $product->qty % $product->pkg_qty;
if ($remaining_qty) {
$package = drupal_clone($product);
$package->description = $product->model;
$weight = $product->weight * $remaining_qty;
switch ($product->weight_units) {
case 'g':
// Convert to kg and fall through
$weight = $weight * G_TO_KG;
case 'kg':
// Convert to lb and fall through
$weight = $weight * KG_TO_LB;
case 'lb':
$package->pounds = floor($weight);
$package->ounces = LB_TO_OZ * ($weight - $package->pounds);
break;
case 'oz':
$package->pounds = floor($weight * OZ_TO_LB);
$package->ounces = $weight - $package->pounds * LB_TO_OZ;
break;
}
$package->container = $product->usps['container'];
$length_conversion = uc_length_conversion($product->length_units, 'in');
$package->length = max($product->length, $product->width) * $length_conversion;
$package->width = min($product->length, $product->width) * $length_conversion;
$package->height = $product->height * $length_conversion;
if ($package->length < $package->height) {
list($package->length, $package->height) = array(
$package->height,
$package->length,
);
}
$package->girth = 2 * $package->width + 2 * $package->height;
$package->size = $package->length <= 12 ? 'REGULAR' : 'LARGE';
$package->machinable = $package->length >= 6 && $package->length <= 34 && $package->width >= 0.25 && $package->width <= 17 && $package->height >= 3.5 && $package->height <= 17 && ($package->pounds == 0 ? $package->ounces >= 6 : TRUE) && $package->pounds <= 35 && ($package->pounds == 35 ? $package->ounces == 0 : TRUE);
$package->price = $product->price * $remaining_qty;
$package->qty = 1;
$packages[$key][] = $package;
}
}
}
return $packages;
}
/**
* Convenience function for select form elements.
*/
function _uc_usps_pkg_types() {
return array(
'VARIABLE' => t('Variable'),
'FLAT RATE BOX' => t('Flat rate box'),
'LG FLAT RATE BOX' => t('Large flat rate box'),
'FLAT RATE ENVELOPE' => t('Flat rate envelope'),
'RECTANGULAR' => t('Rectangular'),
'NONRECTANGULAR' => t('Non-rectangular'),
);
}
/**
* Maps envelope shipment services to their IDs.
*/
function _uc_usps_env_services() {
return array(
'zero' => t('U.S.P.S. First-Class Mail Postcard'),
'zeroFlat' => t('U.S.P.S. First-Class Mail Letter'),
12 => t('U.S.P.S. First-Class Postcard Stamped'),
1 => t('U.S.P.S. Priority Mail'),
16 => t('U.S.P.S. Priority Mail Flat-Rate Envelope'),
3 => t('U.S.P.S. Express Mail'),
13 => t('U.S.P.S. Express Mail Flat-Rate Envelope'),
23 => t('U.S.P.S. Express Mail Sunday/Holiday Guarantee'),
25 => t('U.S.P.S. Express Mail Flat-Rate Envelope Sunday/Holiday Guarantee'),
);
}
/**
* Maps parcel shipment services to their IDs.
*/
function _uc_usps_services() {
return array(
'zeroFlat' => t('U.S.P.S. First-Class Mail Letter'),
'zeroParcel' => t('U.S.P.S. First-Class Mail Parcel'),
1 => t('U.S.P.S. Priority Mail'),
28 => t('U.S.P.S. Priority Mail Small Flat-Rate Box'),
17 => t('U.S.P.S. Priority Mail Regular/Medium Flat-Rate Box'),
22 => t('U.S.P.S. Priority Mail Large Flat-Rate Box'),
3 => t('U.S.P.S. Express Mail'),
23 => t('U.S.P.S. Express Mail Sunday/Holiday Guarantee'),
4 => t('U.S.P.S. Parcel Post'),
5 => t('U.S.P.S. Bound Printed Matter'),
6 => t('U.S.P.S. Media Mail'),
7 => t('U.S.P.S. Library'),
);
}
/**
* Maps international envelope services to their IDs.
*/
function _uc_usps_intl_env_services() {
return array(
13 => t('First Class Mail International Letter'),
14 => t('First Class Mail International Large Envelope'),
2 => t('Priority Mail International'),
8 => t('Priority Mail International Flat Rate Envelope'),
4 => t('Global Express Guaranteed'),
12 => t('GXG Envelopes'),
1 => t('Express Mail International (EMS)'),
10 => t('Express Mail International (EMS) Flat Rate Envelope'),
);
}
/**
* Maps international parcel services to their IDs.
*/
function _uc_usps_intl_services() {
return array(
15 => t('First Class Mail International Package'),
2 => t('Priority Mail International'),
16 => t('Priority Mail International Small Flat-Rate Box'),
9 => t('Priority Mail International Regular/Medium Flat-Rate Box'),
11 => t('Priority Mail International Large Flat-Rate Box'),
4 => t('Global Express Guaranteed'),
6 => t('Global Express Guaranteed Non-Document Rectangular'),
7 => t('Global Express Guaranteed Non-Document Non-Rectangular'),
1 => t('Express Mail International (EMS)'),
);
}
Functions
Name![]() |
Description |
---|---|
theme_uc_usps_option_label | Theme function to format the USPS service name and rate amount line-item shown to the customer. |
uc_usps_ca_predicate | Implements hook_ca_predicate(). |
uc_usps_form_alter | Implements hook_form_alter(). |
uc_usps_intl_rate_request | Constructs a quote request for international shipments. |
uc_usps_markup | Modifies the rate received from USPS before displaying to the customer. |
uc_usps_menu | Implements hook_menu(). |
uc_usps_nodeapi | Implements hook_nodeapi(). |
uc_usps_quote | Callback for retrieving USPS shipping quote. |
uc_usps_rate_request | Constructs a quote request for domestic shipments. |
uc_usps_shipping_method | Implements hook_shipping_method(). |
uc_usps_shipping_type | Implements hook_shipping_type(). |
uc_usps_theme | Implements hook_theme(). |
_uc_usps_env_services | Maps envelope shipment services to their IDs. |
_uc_usps_intl_env_services | Maps international envelope services to their IDs. |
_uc_usps_intl_services | Maps international parcel services to their IDs. |
_uc_usps_package_products | Organizes products into packages for shipment. |
_uc_usps_pkg_types | Convenience function for select form elements. |
_uc_usps_services | Maps parcel shipment services to their IDs. |