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:
36: class Mage_Usa_Model_Shipping_Carrier_Usps
37: extends Mage_Usa_Model_Shipping_Carrier_Abstract
38: implements Mage_Shipping_Model_Carrier_Interface
39: {
40: 41: 42:
43: const CONTAINER_VARIABLE = 'VARIABLE';
44: const CONTAINER_FLAT_RATE_BOX = 'FLAT RATE BOX';
45: const CONTAINER_FLAT_RATE_ENVELOPE = 'FLAT RATE ENVELOPE';
46: const CONTAINER_RECTANGULAR = 'RECTANGULAR';
47: const CONTAINER_NONRECTANGULAR = 'NONRECTANGULAR';
48:
49: 50: 51:
52: const SIZE_REGULAR = 'REGULAR';
53: const SIZE_LARGE = 'LARGE';
54:
55: 56: 57: 58: 59:
60: const DEFAULT_REVISION = 2;
61:
62: 63: 64: 65: 66:
67: const CODE = 'usps';
68:
69: 70: 71:
72: const OUNCES_POUND = 16;
73:
74: 75: 76: 77: 78:
79: protected $_code = self::CODE;
80:
81: 82: 83: 84: 85: 86:
87: protected $_isZipCodeRequired;
88:
89: 90: 91: 92: 93:
94: protected $_request = null;
95:
96: 97: 98: 99: 100:
101: protected $_rawRequest = null;
102:
103: 104: 105: 106: 107:
108: protected $_result = null;
109:
110: 111: 112: 113: 114:
115: protected $_defaultGatewayUrl = 'http://production.shippingapis.com/ShippingAPI.dll';
116:
117: 118: 119: 120: 121:
122: protected $_customizableContainerTypes = array('VARIABLE', 'RECTANGULAR', 'NONRECTANGULAR');
123:
124: 125: 126: 127: 128: 129:
130: public function collectRates(Mage_Shipping_Model_Rate_Request $request)
131: {
132: if (!$this->getConfigFlag($this->_activeFlag)) {
133: return false;
134: }
135:
136: $this->setRequest($request);
137:
138: $this->_result = $this->_getQuotes();
139:
140: $this->_updateFreeMethodQuote($request);
141:
142: return $this->getResult();
143: }
144:
145: 146: 147: 148: 149: 150:
151: public function setRequest(Mage_Shipping_Model_Rate_Request $request)
152: {
153: $this->_request = $request;
154:
155: $r = new Varien_Object();
156:
157: if ($request->getLimitMethod()) {
158: $r->setService($request->getLimitMethod());
159: } else {
160: $r->setService('ALL');
161: }
162:
163: if ($request->getUspsUserid()) {
164: $userId = $request->getUspsUserid();
165: } else {
166: $userId = $this->getConfigData('userid');
167: }
168: $r->setUserId($userId);
169:
170: if ($request->getUspsContainer()) {
171: $container = $request->getUspsContainer();
172: } else {
173: $container = $this->getConfigData('container');
174: }
175: $r->setContainer($container);
176:
177: if ($request->getUspsSize()) {
178: $size = $request->getUspsSize();
179: } else {
180: $size = $this->getConfigData('size');
181: }
182: $r->setSize($size);
183:
184: if ($request->getGirth()) {
185: $girth = $request->getGirth();
186: } else {
187: $girth = $this->getConfigData('girth');
188: }
189: $r->setGirth($girth);
190:
191: if ($request->getHeight()) {
192: $height = $request->getHeight();
193: } else {
194: $height = $this->getConfigData('height');
195: }
196: $r->setHeight($height);
197:
198: if ($request->getLength()) {
199: $length = $request->getLength();
200: } else {
201: $length = $this->getConfigData('length');
202: }
203: $r->setLength($length);
204:
205: if ($request->getWidth()) {
206: $width = $request->getWidth();
207: } else {
208: $width = $this->getConfigData('width');
209: }
210: $r->setWidth($width);
211:
212: if ($request->getUspsMachinable()) {
213: $machinable = $request->getUspsMachinable();
214: } else {
215: $machinable = $this->getConfigData('machinable');
216: }
217: $r->setMachinable($machinable);
218:
219: if ($request->getOrigPostcode()) {
220: $r->setOrigPostal($request->getOrigPostcode());
221: } else {
222: $r->setOrigPostal(Mage::getStoreConfig(
223: Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP,
224: $request->getStoreId()
225: ));
226: }
227:
228: if ($request->getOrigCountryId()) {
229: $r->setOrigCountryId($request->getOrigCountryId());
230: } else {
231: $r->setOrigCountryId(Mage::getStoreConfig(
232: Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID,
233: $request->getStoreId()
234: ));
235: }
236:
237: if ($request->getDestCountryId()) {
238: $destCountry = $request->getDestCountryId();
239: } else {
240: $destCountry = self::USA_COUNTRY_ID;
241: }
242:
243: $r->setDestCountryId($destCountry);
244:
245: if (!$this->_isUSCountry($destCountry)) {
246: $r->setDestCountryName($this->_getCountryName($destCountry));
247: }
248:
249: if ($request->getDestPostcode()) {
250: $r->setDestPostal($request->getDestPostcode());
251: }
252:
253: $weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
254: $r->setWeightPounds(floor($weight));
255: $r->setWeightOunces(round(($weight-floor($weight)) * self::OUNCES_POUND, 1));
256: if ($request->getFreeMethodWeight()!=$request->getPackageWeight()) {
257: $r->setFreeMethodWeight($request->getFreeMethodWeight());
258: }
259:
260: $r->setValue($request->getPackageValue());
261: $r->setValueWithDiscount($request->getPackageValueWithDiscount());
262:
263: $r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
264:
265: $this->_rawRequest = $r;
266:
267: return $this;
268: }
269:
270: 271: 272: 273: 274:
275: public function getResult()
276: {
277: return $this->_result;
278: }
279:
280: 281: 282: 283: 284:
285: protected function _getQuotes()
286: {
287: return $this->_getXmlQuotes();
288: }
289:
290: 291: 292: 293: 294: 295:
296: protected function _setFreeMethodRequest($freeMethod)
297: {
298: $r = $this->_rawRequest;
299:
300: $weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight());
301: $r->setWeightPounds(floor($weight));
302: $r->setWeightOunces(round(($weight-floor($weight)) * self::OUNCES_POUND, 1));
303: $r->setService($freeMethod);
304: }
305:
306: 307: 308: 309: 310: 311:
312: protected function _getXmlQuotes()
313: {
314: $r = $this->_rawRequest;
315:
316:
317: if(!$this->_isUSCountry($r->getOrigCountryId())){
318: $responseBody = '';
319: return $this->_parseXmlResponse($responseBody);
320: }
321:
322: if ($this->_isUSCountry($r->getDestCountryId())) {
323: $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><RateV4Request/>');
324: $xml->addAttribute('USERID', $r->getUserId());
325:
326: $xml->addChild('Revision', '2');
327:
328: $package = $xml->addChild('Package');
329: $package->addAttribute('ID', 0);
330: $service = $this->getCode('service_to_code', $r->getService());
331: if (!$service) {
332: $service = $r->getService();
333: }
334: if ($r->getContainer() == 'FLAT RATE BOX' || $r->getContainer() == 'FLAT RATE ENVELOPE') {
335: $service = 'PRIORITY';
336: }
337: $package->addChild('Service', $service);
338:
339:
340: if ($r->getService() == 'FIRST CLASS' || $r->getService() == 'FIRST CLASS HFP COMMERCIAL') {
341: $package->addChild('FirstClassMailType', 'PARCEL');
342: }
343: $package->addChild('ZipOrigination', $r->getOrigPostal());
344:
345: $package->addChild('ZipDestination', substr($r->getDestPostal(), 0, 5));
346: $package->addChild('Pounds', $r->getWeightPounds());
347: $package->addChild('Ounces', $r->getWeightOunces());
348:
349: $package->addChild('Container', $r->getContainer());
350: $package->addChild('Size', $r->getSize());
351: if ($r->getSize() == 'LARGE') {
352: $package->addChild('Width', $r->getWidth());
353: $package->addChild('Length', $r->getLength());
354: $package->addChild('Height', $r->getHeight());
355: if ($r->getContainer() == 'NONRECTANGULAR' || $r->getContainer() == 'VARIABLE') {
356: $package->addChild('Girth', $r->getGirth());
357: }
358: }
359: $package->addChild('Machinable', $r->getMachinable());
360:
361: $api = 'RateV4';
362: } else {
363: $xml = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><IntlRateV2Request/>');
364: $xml->addAttribute('USERID', $r->getUserId());
365:
366: $xml->addChild('Revision', '2');
367:
368: $package = $xml->addChild('Package');
369: $package->addAttribute('ID', 0);
370: $package->addChild('Pounds', $r->getWeightPounds());
371: $package->addChild('Ounces', $r->getWeightOunces());
372: $package->addChild('MailType', 'All');
373: $package->addChild('ValueOfContents', $r->getValue());
374: $package->addChild('Country', $r->getDestCountryName());
375: $package->addChild('Container', $r->getContainer());
376: $package->addChild('Size', $r->getSize());
377: $width = $length = $height = $girth = '';
378: if ($r->getSize() == 'LARGE') {
379: $width = $r->getWidth();
380: $length = $r->getLength();
381: $height = $r->getHeight();
382: if ($r->getContainer() == 'NONRECTANGULAR') {
383: $girth = $r->getGirth();
384: }
385: }
386: $package->addChild('Width', $width);
387: $package->addChild('Length', $length);
388: $package->addChild('Height', $height);
389: $package->addChild('Girth', $girth);
390:
391:
392: $api = 'IntlRateV2';
393: }
394: $request = $xml->asXML();
395:
396: $responseBody = $this->_getCachedQuotes($request);
397: if ($responseBody === null) {
398: $debugData = array('request' => $request);
399: try {
400: $url = $this->getConfigData('gateway_url');
401: if (!$url) {
402: $url = $this->_defaultGatewayUrl;
403: }
404: $client = new Zend_Http_Client();
405: $client->setUri($url);
406: $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
407: $client->setParameterGet('API', $api);
408: $client->setParameterGet('XML', $request);
409: $response = $client->request();
410: $responseBody = $response->getBody();
411:
412: $debugData['result'] = $responseBody;
413: $this->_setCachedQuotes($request, $responseBody);
414: } catch (Exception $e) {
415: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
416: $responseBody = '';
417: }
418: $this->_debug($debugData);
419: }
420: return $this->_parseXmlResponse($responseBody);
421: }
422:
423: 424: 425: 426: 427: 428: 429:
430: protected function _parseXmlResponse($response)
431: {
432: $costArr = array();
433: $priceArr = array();
434: if (strlen(trim($response)) > 0) {
435: if (strpos(trim($response), '<?xml') === 0) {
436: if (strpos($response, '<?xml version="1.0"?>') !== false) {
437: $response = str_replace(
438: '<?xml version="1.0"?>',
439: '<?xml version="1.0" encoding="ISO-8859-1"?>',
440: $response
441: );
442: }
443:
444: $xml = simplexml_load_string($response);
445:
446: if (is_object($xml)) {
447: if (is_object($xml->Number) && is_object($xml->Description) && (string)$xml->Description!='') {
448: $errorTitle = (string)$xml->Description;
449: } elseif (is_object($xml->Package)
450: && is_object($xml->Package->Error)
451: && is_object($xml->Package->Error->Description)
452: && (string)$xml->Package->Error->Description!=''
453: ) {
454: $errorTitle = (string)$xml->Package->Error->Description;
455: } else {
456: $errorTitle = 'Unknown error';
457: }
458: $r = $this->_rawRequest;
459: $allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
460: $allMethods = $this->getCode('method');
461: $newMethod = false;
462: if ($this->_isUSCountry($r->getDestCountryId())) {
463: if (is_object($xml->Package) && is_object($xml->Package->Postage)) {
464: foreach ($xml->Package->Postage as $postage) {
465: $serviceName = $this->_filterServiceName((string)$postage->MailService);
466: $postage->MailService = $serviceName;
467: if (in_array($serviceName, $allowedMethods)) {
468: $costArr[$serviceName] = (string)$postage->Rate;
469: $priceArr[$serviceName] = $this->getMethodPrice(
470: (string)$postage->Rate,
471: $serviceName
472: );
473: } elseif (!in_array($serviceName, $allMethods)) {
474: $allMethods[] = $serviceName;
475: $newMethod = true;
476: }
477: }
478: asort($priceArr);
479: }
480: } else {
481: 482: 483:
484: if (is_object($xml->Package) && is_object($xml->Package->Service)) {
485: foreach ($xml->Package->Service as $service) {
486: $serviceName = $this->_filterServiceName((string)$service->SvcDescription);
487: $service->SvcDescription = $serviceName;
488: if (in_array($serviceName, $allowedMethods)) {
489: $costArr[$serviceName] = (string)$service->Postage;
490: $priceArr[$serviceName] = $this->getMethodPrice(
491: (string)$service->Postage,
492: $serviceName
493: );
494: } elseif (!in_array($serviceName, $allMethods)) {
495: $allMethods[] = $serviceName;
496: $newMethod = true;
497: }
498: }
499: asort($priceArr);
500: }
501: }
502: 503: 504: 505:
506: if (false && $newMethod) {
507: sort($allMethods);
508: $insert['usps']['fields']['methods']['value'] = $allMethods;
509: Mage::getResourceModel('adminhtml/config')->saveSectionPost('carriers','','',$insert);
510: }
511: }
512: } else {
513: $errorTitle = 'Response is in the wrong format';
514: }
515: }
516:
517: $result = Mage::getModel('shipping/rate_result');
518: if (empty($priceArr)) {
519: $error = Mage::getModel('shipping/rate_result_error');
520: $error->setCarrier('usps');
521: $error->setCarrierTitle($this->getConfigData('title'));
522: $error->setErrorMessage($this->getConfigData('specificerrmsg'));
523: $result->append($error);
524: } else {
525: foreach ($priceArr as $method=>$price) {
526: $rate = Mage::getModel('shipping/rate_result_method');
527: $rate->setCarrier('usps');
528: $rate->setCarrierTitle($this->getConfigData('title'));
529: $rate->setMethod($method);
530: $rate->setMethodTitle($method);
531: $rate->setCost($costArr[$method]);
532: $rate->setPrice($price);
533: $result->append($rate);
534: }
535: }
536:
537: return $result;
538: }
539:
540: 541: 542: 543: 544: 545: 546:
547: public function getCode($type, $code='')
548: {
549: $codes = array(
550:
551: 'service'=>array(
552: 'FIRST CLASS' => Mage::helper('usa')->__('First-Class'),
553: 'PRIORITY' => Mage::helper('usa')->__('Priority Mail'),
554: 'EXPRESS' => Mage::helper('usa')->__('Express Mail'),
555: 'BPM' => Mage::helper('usa')->__('Bound Printed Matter'),
556: 'PARCEL' => Mage::helper('usa')->__('Parcel Post'),
557: 'MEDIA' => Mage::helper('usa')->__('Media Mail'),
558: 'LIBRARY' => Mage::helper('usa')->__('Library'),
559: ),
560:
561: 'service_to_code'=>array(
562: 'First-Class' => 'FIRST CLASS',
563: 'First-Class Mail International Large Envelope' => 'FIRST CLASS',
564: 'First-Class Mail International Letter' => 'FIRST CLASS',
565: 'First-Class Mail International Package' => 'FIRST CLASS',
566: 'First-Class Mail International Parcel' => 'FIRST CLASS',
567: 'First-Class Mail' => 'FIRST CLASS',
568: 'First-Class Mail Flat' => 'FIRST CLASS',
569: 'First-Class Mail Large Envelope' => 'FIRST CLASS',
570: 'First-Class Mail International' => 'FIRST CLASS',
571: 'First-Class Mail Letter' => 'FIRST CLASS',
572: 'First-Class Mail Parcel' => 'FIRST CLASS',
573: 'First-Class Mail Package' => 'FIRST CLASS',
574: 'Parcel Post' => 'PARCEL',
575: 'Bound Printed Matter' => 'BPM',
576: 'Media Mail' => 'MEDIA',
577: 'Library Mail' => 'LIBRARY',
578: 'Express Mail' => 'EXPRESS',
579: 'Express Mail PO to PO' => 'EXPRESS',
580: 'Express Mail Flat Rate Envelope' => 'EXPRESS',
581: 'Express Mail Flat-Rate Envelope Sunday/Holiday Guarantee' => 'EXPRESS',
582: 'Express Mail Sunday/Holiday Guarantee' => 'EXPRESS',
583: 'Express Mail Flat Rate Envelope Hold For Pickup' => 'EXPRESS',
584: 'Express Mail Hold For Pickup' => 'EXPRESS',
585: 'Global Express Guaranteed (GXG)' => 'EXPRESS',
586: 'Global Express Guaranteed Non-Document Rectangular' => 'EXPRESS',
587: 'Global Express Guaranteed Non-Document Non-Rectangular' => 'EXPRESS',
588: 'USPS GXG Envelopes' => 'EXPRESS',
589: 'Express Mail International' => 'EXPRESS',
590: 'Express Mail International Flat Rate Envelope' => 'EXPRESS',
591: 'Priority Mail' => 'PRIORITY',
592: 'Priority Mail Small Flat Rate Box' => 'PRIORITY',
593: 'Priority Mail Medium Flat Rate Box' => 'PRIORITY',
594: 'Priority Mail Large Flat Rate Box' => 'PRIORITY',
595: 'Priority Mail Flat Rate Box' => 'PRIORITY',
596: 'Priority Mail Flat Rate Envelope' => 'PRIORITY',
597: 'Priority Mail International' => 'PRIORITY',
598: 'Priority Mail International Flat Rate Envelope' => 'PRIORITY',
599: 'Priority Mail International Small Flat Rate Box' => 'PRIORITY',
600: 'Priority Mail International Medium Flat Rate Box' => 'PRIORITY',
601: 'Priority Mail International Large Flat Rate Box' => 'PRIORITY',
602: 'Priority Mail International Flat Rate Box' => 'PRIORITY'
603: ),
604:
605: 'first_class_mail_type'=>array(
606: 'LETTER' => Mage::helper('usa')->__('Letter'),
607: 'FLAT' => Mage::helper('usa')->__('Flat'),
608: 'PARCEL' => Mage::helper('usa')->__('Parcel'),
609: ),
610:
611: 'container'=>array(
612: 'VARIABLE' => Mage::helper('usa')->__('Variable'),
613: 'FLAT RATE BOX' => Mage::helper('usa')->__('Flat-Rate Box'),
614: 'FLAT RATE ENVELOPE' => Mage::helper('usa')->__('Flat-Rate Envelope'),
615: 'RECTANGULAR' => Mage::helper('usa')->__('Rectangular'),
616: 'NONRECTANGULAR' => Mage::helper('usa')->__('Non-rectangular'),
617: ),
618:
619: 'containers_filter' => array(
620: array(
621: 'containers' => array('VARIABLE'),
622: 'filters' => array(
623: 'within_us' => array(
624: 'method' => array(
625: 'Express Mail Flat Rate Envelope',
626: 'Express Mail Flat Rate Envelope Hold For Pickup',
627: 'Priority Mail Flat Rate Envelope',
628: 'Priority Mail Large Flat Rate Box',
629: 'Priority Mail Medium Flat Rate Box',
630: 'Priority Mail Small Flat Rate Box',
631: 'Express Mail',
632: 'Priority Mail',
633: 'Parcel Post',
634: 'Media Mail',
635: 'First-Class Mail Large Envelope',
636: )
637: ),
638: 'from_us' => array(
639: 'method' => array(
640: 'Express Mail International Flat Rate Envelope',
641: 'Priority Mail International Flat Rate Envelope',
642: 'Priority Mail International Large Flat Rate Box',
643: 'Priority Mail International Medium Flat Rate Box',
644: 'Priority Mail International Small Flat Rate Box',
645: 'Global Express Guaranteed (GXG)',
646: 'USPS GXG Envelopes',
647: 'Express Mail International',
648: 'Priority Mail International',
649: 'First-Class Mail International Package',
650: 'First-Class Mail International Large Envelope',
651: 'First-Class Mail International Parcel',
652: )
653: )
654: )
655: ),
656: array(
657: 'containers' => array('FLAT RATE BOX'),
658: 'filters' => array(
659: 'within_us' => array(
660: 'method' => array(
661: 'Priority Mail Large Flat Rate Box',
662: 'Priority Mail Medium Flat Rate Box',
663: 'Priority Mail Small Flat Rate Box',
664: )
665: ),
666: 'from_us' => array(
667: 'method' => array(
668: 'Priority Mail International Large Flat Rate Box',
669: 'Priority Mail International Medium Flat Rate Box',
670: 'Priority Mail International Small Flat Rate Box',
671: )
672: )
673: )
674: ),
675: array(
676: 'containers' => array('FLAT RATE ENVELOPE'),
677: 'filters' => array(
678: 'within_us' => array(
679: 'method' => array(
680: 'Express Mail Flat Rate Envelope',
681: 'Express Mail Flat Rate Envelope Hold For Pickup',
682: 'Priority Mail Flat Rate Envelope',
683: )
684: ),
685: 'from_us' => array(
686: 'method' => array(
687: 'Express Mail International Flat Rate Envelope',
688: 'Priority Mail International Flat Rate Envelope',
689: )
690: )
691: )
692: ),
693: array(
694: 'containers' => array('RECTANGULAR'),
695: 'filters' => array(
696: 'within_us' => array(
697: 'method' => array(
698: 'Express Mail',
699: 'Priority Mail',
700: 'Parcel Post',
701: 'Media Mail',
702: )
703: ),
704: 'from_us' => array(
705: 'method' => array(
706: 'USPS GXG Envelopes',
707: 'Express Mail International',
708: 'Priority Mail International',
709: 'First-Class Mail International Package',
710: 'First-Class Mail International Parcel',
711: )
712: )
713: )
714: ),
715: array(
716: 'containers' => array('NONRECTANGULAR'),
717: 'filters' => array(
718: 'within_us' => array(
719: 'method' => array(
720: 'Express Mail',
721: 'Priority Mail',
722: 'Parcel Post',
723: 'Media Mail',
724: )
725: ),
726: 'from_us' => array(
727: 'method' => array(
728: 'Global Express Guaranteed (GXG)',
729: 'USPS GXG Envelopes',
730: 'Express Mail International',
731: 'Priority Mail International',
732: 'First-Class Mail International Package',
733: 'First-Class Mail International Parcel',
734: )
735: )
736: )
737: ),
738: ),
739:
740: 'size'=>array(
741: 'REGULAR' => Mage::helper('usa')->__('Regular'),
742: 'LARGE' => Mage::helper('usa')->__('Large'),
743: ),
744:
745: 'machinable'=>array(
746: 'true' => Mage::helper('usa')->__('Yes'),
747: 'false' => Mage::helper('usa')->__('No'),
748: ),
749:
750: 'delivery_confirmation_types' => array(
751: 'True' => Mage::helper('usa')->__('Not Required'),
752: 'False' => Mage::helper('usa')->__('Required'),
753: ),
754: );
755:
756: $methods = $this->getConfigData('methods');
757: if (!empty($methods)) {
758: $codes['method'] = explode(",", $methods);
759: } else {
760: $codes['method'] = array();
761: }
762:
763: if (!isset($codes[$type])) {
764: return false;
765: } elseif (''===$code) {
766: return $codes[$type];
767: }
768:
769: if (!isset($codes[$type][$code])) {
770: return false;
771: } else {
772: return $codes[$type][$code];
773: }
774: }
775:
776: 777: 778: 779: 780: 781:
782: public function getTracking($trackings)
783: {
784: $this->setTrackingReqeust();
785:
786: if (!is_array($trackings)) {
787: $trackings = array($trackings);
788: }
789:
790: $this->_getXmlTracking($trackings);
791:
792: return $this->_result;
793: }
794:
795: 796: 797: 798: 799:
800: protected function setTrackingReqeust()
801: {
802: $r = new Varien_Object();
803:
804: $userId = $this->getConfigData('userid');
805: $r->setUserId($userId);
806:
807: $this->_rawTrackRequest = $r;
808: }
809:
810: 811: 812: 813: 814: 815:
816: protected function _getXmlTracking($trackings)
817: {
818: $r = $this->_rawTrackRequest;
819:
820: foreach ($trackings as $tracking) {
821: $xml = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><TrackRequest/>');
822: $xml->addAttribute('USERID', $r->getUserId());
823:
824: $trackid = $xml->addChild('TrackID');
825: $trackid->addAttribute('ID',$tracking);
826:
827: $api = 'TrackV2';
828: $request = $xml->asXML();
829: $debugData = array('request' => $request);
830:
831: try {
832: $url = $this->getConfigData('gateway_url');
833: if (!$url) {
834: $url = $this->_defaultGatewayUrl;
835: }
836: $client = new Zend_Http_Client();
837: $client->setUri($url);
838: $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
839: $client->setParameterGet('API', $api);
840: $client->setParameterGet('XML', $request);
841: $response = $client->request();
842: $responseBody = $response->getBody();
843: $debugData['result'] = $responseBody;
844: }
845: catch (Exception $e) {
846: $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
847: $responseBody = '';
848: }
849:
850: $this->_debug($debugData);
851: $this->_parseXmlTrackingResponse($tracking, $responseBody);
852: }
853: }
854:
855: 856: 857: 858: 859: 860: 861:
862: protected function _parseXmlTrackingResponse($trackingvalue, $response)
863: {
864: $errorTitle = Mage::helper('usa')->__('Unable to retrieve tracking');
865: $resultArr=array();
866: if (strlen(trim($response)) > 0) {
867: if (strpos(trim($response), '<?xml')===0) {
868: $xml = simplexml_load_string($response);
869: if (is_object($xml)) {
870: if (isset($xml->Number) && isset($xml->Description) && (string)$xml->Description!='') {
871: $errorTitle = (string)$xml->Description;
872: } elseif (isset($xml->TrackInfo)
873: && isset($xml->TrackInfo->Error)
874: && isset($xml->TrackInfo->Error->Description)
875: && (string)$xml->TrackInfo->Error->Description!=''
876: ) {
877: $errorTitle = (string)$xml->TrackInfo->Error->Description;
878: } else {
879: $errorTitle = Mage::helper('usa')->__('Unknown error');
880: }
881:
882: if(isset($xml->TrackInfo) && isset($xml->TrackInfo->TrackSummary)){
883: $resultArr['tracksummary'] = (string)$xml->TrackInfo->TrackSummary;
884:
885: }
886: }
887: }
888: }
889:
890: if (!$this->_result) {
891: $this->_result = Mage::getModel('shipping/tracking_result');
892: }
893: $defaults = $this->getDefaults();
894:
895: if ($resultArr) {
896: $tracking = Mage::getModel('shipping/tracking_result_status');
897: $tracking->setCarrier('usps');
898: $tracking->setCarrierTitle($this->getConfigData('title'));
899: $tracking->setTracking($trackingvalue);
900: $tracking->setTrackSummary($resultArr['tracksummary']);
901: $this->_result->append($tracking);
902: } else {
903: $error = Mage::getModel('shipping/tracking_result_error');
904: $error->setCarrier('usps');
905: $error->setCarrierTitle($this->getConfigData('title'));
906: $error->setTracking($trackingvalue);
907: $error->setErrorMessage($errorTitle);
908: $this->_result->append($error);
909: }
910: }
911:
912: 913: 914: 915: 916:
917: public function getResponse()
918: {
919: $statuses = '';
920: if ($this->_result instanceof Mage_Shipping_Model_Tracking_Result) {
921: if ($trackings = $this->_result->getAllTrackings()) {
922: foreach ($trackings as $tracking) {
923: if($data = $tracking->getAllData()) {
924: if (!empty($data['track_summary'])) {
925: $statuses .= Mage::helper('usa')->__($data['track_summary']);
926: } else {
927: $statuses .= Mage::helper('usa')->__('Empty response');
928: }
929: }
930: }
931: }
932: }
933: if (empty($statuses)) {
934: $statuses = Mage::helper('usa')->__('Empty response');
935: }
936: return $statuses;
937: }
938:
939: 940: 941: 942: 943:
944: public function getAllowedMethods()
945: {
946: $allowed = explode(',', $this->getConfigData('allowed_methods'));
947: $arr = array();
948: foreach ($allowed as $k) {
949: $arr[$k] = $k;
950: }
951: return $arr;
952: }
953:
954: 955: 956: 957: 958: 959: 960:
961: protected function _getCountryName($countryId)
962: {
963: $countries = array (
964: 'AD' => 'Andorra',
965: 'AE' => 'United Arab Emirates',
966: 'AF' => 'Afghanistan',
967: 'AG' => 'Antigua and Barbuda',
968: 'AI' => 'Anguilla',
969: 'AL' => 'Albania',
970: 'AM' => 'Armenia',
971: 'AN' => 'Netherlands Antilles',
972: 'AO' => 'Angola',
973: 'AR' => 'Argentina',
974: 'AT' => 'Austria',
975: 'AU' => 'Australia',
976: 'AW' => 'Aruba',
977: 'AX' => 'Aland Island (Finland)',
978: 'AZ' => 'Azerbaijan',
979: 'BA' => 'Bosnia-Herzegovina',
980: 'BB' => 'Barbados',
981: 'BD' => 'Bangladesh',
982: 'BE' => 'Belgium',
983: 'BF' => 'Burkina Faso',
984: 'BG' => 'Bulgaria',
985: 'BH' => 'Bahrain',
986: 'BI' => 'Burundi',
987: 'BJ' => 'Benin',
988: 'BM' => 'Bermuda',
989: 'BN' => 'Brunei Darussalam',
990: 'BO' => 'Bolivia',
991: 'BR' => 'Brazil',
992: 'BS' => 'Bahamas',
993: 'BT' => 'Bhutan',
994: 'BW' => 'Botswana',
995: 'BY' => 'Belarus',
996: 'BZ' => 'Belize',
997: 'CA' => 'Canada',
998: 'CC' => 'Cocos Island (Australia)',
999: 'CD' => 'Congo, Democratic Republic of the',
1000: 'CF' => 'Central African Republic',
1001: 'CG' => 'Congo, Republic of the',
1002: 'CH' => 'Switzerland',
1003: 'CI' => 'Cote d Ivoire (Ivory Coast)',
1004: 'CK' => 'Cook Islands (New Zealand)',
1005: 'CL' => 'Chile',
1006: 'CM' => 'Cameroon',
1007: 'CN' => 'China',
1008: 'CO' => 'Colombia',
1009: 'CR' => 'Costa Rica',
1010: 'CU' => 'Cuba',
1011: 'CV' => 'Cape Verde',
1012: 'CX' => 'Christmas Island (Australia)',
1013: 'CY' => 'Cyprus',
1014: 'CZ' => 'Czech Republic',
1015: 'DE' => 'Germany',
1016: 'DJ' => 'Djibouti',
1017: 'DK' => 'Denmark',
1018: 'DM' => 'Dominica',
1019: 'DO' => 'Dominican Republic',
1020: 'DZ' => 'Algeria',
1021: 'EC' => 'Ecuador',
1022: 'EE' => 'Estonia',
1023: 'EG' => 'Egypt',
1024: 'ER' => 'Eritrea',
1025: 'ES' => 'Spain',
1026: 'ET' => 'Ethiopia',
1027: 'FI' => 'Finland',
1028: 'FJ' => 'Fiji',
1029: 'FK' => 'Falkland Islands',
1030: 'FM' => 'Micronesia, Federated States of',
1031: 'FO' => 'Faroe Islands',
1032: 'FR' => 'France',
1033: 'GA' => 'Gabon',
1034: 'GB' => 'Great Britain and Northern Ireland',
1035: 'GD' => 'Grenada',
1036: 'GE' => 'Georgia, Republic of',
1037: 'GF' => 'French Guiana',
1038: 'GH' => 'Ghana',
1039: 'GI' => 'Gibraltar',
1040: 'GL' => 'Greenland',
1041: 'GM' => 'Gambia',
1042: 'GN' => 'Guinea',
1043: 'GP' => 'Guadeloupe',
1044: 'GQ' => 'Equatorial Guinea',
1045: 'GR' => 'Greece',
1046: 'GS' => 'South Georgia (Falkland Islands)',
1047: 'GT' => 'Guatemala',
1048: 'GW' => 'Guinea-Bissau',
1049: 'GY' => 'Guyana',
1050: 'HK' => 'Hong Kong',
1051: 'HN' => 'Honduras',
1052: 'HR' => 'Croatia',
1053: 'HT' => 'Haiti',
1054: 'HU' => 'Hungary',
1055: 'ID' => 'Indonesia',
1056: 'IE' => 'Ireland',
1057: 'IL' => 'Israel',
1058: 'IN' => 'India',
1059: 'IQ' => 'Iraq',
1060: 'IR' => 'Iran',
1061: 'IS' => 'Iceland',
1062: 'IT' => 'Italy',
1063: 'JM' => 'Jamaica',
1064: 'JO' => 'Jordan',
1065: 'JP' => 'Japan',
1066: 'KE' => 'Kenya',
1067: 'KG' => 'Kyrgyzstan',
1068: 'KH' => 'Cambodia',
1069: 'KI' => 'Kiribati',
1070: 'KM' => 'Comoros',
1071: 'KN' => 'Saint Kitts (St. Christopher and Nevis)',
1072: 'KP' => 'North Korea (Korea, Democratic People\'s Republic of)',
1073: 'KR' => 'South Korea (Korea, Republic of)',
1074: 'KW' => 'Kuwait',
1075: 'KY' => 'Cayman Islands',
1076: 'KZ' => 'Kazakhstan',
1077: 'LA' => 'Laos',
1078: 'LB' => 'Lebanon',
1079: 'LC' => 'Saint Lucia',
1080: 'LI' => 'Liechtenstein',
1081: 'LK' => 'Sri Lanka',
1082: 'LR' => 'Liberia',
1083: 'LS' => 'Lesotho',
1084: 'LT' => 'Lithuania',
1085: 'LU' => 'Luxembourg',
1086: 'LV' => 'Latvia',
1087: 'LY' => 'Libya',
1088: 'MA' => 'Morocco',
1089: 'MC' => 'Monaco (France)',
1090: 'MD' => 'Moldova',
1091: 'MG' => 'Madagascar',
1092: 'MK' => 'Macedonia, Republic of',
1093: 'ML' => 'Mali',
1094: 'MM' => 'Burma',
1095: 'MN' => 'Mongolia',
1096: 'MO' => 'Macao',
1097: 'MQ' => 'Martinique',
1098: 'MR' => 'Mauritania',
1099: 'MS' => 'Montserrat',
1100: 'MT' => 'Malta',
1101: 'MU' => 'Mauritius',
1102: 'MV' => 'Maldives',
1103: 'MW' => 'Malawi',
1104: 'MX' => 'Mexico',
1105: 'MY' => 'Malaysia',
1106: 'MZ' => 'Mozambique',
1107: 'NA' => 'Namibia',
1108: 'NC' => 'New Caledonia',
1109: 'NE' => 'Niger',
1110: 'NG' => 'Nigeria',
1111: 'NI' => 'Nicaragua',
1112: 'NL' => 'Netherlands',
1113: 'NO' => 'Norway',
1114: 'NP' => 'Nepal',
1115: 'NR' => 'Nauru',
1116: 'NZ' => 'New Zealand',
1117: 'OM' => 'Oman',
1118: 'PA' => 'Panama',
1119: 'PE' => 'Peru',
1120: 'PF' => 'French Polynesia',
1121: 'PG' => 'Papua New Guinea',
1122: 'PH' => 'Philippines',
1123: 'PK' => 'Pakistan',
1124: 'PL' => 'Poland',
1125: 'PM' => 'Saint Pierre and Miquelon',
1126: 'PN' => 'Pitcairn Island',
1127: 'PT' => 'Portugal',
1128: 'PY' => 'Paraguay',
1129: 'QA' => 'Qatar',
1130: 'RE' => 'Reunion',
1131: 'RO' => 'Romania',
1132: 'RS' => 'Serbia',
1133: 'RU' => 'Russia',
1134: 'RW' => 'Rwanda',
1135: 'SA' => 'Saudi Arabia',
1136: 'SB' => 'Solomon Islands',
1137: 'SC' => 'Seychelles',
1138: 'SD' => 'Sudan',
1139: 'SE' => 'Sweden',
1140: 'SG' => 'Singapore',
1141: 'SH' => 'Saint Helena',
1142: 'SI' => 'Slovenia',
1143: 'SK' => 'Slovak Republic',
1144: 'SL' => 'Sierra Leone',
1145: 'SM' => 'San Marino',
1146: 'SN' => 'Senegal',
1147: 'SO' => 'Somalia',
1148: 'SR' => 'Suriname',
1149: 'ST' => 'Sao Tome and Principe',
1150: 'SV' => 'El Salvador',
1151: 'SY' => 'Syrian Arab Republic',
1152: 'SZ' => 'Swaziland',
1153: 'TC' => 'Turks and Caicos Islands',
1154: 'TD' => 'Chad',
1155: 'TG' => 'Togo',
1156: 'TH' => 'Thailand',
1157: 'TJ' => 'Tajikistan',
1158: 'TK' => 'Tokelau (Union) Group (Western Samoa)',
1159: 'TL' => 'East Timor (Indonesia)',
1160: 'TM' => 'Turkmenistan',
1161: 'TN' => 'Tunisia',
1162: 'TO' => 'Tonga',
1163: 'TR' => 'Turkey',
1164: 'TT' => 'Trinidad and Tobago',
1165: 'TV' => 'Tuvalu',
1166: 'TW' => 'Taiwan',
1167: 'TZ' => 'Tanzania',
1168: 'UA' => 'Ukraine',
1169: 'UG' => 'Uganda',
1170: 'UY' => 'Uruguay',
1171: 'UZ' => 'Uzbekistan',
1172: 'VA' => 'Vatican City',
1173: 'VC' => 'Saint Vincent and the Grenadines',
1174: 'VE' => 'Venezuela',
1175: 'VG' => 'British Virgin Islands',
1176: 'VN' => 'Vietnam',
1177: 'VU' => 'Vanuatu',
1178: 'WF' => 'Wallis and Futuna Islands',
1179: 'WS' => 'Western Samoa',
1180: 'YE' => 'Yemen',
1181: 'YT' => 'Mayotte (France)',
1182: 'ZA' => 'South Africa',
1183: 'ZM' => 'Zambia',
1184: 'ZW' => 'Zimbabwe',
1185: 'US' => 'United States',
1186: );
1187:
1188: if (isset($countries[$countryId])) {
1189: return $countries[$countryId];
1190: }
1191:
1192: return false;
1193: }
1194:
1195: 1196: 1197: 1198: 1199: 1200:
1201: protected function _filterServiceName($name)
1202: {
1203: $name = (string)preg_replace(array('~<[^/!][^>]+>.*</[^>]+>~sU', '~\<!--.*--\>~isU', '~<[^>]+>~is'), '',
1204: html_entity_decode($name)
1205: );
1206: $name = str_replace('*', '', $name);
1207:
1208: return $name;
1209: }
1210:
1211: 1212: 1213: 1214: 1215: 1216: 1217: 1218:
1219: protected function _formUsExpressShipmentRequest(Varien_Object $request)
1220: {
1221: $packageParams = $request->getPackageParams();
1222:
1223: $packageWeight = $request->getPackageWeight();
1224: if ($packageParams->getWeightUnits() != Zend_Measure_Weight::OUNCE) {
1225: $packageWeight = round(Mage::helper('usa')->convertMeasureWeight(
1226: $request->getPackageWeight(),
1227: $packageParams->getWeightUnits(),
1228: Zend_Measure_Weight::OUNCE
1229: ));
1230: }
1231:
1232: list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1233: list($toZip5, $toZip4) = $this->_parseZip($request->getRecipientAddressPostalCode(), true);
1234:
1235: $rootNode = 'ExpressMailLabelRequest';
1236:
1237: $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1238: $xml = $xmlWrap->addChild($rootNode);
1239: $xml->addAttribute('USERID', $this->getConfigData('userid'));
1240: $xml->addAttribute('PASSWORD', $this->getConfigData('password'));
1241: $xml->addChild('Option');
1242: $xml->addChild('Revision');
1243: $xml->addChild('EMCAAccount');
1244: $xml->addChild('EMCAPassword');
1245: $xml->addChild('ImageParameters');
1246: $xml->addChild('FromFirstName', $request->getShipperContactPersonFirstName());
1247: $xml->addChild('FromLastName', $request->getShipperContactPersonLastName());
1248: $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1249: $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1250: $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1251: $xml->addChild('FromCity', $request->getShipperAddressCity());
1252: $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1253: $xml->addChild('FromZip5', $fromZip5);
1254: $xml->addChild('FromZip4', $fromZip4);
1255: $xml->addChild('FromPhone', $request->getShipperContactPhoneNumber());
1256: $xml->addChild('ToFirstName', $request->getRecipientContactPersonFirstName());
1257: $xml->addChild('ToLastName', $request->getRecipientContactPersonLastName());
1258: $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1259: $xml->addChild('ToAddress1', $request->getRecipientAddressStreet2());
1260: $xml->addChild('ToAddress2', $request->getRecipientAddressStreet1());
1261: $xml->addChild('ToCity', $request->getRecipientAddressCity());
1262: $xml->addChild('ToState', $request->getRecipientAddressStateOrProvinceCode());
1263: $xml->addChild('ToZip5', $toZip5);
1264: $xml->addChild('ToZip4', $toZip4);
1265: $xml->addChild('ToPhone', $request->getRecipientContactPhoneNumber());
1266: $xml->addChild('WeightInOunces', $packageWeight);
1267: $xml->addChild('WaiverOfSignature', $packageParams->getDeliveryConfirmation());
1268: $xml->addChild('POZipCode');
1269: $xml->addChild('ImageType', 'PDF');
1270:
1271: $xml = $xmlWrap->{$rootNode}->asXML();
1272: return $xml;
1273: }
1274:
1275: 1276: 1277: 1278: 1279: 1280: 1281: 1282: 1283:
1284: protected function _formUsSignatureConfirmationShipmentRequest(Varien_Object $request, $serviceType)
1285: {
1286: switch ($serviceType) {
1287: case 'PRIORITY':
1288: $serviceType = 'Priority';
1289: break;
1290: case 'FIRST CLASS':
1291: $serviceType = 'First Class';
1292: break;
1293: case 'PARCEL':
1294: $serviceType = 'Parcel Post';
1295: break;
1296: case 'MEDIA':
1297: $serviceType = 'Media Mail';
1298: break;
1299: case 'LIBRARY':
1300: $serviceType = 'Library Mail';
1301: break;
1302: default:
1303: throw new Exception(Mage::helper('usa')->__('Service type does not match'));
1304: }
1305: $packageParams = $request->getPackageParams();
1306: $packageWeight = $request->getPackageWeight();
1307: if ($packageParams->getWeightUnits() != Zend_Measure_Weight::OUNCE) {
1308: $packageWeight = round(Mage::helper('usa')->convertMeasureWeight(
1309: $request->getPackageWeight(),
1310: $packageParams->getWeightUnits(),
1311: Zend_Measure_Weight::OUNCE
1312: ));
1313: }
1314:
1315: list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1316: list($toZip5, $toZip4) = $this->_parseZip($request->getRecipientAddressPostalCode(), true);
1317:
1318: if ($this->getConfigData('mode')) {
1319: $rootNode = 'SignatureConfirmationV3.0Request';
1320: } else {
1321: $rootNode = 'SigConfirmCertifyV3.0Request';
1322: }
1323:
1324: $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1325: $xml = $xmlWrap->addChild($rootNode);
1326: $xml->addAttribute('USERID', $this->getConfigData('userid'));
1327: $xml->addChild('Option', 1);
1328: $xml->addChild('ImageParameters');
1329: $xml->addChild('FromName', $request->getShipperContactPersonName());
1330: $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1331: $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1332: $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1333: $xml->addChild('FromCity', $request->getShipperAddressCity());
1334: $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1335: $xml->addChild('FromZip5', $fromZip5);
1336: $xml->addChild('FromZip4', $fromZip4);
1337: $xml->addChild('ToName', $request->getRecipientContactPersonName());
1338: $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1339: $xml->addChild('ToAddress1', $request->getRecipientAddressStreet2());
1340: $xml->addChild('ToAddress2', $request->getRecipientAddressStreet1());
1341: $xml->addChild('ToCity', $request->getRecipientAddressCity());
1342: $xml->addChild('ToState', $request->getRecipientAddressStateOrProvinceCode());
1343: $xml->addChild('ToZip5', $toZip5);
1344: $xml->addChild('ToZip4', $toZip4);
1345: $xml->addChild('WeightInOunces', $packageWeight);
1346: $xml->addChild('ServiceType', $serviceType);
1347: $xml->addChild('WaiverOfSignature', $packageParams->getDeliveryConfirmation());
1348: $xml->addChild('ImageType', 'PDF');
1349:
1350: $xml = $xmlWrap->{$rootNode}->asXML();
1351: return $xml;
1352: }
1353:
1354: 1355: 1356: 1357: 1358: 1359:
1360: protected function _convertPoundOunces($weightInPounds)
1361: {
1362: $weightInOunces = ceil($weightInPounds * self::OUNCES_POUND);
1363: $pounds = floor($weightInOunces / self::OUNCES_POUND);
1364: $ounces = $weightInOunces % self::OUNCES_POUND;
1365: return array($pounds, $ounces);
1366: }
1367:
1368: 1369: 1370: 1371: 1372: 1373: 1374: 1375:
1376: protected function _formIntlShipmentRequest(Varien_Object $request)
1377: {
1378: $packageParams = $request->getPackageParams();
1379: $height = $packageParams->getHeight();
1380: $width = $packageParams->getWidth();
1381: $length = $packageParams->getLength();
1382: $girth = $packageParams->getGirth();
1383: $packageWeight = $request->getPackageWeight();
1384: if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
1385: $packageWeight = Mage::helper('usa')->convertMeasureWeight(
1386: $request->getPackageWeight(),
1387: $packageParams->getWeightUnits(),
1388: Zend_Measure_Weight::POUND
1389: );
1390: }
1391: if ($packageParams->getDimensionUnits() != Zend_Measure_Length::INCH) {
1392: $length = round(Mage::helper('usa')->convertMeasureDimension(
1393: $packageParams->getLength(),
1394: $packageParams->getDimensionUnits(),
1395: Zend_Measure_Length::INCH
1396: ));
1397: $width = round(Mage::helper('usa')->convertMeasureDimension(
1398: $packageParams->getWidth(),
1399: $packageParams->getDimensionUnits(),
1400: Zend_Measure_Length::INCH
1401: ));
1402: $height = round(Mage::helper('usa')->convertMeasureDimension(
1403: $packageParams->getHeight(),
1404: $packageParams->getDimensionUnits(),
1405: Zend_Measure_Length::INCH
1406: ));
1407: }
1408: if ($packageParams->getGirthDimensionUnits() != Zend_Measure_Length::INCH) {
1409: $girth = round(Mage::helper('usa')->convertMeasureDimension(
1410: $packageParams->getGirth(),
1411: $packageParams->getGirthDimensionUnits(),
1412: Zend_Measure_Length::INCH
1413: ));
1414: }
1415:
1416: $container = $request->getPackagingType();
1417: switch ($container) {
1418: case 'VARIABLE':
1419: $container = 'VARIABLE';
1420: break;
1421: case 'FLAT RATE ENVELOPE':
1422: $container = 'FLATRATEENV';
1423: break;
1424: case 'FLAT RATE BOX':
1425: $container = 'FLATRATEBOX';
1426: break;
1427: case 'RECTANGULAR':
1428: $container = 'RECTANGULAR';
1429: break;
1430: case 'NONRECTANGULAR':
1431: $container = 'NONRECTANGULAR';
1432: break;
1433: default:
1434: $container = 'VARIABLE';
1435: }
1436: $shippingMethod = $request->getShippingMethod();
1437: list($fromZip5, $fromZip4) = $this->_parseZip($request->getShipperAddressPostalCode());
1438:
1439:
1440: $xmlWrap = new SimpleXMLElement('<?xml version = "1.0" encoding = "UTF-8"?><wrap/>');
1441: $method = '';
1442: if (stripos($shippingMethod, 'Priority') !== false) {
1443: $method = 'Priority';
1444: $rootNode = 'PriorityMailIntlRequest';
1445: $xml = $xmlWrap->addChild($rootNode);
1446: } else if (stripos($shippingMethod, 'First-Class') !== false) {
1447: $method = 'FirstClass';
1448: $rootNode = 'FirstClassMailIntlRequest';
1449: $xml = $xmlWrap->addChild($rootNode);
1450: } else {
1451: $method = 'Express';
1452: $rootNode = 'ExpressMailIntlRequest';
1453: $xml = $xmlWrap->addChild($rootNode);
1454: }
1455:
1456: $xml->addAttribute('USERID', $this->getConfigData('userid'));
1457: $xml->addAttribute('PASSWORD', $this->getConfigData('password'));
1458: $xml->addChild('Option');
1459: $xml->addChild('Revision', self::DEFAULT_REVISION);
1460: $xml->addChild('ImageParameters');
1461: $xml->addChild('FromFirstName', $request->getShipperContactPersonFirstName());
1462: $xml->addChild('FromLastName', $request->getShipperContactPersonLastName());
1463: $xml->addChild('FromFirm', $request->getShipperContactCompanyName());
1464: $xml->addChild('FromAddress1', $request->getShipperAddressStreet2());
1465: $xml->addChild('FromAddress2', $request->getShipperAddressStreet1());
1466: $xml->addChild('FromCity', $request->getShipperAddressCity());
1467: $xml->addChild('FromState', $request->getShipperAddressStateOrProvinceCode());
1468: $xml->addChild('FromZip5', $fromZip5);
1469: $xml->addChild('FromZip4', $fromZip4);
1470: $xml->addChild('FromPhone', $request->getShipperContactPhoneNumber());
1471: if ($method != 'FirstClass') {
1472: if ($request->getReferenceData()) {
1473: $referenceData = $request->getReferenceData() . ' P' . $request->getPackageId();
1474: } else {
1475: $referenceData = $request->getOrderShipment()->getOrder()->getIncrementId()
1476: . ' P'
1477: . $request->getPackageId();
1478: }
1479: $xml->addChild('FromCustomsReference', 'Order #' . $referenceData);
1480: }
1481: $xml->addChild('ToName', $request->getRecipientContactPersonName());
1482: $xml->addChild('ToFirm', $request->getRecipientContactCompanyName());
1483: $xml->addChild('ToAddress1', $request->getRecipientAddressStreet1());
1484: $xml->addChild('ToAddress2', $request->getRecipientAddressStreet2());
1485: $xml->addChild('ToCity', $request->getRecipientAddressCity());
1486: $xml->addChild('ToProvince', $request->getRecipientAddressStateOrProvinceCode());
1487: $xml->addChild('ToCountry', $this->_getCountryName($request->getRecipientAddressCountryCode()));
1488: $xml->addChild('ToPostalCode', $request->getRecipientAddressPostalCode());
1489: $xml->addChild('ToPOBoxFlag', 'N');
1490: $xml->addChild('ToPhone', $request->getRecipientContactPhoneNumber());
1491: $xml->addChild('ToFax');
1492: $xml->addChild('ToEmail');
1493: if ($method != 'FirstClass') {
1494: $xml->addChild('NonDeliveryOption', 'Return');
1495: }
1496: if ($method == 'FirstClass') {
1497: if (stripos($shippingMethod, 'Letter') !== false) {
1498: $xml->addChild('FirstClassMailType', 'LETTER');
1499: } else if (stripos($shippingMethod, 'Flat') !== false) {
1500: $xml->addChild('FirstClassMailType', 'FLAT');
1501: } else{
1502: $xml->addChild('FirstClassMailType', 'PARCEL');
1503: }
1504: }
1505: if ($method != 'FirstClass') {
1506: $xml->addChild('Container', $container);
1507: }
1508: $shippingContents = $xml->addChild('ShippingContents');
1509: $packageItems = $request->getPackageItems();
1510:
1511: $countriesOfManufacture = array();
1512: $productIds = array();
1513: foreach ($packageItems as $itemShipment) {
1514: $item = new Varien_Object();
1515: $item->setData($itemShipment);
1516:
1517: $productIds[]= $item->getProductId();
1518: }
1519: $productCollection = Mage::getResourceModel('catalog/product_collection')
1520: ->addStoreFilter($request->getStoreId())
1521: ->addFieldToFilter('entity_id', array('in' => $productIds))
1522: ->addAttributeToSelect('country_of_manufacture');
1523: foreach ($productCollection as $product) {
1524: $countriesOfManufacture[$product->getId()] = $product->getCountryOfManufacture();
1525: }
1526:
1527: $packagePoundsWeight = $packageOuncesWeight = 0;
1528:
1529: foreach ($packageItems as $itemShipment) {
1530: $item = new Varien_Object();
1531: $item->setData($itemShipment);
1532:
1533: $itemWeight = $item->getWeight() * $item->getQty();
1534: if ($packageParams->getWeightUnits() != Zend_Measure_Weight::POUND) {
1535: $itemWeight = Mage::helper('usa')->convertMeasureWeight(
1536: $itemWeight,
1537: $packageParams->getWeightUnits(),
1538: Zend_Measure_Weight::POUND
1539: );
1540: }
1541: if (!empty($countriesOfManufacture[$item->getProductId()])) {
1542: $countryOfManufacture = $this->_getCountryName(
1543: $countriesOfManufacture[$item->getProductId()]
1544: );
1545: } else {
1546: $countryOfManufacture = '';
1547: }
1548: $itemDetail = $shippingContents->addChild('ItemDetail');
1549: $itemDetail->addChild('Description', $item->getName());
1550: $ceiledQty = ceil($item->getQty());
1551: if ($ceiledQty < 1) {
1552: $ceiledQty = 1;
1553: }
1554: $individualItemWeight = $itemWeight / $ceiledQty;
1555: $itemDetail->addChild('Quantity', $ceiledQty);
1556: $itemDetail->addChild('Value', $item->getCustomsValue() * $item->getQty());
1557: list($individualPoundsWeight, $individualOuncesWeight) = $this->_convertPoundOunces($individualItemWeight);
1558: $itemDetail->addChild('NetPounds', $individualPoundsWeight);
1559: $itemDetail->addChild('NetOunces', $individualOuncesWeight);
1560: $itemDetail->addChild('HSTariffNumber', 0);
1561: $itemDetail->addChild('CountryOfOrigin', $countryOfManufacture);
1562:
1563: list($itemPoundsWeight, $itemOuncesWeight) = $this->_convertPoundOunces($itemWeight);
1564: $packagePoundsWeight += $itemPoundsWeight;
1565: $packageOuncesWeight += $itemOuncesWeight;
1566: }
1567: $additionalPackagePoundsWeight = floor($packageOuncesWeight / self::OUNCES_POUND);
1568: $packagePoundsWeight += $additionalPackagePoundsWeight;
1569: $packageOuncesWeight -= $additionalPackagePoundsWeight * self::OUNCES_POUND;
1570: if ($packagePoundsWeight + $packageOuncesWeight / self::OUNCES_POUND < $packageWeight) {
1571: list($packagePoundsWeight, $packageOuncesWeight) = $this->_convertPoundOunces($packageWeight);
1572: }
1573:
1574: $xml->addChild('GrossPounds', $packagePoundsWeight);
1575: $xml->addChild('GrossOunces', $packageOuncesWeight);
1576: if ($packageParams->getContentType() == 'OTHER' && $packageParams->getContentTypeOther() != null) {
1577: $xml->addChild('ContentType', $packageParams->getContentType());
1578: $xml->addChild('ContentTypeOther ', $packageParams->getContentTypeOther());
1579: } else {
1580: $xml->addChild('ContentType', $packageParams->getContentType());
1581: }
1582:
1583: $xml->addChild('Agreement', 'y');
1584: $xml->addChild('ImageType', 'PDF');
1585: $xml->addChild('ImageLayout', 'ALLINONEFILE');
1586: if ($method == 'FirstClass') {
1587: $xml->addChild('Container', $container);
1588: }
1589:
1590: if ($packageParams->getSize()) {
1591: $xml->addChild('Size', $packageParams->getSize());
1592: }
1593:
1594: $xml->addChild('Length', $length);
1595: $xml->addChild('Width', $width);
1596: $xml->addChild('Height', $height);
1597: if ($girth) {
1598: $xml->addChild('Girth', $girth);
1599: }
1600:
1601: $xml = $xmlWrap->{$rootNode}->asXML();
1602: return $xml;
1603: }
1604:
1605: 1606: 1607: 1608: 1609: 1610:
1611: protected function _doShipmentRequest(Varien_Object $request)
1612: {
1613: $this->_prepareShipmentRequest($request);
1614: $result = new Varien_Object();
1615: $service = $this->getCode('service_to_code', $request->getShippingMethod());
1616: $recipientUSCountry = $this->_isUSCountry($request->getRecipientAddressCountryCode());
1617:
1618: if ($recipientUSCountry && $service == 'EXPRESS') {
1619: $requestXml = $this->_formUsExpressShipmentRequest($request);
1620: $api = 'ExpressMailLabel';
1621: } else if ($recipientUSCountry) {
1622: $requestXml = $this->_formUsSignatureConfirmationShipmentRequest($request, $service);
1623: if ($this->getConfigData('mode')) {
1624: $api = 'SignatureConfirmationV3';
1625: } else {
1626: $api = 'SignatureConfirmationCertifyV3';
1627: }
1628: } else if ($service == 'FIRST CLASS') {
1629: $requestXml = $this->_formIntlShipmentRequest($request);
1630: $api = 'FirstClassMailIntl';
1631: } else if ($service == 'PRIORITY') {
1632: $requestXml = $this->_formIntlShipmentRequest($request);
1633: $api = 'PriorityMailIntl';
1634: } else {
1635: $requestXml = $this->_formIntlShipmentRequest($request);
1636: $api = 'ExpressMailIntl';
1637: }
1638:
1639: $debugData = array('request' => $requestXml);
1640: $url = $this->getConfigData('gateway_secure_url');
1641: if (!$url) {
1642: $url = $this->_defaultGatewayUrl;
1643: }
1644: $client = new Zend_Http_Client();
1645: $client->setUri($url);
1646: $client->setConfig(array('maxredirects'=>0, 'timeout'=>30));
1647: $client->setParameterGet('API', $api);
1648: $client->setParameterGet('XML', $requestXml);
1649: $response = $client->request()->getBody();
1650:
1651: $response = simplexml_load_string($response);
1652: if ($response === false || $response->getName() == 'Error') {
1653: $debugData['result'] = array(
1654: 'error' => $response->Description,
1655: 'code' => $response->Number,
1656: 'xml' => $response->asXML()
1657: );
1658: $this->_debug($debugData);
1659: $result->setErrors($debugData['result']['error']);
1660: } else {
1661: if ($recipientUSCountry && $service == 'EXPRESS') {
1662: $labelContent = base64_decode((string) $response->EMLabel);
1663: $trackingNumber = (string) $response->EMConfirmationNumber;
1664: } else if ($recipientUSCountry) {
1665: $labelContent = base64_decode((string) $response->SignatureConfirmationLabel);
1666: $trackingNumber = (string) $response->SignatureConfirmationNumber;
1667: } else {
1668: $labelContent = base64_decode((string) $response->LabelImage);
1669: $trackingNumber = (string) $response->BarcodeNumber;
1670: }
1671: $result->setShippingLabelContent($labelContent);
1672: $result->setTrackingNumber($trackingNumber);
1673: }
1674:
1675: $result->setGatewayResponse($response);
1676: $debugData['result'] = $response;
1677: $this->_debug($debugData);
1678: return $result;
1679: }
1680:
1681: 1682: 1683: 1684: 1685: 1686:
1687: public function getContainerTypes(Varien_Object $params = null)
1688: {
1689: if (is_null($params)) {
1690: return $this->_getAllowedContainers();
1691: }
1692: return $this->_isUSCountry($params->getCountryRecipient()) ? array() : $this->_getAllowedContainers($params);
1693: }
1694:
1695: 1696: 1697: 1698: 1699:
1700: public function getContainerTypesAll()
1701: {
1702: return $this->getCode('container');
1703: }
1704:
1705: 1706: 1707: 1708: 1709:
1710: public function getContainerTypesFilter()
1711: {
1712: return $this->getCode('containers_filter');
1713: }
1714:
1715: 1716: 1717: 1718: 1719: 1720:
1721: public function getDeliveryConfirmationTypes(Varien_Object $params = null)
1722: {
1723: if ($params == null) {
1724: return array();
1725: }
1726: $countryRecipient = $params->getCountryRecipient();
1727: if ($this->_isUSCountry($countryRecipient)) {
1728: return $this->getCode('delivery_confirmation_types');
1729: } else {
1730: return array();
1731: }
1732: }
1733:
1734: 1735: 1736: 1737: 1738: 1739:
1740: public function isGirthAllowed($countyDest = null)
1741: {
1742: return $this->_isUSCountry($countyDest) ? false : true;
1743: }
1744:
1745: 1746: 1747: 1748: 1749: 1750:
1751: public function getContentTypes(Varien_Object $params)
1752: {
1753: $countryShipper = $params->getCountryShipper();
1754: $countryRecipient = $params->getCountryRecipient();
1755:
1756: if ($countryShipper == self::USA_COUNTRY_ID
1757: && $countryRecipient != self::USA_COUNTRY_ID
1758: ) {
1759: return array(
1760: 'MERCHANDISE' => Mage::helper('usa')->__('Merchandise'),
1761: 'SAMPLE' => Mage::helper('usa')->__('Sample'),
1762: 'GIFT' => Mage::helper('usa')->__('Gift'),
1763: 'DOCUMENTS' => Mage::helper('usa')->__('Documents'),
1764: 'RETURN' => Mage::helper('usa')->__('Return'),
1765: 'OTHER' => Mage::helper('usa')->__('Other'),
1766: );
1767: }
1768: return array();
1769: }
1770:
1771: 1772: 1773: 1774: 1775: 1776: 1777:
1778: protected function _parseZip($zipString, $returnFull = false)
1779: {
1780: $zip4 = '';
1781: $zip5 = '';
1782: $zip = array($zipString);
1783: if (preg_match('/[\\d\\w]{5}\\-[\\d\\w]{4}/', $zipString) != 0) {
1784: $zip = explode('-', $zipString);
1785: }
1786: for ($i = 0; $i < count($zip); ++$i) {
1787: if (strlen($zip[$i]) == 5) {
1788: $zip5 = $zip[$i];
1789: } elseif (strlen($zip[$i]) == 4) {
1790: $zip4 = $zip[$i];
1791: }
1792: }
1793: if (empty($zip5) && empty($zip4) && $returnFull) {
1794: $zip5 = $zipString;
1795: }
1796:
1797: return array($zip5, $zip4);
1798: }
1799: }
1800: