You are here

commerce_ups.module in Commerce UPS 7.2

Same filename and directory in other branches
  1. 8.3 commerce_ups.module
  2. 7 commerce_ups.module

Handles main functionality for Commerce UPS module.

File

commerce_ups.module
View source
<?php

/**
 * @file
 * Handles main functionality for Commerce UPS module.
 */

/**
 * Implements hook_menu().
 */
function commerce_ups_menu() {
  $items['admin/commerce/config/shipping/methods/ups/edit'] = array(
    'title' => 'Edit',
    'description' => 'Configure the UPS shipping method.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'commerce_ups_settings_form',
    ),
    'access arguments' => array(
      'administer shipping',
    ),
    'file' => 'includes/commerce_ups.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_INLINE,
    'weight' => 0,
  );
  return $items;
}

/**
 * Implements hook_commerce_shipping_method_info().
 */
function commerce_ups_commerce_shipping_method_info() {
  $shipping_methods['ups'] = array(
    'title' => t('UPS'),
    'description' => t('Quote rates from UPS'),
  );
  return $shipping_methods;
}

/**
 * Implements hook_commerce_shipping_service_info().
 */
function commerce_ups_commerce_shipping_service_info() {
  $shipping_services = array();
  $available_services = _commerce_ups_service_list();
  $selected_services = variable_get('commerce_ups_services', array());
  foreach ($selected_services as $id => $val) {

    // If you find a selected one...
    if ($val != 0) {
      $service = $available_services[$id];
      $shipping_services[$service['slug']] = array(
        'title' => t($service['title']),
        'description' => t($service['description']),
        'display_title' => t($service['title']),
        'shipping_method' => 'ups',
        'price_component' => 'shipping',
        'callbacks' => array(
          'rate' => 'commerce_ups_service_rate_order',
        ),
      );
    }
  }
  return $shipping_services;
}

/**
 * Shipping service callback: returns a base price array for a shipping service
 * calculated for the given order.
 */
function commerce_ups_service_rate_order($shipping_service, $order) {

  // First attempt to recover cached shipping rates for the current order.
  $rates = commerce_shipping_rates_cache_get('ups', $order, variable_get('commerce_ups_rates_timeout', 0));

  // If no rates were recovered from the cache or the cached rates are over one minute old...
  if (!is_array($rates)) {
    $rates = array();
    module_load_include('inc', 'commerce_ups', 'includes/commerce_ups.xml');

    // Build the rate request for the current order. This returns XML.
    $rate_request_xml = commerce_ups_build_rate_request($order);

    // If we got a valid rate request object back...
    if ($rate_request_xml) {

      // Submit the API request to UPS.
      $response = commerce_ups_api_request('Rate', $rate_request_xml, t('Requesting shipping rates for Order @order_number', array(
        '@order_number' => $order->order_number,
      )));
      if (!empty($response)) {

        // Parse the response to cache all requested rates for the current order.
        foreach ($response->RatedShipment as $rate) {

          // Extract the service name and price information from the rate object.
          $service_name = commerce_ups_commerce_shipping_service_name((string) $rate->Service->Code);
          if ($rate->NegotiatedRates) {
            $decimal = (string) $rate->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue;
            $currency_code = (string) $rate->NegotiatedRates->NetSummaryCharges->GrandTotal->CurrencyCode;
          }
          else {
            $decimal = (string) $rate->TotalCharges->MonetaryValue;
            $currency_code = (string) $rate->TotalCharges->CurrencyCode;
          }

          // Add an item to the rates array for the current service.
          $rates[$service_name] = array(
            'amount' => commerce_currency_decimal_to_amount($decimal, $currency_code),
            'currency_code' => $currency_code,
            'data' => array(),
          );
        }

        // Cache the calculated rates for subsequent requests.
        commerce_shipping_rates_cache_set('ups', $order, $rates);
      }
    }
  }

  // Allow other modules to alter the returned rates.
  drupal_alter('commerce_ups_service_rate_order', $rates, $order);

  // Return the rate for the requested service or FALSE if not found.
  return isset($rates[$shipping_service['name']]) ? $rates[$shipping_service['name']] : FALSE;
}

/**
 * Implements hook_commerce_shipping_service_rate_options_alter().
 */
function commerce_ups_commerce_shipping_service_rate_options_alter(&$options, $order) {

  // If the display UPS logo next to UPS services is enabled in settings,
  // loop through the shipping options and add the UPS logo to UPS services.
  if (variable_get('commerce_ups_show_logo', FALSE)) {
    $image = drupal_get_path('module', 'commerce_ups') . '/images/ups-logo.png';
    if (file_exists($image)) {
      foreach ($options as $key => &$option) {
        if (preg_match('/^ups_/', $key)) {
          $option = theme('image', array(
            'path' => $image,
            'width' => '16px',
          )) . ' ' . $option;
        }
      }
    }
  }
}

/**
 * Convenience function to get UPS codes for their services.
 */
function _commerce_ups_service_list() {
  $services = array(
    // Domestic services.
    '03' => array(
      'title' => t('UPS Ground'),
      'description' => t('Ground Delivery'),
      'slug' => 'ups_ground',
    ),
    '01' => array(
      'title' => t('UPS Next Day Air'),
      'description' => t('Next Day Air'),
      'slug' => 'ups_next_day_air',
    ),
    '13' => array(
      'title' => t('UPS Next Day Air Saver'),
      'description' => t('Next Day Air Saver'),
      'slug' => 'ups_next_day_air_saver',
    ),
    '14' => array(
      'title' => t('UPS Next Day Early A.M.'),
      'description' => t('Next Day Early A.M.'),
      'slug' => 'ups_next_day_early_a.m.',
    ),
    '02' => array(
      'title' => t('UPS 2nd Day Air'),
      'description' => t('2nd Day Air'),
      'slug' => 'ups_2nd_day_air',
    ),
    '59' => array(
      'title' => t('UPS 2nd Day Air A.M.'),
      'description' => t('2nd Day Air A.M.'),
      'slug' => 'ups_2nd_day_air_a.m.',
    ),
    '12' => array(
      'title' => t('UPS 3 Day Select'),
      'description' => t('3 Day Select'),
      'slug' => 'ups_3_day_select.',
    ),
    // International services.
    '11' => array(
      'title' => t('UPS Standard'),
      'description' => t('International Standard'),
      'slug' => 'ups_standard',
    ),
    '07' => array(
      'title' => t('UPS Worldwide Express'),
      'description' => t('Worldwide Express'),
      'slug' => 'ups_worldwide_express',
    ),
    '08' => array(
      'title' => t('UPS Worldwide Expedited'),
      'description' => t('Worldwide Expedited'),
      'slug' => 'ups_worldwide_expedited',
    ),
    '54' => array(
      'title' => t('UPS Worldwide Express Plus'),
      'description' => t('Worldwide Express Plus'),
      'slug' => 'ups_worldwide_express_plus',
    ),
    '65' => array(
      'title' => t('UPS Worldwide Saver'),
      'description' => t('Worldwide Saver'),
      'slug' => 'ups_worldwide_saver',
    ),
  );
  drupal_alter('commerce_ups_service_list', $services);
  return $services;
}

/**
 * Convenience function to get UPS codes for their package types.
 */
function _commerce_ups_packaging_types() {
  return array(
    // Customer Supplied Page is first so it will be the default.
    '02' => t('Customer Supplied Package'),
    '01' => t('UPS Letter'),
    '03' => t('Tube'),
    '04' => t('PAK'),
    '21' => t('UPS Express Box'),
    '24' => t('UPS 25KG Box'),
    '25' => t('UPS 10KG Box'),
    '30' => t('Pallet'),
    '2a' => t('Small Express Box'),
    '2b' => t('Medium Express Box'),
    '2c' => t('Large Express Box'),
  );
}

/**
 * Types of pickup for UPS.
 */
function _commerce_ups_pickup_types() {
  return array(
    '06' => 'One Time Pickup',
    '01' => 'Daily Pickup',
    '03' => 'Customer Counter',
    '07' => 'On Call Air',
    '19' => 'Letter Center',
    '20' => 'Air Service Center',
  );
}

/**
 * List of Shipping Service.
 */
function commerce_ups_commerce_shipping_service_name($service_code) {
  $service_names = _commerce_ups_service_list();
  return $service_names[$service_code]['slug'];
}

/**
 * Encrypt a specified value.
 */
function commerce_ups_encrypt($value) {
  if (module_exists('aes')) {
    return aes_encrypt($value);
  }
  return encrypt($value);
}

/**
 * Decrypt all api variables in one function call.
 */
function commerce_ups_decrypt_vars($include_password) {
  $user_vars = array();
  if (variable_get('commerce_ups_encrypt', FALSE) && commerce_ups_encryption_available()) {
    if (module_exists('aes')) {
      $user_vars['ups_accountid'] = aes_decrypt(variable_get('commerce_ups_account_id', ''));
      $user_vars['ups_userid'] = aes_decrypt(variable_get('commerce_ups_user_id', ''));
      $user_vars['ups_accesskey'] = aes_decrypt(variable_get('commerce_ups_access_key', ''));
      if ($include_password) {
        $user_vars['ups_password'] = variable_get('commerce_ups_password', '');
      }
    }
    else {
      $user_vars['ups_accountid'] = decrypt(variable_get('commerce_ups_account_id', ''));
      $user_vars['ups_userid'] = decrypt(variable_get('commerce_ups_user_id', ''));
      $user_vars['ups_accesskey'] = decrypt(variable_get('commerce_ups_access_key', ''));
      if ($include_password) {
        $user_vars['ups_password'] = decrypt(variable_get('commerce_ups_password', ''));
      }
    }
  }
  else {
    $user_vars['ups_accountid'] = variable_get('commerce_ups_account_id', '');
    $user_vars['ups_userid'] = variable_get('commerce_ups_user_id', '');
    $user_vars['ups_accesskey'] = variable_get('commerce_ups_access_key', '');
    if ($include_password) {
      $user_vars['ups_password'] = variable_get('commerce_ups_password', '');
    }
  }
  return $user_vars;
}

/**
 * Check whether encryption is available.
 */
function commerce_ups_encryption_available($options = array()) {

  // The old (insecure) AES module exists.
  if (module_exists('aes')) {
    return TRUE;
  }
  elseif (module_exists('real_aes')) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Defines the available endpoints for the UPS XML API.
 */
function commerce_ups_api_endpoint($method) {
  $endpoints = array(
    'Rate' => 'https://onlinetools.ups.com/ups.app/xml/Rate',
    'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
    'ShipAccept' => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept',
    // Test URLs
    'RateTest' => 'https://wwwcie.ups.com/ups.app/xml/Rate',
    'ShipConfirmTest' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
    'ShipAcceptTest' => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',
  );

  // Allow other modules to alter the API endpoints.
  drupal_alter('commerce_ups_api_endpoint', $endpoints, $method);
  if (!empty($endpoints[$method])) {
    return $endpoints[$method];
  }
  return FALSE;
}

Functions

Namesort descending Description
commerce_ups_api_endpoint Defines the available endpoints for the UPS XML API.
commerce_ups_commerce_shipping_method_info Implements hook_commerce_shipping_method_info().
commerce_ups_commerce_shipping_service_info Implements hook_commerce_shipping_service_info().
commerce_ups_commerce_shipping_service_name List of Shipping Service.
commerce_ups_commerce_shipping_service_rate_options_alter Implements hook_commerce_shipping_service_rate_options_alter().
commerce_ups_decrypt_vars Decrypt all api variables in one function call.
commerce_ups_encrypt Encrypt a specified value.
commerce_ups_encryption_available Check whether encryption is available.
commerce_ups_menu Implements hook_menu().
commerce_ups_service_rate_order Shipping service callback: returns a base price array for a shipping service calculated for the given order.
_commerce_ups_packaging_types Convenience function to get UPS codes for their package types.
_commerce_ups_pickup_types Types of pickup for UPS.
_commerce_ups_service_list Convenience function to get UPS codes for their services.