1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: 29: 30: 31: 32: 33: 34:
35: class Mage_Usa_Model_Shipping_Carrier_Ups
36: extends Mage_Usa_Model_Shipping_Carrier_Abstract
37: implements Mage_Shipping_Model_Carrier_Interface
38: {
39:
40: 41: 42: 43: 44:
45: const CODE = 'ups';
46:
47: 48: 49: 50: 51:
52: const DELIVERY_CONFIRMATION_SHIPMENT = 1;
53: const DELIVERY_CONFIRMATION_PACKAGE = 2;
54:
55: 56: 57: 58: 59:
60: protected $_code = self::CODE;
61:
62: 63: 64: 65: 66:
67: protected $_request = null;
68:
69: 70: 71: 72: 73:
74: protected $_rawRequest = null;
75:
76: 77: 78: 79: 80:
81: protected $_result = null;
82:
83: 84: 85: 86: 87:
88: protected $_baseCurrencyRate;
89:
90: 91: 92: 93: 94:
95: protected $_xmlAccessRequest = null;
96:
97: 98: 99: 100: 101:
102: protected $_defaultCgiGatewayUrl = 'http://www.ups.com:80/using/services/rave/qcostcgi.cgi';
103:
104: 105: 106: 107: 108:
109: protected $_defaultUrls = array(
110: 'ShipConfirm' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
111: 'ShipAccept' => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',
112: );
113:
114: 115: 116: 117: 118:
119: protected $_customizableContainerTypes = array('CP', 'CSP');
120:
121: 122: 123: 124: 125: 126:
127:
128: public function collectRates(Mage_Shipping_Model_Rate_Request $request)
129: {
130: if (!$this->getConfigFlag($this->_activeFlag)) {
131: return false;
132: }
133:
134: $this->setRequest($request);
135:
136: $this->_result = $this->_getQuotes();
137: $this->_updateFreeMethodQuote($request);
138:
139: return $this->getResult();
140: }
141:
142: 143: 144: 145: 146: 147:
148: public function setRequest(Mage_Shipping_Model_Rate_Request $request)
149: {
150: $this->_request = $request;
151:
152: $r = new Varien_Object();
153:
154: if ($request->getLimitMethod()) {
155: $r->setAction($this->getCode('action', 'single'));
156: $r->setProduct($request->getLimitMethod());
157: } else {
158: $r->setAction($this->getCode('action', 'all'));
159: $r->setProduct('GND'.$this->getConfigData('dest_type'));
160: }
161:
162: if ($request->getUpsPickup()) {
163: $pickup = $request->getUpsPickup();
164: } else {
165: $pickup = $this->getConfigData('pickup');
166: }
167: $r->setPickup($this->getCode('pickup', $pickup));
168:
169: if ($request->getUpsContainer()) {
170: $container = $request->getUpsContainer();
171: } else {
172: $container = $this->getConfigData('container');
173: }
174: $r->setContainer($this->getCode('container', $container));
175:
176: if ($request->getUpsDestType()) {
177: $destType = $request->getUpsDestType();
178: } else {
179: $destType = $this->getConfigData('dest_type');
180: }
181: $r->setDestType($this->getCode('dest_type', $destType));
182:
183: if ($request->getOrigCountry()) {
184: $origCountry = $request->getOrigCountry();
185: } else {
186: $origCountry = Mage::getStoreConfig(
187: Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID,
188: $request->getStoreId()
189: );
190: }
191:
192: $r->setOrigCountry(Mage::getModel('directory/country')->load($origCountry)->getIso2Code());
193:
194: if ($request->getOrigRegionCode()) {
195: $origRegionCode = $request->getOrigRegionCode();
196: } else {
197: $origRegionCode = Mage::getStoreConfig(
198: Mage_Shipping_Model_Shipping::XML_PATH_STORE_REGION_ID,
199: $request->getStoreId()
200: );
201: }
202: if (is_numeric($origRegionCode)) {
203: $origRegionCode = Mage::getModel('directory/region')->load($origRegionCode)->getCode();
204: }
205: $r->setOrigRegionCode($origRegionCode);
206:
207: if ($request->getOrigPostcode()) {
208: $r->setOrigPostal($request->getOrigPostcode());
209: } else {
210: $r->setOrigPostal(Mage::getStoreConfig(
211: Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP,
212: $request->getStoreId()
213: ));
214: }
215:
216: if ($request->getOrigCity()) {
217: $r->setOrigCity($request->getOrigCity());
218: } else {
219: $r->setOrigCity(Mage::getStoreConfig(
220: Mage_Shipping_Model_Shipping::XML_PATH_STORE_CITY,
221: $request->getStoreId()
222: ));
223: }
224:
225:
226: if ($request->getDestCountryId()) {
227: $destCountry = $request->getDestCountryId();
228: } else {
229: $destCountry = self::USA_COUNTRY_ID;
230: }
231:
232:
233: if ($destCountry == self::USA_COUNTRY_ID
234: && ($request->getDestPostcode()=='00912' || $request->getDestRegionCode()==self::PUERTORICO_COUNTRY_ID)
235: ) {
236: $destCountry = self::PUERTORICO_COUNTRY_ID;
237: }
238:
239:
240: if ($destCountry == self::USA_COUNTRY_ID && $request->getDestRegionCode() == self::GUAM_REGION_CODE) {
241: $destCountry = self::GUAM_COUNTRY_ID;
242: }
243:
244: $r->setDestCountry(Mage::getModel('directory/country')->load($destCountry)->getIso2Code());
245:
246: $r->setDestRegionCode($request->getDestRegionCode());
247:
248: if ($request->getDestPostcode()) {
249: $r->setDestPostal($request->getDestPostcode());
250: } else {
251:
252: }
253:
254: $weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
255:
256: $weight = $this->_getCorrectWeight($weight);
257:
258: $r->setWeight($weight);
259: if ($request->getFreeMethodWeight()!=$request->getPackageWeight()) {
260: $r->setFreeMethodWeight($request->getFreeMethodWeight());
261: }
262:
263: $r->setValue($request->getPackageValue());
264: $r->setValueWithDiscount($request->getPackageValueWithDiscount());
265:
266: if ($request->getUpsUnitMeasure()) {
267: $unit = $request->getUpsUnitMeasure();
268: } else {
269: $unit = $this->getConfigData('unit_of_measure');
270: }
271: $r->setUnitMeasure($unit);
272:
273: $r->setIsReturn($request->getIsReturn());
274:
275: $r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
276:
277: $this->_rawRequest = $r;
278:
279: return $this;
280: }
281:
282: 283: 284: 285: 286: 287: 288: 289: 290: 291:
292: protected function _getCorrectWeight($weight)
293: {
294: $minWeight = $this->getConfigData('min_package_weight');
295:
296: if($weight < $minWeight){
297: $weight = $minWeight;
298: }
299:
300:
301: $weight = ceil($weight*10) / 10;
302:
303: return $weight;
304: }
305:
306: 307: 308: 309: 310:
311: public function getResult()
312: {
313: return $this->_result;
314: }
315:
316: 317: 318: 319: 320:
321: protected function _getQuotes()
322: {
323: switch ($this->getConfigData('type')) {
324: case 'UPS':
325: return $this->_getCgiQuotes();
326:
327: case 'UPS_XML':
328: return $this->_getXmlQuotes();
329: }
330: return null;
331: }
332:
333: 334: 335: 336: 337: 338:
339: protected function _setFreeMethodRequest($freeMethod)
340: {
341: $r = $this->_rawRequest;
342:
343: $weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight());
344: $weight = $this->_getCorrectWeight($weight);
345: $r->setWeight($weight);
346: $r->setAction($this->getCode('action', 'single'));
347: $r->setProduct($freeMethod);
348: }
349:
350: 351: 352: 353: 354:
355: protected function _getCgiQuotes()
356: {
357: $r = $this->_rawRequest;
358:
359: $params = array(
360: 'accept_UPS_license_agreement' => 'yes',
361: '10_action' => $r->getAction(),
362: '13_product' => $r->getProduct(),
363: '14_origCountry' => $r->getOrigCountry(),
364: '15_origPostal' => $r->getOrigPostal(),
365: 'origCity' => $r->getOrigCity(),
366: '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ?
367: substr($r->getDestPostal(), 0, 5) :
368: $r->getDestPostal(),
369: '22_destCountry' => $r->getDestCountry(),
370: '23_weight' => $r->getWeight(),
371: '47_rate_chart' => $r->getPickup(),
372: '48_container' => $r->getContainer(),
373: '49_residential' => $r->getDestType(),
374: 'weight_std' => strtolower($r->getUnitMeasure()),
375: );
376: $params['47_rate_chart'] = $params['47_rate_chart']['label'];
377:
378: $responseBody = $this->_getCachedQuotes($params);
379: if ($responseBody === null) {
380: $debugData = array('request' => $params);
381: try {
382: $url = $this->getConfigData('gateway_url');
383: if (!$url) {
384: $url = $this->_defaultCgiGatewayUrl;
385: }
386: $client = new Zend_Http_Client();
387: $client->setUri($url);
388: $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
389: $client->setParameterGet($params);
390: $response = $client->request();
391: $responseBody = $response->getBody();
392:
393: $debugData['result'] = $responseBody;
394: $this->_setCachedQuotes($params, $responseBody);
395: }
396: catch (Exception $e) {
397: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
398: $responseBody = '';
399: }
400: $this->_debug($debugData);
401: }
402:
403: return $this->_parseCgiResponse($responseBody);
404: }
405:
406: 407: 408: 409: 410: 411: 412:
413: public function getShipmentByCode($code, $origin = null){
414: if($origin===null){
415: $origin = $this->getConfigData('origin_shipment');
416: }
417: $arr = $this->getCode('originShipment',$origin);
418: if(isset($arr[$code]))
419: return $arr[$code];
420: else
421: return false;
422: }
423:
424:
425: 426: 427: 428: 429: 430:
431: protected function _parseCgiResponse($response)
432: {
433: $costArr = array();
434: $priceArr = array();
435: $errorTitle = Mage::helper('usa')->__('Unknown error');
436: if (strlen(trim($response))>0) {
437: $rRows = explode("\n", $response);
438: $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
439: foreach ($rRows as $rRow) {
440: $r = explode('%', $rRow);
441: switch (substr($r[0],-1)) {
442: case 3: case 4:
443: if (in_array($r[1], $allowedMethods)) {
444: $responsePrice = Mage::app()->getLocale()->getNumber($r[8]);
445: $costArr[$r[1]] = $responsePrice;
446: $priceArr[$r[1]] = $this->getMethodPrice($responsePrice, $r[1]);
447: }
448: break;
449: case 5:
450: $errorTitle = $r[1];
451: break;
452: case 6:
453: if (in_array($r[3], $allowedMethods)) {
454: $responsePrice = Mage::app()->getLocale()->getNumber($r[10]);
455: $costArr[$r[3]] = $responsePrice;
456: $priceArr[$r[3]] = $this->getMethodPrice($responsePrice, $r[3]);
457: }
458: break;
459: }
460: }
461: asort($priceArr);
462: }
463:
464: $result = Mage::getModel('shipping/rate_result');
465: $defaults = $this->getDefaults();
466: if (empty($priceArr)) {
467: $error = Mage::getModel('shipping/rate_result_error');
468: $error->setCarrier('ups');
469: $error->setCarrierTitle($this->getConfigData('title'));
470: $error->setErrorMessage($this->getConfigData('specificerrmsg'));
471: $result->append($error);
472: } else {
473: foreach ($priceArr as $method=>$price) {
474: $rate = Mage::getModel('shipping/rate_result_method');
475: $rate->setCarrier('ups');
476: $rate->setCarrierTitle($this->getConfigData('title'));
477: $rate->setMethod($method);
478: $method_arr = $this->getCode('method', $method);
479: $rate->setMethodTitle(Mage::helper('usa')->__($method_arr));
480: $rate->setCost($costArr[$method]);
481: $rate->setPrice($price);
482: $result->append($rate);
483: }
484: }
485:
486: return $result;
487: }
488:
489: 490: 491: 492: 493: 494: 495:
496: public function getCode($type, $code='')
497: {
498: $codes = array(
499: 'action'=>array(
500: 'single'=>'3',
501: 'all'=>'4',
502: ),
503:
504: 'originShipment'=>array(
505:
506: 'United States Domestic Shipments' => array(
507: '01' => Mage::helper('usa')->__('UPS Next Day Air'),
508: '02' => Mage::helper('usa')->__('UPS Second Day Air'),
509: '03' => Mage::helper('usa')->__('UPS Ground'),
510: '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
511: '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
512: '11' => Mage::helper('usa')->__('UPS Standard'),
513: '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
514: '13' => Mage::helper('usa')->__('UPS Next Day Air Saver'),
515: '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
516: '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
517: '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'),
518: '65' => Mage::helper('usa')->__('UPS Saver'),
519: ),
520:
521: 'Shipments Originating in United States' => array(
522: '01' => Mage::helper('usa')->__('UPS Next Day Air'),
523: '02' => Mage::helper('usa')->__('UPS Second Day Air'),
524: '03' => Mage::helper('usa')->__('UPS Ground'),
525: '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
526: '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
527: '11' => Mage::helper('usa')->__('UPS Standard'),
528: '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
529: '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
530: '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
531: '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'),
532: '65' => Mage::helper('usa')->__('UPS Worldwide Saver'),
533: ),
534:
535: 'Shipments Originating in Canada' => array(
536: '01' => Mage::helper('usa')->__('UPS Express'),
537: '02' => Mage::helper('usa')->__('UPS Expedited'),
538: '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
539: '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
540: '11' => Mage::helper('usa')->__('UPS Standard'),
541: '12' => Mage::helper('usa')->__('UPS Three-Day Select'),
542: '14' => Mage::helper('usa')->__('UPS Express Early A.M.'),
543: '65' => Mage::helper('usa')->__('UPS Saver'),
544: ),
545:
546: 'Shipments Originating in the European Union' => array(
547: '07' => Mage::helper('usa')->__('UPS Express'),
548: '08' => Mage::helper('usa')->__('UPS Expedited'),
549: '11' => Mage::helper('usa')->__('UPS Standard'),
550: '54' => Mage::helper('usa')->__('UPS Worldwide Express PlusSM'),
551: '65' => Mage::helper('usa')->__('UPS Saver'),
552: ),
553:
554: 'Polish Domestic Shipments' => array(
555: '07' => Mage::helper('usa')->__('UPS Express'),
556: '08' => Mage::helper('usa')->__('UPS Expedited'),
557: '11' => Mage::helper('usa')->__('UPS Standard'),
558: '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
559: '65' => Mage::helper('usa')->__('UPS Saver'),
560: '82' => Mage::helper('usa')->__('UPS Today Standard'),
561: '83' => Mage::helper('usa')->__('UPS Today Dedicated Courrier'),
562: '84' => Mage::helper('usa')->__('UPS Today Intercity'),
563: '85' => Mage::helper('usa')->__('UPS Today Express'),
564: '86' => Mage::helper('usa')->__('UPS Today Express Saver'),
565: ),
566:
567: 'Puerto Rico Origin' => array(
568: '01' => Mage::helper('usa')->__('UPS Next Day Air'),
569: '02' => Mage::helper('usa')->__('UPS Second Day Air'),
570: '03' => Mage::helper('usa')->__('UPS Ground'),
571: '07' => Mage::helper('usa')->__('UPS Worldwide Express'),
572: '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
573: '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'),
574: '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
575: '65' => Mage::helper('usa')->__('UPS Saver'),
576: ),
577:
578: 'Shipments Originating in Mexico' => array(
579: '07' => Mage::helper('usa')->__('UPS Express'),
580: '08' => Mage::helper('usa')->__('UPS Expedited'),
581: '54' => Mage::helper('usa')->__('UPS Express Plus'),
582: '65' => Mage::helper('usa')->__('UPS Saver'),
583: ),
584:
585: 'Shipments Originating in Other Countries' => array(
586: '07' => Mage::helper('usa')->__('UPS Express'),
587: '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'),
588: '11' => Mage::helper('usa')->__('UPS Standard'),
589: '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'),
590: '65' => Mage::helper('usa')->__('UPS Saver')
591: )
592: ),
593:
594: 'method'=>array(
595: '1DM' => Mage::helper('usa')->__('Next Day Air Early AM'),
596: '1DML' => Mage::helper('usa')->__('Next Day Air Early AM Letter'),
597: '1DA' => Mage::helper('usa')->__('Next Day Air'),
598: '1DAL' => Mage::helper('usa')->__('Next Day Air Letter'),
599: '1DAPI' => Mage::helper('usa')->__('Next Day Air Intra (Puerto Rico)'),
600: '1DP' => Mage::helper('usa')->__('Next Day Air Saver'),
601: '1DPL' => Mage::helper('usa')->__('Next Day Air Saver Letter'),
602: '2DM' => Mage::helper('usa')->__('2nd Day Air AM'),
603: '2DML' => Mage::helper('usa')->__('2nd Day Air AM Letter'),
604: '2DA' => Mage::helper('usa')->__('2nd Day Air'),
605: '2DAL' => Mage::helper('usa')->__('2nd Day Air Letter'),
606: '3DS' => Mage::helper('usa')->__('3 Day Select'),
607: 'GND' => Mage::helper('usa')->__('Ground'),
608: 'GNDCOM' => Mage::helper('usa')->__('Ground Commercial'),
609: 'GNDRES' => Mage::helper('usa')->__('Ground Residential'),
610: 'STD' => Mage::helper('usa')->__('Canada Standard'),
611: 'XPR' => Mage::helper('usa')->__('Worldwide Express'),
612: 'WXS' => Mage::helper('usa')->__('Worldwide Express Saver'),
613: 'XPRL' => Mage::helper('usa')->__('Worldwide Express Letter'),
614: 'XDM' => Mage::helper('usa')->__('Worldwide Express Plus'),
615: 'XDML' => Mage::helper('usa')->__('Worldwide Express Plus Letter'),
616: 'XPD' => Mage::helper('usa')->__('Worldwide Expedited'),
617: ),
618:
619: 'pickup'=>array(
620: 'RDP' => array("label"=>'Regular Daily Pickup',"code"=>"01"),
621: 'OCA' => array("label"=>'On Call Air',"code"=>"07"),
622: 'OTP' => array("label"=>'One Time Pickup',"code"=>"06"),
623: 'LC' => array("label"=>'Letter Center',"code"=>"19"),
624: 'CC' => array("label"=>'Customer Counter',"code"=>"03"),
625: ),
626:
627: 'container'=>array(
628: 'CP' => '00',
629: 'ULE' => '01',
630: 'CSP' => '02',
631: 'UT' => '03',
632: 'PAK' => '04',
633: 'UEB' => '21',
634: 'UW25' => '24',
635: 'UW10' => '25',
636: 'PLT' => '30',
637: 'SEB' => '2a',
638: 'MEB' => '2b',
639: 'LEB' => '2c',
640: ),
641:
642: 'container_description'=>array(
643: 'CP' => Mage::helper('usa')->__('Customer Packaging'),
644: 'ULE' => Mage::helper('usa')->__('UPS Letter Envelope'),
645: 'CSP' => Mage::helper('usa')->__('Customer Supplied Package'),
646: 'UT' => Mage::helper('usa')->__('UPS Tube'),
647: 'PAK' => Mage::helper('usa')->__('PAK'),
648: 'UEB' => Mage::helper('usa')->__('UPS Express Box'),
649: 'UW25' => Mage::helper('usa')->__('UPS Worldwide 25 kilo'),
650: 'UW10' => Mage::helper('usa')->__('UPS Worldwide 10 kilo'),
651: 'PLT' => Mage::helper('usa')->__('Pallet'),
652: 'SEB' => Mage::helper('usa')->__('Small Express Box'),
653: 'MEB' => Mage::helper('usa')->__('Medium Express Box'),
654: 'LEB' => Mage::helper('usa')->__('Large Express Box'),
655: ),
656:
657: 'dest_type'=>array(
658: 'RES' => '01',
659: 'COM' => '02',
660: ),
661:
662: 'dest_type_description'=>array(
663: 'RES' => Mage::helper('usa')->__('Residential'),
664: 'COM' => Mage::helper('usa')->__('Commercial'),
665: ),
666:
667: 'unit_of_measure'=>array(
668: 'LBS' => Mage::helper('usa')->__('Pounds'),
669: 'KGS' => Mage::helper('usa')->__('Kilograms'),
670: ),
671: 'containers_filter' => array(
672: array(
673: 'containers' => array('00'),
674: 'filters' => array(
675: 'within_us' => array(
676: 'method' => array(
677: '01',
678: '13',
679: '12',
680: '59',
681: '03',
682: '14',
683: '02',
684: )
685: ),
686: 'from_us' => array(
687: 'method' => array(
688: '07',
689: '54',
690: '08',
691: '65',
692: '11',
693: )
694: )
695: )
696: ),
697: array(
698:
699: 'containers' => array('2a', '2b', '2c', '03'),
700: 'filters' => array(
701: 'within_us' => array(
702: 'method' => array(
703: '01',
704: '13',
705: '14',
706: '02',
707: '59',
708: '13',
709: )
710: ),
711: 'from_us' => array(
712: 'method' => array(
713: '07',
714: '54',
715: '08',
716: '65',
717: )
718: )
719: )
720: ),
721: array(
722: 'containers' => array('24', '25'),
723: 'filters' => array(
724: 'within_us' => array(
725: 'method' => array()
726: ),
727: 'from_us' => array(
728: 'method' => array(
729: '07',
730: '54',
731: '65',
732: )
733: )
734: )
735: ),
736: array(
737: 'containers' => array('01', '04'),
738: 'filters' => array(
739: 'within_us' => array(
740: 'method' => array(
741: '01',
742: '14',
743: '02',
744: '59',
745: '13',
746: )
747: ),
748: 'from_us' => array(
749: 'method' => array(
750: '07',
751: '54',
752: '65',
753: )
754: )
755: )
756: ),
757: array(
758: 'containers' => array('04'),
759: 'filters' => array(
760: 'within_us' => array(
761: 'method' => array()
762: ),
763: 'from_us' => array(
764: 'method' => array(
765: '08',
766: )
767: )
768: )
769: ),
770: )
771: );
772:
773: if (!isset($codes[$type])) {
774: return false;
775: } elseif (''===$code) {
776: return $codes[$type];
777: }
778:
779: if (!isset($codes[$type][$code])) {
780: return false;
781: } else {
782: return $codes[$type][$code];
783: }
784: }
785:
786: 787: 788: 789: 790:
791: protected function _getXmlQuotes()
792: {
793: $url = $this->getConfigData('gateway_xml_url');
794:
795: $this->setXMLAccessRequest();
796: $xmlRequest=$this->_xmlAccessRequest;
797:
798: $r = $this->_rawRequest;
799: $params = array(
800: 'accept_UPS_license_agreement' => 'yes',
801: '10_action' => $r->getAction(),
802: '13_product' => $r->getProduct(),
803: '14_origCountry' => $r->getOrigCountry(),
804: '15_origPostal' => $r->getOrigPostal(),
805: 'origCity' => $r->getOrigCity(),
806: 'origRegionCode' => $r->getOrigRegionCode(),
807: '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ?
808: substr($r->getDestPostal(), 0, 5) :
809: $r->getDestPostal(),
810: '22_destCountry' => $r->getDestCountry(),
811: 'destRegionCode' => $r->getDestRegionCode(),
812: '23_weight' => $r->getWeight(),
813: '47_rate_chart' => $r->getPickup(),
814: '48_container' => $r->getContainer(),
815: '49_residential' => $r->getDestType(),
816: );
817:
818: if ($params['10_action'] == '4') {
819: $params['10_action'] = 'Shop';
820: $serviceCode = null;
821: } else {
822: $params['10_action'] = 'Rate';
823: $serviceCode = $r->getProduct() ? $r->getProduct() : '';
824: }
825: $serviceDescription = $serviceCode ? $this->getShipmentByCode($serviceCode) : '';
826:
827: $xmlRequest .= <<< XMLRequest
828: <?xml version="1.0"?>
829: <RatingServiceSelectionRequest xml:lang="en-US">
830: <Request>
831: <TransactionReference>
832: <CustomerContext>Rating and Service</CustomerContext>
833: <XpciVersion>1.0</XpciVersion>
834: </TransactionReference>
835: <RequestAction>Rate</RequestAction>
836: <RequestOption>{$params['10_action']}</RequestOption>
837: </Request>
838: <PickupType>
839: <Code>{$params['47_rate_chart']['code']}</Code>
840: <Description>{$params['47_rate_chart']['label']}</Description>
841: </PickupType>
842:
843: <Shipment>
844: XMLRequest;
845:
846: if ($serviceCode !== null) {
847: $xmlRequest .= "<Service>" .
848: "<Code>{$serviceCode}</Code>" .
849: "<Description>{$serviceDescription}</Description>" .
850: "</Service>";
851: }
852:
853: $xmlRequest .= <<< XMLRequest
854: <Shipper>
855: XMLRequest;
856:
857: if ($this->getConfigFlag('negotiated_active') && ($shipper = $this->getConfigData('shipper_number')) ) {
858: $xmlRequest .= "<ShipperNumber>{$shipper}</ShipperNumber>";
859: }
860:
861: if ($r->getIsReturn()) {
862: $shipperCity = '';
863: $shipperPostalCode = $params['19_destPostal'];
864: $shipperCountryCode = $params['22_destCountry'];
865: $shipperStateProvince = $params['destRegionCode'];
866: } else {
867: $shipperCity = $params['origCity'];
868: $shipperPostalCode = $params['15_origPostal'];
869: $shipperCountryCode = $params['14_origCountry'];
870: $shipperStateProvince = $params['origRegionCode'];
871: }
872:
873: $xmlRequest .= <<< XMLRequest
874: <Address>
875: <City>{$shipperCity}</City>
876: <PostalCode>{$shipperPostalCode}</PostalCode>
877: <CountryCode>{$shipperCountryCode}</CountryCode>
878: <StateProvinceCode>{$shipperStateProvince}</StateProvinceCode>
879: </Address>
880: </Shipper>
881: <ShipTo>
882: <Address>
883: <PostalCode>{$params['19_destPostal']}</PostalCode>
884: <CountryCode>{$params['22_destCountry']}</CountryCode>
885: <ResidentialAddress>{$params['49_residential']}</ResidentialAddress>
886: <StateProvinceCode>{$params['destRegionCode']}</StateProvinceCode>
887: XMLRequest;
888:
889: $xmlRequest .= ($params['49_residential']==='01'
890: ? "<ResidentialAddressIndicator>{$params['49_residential']}</ResidentialAddressIndicator>"
891: : ''
892: );
893:
894: $xmlRequest .= <<< XMLRequest
895: </Address>
896: </ShipTo>
897:
898:
899: <ShipFrom>
900: <Address>
901: <PostalCode>{$params['15_origPostal']}</PostalCode>
902: <CountryCode>{$params['14_origCountry']}</CountryCode>
903: <StateProvinceCode>{$params['origRegionCode']}</StateProvinceCode>
904: </Address>
905: </ShipFrom>
906:
907: <Package>
908: <PackagingType><Code>{$params['48_container']}</Code></PackagingType>
909: <PackageWeight>
910: <UnitOfMeasurement><Code>{$r->getUnitMeasure()}</Code></UnitOfMeasurement>
911: <Weight>{$params['23_weight']}</Weight>
912: </PackageWeight>
913: </Package>
914: XMLRequest;
915: if ($this->getConfigFlag('negotiated_active')) {
916: $xmlRequest .= "<RateInformation><NegotiatedRatesIndicator/></RateInformation>";
917: }
918:
919: $xmlRequest .= <<< XMLRequest
920: </Shipment>
921: </RatingServiceSelectionRequest>
922: XMLRequest;
923:
924: $xmlResponse = $this->_getCachedQuotes($xmlRequest);
925: if ($xmlResponse === null) {
926: $debugData = array('request' => $xmlRequest);
927: try {
928: $ch = curl_init();
929: curl_setopt($ch, CURLOPT_URL, $url);
930: curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
931: curl_setopt($ch, CURLOPT_HEADER, 0);
932: curl_setopt($ch, CURLOPT_POST, 1);
933: curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
934: curl_setopt($ch, CURLOPT_TIMEOUT, 30);
935: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (boolean)$this->getConfigFlag('mode_xml'));
936: $xmlResponse = curl_exec ($ch);
937:
938: $debugData['result'] = $xmlResponse;
939: $this->_setCachedQuotes($xmlRequest, $xmlResponse);
940: }
941: catch (Exception $e) {
942: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
943: $xmlResponse = '';
944: }
945: $this->_debug($debugData);
946: }
947:
948: return $this->_parseXmlResponse($xmlResponse);
949: }
950:
951: 952: 953: 954: 955: 956:
957: protected function _getBaseCurrencyRate($code)
958: {
959: if (!$this->_baseCurrencyRate) {
960: $this->_baseCurrencyRate = Mage::getModel('directory/currency')
961: ->load($code)
962: ->getAnyRate($this->_request->getBaseCurrency()->getCode());
963: }
964:
965: return $this->_baseCurrencyRate;
966: }
967:
968: 969: 970: 971: 972: 973:
974: protected function _parseXmlResponse($xmlResponse)
975: {
976: $costArr = array();
977: $priceArr = array();
978: if (strlen(trim($xmlResponse))>0) {
979: $xml = new Varien_Simplexml_Config();
980: $xml->loadString($xmlResponse);
981: $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/ResponseStatusCode/text()");
982: $success = (int)$arr[0];
983: if ($success===1) {
984: $arr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment");
985: $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
986:
987:
988: $negotiatedArr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment/NegotiatedRates");
989: $negotiatedActive = $this->getConfigFlag('negotiated_active')
990: && $this->getConfigData('shipper_number')
991: && !empty($negotiatedArr);
992:
993: $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies();
994:
995: foreach ($arr as $shipElement){
996: $code = (string)$shipElement->Service->Code;
997: if (in_array($code, $allowedMethods)) {
998:
999: if ($negotiatedActive) {
1000: $cost = $shipElement->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue;
1001: } else {
1002: $cost = $shipElement->TotalCharges->MonetaryValue;
1003: }
1004:
1005:
1006: $successConversion = true;
1007: $responseCurrencyCode = (string) $shipElement->TotalCharges->CurrencyCode;
1008: if ($responseCurrencyCode) {
1009: if (in_array($responseCurrencyCode, $allowedCurrencies)) {
1010: $cost = (float) $cost * $this->_getBaseCurrencyRate($responseCurrencyCode);
1011: } else {
1012: $errorTitle = Mage::helper('directory')->__('Can\'t convert rate from "%s-%s".', $responseCurrencyCode, $this->_request->getPackageCurrency()->getCode());
1013: $error = Mage::getModel('shipping/rate_result_error');
1014: $error->setCarrier('ups');
1015: $error->setCarrierTitle($this->getConfigData('title'));
1016: $error->setErrorMessage($errorTitle);
1017: $successConversion = false;
1018: }
1019: }
1020:
1021: if ($successConversion) {
1022: $costArr[$code] = $cost;
1023: $priceArr[$code] = $this->getMethodPrice(floatval($cost),$code);
1024: }
1025: }
1026: }
1027: } else {
1028: $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/Error/ErrorDescription/text()");
1029: $errorTitle = (string)$arr[0][0];
1030: $error = Mage::getModel('shipping/rate_result_error');
1031: $error->setCarrier('ups');
1032: $error->setCarrierTitle($this->getConfigData('title'));
1033: $error->setErrorMessage($this->getConfigData('specificerrmsg'));
1034: }
1035: }
1036:
1037: $result = Mage::getModel('shipping/rate_result');
1038: $defaults = $this->getDefaults();
1039: if (empty($priceArr)) {
1040: $error = Mage::getModel('shipping/rate_result_error');
1041: $error->setCarrier('ups');
1042: $error->setCarrierTitle($this->getConfigData('title'));
1043: if(!isset($errorTitle)){
1044: $errorTitle = Mage::helper('usa')->__('Cannot retrieve shipping rates');
1045: }
1046: $error->setErrorMessage($this->getConfigData('specificerrmsg'));
1047: $result->append($error);
1048: } else {
1049: foreach ($priceArr as $method=>$price) {
1050: $rate = Mage::getModel('shipping/rate_result_method');
1051: $rate->setCarrier('ups');
1052: $rate->setCarrierTitle($this->getConfigData('title'));
1053: $rate->setMethod($method);
1054: $method_arr = $this->getShipmentByCode($method);
1055: $rate->setMethodTitle($method_arr);
1056: $rate->setCost($costArr[$method]);
1057: $rate->setPrice($price);
1058: $result->append($rate);
1059: }
1060: }
1061: return $result;
1062: }
1063:
1064: 1065: 1066: 1067: 1068: 1069:
1070: public function getTracking($trackings)
1071: {
1072: $return = array();
1073:
1074: if (!is_array($trackings)) {
1075: $trackings = array($trackings);
1076: }
1077:
1078: if ($this->getConfigData('type')=='UPS') {
1079: $this->_getCgiTracking($trackings);
1080: } elseif ($this->getConfigData('type')=='UPS_XML'){
1081: $this->setXMLAccessRequest();
1082: $this->_getXmlTracking($trackings);
1083: }
1084:
1085: return $this->_result;
1086: }
1087:
1088: 1089: 1090: 1091: 1092:
1093: protected function setXMLAccessRequest()
1094: {
1095: $userid = $this->getConfigData('username');
1096: $userid_pass = $this->getConfigData('password');
1097: $access_key = $this->getConfigData('access_license_number');
1098:
1099: $this->_xmlAccessRequest = <<<XMLAuth
1100: <?xml version="1.0"?>
1101: <AccessRequest xml:lang="en-US">
1102: <AccessLicenseNumber>$access_key</AccessLicenseNumber>
1103: <UserId>$userid</UserId>
1104: <Password>$userid_pass</Password>
1105: </AccessRequest>
1106: XMLAuth;
1107: }
1108:
1109: 1110: 1111: 1112: 1113: 1114:
1115: protected function _getCgiTracking($trackings)
1116: {
1117:
1118:
1119: $result = Mage::getModel('shipping/tracking_result');
1120: $defaults = $this->getDefaults();
1121: foreach($trackings as $tracking){
1122: $status = Mage::getModel('shipping/tracking_result_status');
1123: $status->setCarrier('ups');
1124: $status->setCarrierTitle($this->getConfigData('title'));
1125: $status->setTracking($tracking);
1126: $status->setPopup(1);
1127: $status->setUrl("http://wwwapps.ups.com/WebTracking/processInputRequest?HTMLVersion=5.0&error_carried=true"
1128: . "&tracknums_displayed=5&TypeOfInquiryNumber=T&loc=en_US&InquiryNumber1=$tracking"
1129: . "&AgreeToTermsAndConditions=yes"
1130: );
1131: $result->append($status);
1132: }
1133:
1134: $this->_result = $result;
1135: return $result;
1136: }
1137:
1138: 1139: 1140: 1141: 1142: 1143:
1144: protected function _getXmlTracking($trackings)
1145: {
1146: $url = $this->getConfigData('tracking_xml_url');
1147:
1148: foreach($trackings as $tracking){
1149: $xmlRequest=$this->_xmlAccessRequest;
1150:
1151: 1152: 1153:
1154: $xmlRequest .= <<<XMLAuth
1155: <?xml version="1.0" ?>
1156: <TrackRequest xml:lang="en-US">
1157: <Request>
1158: <RequestAction>Track</RequestAction>
1159: <RequestOption>activity</RequestOption>
1160: </Request>
1161: <TrackingNumber>$tracking</TrackingNumber>
1162: <IncludeFreight>01</IncludeFreight>
1163: </TrackRequest>
1164: XMLAuth;
1165: $debugData = array('request' => $xmlRequest);
1166:
1167: try {
1168: $ch = curl_init();
1169: curl_setopt($ch, CURLOPT_URL, $url);
1170: curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1171: curl_setopt($ch, CURLOPT_HEADER, 0);
1172: curl_setopt($ch, CURLOPT_POST, 1);
1173: curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
1174: curl_setopt($ch, CURLOPT_TIMEOUT, 30);
1175: $xmlResponse = curl_exec ($ch);
1176: $debugData['result'] = $xmlResponse;
1177: curl_close ($ch);
1178: }
1179: catch (Exception $e) {
1180: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
1181: $xmlResponse = '';
1182: }
1183:
1184: $this->_debug($debugData);
1185: $this->_parseXmlTrackingResponse($tracking, $xmlResponse);
1186: }
1187:
1188: return $this->_result;
1189: }
1190:
1191: 1192: 1193: 1194: 1195: 1196: 1197:
1198: protected function _parseXmlTrackingResponse($trackingvalue, $xmlResponse)
1199: {
1200: $errorTitle = 'Unable to retrieve tracking';
1201: $resultArr = array();
1202: $packageProgress = array();
1203:
1204: if ($xmlResponse) {
1205: $xml = new Varien_Simplexml_Config();
1206: $xml->loadString($xmlResponse);
1207: $arr = $xml->getXpath("//TrackResponse/Response/ResponseStatusCode/text()");
1208: $success = (int)$arr[0][0];
1209:
1210: if($success===1){
1211: $arr = $xml->getXpath("//TrackResponse/Shipment/Service/Description/text()");
1212: $resultArr['service'] = (string)$arr[0];
1213:
1214: $arr = $xml->getXpath("//TrackResponse/Shipment/PickupDate/text()");
1215: $resultArr['shippeddate'] = (string)$arr[0];
1216:
1217: $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/Weight/text()");
1218: $weight = (string)$arr[0];
1219:
1220: $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/UnitOfMeasurement/Code/text()");
1221: $unit = (string)$arr[0];
1222:
1223: $resultArr['weight'] = "{$weight} {$unit}";
1224:
1225: $activityTags = $xml->getXpath("//TrackResponse/Shipment/Package/Activity");
1226: if ($activityTags) {
1227: $i=1;
1228: foreach ($activityTags as $activityTag) {
1229: $addArr=array();
1230: if (isset($activityTag->ActivityLocation->Address->City)) {
1231: $addArr[] = (string)$activityTag->ActivityLocation->Address->City;
1232: }
1233: if (isset($activityTag->ActivityLocation->Address->StateProvinceCode)) {
1234: $addArr[] = (string)$activityTag->ActivityLocation->Address->StateProvinceCode;
1235: }
1236: if (isset($activityTag->ActivityLocation->Address->CountryCode)) {
1237: $addArr[] = (string)$activityTag->ActivityLocation->Address->CountryCode;
1238: }
1239: $dateArr = array();
1240: $date = (string)$activityTag->Date;
1241: $dateArr[] = substr($date,0,4);
1242: $dateArr[] = substr($date,4,2);
1243: $dateArr[] = substr($date,-2,2);
1244:
1245: $timeArr = array();
1246: $time = (string)$activityTag->Time;
1247: $timeArr[] = substr($time,0,2);
1248: $timeArr[] = substr($time,2,2);
1249: $timeArr[] = substr($time,-2,2);
1250:
1251: if($i==1){
1252: $resultArr['status'] = (string)$activityTag->Status->StatusType->Description;
1253: $resultArr['deliverydate'] = implode('-',$dateArr);
1254: $resultArr['deliverytime'] = implode(':',$timeArr);
1255: $resultArr['deliverylocation'] = (string)$activityTag->ActivityLocation->Description;
1256: $resultArr['signedby'] = (string)$activityTag->ActivityLocation->SignedForByName;
1257: if ($addArr) {
1258: $resultArr['deliveryto']=implode(', ',$addArr);
1259: }
1260: }else{
1261: $tempArr=array();
1262: $tempArr['activity'] = (string)$activityTag->Status->StatusType->Description;
1263: $tempArr['deliverydate'] = implode('-',$dateArr);
1264: $tempArr['deliverytime'] = implode(':',$timeArr);
1265: if ($addArr) {
1266: $tempArr['deliverylocation']=implode(', ',$addArr);
1267: }
1268: $packageProgress[] = $tempArr;
1269: }
1270: $i++;
1271: }
1272: $resultArr['progressdetail'] = $packageProgress;
1273: }
1274: } else {
1275: $arr = $xml->getXpath("//TrackResponse/Response/Error/ErrorDescription/text()");
1276: $errorTitle = (string)$arr[0][0];
1277: }
1278: }
1279:
1280: if (!$this->_result) {
1281: $this->_result = Mage::getModel('shipping/tracking_result');
1282: }
1283:
1284: $defaults = $this->getDefaults();
1285:
1286: if ($resultArr) {
1287: $tracking = Mage::getModel('shipping/tracking_result_status');
1288: $tracking->setCarrier('ups');
1289: $tracking->setCarrierTitle($this->getConfigData('title'));
1290: $tracking->setTracking($trackingvalue);
1291: $tracking->addData($resultArr);
1292: $this->_result->append($tracking);
1293: } else {
1294: $error = Mage::getModel('shipping/tracking_result_error');
1295: $error->setCarrier('ups');
1296: $error->setCarrierTitle($this->getConfigData('title'));
1297: $error->setTracking($trackingvalue);
1298: $error->setErrorMessage($errorTitle);
1299: $this->_result->append($error);
1300: }
1301: return $this->_result;
1302: }
1303:
1304: 1305: 1306: 1307: 1308:
1309: public function getResponse()
1310: {
1311: $statuses = '';
1312: if ($this->_result instanceof Mage_Shipping_Model_Tracking_Result){
1313: if ($trackings = $this->_result->getAllTrackings()) {
1314: foreach ($trackings as $tracking){
1315: if($data = $tracking->getAllData()){
1316: if (isset($data['status'])) {
1317: $statuses .= Mage::helper('usa')->__($data['status']);
1318: } else {
1319: $statuses .= Mage::helper('usa')->__($data['error_message']);
1320: }
1321: }
1322: }
1323: }
1324: }
1325: if (empty($statuses)) {
1326: $statuses = Mage::helper('usa')->__('Empty response');
1327: }
1328: return $statuses;
1329: }
1330:
1331: 1332: 1333: 1334: 1335:
1336: public function getAllowedMethods()
1337: {
1338: $allowed = explode(',', $this->getConfigData('allowed_methods'));
1339: $arr = array();
1340: $isByCode = $this->getConfigData('type') == 'UPS_XML';
1341: foreach ($allowed as $k) {
1342: $arr[$k] = $isByCode ? $this->getShipmentByCode($k) : $this->getCode('method', $k);
1343: }
1344: return $arr;
1345: }
1346:
1347: 1348: 1349: 1350: 1351: 1352:
1353: protected function _formShipmentRequest(Varien_Object $request)
1354: {
1355: $packageParams = $request->getPackageParams();
1356: $height = $packageParams->getHeight();
1357: $width = $packageParams->getWidth();
1358: $length = $packageParams->getLength();
1359: $weightUnits = $packageParams->getWeightUnits() == Zend_Measure_Weight::POUND ? 'LBS' : 'KGS';
1360: $dimensionsUnits = $packageParams->getDimensionUnits() == Zend_Measure_Length::INCH ? 'IN' : 'CM';
1361:
1362: $itemsDesc = array();
1363: $itemsShipment = $request->getPackageItems();
1364: foreach ($itemsShipment as $itemShipment) {
1365: $item = new Varien_Object();
1366: $item->setData($itemShipment);
1367: $itemsDesc[] = $item->getName();
1368: }
1369:
1370: $xmlRequest = new SimpleXMLElement('<?xml version = "1.0" ?><ShipmentConfirmRequest xml:lang="en-US"/>');
1371: $requestPart = $xmlRequest->addChild('Request');
1372: $requestPart->addChild('RequestAction', 'ShipConfirm');
1373: $requestPart->addChild('RequestOption', 'nonvalidate');
1374:
1375: $shipmentPart = $xmlRequest->addChild('Shipment');
1376: if ($request->getIsReturn()) {
1377: $returnPart = $shipmentPart->addChild('ReturnService');
1378:
1379: $returnPart->addChild('Code', '9');
1380: }
1381: $shipmentPart->addChild('Description', substr(implode(' ', $itemsDesc), 0, 35));
1382:
1383: $shipperPart = $shipmentPart->addChild('Shipper');
1384: if ($request->getIsReturn()) {
1385: $shipperPart->addChild('Name', $request->getRecipientContactCompanyName());
1386: $shipperPart->addChild('AttentionName', $request->getRecipientContactPersonName());
1387: $shipperPart->addChild('ShipperNumber', $this->getConfigData('shipper_number'));
1388: $shipperPart->addChild('PhoneNumber', $request->getRecipientContactPhoneNumber());
1389:
1390: $addressPart = $shipperPart->addChild('Address');
1391: $addressPart->addChild('AddressLine1', $request->getRecipientAddressStreet());
1392: $addressPart->addChild('AddressLine2', $request->getRecipientAddressStreet2());
1393: $addressPart->addChild('City', $request->getRecipientAddressCity());
1394: $addressPart->addChild('CountryCode', $request->getRecipientAddressCountryCode());
1395: $addressPart->addChild('PostalCode', $request->getRecipientAddressPostalCode());
1396: if ($request->getRecipientAddressStateOrProvinceCode()) {
1397: $addressPart->addChild('StateProvinceCode', $request->getRecipientAddressStateOrProvinceCode());
1398: }
1399: } else {
1400: $shipperPart->addChild('Name', $request->getShipperContactCompanyName());
1401: $shipperPart->addChild('AttentionName', $request->getShipperContactPersonName());
1402: $shipperPart->addChild('ShipperNumber', $this->getConfigData('shipper_number'));
1403: $shipperPart->addChild('PhoneNumber', $request->getShipperContactPhoneNumber());
1404:
1405: $addressPart = $shipperPart->addChild('Address');
1406: $addressPart->addChild('AddressLine1', $request->getShipperAddressStreet());
1407: $addressPart->addChild('AddressLine2', $request->getShipperAddressStreet2());
1408: $addressPart->addChild('City', $request->getShipperAddressCity());
1409: $addressPart->addChild('CountryCode', $request->getShipperAddressCountryCode());
1410: $addressPart->addChild('PostalCode', $request->getShipperAddressPostalCode());
1411: if ($request->getShipperAddressStateOrProvinceCode()) {
1412: $addressPart->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode());
1413: }
1414: }
1415:
1416: $shipToPart = $shipmentPart->addChild('ShipTo');
1417: $shipToPart->addChild('AttentionName', $request->getRecipientContactPersonName());
1418: $shipToPart->addChild('CompanyName', $request->getRecipientContactCompanyName()
1419: ? $request->getRecipientContactCompanyName()
1420: : 'N/A');
1421: $shipToPart->addChild('PhoneNumber', $request->getRecipientContactPhoneNumber());
1422:
1423: $addressPart = $shipToPart->addChild('Address');
1424: $addressPart->addChild('AddressLine1', $request->getRecipientAddressStreet1());
1425: $addressPart->addChild('AddressLine2', $request->getRecipientAddressStreet2());
1426: $addressPart->addChild('City', $request->getRecipientAddressCity());
1427: $addressPart->addChild('CountryCode', $request->getRecipientAddressCountryCode());
1428: $addressPart->addChild('PostalCode', $request->getRecipientAddressPostalCode());
1429: if ($request->getRecipientAddressStateOrProvinceCode()) {
1430: $addressPart->addChild('StateProvinceCode', $request->getRecipientAddressRegionCode());
1431: }
1432: if ($this->getConfigData('dest_type') == 'RES') {
1433: $addressPart->addChild('ResidentialAddress');
1434: }
1435:
1436: if ($request->getIsReturn()) {
1437: $shipFromPart = $shipmentPart->addChild('ShipFrom');
1438: $shipFromPart->addChild('AttentionName', $request->getShipperContactPersonName());
1439: $shipFromPart->addChild('CompanyName', $request->getShipperContactCompanyName()
1440: ? $request->getShipperContactCompanyName()
1441: : $request->getShipperContactPersonName());
1442: $shipFromAddress = $shipFromPart->addChild('Address');
1443: $shipFromAddress->addChild('AddressLine1', $request->getShipperAddressStreet1());
1444: $shipFromAddress->addChild('AddressLine2', $request->getShipperAddressStreet2());
1445: $shipFromAddress->addChild('City', $request->getShipperAddressCity());
1446: $shipFromAddress->addChild('CountryCode', $request->getShipperAddressCountryCode());
1447: $shipFromAddress->addChild('PostalCode', $request->getShipperAddressPostalCode());
1448: if ($request->getShipperAddressStateOrProvinceCode()) {
1449: $shipFromAddress->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode());
1450: }
1451:
1452: $addressPart = $shipToPart->addChild('Address');
1453: $addressPart->addChild('AddressLine1', $request->getShipperAddressStreet1());
1454: $addressPart->addChild('AddressLine2', $request->getShipperAddressStreet2());
1455: $addressPart->addChild('City', $request->getShipperAddressCity());
1456: $addressPart->addChild('CountryCode', $request->getShipperAddressCountryCode());
1457: $addressPart->addChild('PostalCode', $request->getShipperAddressPostalCode());
1458: if ($request->getShipperAddressStateOrProvinceCode()) {
1459: $addressPart->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode());
1460: }
1461: if ($this->getConfigData('dest_type') == 'RES') {
1462: $addressPart->addChild('ResidentialAddress');
1463: }
1464: }
1465:
1466: $servicePart = $shipmentPart->addChild('Service');
1467: $servicePart->addChild('Code', $request->getShippingMethod());
1468: $packagePart = $shipmentPart->addChild('Package');
1469: $packagePart->addChild('Description', substr(implode(' ', $itemsDesc), 0, 35));
1470: $packagePart->addChild('PackagingType')
1471: ->addChild('Code', $request->getPackagingType());
1472: $packageWeight = $packagePart->addChild('PackageWeight');
1473: $packageWeight->addChild('Weight', $request->getPackageWeight());
1474: $packageWeight->addChild('UnitOfMeasurement')->addChild('Code', $weightUnits);
1475:
1476:
1477: if ($length || $width || $height) {
1478: $packageDimensions = $packagePart->addChild('Dimensions');
1479: $packageDimensions->addChild('UnitOfMeasurement')->addChild('Code', $dimensionsUnits);
1480: $packageDimensions->addChild('Length', $length);
1481: $packageDimensions->addChild('Width', $width);
1482: $packageDimensions->addChild('Height', $height);
1483: }
1484:
1485:
1486: if ($this->_isUSCountry($request->getRecipientAddressCountryCode())
1487: && $this->_isUSCountry($request->getShipperAddressCountryCode())
1488: ) {
1489: if ($request->getReferenceData()) {
1490: $referenceData = $request->getReferenceData() . $request->getPackageId();
1491: } else {
1492: $referenceData = 'Order #'
1493: . $request->getOrderShipment()->getOrder()->getIncrementId()
1494: . ' P'
1495: . $request->getPackageId();
1496: }
1497: $referencePart = $packagePart->addChild('ReferenceNumber');
1498: $referencePart->addChild('Code', '02');
1499: $referencePart->addChild('Value', $referenceData);
1500: }
1501:
1502: $deliveryConfirmation = $packageParams->getDeliveryConfirmation();
1503: if ($deliveryConfirmation) {
1504:
1505: $serviceOptionsNode = null;
1506: switch ($this->_getDeliveryConfirmationLevel($request->getRecipientAddressCountryCode())) {
1507: case self::DELIVERY_CONFIRMATION_PACKAGE:
1508: $serviceOptionsNode = $packagePart->addChild('PackageServiceOptions');
1509: break;
1510: case self::DELIVERY_CONFIRMATION_SHIPMENT:
1511: $serviceOptionsNode = $shipmentPart->addChild('ShipmentServiceOptions');
1512: break;
1513: }
1514: if (!is_null($serviceOptionsNode)) {
1515: $serviceOptionsNode
1516: ->addChild('DeliveryConfirmation')
1517: ->addChild('DCISType', $packageParams->getDeliveryConfirmation());
1518: }
1519: }
1520:
1521: $shipmentPart->addChild('PaymentInformation')
1522: ->addChild('Prepaid')
1523: ->addChild('BillShipper')
1524: ->addChild('AccountNumber', $this->getConfigData('shipper_number'));
1525:
1526: if ($request->getPackagingType() != $this->getCode('container', 'ULE')
1527: && $request->getShipperAddressCountryCode() == Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID
1528: && ($request->getRecipientAddressCountryCode() == 'CA'
1529: || $request->getRecipientAddressCountryCode() == 'PR'
1530: )) {
1531: $invoiceLineTotalPart = $shipmentPart->addChild('InvoiceLineTotal');
1532: $invoiceLineTotalPart->addChild('CurrencyCode', $request->getBaseCurrencyCode());
1533: $invoiceLineTotalPart->addChild('MonetaryValue', ceil($packageParams->getCustomsValue()));
1534: }
1535:
1536: $labelPart = $xmlRequest->addChild('LabelSpecification');
1537: $labelPart->addChild('LabelPrintMethod')
1538: ->addChild('Code', 'GIF');
1539: $labelPart->addChild('LabelImageFormat')
1540: ->addChild('Code', 'GIF');
1541:
1542: $this->setXMLAccessRequest();
1543: $xmlRequest = $this->_xmlAccessRequest . $xmlRequest->asXml();
1544: return $xmlRequest;
1545: }
1546:
1547: 1548: 1549: 1550: 1551: 1552:
1553: protected function _sendShipmentAcceptRequest(SimpleXMLElement $shipmentConfirmResponse)
1554: {
1555: $xmlRequest = new SimpleXMLElement('<?xml version = "1.0" ?><ShipmentAcceptRequest/>');
1556: $request = $xmlRequest->addChild('Request');
1557: $request->addChild('RequestAction', 'ShipAccept');
1558: $xmlRequest->addChild('ShipmentDigest', $shipmentConfirmResponse->ShipmentDigest);
1559:
1560: $debugData = array('request' => $xmlRequest->asXML());
1561: try {
1562: $url = $this->_defaultUrls['ShipAccept'];
1563:
1564: $ch = curl_init($url);
1565: curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1566: curl_setopt($ch, CURLOPT_HEADER, 0);
1567: curl_setopt($ch, CURLOPT_POST, 1);
1568: curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_xmlAccessRequest . $xmlRequest->asXML());
1569: curl_setopt($ch, CURLOPT_TIMEOUT, 30);
1570: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (boolean)$this->getConfigFlag('mode_xml'));
1571: $xmlResponse = curl_exec ($ch);
1572:
1573: $debugData['result'] = $xmlResponse;
1574: $this->_setCachedQuotes($xmlRequest, $xmlResponse);
1575: } catch (Exception $e) {
1576: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
1577: $xmlResponse = '';
1578: }
1579:
1580: try {
1581: $response = new SimpleXMLElement($xmlResponse);
1582: } catch (Exception $e) {
1583: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
1584: }
1585:
1586: $result = new Varien_Object();
1587: if (isset($response->Error)) {
1588: $result->setErrors((string)$response->Error->ErrorDescription);
1589: } else {
1590: $shippingLabelContent = (string)$response->ShipmentResults->PackageResults->LabelImage->GraphicImage;
1591: $trackingNumber = (string)$response->ShipmentResults->PackageResults->TrackingNumber;
1592:
1593: $result->setShippingLabelContent(base64_decode($shippingLabelContent));
1594: $result->setTrackingNumber($trackingNumber);
1595: }
1596:
1597: $this->_debug($debugData);
1598: return $result;
1599: }
1600:
1601: 1602: 1603: 1604: 1605: 1606:
1607: protected function _doShipmentRequest(Varien_Object $request)
1608: {
1609: $this->_prepareShipmentRequest($request);
1610: $result = new Varien_Object();
1611: $xmlRequest = $this->_formShipmentRequest($request);
1612: $xmlResponse = $this->_getCachedQuotes($xmlRequest);
1613:
1614: if ($xmlResponse === null) {
1615: $url = $this->getConfigData('url');
1616: if (!$url) {
1617: $url = $this->_defaultUrls['ShipConfirm'];
1618: }
1619:
1620: $debugData = array('request' => $xmlRequest);
1621: $ch = curl_init();
1622: curl_setopt($ch, CURLOPT_URL, $url);
1623: curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1624: curl_setopt($ch, CURLOPT_HEADER, 0);
1625: curl_setopt($ch, CURLOPT_POST, 1);
1626: curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
1627: curl_setopt($ch, CURLOPT_TIMEOUT, 30);
1628: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (boolean)$this->getConfigFlag('mode_xml'));
1629: $xmlResponse = curl_exec($ch);
1630: if ($xmlResponse === false) {
1631: throw new Exception(curl_error($ch));
1632: } else {
1633: $debugData['result'] = $xmlResponse;
1634: $this->_setCachedQuotes($xmlRequest, $xmlResponse);
1635: }
1636: }
1637:
1638: try {
1639: $response = new SimpleXMLElement($xmlResponse);
1640: } catch (Exception $e) {
1641: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
1642: $result->setErrors($e->getMessage());
1643: }
1644:
1645: if (isset($response->Response->Error)
1646: && in_array($response->Response->Error->ErrorSeverity, array('Hard', 'Transient'))
1647: ) {
1648: $result->setErrors((string)$response->Response->Error->ErrorDescription);
1649: }
1650:
1651: $this->_debug($debugData);
1652:
1653: if ($result->hasErrors() || empty($response)) {
1654: return $result;
1655: } else {
1656: return $this->_sendShipmentAcceptRequest($response);
1657: }
1658: }
1659:
1660: 1661: 1662: 1663: 1664: 1665:
1666: public function getContainerTypes(Varien_Object $params = null)
1667: {
1668: if ($params == null) {
1669: return $this->_getAllowedContainers($params);
1670: }
1671: $method = $params->getMethod();
1672: $countryShipper = $params->getCountryShipper();
1673: $countryRecipient = $params->getCountryRecipient();
1674:
1675: if (($countryShipper == self::USA_COUNTRY_ID
1676: && $countryRecipient == self::CANADA_COUNTRY_ID)
1677: || ($countryShipper == self::CANADA_COUNTRY_ID
1678: && $countryRecipient == self::USA_COUNTRY_ID)
1679: || ($countryShipper == self::MEXICO_COUNTRY_ID
1680: && $countryRecipient == self::USA_COUNTRY_ID)
1681: && $method == '11'
1682: ) {
1683: $containerTypes = array();
1684: if ($method == '07'
1685: || $method == '08'
1686: || $method == '65'
1687:
1688: ) {
1689:
1690: if ($method != '08') {
1691: $containerTypes = array(
1692: '01' => Mage::helper('usa')->__('UPS Letter Envelope'),
1693: '24' => Mage::helper('usa')->__('UPS Worldwide 25 kilo'),
1694: '25' => Mage::helper('usa')->__('UPS Worldwide 10 kilo'),
1695: );
1696: }
1697: $containerTypes = $containerTypes + array(
1698: '03' => Mage::helper('usa')->__('UPS Tube'),
1699: '04' => Mage::helper('usa')->__('PAK'),
1700: '2a' => Mage::helper('usa')->__('Small Express Box'),
1701: '2b' => Mage::helper('usa')->__('Medium Express Box'),
1702: '2c' => Mage::helper('usa')->__('Large Express Box'),
1703: );
1704: }
1705: return array('00' => Mage::helper('usa')->__('Customer Packaging')) + $containerTypes;
1706: } elseif ($countryShipper == self::USA_COUNTRY_ID && $countryRecipient == self::PUERTORICO_COUNTRY_ID
1707: && ($method == '03'
1708: || $method == '02'
1709: || $method == '01'
1710: )) {
1711:
1712: $params->setCountryRecipient(self::USA_COUNTRY_ID);
1713: $containerTypes = $this->_getAllowedContainers($params);
1714: $params->setCountryRecipient($countryRecipient);
1715: return $containerTypes;
1716: }
1717: return $this->_getAllowedContainers($params);
1718: }
1719:
1720: 1721: 1722: 1723: 1724:
1725: public function getContainerTypesAll()
1726: {
1727: $codes = $this->getCode('container');
1728: $descriptions = $this->getCode('container_description');
1729: $result = array();
1730: foreach ($codes as $key => &$code) {
1731: $result[$code] = $descriptions[$key];
1732: }
1733: return $result;
1734:
1735: }
1736:
1737: 1738: 1739: 1740: 1741:
1742: public function getContainerTypesFilter()
1743: {
1744: return $this->getCode('containers_filter');
1745: }
1746:
1747: 1748: 1749: 1750: 1751: 1752:
1753: public function getDeliveryConfirmationTypes(Varien_Object $params = null)
1754: {
1755: $countryRecipient = $params != null ? $params->getCountryRecipient() : null;
1756: $deliveryConfirmationTypes = array();
1757: switch ($this->_getDeliveryConfirmationLevel($countryRecipient)) {
1758: case self::DELIVERY_CONFIRMATION_PACKAGE:
1759: $deliveryConfirmationTypes = array(
1760: 1 => Mage::helper('usa')->__('Delivery Confirmation'),
1761: 2 => Mage::helper('usa')->__('Signature Required'),
1762: 3 => Mage::helper('usa')->__('Adult Signature Required'),
1763: );
1764: break;
1765: case self::DELIVERY_CONFIRMATION_SHIPMENT:
1766: $deliveryConfirmationTypes = array(
1767: 1 => Mage::helper('usa')->__('Signature Required'),
1768: 2 => Mage::helper('usa')->__('Adult Signature Required'),
1769: );
1770: }
1771: array_unshift($deliveryConfirmationTypes, Mage::helper('usa')->__('Not Required'));
1772:
1773: return $deliveryConfirmationTypes;
1774: }
1775:
1776: 1777: 1778: 1779: 1780:
1781: public function getCustomizableContainerTypes()
1782: {
1783: $result = array();
1784: $containerTypes = $this->getCode('container');
1785: foreach (parent::getCustomizableContainerTypes() as $containerType) {
1786: $result[$containerType] = $containerTypes[$containerType];
1787: }
1788: return $result;
1789: }
1790:
1791: 1792: 1793: 1794: 1795: 1796: 1797:
1798: protected function _getDeliveryConfirmationLevel($countyDest = null) {
1799: if (is_null($countyDest)) {
1800: return null;
1801: }
1802:
1803: if ($countyDest == Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID) {
1804: return self::DELIVERY_CONFIRMATION_PACKAGE;
1805: }
1806:
1807: return self::DELIVERY_CONFIRMATION_SHIPMENT;
1808: }
1809: }
1810: