usps.php (18132B)
1 <?php 2 class ModelExtensionShippingUsps extends Model { 3 public function getQuote($address) { 4 $this->load->language('extension/shipping/usps'); 5 6 $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('shipping_usps_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')"); 7 8 if (!$this->config->get('shipping_usps_geo_zone_id')) { 9 $status = true; 10 } elseif ($query->num_rows) { 11 $status = true; 12 } else { 13 $status = false; 14 } 15 16 $weight = $this->weight->convert($this->cart->getWeight(), $this->config->get('config_weight_class_id'), $this->config->get('shipping_usps_weight_class_id')); 17 18 // 70 pound limit 19 if ($weight > 70) { 20 $status = false; 21 } 22 23 $method_data = array(); 24 25 if ($status) { 26 $this->load->model('localisation/country'); 27 28 $quote_data = array(); 29 30 $weight = ($weight < 0.1 ? 0.1 : $weight); 31 $pounds = floor($weight); 32 $ounces = round(16 * ($weight - $pounds), 2); // max 5 digits 33 34 $postcode = str_replace(' ', '', $address['postcode']); 35 36 if ($address['iso_code_2'] == 'US') { 37 $xml = '<RateV4Request USERID="' . $this->config->get('shipping_usps_user_id') . '">'; 38 $xml .= ' <Package ID="1">'; 39 $xml .= ' <Service>ALL</Service>'; 40 $xml .= ' <ZipOrigination>' . substr($this->config->get('shipping_usps_postcode'), 0, 5) . '</ZipOrigination>'; 41 $xml .= ' <ZipDestination>' . substr($postcode, 0, 5) . '</ZipDestination>'; 42 $xml .= ' <Pounds>' . $pounds . '</Pounds>'; 43 $xml .= ' <Ounces>' . $ounces . '</Ounces>'; 44 45 // Prevent common size mismatch error from USPS (Size cannot be Regular if Container is Rectangular for some reason) 46 if ($this->config->get('shipping_usps_container') == 'RECTANGULAR' && $this->config->get('shipping_usps_size') == 'REGULAR') { 47 $this->config->set('shipping_usps_container', 'VARIABLE'); 48 } 49 50 $xml .= ' <Container>' . $this->config->get('shipping_usps_container') . '</Container>'; 51 $xml .= ' <Size>' . $this->config->get('shipping_usps_size') . '</Size>'; 52 $xml .= ' <Width>' . $this->config->get('shipping_usps_width') . '</Width>'; 53 $xml .= ' <Length>' . $this->config->get('shipping_usps_length') . '</Length>'; 54 $xml .= ' <Height>' . $this->config->get('shipping_usps_height') . '</Height>'; 55 56 // Calculate girth based on usps calculation 57 $xml .= ' <Girth>' . (round(((float)$this->config->get('shipping_usps_length') + (float)$this->config->get('shipping_usps_width') * 2 + (float)$this->config->get('shipping_usps_height') * 2), 1)) . '</Girth>'; 58 $xml .= ' <Machinable>' . ($this->config->get('shipping_usps_machinable') ? 'true' : 'false') . '</Machinable>'; 59 $xml .= ' </Package>'; 60 $xml .= '</RateV4Request>'; 61 62 $request = 'API=RateV4&XML=' . urlencode($xml); 63 } else { 64 $country = array( 65 'AF' => 'Afghanistan', 66 'AL' => 'Albania', 67 'DZ' => 'Algeria', 68 'AD' => 'Andorra', 69 'AO' => 'Angola', 70 'AI' => 'Anguilla', 71 'AG' => 'Antigua and Barbuda', 72 'AR' => 'Argentina', 73 'AM' => 'Armenia', 74 'AW' => 'Aruba', 75 'AU' => 'Australia', 76 'AT' => 'Austria', 77 'AZ' => 'Azerbaijan', 78 'BS' => 'Bahamas', 79 'BH' => 'Bahrain', 80 'BD' => 'Bangladesh', 81 'BB' => 'Barbados', 82 'BY' => 'Belarus', 83 'BE' => 'Belgium', 84 'BZ' => 'Belize', 85 'BJ' => 'Benin', 86 'BM' => 'Bermuda', 87 'BT' => 'Bhutan', 88 'BO' => 'Bolivia', 89 'BA' => 'Bosnia-Herzegovina', 90 'BW' => 'Botswana', 91 'BR' => 'Brazil', 92 'VG' => 'British Virgin Islands', 93 'BN' => 'Brunei Darussalam', 94 'BG' => 'Bulgaria', 95 'BF' => 'Burkina Faso', 96 'MM' => 'Burma', 97 'BI' => 'Burundi', 98 'KH' => 'Cambodia', 99 'CM' => 'Cameroon', 100 'CA' => 'Canada', 101 'CV' => 'Cape Verde', 102 'KY' => 'Cayman Islands', 103 'CF' => 'Central African Republic', 104 'TD' => 'Chad', 105 'CL' => 'Chile', 106 'CN' => 'China', 107 'CX' => 'Christmas Island (Australia)', 108 'CC' => 'Cocos Island (Australia)', 109 'CO' => 'Colombia', 110 'KM' => 'Comoros', 111 'CG' => 'Congo (Brazzaville),Republic of the', 112 'ZR' => 'Congo, Democratic Republic of the', 113 'CK' => 'Cook Islands (New Zealand)', 114 'CR' => 'Costa Rica', 115 'CI' => 'Cote d\'Ivoire (Ivory Coast)', 116 'HR' => 'Croatia', 117 'CU' => 'Cuba', 118 'CY' => 'Cyprus', 119 'CZ' => 'Czech Republic', 120 'DK' => 'Denmark', 121 'DJ' => 'Djibouti', 122 'DM' => 'Dominica', 123 'DO' => 'Dominican Republic', 124 'TP' => 'East Timor (Indonesia)', 125 'EC' => 'Ecuador', 126 'EG' => 'Egypt', 127 'SV' => 'El Salvador', 128 'GQ' => 'Equatorial Guinea', 129 'ER' => 'Eritrea', 130 'EE' => 'Estonia', 131 'ET' => 'Ethiopia', 132 'FK' => 'Falkland Islands', 133 'FO' => 'Faroe Islands', 134 'FJ' => 'Fiji', 135 'FI' => 'Finland', 136 'FR' => 'France', 137 'GF' => 'French Guiana', 138 'PF' => 'French Polynesia', 139 'GA' => 'Gabon', 140 'GM' => 'Gambia', 141 'GE' => 'Georgia, Republic of', 142 'DE' => 'Germany', 143 'GH' => 'Ghana', 144 'GI' => 'Gibraltar', 145 'GB' => 'Great Britain and Northern Ireland', 146 'GR' => 'Greece', 147 'GL' => 'Greenland', 148 'GD' => 'Grenada', 149 'GP' => 'Guadeloupe', 150 'GT' => 'Guatemala', 151 'GN' => 'Guinea', 152 'GW' => 'Guinea-Bissau', 153 'GY' => 'Guyana', 154 'HT' => 'Haiti', 155 'HN' => 'Honduras', 156 'HK' => 'Hong Kong', 157 'HU' => 'Hungary', 158 'IS' => 'Iceland', 159 'IN' => 'India', 160 'ID' => 'Indonesia', 161 'IR' => 'Iran', 162 'IQ' => 'Iraq', 163 'IE' => 'Ireland', 164 'IL' => 'Israel', 165 'IT' => 'Italy', 166 'JM' => 'Jamaica', 167 'JP' => 'Japan', 168 'JO' => 'Jordan', 169 'KZ' => 'Kazakhstan', 170 'KE' => 'Kenya', 171 'KI' => 'Kiribati', 172 'KW' => 'Kuwait', 173 'KG' => 'Kyrgyzstan', 174 'LA' => 'Laos', 175 'LV' => 'Latvia', 176 'LB' => 'Lebanon', 177 'LS' => 'Lesotho', 178 'LR' => 'Liberia', 179 'LY' => 'Libya', 180 'LI' => 'Liechtenstein', 181 'LT' => 'Lithuania', 182 'LU' => 'Luxembourg', 183 'MO' => 'Macao', 184 'MK' => 'Macedonia, Republic of', 185 'MG' => 'Madagascar', 186 'MW' => 'Malawi', 187 'MY' => 'Malaysia', 188 'MV' => 'Maldives', 189 'ML' => 'Mali', 190 'MT' => 'Malta', 191 'MQ' => 'Martinique', 192 'MR' => 'Mauritania', 193 'MU' => 'Mauritius', 194 'YT' => 'Mayotte (France)', 195 'MX' => 'Mexico', 196 'MD' => 'Moldova', 197 'MC' => 'Monaco (France)', 198 'MN' => 'Mongolia', 199 'MS' => 'Montserrat', 200 'MA' => 'Morocco', 201 'MZ' => 'Mozambique', 202 'NA' => 'Namibia', 203 'NR' => 'Nauru', 204 'NP' => 'Nepal', 205 'NL' => 'Netherlands', 206 'AN' => 'Netherlands Antilles', 207 'NC' => 'New Caledonia', 208 'NZ' => 'New Zealand', 209 'NI' => 'Nicaragua', 210 'NE' => 'Niger', 211 'NG' => 'Nigeria', 212 'KP' => 'North Korea (Korea, Democratic People\'s Republic of)', 213 'NO' => 'Norway', 214 'OM' => 'Oman', 215 'PK' => 'Pakistan', 216 'PA' => 'Panama', 217 'PG' => 'Papua New Guinea', 218 'PY' => 'Paraguay', 219 'PE' => 'Peru', 220 'PH' => 'Philippines', 221 'PN' => 'Pitcairn Island', 222 'PL' => 'Poland', 223 'PT' => 'Portugal', 224 'QA' => 'Qatar', 225 'RE' => 'Reunion', 226 'RO' => 'Romania', 227 'RU' => 'Russia', 228 'RW' => 'Rwanda', 229 'SH' => 'Saint Helena', 230 'KN' => 'Saint Kitts (St. Christopher and Nevis)', 231 'LC' => 'Saint Lucia', 232 'PM' => 'Saint Pierre and Miquelon', 233 'VC' => 'Saint Vincent and the Grenadines', 234 'SM' => 'San Marino', 235 'ST' => 'Sao Tome and Principe', 236 'SA' => 'Saudi Arabia', 237 'SN' => 'Senegal', 238 'YU' => 'Serbia-Montenegro', 239 'SC' => 'Seychelles', 240 'SL' => 'Sierra Leone', 241 'SG' => 'Singapore', 242 'SK' => 'Slovak Republic', 243 'SI' => 'Slovenia', 244 'SB' => 'Solomon Islands', 245 'SO' => 'Somalia', 246 'ZA' => 'South Africa', 247 'GS' => 'South Georgia (Falkland Islands)', 248 'KR' => 'South Korea (Korea, Republic of)', 249 'ES' => 'Spain', 250 'LK' => 'Sri Lanka', 251 'SD' => 'Sudan', 252 'SR' => 'Suriname', 253 'SZ' => 'Swaziland', 254 'SE' => 'Sweden', 255 'CH' => 'Switzerland', 256 'SY' => 'Syrian Arab Republic', 257 'TW' => 'Taiwan', 258 'TJ' => 'Tajikistan', 259 'TZ' => 'Tanzania', 260 'TH' => 'Thailand', 261 'TG' => 'Togo', 262 'TK' => 'Tokelau (Union) Group (Western Samoa)', 263 'TO' => 'Tonga', 264 'TT' => 'Trinidad and Tobago', 265 'TN' => 'Tunisia', 266 'TR' => 'Turkey', 267 'TM' => 'Turkmenistan', 268 'TC' => 'Turks and Caicos Islands', 269 'TV' => 'Tuvalu', 270 'UG' => 'Uganda', 271 'UA' => 'Ukraine', 272 'AE' => 'United Arab Emirates', 273 'UY' => 'Uruguay', 274 'UZ' => 'Uzbekistan', 275 'VU' => 'Vanuatu', 276 'VA' => 'Vatican City', 277 'VE' => 'Venezuela', 278 'VN' => 'Vietnam', 279 'WF' => 'Wallis and Futuna Islands', 280 'WS' => 'Western Samoa', 281 'YE' => 'Yemen', 282 'ZM' => 'Zambia', 283 'ZW' => 'Zimbabwe' 284 ); 285 286 if (isset($country[$address['iso_code_2']])) { 287 $xml = '<IntlRateV2Request USERID="' . $this->config->get('shipping_usps_user_id') . '">'; 288 $xml .= ' <Revision>2</Revision>'; 289 $xml .= ' <Package ID="1">'; 290 $xml .= ' <Pounds>' . $pounds . '</Pounds>'; 291 $xml .= ' <Ounces>' . $ounces . '</Ounces>'; 292 $xml .= ' <MailType>All</MailType>'; 293 $xml .= ' <GXG>'; 294 $xml .= ' <POBoxFlag>N</POBoxFlag>'; 295 $xml .= ' <GiftFlag>N</GiftFlag>'; 296 $xml .= ' </GXG>'; 297 $xml .= ' <ValueOfContents>' . $this->cart->getSubTotal() . '</ValueOfContents>'; 298 $xml .= ' <Country>' . $country[$address['iso_code_2']] . '</Country>'; 299 300 // Intl only supports RECT and NONRECT 301 if ($this->config->get('shipping_usps_container') == 'VARIABLE') { 302 $this->config->set('shipping_usps_container', 'NONRECTANGULAR'); 303 } 304 305 $xml .= ' <Container>' . $this->config->get('shipping_usps_container') . '</Container>'; 306 $xml .= ' <Size>' . $this->config->get('shipping_usps_size') . '</Size>'; 307 $xml .= ' <Width>' . $this->config->get('shipping_usps_width') . '</Width>'; 308 $xml .= ' <Length>' . $this->config->get('shipping_usps_length') . '</Length>'; 309 $xml .= ' <Height>' . $this->config->get('shipping_usps_height') . '</Height>'; 310 311 // Calculate girth based on usps calculation 312 $xml .= ' <Girth>' . (round(((float)$this->config->get('shipping_usps_length') + (float)$this->config->get('shipping_usps_width') * 2 + (float)$this->config->get('shipping_usps_height') * 2), 1)) . '</Girth>'; 313 $xml .= ' <OriginZip>' . substr($this->config->get('shipping_usps_postcode'), 0, 5) . '</OriginZip>'; 314 $xml .= ' <CommercialFlag>N</CommercialFlag>'; 315 $xml .= ' </Package>'; 316 $xml .= '</IntlRateV2Request>'; 317 318 $request = 'API=IntlRateV2&XML=' . urlencode($xml); 319 } else { 320 $status = false; 321 } 322 } 323 324 if ($status) { 325 $curl = curl_init(); 326 327 curl_setopt($curl, CURLOPT_URL, 'production.shippingapis.com/ShippingAPI.dll?' . $request); 328 curl_setopt($curl, CURLOPT_HEADER, 0); 329 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 330 331 $result = curl_exec($curl); 332 333 curl_close($curl); 334 335 // strip reg, trade and ** out, updated 9-11-2013 336 $result = str_replace('&lt;sup&gt;&#174;&lt;/sup&gt;', '', $result); 337 $result = str_replace('&lt;sup&gt;&#8482;&lt;/sup&gt;', '', $result); 338 $result = str_replace('&lt;sup&gt;&#174;&lt;/sup&gt;', '', $result); 339 340 $result = str_replace('**', '', $result); 341 $result = str_replace("\r\n", '', $result); 342 $result = str_replace('\"', '"', $result); 343 344 if ($result) { 345 if ($this->config->get('shipping_usps_debug')) { 346 $this->log->write("USPS DATA SENT: " . urldecode($request)); 347 $this->log->write("USPS DATA RECV: " . $result); 348 } 349 350 $dom = new DOMDocument('1.0', 'UTF-8'); 351 $dom->loadXml($result); 352 353 $rate_response = $dom->getElementsByTagName('RateV4Response')->item(0); 354 $intl_rate_response = $dom->getElementsByTagName('IntlRateV2Response')->item(0); 355 $error = $dom->getElementsByTagName('Error')->item(0); 356 357 $firstclasses = array ( 358 'First-Class Mail Parcel', 359 'First-Class Mail Large Envelope', 360 'First-Class Mail Stamped Letter', 361 'First-Class Mail Postcards' 362 ); 363 364 if ($rate_response || $intl_rate_response) { 365 if ($address['iso_code_2'] == 'US') { 366 $allowed = array(0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 16, 17, 18, 19, 22, 23, 25, 27, 28); 367 368 $package = $rate_response->getElementsByTagName('Package')->item(0); 369 370 $postages = $package->getElementsByTagName('Postage'); 371 372 if ($postages->length) { 373 foreach ($postages as $postage) { 374 $classid = $postage->getAttribute('CLASSID'); 375 376 if (in_array($classid, $allowed)) { 377 if ($classid == '0') { 378 $mailservice = $postage->getElementsByTagName('MailService')->item(0)->nodeValue; 379 380 foreach ($firstclasses as $k => $firstclass) { 381 if ($firstclass == $mailservice) { 382 $classid = $classid . $k; 383 break; 384 } 385 } 386 387 if (($this->config->get('shipping_usps_domestic_' . $classid))) { 388 $cost = $postage->getElementsByTagName('Rate')->item(0)->nodeValue; 389 390 $quote_data[$classid] = array( 391 'code' => 'usps.' . $classid, 392 'title' => $postage->getElementsByTagName('MailService')->item(0)->nodeValue, 393 'cost' => $this->currency->convert($cost, 'USD', $this->config->get('config_currency')), 394 'tax_class_id' => $this->config->get('shipping_usps_tax_class_id'), 395 'text' => $this->currency->format($this->tax->calculate($this->currency->convert($cost, 'USD', $this->session->data['currency']), $this->config->get('shipping_usps_tax_class_id'), $this->config->get('config_tax')), $this->session->data['currency'], 1.0000000) 396 ); 397 } 398 399 } elseif ($this->config->get('shipping_usps_domestic_' . $classid)) { 400 $cost = $postage->getElementsByTagName('Rate')->item(0)->nodeValue; 401 402 $quote_data[$classid] = array( 403 'code' => 'usps.' . $classid, 404 'title' => $postage->getElementsByTagName('MailService')->item(0)->nodeValue, 405 'cost' => $this->currency->convert($cost, 'USD', $this->config->get('config_currency')), 406 'tax_class_id' => $this->config->get('shipping_usps_tax_class_id'), 407 'text' => $this->currency->format($this->tax->calculate($this->currency->convert($cost, 'USD', $this->session->data['currency']), $this->config->get('shipping_usps_tax_class_id'), $this->config->get('config_tax')), $this->session->data['currency'], 1.0000000) 408 ); 409 } 410 } 411 } 412 } else { 413 $error = $package->getElementsByTagName('Error')->item(0); 414 415 $method_data = array( 416 'code' => 'usps', 417 'title' => $this->language->get('text_title'), 418 'quote' => $quote_data, 419 'sort_order' => $this->config->get('shipping_usps_sort_order'), 420 'error' => $error->getElementsByTagName('Description')->item(0)->nodeValue 421 ); 422 } 423 } else { 424 $allowed = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 21); 425 426 $package = $intl_rate_response->getElementsByTagName('Package')->item(0); 427 428 $services = $package->getElementsByTagName('Service'); 429 430 foreach ($services as $service) { 431 $id = $service->getAttribute('ID'); 432 433 if (in_array($id, $allowed) && $this->config->get('shipping_usps_international_' . $id)) { 434 $title = $service->getElementsByTagName('SvcDescription')->item(0)->nodeValue; 435 436 if ($this->config->get('shipping_usps_display_time')) { 437 $title .= ' (' . $this->language->get('text_eta') . ' ' . $service->getElementsByTagName('SvcCommitments')->item(0)->nodeValue . ')'; 438 } 439 440 $cost = $service->getElementsByTagName('Postage')->item(0)->nodeValue; 441 442 $quote_data[$id] = array( 443 'code' => 'usps.' . $id, 444 'title' => $title, 445 'cost' => $this->currency->convert($cost, 'USD', $this->config->get('config_currency')), 446 'tax_class_id' => $this->config->get('shipping_usps_tax_class_id'), 447 'text' => $this->currency->format($this->tax->calculate($this->currency->convert($cost, 'USD', $this->session->data['currency']), $this->config->get('shipping_usps_tax_class_id'), $this->config->get('config_tax')), $this->session->data['currency'], 1.0000000) 448 ); 449 } 450 } 451 } 452 } elseif ($error) { 453 $method_data = array( 454 'code' => 'usps', 455 'title' => $this->language->get('text_title'), 456 'quote' => $quote_data, 457 'sort_order' => $this->config->get('shipping_usps_sort_order'), 458 'error' => $error->getElementsByTagName('Description')->item(0)->nodeValue 459 ); 460 } 461 } 462 } 463 464 if ($quote_data) { 465 $title = $this->language->get('text_title'); 466 467 if ($this->config->get('shipping_usps_display_weight')) { 468 $title .= ' (' . $this->language->get('text_weight') . ' ' . $this->weight->format($weight, $this->config->get('shipping_usps_weight_class_id')) . ')'; 469 } 470 471 $method_data = array( 472 'code' => 'usps', 473 'title' => $title, 474 'quote' => $quote_data, 475 'sort_order' => $this->config->get('shipping_usps_sort_order'), 476 'error' => false 477 ); 478 } 479 } 480 481 return $method_data; 482 } 483 }