================================================== =============================
INSTALLATION
================================================== =============================

--------
STEP 1
--------
BACKUP your database and any files that will be amended before beginning

Run the three queries found in (or use the file itself) the included sql file: configuration_shipping.sql to add three configuration keys to the table configuration. Then configure them in Admin->Configuration->Shipping/Packaging:

Dimensions Support (leave at No for the time being, read step 6 for further info)
Unit Weight (change the default LBS to KGS if needed)
Unit Length (change the default IN to CM if needed)

--------
STEP 2
--------
Extract the files to their appropriate locations. The files needed are:

catalog/admin/includes/classes/xml.php
catalog/admin/includes/classes/xml_5.php
catalog/includes/classes/xml.php
catalog/includes/classes/xml_5.php
catalog/includes/languages/english/modules/shipping/upsxml.php
catalog/includes/modules/shipping/upsxml.php

--------
STEP 3 *** If you have already installed USPS Methods or UPS Choice, you can skip this step
--------

In catalog/admin/modules.php

*****************************************
Find This code somewhere around line 48:
*****************************************

if (tep_not_null($action)) {
switch ($action) {
case 'save':
while (list($key, $value) = each($HTTP_POST_VARS['configuration'])) {

***********************************************
INSERT THE FOLLOWING CODE AFTER THE ABOVE LINE:
***********************************************

if (is_array($value) ) {
$value = implode( ", ", $value);
$value = ereg_replace (", --none--", "", $value);
}

****************************
SO IT SHOULD LOOK LIKE THIS:
****************************

if (tep_not_null($action)) {
switch ($action) {
case 'save':
while (list($key, $value) = each($HTTP_POST_VARS['configuration'])) {
if (is_array($value) ) {
$value = implode( ", ", $value);
$value = ereg_replace (", --none--", "", $value);
}
tep_db_query("update " . TABLE_CONFIGURATION . " set configuration_value = '" . $value . "' where configuration_key = '" . $key . "'");
}
tep_redirect(tep_href_link(FILENAME_MODULES, 'set=' . $set . '&module=' . $HTTP_GET_VARS['module']));
break;
case 'install':


NOTE1: if you fail to do this step you will get the following error message when editing UPS XML in the admin:

Warning: constant() [function.constant]: Couldn't find constant UPSXML_Array in /path/to/your/shop_root/includes/modules/shipping/upsxml.php on line 991

NOTE2: if your settings do not save change the line

while (list($key, $value) = each($HTTP_POST_VARS['configuration'])) {

to:

foreach($_POST['configuration'] as $key => $value) {

--------
STEP 4
--------

This step to add the function tep_cfg_select_multioption to catalog/admin/includes/functions/general.php is no longer needed. Two new functions that can only be used for the UPSXML module were added to the shipping module itself (outside of the class). They are get_multioption_upsxml and upsxml_cfg_select_multioption_indexed and can be moved to admin/included/functions/general.php if you like. Don't forget to remove them from a new version of the shipping module upsxml.php in case of a future update!

--------
STEP 5
--------

The step to enlarge a database field in the table configuration from type "VARCHAR(255)" to TEXT is no longer needed.

----------------------------
STEP 6 ** OPTIONAL **
----------------------------
This module supports the dimensions modifications proposed by Tom St. Croix's Canada Post 3.1 Module.
The shipping module can then employ length, width, height, dimensions in
either centimeters or inches, and weight in pounds or kilograms. Dimensional support is somewhat involved, and is further
detailed in dimensions.txt, but offers more accurate shipping that can save you money.

Additional files needed for dimensional support and packaging addition:

catalog/includes/classes/packing.php
catalog/admin/packaging.php
catalog/admin/includes/languages/english/packaging.php
catalog/admin/includes/languages/english/images/buttons/button_new_package.gif

--------
STEP 7
--------
In admin, choose Modules->Shipping, and activate the new United Parcel Service (XML) module.
Edit the module and set your service options:

UPS Rates account access key (obtain from UPS)
UPS Rates account username (obtain from UPS)
UPS Rates account password (obtain from UPS)
Pickup method
Packaging Type
Customer Classification Code
Shipping Origin (determines what products names are shown based on origin)
Origin City (required for some countries)
Origin State/Province (two letter ISO 3166 code)
Origin Country (two letter ISO 3166 code)
Origin Zip/Postal Code
Test or Production mode
Quote Type
Negotiated Rates
UPS Account Number
Handling Fee
Enable Insurance
Tax Class
Shipping Zone (leave at --none-- to use for all shipping zones)
Sort order of display
Disallowed shipping methods
Shipping Delay
Email UPS errors (to the shop owner)
Time in Transit View Type
Display Weight (for example: (2 pkg(s), 28 lbs total) after United Parcel Service, first line)

If you have any questions regarding the above settings, please refer to the documentation provided to you by UPS when you
signed up for and received your access key. If you still have questions, then post to the forums in the support thread:
http://forums.oscommerce.com/index.p...opic=49382&hl=

Note that Customer Classification Code and Pickup methods are only used when the Shipping Origin is US! So don't bother with it if that is not the case.

--------
STEP 8
--------
Test by setting your customer destination to all sorts of different places, and running through the shipping process several times. Please test thoroughly before committing to its use.

If you fail to get quotes, an error message will usually tell you why. Make sure your origin information is correct, and use the proper two-letter codes for your country and state/province.

If you STILL don't get any quotes, you can enable logging which will record the request/response of the transactions and any cURL errors. Look
for, uncomment, and change (e.g. to your own full path) the line in upsxml.php (line 108):

// $this->logfile = '/srv/www/htdocs/catalog/includes/modules/shipping/upsxml.log';

example of a full path:
'/home/yoursite/public_html/catalog/includes/modules/shipping/upsxml.log';

Change the location of the log to something you can read (don't forget to give the file write permissions 777), create an empty file "upsxml.log" on that location, and give the shopping cart a whirl. Your request/response will
eventually show up there.

If cURL is not compiled into PHP (Windows users (?) and some Linux users) you can change line 115 to : $this->use_exec = '1'; Using exec() cURL from the command line interface (CLI) is then used. See for more information "Changes from 1.1.3 to 1.1.4" in the changes.txt file.
If exec() is disabled and logging is enabled, this will be logged also.

To test UPSXML without having cURL working or having the user names, access keys etc. from UPS set the Time in Transit View Type in the admin to "Not" and follow the instructions, comment and uncomment some lines around line 613-621. Upload the included example_response.xml file, change the path on line 616 to reflect the path on your server and go to checkout with something in the shopping cart. The checkout shipping page should show the shipping methods and prices in the file example_response.jpg.

--------
STEP 9
--------

A few lines below the line 108:
// $this->logfile = '/srv/www/htdocs/catalog/includes/modules/shipping/upsxml.log';
you will find another line:
// $this->ups_error_file = '/srv/www/htdocs/catalog/includes/modules/shipping/upsxml_error.log';

Do as in step 8: create an empty document of that name, set the path to what you want and make it writable for the server. This file will only log the error messages that are returned by UPS. The file in step 8 will grow very big, very quickly. This file is only one line per UPS module (TimeInTransit and Rates are used). Together with the admin setting for getting those errors emailed, you can keep tabs of what is happening. The customer id is logged too, so you can contact them if necessary.

--------
STEP 10
--------

If you have installed Separate Pricing Per Customer (SPPC), add this shipping module to the enabled ones for the customer groups.

----------------------------
STEP 11 ** OPTIONAL **
----------------------------

Steve Lionel (stevel) pointed out that checkout_shipping.php does the whole get quote procedure (contacting the website for shipping quotes like UPSP, UPS, FedEx etcetera) again on pressing the Continue button (action=process). Since that is rather a time waste and waste of resources you can add the following code to avoid this

File: checkout_shipping.php

Line 110-115

**REPLACE**

if ($shipping == 'free_free') {
$quote[0]['methods'][0]['title'] = FREE_SHIPPING_TITLE;
$quote[0]['methods'][0]['cost'] = '0';
} else {
$quote = $shipping_modules->quote($method, $module);
}

**WITH**

if ($shipping == 'free_free') {
$quote[0]['methods'][0]['title'] = FREE_SHIPPING_TITLE;
$quote[0]['methods'][0]['cost'] = '0';
} else { // not free shipping
// check if the cart and send to address haven't changed in the mean time
if (isset($_SESSION['shipping_quotes']) && $_SESSION['shipping_quotes']['cartID'] == $cartID && $_SESSION['shipping_quotes']['sendto'] == $sendto) {
foreach ($_SESSION['shipping_quotes']['quotes'] as $array_key => $shipping_quote) {
if ($shipping_quote['id'] == $module) {
foreach ($shipping_quote['methods'] as $subarray_key => $method_array) {
if ($method_array['id'] == $method) {
$quote[] = array('id' => $module, 'module' => $shipping_quote['module'], 'methods' => array($method_array));
break;
} // end if ($method_array['id'] == $method)
} // end foreach ($shipping_quote['methods'] as $subarray_key => $method_array)
break; // found shipping quote in session
} // end if ($shipping_quote['id'] == $module)
} // end foreach ($_SESSION['shipping_quotes']['quotes']...
// if for some reason the quote is not found in the session so $quote is not set here we get our quotes again
if (!isset($quote)) {
$quote = $shipping_modules->quote($method, $module);
} // end if (!isset($quote))
} else {
$quote = $shipping_modules->quote($method, $module);
}
}

Line 138-139

**REPLACE**

// get all available shipping quotes
$quotes = $shipping_modules->quote();

**WITH**

// get all available shipping quotes
$quotes = $shipping_modules->quote();
if (!tep_session_is_registered('shipping_quotes')) tep_session_register('shipping_quotes');
$shipping_quotes = array('cartID' => $cartID, 'sendto' => $sendto, 'quotes' => $quotes);

Additionally it will need to be unset in checkout_process.php. Find line 270-275 and the indicated line:

// unregister session variables used during checkout
tep_session_unregister('sendto');
tep_session_unregister('billto');
tep_session_unregister('shipping');
tep_session_unregister('shipping_quotes'); // add this line
tep_session_unregister('payment');
tep_session_unregister('comments');


What is does is just store the shipping quotes received in a session variable (so the customer cannot change it) and then access the session variable on action=process instead of getting the quotes again.

----------------------------
STEP 12 ** FOR GODADDY HOSTING ONLY **
----------------------------

A number of people using GoDaddy for their hosting have found that the UPSXML module times out when getting rate quotes. This is due to the fact that GoDaddy uses a special setup for the https connections, namely a proxy server.

In that case (haven't tested this, but this is a compilation from the postings and uploads) change a part of the code in catalog/includes/modules/shipping/upsxml.php

Line 90

**CHANGE**

$this->timeout = '60';

**TO**

$this->timeout = '120';


Line 662-670

**REPLACE**

// uncomment the next line if you get curl error 60: error setting certificate verify locations
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// uncommenting the next line is most likely not necessary in case of error 60
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
curl_setopt($ch, CURLOPT_TIMEOUT, (int)$timeout);

**WITH**

// BOF GODADDY STUFF
// uncomment the next line if you get curl error 60: error setting certificate verify locations
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
// uncommenting the next line is most likely not necessary in case of error 60
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
curl_setopt ($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
// change this->timeout = '60' around line 90 to this->timeout = '120' for GoDaddy hosting
curl_setopt($ch, CURLOPT_TIMEOUT, (int)$timeout);
curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
curl_setopt ($ch, CURLOPT_PROXY, "http://proxy.shr.secureserver.net:3128");
// EOF GODADDY STUFF

================================================== =============================

More...