You are here

uc_usps.module in Ubercart 5

Shipping quote method module that receives quotes from the United States Postal Service via XML web service.

Coded by Lyle Mantooth.

File

shipping/uc_usps/uc_usps.module
View source
<?php

/**
 * @file
 * Shipping quote method module that receives quotes from the United States
 * Postal Service via XML web service.
 *
 * Coded by Lyle Mantooth.
 */

/******************************************************************************
 * Drupal Hooks                                                               *
 ******************************************************************************/

/**
 * Implementation of hook_menu().
 */
function uc_usps_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/store/settings/quotes/methods/usps',
      'title' => t('USPS'),
      'access' => user_access('configure quotes'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'uc_usps_admin_settings',
      ),
      'type' => MENU_LOCAL_TASK,
    );
  }
  return $items;
}

/**
 * Implementation of hook_form_alter().
 *
 * Add package type to products.
 *
 * @see uc_product_form
 */
function uc_usps_form_alter($form_id, &$form) {
  $node = $form['#node'];
  if (is_object($node) && $form_id == $node->type . '_node_form' && isset($form['base']['dimensions']) && in_array($node->type, module_invoke_all('product_types'))) {
    $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' => $node->usps['container'] ? $node->usps['container'] : 'RECTANGULAR',
    );
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function uc_usps_nodeapi(&$node, $op) {
  if (in_array($node->type, module_invoke_all('product_types'))) {
    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;
    }
  }
}

/******************************************************************************
 * Workflow-ng Hooks                                                          *
 ******************************************************************************/

/**
 * Implementation of hook_configuration().
 *
 * Connect USPS quote action and event.
 */
function uc_usps_configuration() {
  $enabled = variable_get('uc_quote_enabled', array());
  $configurations = array(
    'uc_usps_get_quote' => array(
      '#label' => t('Shipping quote from USPS'),
      '#event' => 'get_quote_from_usps',
      '#module' => 'uc_usps',
      '#active' => $enabled['usps'],
    ),
    'uc_usps_get_intl_quote' => array(
      '#label' => t('Shipping quote from USPS Intl.'),
      '#event' => 'get_quote_from_usps_intl',
      '#module' => 'uc_usps',
      '#active' => $enabled['usps_intl'],
    ),
  );

  // Domestic areas include U.S., American Samoa, Guam, Puerto Rico, and the Virgin Islands
  $countries = array(
    16,
    316,
    630,
    840,
    850,
  );
  $us_area_condition = workflow_ng_use_condition('uc_order_condition_delivery_country', array(
    '#label' => t('Is in domestic US areas (US, AS, GU, PR, VI)'),
    '#settings' => array(
      'countries' => $countries,
    ),
  ));
  $not_us_area_condition = workflow_ng_use_condition('uc_order_condition_delivery_country', array(
    '#label' => t('Is not in domestic US areas (US, AS, GU, PR, VI)'),
    '#negate' => true,
    '#settings' => array(
      'countries' => $countries,
    ),
  ));
  $action = workflow_ng_use_action('uc_quote_action_get_quote', array(
    '#label' => t('Fetch a shipping quote'),
  ));
  $configurations['uc_usps_get_quote'] = workflow_ng_configure($configurations['uc_usps_get_quote'], $action, $us_area_condition);
  $configurations['uc_usps_get_intl_quote'] = workflow_ng_configure($configurations['uc_usps_get_intl_quote'], $action, $not_us_area_condition);
  return $configurations;
}

/******************************************************************************
 * Übercart Hooks                                                             *
 ******************************************************************************/

/**
 * Implementation of Übercart's hook_shipping_type().
 */
function uc_usps_shipping_type() {
  $weight = variable_get('uc_quote_type_weight', array(
    'small_package' => 0,
  ));
  $types = array(
    'small_package' => array(
      'id' => 'small_package',
      'title' => t('Small package'),
      'weight' => $weight['small_package'],
    ),
  );
  return $types;
}

/**
 * Implementation of Übercart's hook_shipping_method().
 */
function uc_usps_shipping_method() {
  $enabled = variable_get('uc_quote_enabled', array());
  $weight = variable_get('uc_quote_method_weight', array(
    'usps' => 0,
    'usps_intl' => 1,
  ));
  $methods = array(
    'usps' => array(
      'id' => 'usps',
      'title' => t('U.S. Postal Service'),
      'quote' => array(
        'type' => 'small_package',
        'callback' => 'uc_usps_quote',
        'accessorials' => _uc_usps_services(),
      ),
      'enabled' => $enabled['usps'],
      'weight' => $weight['usps'],
    ),
    'usps_intl' => array(
      'id' => 'usps_intl',
      'title' => t('U.S. Postal Service (Intl.)'),
      'quote' => array(
        'type' => 'small_package',
        'callback' => 'uc_usps_intl_quote',
        'accessorials' => _uc_usps_intl_services(),
      ),
      'enabled' => $enabled['usps_intl'],
      'weight' => $weight['usps_intl'],
    ),
  );
  return $methods;
}

/******************************************************************************
 * Menu Callbacks                                                             *
 ******************************************************************************/

/**
 * Configure USPS settings.
 *
 * @ingroup forms
 */
function uc_usps_admin_settings() {
  $form = array();
  $form['uc_usps_user_id'] = array(
    '#type' => 'textfield',
    '#title' => t('USPS user ID'),
    '#description' => t('To acquire or locate your user ID, refer to the <a href="!url">USPS documentation</a>.', array(
      '!url' => 'http://www.ubercart.org/docs/user/312/usps_web_tool_shipping_quote_settings',
    )),
    '#default_value' => variable_get('uc_usps_user_id', ''),
  );
  $form['uc_usps_services'] = array(
    '#type' => 'checkboxes',
    '#title' => t('USPS services'),
    '#default_value' => variable_get('uc_usps_services', _uc_usps_services()),
    '#options' => _uc_usps_services(),
    '#description' => t('Select the USPS services that are available to customers. Be sure to include the services that the Postal Service agrees are available to you.'),
  );
  $form['uc_usps_intl_services'] = array(
    '#type' => 'checkboxes',
    '#title' => t('USPS international services'),
    '#default_value' => variable_get('uc_usps_intl_services', _uc_usps_intl_services()),
    '#options' => _uc_usps_intl_services(),
    '#description' => t('Select the USPS services that are available to customers. Be sure to include the services that the Postal Service agrees are available to you.'),
  );
  $form['uc_usps_markup_type'] = array(
    '#type' => 'select',
    '#title' => t('Markup type'),
    '#default_value' => variable_get('uc_usps_markup_type', 'percentage'),
    '#options' => array(
      'percentage' => t('Percentage (%)'),
      'multiplier' => t('Multiplier (×)'),
      'currency' => t('Addition (!currency)', array(
        '!currency' => variable_get('uc_currency_sign', '$'),
      )),
    ),
  );
  $form['uc_usps_markup'] = array(
    '#type' => 'textfield',
    '#title' => t('Shipping rate markup'),
    '#default_value' => variable_get('uc_usps_markup', '0'),
    '#description' => t('Markup shipping rate quote by dollar amount, percentage, or multiplier.'),
  );
  $form['uc_usps_all_in_one'] = array(
    '#type' => 'radios',
    '#title' => t('Product packages'),
    '#default_value' => variable_get('uc_usps_all_in_one', 1),
    '#options' => array(
      0 => t('Each in its own package'),
      1 => t('All in one'),
    ),
    '#description' => t('Indicate whether each product is quoted as shipping separately or all in one package.'),
  );
  return system_settings_form($form);
}

/******************************************************************************
 * Module Functions                                                           *
 ******************************************************************************/

/**
 * Callback for retrieving USPS shipping quote.
 *
 * @param $products
 *   Array of cart contents.
 * @param $details
 *   Order details other than product information.
 * @return
 *   JSON object containing rate, error, and debugging information.
 */
function uc_usps_quote($products, $details) {
  include_once drupal_get_path('module', 'uc_store') . '/includes/simplexml.php';

  //drupal_set_message('<pre>'. print_r($products, true) .'</pre>');

  //drupal_set_message('<pre>'. print_r($details, true) .'</pre>');
  $services = array();
  $addresses = array(
    (array) variable_get('uc_quote_store_default_address', new stdClass()),
  );
  $packages = _uc_usps_package_products($products, $addresses);
  if (!count($packages)) {
    return array();
  }
  $dest = (object) $details;
  $usps_server = 'production.shippingapis.com';
  $api_dll = 'ShippingAPI.dll';
  $connection_url = 'http://' . $usps_server . '/' . $api_dll;
  foreach ($packages as $key => $ship_packages) {
    $orig = (object) $addresses[$key];
    $orig->email = variable_get('uc_store_email', '');
    $request = uc_usps_rate_request($ship_packages, $orig, $dest);
    $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";
    }
    $response = new JSimpleXML();
    $response
      ->loadString($result->data);
    if (is_array($response->document->package)) {
      foreach ($response->document->package as $package) {
        if (isset($package->error)) {
          $services['data']['error'] .= $package->error[0]->description[0]
            ->data() . '<br />';
        }
        else {
          foreach ($package->postage as $postage) {
            $attr = $postage
              ->attributes();
            if ($attr['classid'] === 0 || $attr['classid'] === '0') {
              if ($postage->mailservice[0]
                ->data() == "First-Class Mail Parcel") {
                $attr['classid'] = 'zeroParcel';
              }
              else {
                if ($postage->mailservice[0]
                  ->data() == "First-Class Mail Flat") {
                  $attr['classid'] = 'zeroFlat';
                }
                else {
                  $attr['classid'] = 'zero';
                }
              }
            }
            $services[$attr['classid']]['label'] = t('U.S.P.S. @service', array(
              '@service' => $postage->mailservice[0]
                ->data(),
            ));
            $services[$attr['classid']]['rate'] += uc_usps_markup($postage->rate[0]
              ->data());
          }
        }
      }
    }
  }
  $usps_services = array_filter(variable_get('uc_usps_services', _uc_usps_services()));
  foreach ($services as $service => $quote) {
    if ($service != 'data' && !in_array($service, $usps_services)) {
      unset($services[$service]);
    }
  }

  /* $transitreq  = 'USERID="' . variable_get('uc_usps_user_id', '') .'">' .
     '<OriginZip>' . $orig->postal_code . '</OriginZip>' .
     '<DestinationZip>' . $dest->postal_code . '</DestinationZip>'; */
  foreach ($services as $key => $quote) {
    if (isset($quote['rate'])) {
      $services[$key]['format'] = uc_currency_format($quote['rate']);
      $services[$key]['option_label'] = $quote['label'];

      /* if (strpos($quote['label'], 'Express') !== false) {
           $transreq = 'API=ExpressMailCommitment&XML='. urlencode(str_replace('Zip', 'ZIP', '<ExpressMailCommitmentRequest ' . $transitreq . '<Date/></ExpressMailCommitmentRequest>'));
         }
         elseif (strpos($quote['label'], 'Priority') !== false) {
           $transreq = 'API=PriorityMail&XML='. urlencode( '<PriorityMailRequest ' . $transitreq . '</PriorityMailRequest>');
         }
         else {
           $transreq = 'API=StandardB&XML='. urlencode( '<StandardBRequest ' . $transitreq . '</StandardBRequest>');
         }
         $result = drupal_http_request($connection_url, array(), 'POST', $transreq);
         if (user_access('configure quotes') && variable_get('uc_quote_display_debug', false)) {
           $services['data']['debug'] .= htmlentities($result->data) ."<br />\n";
         }
         $transresp = new JSimpleXML();
         $transresp->loadString($result->data);
         if (isset($transresp->document)) {
           if ($transresp->document->name() == 'Error') {
             $services[$key]['error'][] = $transresp->document->description[0]->data();
           }
           else if (isset($transresp->document->days)) {
             $services[$key]['transit'] = $transresp->document->days[0]->data();
             $services[$key]['option_label'] .= format_plural($services[$key]['transit'], ', @count day in transit', ', @count days in transit');
           }
           else if (isset($transresp->document->commitment)) {
             $services[$key]['commitment'] = $transresp->document->commitment[0]->commitmentname[0]->data() .' -- '. $transresp->document->commitment[0]->commitmenttime[0]->data();
             $services[$key]['option_label'] .= ', '. $services[$key]['commitment'];
           }
         } */
    }
  }
  uasort($services, 'uc_quote_price_sort');
  return $services;
}

/**
 * Callback for retrieving USPS shipping quote to other countries.
 *
 * @param $products
 *   Array of cart contents.
 * @param $details
 *   Order details other than product information.
 * @return
 *   JSON object containing rate, error, and debugging information.
 */
function uc_usps_intl_quote($products, $details) {
  include_once drupal_get_path('module', 'uc_store') . '/includes/simplexml.php';
  $services = array();
  $addresses = array(
    variable_get('uc_quote_store_default_address', new stdClass()),
  );
  $packages = _uc_usps_package_products($products, $addresses);
  if (!count($packages)) {
    return array();
  }
  $dest = (object) $details;
  $usps_server = 'production.shippingapis.com';
  $api_dll = 'ShippingAPI.dll';
  $connection_url = 'http://' . $usps_server . '/' . $api_dll;
  foreach ($packages as $key => $ship_packages) {
    $orig = (object) $addresses[$key];
    $orig->email = variable_get('uc_store_email', '');
    $request = uc_usps_intl_rate_request($ship_packages, $orig, $dest);
    $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";
    }
    $response = new JSimpleXML();
    $response
      ->loadString($result->data);

    // drupal_set_message('<pre>'. htmlentities($result->data) .'</pre>');
    if (is_array($response->document->package)) {
      foreach ($response->document->package as $package) {
        if (isset($package->error)) {
          $services['data']['error'] .= $package->error[0]->description[0]
            ->data() . '<br />';
        }
        else {
          foreach ($package->service as $service) {
            $attr = $service
              ->attributes();
            if ($attr['id'] === 0 || $attr['id'] === '0') {
              $attr['id'] = 'zero';
            }
            $services[$attr['id']]['label'] = t('USPS @service', array(
              '@service' => $service->svcdescription[0]
                ->data(),
            ));
            $services[$attr['id']]['rate'] += uc_usps_markup($service->postage[0]
              ->data());
          }
        }
      }
    }
  }
  $usps_services = variable_get('uc_usps_intl_services', _uc_usps_intl_services());
  foreach ($services as $service => $quote) {
    if (!in_array($service, $usps_services)) {
      unset($services[$service]);
    }
  }
  foreach ($services as $key => $quote) {
    if (isset($quote['rate'])) {
      $services[$key]['format'] = uc_currency_format($quote['rate']);
      $services[$key]['option_label'] = $quote['label'];
    }
  }
  uasort($services, 'uc_quote_price_sort');
  return $services;
}

/**
 * Construct an XML quote request.
 *
 * @param $packages
 *   Array of packages received from the cart.
 * @param $origin
 *   Delivery origin address information.
 * @param $destination
 *   Delivery destination address information.
 * @return
 *   RateV3Request XML document to send to USPS
 */
function uc_usps_rate_request($packages, $origin, $destination) {
  $request = '<RateV3Request USERID="' . variable_get('uc_usps_user_id', '') . '">';
  $services_count = 0;
  foreach ($packages as $package) {
    $qty = $package->qty;
    for ($i = 0; $i < $qty; $i++) {
      $request .= '<Package ID="' . $services_count . '">' . '<Service>ALL</Service>' . '<ZipOrigination>' . substr($origin->postal_code, 0, 5) . '</ZipOrigination>' . '<ZipDestination>' . substr($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>' . '<Machinable>' . ($package->machinable ? 'True' : 'False') . '</Machinable>' . '</Package>';
      $services_count++;
    }
  }
  $request .= '</RateV3Request>';
  $request = 'API=RateV3&XML=' . urlencode($request);
  return $request;
}

/*
 * uc_usps_intl_rate_request function (added by Erik - feel free to improve)
 *
 */
function uc_usps_intl_rate_request($packages, $origin, $destination) {
  $request = '<IntlRateRequest USERID="' . variable_get('uc_usps_user_id', '') . '">';
  $services_count = 0;

  // This needs to be international name per USPS website. See http://pe.usps.com/text/Imm/immctry.htm
  $shipto_country = uc_get_country_data(array(
    'country_id' => $destination->country,
  ));
  foreach ($packages as $package) {
    $qty = $package->qty;
    for ($i = 0; $i < $qty; $i++) {
      $request .= '<Package ID="' . $services_count . '">' . '<Pounds>' . intval($package->pounds) . '</Pounds>' . '<Ounces>' . ceil($package->ounces) . '</Ounces>' . '<MailType>Package</MailType>' . '<Country>' . $shipto_country[0]['country_name'] . '</Country>' . '</Package>';
      $services_count++;
    }
  }
  $request .= '</IntlRateRequest>';
  $request = 'API=IntlRate&XML=' . urlencode($request);
  return $request;
}

/**
 * Modify the rate received from USPS before displaying to the customer.
 */
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;
  }
}
function _uc_usps_package_products($products, &$addresses) {
  $last_key = 0;
  $packages = array();
  if (variable_get('uc_usps_all_in_one', true) && count($products) > 1) {
    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 = 16 * ($package[0]->weight - $packages[$key][0]->pounds);
      $packages[$key][0]->container = 'RECTANGULAR';
      $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 {
    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':
            $weight = $weight / 1000;
          case 'kg':
            $weight = $weight * 2.2;
          case 'lb':
            $package->pounds = floor($weight);
            $package->ounces = 16 * ($weight - $package->pounds);
            break;
          case 'oz':
            $package->pounds = floor($weight / 16);
            $package->ounces = $weight - $package->pounds * 16;
            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->width) {
          list($package->length, $package->width) = array(
            $package->width,
            $package->length,
          );
        }
        $package->girth = 2 * $package->width + 2 * $package->height;
        $package->size = $package->length + $package->girth;
        if ($package->size <= 84) {
          $package->size = 'REGULAR';
        }
        else {
          if ($package->size <= 108) {
            $package->size = 'LARGE';
          }
          else {
            if ($package->size <= 130) {
              $package->size = 'OVERSIZE';
            }
            else {
              $package->size = 'GI-HUGE-IC';

              // Too big for the U.S. Postal service.
            }
          }
        }
        $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':
            $weight = $weight / 1000;
          case 'kg':
            $weight = $weight * 2.2;
          case 'lb':
            $package->pounds = floor($weight);
            $package->ounces = 16 * ($weight - $package->pounds);
            break;
          case 'oz':
            $package->pounds = floor($weight / 16);
            $package->ounces = $weight - $package->pounds * 16;
            break;
        }
        $package->container = $product->usps['container'];
        $package->length = max($product->length, $product->width) * $length_conversion;
        $package->width = min($product->length, $product->width) * $length_conversion;
        $package->height = $product->height * $length_conversion;
        $package->girth = 2 * $package->width + 2 * $package->height;
        $package->size = $package->length + $package->girth;
        if ($package->size <= 84) {
          $package->size = 'REGULAR';
        }
        else {
          if ($package->size <= 108) {
            $package->size = 'LARGE';
          }
          else {
            if ($package->size <= 130) {
              $package->size = 'OVERSIZE';
            }
            else {
              $package->size = 'GI-HUGE-IC';

              // Too big for the U.S. Postal service.
            }
          }
        }
        $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'),
    'FLAT RATE ENVELOPE' => t('Flat rate envelope'),
    'RECTANGULAR' => t('Rectangular'),
    'NONRECTANGULAR' => t('Non-rectangular'),
  );
}

/**
 * Convenience function for select form elements.
 */
function _uc_usps_services() {
  return array(
    'zero' => t('U.S.P.S. First-Class Mail'),
    'zeroFlat' => t('U.S.P.S. First-Class Flat'),
    'zeroParcel' => t('U.S.P.S. First-Class Parcel'),
    1 => t('U.S.P.S. Priority Mail'),
    2 => t('U.S.P.S. Express Mail PO to PO'),
    3 => t('U.S.P.S. Express Mail PO to Addressee'),
    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'),
    12 => t('U.S.P.S. First-Class Postcard Stamped'),
    13 => t('U.S.P.S. Express Mail Flat-Rate Envelope'),
    16 => t('U.S.P.S. Priority Mail Flat-Rate Envelope'),
    17 => t('U.S.P.S. Priority Mail Flat-Rate Box'),
  );
}
function _uc_usps_intl_services() {
  return array(
    1 => t('Express Mail International (EMS)'),
    2 => t('Priority Mail International'),
    //3 => t('First Class Mail International'), // Deprecated May 12, 2008
    4 => t('Global Express Guaranteed'),
    6 => t('Global Express Guaranteed Non-Document Rectangular'),
    7 => t('Global Express Guaranteed Non-Document Non-Rectangular'),
    8 => t('Priority Mail International Flat Rate Envelope'),
    9 => t('Priority Mail International Flat Rate Box'),
    10 => t('Express Mail International (EMS) Flat Rate Envelope'),
    13 => t('First Class Mail International Letter'),
    14 => t('First Class Mail International Flat'),
    15 => t('First Class Mail International Parcel'),
  );
}

Functions

Namesort descending Description
uc_usps_admin_settings Configure USPS settings.
uc_usps_configuration Implementation of hook_configuration().
uc_usps_form_alter Implementation of hook_form_alter().
uc_usps_intl_quote Callback for retrieving USPS shipping quote to other countries.
uc_usps_intl_rate_request
uc_usps_markup Modify the rate received from USPS before displaying to the customer.
uc_usps_menu Implementation of hook_menu().
uc_usps_nodeapi Implementation of hook_nodeapi().
uc_usps_quote Callback for retrieving USPS shipping quote.
uc_usps_rate_request Construct an XML quote request.
uc_usps_shipping_method Implementation of Übercart's hook_shipping_method().
uc_usps_shipping_type Implementation of Übercart's hook_shipping_type().
_uc_usps_intl_services
_uc_usps_package_products
_uc_usps_pkg_types Convenience function for select form elements.
_uc_usps_services Convenience function for select form elements.