_carrierHelper = $carrierHelper;
$this->_productCollectionFactory = $productCollectionFactory;
$this->_httpClientFactory = $httpClientFactory;
parent::__construct(
$scopeConfig,
$rateErrorFactory,
$logger,
$xmlSecurity,
$xmlElFactory,
$rateFactory,
$rateMethodFactory,
$trackFactory,
$trackErrorFactory,
$trackStatusFactory,
$regionFactory,
$countryFactory,
$currencyFactory,
$directoryData,
$stockRegistry,
$data
);
}
/**
* Collect and get rates
*
* @param RateRequest $request
* @return \Magento\Quote\Model\Quote\Address\RateResult\Error|bool|Result
*/
public function collectRates(RateRequest $request)
{
if (!$this->canCollectRates()) {
return $this->getErrorMessage();
}
$this->setRequest($request);
$this->_result = $this->_getQuotes();
$this->_updateFreeMethodQuote($request);
return $this->getResult();
}
/**
* Prepare and set request to this instance
*
* @param \Magento\Quote\Model\Quote\Address\RateRequest $request
* @return $this
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function setRequest(\Magento\Quote\Model\Quote\Address\RateRequest $request)
{
$this->_request = $request;
$r = new \Magento\Framework\DataObject();
if ($request->getLimitMethod()) {
$r->setService($request->getLimitMethod());
} else {
$r->setService('ALL');
}
if ($request->getUspsUserid()) {
$userId = $request->getUspsUserid();
} else {
$userId = $this->getConfigData('userid');
}
$r->setUserId($userId);
if ($request->getUspsContainer()) {
$container = $request->getUspsContainer();
} else {
$container = $this->getConfigData('container');
}
$r->setContainer($container);
if ($request->getUspsSize()) {
$size = $request->getUspsSize();
} else {
$size = $this->getConfigData('size');
}
$r->setSize($size);
if ($request->getGirth()) {
$girth = $request->getGirth();
} else {
$girth = $this->getConfigData('girth');
}
$r->setGirth($girth);
if ($request->getHeight()) {
$height = $request->getHeight();
} else {
$height = $this->getConfigData('height');
}
$r->setHeight($height);
if ($request->getLength()) {
$length = $request->getLength();
} else {
$length = $this->getConfigData('length');
}
$r->setLength($length);
if ($request->getWidth()) {
$width = $request->getWidth();
} else {
$width = $this->getConfigData('width');
}
$r->setWidth($width);
if ($request->getUspsMachinable()) {
$machinable = $request->getUspsMachinable();
} else {
$machinable = $this->getConfigData('machinable');
}
$r->setMachinable($machinable);
if ($request->getOrigPostcode()) {
$r->setOrigPostal($request->getOrigPostcode());
} else {
$r->setOrigPostal(
$this->_scopeConfig->getValue(
\Magento\Sales\Model\Order\Shipment::XML_PATH_STORE_ZIP,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$request->getStoreId()
)
);
}
if ($request->getOrigCountryId()) {
$r->setOrigCountryId($request->getOrigCountryId());
} else {
$r->setOrigCountryId(
$this->_scopeConfig->getValue(
\Magento\Sales\Model\Order\Shipment::XML_PATH_STORE_COUNTRY_ID,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$request->getStoreId()
)
);
}
if ($request->getDestCountryId()) {
$destCountry = $request->getDestCountryId();
} else {
$destCountry = self::USA_COUNTRY_ID;
}
$r->setDestCountryId($destCountry);
if (!$this->_isUSCountry($destCountry)) {
$r->setDestCountryName($this->_getCountryName($destCountry));
}
if ($request->getDestPostcode()) {
$r->setDestPostal($request->getDestPostcode());
}
$weight = $this->getTotalNumOfBoxes($request->getPackageWeight());
$r->setWeightPounds(floor($weight));
$ounces = ($weight - floor($weight)) * self::OUNCES_POUND;
$r->setWeightOunces(sprintf('%.' . self::$weightPrecision . 'f', $ounces));
if ($request->getFreeMethodWeight() != $request->getPackageWeight()) {
$r->setFreeMethodWeight($request->getFreeMethodWeight());
}
$r->setValue($request->getPackageValue());
$r->setValueWithDiscount($request->getPackageValueWithDiscount());
$r->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
$this->setRawRequest($r);
return $this;
}
/**
* Get result of request
*
* @return Result|null
*/
public function getResult()
{
return $this->_result;
}
/**
* @inheritdoc
*
* Starting from 23.02.2018 USPS doesn't allow to create free shipping labels via their API.
*/
public function isShippingLabelsAvailable()
{
return false;
}
/**
* Get quotes
*
* @return Result
*/
protected function _getQuotes()
{
return $this->_getXmlQuotes();
}
/**
* Set free method request
*
* @param string $freeMethod
* @return void
*/
protected function _setFreeMethodRequest($freeMethod)
{
$r = $this->_rawRequest;
$weight = $this->getTotalNumOfBoxes($r->getFreeMethodWeight());
$r->setWeightPounds(floor($weight));
$ounces = ($weight - floor($weight)) * self::OUNCES_POUND;
$r->setWeightOunces(sprintf('%.' . self::$weightPrecision . 'f', $ounces));
$r->setService($freeMethod);
}
/**
* Build RateV3 request, send it to USPS gateway and retrieve quotes in XML format
*
* @link http://www.usps.com/webtools/htm/Rate-Calculators-v2-3.htm
* @return Result
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function _getXmlQuotes()
{
$r = $this->_rawRequest;
// The origin address(shipper) must be only in USA
if (!$this->_isUSCountry($r->getOrigCountryId())) {
$responseBody = '';
return $this->_parseXmlResponse($responseBody);
}
if ($this->_isUSCountry($r->getDestCountryId())) {
$xml = $this->_xmlElFactory->create(
['data' => '']
);
$xml->addAttribute('USERID', $r->getUserId());
// according to usps v4 documentation
$xml->addChild('Revision', '2');
$package = $xml->addChild('Package');
$package->addAttribute('ID', 0);
$service = $this->getCode('service_to_code', $r->getService());
if (!$service) {
$service = $r->getService();
}
if (strpos($r->getContainer(), 'FLAT RATE ENVELOPE') !== false ||
strpos($r->getContainer(), 'FLAT RATE BOX') !== false
) {
$service = 'Priority';
}
$package->addChild('Service', $service);
// no matter Letter, Flat or Parcel, use Parcel
if ($r->getService() == 'FIRST CLASS' || $r->getService() == 'FIRST CLASS HFP COMMERCIAL') {
$package->addChild('FirstClassMailType', 'PARCEL');
}
$package->addChild('ZipOrigination', $r->getOrigPostal());
//only 5 chars available
$package->addChild('ZipDestination', substr($r->getDestPostal(), 0, 5));
$package->addChild('Pounds', $r->getWeightPounds());
$package->addChild('Ounces', $r->getWeightOunces());
// Because some methods don't accept VARIABLE and (NON)RECTANGULAR containers
$package->addChild('Container', $r->getContainer());
$package->addChild('Size', $r->getSize());
if ($r->getSize() == 'LARGE') {
$package->addChild('Width', $r->getWidth());
$package->addChild('Length', $r->getLength());
$package->addChild('Height', $r->getHeight());
if ($r->getContainer() == 'NONRECTANGULAR' || $r->getContainer() == 'VARIABLE') {
$package->addChild('Girth', $r->getGirth());
}
}
$package->addChild('Machinable', $r->getMachinable());
$api = 'RateV4';
} else {
$xml = $this->_xmlElFactory->create(
['data' => '']
);
$xml->addAttribute('USERID', $r->getUserId());
// according to usps v4 documentation
$xml->addChild('Revision', '2');
$package = $xml->addChild('Package');
$package->addAttribute('ID', 0);
$package->addChild('Pounds', $r->getWeightPounds());
$package->addChild('Ounces', $r->getWeightOunces());
$package->addChild('MailType', 'All');
$package->addChild('ValueOfContents', $r->getValue());
$package->addChild('Country', $r->getDestCountryName());
$package->addChild('Container', $r->getContainer());
$package->addChild('Size', $r->getSize());
$width = $length = $height = $girth = '';
if ($r->getSize() == 'LARGE') {
$width = $r->getWidth();
$length = $r->getLength();
$height = $r->getHeight();
if ($r->getContainer() == 'NONRECTANGULAR') {
$girth = $r->getGirth();
}
}
$package->addChild('Width', $width);
$package->addChild('Length', $length);
$package->addChild('Height', $height);
$package->addChild('Girth', $girth);
$package->addChild('OriginZip', $r->getOrigPostal());
$package->addChild('AcceptanceDateTime', date('c'));
$package->addChild('DestinationPostalCode', $r->getDestPostal());
$api = 'IntlRateV2';
}
$request = $xml->asXML();
$responseBody = $this->_getCachedQuotes($request);
if ($responseBody === null) {
$debugData = ['request' => $this->filterDebugData($request)];
try {
$url = $this->getConfigData('gateway_url');
if (!$url) {
$url = $this->_defaultGatewayUrl;
}
$client = $this->_httpClientFactory->create();
$client->setUri($url);
$client->setConfig(['maxredirects' => 0, 'timeout' => 30]);
$client->setParameterGet('API', $api);
$client->setParameterGet('XML', $request);
$response = $client->request();
$responseBody = $response->getBody();
$debugData['result'] = $responseBody;
$this->_setCachedQuotes($request, $responseBody);
} catch (\Exception $e) {
$debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
$responseBody = '';
}
$this->_debug($debugData);
}
return $this->_parseXmlResponse($responseBody);
}
/**
* Parse calculated rates
*
* @param string $response
* @return Result
* @link http://www.usps.com/webtools/htm/Rate-Calculators-v2-3.htm
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function _parseXmlResponse($response)
{
$r = $this->_rawRequest;
$costArr = [];
$priceArr = [];
if (strlen(trim($response)) > 0) {
if (strpos(trim($response), '') !== false) {
$response = str_replace(
'',
'',
$response
);
}
$xml = $this->parseXml($response);
if (is_object($xml)) {
$allowedMethods = explode(',', $this->getConfigData('allowed_methods'));
$serviceCodeToActualNameMap = [];
/**
* US Rates
*/
if ($this->_isUSCountry($r->getDestCountryId())) {
if (is_object($xml->Package) && is_object($xml->Package->Postage)) {
foreach ($xml->Package->Postage as $postage) {
$serviceName = $this->_filterServiceName((string)$postage->MailService);
$_serviceCode = $this->getCode('method_to_code', $serviceName);
$serviceCode = $_serviceCode ? $_serviceCode : (string)$postage->attributes()->CLASSID;
$serviceCodeToActualNameMap[$serviceCode] = $serviceName;
if (in_array($serviceCode, $allowedMethods)) {
$costArr[$serviceCode] = (string)$postage->Rate;
$priceArr[$serviceCode] = $this->getMethodPrice(
(string)$postage->Rate,
$serviceCode
);
}
}
asort($priceArr);
}
} else {
/*
* International Rates
*/
if (is_object($xml->Package) && is_object($xml->Package->Service)) {
foreach ($xml->Package->Service as $service) {
$serviceName = $this->_filterServiceName((string)$service->SvcDescription);
$serviceCode = 'INT_' . (string)$service->attributes()->ID;
$serviceCodeToActualNameMap[$serviceCode] = $serviceName;
if (!$this->isServiceAvailable($service)) {
continue;
}
if (in_array($serviceCode, $allowedMethods)) {
$costArr[$serviceCode] = (string)$service->Postage;
$priceArr[$serviceCode] = $this->getMethodPrice(
(string)$service->Postage,
$serviceCode
);
}
}
asort($priceArr);
}
}
}
}
}
$result = $this->_rateFactory->create();
if (empty($priceArr)) {
$error = $this->_rateErrorFactory->create();
$error->setCarrier('usps');
$error->setCarrierTitle($this->getConfigData('title'));
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
$result->append($error);
} else {
foreach ($priceArr as $method => $price) {
$rate = $this->_rateMethodFactory->create();
$rate->setCarrier('usps');
$rate->setCarrierTitle($this->getConfigData('title'));
$rate->setMethod($method);
$rate->setMethodTitle(
isset(
$serviceCodeToActualNameMap[$method]
) ? $serviceCodeToActualNameMap[$method] : $this->getCode(
'method',
$method
)
);
$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|false
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function getCode($type, $code = '')
{
$codes = [
'method' => [
'0_FCLE' => __('First-Class Mail Large Envelope'),
'0_FCL' => __('First-Class Mail Letter'),
'0_FCP' => __('First-Class Package Service - Retail'),
'0_FCPC' => __('First-Class Mail Postcards'),
'1' => __('Priority Mail'),
'2' => __('Priority Mail Express Hold For Pickup'),
'3' => __('Priority Mail Express'),
'4' => __('Retail Ground'),
'6' => __('Media Mail'),
'7' => __('Library Mail'),
'13' => __('Priority Mail Express Flat Rate Envelope'),
'15' => __('First-Class Mail Large Postcards'),
'16' => __('Priority Mail Flat Rate Envelope'),
'17' => __('Priority Mail Medium Flat Rate Box'),
'22' => __('Priority Mail Large Flat Rate Box'),
'23' => __('Priority Mail Express Sunday/Holiday Delivery'),
'25' => __('Priority Mail Express Sunday/Holiday Delivery Flat Rate Envelope'),
'27' => __('Priority Mail Express Flat Rate Envelope Hold For Pickup'),
'28' => __('Priority Mail Small Flat Rate Box'),
'29' => __('Priority Mail Padded Flat Rate Envelope'),
'30' => __('Priority Mail Express Legal Flat Rate Envelope'),
'31' => __('Priority Mail Express Legal Flat Rate Envelope Hold For Pickup'),
'32' => __('Priority Mail Express Sunday/Holiday Delivery Legal Flat Rate Envelope'),
'33' => __('Priority Mail Hold For Pickup'),
'34' => __('Priority Mail Large Flat Rate Box Hold For Pickup'),
'35' => __('Priority Mail Medium Flat Rate Box Hold For Pickup'),
'36' => __('Priority Mail Small Flat Rate Box Hold For Pickup'),
'37' => __('Priority Mail Flat Rate Envelope Hold For Pickup'),
'38' => __('Priority Mail Gift Card Flat Rate Envelope'),
'39' => __('Priority Mail Gift Card Flat Rate Envelope Hold For Pickup'),
'40' => __('Priority Mail Window Flat Rate Envelope'),
'41' => __('Priority Mail Window Flat Rate Envelope Hold For Pickup'),
'42' => __('Priority Mail Small Flat Rate Envelope'),
'43' => __('Priority Mail Small Flat Rate Envelope Hold For Pickup'),
'44' => __('Priority Mail Legal Flat Rate Envelope'),
'45' => __('Priority Mail Legal Flat Rate Envelope Hold For Pickup'),
'46' => __('Priority Mail Padded Flat Rate Envelope Hold For Pickup'),
'47' => __('Priority Mail Regional Rate Box A'),
'48' => __('Priority Mail Regional Rate Box A Hold For Pickup'),
'49' => __('Priority Mail Regional Rate Box B'),
'50' => __('Priority Mail Regional Rate Box B Hold For Pickup'),
'53' => __('First-Class Package Service Hold For Pickup'),
'57' => __('Priority Mail Express Sunday/Holiday Delivery Flat Rate Boxes'),
'58' => __('Priority Mail Regional Rate Box C'),
'59' => __('Priority Mail Regional Rate Box C Hold For Pickup'),
'61' => __('First-Class Package Service'),
'62' => __('Priority Mail Express Padded Flat Rate Envelope'),
'63' => __('Priority Mail Express Padded Flat Rate Envelope Hold For Pickup'),
'64' => __('Priority Mail Express Sunday/Holiday Delivery Padded Flat Rate Envelope'),
'INT_1' => __('Priority Mail Express International'),
'INT_2' => __('Priority Mail International'),
'INT_4' => __('Global Express Guaranteed (GXG)'),
'INT_5' => __('Global Express Guaranteed Document'),
'INT_6' => __('Global Express Guaranteed Non-Document Rectangular'),
'INT_7' => __('Global Express Guaranteed Non-Document Non-Rectangular'),
'INT_8' => __('Priority Mail International Flat Rate Envelope'),
'INT_9' => __('Priority Mail International Medium Flat Rate Box'),
'INT_10' => __('Priority Mail Express International Flat Rate Envelope'),
'INT_11' => __('Priority Mail International Large Flat Rate Box'),
'INT_12' => __('USPS GXG Envelopes'),
'INT_13' => __('First-Class Mail International Letter'),
'INT_14' => __('First-Class Mail International Large Envelope'),
'INT_15' => __('First-Class Package International Service'),
'INT_16' => __('Priority Mail International Small Flat Rate Box'),
'INT_17' => __('Priority Mail Express International Legal Flat Rate Envelope'),
'INT_18' => __('Priority Mail International Gift Card Flat Rate Envelope'),
'INT_19' => __('Priority Mail International Window Flat Rate Envelope'),
'INT_20' => __('Priority Mail International Small Flat Rate Envelope'),
'INT_21' => __('First-Class Mail International Postcard'),
'INT_22' => __('Priority Mail International Legal Flat Rate Envelope'),
'INT_23' => __('Priority Mail International Padded Flat Rate Envelope'),
'INT_24' => __('Priority Mail International DVD Flat Rate priced box'),
'INT_25' => __('Priority Mail International Large Video Flat Rate priced box'),
'INT_27' => __('Priority Mail Express International Padded Flat Rate Envelope'),
],
'service_to_code' => [
'0_FCLE' => 'First Class',
'0_FCL' => 'First Class',
'0_FCP' => 'First Class',
'0_FCPC' => 'First Class',
'1' => 'Priority',
'2' => 'Priority Express',
'3' => 'Priority Express',
'4' => 'Retail Ground',
'6' => 'Media',
'7' => 'Library',
'13' => 'Priority Express',
'15' => 'First Class',
'16' => 'Priority',
'17' => 'Priority',
'22' => 'Priority',
'23' => 'Priority Express',
'25' => 'Priority Express',
'27' => 'Priority Express',
'28' => 'Priority',
'29' => 'Priority',
'30' => 'Priority Express',
'31' => 'Priority Express',
'32' => 'Priority Express',
'33' => 'Priority',
'34' => 'Priority',
'35' => 'Priority',
'36' => 'Priority',
'37' => 'Priority',
'38' => 'Priority',
'39' => 'Priority',
'40' => 'Priority',
'41' => 'Priority',
'42' => 'Priority',
'43' => 'Priority',
'44' => 'Priority',
'45' => 'Priority',
'46' => 'Priority',
'47' => 'Priority',
'48' => 'Priority',
'49' => 'Priority',
'50' => 'Priority',
'53' => 'First Class',
'57' => 'Priority Express',
'58' => 'Priority',
'59' => 'Priority',
'61' => 'First Class',
'62' => 'Priority Express',
'63' => 'Priority Express',
'64' => 'Priority Express',
'INT_1' => 'Priority Express',
'INT_2' => 'Priority',
'INT_4' => 'Priority Express',
'INT_5' => 'Priority Express',
'INT_6' => 'Priority Express',
'INT_7' => 'Priority Express',
'INT_8' => 'Priority',
'INT_9' => 'Priority',
'INT_10' => 'Priority Express',
'INT_11' => 'Priority',
'INT_12' => 'Priority Express',
'INT_13' => 'First Class',
'INT_14' => 'First Class',
'INT_15' => 'First Class',
'INT_16' => 'Priority',
'INT_17' => 'Priority',
'INT_18' => 'Priority',
'INT_19' => 'Priority',
'INT_20' => 'Priority',
'INT_21' => 'First Class',
'INT_22' => 'Priority',
'INT_23' => 'Priority',
'INT_24' => 'Priority',
'INT_25' => 'Priority',
'INT_27' => 'Priority Express',
],
'method_to_code' => [
'First-Class Mail Large Envelope' => '0_FCLE',
'First-Class Mail Letter' => '0_FCL',
'First-Class Package Service - Retail' => '0_FCP',
],
'first_class_mail_type' => ['LETTER' => __('Letter'), 'FLAT' => __('Flat'), 'PARCEL' => __('Parcel')],
'container' => [
'VARIABLE' => __('Variable'),
'SM FLAT RATE BOX' => __('Small Flat-Rate Box'),
'MD FLAT RATE BOX' => __('Medium Flat-Rate Box'),
'LG FLAT RATE BOX' => __('Large Flat-Rate Box'),
'FLAT RATE ENVELOPE' => __('Flat-Rate Envelope'),
'SM FLAT RATE ENVELOPE' => __('Small Flat-Rate Envelope'),
'WINDOW FLAT RATE ENVELOPE' => __('Window Flat-Rate Envelope'),
'GIFT CARD FLAT RATE ENVELOPE' => __('Gift Card Flat-Rate Envelope'),
'LEGAL FLAT RATE ENVELOPE' => __('Legal Flat-Rate Envelope'),
'PADDED FLAT RATE ENVELOPE' => __('Padded Flat-Rate Envelope'),
'RECTANGULAR' => __('Rectangular'),
'NONRECTANGULAR' => __('Non-rectangular'),
],
'containers_filter' => [
[
'containers' => ['VARIABLE'],
'filters' => [
'within_us' => [
'method' => [
'13', '27', '16', '22', '17', '28', '2', '3', '1', '33', '34', '35',
'36', '37', '42', '43', '53', '4', '6', '15', '23', '25', '57'
],
],
'from_us' => [
'method' => [
'INT_10', 'INT_8', 'INT_11', 'INT_9', 'INT_16', 'INT_20', 'INT_4',
'INT_12', 'INT_1', 'INT_2', 'INT_13', 'INT_14', 'INT_15'
],
],
],
],
[
'containers' => ['SM FLAT RATE BOX'],
'filters' => [
'within_us' => [
'method' => ['28', '57'],
],
'from_us' => [
'method' => ['INT_16', 'INT_24'],
],
]
],
[
'containers' => ['MD FLAT RATE BOX'],
'filters' => [
'within_us' => [
'method' => ['17', '57'],
],
'from_us' => [
'method' => ['INT_9', 'INT_24'],
],
]
],
[
'containers' => ['LG FLAT RATE BOX'],
'filters' => [
'within_us' => [
'method' => ['22', '57'],
],
'from_us' => [
'method' => ['INT_11', 'INT_24', 'INT_25'],
],
]
],
[
'containers' => ['SM FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['42', '43'],
],
'from_us' => [
'method' => ['INT_20'],
],
]
],
[
'containers' => ['WINDOW FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['40', '41'],
],
'from_us' => [
'method' => ['INT_19'],
],
]
],
[
'containers' => ['GIFT CARD FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['38', '39'],
],
'from_us' => [
'method' => ['INT_18'],
],
]
],
[
'containers' => ['PADDED FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['62', '63', '64', '46', '29'],
],
'from_us' => [
'method' => ['INT_27', 'INT_23'],
],
]
],
[
'containers' => ['LEGAL FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['44', '45', '30', '31', '32'],
],
'from_us' => [
'method' => ['INT_17', 'INT_22'],
],
]
],
[
'containers' => ['FLAT RATE ENVELOPE'],
'filters' => [
'within_us' => [
'method' => ['16', '13', '27', '16', '15', '37', '42', '43', '25', '62'],
],
'from_us' => [
'method' => [
'INT_10', 'INT_8', 'INT_14', 'INT_20', 'INT_17', 'INT_18', 'INT_19', 'INT_22', 'INT_27'
],
],
]
],
[
'containers' => ['RECTANGULAR'],
'filters' => [
'within_us' => [
'method' => ['3', '1', '4', '6', '7', '61'],
],
'from_us' => [
'method' => ['INT_12', 'INT_1', 'INT_2', 'INT_15'],
],
]
],
[
'containers' => ['NONRECTANGULAR'],
'filters' => [
'within_us' => [
'method' => ['3', '1', '4', '6', '7'],
],
'from_us' => [
'method' => ['INT_4', 'INT_1', 'INT_2', 'INT_15'],
],
]
],
],
'size' => ['REGULAR' => __('Regular'), 'LARGE' => __('Large')],
'machinable' => ['true' => __('Yes'), 'false' => __('No')],
'delivery_confirmation_types' => ['True' => __('Not Required'), 'False' => __('Required')],
];
if (!isset($codes[$type])) {
return false;
} elseif ('' === $code) {
return $codes[$type];
}
if (!isset($codes[$type][$code])) {
return false;
} else {
return $codes[$type][$code];
}
}
/**
* Get tracking
*
* @param string|string[] $trackings
* @return Result|null
*/
public function getTracking($trackings)
{
$this->setTrackingReqeust();
if (!is_array($trackings)) {
$trackings = [$trackings];
}
$this->_getXmlTracking($trackings);
return $this->_result;
}
/**
* Set tracking request
*
* @return void
*/
protected function setTrackingReqeust()
{
$r = new \Magento\Framework\DataObject();
$userId = $this->getConfigData('userid');
$r->setUserId($userId);
$this->_rawTrackRequest = $r;
}
/**
* Send request for tracking
*
* @param string[] $trackings
* @return void
*/
protected function _getXmlTracking($trackings)
{
$r = $this->_rawTrackRequest;
foreach ($trackings as $tracking) {
$xml = $this->_xmlElFactory->create(
['data' => '']
);
$xml->addAttribute('USERID', $r->getUserId());
$trackid = $xml->addChild('TrackID');
$trackid->addAttribute('ID', $tracking);
$api = 'TrackV2';
$request = $xml->asXML();
$debugData = ['request' => $this->filterDebugData($request)];
try {
$url = $this->getConfigData('gateway_url');
if (!$url) {
$url = $this->_defaultGatewayUrl;
}
$client = $this->_httpClientFactory->create();
$client->setUri($url);
$client->setConfig(['maxredirects' => 0, 'timeout' => 30]);
$client->setParameterGet('API', $api);
$client->setParameterGet('XML', $request);
$response = $client->request();
$responseBody = $response->getBody();
$debugData['result'] = $responseBody;
} catch (\Exception $e) {
$debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
$responseBody = '';
}
$this->_debug($debugData);
$this->_parseXmlTrackingResponse($tracking, $responseBody);
}
}
/**
* Parse xml tracking response
*
* @param string $trackingvalue
* @param string $response
* @return void
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
protected function _parseXmlTrackingResponse($trackingvalue, $response)
{
$errorTitle = __('For some reason we can\'t retrieve tracking info right now.');
$resultArr = [];
if (strlen(trim($response)) > 0) {
if (strpos(trim($response), 'parseXml($response);
if (is_object($xml)) {
if (isset($xml->Number) && isset($xml->Description) && (string)$xml->Description != '') {
$errorTitle = (string)$xml->Description;
} elseif (isset($xml->TrackInfo)
&& isset($xml->TrackInfo->Error)
&& isset($xml->TrackInfo->Error->Description)
&& (string)$xml->TrackInfo->Error->Description != ''
) {
$errorTitle = (string)$xml->TrackInfo->Error->Description;
} else {
$errorTitle = __(
'Sorry, something went wrong. Please try again or contact us and we\'ll try to help.'
);
}
if (isset($xml->TrackInfo) && isset($xml->TrackInfo->TrackSummary)) {
$resultArr['tracksummary'] = (string)$xml->TrackInfo->TrackSummary;
}
}
}
}
if (!$this->_result) {
$this->_result = $this->_trackFactory->create();
}
$defaults = $this->getDefaults();
if ($resultArr) {
$tracking = $this->_trackStatusFactory->create();
$tracking->setCarrier('usps');
$tracking->setCarrierTitle($this->getConfigData('title'));
$tracking->setTracking($trackingvalue);
$tracking->setTrackSummary($resultArr['tracksummary']);
$this->_result->append($tracking);
} else {
$error = $this->_trackErrorFactory->create();
$error->setCarrier('usps');
$error->setCarrierTitle($this->getConfigData('title'));
$error->setTracking($trackingvalue);
$error->setErrorMessage($errorTitle);
$this->_result->append($error);
}
}
/**
* Get tracking response
*
* @return string
*/
public function getResponse()
{
$statuses = '';
if ($this->_result instanceof \Magento\Shipping\Model\Tracking\Result) {
if ($trackings = $this->_result->getAllTrackings()) {
foreach ($trackings as $tracking) {
if ($data = $tracking->getAllData()) {
if (!empty($data['track_summary'])) {
$statuses .= __($data['track_summary']);
} else {
$statuses .= __('Empty response');
}
}
}
}
}
if (empty($statuses)) {
$statuses = __('Empty response');
}
return $statuses;
}
/**
* Get allowed shipping methods
*
* @return array
*/
public function getAllowedMethods()
{
$allowed = explode(',', $this->getConfigData('allowed_methods'));
$arr = [];
foreach ($allowed as $k) {
$arr[$k] = $this->getCode('method', $k);
}
return $arr;
}
/**
* Return USPS county name by country ISO 3166-1-alpha-2 code
*
* Return false for unknown countries
*
* @param string $countryId
* @return string|false
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function _getCountryName($countryId)
{
$countries = [
'AD' => 'Andorra',
'AE' => 'United Arab Emirates',
'AF' => 'Afghanistan',
'AG' => 'Antigua and Barbuda',
'AI' => 'Anguilla',
'AL' => 'Albania',
'AM' => 'Armenia',
'AN' => 'Netherlands Antilles',
'AO' => 'Angola',
'AR' => 'Argentina',
'AT' => 'Austria',
'AU' => 'Australia',
'AW' => 'Aruba',
'AX' => 'Aland Island (Finland)',
'AZ' => 'Azerbaijan',
'BA' => 'Bosnia-Herzegovina',
'BB' => 'Barbados',
'BD' => 'Bangladesh',
'BE' => 'Belgium',
'BF' => 'Burkina Faso',
'BG' => 'Bulgaria',
'BH' => 'Bahrain',
'BI' => 'Burundi',
'BJ' => 'Benin',
'BM' => 'Bermuda',
'BN' => 'Brunei Darussalam',
'BO' => 'Bolivia',
'BR' => 'Brazil',
'BS' => 'Bahamas',
'BT' => 'Bhutan',
'BW' => 'Botswana',
'BY' => 'Belarus',
'BZ' => 'Belize',
'CA' => 'Canada',
'CC' => 'Cocos Island (Australia)',
'CD' => 'Congo, Democratic Republic of the',
'CF' => 'Central African Republic',
'CG' => 'Congo, Republic of the',
'CH' => 'Switzerland',
'CI' => 'Ivory Coast (Cote d Ivoire)',
'CK' => 'Cook Islands (New Zealand)',
'CL' => 'Chile',
'CM' => 'Cameroon',
'CN' => 'China',
'CO' => 'Colombia',
'CR' => 'Costa Rica',
'CU' => 'Cuba',
'CV' => 'Cape Verde',
'CX' => 'Christmas Island (Australia)',
'CY' => 'Cyprus',
'CZ' => 'Czech Republic',
'DE' => 'Germany',
'DJ' => 'Djibouti',
'DK' => 'Denmark',
'DM' => 'Dominica',
'DO' => 'Dominican Republic',
'DZ' => 'Algeria',
'EC' => 'Ecuador',
'EE' => 'Estonia',
'EG' => 'Egypt',
'ER' => 'Eritrea',
'ES' => 'Spain',
'ET' => 'Ethiopia',
'FI' => 'Finland',
'FJ' => 'Fiji',
'FK' => 'Falkland Islands',
'FM' => 'Micronesia, Federated States of',
'FO' => 'Faroe Islands',
'FR' => 'France',
'GA' => 'Gabon',
'GB' => 'United Kingdom of Great Britain and Northern Ireland',
'GD' => 'Grenada',
'GE' => 'Georgia, Republic of',
'GF' => 'French Guiana',
'GH' => 'Ghana',
'GI' => 'Gibraltar',
'GL' => 'Greenland',
'GM' => 'Gambia',
'GN' => 'Guinea',
'GP' => 'Guadeloupe',
'GQ' => 'Equatorial Guinea',
'GR' => 'Greece',
'GS' => 'South Georgia (Falkland Islands)',
'GT' => 'Guatemala',
'GW' => 'Guinea-Bissau',
'GY' => 'Guyana',
'HK' => 'Hong Kong',
'HN' => 'Honduras',
'HR' => 'Croatia',
'HT' => 'Haiti',
'HU' => 'Hungary',
'ID' => 'Indonesia',
'IE' => 'Ireland',
'IL' => 'Israel',
'IN' => 'India',
'IQ' => 'Iraq',
'IR' => 'Iran',
'IS' => 'Iceland',
'IT' => 'Italy',
'JM' => 'Jamaica',
'JO' => 'Jordan',
'JP' => 'Japan',
'KE' => 'Kenya',
'KG' => 'Kyrgyzstan',
'KH' => 'Cambodia',
'KI' => 'Kiribati',
'KM' => 'Comoros',
'KN' => 'Saint Kitts (Saint Christopher and Nevis)',
'KP' => 'North Korea (Korea, Democratic People\'s Republic of)',
'KR' => 'South Korea (Korea, Republic of)',
'KW' => 'Kuwait',
'KY' => 'Cayman Islands',
'KZ' => 'Kazakhstan',
'LA' => 'Laos',
'LB' => 'Lebanon',
'LC' => 'Saint Lucia',
'LI' => 'Liechtenstein',
'LK' => 'Sri Lanka',
'LR' => 'Liberia',
'LS' => 'Lesotho',
'LT' => 'Lithuania',
'LU' => 'Luxembourg',
'LV' => 'Latvia',
'LY' => 'Libya',
'MA' => 'Morocco',
'MC' => 'Monaco (France)',
'MD' => 'Moldova',
'MG' => 'Madagascar',
'MK' => 'Macedonia, Republic of',
'ML' => 'Mali',
'MM' => 'Burma',
'MN' => 'Mongolia',
'MO' => 'Macao',
'MQ' => 'Martinique',
'MR' => 'Mauritania',
'MS' => 'Montserrat',
'MT' => 'Malta',
'MU' => 'Mauritius',
'MV' => 'Maldives',
'MW' => 'Malawi',
'MX' => 'Mexico',
'MY' => 'Malaysia',
'MZ' => 'Mozambique',
'NA' => 'Namibia',
'NC' => 'New Caledonia',
'NE' => 'Niger',
'NG' => 'Nigeria',
'NI' => 'Nicaragua',
'NL' => 'Netherlands',
'NO' => 'Norway',
'NP' => 'Nepal',
'NR' => 'Nauru',
'NZ' => 'New Zealand',
'OM' => 'Oman',
'PA' => 'Panama',
'PE' => 'Peru',
'PF' => 'French Polynesia',
'PG' => 'Papua New Guinea',
'PH' => 'Philippines',
'PK' => 'Pakistan',
'PL' => 'Poland',
'PM' => 'Saint Pierre and Miquelon',
'PN' => 'Pitcairn Island',
'PT' => 'Portugal',
'PY' => 'Paraguay',
'QA' => 'Qatar',
'RE' => 'Reunion',
'RO' => 'Romania',
'RS' => 'Serbia',
'RU' => 'Russia',
'RW' => 'Rwanda',
'SA' => 'Saudi Arabia',
'SB' => 'Solomon Islands',
'SC' => 'Seychelles',
'SD' => 'Sudan',
'SE' => 'Sweden',
'SG' => 'Singapore',
'SH' => 'Saint Helena',
'SI' => 'Slovenia',
'SK' => 'Slovak Republic',
'SL' => 'Sierra Leone',
'SM' => 'San Marino',
'SN' => 'Senegal',
'SO' => 'Somalia',
'SR' => 'Suriname',
'ST' => 'Sao Tome and Principe',
'SV' => 'El Salvador',
'SY' => 'Syrian Arab Republic',
'SZ' => 'Eswatini',
'TC' => 'Turks and Caicos Islands',
'TD' => 'Chad',
'TG' => 'Togo',
'TH' => 'Thailand',
'TJ' => 'Tajikistan',
'TK' => 'Tokelau (Union Group) (Western Samoa)',
'TL' => 'East Timor (Timor-Leste, Democratic Republic of)',
'TM' => 'Turkmenistan',
'TN' => 'Tunisia',
'TO' => 'Tonga',
'TR' => 'Turkey',
'TT' => 'Trinidad and Tobago',
'TV' => 'Tuvalu',
'TW' => 'Taiwan',
'TZ' => 'Tanzania',
'UA' => 'Ukraine',
'UG' => 'Uganda',
'UY' => 'Uruguay',
'UZ' => 'Uzbekistan',
'VA' => 'Vatican City',
'VC' => 'Saint Vincent and the Grenadines',
'VE' => 'Venezuela',
'VG' => 'British Virgin Islands',
'VN' => 'Vietnam',
'VU' => 'Vanuatu',
'WF' => 'Wallis and Futuna Islands',
'WS' => 'Western Samoa',
'YE' => 'Yemen',
'YT' => 'Mayotte (France)',
'ZA' => 'South Africa',
'ZM' => 'Zambia',
'ZW' => 'Zimbabwe',
'US' => 'United States',
];
if (isset($countries[$countryId])) {
return $countries[$countryId];
}
return false;
}
/**
* Clean service name from unsupported strings and characters
*
* @param string $name
* @return string
*/
protected function _filterServiceName($name)
{
$name = (string)preg_replace(
['~<[^/!][^>]+>.*[^>]+>~sU', '~\