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: class Mage_Usa_Model_Shipping_Carrier_Dhl_International
35: extends Mage_Usa_Model_Shipping_Carrier_Abstract
36: implements Mage_Shipping_Model_Carrier_Interface
37: {
38: 39: 40:
41: const DHL_CONTENT_TYPE_DOC = 'D';
42: const DHL_CONTENT_TYPE_NON_DOC = 'N';
43:
44: 45: 46:
47: const DIMENSION_MIN_CM = 3;
48: const DIMENSION_MIN_IN = 1;
49:
50: 51: 52: 53: 54:
55: protected $_customizableContainerTypes = array(self::DHL_CONTENT_TYPE_NON_DOC);
56:
57: 58: 59:
60: const CODE = 'dhlint';
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 $_countryParams = null;
89:
90: 91: 92: 93: 94:
95: protected $_errors = array();
96:
97: 98: 99: 100: 101:
102: protected $_rates = array();
103:
104: 105: 106: 107: 108:
109: protected $_code = self::CODE;
110:
111: 112: 113: 114: 115:
116: protected $_freeMethod = 'free_method_nondoc';
117:
118: 119: 120: 121: 122:
123: protected $_maxWeight = 70;
124:
125: 126: 127: 128: 129:
130: protected $_isShippingLabelFlag = false;
131:
132: 133: 134: 135: 136:
137: protected $_requestVariables = array(
138: 'id' => array('code' => 'dhl_id', 'setCode' => 'id'),
139: 'password' => array('code' => 'dhl_password', 'setCode' => 'password'),
140: 'account' => array('code' => 'dhl_account', 'setCode' => 'account_nbr'),
141: 'shipping_key' => array('code' => 'dhl_shipping_key', 'setCode' => 'shipping_key'),
142: 'shipping_intlkey' => array('code' => 'dhl_shipping_intl_key', 'setCode' => 'shipping_intl_key'),
143: 'shipment_type' => array('code' => 'dhl_shipment_type', 'setCode' => 'shipment_type'),
144: 'dutiable' => array('code' => 'dhl_dutiable', 'setCode' => 'dutiable'),
145: 'dutypaymenttype' => array('code' => 'dhl_duty_payment_type', 'setCode' => 'duty_payment_type'),
146: 'contentdesc' => array('code' => 'dhl_content_desc', 'setCode' => 'content_desc')
147: );
148:
149: 150: 151: 152: 153:
154: protected $_isDomestic = false;
155:
156: 157: 158: 159: 160:
161: protected function _construct()
162: {
163: if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_DOC) {
164: $this->_freeMethod = 'free_method_doc';
165: }
166: }
167:
168: 169: 170: 171: 172: 173: 174:
175: protected function _getDefaultValue($origValue, $pathToValue)
176: {
177: if (!$origValue) {
178: $origValue = Mage::getStoreConfig(
179: $pathToValue,
180: $this->getStore()
181: );
182: }
183:
184: return $origValue;
185: }
186:
187: 188: 189: 190: 191: 192:
193: public function collectRates(Mage_Shipping_Model_Rate_Request $request)
194: {
195: if (!$this->getConfigFlag($this->_activeFlag)) {
196: return false;
197: }
198:
199: $requestDhl = clone $request;
200: $this->setStore($requestDhl->getStoreId());
201:
202: $origCompanyName = $this->_getDefaultValue(
203: $requestDhl->getOrigCompanyName(),
204: Mage_Core_Model_Store::XML_PATH_STORE_STORE_NAME
205: );
206: $origCountryId = $this->_getDefaultValue(
207: $requestDhl->getOrigCountryId(),
208: Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID
209: );
210: $origState = $this->_getDefaultValue(
211: $requestDhl->getOrigState(),
212: Mage_Shipping_Model_Shipping::XML_PATH_STORE_REGION_ID
213: );
214: $origCity = $this->_getDefaultValue(
215: $requestDhl->getOrigCity(),
216: Mage_Shipping_Model_Shipping::XML_PATH_STORE_CITY
217: );
218: $origPostcode = $this->_getDefaultValue(
219: $requestDhl->getOrigPostcode(),
220: Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP
221: );
222:
223: $requestDhl->setOrigCompanyName($origCompanyName)
224: ->setCountryId($origCountryId)
225: ->setOrigState($origState)
226: ->setOrigCity($origCity)
227: ->setOrigPostal($origPostcode);
228: $this->setRequest($requestDhl);
229:
230: $this->_result = $this->_getQuotes();
231:
232: $this->_updateFreeMethodQuote($request);
233:
234: return $this->_result;
235: }
236:
237: 238: 239: 240: 241: 242:
243: protected function _setFreeMethodRequest($freeMethod)
244: {
245: $rawRequest = $this->_rawRequest;
246:
247: $rawRequest->setFreeMethodRequest(true);
248: $freeWeight = $this->getTotalNumOfBoxes($rawRequest->getFreeMethodWeight());
249: $rawRequest->setWeight($freeWeight);
250: $rawRequest->setService($freeMethod);
251: }
252:
253: 254: 255: 256: 257:
258: public function getResult()
259: {
260: return $this->_result;
261: }
262:
263: protected function _addParams($requestObject)
264: {
265: $request = $this->_request;
266: foreach ($this->_requestVariables as $code => $objectCode) {
267: if ($request->getDhlId()) {
268: $value = $request->getData($objectCode['code']);
269: } else {
270: $value = $this->getConfigData($code);
271: }
272: $requestObject->setData($objectCode['setCode'], $value);
273: }
274: return $requestObject;
275: }
276:
277: 278: 279: 280: 281: 282:
283: public function setRequest(Varien_Object $request)
284: {
285: $this->_request = $request;
286: $this->setStore($request->getStoreId());
287:
288: $requestObject = new Varien_Object();
289:
290: $requestObject->setIsGenerateLabelReturn($request->getIsGenerateLabelReturn());
291:
292: $requestObject->setStoreId($request->getStoreId());
293:
294: if ($request->getLimitMethod()) {
295: $requestObject->setService($request->getLimitMethod());
296: }
297:
298: $requestObject = $this->_addParams($requestObject);
299:
300: if ($request->getDestPostcode()) {
301: $requestObject->setDestPostal($request->getDestPostcode());
302: }
303:
304: $requestObject->setOrigCountry(
305: $this->_getDefaultValue(
306: $request->getOrigCountry(), Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID)
307: )
308: ->setOrigCountryId(
309: $this->_getDefaultValue(
310: $request->getOrigCountryId(), Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID)
311: );
312:
313: $shippingWeight = $request->getPackageWeight();
314:
315: $requestObject->setValue(round($request->getPackageValue(), 2))
316: ->setValueWithDiscount($request->getPackageValueWithDiscount())
317: ->setCustomsValue($request->getPackageCustomsValue())
318: ->setDestStreet(
319: Mage::helper('core/string')->substr(str_replace("\n", '', $request->getDestStreet()), 0, 35))
320: ->setDestStreetLine2($request->getDestStreetLine2())
321: ->setDestCity($request->getDestCity())
322: ->setOrigCompanyName($request->getOrigCompanyName())
323: ->setOrigCity($request->getOrigCity())
324: ->setOrigPhoneNumber($request->getOrigPhoneNumber())
325: ->setOrigPersonName($request->getOrigPersonName())
326: ->setOrigEmail(Mage::getStoreConfig('trans_email/ident_general/email', $requestObject->getStoreId()))
327: ->setOrigCity($request->getOrigCity())
328: ->setOrigPostal($request->getOrigPostal())
329: ->setOrigStreetLine2($request->getOrigStreetLine2())
330: ->setDestPhoneNumber($request->getDestPhoneNumber())
331: ->setDestPersonName($request->getDestPersonName())
332: ->setDestCompanyName($request->getDestCompanyName());
333:
334: $originStreet2 = Mage::getStoreConfig(
335: Mage_Shipping_Model_Shipping::XML_PATH_STORE_ADDRESS2, $requestObject->getStoreId());
336:
337: $requestObject->setOrigStreet($request->getOrigStreet() ? $request->getOrigStreet() : $originStreet2);
338:
339: if (is_numeric($request->getOrigState())) {
340: $requestObject->setOrigState(Mage::getModel('directory/region')->load($request->getOrigState())->getCode());
341: } else {
342: $requestObject->setOrigState($request->getOrigState());
343: }
344:
345: if ($request->getDestCountryId()) {
346: $destCountry = $request->getDestCountryId();
347: } else {
348: $destCountry = self::USA_COUNTRY_ID;
349: }
350:
351:
352:
353: if ($destCountry == self::USA_COUNTRY_ID && ($request->getDestPostcode() == '00912'
354: || $request->getDestRegionCode() == self::PUERTORICO_COUNTRY_ID)
355: ) {
356: $destCountry = self::PUERTORICO_COUNTRY_ID;
357: }
358:
359: $requestObject->setDestCountryId($destCountry)
360: ->setDestState($request->getDestRegionCode())
361: ->setWeight($shippingWeight)
362: ->setFreeMethodWeight($request->getFreeMethodWeight())
363: ->setOrderShipment($request->getOrderShipment());
364:
365: if ($request->getPackageId()) {
366: $requestObject->setPackageId($request->getPackageId());
367: }
368:
369: $requestObject->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
370:
371: $this->_rawRequest = $requestObject;
372: return $this;
373: }
374:
375: 376: 377: 378: 379:
380: public function getAllowedMethods()
381: {
382: $contentType = $this->getConfigData('content_type');
383: $allowedMethods = array();
384: if ($this->_isDomestic) {
385: $allowedMethods = array_merge(explode(',', $this->getConfigData('doc_methods')),
386: explode(',', $this->getConfigData('nondoc_methods'))
387: );
388: } else {
389: switch ($contentType) {
390: case self::DHL_CONTENT_TYPE_DOC:
391: $allowedMethods = explode(',', $this->getConfigData('doc_methods'));
392: break;
393: case self::DHL_CONTENT_TYPE_NON_DOC:
394: $allowedMethods = explode(',', $this->getConfigData('nondoc_methods'));
395: break;
396: default:
397: Mage::throwException(Mage::helper('usa')->__('Wrong Content Type.'));
398: }
399: }
400: $methods = array();
401: foreach ($allowedMethods as $method) {
402: $methods[$method] = $this->getDhlProductTitle($method);
403: }
404: return $methods;
405: }
406:
407: 408: 409: 410: 411: 412: 413:
414: public function getCode($type, $code = '')
415: {
416: $codes = array(
417: 'unit_of_measure' => array(
418: 'L' => Mage::helper('usa')->__('Pounds'),
419: 'K' => Mage::helper('usa')->__('Kilograms'),
420: ),
421: 'unit_of_dimension' => array(
422: 'I' => Mage::helper('usa')->__('Inches'),
423: 'C' => Mage::helper('usa')->__('Centimeters'),
424: ),
425: 'unit_of_dimension_cut' => array(
426: 'I' => Mage::helper('usa')->__('inch'),
427: 'C' => Mage::helper('usa')->__('cm'),
428: ),
429: 'dimensions' => array(
430: 'HEIGHT' => Mage::helper('usa')->__('Height'),
431: 'DEPTH' => Mage::helper('usa')->__('Depth'),
432: 'WIDTH' => Mage::helper('usa')->__('Width'),
433: ),
434: 'size' => array(
435: '0' => Mage::helper('usa')->__('Regular'),
436: '1' => Mage::helper('usa')->__('Specific'),
437: ),
438: 'dimensions_variables' => array(
439: 'L' => Zend_Measure_Weight::POUND,
440: 'LB' => Zend_Measure_Weight::POUND,
441: 'POUND' => Zend_Measure_Weight::POUND,
442: 'K' => Zend_Measure_Weight::KILOGRAM,
443: 'KG' => Zend_Measure_Weight::KILOGRAM,
444: 'KILOGRAM' => Zend_Measure_Weight::KILOGRAM,
445: 'I' => Zend_Measure_Length::INCH,
446: 'IN' => Zend_Measure_Length::INCH,
447: 'INCH' => Zend_Measure_Length::INCH,
448: 'C' => Zend_Measure_Length::CENTIMETER,
449: 'CM' => Zend_Measure_Length::CENTIMETER,
450: 'CENTIMETER'=> Zend_Measure_Length::CENTIMETER,
451:
452: )
453: );
454:
455: if (!isset($codes[$type])) {
456: return false;
457: } elseif ('' === $code) {
458: return $codes[$type];
459: }
460:
461: $code = strtoupper($code);
462: if (!isset($codes[$type][$code])) {
463: return false;
464: } else {
465: return $codes[$type][$code];
466: }
467: }
468:
469: 470: 471: 472: 473: 474:
475: public function getDhlProducts($doc)
476: {
477: $docType = array(
478: '2' => Mage::helper('usa')->__('Easy shop'),
479: '5' => Mage::helper('usa')->__('Sprintline'),
480: '6' => Mage::helper('usa')->__('Secureline'),
481: '7' => Mage::helper('usa')->__('Express easy'),
482: '9' => Mage::helper('usa')->__('Europack'),
483: 'B' => Mage::helper('usa')->__('Break bulk express'),
484: 'C' => Mage::helper('usa')->__('Medical express'),
485: 'D' => Mage::helper('usa')->__('Express worldwide'),
486: 'U' => Mage::helper('usa')->__('Express worldwide'),
487: 'K' => Mage::helper('usa')->__('Express 9:00'),
488: 'L' => Mage::helper('usa')->__('Express 10:30'),
489: 'G' => Mage::helper('usa')->__('Domestic economy select'),
490: 'W' => Mage::helper('usa')->__('Economy select'),
491: 'I' => Mage::helper('usa')->__('Break bulk economy'),
492: 'N' => Mage::helper('usa')->__('Domestic express'),
493: 'O' => Mage::helper('usa')->__('Others'),
494: 'R' => Mage::helper('usa')->__('Globalmail business'),
495: 'S' => Mage::helper('usa')->__('Same day'),
496: 'T' => Mage::helper('usa')->__('Express 12:00'),
497: 'X' => Mage::helper('usa')->__('Express envelope'),
498: );
499:
500: $nonDocType = array(
501: '1' => Mage::helper('usa')->__('Customer services'),
502: '3' => Mage::helper('usa')->__('Easy shop'),
503: '4' => Mage::helper('usa')->__('Jetline'),
504: '8' => Mage::helper('usa')->__('Express easy'),
505: 'P' => Mage::helper('usa')->__('Express worldwide'),
506: 'Q' => Mage::helper('usa')->__('Medical express'),
507: 'E' => Mage::helper('usa')->__('Express 9:00'),
508: 'F' => Mage::helper('usa')->__('Freight worldwide'),
509: 'H' => Mage::helper('usa')->__('Economy select'),
510: 'J' => Mage::helper('usa')->__('Jumbo box'),
511: 'M' => Mage::helper('usa')->__('Express 10:30'),
512: 'V' => Mage::helper('usa')->__('Europack'),
513: 'Y' => Mage::helper('usa')->__('Express 12:00'),
514: );
515:
516: if ($this->_isDomestic) {
517: return $docType + $nonDocType;
518: }
519: if ($doc == self::DHL_CONTENT_TYPE_DOC) {
520:
521: return $docType;
522: } else {
523:
524: return $nonDocType;
525: }
526: }
527:
528: 529: 530: 531: 532: 533:
534: public function getDhlProductTitle($code)
535: {
536: $contentType = $this->getConfigData('content_type');
537: $dhlProducts = $this->getDhlProducts($contentType);
538: return isset($dhlProducts[$code]) ? $dhlProducts[$code] : false;
539: }
540:
541: 542: 543: 544: 545: 546: 547: 548:
549: protected function _getWeight($weight, $maxWeight = false, $configWeightUnit = false)
550: {
551: if ($maxWeight) {
552: $configWeightUnit = Zend_Measure_Weight::KILOGRAM;
553: } elseif ($configWeightUnit) {
554: $configWeightUnit = $this->getCode('dimensions_variables', $configWeightUnit);
555: } else {
556: $configWeightUnit = $this->getCode('dimensions_variables', (string)$this->getConfigData('unit_of_measure'));
557: }
558:
559: $countryWeightUnit = $this->getCode('dimensions_variables', $this->_getWeightUnit());
560:
561: if ($configWeightUnit != $countryWeightUnit) {
562: $weight = Mage::helper('usa')->convertMeasureWeight(
563: round($weight,3),
564: $configWeightUnit,
565: $countryWeightUnit
566: );
567: }
568:
569: return round($weight, 3);
570: }
571:
572: 573: 574: 575: 576:
577: protected function _getAllItems()
578: {
579: $allItems = $this->_request->getAllItems();
580: $fullItems = array();
581:
582: foreach ($allItems as $item) {
583: if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
584: && $item->getProduct()->getShipmentType()
585: ) {
586: continue;
587: }
588:
589: $qty = $item->getQty();
590: $changeQty = true;
591: $checkWeight = true;
592: $decimalItems = array();
593:
594: if ($item->getParentItem()) {
595: if (!$item->getParentItem()->getProduct()->getShipmentType()) {
596: continue;
597: }
598: $qty = $item->getIsQtyDecimal()
599: ? $item->getParentItem()->getQty()
600: : $item->getParentItem()->getQty() * $item->getQty();
601: }
602:
603: $itemWeight = $item->getWeight();
604: if ($item->getIsQtyDecimal() && $item->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
605: $stockItem = $item->getProduct()->getStockItem();
606: if ($stockItem->getIsDecimalDivided()) {
607: if ($stockItem->getEnableQtyIncrements() && $stockItem->getQtyIncrements()) {
608: $itemWeight = $itemWeight * $stockItem->getQtyIncrements();
609: $qty = round(($item->getWeight() / $itemWeight) * $qty);
610: $changeQty = false;
611: } else {
612: $itemWeight = $this->_getWeight($itemWeight * $item->getQty());
613: $maxWeight = $this->_getWeight($this->_maxWeight, true);
614: if ($itemWeight > $maxWeight) {
615: $qtyItem = floor($itemWeight / $maxWeight);
616: $decimalItems[] = array('weight' => $maxWeight, 'qty' => $qtyItem);
617: $weightItem = Mage::helper('core')->getExactDivision($itemWeight, $maxWeight);
618: if ($weightItem) {
619: $decimalItems[] = array('weight' => $weightItem, 'qty' => 1);
620: }
621: $checkWeight = false;
622: } else {
623: $itemWeight = $itemWeight * $item->getQty();
624: }
625: }
626: } else {
627: $itemWeight = $itemWeight * $item->getQty();
628: }
629: }
630:
631: if ($checkWeight && $this->_getWeight($itemWeight) > $this->_getWeight($this->_maxWeight, true)) {
632: return array();
633: }
634:
635: if ($changeQty && !$item->getParentItem() && $item->getIsQtyDecimal()
636: && $item->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
637: ) {
638: $qty = 1;
639: }
640:
641: if (!empty($decimalItems)) {
642: foreach ($decimalItems as $decimalItem) {
643: $fullItems = array_merge($fullItems,
644: array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight'])
645: );
646: }
647: } else {
648: $fullItems = array_merge($fullItems, array_fill(0, $qty, $this->_getWeight($itemWeight)));
649: }
650: }
651: sort($fullItems);
652:
653: return $fullItems;
654: }
655:
656: 657: 658: 659: 660: 661:
662: protected function _makePieces(SimpleXMLElement $nodeBkgDetails)
663: {
664: $divideOrderWeight = (string)$this->getConfigData('divide_order_weight');
665: $nodePieces = $nodeBkgDetails->addChild('Pieces', '', '');
666: $items = $this->_getAllItems();
667: $numberOfPieces = 0;
668:
669: if ($divideOrderWeight && !empty($items)) {
670: $maxWeight = $this->_getWeight($this->_maxWeight, true);
671: $sumWeight = 0;
672:
673: $reverseOrderItems = $items;
674: arsort($reverseOrderItems);
675:
676: foreach ($reverseOrderItems as $key => $weight) {
677: if (!isset($items[$key])) {
678: continue;
679: }
680: unset($items[$key]);
681: $sumWeight = $weight;
682: foreach ($items as $key => $weight) {
683: if (($sumWeight + $weight) < $maxWeight) {
684: unset($items[$key]);
685: $sumWeight += $weight;
686: } elseif (($sumWeight + $weight) > $maxWeight) {
687: $numberOfPieces++;
688: $nodePiece = $nodePieces->addChild('Piece', '', '');
689: $nodePiece->addChild('PieceID', $numberOfPieces);
690: $this->_addDimension($nodePiece);
691: $nodePiece->addChild('Weight', $sumWeight);
692: break;
693: } else {
694: unset($items[$key]);
695: $numberOfPieces++;
696: $sumWeight += $weight;
697: $nodePiece = $nodePieces->addChild('Piece', '', '');
698: $nodePiece->addChild('PieceID', $numberOfPieces);
699: $this->_addDimension($nodePiece);
700: $nodePiece->addChild('Weight', $sumWeight);
701: $sumWeight = 0;
702: break;
703: }
704: }
705: }
706: if ($sumWeight > 0) {
707: $numberOfPieces++;
708: $nodePiece = $nodePieces->addChild('Piece', '', '');
709: $nodePiece->addChild('PieceID', $numberOfPieces);
710: $this->_addDimension($nodePiece);
711: $nodePiece->addChild('Weight', $sumWeight);
712: }
713: } else {
714: $nodePiece = $nodePieces->addChild('Piece', '', '');
715: $nodePiece->addChild('PieceID', 1);
716: $this->_addDimension($nodePiece);
717: $nodePiece->addChild('Weight', $this->_getWeight($this->_rawRequest->getWeight()));
718: }
719:
720: $handlingAction = $this->getConfigData('handling_action');
721: if ($handlingAction == Mage_Shipping_Model_Carrier_Abstract::HANDLING_ACTION_PERORDER || !$numberOfPieces) {
722: $numberOfPieces = 1;
723: }
724: $this->_numBoxes = $numberOfPieces;
725: }
726:
727: 728: 729: 730: 731: 732: 733:
734: protected function _getDimension($dimension, $configWeightUnit = false)
735: {
736: if (!$configWeightUnit) {
737: $configWeightUnit = $this->getCode('dimensions_variables', (string)$this->getConfigData('unit_of_measure'));
738: } else {
739: $configWeightUnit = $this->getCode('dimensions_variables', $configWeightUnit);
740: }
741:
742: if ($configWeightUnit == Zend_Measure_Weight::POUND) {
743: $configDimensionUnit = Zend_Measure_Length::INCH;
744: } else {
745: $configDimensionUnit = Zend_Measure_Length::CENTIMETER;
746: }
747:
748: $countryDimensionUnit = $this->getCode('dimensions_variables', $this->_getDimensionUnit());
749:
750: if ($configDimensionUnit != $countryDimensionUnit) {
751: $dimension = Mage::helper('usa')->convertMeasureDimension(
752: round($dimension, 3),
753: $configDimensionUnit,
754: $countryDimensionUnit
755: );
756: }
757:
758: return round($dimension, 3);
759: }
760:
761: 762: 763: 764: 765: 766:
767: protected function _addDimension($nodePiece)
768: {
769: $sizeChecker = (string)$this->getConfigData('size');
770:
771: $height = $this->_getDimension((string)$this->getConfigData('height'));
772: $depth = $this->_getDimension((string)$this->getConfigData('depth'));
773: $width = $this->_getDimension((string)$this->getConfigData('width'));
774:
775: if ($sizeChecker && $height && $depth && $width) {
776: $nodePiece->addChild('Height', $height);
777: $nodePiece->addChild('Depth', $depth);
778: $nodePiece->addChild('Width', $width);
779: }
780: }
781:
782: 783: 784: 785: 786:
787: protected function _getQuotes()
788: {
789: $rawRequest = $this->_rawRequest;
790: $xmlStr = '<?xml version = "1.0" encoding = "UTF-8"?>'
791: . '<p:DCTRequest xmlns:p="http://www.dhl.com" xmlns:p1="http://www.dhl.com/datatypes" '
792: . 'xmlns:p2="http://www.dhl.com/DCTRequestdatatypes" '
793: . 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
794: . 'xsi:schemaLocation="http://www.dhl.com DCT-req.xsd "/>';
795: $xml = new SimpleXMLElement($xmlStr);
796: $nodeGetQuote = $xml->addChild('GetQuote', '', '');
797: $nodeRequest = $nodeGetQuote->addChild('Request');
798:
799: $nodeServiceHeader = $nodeRequest->addChild('ServiceHeader');
800: $nodeServiceHeader->addChild('SiteID', (string)$this->getConfigData('id'));
801: $nodeServiceHeader->addChild('Password', (string)$this->getConfigData('password'));
802:
803: $nodeFrom = $nodeGetQuote->addChild('From');
804: $nodeFrom->addChild('CountryCode', $rawRequest->getOrigCountryId());
805: $nodeFrom->addChild('Postalcode', $rawRequest->getOrigPostal());
806: $nodeFrom->addChild('City', $rawRequest->getOrigCity());
807:
808: $nodeBkgDetails = $nodeGetQuote->addChild('BkgDetails');
809: $nodeBkgDetails->addChild('PaymentCountryCode', $rawRequest->getOrigCountryId());
810: $nodeBkgDetails->addChild('Date', Varien_Date::now(true));
811: $nodeBkgDetails->addChild('ReadyTime', 'PT' . (int)(string)$this->getConfigData('ready_time') . 'H00M');
812:
813: $nodeBkgDetails->addChild('DimensionUnit', $this->_getDimensionUnit());
814: $nodeBkgDetails->addChild('WeightUnit', $this->_getWeightUnit());
815:
816: $this->_makePieces($nodeBkgDetails);
817:
818: $nodeBkgDetails->addChild('PaymentAccountNumber', (string)$this->getConfigData('account'));
819:
820: $nodeTo = $nodeGetQuote->addChild('To');
821: $nodeTo->addChild('CountryCode', $rawRequest->getDestCountryId());
822: $nodeTo->addChild('Postalcode', $rawRequest->getDestPostal());
823: $nodeTo->addChild('City', $rawRequest->getDestCity());
824:
825: $this->_checkDomesticStatus($rawRequest->getOrigCountryId(), $rawRequest->getDestCountryId());
826:
827: if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_NON_DOC && !$this->_isDomestic) {
828:
829: $nodeBkgDetails->addChild('IsDutiable', 'Y');
830: $nodeDutiable = $nodeGetQuote->addChild('Dutiable');
831: $baseCurrencyCode = Mage::app()->getWebsite($this->_request->getWebsiteId())->getBaseCurrencyCode();
832: $nodeDutiable->addChild('DeclaredCurrency', $baseCurrencyCode);
833: $nodeDutiable->addChild('DeclaredValue', sprintf("%.2F", $rawRequest->getValue()));
834: }
835:
836: $request = $xml->asXML();
837: $request = utf8_encode($request);
838: $responseBody = $this->_getCachedQuotes($request);
839: if ($responseBody === null) {
840: $debugData = array('request' => $request);
841: try {
842: $client = new Varien_Http_Client();
843: $client->setUri((string)$this->getConfigData('gateway_url'));
844: $client->setConfig(array('maxredirects' => 0, 'timeout' => 30));
845: $client->setRawData($request);
846: $responseBody = $client->request(Varien_Http_Client::POST)->getBody();
847: $debugData['result'] = $responseBody;
848: $this->_setCachedQuotes($request, $responseBody);
849: } catch (Exception $e) {
850: $this->_errors[$e->getCode()] = $e->getMessage();
851: $responseBody = '';
852: }
853: $this->_debug($debugData);
854: }
855:
856: return $this->_parseResponse($responseBody);
857: }
858:
859: 860: 861: 862: 863: 864:
865: protected function _parseResponse($response)
866: {
867: $htmlTranslationTable = get_html_translation_table(HTML_ENTITIES);
868: unset($htmlTranslationTable['<'], $htmlTranslationTable['>'], $htmlTranslationTable['"']);
869: $response = str_replace(array_keys($htmlTranslationTable), array_values($htmlTranslationTable), $response);
870:
871: $responseError = Mage::helper('usa')->__('The response is in wrong format.');
872:
873: if (strlen(trim($response)) > 0) {
874: if (strpos(trim($response), '<?xml') === 0) {
875: $xml = simplexml_load_string($response);
876: if (is_object($xml)) {
877: if (in_array($xml->getName(), array('ErrorResponse', 'ShipmentValidateErrorResponse'))
878: || isset($xml->GetQuoteResponse->Note->Condition)
879: ) {
880: $code = null;
881: $data = null;
882: if (isset($xml->Response->Status->Condition)) {
883: $nodeCondition = $xml->Response->Status->Condition;
884: } else {
885: $nodeCondition = $xml->GetQuoteResponse->Note->Condition;
886: }
887:
888: if ($this->_isShippingLabelFlag) {
889: foreach ($nodeCondition as $condition) {
890: $code = isset($condition->ConditionCode) ? (string)$condition->ConditionCode : 0;
891: $data = isset($condition->ConditionData) ? (string)$condition->ConditionData : '';
892: if (!empty($code) && !empty($data)) {
893: break;
894: }
895: }
896: Mage::throwException(Mage::helper('usa')->__('Error #%s : %s', trim($code), trim($data)));
897: }
898:
899: $code = isset($nodeCondition->ConditionCode) ? (string)$nodeCondition->ConditionCode : 0;
900: $data = isset($nodeCondition->ConditionData) ? (string)$nodeCondition->ConditionData : '';
901: $this->_errors[$code] = Mage::helper('usa')->__('Error #%s : %s', trim($code), trim($data));
902: } else {
903: if (isset($xml->GetQuoteResponse->BkgDetails->QtdShp)) {
904: foreach ($xml->GetQuoteResponse->BkgDetails->QtdShp as $quotedShipment) {
905: $this->_addRate($quotedShipment);
906: }
907: } elseif (isset($xml->AirwayBillNumber)) {
908: $result = new Varien_Object();
909: $result->setTrackingNumber((string)$xml->AirwayBillNumber);
910: try {
911:
912: $pdf = Mage::getModel(
913: 'usa/shipping_carrier_dhl_label_pdf',
914: array('info' => $xml, 'request' => $this->_request)
915: );
916: $result->setShippingLabelContent($pdf->render());
917: } catch (Exception $e) {
918: Mage::throwException(Mage::helper('usa')->__($e->getMessage()));
919: }
920: return $result;
921: } else {
922: $this->_errors[] = $responseError;
923: }
924: }
925: }
926: } else {
927: $this->_errors[] = $responseError;
928: }
929: } else {
930: $this->_errors[] = $responseError;
931: }
932:
933:
934: $result = Mage::getModel('shipping/rate_result');
935: if ($this->_rates) {
936: foreach ($this->_rates as $rate) {
937: $method = $rate['service'];
938: $data = $rate['data'];
939:
940: $rate = Mage::getModel('shipping/rate_result_method');
941: $rate->setCarrier(self::CODE);
942: $rate->setCarrierTitle($this->getConfigData('title'));
943: $rate->setMethod($method);
944: $rate->setMethodTitle($data['term']);
945: $rate->setCost($data['price_total']);
946: $rate->setPrice($data['price_total']);
947: $result->append($rate);
948: }
949: } else if (!empty($this->_errors)) {
950: if ($this->_isShippingLabelFlag) {
951: Mage::throwException($responseError);
952: }
953: return $this->_showError();
954: }
955: return $result;
956: }
957:
958: 959: 960: 961: 962: 963:
964: protected function _addRate(SimpleXMLElement $shipmentDetails)
965: {
966: if (isset($shipmentDetails->ProductShortName)
967: && isset($shipmentDetails->ShippingCharge)
968: && isset($shipmentDetails->GlobalProductCode)
969: && isset($shipmentDetails->CurrencyCode)
970: && array_key_exists((string)$shipmentDetails->GlobalProductCode, $this->getAllowedMethods())
971: ) {
972:
973: $dhlProduct = (string)$shipmentDetails->GlobalProductCode;
974: $totalEstimate = (float)(string)$shipmentDetails->ShippingCharge;
975: $currencyCode = (string)$shipmentDetails->CurrencyCode;
976: $baseCurrencyCode = Mage::app()->getWebsite($this->_request->getWebsiteId())->getBaseCurrencyCode();
977: $dhlProductDescription = $this->getDhlProductTitle($dhlProduct);
978:
979: if ($currencyCode != $baseCurrencyCode) {
980:
981: $currency = Mage::getModel('directory/currency');
982: $rates = $currency->getCurrencyRates($currencyCode, array($baseCurrencyCode));
983: if (!empty($rates) && isset($rates[$baseCurrencyCode])) {
984:
985: $totalEstimate = $totalEstimate * $rates[$baseCurrencyCode];
986: } else {
987: $rates = $currency->getCurrencyRates($baseCurrencyCode, array($currencyCode));
988: if (!empty($rates) && isset($rates[$currencyCode])) {
989: $totalEstimate = $totalEstimate/$rates[$currencyCode];
990: }
991: if (!isset($rates[$currencyCode]) || !$totalEstimate) {
992: $totalEstimate = false;
993: $this->_errors[] = Mage::helper('usa')->__("Exchange rate %s (Base Currency) -> %s not found. DHL method %s skipped", $currencyCode, $baseCurrencyCode, $dhlProductDescription);
994: }
995: }
996: }
997: if ($totalEstimate) {
998: $data = array('term' => $dhlProductDescription,
999: 'price_total' => $this->getMethodPrice($totalEstimate, $dhlProduct));
1000: if (!empty($this->_rates)) {
1001: foreach ($this->_rates as $product) {
1002: if ($product['data']['term'] == $data['term']
1003: && $product['data']['price_total'] == $data['price_total']
1004: ) {
1005: return $this;
1006: }
1007: }
1008: }
1009: $this->_rates[] = array('service' => $dhlProduct, 'data' => $data);
1010: } else {
1011: $this->_errors[] = Mage::helper('usa')->__("Zero shipping charge for '%s'", $dhlProductDescription);
1012: }
1013: } else {
1014: $dhlProductDescription = false;
1015: if (isset($shipmentDetails->GlobalProductCode)) {
1016: $dhlProductDescription = $this->getDhlProductTitle((string)$shipmentDetails->GlobalProductCode);
1017: }
1018: $dhlProductDescription = $dhlProductDescription ? $dhlProductDescription : Mage::helper('usa')->__("DHL");
1019: $this->_errors[] = Mage::helper('usa')->__("Zero shipping charge for '%s'", $dhlProductDescription);
1020: }
1021: return $this;
1022: }
1023:
1024: 1025: 1026: 1027: 1028:
1029: protected function _getDimensionUnit()
1030: {
1031: $countryId = $this->_rawRequest->getOrigCountryId();
1032: $measureUnit = $this->getCountryParams($countryId)->getMeasureUnit();
1033: if (empty($measureUnit)) {
1034: Mage::throwException(Mage::helper('usa')->__("Cannot identify measure unit for %s", $countryId));
1035: }
1036: return $measureUnit;
1037: }
1038:
1039: 1040: 1041: 1042: 1043:
1044: protected function _getWeightUnit()
1045: {
1046: $countryId = $this->_rawRequest->getOrigCountryId();
1047: $weightUnit = $this->getCountryParams($countryId)->getWeightUnit();
1048: if (empty($weightUnit)) {
1049: Mage::throwException(Mage::helper('usa')->__("Cannot identify weight unit for %s", $countryId));
1050: }
1051: return $weightUnit;
1052: }
1053:
1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061:
1062: protected function getCountryParams($countryCode)
1063: {
1064: if (empty($this->_countryParams)) {
1065: $dhlConfigPath = Mage::getModuleDir('etc', 'Mage_Usa') . DS . 'dhl' . DS;
1066: $countriesXml = file_get_contents($dhlConfigPath . 'international' . DS . 'countries.xml');
1067: $this->_countryParams = new Varien_Simplexml_Element($countriesXml);
1068: }
1069: if (isset($this->_countryParams->$countryCode)) {
1070: $countryParams = new Varien_Object($this->_countryParams->$countryCode->asArray());
1071: }
1072: return isset($countryParams) ? $countryParams : new Varien_Object();
1073: }
1074:
1075: 1076: 1077: 1078: 1079: 1080:
1081: protected function _doShipmentRequest(Varien_Object $request)
1082: {
1083: $this->_prepareShipmentRequest($request);
1084: $this->_mapRequestToShipment($request);
1085: $this->setRequest($request);
1086:
1087: return $this->_doRequest();
1088: }
1089:
1090: 1091: 1092: 1093: 1094: 1095:
1096: public function proccessAdditionalValidation(Mage_Shipping_Model_Rate_Request $request)
1097: {
1098:
1099: if (!count($this->getAllItems($request))) {
1100: $this->_errors[] = Mage::helper('usa')->__('There is no items in this order');
1101: }
1102:
1103: $countryParams = $this->getCountryParams(
1104: Mage::getStoreConfig(Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID, $request->getStoreId())
1105: );
1106: if (!$countryParams->getData()) {
1107: $this->_errors[] = Mage::helper('usa')->__('Please, specify origin country');
1108: }
1109:
1110: if (!empty($this->_errors)) {
1111: return $this->_showError();
1112: }
1113:
1114: return $this;
1115: }
1116:
1117: 1118: 1119: 1120: 1121:
1122: protected function _showError()
1123: {
1124: $showMethod = $this->getConfigData('showmethod');
1125:
1126: if ($showMethod) {
1127:
1128: $error = Mage::getModel('shipping/rate_result_error');
1129: $error->setCarrier(self::CODE);
1130: $error->setCarrierTitle($this->getConfigData('title'));
1131: $error->setErrorMessage($this->getConfigData('specificerrmsg'));
1132: $this->_debug($this->_errors);
1133: return $error;
1134: } else {
1135: return false;
1136: }
1137: }
1138:
1139: 1140: 1141: 1142: 1143: 1144:
1145: public function getContainerTypes(Varien_Object $params = null)
1146: {
1147: return array(
1148: self::DHL_CONTENT_TYPE_DOC => Mage::helper('usa')->__('Documents'),
1149: self::DHL_CONTENT_TYPE_NON_DOC => Mage::helper('usa')->__('Non Documents')
1150: );
1151: }
1152:
1153: 1154: 1155: 1156: 1157: 1158:
1159: protected function _mapRequestToShipment(Varien_Object $request)
1160: {
1161:
1162: $request->setOrigCountryId($request->getShipperAddressCountryCode());
1163: $this->_rawRequest = $request;
1164: $customsValue = 0;
1165: $packageWeight = 0;
1166: $packages = $request->getPackages();
1167: foreach ($packages as &$piece) {
1168: $params = $piece['params'];
1169: if ($params['width'] || $params['length'] || $params['height']) {
1170: $minValue = $this->_getMinDimension($params['dimension_units']);
1171: if ($params['width'] < $minValue || $params['length'] < $minValue || $params['height'] < $minValue) {
1172: $message = Mage::helper('usa')->__('Height, width and length should be equal or greater than %s', $minValue);
1173: Mage::throwException($message);
1174: }
1175: }
1176:
1177: $weightUnits = $piece['params']['weight_units'];
1178: $piece['params']['height'] = $this->_getDimension($piece['params']['height'], $weightUnits);
1179: $piece['params']['length'] = $this->_getDimension($piece['params']['length'], $weightUnits);
1180: $piece['params']['width'] = $this->_getDimension($piece['params']['width'], $weightUnits);
1181: $piece['params']['dimension_units'] = $this->_getDimensionUnit();
1182: $piece['params']['weight'] = $this->_getWeight($piece['params']['weight'], false, $weightUnits);
1183: $piece['params']['weight_units'] = $this->_getWeightUnit();
1184:
1185: $customsValue += $piece['params']['customs_value'];
1186: $packageWeight += $piece['params']['weight'];
1187: }
1188:
1189: $request->setPackages($packages)
1190: ->setPackageWeight($packageWeight)
1191: ->setPackageValue($customsValue)
1192: ->setValueWithDiscount($customsValue)
1193: ->setPackageCustomsValue($customsValue)
1194: ->setFreeMethodWeight(0);
1195: }
1196:
1197: 1198: 1199: 1200: 1201: 1202:
1203: protected function _getMinDimension($dimensionUnit)
1204: {
1205: return $dimensionUnit == "CENTIMETER" ? self::DIMENSION_MIN_CM : self::DIMENSION_MIN_IN;
1206: }
1207:
1208: 1209: 1210: 1211: 1212:
1213: protected function _doRequest()
1214: {
1215: $rawRequest = $this->_request;
1216:
1217: $originRegion = (string)$this->getCountryParams(
1218: Mage::getStoreConfig(Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID, $this->getStore())
1219: )->region;
1220:
1221: if (!$originRegion) {
1222: Mage::throwException(Mage::helper('usa')->__('Wrong Region.'));
1223: }
1224:
1225: if ($originRegion == 'AM') {
1226: $originRegion = '';
1227: }
1228:
1229: $xmlStr = '<?xml version="1.0" encoding="UTF-8"?>'
1230: . '<req:ShipmentValidateRequest' . $originRegion
1231: . ' xmlns:req="http://www.dhl.com"'
1232: . ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
1233: . ' xsi:schemaLocation="http://www.dhl.com ship-val-req'
1234: . ($originRegion ? '_' . $originRegion : '') . '.xsd" />';
1235: $xml = new SimpleXMLElement($xmlStr);
1236:
1237: $nodeRequest = $xml->addChild('Request', '', '');
1238: $nodeServiceHeader = $nodeRequest->addChild('ServiceHeader');
1239: $nodeServiceHeader->addChild('SiteID', (string)$this->getConfigData('id'));
1240: $nodeServiceHeader->addChild('Password', (string)$this->getConfigData('password'));
1241:
1242: if (!$originRegion) {
1243: $xml->addChild('RequestedPickupTime', 'N', '');
1244: }
1245: $xml->addChild('NewShipper', 'N', '');
1246: $xml->addChild('LanguageCode', 'EN', '');
1247: $xml->addChild('PiecesEnabled', 'Y', '');
1248:
1249:
1250: $nodeBilling = $xml->addChild('Billing', '', '');
1251: $nodeBilling->addChild('ShipperAccountNumber', (string)$this->getConfigData('account'));
1252: 1253: 1254: 1255: 1256: 1257:
1258: $nodeBilling->addChild('ShippingPaymentType', 'S');
1259:
1260: 1261: 1262:
1263: $nodeBilling->addChild('BillingAccountNumber', (string)$this->getConfigData('account'));
1264: $nodeBilling->addChild('DutyPaymentType', 'S');
1265: $nodeBilling->addChild('DutyAccountNumber', (string)$this->getConfigData('account'));
1266:
1267:
1268: $nodeConsignee = $xml->addChild('Consignee', '', '');
1269:
1270: $companyName = ($rawRequest->getRecipientContactCompanyName())
1271: ? $rawRequest->getRecipientContactCompanyName()
1272: : $rawRequest->getRecipientContactPersonName();
1273:
1274: $nodeConsignee->addChild('CompanyName', substr($companyName, 0, 35));
1275:
1276: $address = $rawRequest->getRecipientAddressStreet1(). ' ' . $rawRequest->getRecipientAddressStreet2();
1277: $address = Mage::helper('core/string')->str_split($address, 35, false, true);
1278: if (is_array($address)) {
1279: foreach ($address as $addressLine) {
1280: $nodeConsignee->addChild('AddressLine', $addressLine);
1281: }
1282: } else {
1283: $nodeConsignee->addChild('AddressLine', $address);
1284: }
1285:
1286: $nodeConsignee->addChild('City', $rawRequest->getRecipientAddressCity());
1287: $nodeConsignee->addChild('Division', $rawRequest->getRecipientAddressStateOrProvinceCode());
1288: $nodeConsignee->addChild('PostalCode', $rawRequest->getRecipientAddressPostalCode());
1289: $nodeConsignee->addChild('CountryCode', $rawRequest->getRecipientAddressCountryCode());
1290: $nodeConsignee->addChild('CountryName',
1291: (string)$this->getCountryParams($rawRequest->getRecipientAddressCountryCode())->name
1292: );
1293: $nodeContact = $nodeConsignee->addChild('Contact');
1294: $nodeContact->addChild('PersonName', substr($rawRequest->getRecipientContactPersonName(), 0, 34));
1295: $nodeContact->addChild('PhoneNumber', substr($rawRequest->getRecipientContactPhoneNumber(), 0, 24));
1296:
1297: 1298: 1299: 1300:
1301: $nodeCommodity = $xml->addChild('Commodity', '', '');
1302: $nodeCommodity->addChild('CommodityCode', '1');
1303:
1304: $this->_checkDomesticStatus($rawRequest->getShipperAddressCountryCode(),
1305: $rawRequest->getRecipientAddressCountryCode()
1306: );
1307:
1308:
1309: if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_NON_DOC && !$this->_isDomestic) {
1310: $nodeDutiable = $xml->addChild('Dutiable', '', '');
1311: $nodeDutiable->addChild('DeclaredValue',
1312: sprintf("%.2F", $rawRequest->getOrderShipment()->getOrder()->getSubtotal())
1313: );
1314: $baseCurrencyCode = Mage::app()->getWebsite($rawRequest->getWebsiteId())->getBaseCurrencyCode();
1315: $nodeDutiable->addChild('DeclaredCurrency', $baseCurrencyCode);
1316: }
1317:
1318: 1319: 1320: 1321:
1322: $nodeReference = $xml->addChild('Reference', '', '');
1323: $nodeReference->addChild('ReferenceID', 'shipment reference');
1324: $nodeReference->addChild('ReferenceType', 'St');
1325:
1326:
1327: $this->_shipmentDetails($xml, $rawRequest, $originRegion);
1328:
1329:
1330: $nodeShipper = $xml->addChild('Shipper', '', '');
1331: $nodeShipper->addChild('ShipperID', (string)$this->getConfigData('account'));
1332: $nodeShipper->addChild('CompanyName', $rawRequest->getShipperContactCompanyName());
1333: $nodeShipper->addChild('RegisteredAccount', (string)$this->getConfigData('account'));
1334:
1335: $address = $rawRequest->getShipperAddressStreet1(). ' ' . $rawRequest->getShipperAddressStreet2();
1336: $address = Mage::helper('core/string')->str_split($address, 35, false, true);
1337: if (is_array($address)) {
1338: foreach ($address as $addressLine) {
1339: $nodeShipper->addChild('AddressLine', $addressLine);
1340: }
1341: } else {
1342: $nodeShipper->addChild('AddressLine', $address);
1343: }
1344:
1345: $nodeShipper->addChild('City', $rawRequest->getShipperAddressCity());
1346: $nodeShipper->addChild('Division', $rawRequest->getShipperAddressStateOrProvinceCode());
1347: $nodeShipper->addChild('PostalCode', $rawRequest->getShipperAddressPostalCode());
1348: $nodeShipper->addChild('CountryCode', $rawRequest->getShipperAddressCountryCode());
1349: $nodeShipper->addChild('CountryName',
1350: (string)$this->getCountryParams($rawRequest->getShipperAddressCountryCode())->name
1351: );
1352: $nodeContact = $nodeShipper->addChild('Contact', '', '');
1353: $nodeContact->addChild('PersonName', substr($rawRequest->getShipperContactPersonName(), 0, 34));
1354: $nodeContact->addChild('PhoneNumber', substr($rawRequest->getShipperContactPhoneNumber(), 0, 24));
1355:
1356: $request = $xml->asXML();
1357: $request = utf8_encode($request);
1358:
1359: $responseBody = $this->_getCachedQuotes($request);
1360: if ($responseBody === null) {
1361: $debugData = array('request' => $request);
1362: try {
1363: $client = new Varien_Http_Client();
1364: $client->setUri((string)$this->getConfigData('gateway_url'));
1365: $client->setConfig(array('maxredirects' => 0, 'timeout' => 30));
1366: $client->setRawData($request);
1367: $responseBody = $client->request(Varien_Http_Client::POST)->getBody();
1368: $debugData['result'] = $responseBody;
1369: $this->_setCachedQuotes($request, $responseBody);
1370: } catch (Exception $e) {
1371: $this->_errors[$e->getCode()] = $e->getMessage();
1372: $responseBody = '';
1373: }
1374: $this->_debug($debugData);
1375: }
1376: $this->_isShippingLabelFlag = true;
1377: return $this->_parseResponse($responseBody);
1378: }
1379:
1380: 1381: 1382: 1383: 1384: 1385: 1386: 1387:
1388: protected function _shipmentDetails($xml, $rawRequest, $originRegion = '')
1389: {
1390: $nodeShipmentDetails = $xml->addChild('ShipmentDetails', '', '');
1391: $nodeShipmentDetails->addChild('NumberOfPieces', count($rawRequest->getPackages()));
1392:
1393: if ($originRegion) {
1394: $nodeShipmentDetails->addChild('CurrencyCode',
1395: Mage::app()->getWebsite($this->_request->getWebsiteId())->getBaseCurrencyCode()
1396: );
1397: }
1398:
1399: $nodePieces = $nodeShipmentDetails->addChild('Pieces', '', '');
1400:
1401: 1402: 1403: 1404: 1405: 1406: 1407:
1408: $i = 0;
1409: foreach ($rawRequest->getPackages() as $package) {
1410: $nodePiece = $nodePieces->addChild('Piece', '', '');
1411: $packageType = 'EE';
1412: if ($package['params']['container'] == self::DHL_CONTENT_TYPE_NON_DOC) {
1413: $packageType = 'CP';
1414: }
1415: $nodePiece->addChild('PieceID', ++$i);
1416: $nodePiece->addChild('PackageType', $packageType);
1417: $nodePiece->addChild('Weight', round($package['params']['weight'],1));
1418: $params = $package['params'];
1419: if ($params['width'] && $params['length'] && $params['height']) {
1420: if (!$originRegion) {
1421: $nodePiece->addChild('Width', round($params['width']));
1422: $nodePiece->addChild('Height', round($params['height']));
1423: $nodePiece->addChild('Depth', round($params['length']));
1424: } else {
1425: $nodePiece->addChild('Depth', round($params['length']));
1426: $nodePiece->addChild('Width', round($params['width']));
1427: $nodePiece->addChild('Height', round($params['height']));
1428: }
1429: }
1430: $content = array();
1431: foreach ($package['items'] as $item) {
1432: $content[] = $item['name'];
1433: }
1434: $nodePiece->addChild('PieceContents', substr(implode(',', $content), 0, 34));
1435: }
1436:
1437: if (!$originRegion) {
1438: $nodeShipmentDetails->addChild('Weight', round($rawRequest->getPackageWeight(),1));
1439:
1440: $nodeShipmentDetails->addChild('WeightUnit', substr($this->_getWeightUnit(),0,1));
1441:
1442: $nodeShipmentDetails->addChild('GlobalProductCode', $rawRequest->getShippingMethod());
1443: $nodeShipmentDetails->addChild('LocalProductCode', $rawRequest->getShippingMethod());
1444:
1445: $nodeShipmentDetails->addChild('Date', Mage::getModel('core/date')->date('Y-m-d'));
1446: $nodeShipmentDetails->addChild('Contents', 'DHL Parcel');
1447: 1448: 1449: 1450: 1451:
1452: $nodeShipmentDetails->addChild('DoorTo', 'DD');
1453: $nodeShipmentDetails->addChild('DimensionUnit', substr($this->_getDimensionUnit(),0,1));
1454: if ($package['params']['container'] == self::DHL_CONTENT_TYPE_NON_DOC) {
1455: $packageType = 'CP';
1456: }
1457: $nodeShipmentDetails->addChild('PackageType', $packageType);
1458: if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_NON_DOC) {
1459: $nodeShipmentDetails->addChild('IsDutiable', 'Y');
1460: }
1461: $nodeShipmentDetails->addChild('CurrencyCode',
1462: Mage::app()->getWebsite($this->_request->getWebsiteId())->getBaseCurrencyCode()
1463: );
1464: } else {
1465: if ($package['params']['container'] == self::DHL_CONTENT_TYPE_NON_DOC) {
1466: $packageType = 'CP';
1467: }
1468: $nodeShipmentDetails->addChild('PackageType', $packageType);
1469: $nodeShipmentDetails->addChild('Weight', $rawRequest->getPackageWeight());
1470:
1471: $nodeShipmentDetails->addChild('DimensionUnit', substr($this->_getDimensionUnit(),0,1));
1472: $nodeShipmentDetails->addChild('WeightUnit', substr($this->_getWeightUnit(),0,1));
1473:
1474: $nodeShipmentDetails->addChild('GlobalProductCode', $rawRequest->getShippingMethod());
1475: $nodeShipmentDetails->addChild('LocalProductCode', $rawRequest->getShippingMethod());
1476:
1477: 1478: 1479: 1480: 1481:
1482: $nodeShipmentDetails->addChild('DoorTo', 'DD');
1483: $nodeShipmentDetails->addChild('Date', Mage::getModel('core/date')->date('Y-m-d'));
1484: $nodeShipmentDetails->addChild('Contents', 'DHL Parcel');
1485: }
1486: }
1487:
1488: 1489: 1490: 1491: 1492: 1493:
1494: public function getTracking($trackings)
1495: {
1496: if (!is_array($trackings)) {
1497: $trackings = array($trackings);
1498: }
1499: $this->_getXMLTracking($trackings);
1500:
1501: return $this->_result;
1502: }
1503:
1504: 1505: 1506: 1507: 1508: 1509:
1510: protected function _getXMLTracking($trackings)
1511: {
1512: $xmlStr = '<?xml version="1.0" encoding="UTF-8"?>'
1513: . '<req:KnownTrackingRequest'
1514: . ' xmlns:req="http://www.dhl.com"'
1515: . ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
1516: . ' xsi:schemaLocation="http://www.dhl.com TrackingRequestKnown.xsd" />';
1517:
1518: $xml = new SimpleXMLElement($xmlStr);
1519:
1520: $requestNode = $xml->addChild('Request', '', '');
1521: $serviceHeaderNode = $requestNode->addChild('ServiceHeader', '', '');
1522: $serviceHeaderNode->addChild('SiteID', (string)$this->getConfigData('id'));
1523: $serviceHeaderNode->addChild('Password', (string)$this->getConfigData('password'));
1524:
1525: $xml->addChild('LanguageCode', 'EN', '');
1526: foreach ($trackings as $tracking) {
1527: $xml->addChild('AWBNumber', $tracking, '');
1528: }
1529: 1530: 1531: 1532: 1533:
1534: $xml->addChild('LevelOfDetails', 'ALL_CHECK_POINTS', '');
1535:
1536: 1537: 1538: 1539: 1540: 1541: 1542: 1543: 1544: 1545:
1546:
1547:
1548: $request = $xml->asXML();
1549: $request = utf8_encode($request);
1550:
1551: $responseBody = $this->_getCachedQuotes($request);
1552: if ($responseBody === null) {
1553: $debugData = array('request' => $request);
1554: try {
1555: $client = new Varien_Http_Client();
1556: $client->setUri((string)$this->getConfigData('gateway_url'));
1557: $client->setConfig(array('maxredirects' => 0, 'timeout' => 30));
1558: $client->setRawData($request);
1559: $responseBody = $client->request(Varien_Http_Client::POST)->getBody();
1560: $debugData['result'] = $responseBody;
1561: $this->_setCachedQuotes($request, $responseBody);
1562: } catch (Exception $e) {
1563: $this->_errors[$e->getCode()] = $e->getMessage();
1564: $responseBody = '';
1565: }
1566: $this->_debug($debugData);
1567: }
1568:
1569: $this->_parseXmlTrackingResponse($trackings, $responseBody);
1570: }
1571:
1572: 1573: 1574: 1575: 1576: 1577: 1578:
1579: protected function _parseXmlTrackingResponse($trackings, $response)
1580: {
1581: $errorTitle = Mage::helper('usa')->__('Unable to retrieve tracking');
1582: $resultArr = array();
1583:
1584: $htmlTranslationTable = get_html_translation_table(HTML_ENTITIES);
1585: unset($htmlTranslationTable['<'], $htmlTranslationTable['>'], $htmlTranslationTable['"']);
1586: $response = str_replace(array_keys($htmlTranslationTable), array_values($htmlTranslationTable), $response);
1587:
1588: if (strlen(trim($response)) > 0) {
1589: $xml = simplexml_load_string($response);
1590: if (!is_object($xml)) {
1591: $errorTitle = Mage::helper('usa')->__('Response is in the wrong format');
1592: }
1593: if (is_object($xml) && ((isset($xml->Response->Status->ActionStatus)
1594: && $xml->Response->Status->ActionStatus == 'Failure')
1595: || isset($xml->GetQuoteResponse->Note->Condition))
1596: ) {
1597: if (isset($xml->Response->Status->Condition)) {
1598: $nodeCondition = $xml->Response->Status->Condition;
1599: }
1600:
1601: $code = isset($nodeCondition->ConditionCode) ? (string)$nodeCondition->ConditionCode : 0;
1602: $data = isset($nodeCondition->ConditionData) ? (string)$nodeCondition->ConditionData : '';
1603: $this->_errors[$code] = Mage::helper('usa')->__('Error #%s : %s', $code, $data);
1604: } elseif (is_object($xml) && is_object($xml->AWBInfo)) {
1605: foreach ($xml->AWBInfo as $awbinfo) {
1606: $awbinfoData = array();
1607: $trackNum = isset($awbinfo->AWBNumber) ? (string)$awbinfo->AWBNumber : '';
1608: if (!is_object($awbinfo) || !$awbinfo->ShipmentInfo) {
1609: $this->_errors[$trackNum] = Mage::helper('usa')->__('Unable to retrieve tracking');
1610: continue;
1611: }
1612: $shipmentInfo = $awbinfo->ShipmentInfo;
1613:
1614: if ($shipmentInfo->ShipmentDesc) {
1615: $awbinfoData['service'] = (string)$shipmentInfo->ShipmentDesc;
1616: }
1617:
1618: $awbinfoData['weight'] = (string)$shipmentInfo->Weight . ' ' . (string)$shipmentInfo->WeightUnit;
1619:
1620: $packageProgress = array();
1621: if (isset($shipmentInfo->ShipmentEvent)) {
1622: foreach ($shipmentInfo->ShipmentEvent as $shipmentEvent) {
1623: $shipmentEventArray = array();
1624: $shipmentEventArray['activity'] = (string)$shipmentEvent->ServiceEvent->EventCode
1625: . ' ' . (string)$shipmentEvent->ServiceEvent->Description;
1626: $shipmentEventArray['deliverydate'] = (string)$shipmentEvent->Date;
1627: $shipmentEventArray['deliverytime'] = (string)$shipmentEvent->Time;
1628: $shipmentEventArray['deliverylocation'] = (string)$shipmentEvent->ServiceArea->Description
1629: . ' [' . (string)$shipmentEvent->ServiceArea->ServiceAreaCode . ']';
1630: $packageProgress[] = $shipmentEventArray;
1631: }
1632: $awbinfoData['progressdetail'] = $packageProgress;
1633: }
1634: $resultArr[$trackNum] = $awbinfoData;
1635: }
1636: }
1637: }
1638:
1639: $result = Mage::getModel('shipping/tracking_result');
1640:
1641: if (!empty($resultArr)) {
1642: foreach ($resultArr as $trackNum => $data) {
1643: $tracking = Mage::getModel('shipping/tracking_result_status');
1644: $tracking->setCarrier($this->_code);
1645: $tracking->setCarrierTitle($this->getConfigData('title'));
1646: $tracking->setTracking($trackNum);
1647: $tracking->addData($data);
1648: $result->append($tracking);
1649: }
1650: }
1651:
1652: if (!empty($this->_errors) || empty($resultArr)) {
1653: $resultArr = !empty($this->_errors) ? $this->_errors : $trackings;
1654: foreach ($resultArr as $trackNum => $err) {
1655: $error = Mage::getModel('shipping/tracking_result_error');
1656: $error->setCarrier($this->_code);
1657: $error->setCarrierTitle($this->getConfigData('title'));
1658: $error->setTracking(!empty($this->_errors) ? $trackNum : $err);
1659: $error->setErrorMessage(!empty($this->_errors) ? $err : $errorTitle);
1660: $result->append($error);
1661: }
1662: }
1663:
1664: $this->_result = $result;
1665: }
1666:
1667: 1668: 1669: 1670: 1671: 1672: 1673: 1674:
1675: protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
1676: {
1677: if ($handlingType == Mage_Shipping_Model_Carrier_Abstract::HANDLING_TYPE_PERCENT) {
1678: return $cost + ($cost * $this->_numBoxes * $handlingFee / 100);
1679: }
1680:
1681: return $cost + $this->_numBoxes * $handlingFee;
1682: }
1683:
1684: 1685: 1686: 1687: 1688: 1689:
1690: public function requestToShipment(Mage_Shipping_Model_Shipment_Request $request)
1691: {
1692: $packages = $request->getPackages();
1693: if (!is_array($packages) || !$packages) {
1694: Mage::throwException(Mage::helper('usa')->__('No packages for request'));
1695: }
1696: $result = $this->_doShipmentRequest($request);
1697:
1698: $response = new Varien_Object(array(
1699: 'info' => array(array(
1700: 'tracking_number' => $result->getTrackingNumber(),
1701: 'label_content' => $result->getShippingLabelContent()
1702: ))
1703: ));
1704:
1705: $request->setMasterTrackingId($result->getTrackingNumber());
1706:
1707: return $response;
1708: }
1709:
1710: 1711: 1712: 1713: 1714: 1715: 1716:
1717: protected function _checkDomesticStatus($origCountryCode, $destCountryCode)
1718: {
1719: $this->_isDomestic = false;
1720:
1721: $origCountry = (string)$this->getCountryParams($origCountryCode)->name;
1722: $destCountry = (string)$this->getCountryParams($destCountryCode)->name;
1723: $isDomestic = (string)$this->getCountryParams($destCountryCode)->domestic;
1724:
1725: if ($origCountry == $destCountry && $isDomestic) {
1726: $this->_isDomestic = true;
1727: }
1728:
1729: return $this->_isDomestic;
1730: }
1731: }
1732: