PageRenderTime 63ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/magento/app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php

https://bitbucket.org/jit_bec/shopifine
PHP | 1809 lines | 1345 code | 181 blank | 283 comment | 180 complexity | d250bb3d610ebb5f15f7ea70a3e9baf6 MD5 | raw file
Possible License(s): LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Usa
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * UPS shipping implementation
  28. *
  29. * @category Mage
  30. * @package Mage_Usa
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Usa_Model_Shipping_Carrier_Ups
  34. extends Mage_Usa_Model_Shipping_Carrier_Abstract
  35. implements Mage_Shipping_Model_Carrier_Interface
  36. {
  37. /**
  38. * Code of the carrier
  39. *
  40. * @var string
  41. */
  42. const CODE = 'ups';
  43. /**
  44. * Delivery Confirmation level based on origin/destination
  45. *
  46. * @var int
  47. */
  48. const DELIVERY_CONFIRMATION_SHIPMENT = 1;
  49. const DELIVERY_CONFIRMATION_PACKAGE = 2;
  50. /**
  51. * Code of the carrier
  52. *
  53. * @var string
  54. */
  55. protected $_code = self::CODE;
  56. /**
  57. * Rate request data
  58. *
  59. * @var Mage_Shipping_Model_Rate_Request|null
  60. */
  61. protected $_request = null;
  62. /**
  63. * Raw rate request data
  64. *
  65. * @var Varien_Object|null
  66. */
  67. protected $_rawRequest = null;
  68. /**
  69. * Rate result data
  70. *
  71. * @var Mage_Shipping_Model_Rate_Result|null
  72. */
  73. protected $_result = null;
  74. /**
  75. * Base currency rate
  76. *
  77. * @var double
  78. */
  79. protected $_baseCurrencyRate;
  80. /**
  81. * Xml access request
  82. *
  83. * @var string
  84. */
  85. protected $_xmlAccessRequest = null;
  86. /**
  87. * Default cgi gateway url
  88. *
  89. * @var string
  90. */
  91. protected $_defaultCgiGatewayUrl = 'http://www.ups.com:80/using/services/rave/qcostcgi.cgi';
  92. /**
  93. * Default urls for shipment
  94. *
  95. * @var array
  96. */
  97. protected $_defaultUrls = array(
  98. 'ShipConfirm' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
  99. 'ShipAccept' => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',
  100. );
  101. /**
  102. * Container types that could be customized for UPS carrier
  103. *
  104. * @var array
  105. */
  106. protected $_customizableContainerTypes = array('CP', 'CSP');
  107. /**
  108. * Collect and get rates
  109. *
  110. * @param Mage_Shipping_Model_Rate_Request $request
  111. * @return Mage_Shipping_Model_Rate_Result|bool|null
  112. */
  113. public function collectRates(Mage_Shipping_Model_Rate_Request $request)
  114. {
  115. if (!$this->getConfigFlag($this->_activeFlag)) {
  116. return false;
  117. }
  118. $this->setRequest($request);
  119. $this->_result = $this->_getQuotes();
  120. $this->_updateFreeMethodQuote($request);
  121. return $this->getResult();
  122. }
  123. /**
  124. * Prepare and set request to this instance
  125. *
  126. * @param Mage_Shipping_Model_Rate_Request $request
  127. * @return Mage_Usa_Model_Shipping_Carrier_Ups
  128. */
  129. public function setRequest(Mage_Shipping_Model_Rate_Request $request)
  130. {
  131. $this->_request = $request;
  132. $r = new Varien_Object();
  133. if ($request->getLimitMethod()) {
  134. $r->setAction($this->getCode('action', 'single'));
  135. $r->setProduct($request->getLimitMethod());
  136. } else {
  137. $r->setAction($this->getCode('action', 'all'));
  138. $r->setProduct('GND'.$this->getConfigData('dest_type'));
  139. }
  140. if ($request->getUpsPickup()) {
  141. $pickup = $request->getUpsPickup();
  142. } else {
  143. $pickup = $this->getConfigData('pickup');
  144. }
  145. $r->setPickup($this->getCode('pickup', $pickup));
  146. if ($request->getUpsContainer()) {
  147. $container = $request->getUpsContainer();
  148. } else {
  149. $container = $this->getConfigData('container');
  150. }
  151. $r->setContainer($this->getCode('container', $container));
  152. if ($request->getUpsDestType()) {
  153. $destType = $request->getUpsDestType();
  154. } else {
  155. $destType = $this->getConfigData('dest_type');
  156. }
  157. $r->setDestType($this->getCode('dest_type', $destType));
  158. if ($request->getOrigCountry()) {
  159. $origCountry = $request->getOrigCountry();
  160. } else {
  161. $origCountry = Mage::getStoreConfig(
  162. Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID,
  163. $request->getStoreId()
  164. );
  165. }
  166. $r->setOrigCountry(Mage::getModel('directory/country')->load($origCountry)->getIso2Code());
  167. if ($request->getOrigRegionCode()) {
  168. $origRegionCode = $request->getOrigRegionCode();
  169. } else {
  170. $origRegionCode = Mage::getStoreConfig(
  171. Mage_Shipping_Model_Shipping::XML_PATH_STORE_REGION_ID,
  172. $request->getStoreId()
  173. );
  174. }
  175. if (is_numeric($origRegionCode)) {
  176. $origRegionCode = Mage::getModel('directory/region')->load($origRegionCode)->getCode();
  177. }
  178. $r->setOrigRegionCode($origRegionCode);
  179. if ($request->getOrigPostcode()) {
  180. $r->setOrigPostal($request->getOrigPostcode());
  181. } else {
  182. $r->setOrigPostal(Mage::getStoreConfig(
  183. Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP,
  184. $request->getStoreId()
  185. ));
  186. }
  187. if ($request->getOrigCity()) {
  188. $r->setOrigCity($request->getOrigCity());
  189. } else {
  190. $r->setOrigCity(Mage::getStoreConfig(
  191. Mage_Shipping_Model_Shipping::XML_PATH_STORE_CITY,
  192. $request->getStoreId()
  193. ));
  194. }
  195. if ($request->getDestCountryId()) {
  196. $destCountry = $request->getDestCountryId();
  197. } else {
  198. $destCountry = self::USA_COUNTRY_ID;
  199. }
  200. //for UPS, puero rico state for US will assume as puerto rico country
  201. if ($destCountry == self::USA_COUNTRY_ID
  202. && ($request->getDestPostcode()=='00912' || $request->getDestRegionCode()==self::PUERTORICO_COUNTRY_ID)
  203. ) {
  204. $destCountry = self::PUERTORICO_COUNTRY_ID;
  205. }
  206. // For UPS, Guam state of the USA will be represented by Guam country
  207. if ($destCountry == self::USA_COUNTRY_ID && $request->getDestRegionCode() == self::GUAM_REGION_CODE) {
  208. $destCountry = self::GUAM_COUNTRY_ID;
  209. }
  210. $r->setDestCountry(Mage::getModel('directory/country')->load($destCountry)->getIso2Code());
  211. $r->setDestRegionCode($request->getDestRegionCode());
  212. if ($request->getDestPostcode()) {
  213. $r->setDestPostal($request->getDestPostcode());
  214. } else {
  215. }
  216. $weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
  217. $weight = $this->_getCorrectWeight($weight);
  218. $r->setWeight($weight);
  219. if ($request->getFreeMethodWeight()!=$request->getPackageWeight()) {
  220. $r->setFreeMethodWeight($request->getFreeMethodWeight());
  221. }
  222. $r->setValue($request->getPackageValue());
  223. $r->setValueWithDiscount($request->getPackageValueWithDiscount());
  224. if ($request->getUpsUnitMeasure()) {
  225. $unit = $request->getUpsUnitMeasure();
  226. } else {
  227. $unit = $this->getConfigData('unit_of_measure');
  228. }
  229. $r->setUnitMeasure($unit);
  230. $r->setIsReturn($request->getIsReturn());
  231. $r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
  232. $this->_rawRequest = $r;
  233. return $this;
  234. }
  235. /**
  236. * Get correct weigt.
  237. *
  238. * Namely:
  239. * Checks the current weight to comply with the minimum weight standards set by the carrier.
  240. * Then strictly rounds the weight up until the first significant digit after the decimal point.
  241. *
  242. * @param float|integer|double $weight
  243. * @return float
  244. */
  245. protected function _getCorrectWeight($weight)
  246. {
  247. $minWeight = $this->getConfigData('min_package_weight');
  248. if($weight < $minWeight){
  249. $weight = $minWeight;
  250. }
  251. //rounds a number to one significant figure
  252. $weight = ceil($weight*10) / 10;
  253. return $weight;
  254. }
  255. /**
  256. * Get result of request
  257. *
  258. * @return mixed
  259. */
  260. public function getResult()
  261. {
  262. return $this->_result;
  263. }
  264. /**
  265. * Do remote request for and handle errors
  266. *
  267. * @return Mage_Shipping_Model_Rate_Result
  268. */
  269. protected function _getQuotes()
  270. {
  271. switch ($this->getConfigData('type')) {
  272. case 'UPS':
  273. return $this->_getCgiQuotes();
  274. case 'UPS_XML':
  275. return $this->_getXmlQuotes();
  276. }
  277. return null;
  278. }
  279. /**
  280. * Set free method request
  281. *
  282. * @param string $freeMethod
  283. * @return null
  284. */
  285. protected function _setFreeMethodRequest($freeMethod)
  286. {
  287. $r = $this->_rawRequest;
  288. $weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight());
  289. $weight = $this->_getCorrectWeight($weight);
  290. $r->setWeight($weight);
  291. $r->setAction($this->getCode('action', 'single'));
  292. $r->setProduct($freeMethod);
  293. }
  294. /**
  295. * Get cgi rates
  296. *
  297. * @return Mage_Shipping_Model_Rate_Result
  298. */
  299. protected function _getCgiQuotes()
  300. {
  301. $r = $this->_rawRequest;
  302. $params = array(
  303. 'accept_UPS_license_agreement' => 'yes',
  304. '10_action' => $r->getAction(),
  305. '13_product' => $r->getProduct(),
  306. '14_origCountry' => $r->getOrigCountry(),
  307. '15_origPostal' => $r->getOrigPostal(),
  308. 'origCity' => $r->getOrigCity(),
  309. '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ?
  310. substr($r->getDestPostal(), 0, 5) :
  311. $r->getDestPostal(),
  312. '22_destCountry' => $r->getDestCountry(),
  313. '23_weight' => $r->getWeight(),
  314. '47_rate_chart' => $r->getPickup(),
  315. '48_container' => $r->getContainer(),
  316. '49_residential' => $r->getDestType(),
  317. 'weight_std' => strtolower($r->getUnitMeasure()),
  318. );
  319. $params['47_rate_chart'] = $params['47_rate_chart']['label'];
  320. $responseBody = $this->_getCachedQuotes($params);
  321. if ($responseBody === null) {
  322. $debugData = array('request' => $params);
  323. try {
  324. $url = $this->getConfigData('gateway_url');
  325. if (!$url) {
  326. $url = $this->_defaultCgiGatewayUrl;
  327. }
  328. $client = new Zend_Http_Client();
  329. $client->setUri($url);
  330. $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
  331. $client->setParameterGet($params);
  332. $response = $client->request();
  333. $responseBody = $response->getBody();
  334. $debugData['result'] = $responseBody;
  335. $this->_setCachedQuotes($params, $responseBody);
  336. }
  337. catch (Exception $e) {
  338. $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
  339. $responseBody = '';
  340. }
  341. $this->_debug($debugData);
  342. }
  343. return $this->_parseCgiResponse($responseBody);
  344. }
  345. /**
  346. * Get shipment by code
  347. *
  348. * @param string $code
  349. * @param string $origin
  350. * @return array|bool
  351. */
  352. public function getShipmentByCode($code, $origin = null){
  353. if($origin===null){
  354. $origin = $this->getConfigData('origin_shipment');
  355. }
  356. $arr = $this->getCode('originShipment',$origin);
  357. if(isset($arr[$code]))
  358. return $arr[$code];
  359. else
  360. return false;
  361. }
  362. /**
  363. * Prepare shipping rate result based on response
  364. *
  365. * @param mixed $response
  366. * @return Mage_Shipping_Model_Rate_Result
  367. */
  368. protected function _parseCgiResponse($response)
  369. {
  370. $costArr = array();
  371. $priceArr = array();
  372. $errorTitle = Mage::helper('usa')->__('Unknown error');
  373. if (strlen(trim($response))>0) {
  374. $rRows = explode("\n", $response);
  375. $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
  376. foreach ($rRows as $rRow) {
  377. $r = explode('%', $rRow);
  378. switch (substr($r[0],-1)) {
  379. case 3: case 4:
  380. if (in_array($r[1], $allowedMethods)) {
  381. $responsePrice = Mage::app()->getLocale()->getNumber($r[8]);
  382. $costArr[$r[1]] = $responsePrice;
  383. $priceArr[$r[1]] = $this->getMethodPrice($responsePrice, $r[1]);
  384. }
  385. break;
  386. case 5:
  387. $errorTitle = $r[1];
  388. break;
  389. case 6:
  390. if (in_array($r[3], $allowedMethods)) {
  391. $responsePrice = Mage::app()->getLocale()->getNumber($r[10]);
  392. $costArr[$r[3]] = $responsePrice;
  393. $priceArr[$r[3]] = $this->getMethodPrice($responsePrice, $r[3]);
  394. }
  395. break;
  396. }
  397. }
  398. asort($priceArr);
  399. }
  400. $result = Mage::getModel('shipping/rate_result');
  401. $defaults = $this->getDefaults();
  402. if (empty($priceArr)) {
  403. $error = Mage::getModel('shipping/rate_result_error');
  404. $error->setCarrier('ups');
  405. $error->setCarrierTitle($this->getConfigData('title'));
  406. $error->setErrorMessage($this->getConfigData('specificerrmsg'));
  407. $result->append($error);
  408. } else {
  409. foreach ($priceArr as $method=>$price) {
  410. $rate = Mage::getModel('shipping/rate_result_method');
  411. $rate->setCarrier('ups');
  412. $rate->setCarrierTitle($this->getConfigData('title'));
  413. $rate->setMethod($method);
  414. $method_arr = $this->getCode('method', $method);
  415. $rate->setMethodTitle(Mage::helper('usa')->__($method_arr));
  416. $rate->setCost($costArr[$method]);
  417. $rate->setPrice($price);
  418. $result->append($rate);
  419. }
  420. }
  421. return $result;
  422. }
  423. /**
  424. * Get configuration data of carrier
  425. *
  426. * @param string $type
  427. * @param string $code
  428. * @return array|bool
  429. */
  430. public function getCode($type, $code='')
  431. {
  432. $codes = array(
  433. 'action'=>array(
  434. 'single'=>'3',
  435. 'all'=>'4',
  436. ),
  437. 'originShipment'=>array(
  438. // United States Domestic Shipments
  439. 'United States Domestic Shipments' => array(
  440. '01' => Mage::helper('usa')->__('UPS Next Day Air'),
  441. '02' => Mage::helper('usa')->__('UPS Second Day Air'),
  442. '03' => Mage::helper('usa')->__('UPS Ground'),
  443. '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
  444. '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
  445. '11' => Mage::helper('usa')->__('UPS Standard'),
  446. '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
  447. '13' => Mage::helper('usa')->__('UPS Next Day Air Saver'),
  448. '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
  449. '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
  450. '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'),
  451. '65' => Mage::helper('usa')->__('UPS Saver'),
  452. ),
  453. // Shipments Originating in United States
  454. 'Shipments Originating in United States' => array(
  455. '01' => Mage::helper('usa')->__('UPS Next Day Air'),
  456. '02' => Mage::helper('usa')->__('UPS Second Day Air'),
  457. '03' => Mage::helper('usa')->__('UPS Ground'),
  458. '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
  459. '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
  460. '11' => Mage::helper('usa')->__('UPS Standard'),
  461. '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
  462. '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
  463. '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
  464. '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'),
  465. '65' => Mage::helper('usa')->__('UPS Worldwide Saver'),
  466. ),
  467. // Shipments Originating in Canada
  468. 'Shipments Originating in Canada' => array(
  469. '01' => Mage::helper('usa')->__('UPS Express'),
  470. '02' => Mage::helper('usa')->__('UPS Expedited'),
  471. '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
  472. '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
  473. '11' => Mage::helper('usa')->__('UPS Standard'),
  474. '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
  475. '14' => Mage::helper('usa')->__('UPS Express Early A.M.'),
  476. '65' => Mage::helper('usa')->__('UPS Saver'),
  477. ),
  478. // Shipments Originating in the European Union
  479. 'Shipments Originating in the European Union' => array(
  480. '07' => Mage::helper('usa')->__('UPS Express'),
  481. '08' => Mage::helper('usa')->__('UPS Expedited'),
  482. '11' => Mage::helper('usa')->__('UPS Standard'),
  483. '54' => Mage::helper('usa')->__('UPS Worldwide Express PlusSM'),
  484. '65' => Mage::helper('usa')->__('UPS Saver'),
  485. ),
  486. // Polish Domestic Shipments
  487. 'Polish Domestic Shipments' => array(
  488. '07' => Mage::helper('usa')->__('UPS Express'),
  489. '08' => Mage::helper('usa')->__('UPS Expedited'),
  490. '11' => Mage::helper('usa')->__('UPS Standard'),
  491. '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
  492. '65' => Mage::helper('usa')->__('UPS Saver'),
  493. '82' => Mage::helper('usa')->__('UPS Today Standard'),
  494. '83' => Mage::helper('usa')->__('UPS Today Dedicated Courrier'),
  495. '84' => Mage::helper('usa')->__('UPS Today Intercity'),
  496. '85' => Mage::helper('usa')->__('UPS Today Express'),
  497. '86' => Mage::helper('usa')->__('UPS Today Express Saver'),
  498. ),
  499. // Puerto Rico Origin
  500. 'Puerto Rico Origin' => array(
  501. '01' => Mage::helper('usa')->__('UPS Next Day Air'),
  502. '02' => Mage::helper('usa')->__('UPS Second Day Air'),
  503. '03' => Mage::helper('usa')->__('UPS Ground'),
  504. '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
  505. '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
  506. '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
  507. '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
  508. '65' => Mage::helper('usa')->__('UPS Saver'),
  509. ),
  510. // Shipments Originating in Mexico
  511. 'Shipments Originating in Mexico' => array(
  512. '07' => Mage::helper('usa')->__('UPS Express'),
  513. '08' => Mage::helper('usa')->__('UPS Expedited'),
  514. '54' => Mage::helper('usa')->__('UPS Express Plus'),
  515. '65' => Mage::helper('usa')->__('UPS Saver'),
  516. ),
  517. // Shipments Originating in Other Countries
  518. 'Shipments Originating in Other Countries' => array(
  519. '07' => Mage::helper('usa')->__('UPS Express'),
  520. '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
  521. '11' => Mage::helper('usa')->__('UPS Standard'),
  522. '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
  523. '65' => Mage::helper('usa')->__('UPS Saver')
  524. )
  525. ),
  526. 'method'=>array(
  527. '1DM' => Mage::helper('usa')->__('Next Day Air Early AM'),
  528. '1DML' => Mage::helper('usa')->__('Next Day Air Early AM Letter'),
  529. '1DA' => Mage::helper('usa')->__('Next Day Air'),
  530. '1DAL' => Mage::helper('usa')->__('Next Day Air Letter'),
  531. '1DAPI' => Mage::helper('usa')->__('Next Day Air Intra (Puerto Rico)'),
  532. '1DP' => Mage::helper('usa')->__('Next Day Air Saver'),
  533. '1DPL' => Mage::helper('usa')->__('Next Day Air Saver Letter'),
  534. '2DM' => Mage::helper('usa')->__('2nd Day Air AM'),
  535. '2DML' => Mage::helper('usa')->__('2nd Day Air AM Letter'),
  536. '2DA' => Mage::helper('usa')->__('2nd Day Air'),
  537. '2DAL' => Mage::helper('usa')->__('2nd Day Air Letter'),
  538. '3DS' => Mage::helper('usa')->__('3 Day Select'),
  539. 'GND' => Mage::helper('usa')->__('Ground'),
  540. 'GNDCOM' => Mage::helper('usa')->__('Ground Commercial'),
  541. 'GNDRES' => Mage::helper('usa')->__('Ground Residential'),
  542. 'STD' => Mage::helper('usa')->__('Canada Standard'),
  543. 'XPR' => Mage::helper('usa')->__('Worldwide Express'),
  544. 'WXS' => Mage::helper('usa')->__('Worldwide Express Saver'),
  545. 'XPRL' => Mage::helper('usa')->__('Worldwide Express Letter'),
  546. 'XDM' => Mage::helper('usa')->__('Worldwide Express Plus'),
  547. 'XDML' => Mage::helper('usa')->__('Worldwide Express Plus Letter'),
  548. 'XPD' => Mage::helper('usa')->__('Worldwide Expedited'),
  549. ),
  550. 'pickup'=>array(
  551. 'RDP' => array("label"=>'Regular Daily Pickup',"code"=>"01"),
  552. 'OCA' => array("label"=>'On Call Air',"code"=>"07"),
  553. 'OTP' => array("label"=>'One Time Pickup',"code"=>"06"),
  554. 'LC' => array("label"=>'Letter Center',"code"=>"19"),
  555. 'CC' => array("label"=>'Customer Counter',"code"=>"03"),
  556. ),
  557. 'container'=>array(
  558. 'CP' => '00', // Customer Packaging
  559. 'ULE' => '01', // UPS Letter Envelope
  560. 'CSP' => '02', // Customer Supplied Package
  561. 'UT' => '03', // UPS Tube
  562. 'PAK' => '04', // PAK
  563. 'UEB' => '21', // UPS Express Box
  564. 'UW25' => '24', // UPS Worldwide 25 kilo
  565. 'UW10' => '25', // UPS Worldwide 10 kilo
  566. 'PLT' => '30', // Pallet
  567. 'SEB' => '2a', // Small Express Box
  568. 'MEB' => '2b', // Medium Express Box
  569. 'LEB' => '2c', // Large Express Box
  570. ),
  571. 'container_description'=>array(
  572. 'CP' => Mage::helper('usa')->__('Customer Packaging'),
  573. 'ULE' => Mage::helper('usa')->__('UPS Letter Envelope'),
  574. 'CSP' => Mage::helper('usa')->__('Customer Supplied Package'),
  575. 'UT' => Mage::helper('usa')->__('UPS Tube'),
  576. 'PAK' => Mage::helper('usa')->__('PAK'),
  577. 'UEB' => Mage::helper('usa')->__('UPS Express Box'),
  578. 'UW25' => Mage::helper('usa')->__('UPS Worldwide 25 kilo'),
  579. 'UW10' => Mage::helper('usa')->__('UPS Worldwide 10 kilo'),
  580. 'PLT' => Mage::helper('usa')->__('Pallet'),
  581. 'SEB' => Mage::helper('usa')->__('Small Express Box'),
  582. 'MEB' => Mage::helper('usa')->__('Medium Express Box'),
  583. 'LEB' => Mage::helper('usa')->__('Large Express Box'),
  584. ),
  585. 'dest_type'=>array(
  586. 'RES' => '01', // Residential
  587. 'COM' => '02', // Commercial
  588. ),
  589. 'dest_type_description'=>array(
  590. 'RES' => Mage::helper('usa')->__('Residential'),
  591. 'COM' => Mage::helper('usa')->__('Commercial'),
  592. ),
  593. 'unit_of_measure'=>array(
  594. 'LBS' => Mage::helper('usa')->__('Pounds'),
  595. 'KGS' => Mage::helper('usa')->__('Kilograms'),
  596. ),
  597. 'containers_filter' => array(
  598. array(
  599. 'containers' => array('00'), // Customer Packaging
  600. 'filters' => array(
  601. 'within_us' => array(
  602. 'method' => array(
  603. '01', // Next Day Air
  604. '13', // Next Day Air Saver
  605. '12', // 3 Day Select
  606. '59', // 2nd Day Air AM
  607. '03', // Ground
  608. '14', // Next Day Air Early AM
  609. '02', // 2nd Day Air
  610. )
  611. ),
  612. 'from_us' => array(
  613. 'method' => array(
  614. '07', // Worldwide Express
  615. '54', // Worldwide Express Plus
  616. '08', // Worldwide Expedited
  617. '65', // Worldwide Saver
  618. '11', // Standard
  619. )
  620. )
  621. )
  622. ),
  623. array(
  624. // Small Express Box, Medium Express Box, Large Express Box, UPS Tube
  625. 'containers' => array('2a', '2b', '2c', '03'),
  626. 'filters' => array(
  627. 'within_us' => array(
  628. 'method' => array(
  629. '01', // Next Day Air
  630. '13', // Next Day Air Saver
  631. '14', // Next Day Air Early AM
  632. '02', // 2nd Day Air
  633. '59', // 2nd Day Air AM
  634. '13', // Next Day Air Saver
  635. )
  636. ),
  637. 'from_us' => array(
  638. 'method' => array(
  639. '07', // Worldwide Express
  640. '54', // Worldwide Express Plus
  641. '08', // Worldwide Expedited
  642. '65', // Worldwide Saver
  643. )
  644. )
  645. )
  646. ),
  647. array(
  648. 'containers' => array('24', '25'), // UPS Worldwide 25 kilo, UPS Worldwide 10 kilo
  649. 'filters' => array(
  650. 'within_us' => array(
  651. 'method' => array()
  652. ),
  653. 'from_us' => array(
  654. 'method' => array(
  655. '07', // Worldwide Express
  656. '54', // Worldwide Express Plus
  657. '65', // Worldwide Saver
  658. )
  659. )
  660. )
  661. ),
  662. array(
  663. 'containers' => array('01', '04'), // UPS Letter, UPS PAK
  664. 'filters' => array(
  665. 'within_us' => array(
  666. 'method' => array(
  667. '01', // Next Day Air
  668. '14', // Next Day Air Early AM
  669. '02', // 2nd Day Air
  670. '59', // 2nd Day Air AM
  671. '13', // Next Day Air Saver
  672. )
  673. ),
  674. 'from_us' => array(
  675. 'method' => array(
  676. '07', // Worldwide Express
  677. '54', // Worldwide Express Plus
  678. '65', // Worldwide Saver
  679. )
  680. )
  681. )
  682. ),
  683. array(
  684. 'containers' => array('04'), // UPS PAK
  685. 'filters' => array(
  686. 'within_us' => array(
  687. 'method' => array()
  688. ),
  689. 'from_us' => array(
  690. 'method' => array(
  691. '08', // Worldwide Expedited
  692. )
  693. )
  694. )
  695. ),
  696. )
  697. );
  698. if (!isset($codes[$type])) {
  699. return false;
  700. } elseif (''===$code) {
  701. return $codes[$type];
  702. }
  703. if (!isset($codes[$type][$code])) {
  704. return false;
  705. } else {
  706. return $codes[$type][$code];
  707. }
  708. }
  709. /**
  710. * Get xml rates
  711. *
  712. * @return Mage_Shipping_Model_Rate_Result
  713. */
  714. protected function _getXmlQuotes()
  715. {
  716. $url = $this->getConfigData('gateway_xml_url');
  717. $this->setXMLAccessRequest();
  718. $xmlRequest=$this->_xmlAccessRequest;
  719. $r = $this->_rawRequest;
  720. $params = array(
  721. 'accept_UPS_license_agreement' => 'yes',
  722. '10_action' => $r->getAction(),
  723. '13_product' => $r->getProduct(),
  724. '14_origCountry' => $r->getOrigCountry(),
  725. '15_origPostal' => $r->getOrigPostal(),
  726. 'origCity' => $r->getOrigCity(),
  727. 'origRegionCode' => $r->getOrigRegionCode(),
  728. '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ?
  729. substr($r->getDestPostal(), 0, 5) :
  730. $r->getDestPostal(),
  731. '22_destCountry' => $r->getDestCountry(),
  732. 'destRegionCode' => $r->getDestRegionCode(),
  733. '23_weight' => $r->getWeight(),
  734. '47_rate_chart' => $r->getPickup(),
  735. '48_container' => $r->getContainer(),
  736. '49_residential' => $r->getDestType(),
  737. );
  738. if ($params['10_action'] == '4') {
  739. $params['10_action'] = 'Shop';
  740. $serviceCode = null; // Service code is not relevant when we're asking ALL possible services' rates
  741. } else {
  742. $params['10_action'] = 'Rate';
  743. $serviceCode = $r->getProduct() ? $r->getProduct() : '';
  744. }
  745. $serviceDescription = $serviceCode ? $this->getShipmentByCode($serviceCode) : '';
  746. $xmlRequest .= <<< XMLRequest
  747. <?xml version="1.0"?>
  748. <RatingServiceSelectionRequest xml:lang="en-US">
  749. <Request>
  750. <TransactionReference>
  751. <CustomerContext>Rating and Service</CustomerContext>
  752. <XpciVersion>1.0</XpciVersion>
  753. </TransactionReference>
  754. <RequestAction>Rate</RequestAction>
  755. <RequestOption>{$params['10_action']}</RequestOption>
  756. </Request>
  757. <PickupType>
  758. <Code>{$params['47_rate_chart']['code']}</Code>
  759. <Description>{$params['47_rate_chart']['label']}</Description>
  760. </PickupType>
  761. <Shipment>
  762. XMLRequest;
  763. if ($serviceCode !== null) {
  764. $xmlRequest .= "<Service>" .
  765. "<Code>{$serviceCode}</Code>" .
  766. "<Description>{$serviceDescription}</Description>" .
  767. "</Service>";
  768. }
  769. $xmlRequest .= <<< XMLRequest
  770. <Shipper>
  771. XMLRequest;
  772. if ($this->getConfigFlag('negotiated_active') && ($shipper = $this->getConfigData('shipper_number')) ) {
  773. $xmlRequest .= "<ShipperNumber>{$shipper}</ShipperNumber>";
  774. }
  775. if ($r->getIsReturn()) {
  776. $shipperCity = '';
  777. $shipperPostalCode = $params['19_destPostal'];
  778. $shipperCountryCode = $params['22_destCountry'];
  779. $shipperStateProvince = $params['destRegionCode'];
  780. } else {
  781. $shipperCity = $params['origCity'];
  782. $shipperPostalCode = $params['15_origPostal'];
  783. $shipperCountryCode = $params['14_origCountry'];
  784. $shipperStateProvince = $params['origRegionCode'];
  785. }
  786. $xmlRequest .= <<< XMLRequest
  787. <Address>
  788. <City>{$shipperCity}</City>
  789. <PostalCode>{$shipperPostalCode}</PostalCode>
  790. <CountryCode>{$shipperCountryCode}</CountryCode>
  791. <StateProvinceCode>{$shipperStateProvince}</StateProvinceCode>
  792. </Address>
  793. </Shipper>
  794. <ShipTo>
  795. <Address>
  796. <PostalCode>{$params['19_destPostal']}</PostalCode>
  797. <CountryCode>{$params['22_destCountry']}</CountryCode>
  798. <ResidentialAddress>{$params['49_residential']}</ResidentialAddress>
  799. <StateProvinceCode>{$params['destRegionCode']}</StateProvinceCode>
  800. XMLRequest;
  801. $xmlRequest .= ($params['49_residential']==='01'
  802. ? "<ResidentialAddressIndicator>{$params['49_residential']}</ResidentialAddressIndicator>"
  803. : ''
  804. );
  805. $xmlRequest .= <<< XMLRequest
  806. </Address>
  807. </ShipTo>
  808. <ShipFrom>
  809. <Address>
  810. <PostalCode>{$params['15_origPostal']}</PostalCode>
  811. <CountryCode>{$params['14_origCountry']}</CountryCode>
  812. <StateProvinceCode>{$params['origRegionCode']}</StateProvinceCode>
  813. </Address>
  814. </ShipFrom>
  815. <Package>
  816. <PackagingType><Code>{$params['48_container']}</Code></PackagingType>
  817. <PackageWeight>
  818. <UnitOfMeasurement><Code>{$r->getUnitMeasure()}</Code></UnitOfMeasurement>
  819. <Weight>{$params['23_weight']}</Weight>
  820. </PackageWeight>
  821. </Package>
  822. XMLRequest;
  823. if ($this->getConfigFlag('negotiated_active')) {
  824. $xmlRequest .= "<RateInformation><NegotiatedRatesIndicator/></RateInformation>";
  825. }
  826. $xmlRequest .= <<< XMLRequest
  827. </Shipment>
  828. </RatingServiceSelectionRequest>
  829. XMLRequest;
  830. $xmlResponse = $this->_getCachedQuotes($xmlRequest);
  831. if ($xmlResponse === null) {
  832. $debugData = array('request' => $xmlRequest);
  833. try {
  834. $ch = curl_init();
  835. curl_setopt($ch, CURLOPT_URL, $url);
  836. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  837. curl_setopt($ch, CURLOPT_HEADER, 0);
  838. curl_setopt($ch, CURLOPT_POST, 1);
  839. curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
  840. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  841. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (boolean)$this->getConfigFlag('mode_xml'));
  842. $xmlResponse = curl_exec ($ch);
  843. $debugData['result'] = $xmlResponse;
  844. $this->_setCachedQuotes($xmlRequest, $xmlResponse);
  845. }
  846. catch (Exception $e) {
  847. $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
  848. $xmlResponse = '';
  849. }
  850. $this->_debug($debugData);
  851. }
  852. return $this->_parseXmlResponse($xmlResponse);
  853. }
  854. /**
  855. * Get base currency rate
  856. *
  857. * @param string $code
  858. * @return double
  859. */
  860. protected function _getBaseCurrencyRate($code)
  861. {
  862. if (!$this->_baseCurrencyRate) {
  863. $this->_baseCurrencyRate = Mage::getModel('directory/currency')
  864. ->load($code)
  865. ->getAnyRate($this->_request->getBaseCurrency()->getCode());
  866. }
  867. return $this->_baseCurrencyRate;
  868. }
  869. /**
  870. * Prepare shipping rate result based on response
  871. *
  872. * @param mixed $response
  873. * @return Mage_Shipping_Model_Rate_Result
  874. */
  875. protected function _parseXmlResponse($xmlResponse)
  876. {
  877. $costArr = array();
  878. $priceArr = array();
  879. if (strlen(trim($xmlResponse))>0) {
  880. $xml = new Varien_Simplexml_Config();
  881. $xml->loadString($xmlResponse);
  882. $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/ResponseStatusCode/text()");
  883. $success = (int)$arr[0];
  884. if ($success===1) {
  885. $arr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment");
  886. $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
  887. // Negotiated rates
  888. $negotiatedArr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment/NegotiatedRates");
  889. $negotiatedActive = $this->getConfigFlag('negotiated_active')
  890. && $this->getConfigData('shipper_number')
  891. && !empty($negotiatedArr);
  892. $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies();
  893. foreach ($arr as $shipElement){
  894. $code = (string)$shipElement->Service->Code;
  895. if (in_array($code, $allowedMethods)) {
  896. if ($negotiatedActive) {
  897. $cost = $shipElement->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue;
  898. } else {
  899. $cost = $shipElement->TotalCharges->MonetaryValue;
  900. }
  901. //convert price with Origin country currency code to base currency code
  902. $successConversion = true;
  903. $responseCurrencyCode = (string) $shipElement->TotalCharges->CurrencyCode;
  904. if ($responseCurrencyCode) {
  905. if (in_array($responseCurrencyCode, $allowedCurrencies)) {
  906. $cost = (float) $cost * $this->_getBaseCurrencyRate($responseCurrencyCode);
  907. } else {
  908. $errorTitle = Mage::helper('directory')->__('Can\'t convert rate from "%s-%s".', $responseCurrencyCode, $this->_request->getPackageCurrency()->getCode());
  909. $error = Mage::getModel('shipping/rate_result_error');
  910. $error->setCarrier('ups');
  911. $error->setCarrierTitle($this->getConfigData('title'));
  912. $error->setErrorMessage($errorTitle);
  913. $successConversion = false;
  914. }
  915. }
  916. if ($successConversion) {
  917. $costArr[$code] = $cost;
  918. $priceArr[$code] = $this->getMethodPrice(floatval($cost),$code);
  919. }
  920. }
  921. }
  922. } else {
  923. $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/Error/ErrorDescription/text()");
  924. $errorTitle = (string)$arr[0][0];
  925. $error = Mage::getModel('shipping/rate_result_error');
  926. $error->setCarrier('ups');
  927. $error->setCarrierTitle($this->getConfigData('title'));
  928. $error->setErrorMessage($this->getConfigData('specificerrmsg'));
  929. }
  930. }
  931. $result = Mage::getModel('shipping/rate_result');
  932. $defaults = $this->getDefaults();
  933. if (empty($priceArr)) {
  934. $error = Mage::getModel('shipping/rate_result_error');
  935. $error->setCarrier('ups');
  936. $error->setCarrierTitle($this->getConfigData('title'));
  937. if(!isset($errorTitle)){
  938. $errorTitle = Mage::helper('usa')->__('Cannot retrieve shipping rates');
  939. }
  940. $error->setErrorMessage($this->getConfigData('specificerrmsg'));
  941. $result->append($error);
  942. } else {
  943. foreach ($priceArr as $method=>$price) {
  944. $rate = Mage::getModel('shipping/rate_result_method');
  945. $rate->setCarrier('ups');
  946. $rate->setCarrierTitle($this->getConfigData('title'));
  947. $rate->setMethod($method);
  948. $method_arr = $this->getShipmentByCode($method);
  949. $rate->setMethodTitle($method_arr);
  950. $rate->setCost($costArr[$method]);
  951. $rate->setPrice($price);
  952. $result->append($rate);
  953. }
  954. }
  955. return $result;
  956. }
  957. /**
  958. * Get tracking
  959. *
  960. * @param mixed $trackings
  961. * @return mixed
  962. */
  963. public function getTracking($trackings)
  964. {
  965. $return = array();
  966. if (!is_array($trackings)) {
  967. $trackings = array($trackings);
  968. }
  969. if ($this->getConfigData('type')=='UPS') {
  970. $this->_getCgiTracking($trackings);
  971. } elseif ($this->getConfigData('type')=='UPS_XML'){
  972. $this->setXMLAccessRequest();
  973. $this->_getXmlTracking($trackings);
  974. }
  975. return $this->_result;
  976. }
  977. /**
  978. * Set xml access request
  979. *
  980. * @return null
  981. */
  982. protected function setXMLAccessRequest()
  983. {
  984. $userid = $this->getConfigData('username');
  985. $userid_pass = $this->getConfigData('password');
  986. $access_key = $this->getConfigData('access_license_number');
  987. $this->_xmlAccessRequest = <<<XMLAuth
  988. <?xml version="1.0"?>
  989. <AccessRequest xml:lang="en-US">
  990. <AccessLicenseNumber>$access_key</AccessLicenseNumber>
  991. <UserId>$userid</UserId>
  992. <Password>$userid_pass</Password>
  993. </AccessRequest>
  994. XMLAuth;
  995. }
  996. /**
  997. * Get cgi tracking
  998. *
  999. * @param mixed $trackings
  1000. * @return mixed
  1001. */
  1002. protected function _getCgiTracking($trackings)
  1003. {
  1004. //ups no longer support tracking for data streaming version
  1005. //so we can only reply the popup window to ups.
  1006. $result = Mage::getModel('shipping/tracking_result');
  1007. $defaults = $this->getDefaults();
  1008. foreach($trackings as $tracking){
  1009. $status = Mage::getModel('shipping/tracking_result_status');
  1010. $status->setCarrier('ups');
  1011. $status->setCarrierTitle($this->getConfigData('title'));
  1012. $status->setTracking($tracking);
  1013. $status->setPopup(1);
  1014. $status->setUrl("http://wwwapps.ups.com/WebTracking/processInputRequest?HTMLVersion=5.0&error_carried=true"
  1015. . "&tracknums_displayed=5&TypeOfInquiryNumber=T&loc=en_US&InquiryNumber1=$tracking"
  1016. . "&AgreeToTermsAndConditions=yes"
  1017. );
  1018. $result->append($status);
  1019. }
  1020. $this->_result = $result;
  1021. return $result;
  1022. }
  1023. /**
  1024. * Get xml tracking
  1025. *
  1026. * @param mixed $trackings
  1027. * @return mixed
  1028. */
  1029. protected function _getXmlTracking($trackings)
  1030. {
  1031. $url = $this->getConfigData('tracking_xml_url');
  1032. foreach($trackings as $tracking){
  1033. $xmlRequest=$this->_xmlAccessRequest;
  1034. /*
  1035. * RequestOption==>'activity' or '1' to request all activities
  1036. */
  1037. $xmlRequest .= <<<XMLAuth
  1038. <?xml version="1.0" ?>
  1039. <TrackRequest xml:lang="en-US">
  1040. <Request>
  1041. <RequestAction>Track</RequestAction>
  1042. <RequestOption>activity</RequestOption>
  1043. </Request>
  1044. <TrackingNumber>$tracking</TrackingNumber>
  1045. <IncludeFreight>01</IncludeFreight>
  1046. </TrackRequest>
  1047. XMLAuth;
  1048. $debugData = array('request' => $xmlRequest);
  1049. try {
  1050. $ch = curl_init();
  1051. curl_setopt($ch, CURLOPT_URL, $url);
  1052. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  1053. curl_setopt($ch, CURLOPT_HEADER, 0);
  1054. curl_setopt($ch, CURLOPT_POST, 1);
  1055. curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
  1056. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  1057. $xmlResponse = curl_exec ($ch);
  1058. $debugData['result'] = $xmlResponse;
  1059. curl_close ($ch);
  1060. }
  1061. catch (Exception $e) {
  1062. $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
  1063. $xmlResponse = '';
  1064. }
  1065. $this->_debug($debugData);
  1066. $this->_parseXmlTrackingResponse($tracking, $xmlResponse);
  1067. }
  1068. return $this->_result;
  1069. }
  1070. /**
  1071. * Parse xml tracking response
  1072. *
  1073. * @param string $trackingvalue
  1074. * @param string $response
  1075. * @return null
  1076. */
  1077. protected function _parseXmlTrackingResponse($trackingvalue, $xmlResponse)
  1078. {
  1079. $errorTitle = 'Unable to retrieve tracking';
  1080. $resultArr = array();
  1081. $packageProgress = array();
  1082. if ($xmlResponse) {
  1083. $xml = new Varien_Simplexml_Config();
  1084. $xml->loadString($xmlResponse);
  1085. $arr = $xml->getXpath("//TrackResponse/Response/ResponseStatusCode/text()");
  1086. $success = (int)$arr[0][0];
  1087. if($success===1){
  1088. $arr = $xml->getXpath("//TrackResponse/Shipment/Service/Description/text()");
  1089. $resultArr['service'] = (string)$arr[0];
  1090. $arr = $xml->getXpath("//TrackResponse/Shipment/PickupDate/text()");
  1091. $resultArr['shippeddate'] = (string)$arr[0];
  1092. $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/Weight/text()");
  1093. $weight = (string)$arr[0];
  1094. $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/UnitOfMeasurement/Code/text()");
  1095. $unit = (string)$arr[0];
  1096. $resultArr['weight'] = "{$weight} {$unit}";
  1097. $activityTags = $xml->getXpath("//TrackResponse/Shipment/Package/Activity");
  1098. if ($activityTags) {
  1099. $i=1;
  1100. foreach ($activityTags as $activityTag) {
  1101. $addArr=array();
  1102. if (isset($activityTag->ActivityLocation->Address->City)) {
  1103. $addArr[] = (string)$activityTag->ActivityLocation->Address->City;
  1104. }
  1105. if (isset($activityTag->ActivityLocation->Address->StateProvinceCode)) {
  1106. $addArr[] = (string)$activityTag->ActivityLocation->Address->StateProvinceCode;
  1107. }
  1108. if (isset($activityTag->ActivityLocation->Address->CountryCode)) {
  1109. $addArr[] = (string)$activityTag->ActivityLocation->Address->CountryCode;
  1110. }
  1111. $dateArr = array();
  1112. $date = (string)$activityTag->Date;//YYYYMMDD
  1113. $dateArr[] = substr($date,0,4);
  1114. $dateArr[] = substr($date,4,2);
  1115. $dateArr[] = substr($date,-2,2);
  1116. $timeArr = array();
  1117. $time = (string)$activityTag->Time;//HHMMSS
  1118. $timeArr[] = substr($time,0,2);
  1119. $timeArr[] = substr($time,2,2);
  1120. $timeArr[] = substr($time,-2,2);
  1121. if($i==1){
  1122. $resultArr['status'] = (string)$activityTag->Status->StatusType->Description;
  1123. $resultArr['deliverydate'] = implode('-',$dateArr);//YYYY-MM-DD
  1124. $resultArr['deliverytime'] = implode(':',$timeArr);//HH:MM:SS
  1125. $resultArr['deliverylocation'] = (string)$activityTag->ActivityLocation->Description;
  1126. $resultArr['signedby'] = (string)$activityTag->ActivityLocation->SignedForByName;
  1127. if ($addArr) {
  1128. $resultArr['deliveryto']=implode(', ',$addArr);
  1129. }
  1130. }else{
  1131. $tempArr=array();
  1132. $tempArr['activity'] = (string)$activityTag->Status->StatusType->Description;
  1133. $tempArr['deliverydate'] = implode('-',$dateArr);//YYYY-MM-DD
  1134. $tempArr['deliverytime'] = implode(':',$timeArr);//HH:MM:SS
  1135. if ($addArr) {
  1136. $tempArr['deliverylocation']=implode(', ',$addArr);
  1137. }
  1138. $packageProgress[] = $tempArr;
  1139. }
  1140. $i++;
  1141. }
  1142. $resultArr['progressdetail'] = $packageProgress;
  1143. }
  1144. } else {
  1145. $arr = $xml->getXpath("//TrackResponse/Response/Error/ErrorDescription/text()");
  1146. $errorTitle = (string)$arr[0][0];
  1147. }
  1148. }
  1149. if (!$this->_result) {
  1150. $this->_result = Mage::getModel('shipping/tracking_result');
  1151. }
  1152. $defaults = $this->getDefaults();
  1153. if ($resultArr) {
  1154. $tracking = Mage::getModel('…

Large files files are truncated, but you can click here to view the full file