*/ class Mage_Usa_Model_Shipping_Carrier_Ups extends Mage_Usa_Model_Shipping_Carrier_Abstract implements Mage_Shipping_Model_Carrier_Interface { /** * Code of the carrier * * @var string */ const CODE = 'ups'; /** * Delivery Confirmation level based on origin/destination * * @var int */ const DELIVERY_CONFIRMATION_SHIPMENT = 1; const DELIVERY_CONFIRMATION_PACKAGE = 2; /** * Code of the carrier * * @var string */ protected $_code = self::CODE; /** * Rate request data * * @var Mage_Shipping_Model_Rate_Request|null */ protected $_request = null; /** * Raw rate request data * * @var Varien_Object|null */ protected $_rawRequest = null; /** * Rate result data * * @var Mage_Shipping_Model_Rate_Result|null */ protected $_result = null; /** * Base currency rate * * @var double */ protected $_baseCurrencyRate; /** * Xml access request * * @var string */ protected $_xmlAccessRequest = null; /** * Default cgi gateway url * * @var string */ protected $_defaultCgiGatewayUrl = 'http://www.ups.com:80/using/services/rave/qcostcgi.cgi'; /** * Default urls for XML * * @var array */ protected $_defaultUrls = array( 'Rate' => 'https://onlinetools.ups.com/ups.app/xml/Rate', 'Track' => 'https://onlinetools.ups.com/ups.app/xml/Track', 'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm', 'ShipAccept' => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept', ); /** * Container types that could be customized for UPS carrier * * @var array */ protected $_customizableContainerTypes = array('CP', 'CSP'); /** * Collect and get rates * * @param Mage_Shipping_Model_Rate_Request $request * @return Mage_Shipping_Model_Rate_Result|bool|null */ public function collectRates(Mage_Shipping_Model_Rate_Request $request) { if (!$this->getConfigFlag($this->_activeFlag)) { return false; } $this->setRequest($request); $this->_result = $this->_getQuotes(); $this->_updateFreeMethodQuote($request); return $this->getResult(); } /** * Prepare and set request to this instance * * @param Mage_Shipping_Model_Rate_Request $request * @return Mage_Usa_Model_Shipping_Carrier_Ups */ public function setRequest(Mage_Shipping_Model_Rate_Request $request) { $this->_request = $request; $r = new Varien_Object(); if ($request->getLimitMethod()) { $r->setAction($this->getCode('action', 'single')); $r->setProduct($request->getLimitMethod()); } else { $r->setAction($this->getCode('action', 'all')); $r->setProduct('GND'.$this->getConfigData('dest_type')); } if ($request->getUpsPickup()) { $pickup = $request->getUpsPickup(); } else { $pickup = $this->getConfigData('pickup'); } $r->setPickup($this->getCode('pickup', $pickup)); if ($request->getUpsContainer()) { $container = $request->getUpsContainer(); } else { $container = $this->getConfigData('container'); } $r->setContainer($this->getCode('container', $container)); if ($request->getUpsDestType()) { $destType = $request->getUpsDestType(); } else { $destType = $this->getConfigData('dest_type'); } $r->setDestType($this->getCode('dest_type', $destType)); if ($request->getOrigCountry()) { $origCountry = $request->getOrigCountry(); } else { $origCountry = Mage::getStoreConfig( Mage_Shipping_Model_Shipping::XML_PATH_STORE_COUNTRY_ID, $request->getStoreId() ); } $r->setOrigCountry(Mage::getModel('directory/country')->load($origCountry)->getIso2Code()); if ($request->getOrigRegionCode()) { $origRegionCode = $request->getOrigRegionCode(); } else { $origRegionCode = Mage::getStoreConfig( Mage_Shipping_Model_Shipping::XML_PATH_STORE_REGION_ID, $request->getStoreId() ); } if (is_numeric($origRegionCode)) { $origRegionCode = Mage::getModel('directory/region')->load($origRegionCode)->getCode(); } $r->setOrigRegionCode($origRegionCode); if ($request->getOrigPostcode()) { $r->setOrigPostal($request->getOrigPostcode()); } else { $r->setOrigPostal(Mage::getStoreConfig( Mage_Shipping_Model_Shipping::XML_PATH_STORE_ZIP, $request->getStoreId() )); } if ($request->getOrigCity()) { $r->setOrigCity($request->getOrigCity()); } else { $r->setOrigCity(Mage::getStoreConfig( Mage_Shipping_Model_Shipping::XML_PATH_STORE_CITY, $request->getStoreId() )); } if ($request->getDestCountryId()) { $destCountry = $request->getDestCountryId(); } else { $destCountry = self::USA_COUNTRY_ID; } //for UPS, puero rico state for US will assume as puerto rico country if ($destCountry == self::USA_COUNTRY_ID && ($request->getDestPostcode()=='00912' || $request->getDestRegionCode()==self::PUERTORICO_COUNTRY_ID) ) { $destCountry = self::PUERTORICO_COUNTRY_ID; } // For UPS, Guam state of the USA will be represented by Guam country if ($destCountry == self::USA_COUNTRY_ID && $request->getDestRegionCode() == self::GUAM_REGION_CODE) { $destCountry = self::GUAM_COUNTRY_ID; } $r->setDestCountry(Mage::getModel('directory/country')->load($destCountry)->getIso2Code()); $r->setDestRegionCode($request->getDestRegionCode()); if ($request->getDestPostcode()) { $r->setDestPostal($request->getDestPostcode()); } else { } $weight = $this->getTotalNumOfBoxes($request->getPackageWeight()); $weight = $this->_getCorrectWeight($weight); $r->setWeight($weight); if ($request->getFreeMethodWeight()!=$request->getPackageWeight()) { $r->setFreeMethodWeight($request->getFreeMethodWeight()); } $r->setValue($request->getPackageValue()); $r->setValueWithDiscount($request->getPackageValueWithDiscount()); if ($request->getUpsUnitMeasure()) { $unit = $request->getUpsUnitMeasure(); } else { $unit = $this->getConfigData('unit_of_measure'); } $r->setUnitMeasure($unit); $r->setIsReturn($request->getIsReturn()); $r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax()); $this->_rawRequest = $r; return $this; } /** * Get correct weigt. * * Namely: * Checks the current weight to comply with the minimum weight standards set by the carrier. * Then strictly rounds the weight up until the first significant digit after the decimal point. * * @param float|integer|double $weight * @return float */ protected function _getCorrectWeight($weight) { $minWeight = $this->getConfigData('min_package_weight'); if($weight < $minWeight){ $weight = $minWeight; } //rounds a number to one significant figure $weight = ceil($weight*10) / 10; return $weight; } /** * Get result of request * * @return mixed */ public function getResult() { return $this->_result; } /** * Do remote request for and handle errors * * @return Mage_Shipping_Model_Rate_Result */ protected function _getQuotes() { switch ($this->getConfigData('type')) { case 'UPS': return $this->_getCgiQuotes(); case 'UPS_XML': return $this->_getXmlQuotes(); } return null; } /** * Set free method request * * @param string $freeMethod * @return null */ protected function _setFreeMethodRequest($freeMethod) { $r = $this->_rawRequest; $weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight()); $weight = $this->_getCorrectWeight($weight); $r->setWeight($weight); $r->setAction($this->getCode('action', 'single')); $r->setProduct($freeMethod); } /** * Get cgi rates * * @return Mage_Shipping_Model_Rate_Result */ protected function _getCgiQuotes() { $r = $this->_rawRequest; $params = array( 'accept_UPS_license_agreement' => 'yes', '10_action' => $r->getAction(), '13_product' => $r->getProduct(), '14_origCountry' => $r->getOrigCountry(), '15_origPostal' => $r->getOrigPostal(), 'origCity' => $r->getOrigCity(), '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ? substr($r->getDestPostal(), 0, 5) : $r->getDestPostal(), '22_destCountry' => $r->getDestCountry(), '23_weight' => $r->getWeight(), '47_rate_chart' => $r->getPickup(), '48_container' => $r->getContainer(), '49_residential' => $r->getDestType(), 'weight_std' => strtolower($r->getUnitMeasure()), ); $params['47_rate_chart'] = $params['47_rate_chart']['label']; $responseBody = $this->_getCachedQuotes($params); if ($responseBody === null) { $debugData = array('request' => $params); try { $url = $this->getConfigData('gateway_url'); if (!$url) { $url = $this->_defaultCgiGatewayUrl; } $client = new Zend_Http_Client(); $client->setUri($url); $client->setConfig(array('maxredirects'=>0, 'timeout'=>30)); $client->setParameterGet($params); $response = $client->request(); $responseBody = $response->getBody(); $debugData['result'] = $responseBody; $this->_setCachedQuotes($params, $responseBody); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); $responseBody = ''; } $this->_debug($debugData); } return $this->_parseCgiResponse($responseBody); } /** * Get shipment by code * * @param string $code * @param string $origin * @return array|bool */ public function getShipmentByCode($code, $origin = null){ if($origin===null){ $origin = $this->getConfigData('origin_shipment'); } $arr = $this->getCode('originShipment',$origin); if(isset($arr[$code])) return $arr[$code]; else return false; } /** * Prepare shipping rate result based on response * * @param mixed $response * @return Mage_Shipping_Model_Rate_Result */ protected function _parseCgiResponse($response) { $costArr = array(); $priceArr = array(); $errorTitle = Mage::helper('usa')->__('Unknown error'); if (strlen(trim($response))>0) { $rRows = explode("\n", $response); $allowedMethods = explode(",", $this->getConfigData('allowed_methods')); foreach ($rRows as $rRow) { $r = explode('%', $rRow); switch (substr($r[0],-1)) { case 3: case 4: if (in_array($r[1], $allowedMethods)) { $responsePrice = Mage::app()->getLocale()->getNumber($r[10]); $costArr[$r[1]] = $responsePrice; $priceArr[$r[1]] = $this->getMethodPrice($responsePrice, $r[1]); } break; case 5: $errorTitle = $r[1]; break; case 6: if (in_array($r[3], $allowedMethods)) { $responsePrice = Mage::app()->getLocale()->getNumber($r[10]); $costArr[$r[3]] = $responsePrice; $priceArr[$r[3]] = $this->getMethodPrice($responsePrice, $r[3]); } break; } } asort($priceArr); } $result = Mage::getModel('shipping/rate_result'); $defaults = $this->getDefaults(); if (empty($priceArr)) { $error = Mage::getModel('shipping/rate_result_error'); $error->setCarrier('ups'); $error->setCarrierTitle($this->getConfigData('title')); $error->setErrorMessage($this->getConfigData('specificerrmsg')); $result->append($error); } else { foreach ($priceArr as $method=>$price) { $rate = Mage::getModel('shipping/rate_result_method'); $rate->setCarrier('ups'); $rate->setCarrierTitle($this->getConfigData('title')); $rate->setMethod($method); $method_arr = $this->getCode('method', $method); $rate->setMethodTitle($method_arr); $rate->setCost($costArr[$method]); $rate->setPrice($price); $result->append($rate); } } return $result; } /** * Get configuration data of carrier * * @param string $type * @param string $code * @return array|bool */ public function getCode($type, $code='') { $codes = array( 'action'=>array( 'single'=>'3', 'all'=>'4', ), 'originShipment'=>array( // United States Domestic Shipments 'United States Domestic Shipments' => array( '01' => Mage::helper('usa')->__('UPS Next Day Air'), '02' => Mage::helper('usa')->__('UPS Second Day Air'), '03' => Mage::helper('usa')->__('UPS Ground'), '07' => Mage::helper('usa')->__('UPS Worldwide Express'), '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '12' => Mage::helper('usa')->__('UPS Three-Day Select'), '13' => Mage::helper('usa')->__('UPS Next Day Air Saver'), '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'), '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'), '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'), '65' => Mage::helper('usa')->__('UPS Saver'), ), // Shipments Originating in United States 'Shipments Originating in United States' => array( '01' => Mage::helper('usa')->__('UPS Next Day Air'), '02' => Mage::helper('usa')->__('UPS Second Day Air'), '03' => Mage::helper('usa')->__('UPS Ground'), '07' => Mage::helper('usa')->__('UPS Worldwide Express'), '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '12' => Mage::helper('usa')->__('UPS Three-Day Select'), '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'), '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'), '59' => Mage::helper('usa')->__('UPS Second Day Air A.M.'), '65' => Mage::helper('usa')->__('UPS Worldwide Saver'), ), // Shipments Originating in Canada 'Shipments Originating in Canada' => array( '01' => Mage::helper('usa')->__('UPS Express'), '02' => Mage::helper('usa')->__('UPS Expedited'), '07' => Mage::helper('usa')->__('UPS Worldwide Express'), '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '12' => Mage::helper('usa')->__('UPS Three-Day Select'), '14' => Mage::helper('usa')->__('UPS Express Early A.M.'), '65' => Mage::helper('usa')->__('UPS Saver'), ), // Shipments Originating in the European Union 'Shipments Originating in the European Union' => array( '07' => Mage::helper('usa')->__('UPS Express'), '08' => Mage::helper('usa')->__('UPS Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '54' => Mage::helper('usa')->__('UPS Worldwide Express PlusSM'), '65' => Mage::helper('usa')->__('UPS Saver'), ), // Polish Domestic Shipments 'Polish Domestic Shipments' => array( '07' => Mage::helper('usa')->__('UPS Express'), '08' => Mage::helper('usa')->__('UPS Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'), '65' => Mage::helper('usa')->__('UPS Saver'), '82' => Mage::helper('usa')->__('UPS Today Standard'), '83' => Mage::helper('usa')->__('UPS Today Dedicated Courrier'), '84' => Mage::helper('usa')->__('UPS Today Intercity'), '85' => Mage::helper('usa')->__('UPS Today Express'), '86' => Mage::helper('usa')->__('UPS Today Express Saver'), ), // Puerto Rico Origin 'Puerto Rico Origin' => array( '01' => Mage::helper('usa')->__('UPS Next Day Air'), '02' => Mage::helper('usa')->__('UPS Second Day Air'), '03' => Mage::helper('usa')->__('UPS Ground'), '07' => Mage::helper('usa')->__('UPS Worldwide Express'), '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'), '14' => Mage::helper('usa')->__('UPS Next Day Air Early A.M.'), '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'), '65' => Mage::helper('usa')->__('UPS Saver'), ), // Shipments Originating in Mexico 'Shipments Originating in Mexico' => array( '07' => Mage::helper('usa')->__('UPS Express'), '08' => Mage::helper('usa')->__('UPS Expedited'), '54' => Mage::helper('usa')->__('UPS Express Plus'), '65' => Mage::helper('usa')->__('UPS Saver'), ), // Shipments Originating in Other Countries 'Shipments Originating in Other Countries' => array( '07' => Mage::helper('usa')->__('UPS Express'), '08' => Mage::helper('usa')->__('UPS Worldwide Expedited'), '11' => Mage::helper('usa')->__('UPS Standard'), '54' => Mage::helper('usa')->__('UPS Worldwide Express Plus'), '65' => Mage::helper('usa')->__('UPS Saver') ) ), 'method'=>array( '1DM' => Mage::helper('usa')->__('Next Day Air Early AM'), '1DML' => Mage::helper('usa')->__('Next Day Air Early AM Letter'), '1DA' => Mage::helper('usa')->__('Next Day Air'), '1DAL' => Mage::helper('usa')->__('Next Day Air Letter'), '1DAPI' => Mage::helper('usa')->__('Next Day Air Intra (Puerto Rico)'), '1DP' => Mage::helper('usa')->__('Next Day Air Saver'), '1DPL' => Mage::helper('usa')->__('Next Day Air Saver Letter'), '2DM' => Mage::helper('usa')->__('2nd Day Air AM'), '2DML' => Mage::helper('usa')->__('2nd Day Air AM Letter'), '2DA' => Mage::helper('usa')->__('2nd Day Air'), '2DAL' => Mage::helper('usa')->__('2nd Day Air Letter'), '3DS' => Mage::helper('usa')->__('3 Day Select'), 'GND' => Mage::helper('usa')->__('Ground'), 'GNDCOM' => Mage::helper('usa')->__('Ground Commercial'), 'GNDRES' => Mage::helper('usa')->__('Ground Residential'), 'STD' => Mage::helper('usa')->__('Canada Standard'), 'XPR' => Mage::helper('usa')->__('Worldwide Express'), 'WXS' => Mage::helper('usa')->__('Worldwide Express Saver'), 'XPRL' => Mage::helper('usa')->__('Worldwide Express Letter'), 'XDM' => Mage::helper('usa')->__('Worldwide Express Plus'), 'XDML' => Mage::helper('usa')->__('Worldwide Express Plus Letter'), 'XPD' => Mage::helper('usa')->__('Worldwide Expedited'), ), 'pickup'=>array( 'RDP' => array("label"=>'Regular Daily Pickup',"code"=>"01"), 'OCA' => array("label"=>'On Call Air',"code"=>"07"), 'OTP' => array("label"=>'One Time Pickup',"code"=>"06"), 'LC' => array("label"=>'Letter Center',"code"=>"19"), 'CC' => array("label"=>'Customer Counter',"code"=>"03"), ), 'container'=>array( 'CP' => '00', // Customer Packaging 'ULE' => '01', // UPS Letter Envelope 'CSP' => '02', // Customer Supplied Package 'UT' => '03', // UPS Tube 'PAK' => '04', // PAK 'UEB' => '21', // UPS Express Box 'UW25' => '24', // UPS Worldwide 25 kilo 'UW10' => '25', // UPS Worldwide 10 kilo 'PLT' => '30', // Pallet 'SEB' => '2a', // Small Express Box 'MEB' => '2b', // Medium Express Box 'LEB' => '2c', // Large Express Box ), 'container_description'=>array( 'CP' => Mage::helper('usa')->__('Customer Packaging'), 'ULE' => Mage::helper('usa')->__('UPS Letter Envelope'), 'CSP' => Mage::helper('usa')->__('Customer Supplied Package'), 'UT' => Mage::helper('usa')->__('UPS Tube'), 'PAK' => Mage::helper('usa')->__('PAK'), 'UEB' => Mage::helper('usa')->__('UPS Express Box'), 'UW25' => Mage::helper('usa')->__('UPS Worldwide 25 kilo'), 'UW10' => Mage::helper('usa')->__('UPS Worldwide 10 kilo'), 'PLT' => Mage::helper('usa')->__('Pallet'), 'SEB' => Mage::helper('usa')->__('Small Express Box'), 'MEB' => Mage::helper('usa')->__('Medium Express Box'), 'LEB' => Mage::helper('usa')->__('Large Express Box'), ), 'dest_type'=>array( 'RES' => '01', // Residential 'COM' => '02', // Commercial ), 'dest_type_description'=>array( 'RES' => Mage::helper('usa')->__('Residential'), 'COM' => Mage::helper('usa')->__('Commercial'), ), 'unit_of_measure'=>array( 'LBS' => Mage::helper('usa')->__('Pounds'), 'KGS' => Mage::helper('usa')->__('Kilograms'), ), 'containers_filter' => array( array( 'containers' => array('00'), // Customer Packaging 'filters' => array( 'within_us' => array( 'method' => array( '01', // Next Day Air '13', // Next Day Air Saver '12', // 3 Day Select '59', // 2nd Day Air AM '03', // Ground '14', // Next Day Air Early AM '02', // 2nd Day Air ) ), 'from_us' => array( 'method' => array( '07', // Worldwide Express '54', // Worldwide Express Plus '08', // Worldwide Expedited '65', // Worldwide Saver '11', // Standard ) ) ) ), array( // Small Express Box, Medium Express Box, Large Express Box, UPS Tube 'containers' => array('2a', '2b', '2c', '03'), 'filters' => array( 'within_us' => array( 'method' => array( '01', // Next Day Air '13', // Next Day Air Saver '14', // Next Day Air Early AM '02', // 2nd Day Air '59', // 2nd Day Air AM '13', // Next Day Air Saver ) ), 'from_us' => array( 'method' => array( '07', // Worldwide Express '54', // Worldwide Express Plus '08', // Worldwide Expedited '65', // Worldwide Saver ) ) ) ), array( 'containers' => array('24', '25'), // UPS Worldwide 25 kilo, UPS Worldwide 10 kilo 'filters' => array( 'within_us' => array( 'method' => array() ), 'from_us' => array( 'method' => array( '07', // Worldwide Express '54', // Worldwide Express Plus '65', // Worldwide Saver ) ) ) ), array( 'containers' => array('01', '04'), // UPS Letter, UPS PAK 'filters' => array( 'within_us' => array( 'method' => array( '01', // Next Day Air '14', // Next Day Air Early AM '02', // 2nd Day Air '59', // 2nd Day Air AM '13', // Next Day Air Saver ) ), 'from_us' => array( 'method' => array( '07', // Worldwide Express '54', // Worldwide Express Plus '65', // Worldwide Saver ) ) ) ), array( 'containers' => array('04'), // UPS PAK 'filters' => array( 'within_us' => array( 'method' => array() ), 'from_us' => array( 'method' => array( '08', // Worldwide Expedited ) ) ) ), ) ); if (!isset($codes[$type])) { return false; } elseif (''===$code) { return $codes[$type]; } if (!isset($codes[$type][$code])) { return false; } else { return $codes[$type][$code]; } } /** * Get xml rates * * @return Mage_Shipping_Model_Rate_Result */ protected function _getXmlQuotes() { $url = $this->getConfigData('gateway_xml_url'); if (!$url) { $url = $this->_defaultUrls['Rate']; } $this->setXMLAccessRequest(); $xmlRequest=$this->_xmlAccessRequest; $r = $this->_rawRequest; $params = array( 'accept_UPS_license_agreement' => 'yes', '10_action' => $r->getAction(), '13_product' => $r->getProduct(), '14_origCountry' => $r->getOrigCountry(), '15_origPostal' => $r->getOrigPostal(), 'origCity' => $r->getOrigCity(), 'origRegionCode' => $r->getOrigRegionCode(), '19_destPostal' => Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID == $r->getDestCountry() ? substr($r->getDestPostal(), 0, 5) : $r->getDestPostal(), '22_destCountry' => $r->getDestCountry(), 'destRegionCode' => $r->getDestRegionCode(), '23_weight' => $r->getWeight(), '47_rate_chart' => $r->getPickup(), '48_container' => $r->getContainer(), '49_residential' => $r->getDestType(), ); if ($params['10_action'] == '4') { $params['10_action'] = 'Shop'; $serviceCode = null; // Service code is not relevant when we're asking ALL possible services' rates } else { $params['10_action'] = 'Rate'; $serviceCode = $r->getProduct() ? $r->getProduct() : ''; } $serviceDescription = $serviceCode ? $this->getShipmentByCode($serviceCode) : ''; $xmlRequest .= <<< XMLRequest Rating and Service 1.0 Rate {$params['10_action']} {$params['47_rate_chart']['code']} {$params['47_rate_chart']['label']} XMLRequest; if ($serviceCode !== null) { $xmlRequest .= "" . "{$serviceCode}" . "{$serviceDescription}" . ""; } $xmlRequest .= <<< XMLRequest XMLRequest; if ($this->getConfigFlag('negotiated_active') && ($shipper = $this->getConfigData('shipper_number')) ) { $xmlRequest .= "{$shipper}"; } if ($r->getIsReturn()) { $shipperCity = ''; $shipperPostalCode = $params['19_destPostal']; $shipperCountryCode = $params['22_destCountry']; $shipperStateProvince = $params['destRegionCode']; } else { $shipperCity = $params['origCity']; $shipperPostalCode = $params['15_origPostal']; $shipperCountryCode = $params['14_origCountry']; $shipperStateProvince = $params['origRegionCode']; } $xmlRequest .= <<< XMLRequest
{$shipperCity} {$shipperPostalCode} {$shipperCountryCode} {$shipperStateProvince}
{$params['19_destPostal']} {$params['22_destCountry']} {$params['49_residential']} {$params['destRegionCode']} XMLRequest; $xmlRequest .= ($params['49_residential']==='01' ? "{$params['49_residential']}" : '' ); $xmlRequest .= <<< XMLRequest
{$params['15_origPostal']} {$params['14_origCountry']} {$params['origRegionCode']}
{$params['48_container']} {$r->getUnitMeasure()} {$params['23_weight']} XMLRequest; if ($this->getConfigFlag('negotiated_active')) { $xmlRequest .= ""; } $xmlRequest .= <<< XMLRequest
XMLRequest; $xmlResponse = $this->_getCachedQuotes($xmlRequest); if ($xmlResponse === null) { $debugData = array('request' => $xmlRequest); try { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->getConfigFlag('verify_peer')); $xmlResponse = curl_exec ($ch); $debugData['result'] = $xmlResponse; $this->_setCachedQuotes($xmlRequest, $xmlResponse); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); $xmlResponse = ''; } $this->_debug($debugData); } return $this->_parseXmlResponse($xmlResponse); } /** * Get base currency rate * * @param string $code * @return double */ protected function _getBaseCurrencyRate($code) { if (!$this->_baseCurrencyRate) { $this->_baseCurrencyRate = Mage::getModel('directory/currency') ->load($code) ->getAnyRate($this->_request->getBaseCurrency()->getCode()); } return $this->_baseCurrencyRate; } /** * Prepare shipping rate result based on response * * @param mixed $response * @return Mage_Shipping_Model_Rate_Result */ protected function _parseXmlResponse($xmlResponse) { $costArr = array(); $priceArr = array(); if (strlen(trim($xmlResponse))>0) { $xml = new Varien_Simplexml_Config(); $xml->loadString($xmlResponse); $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/ResponseStatusCode/text()"); $success = (int)$arr[0]; if ($success===1) { $arr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment"); $allowedMethods = explode(",", $this->getConfigData('allowed_methods')); // Negotiated rates $negotiatedArr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment/NegotiatedRates"); $negotiatedActive = $this->getConfigFlag('negotiated_active') && $this->getConfigData('shipper_number') && !empty($negotiatedArr); $allowedCurrencies = Mage::getModel('directory/currency')->getConfigAllowCurrencies(); foreach ($arr as $shipElement){ $code = (string)$shipElement->Service->Code; if (in_array($code, $allowedMethods)) { if ($negotiatedActive) { $cost = $shipElement->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue; } else { $cost = $shipElement->TotalCharges->MonetaryValue; } //convert price with Origin country currency code to base currency code $successConversion = true; $responseCurrencyCode = (string) $shipElement->TotalCharges->CurrencyCode; if ($responseCurrencyCode) { if (in_array($responseCurrencyCode, $allowedCurrencies)) { $cost = (float) $cost * $this->_getBaseCurrencyRate($responseCurrencyCode); } else { $errorTitle = Mage::helper('directory')->__('Can\'t convert rate from "%s-%s".', $responseCurrencyCode, $this->_request->getPackageCurrency()->getCode()); $error = Mage::getModel('shipping/rate_result_error'); $error->setCarrier('ups'); $error->setCarrierTitle($this->getConfigData('title')); $error->setErrorMessage($errorTitle); $successConversion = false; } } if ($successConversion) { $costArr[$code] = $cost; $priceArr[$code] = $this->getMethodPrice(floatval($cost),$code); } } } } else { $arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/Error/ErrorDescription/text()"); $errorTitle = (string)$arr[0][0]; $error = Mage::getModel('shipping/rate_result_error'); $error->setCarrier('ups'); $error->setCarrierTitle($this->getConfigData('title')); $error->setErrorMessage($this->getConfigData('specificerrmsg')); } } $result = Mage::getModel('shipping/rate_result'); $defaults = $this->getDefaults(); if (empty($priceArr)) { $error = Mage::getModel('shipping/rate_result_error'); $error->setCarrier('ups'); $error->setCarrierTitle($this->getConfigData('title')); if(!isset($errorTitle)){ $errorTitle = Mage::helper('usa')->__('Cannot retrieve shipping rates'); } $error->setErrorMessage($this->getConfigData('specificerrmsg')); $result->append($error); } else { foreach ($priceArr as $method=>$price) { $rate = Mage::getModel('shipping/rate_result_method'); $rate->setCarrier('ups'); $rate->setCarrierTitle($this->getConfigData('title')); $rate->setMethod($method); $method_arr = $this->getShipmentByCode($method); $rate->setMethodTitle($method_arr); $rate->setCost($costArr[$method]); $rate->setPrice($price); $result->append($rate); } } return $result; } /** * Get tracking * * @param mixed $trackings * @return mixed */ public function getTracking($trackings) { $return = array(); if (!is_array($trackings)) { $trackings = array($trackings); } if ($this->getConfigData('type')=='UPS') { $this->_getCgiTracking($trackings); } elseif ($this->getConfigData('type')=='UPS_XML'){ $this->setXMLAccessRequest(); $this->_getXmlTracking($trackings); } return $this->_result; } /** * Set xml access request * * @return null */ protected function setXMLAccessRequest() { $userid = $this->getConfigData('username'); $userid_pass = $this->getConfigData('password'); $access_key = $this->getConfigData('access_license_number'); $this->_xmlAccessRequest = << $access_key $userid $userid_pass XMLAuth; } /** * Get cgi tracking * * @param mixed $trackings * @return mixed */ protected function _getCgiTracking($trackings) { //ups no longer support tracking for data streaming version //so we can only reply the popup window to ups. $result = Mage::getModel('shipping/tracking_result'); $defaults = $this->getDefaults(); foreach($trackings as $tracking){ $status = Mage::getModel('shipping/tracking_result_status'); $status->setCarrier('ups'); $status->setCarrierTitle($this->getConfigData('title')); $status->setTracking($tracking); $status->setPopup(1); $status->setUrl("http://wwwapps.ups.com/WebTracking/processInputRequest?HTMLVersion=5.0&error_carried=true" . "&tracknums_displayed=5&TypeOfInquiryNumber=T&loc=en_US&InquiryNumber1=$tracking" . "&AgreeToTermsAndConditions=yes" ); $result->append($status); } $this->_result = $result; return $result; } /** * Get xml tracking * * @param mixed $trackings * @return mixed */ protected function _getXmlTracking($trackings) { $url = $this->getConfigData('tracking_xml_url'); if (!$url) { $url = $this->_defaultUrls['Track']; } foreach($trackings as $tracking){ $xmlRequest=$this->_xmlAccessRequest; /* * RequestOption==>'activity' or '1' to request all activities */ $xmlRequest .= << Track activity $tracking 01 XMLAuth; $debugData = array('request' => $xmlRequest); try { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $xmlResponse = curl_exec ($ch); $debugData['result'] = $xmlResponse; curl_close ($ch); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); $xmlResponse = ''; } $this->_debug($debugData); $this->_parseXmlTrackingResponse($tracking, $xmlResponse); } return $this->_result; } /** * Parse xml tracking response * * @param string $trackingvalue * @param string $response * @return null */ protected function _parseXmlTrackingResponse($trackingvalue, $xmlResponse) { $errorTitle = 'Unable to retrieve tracking'; $resultArr = array(); $packageProgress = array(); if ($xmlResponse) { $xml = new Varien_Simplexml_Config(); $xml->loadString($xmlResponse); $arr = $xml->getXpath("//TrackResponse/Response/ResponseStatusCode/text()"); $success = (int)$arr[0][0]; if($success===1){ $arr = $xml->getXpath("//TrackResponse/Shipment/Service/Description/text()"); $resultArr['service'] = (string)$arr[0]; $arr = $xml->getXpath("//TrackResponse/Shipment/PickupDate/text()"); $resultArr['shippeddate'] = (string)$arr[0]; $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/Weight/text()"); $weight = (string)$arr[0]; $arr = $xml->getXpath("//TrackResponse/Shipment/Package/PackageWeight/UnitOfMeasurement/Code/text()"); $unit = (string)$arr[0]; $resultArr['weight'] = "{$weight} {$unit}"; $activityTags = $xml->getXpath("//TrackResponse/Shipment/Package/Activity"); if ($activityTags) { $i=1; foreach ($activityTags as $activityTag) { $addArr=array(); if (isset($activityTag->ActivityLocation->Address->City)) { $addArr[] = (string)$activityTag->ActivityLocation->Address->City; } if (isset($activityTag->ActivityLocation->Address->StateProvinceCode)) { $addArr[] = (string)$activityTag->ActivityLocation->Address->StateProvinceCode; } if (isset($activityTag->ActivityLocation->Address->CountryCode)) { $addArr[] = (string)$activityTag->ActivityLocation->Address->CountryCode; } $dateArr = array(); $date = (string)$activityTag->Date;//YYYYMMDD $dateArr[] = substr($date,0,4); $dateArr[] = substr($date,4,2); $dateArr[] = substr($date,-2,2); $timeArr = array(); $time = (string)$activityTag->Time;//HHMMSS $timeArr[] = substr($time,0,2); $timeArr[] = substr($time,2,2); $timeArr[] = substr($time,-2,2); if($i==1){ $resultArr['status'] = (string)$activityTag->Status->StatusType->Description; $resultArr['deliverydate'] = implode('-',$dateArr);//YYYY-MM-DD $resultArr['deliverytime'] = implode(':',$timeArr);//HH:MM:SS $resultArr['deliverylocation'] = (string)$activityTag->ActivityLocation->Description; $resultArr['signedby'] = (string)$activityTag->ActivityLocation->SignedForByName; if ($addArr) { $resultArr['deliveryto']=implode(', ',$addArr); } }else{ $tempArr=array(); $tempArr['activity'] = (string)$activityTag->Status->StatusType->Description; $tempArr['deliverydate'] = implode('-',$dateArr);//YYYY-MM-DD $tempArr['deliverytime'] = implode(':',$timeArr);//HH:MM:SS if ($addArr) { $tempArr['deliverylocation']=implode(', ',$addArr); } $packageProgress[] = $tempArr; } $i++; } $resultArr['progressdetail'] = $packageProgress; } } else { $arr = $xml->getXpath("//TrackResponse/Response/Error/ErrorDescription/text()"); $errorTitle = (string)$arr[0][0]; } } if (!$this->_result) { $this->_result = Mage::getModel('shipping/tracking_result'); } $defaults = $this->getDefaults(); if ($resultArr) { $tracking = Mage::getModel('shipping/tracking_result_status'); $tracking->setCarrier('ups'); $tracking->setCarrierTitle($this->getConfigData('title')); $tracking->setTracking($trackingvalue); $tracking->addData($resultArr); $this->_result->append($tracking); } else { $error = Mage::getModel('shipping/tracking_result_error'); $error->setCarrier('ups'); $error->setCarrierTitle($this->getConfigData('title')); $error->setTracking($trackingvalue); $error->setErrorMessage($errorTitle); $this->_result->append($error); } return $this->_result; } /** * Get tracking response * * @return string */ public function getResponse() { $statuses = ''; if ($this->_result instanceof Mage_Shipping_Model_Tracking_Result){ if ($trackings = $this->_result->getAllTrackings()) { foreach ($trackings as $tracking){ if($data = $tracking->getAllData()){ if (isset($data['status'])) { $statuses .= Mage::helper('usa')->__($data['status']); } else { $statuses .= Mage::helper('usa')->__($data['error_message']); } } } } } if (empty($statuses)) { $statuses = Mage::helper('usa')->__('Empty response'); } return $statuses; } /** * Get allowed shipping methods * * @return array */ public function getAllowedMethods() { $allowed = explode(',', $this->getConfigData('allowed_methods')); $arr = array(); $isByCode = $this->getConfigData('type') == 'UPS_XML'; foreach ($allowed as $k) { $arr[$k] = $isByCode ? $this->getShipmentByCode($k) : $this->getCode('method', $k); } return $arr; } /** * Form XML for shipment request * * @param Varien_Object $request * @return string */ protected function _formShipmentRequest(Varien_Object $request) { $packageParams = $request->getPackageParams(); $height = $packageParams->getHeight(); $width = $packageParams->getWidth(); $length = $packageParams->getLength(); $weightUnits = $packageParams->getWeightUnits() == Zend_Measure_Weight::POUND ? 'LBS' : 'KGS'; $dimensionsUnits = $packageParams->getDimensionUnits() == Zend_Measure_Length::INCH ? 'IN' : 'CM'; $itemsDesc = array(); $itemsShipment = $request->getPackageItems(); foreach ($itemsShipment as $itemShipment) { $item = new Varien_Object(); $item->setData($itemShipment); $itemsDesc[] = $item->getName(); } $xmlRequest = new SimpleXMLElement(''); $requestPart = $xmlRequest->addChild('Request'); $requestPart->addChild('RequestAction', 'ShipConfirm'); $requestPart->addChild('RequestOption', 'nonvalidate'); $shipmentPart = $xmlRequest->addChild('Shipment'); if ($request->getIsReturn()) { $returnPart = $shipmentPart->addChild('ReturnService'); // UPS Print Return Label $returnPart->addChild('Code', '9'); } $shipmentPart->addChild('Description', substr(implode(' ', $itemsDesc), 0, 35));//empirical $shipperPart = $shipmentPart->addChild('Shipper'); if ($request->getIsReturn()) { $shipperPart->addChild('Name', $request->getRecipientContactCompanyName()); $shipperPart->addChild('AttentionName', $request->getRecipientContactPersonName()); $shipperPart->addChild('ShipperNumber', $this->getConfigData('shipper_number')); $shipperPart->addChild('PhoneNumber', $request->getRecipientContactPhoneNumber()); $addressPart = $shipperPart->addChild('Address'); $addressPart->addChild('AddressLine1', $request->getRecipientAddressStreet()); $addressPart->addChild('AddressLine2', $request->getRecipientAddressStreet2()); $addressPart->addChild('City', $request->getRecipientAddressCity()); $addressPart->addChild('CountryCode', $request->getRecipientAddressCountryCode()); $addressPart->addChild('PostalCode', $request->getRecipientAddressPostalCode()); if ($request->getRecipientAddressStateOrProvinceCode()) { $addressPart->addChild('StateProvinceCode', $request->getRecipientAddressStateOrProvinceCode()); } } else { $shipperPart->addChild('Name', $request->getShipperContactCompanyName()); $shipperPart->addChild('AttentionName', $request->getShipperContactPersonName()); $shipperPart->addChild('ShipperNumber', $this->getConfigData('shipper_number')); $shipperPart->addChild('PhoneNumber', $request->getShipperContactPhoneNumber()); $addressPart = $shipperPart->addChild('Address'); $addressPart->addChild('AddressLine1', $request->getShipperAddressStreet()); $addressPart->addChild('AddressLine2', $request->getShipperAddressStreet2()); $addressPart->addChild('City', $request->getShipperAddressCity()); $addressPart->addChild('CountryCode', $request->getShipperAddressCountryCode()); $addressPart->addChild('PostalCode', $request->getShipperAddressPostalCode()); if ($request->getShipperAddressStateOrProvinceCode()) { $addressPart->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode()); } } $shipToPart = $shipmentPart->addChild('ShipTo'); $shipToPart->addChild('AttentionName', $request->getRecipientContactPersonName()); $shipToPart->addChild('CompanyName', $request->getRecipientContactCompanyName() ? $request->getRecipientContactCompanyName() : 'N/A'); $shipToPart->addChild('PhoneNumber', $request->getRecipientContactPhoneNumber()); $addressPart = $shipToPart->addChild('Address'); $addressPart->addChild('AddressLine1', $request->getRecipientAddressStreet1()); $addressPart->addChild('AddressLine2', $request->getRecipientAddressStreet2()); $addressPart->addChild('City', $request->getRecipientAddressCity()); $addressPart->addChild('CountryCode', $request->getRecipientAddressCountryCode()); $addressPart->addChild('PostalCode', $request->getRecipientAddressPostalCode()); if ($request->getRecipientAddressStateOrProvinceCode()) { $addressPart->addChild('StateProvinceCode', $request->getRecipientAddressRegionCode()); } if ($this->getConfigData('dest_type') == 'RES') { $addressPart->addChild('ResidentialAddress'); } if ($request->getIsReturn()) { $shipFromPart = $shipmentPart->addChild('ShipFrom'); $shipFromPart->addChild('AttentionName', $request->getShipperContactPersonName()); $shipFromPart->addChild('CompanyName', $request->getShipperContactCompanyName() ? $request->getShipperContactCompanyName() : $request->getShipperContactPersonName()); $shipFromAddress = $shipFromPart->addChild('Address'); $shipFromAddress->addChild('AddressLine1', $request->getShipperAddressStreet1()); $shipFromAddress->addChild('AddressLine2', $request->getShipperAddressStreet2()); $shipFromAddress->addChild('City', $request->getShipperAddressCity()); $shipFromAddress->addChild('CountryCode', $request->getShipperAddressCountryCode()); $shipFromAddress->addChild('PostalCode', $request->getShipperAddressPostalCode()); if ($request->getShipperAddressStateOrProvinceCode()) { $shipFromAddress->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode()); } $addressPart = $shipToPart->addChild('Address'); $addressPart->addChild('AddressLine1', $request->getShipperAddressStreet1()); $addressPart->addChild('AddressLine2', $request->getShipperAddressStreet2()); $addressPart->addChild('City', $request->getShipperAddressCity()); $addressPart->addChild('CountryCode', $request->getShipperAddressCountryCode()); $addressPart->addChild('PostalCode', $request->getShipperAddressPostalCode()); if ($request->getShipperAddressStateOrProvinceCode()) { $addressPart->addChild('StateProvinceCode', $request->getShipperAddressStateOrProvinceCode()); } if ($this->getConfigData('dest_type') == 'RES') { $addressPart->addChild('ResidentialAddress'); } } $servicePart = $shipmentPart->addChild('Service'); $servicePart->addChild('Code', $request->getShippingMethod()); $packagePart = $shipmentPart->addChild('Package'); $packagePart->addChild('Description', substr(implode(' ', $itemsDesc), 0, 35));//empirical $packagePart->addChild('PackagingType') ->addChild('Code', $request->getPackagingType()); $packageWeight = $packagePart->addChild('PackageWeight'); $packageWeight->addChild('Weight', $request->getPackageWeight()); $packageWeight->addChild('UnitOfMeasurement')->addChild('Code', $weightUnits); // set dimensions if ($length || $width || $height) { $packageDimensions = $packagePart->addChild('Dimensions'); $packageDimensions->addChild('UnitOfMeasurement')->addChild('Code', $dimensionsUnits); $packageDimensions->addChild('Length', $length); $packageDimensions->addChild('Width', $width); $packageDimensions->addChild('Height', $height); } // ups support reference number only for domestic service if ($this->_isUSCountry($request->getRecipientAddressCountryCode()) && $this->_isUSCountry($request->getShipperAddressCountryCode()) ) { if ($request->getReferenceData()) { $referenceData = $request->getReferenceData() . $request->getPackageId(); } else { $referenceData = 'Order #' . $request->getOrderShipment()->getOrder()->getIncrementId() . ' P' . $request->getPackageId(); } $referencePart = $packagePart->addChild('ReferenceNumber'); $referencePart->addChild('Code', '02'); $referencePart->addChild('Value', $referenceData); } $deliveryConfirmation = $packageParams->getDeliveryConfirmation(); if ($deliveryConfirmation) { /** @var $serviceOptionsNode SimpleXMLElement */ $serviceOptionsNode = null; switch ($this->_getDeliveryConfirmationLevel($request->getRecipientAddressCountryCode())) { case self::DELIVERY_CONFIRMATION_PACKAGE: $serviceOptionsNode = $packagePart->addChild('PackageServiceOptions'); break; case self::DELIVERY_CONFIRMATION_SHIPMENT: $serviceOptionsNode = $shipmentPart->addChild('ShipmentServiceOptions'); break; } if (!is_null($serviceOptionsNode)) { $serviceOptionsNode ->addChild('DeliveryConfirmation') ->addChild('DCISType', $packageParams->getDeliveryConfirmation()); } } $shipmentPart->addChild('PaymentInformation') ->addChild('Prepaid') ->addChild('BillShipper') ->addChild('AccountNumber', $this->getConfigData('shipper_number')); if ($request->getPackagingType() != $this->getCode('container', 'ULE') && $request->getShipperAddressCountryCode() == Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID && ($request->getRecipientAddressCountryCode() == 'CA' //Canada || $request->getRecipientAddressCountryCode() == 'PR' //Puerto Rico )) { $invoiceLineTotalPart = $shipmentPart->addChild('InvoiceLineTotal'); $invoiceLineTotalPart->addChild('CurrencyCode', $request->getBaseCurrencyCode()); $invoiceLineTotalPart->addChild('MonetaryValue', ceil($packageParams->getCustomsValue())); } $labelPart = $xmlRequest->addChild('LabelSpecification'); $labelPart->addChild('LabelPrintMethod') ->addChild('Code', 'GIF'); $labelPart->addChild('LabelImageFormat') ->addChild('Code', 'GIF'); $this->setXMLAccessRequest(); $xmlRequest = $this->_xmlAccessRequest . $xmlRequest->asXml(); return $xmlRequest; } /** * Send and process shipment accept request * * @param SimpleXMLElement * @return Varien_Object */ protected function _sendShipmentAcceptRequest(SimpleXMLElement $shipmentConfirmResponse) { $xmlRequest = new SimpleXMLElement(''); $request = $xmlRequest->addChild('Request'); $request->addChild('RequestAction', 'ShipAccept'); $xmlRequest->addChild('ShipmentDigest', $shipmentConfirmResponse->ShipmentDigest); $debugData = array('request' => $xmlRequest->asXML()); try { $url = $this->getConfigData('shipaccept_xml_url'); if (!$url) { $url = $this->_defaultUrls['ShipAccept']; } $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_xmlAccessRequest . $xmlRequest->asXML()); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->getConfigFlag('verify_peer')); $xmlResponse = curl_exec ($ch); $debugData['result'] = $xmlResponse; $this->_setCachedQuotes($xmlRequest, $xmlResponse); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); $xmlResponse = ''; } try { $response = new SimpleXMLElement($xmlResponse); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); } $result = new Varien_Object(); if (isset($response->Error)) { $result->setErrors((string)$response->Error->ErrorDescription); } else { $shippingLabelContent = (string)$response->ShipmentResults->PackageResults->LabelImage->GraphicImage; $trackingNumber = (string)$response->ShipmentResults->PackageResults->TrackingNumber; $result->setShippingLabelContent(base64_decode($shippingLabelContent)); $result->setTrackingNumber($trackingNumber); } $this->_debug($debugData); return $result; } /** * Do shipment request to carrier web service, obtain Print Shipping Labels and process errors in response * * @param Varien_Object $request * @return Varien_Object */ protected function _doShipmentRequest(Varien_Object $request) { $this->_prepareShipmentRequest($request); $result = new Varien_Object(); $xmlRequest = $this->_formShipmentRequest($request); $xmlResponse = $this->_getCachedQuotes($xmlRequest); if ($xmlResponse === null) { $url = $this->getConfigData('shipconfirm_xml_url'); if (!$url) { $url = $this->_defaultUrls['ShipConfirm']; } $debugData = array('request' => $xmlRequest); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->getConfigFlag('verify_peer')); $xmlResponse = curl_exec($ch); if ($xmlResponse === false) { throw new Exception(curl_error($ch)); } else { $debugData['result'] = $xmlResponse; $this->_setCachedQuotes($xmlRequest, $xmlResponse); } } try { $response = new SimpleXMLElement($xmlResponse); } catch (Exception $e) { $debugData['result'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); $result->setErrors($e->getMessage()); } if (isset($response->Response->Error) && in_array($response->Response->Error->ErrorSeverity, array('Hard', 'Transient')) ) { $result->setErrors((string)$response->Response->Error->ErrorDescription); } $this->_debug($debugData); if ($result->hasErrors() || empty($response)) { return $result; } else { return $this->_sendShipmentAcceptRequest($response); } } /** * Return container types of carrier * * @param Varien_Object|null $params * @return array|bool */ public function getContainerTypes(Varien_Object $params = null) { if ($params == null) { return $this->_getAllowedContainers($params); } $method = $params->getMethod(); $countryShipper = $params->getCountryShipper(); $countryRecipient = $params->getCountryRecipient(); if (($countryShipper == self::USA_COUNTRY_ID && $countryRecipient == self::CANADA_COUNTRY_ID) || ($countryShipper == self::CANADA_COUNTRY_ID && $countryRecipient == self::USA_COUNTRY_ID) || ($countryShipper == self::MEXICO_COUNTRY_ID && $countryRecipient == self::USA_COUNTRY_ID) && $method == '11' // UPS Standard ) { $containerTypes = array(); if ($method == '07' // Worldwide Express || $method == '08' // Worldwide Expedited || $method == '65' // Worldwide Saver ) { // Worldwide Expedited if ($method != '08') { $containerTypes = array( '01' => Mage::helper('usa')->__('UPS Letter Envelope'), '24' => Mage::helper('usa')->__('UPS Worldwide 25 kilo'), '25' => Mage::helper('usa')->__('UPS Worldwide 10 kilo'), ); } $containerTypes = $containerTypes + array( '03' => Mage::helper('usa')->__('UPS Tube'), '04' => Mage::helper('usa')->__('PAK'), '2a' => Mage::helper('usa')->__('Small Express Box'), '2b' => Mage::helper('usa')->__('Medium Express Box'), '2c' => Mage::helper('usa')->__('Large Express Box'), ); } return array('00' => Mage::helper('usa')->__('Customer Packaging')) + $containerTypes; } elseif ($countryShipper == self::USA_COUNTRY_ID && $countryRecipient == self::PUERTORICO_COUNTRY_ID && ($method == '03' // UPS Ground || $method == '02' // UPS Second Day Air || $method == '01' // UPS Next Day Air )) { // Container types should be the same as for domestic $params->setCountryRecipient(self::USA_COUNTRY_ID); $containerTypes = $this->_getAllowedContainers($params); $params->setCountryRecipient($countryRecipient); return $containerTypes; } return $this->_getAllowedContainers($params); } /** * Return all container types of carrier * * @return array|bool */ public function getContainerTypesAll() { $codes = $this->getCode('container'); $descriptions = $this->getCode('container_description'); $result = array(); foreach ($codes as $key => &$code) { $result[$code] = $descriptions[$key]; } return $result; } /** * Return structured data of containers witch related with shipping methods * * @return array|bool */ public function getContainerTypesFilter() { return $this->getCode('containers_filter'); } /** * Return delivery confirmation types of carrier * * @param Varien_Object|null $params * @return array|bool */ public function getDeliveryConfirmationTypes(Varien_Object $params = null) { $countryRecipient = $params != null ? $params->getCountryRecipient() : null; $deliveryConfirmationTypes = array(); switch ($this->_getDeliveryConfirmationLevel($countryRecipient)) { case self::DELIVERY_CONFIRMATION_PACKAGE: $deliveryConfirmationTypes = array( 1 => Mage::helper('usa')->__('Delivery Confirmation'), 2 => Mage::helper('usa')->__('Signature Required'), 3 => Mage::helper('usa')->__('Adult Signature Required'), ); break; case self::DELIVERY_CONFIRMATION_SHIPMENT: $deliveryConfirmationTypes = array( 1 => Mage::helper('usa')->__('Signature Required'), 2 => Mage::helper('usa')->__('Adult Signature Required'), ); } array_unshift($deliveryConfirmationTypes, Mage::helper('usa')->__('Not Required')); return $deliveryConfirmationTypes; } /** * Get Container Types, that could be customized for UPS carrier * * @return array */ public function getCustomizableContainerTypes() { $result = array(); $containerTypes = $this->getCode('container'); foreach (parent::getCustomizableContainerTypes() as $containerType) { $result[$containerType] = $containerTypes[$containerType]; } return $result; } /** * Get delivery confirmation level based on origin/destination * Return null if delivery confirmation is not acceptable * * @var string $countyDest * @return int|null */ protected function _getDeliveryConfirmationLevel($countyDest = null) { if (is_null($countyDest)) { return null; } if ($countyDest == Mage_Usa_Model_Shipping_Carrier_Abstract::USA_COUNTRY_ID) { return self::DELIVERY_CONFIRMATION_PACKAGE; } return self::DELIVERY_CONFIRMATION_SHIPMENT; } }