1895 lines
81 KiB
Diff
1895 lines
81 KiB
Diff
diff --git a/vendor/magento/module-shipping/view/adminhtml/templates/order/packaging/popup.phtml b/vendor/magento/module-shipping/view/adminhtml/templates/order/packaging/popup.phtml
|
|
index 6b188c21056e..0144d7edfca3 100644
|
|
--- a/vendor/magento/module-shipping/view/adminhtml/templates/order/packaging/popup.phtml
|
|
+++ b/vendor/magento/module-shipping/view/adminhtml/templates/order/packaging/popup.phtml
|
|
@@ -51,7 +51,7 @@ $girthEnabled = $block->isDisplayGirthValue() && $block->isGirthAllowed() ? 1 :
|
|
});
|
|
packaging.setItemQtyCallback(function(itemId){
|
|
var item = $$('[name="shipment[items]['+itemId+']"]')[0],
|
|
- itemTitle = $('order_item_' + itemId + '_title');
|
|
+ itemTitle = $$('order_item_' + itemId + '_title');
|
|
if (!itemTitle && !item) {
|
|
return 0;
|
|
}
|
|
diff --git a/vendor/magento/module-ups/Helper/Config.php b/vendor/magento/module-ups/Helper/Config.php
|
|
index 7d098137ec53..f79fb1fbbf36 100644
|
|
--- a/vendor/magento/module-ups/Helper/Config.php
|
|
+++ b/vendor/magento/module-ups/Helper/Config.php
|
|
@@ -115,15 +115,24 @@ protected function getCodes()
|
|
'03' => __('UPS Ground'),
|
|
'07' => __('UPS Worldwide Express'),
|
|
'08' => __('UPS Worldwide Expedited'),
|
|
+ '12' => __('UPS Three-Day Select'),
|
|
'14' => __('UPS Next Day Air Early A.M.'),
|
|
'54' => __('UPS Worldwide Express Plus'),
|
|
'65' => __('UPS Saver'),
|
|
],
|
|
// Shipments Originating in Mexico
|
|
'Shipments Originating in Mexico' => [
|
|
+ '01' => __('UPS Next Day Air'),
|
|
+ '02' => __('UPS Second Day Air'),
|
|
+ '03' => __('UPS Ground'),
|
|
'07' => __('UPS Express'),
|
|
'08' => __('UPS Expedited'),
|
|
+ '11' => __('UPS Standard'),
|
|
+ '12' => __('UPS Three-Day Select'),
|
|
+ '13' => __('UPS Next Day Air Saver'),
|
|
+ '14' => __('UPS Next Day Air Early A.M.'),
|
|
'54' => __('UPS Express Plus'),
|
|
+ '59' => __('UPS Second Day Air A.M.'),
|
|
'65' => __('UPS Saver'),
|
|
],
|
|
// Shipments Originating in Other Countries
|
|
diff --git a/vendor/magento/module-ups/Model/Carrier.php b/vendor/magento/module-ups/Model/Carrier.php
|
|
index 9208022be43e..392dc4b63aa8 100644
|
|
--- a/vendor/magento/module-ups/Model/Carrier.php
|
|
+++ b/vendor/magento/module-ups/Model/Carrier.php
|
|
@@ -7,6 +7,7 @@
|
|
|
|
namespace Magento\Ups\Model;
|
|
|
|
+use GuzzleHttp\Exception\GuzzleException;
|
|
use Laminas\Http\Client;
|
|
use Magento\CatalogInventory\Api\StockRegistryInterface;
|
|
use Magento\Directory\Helper\Data;
|
|
@@ -46,6 +47,7 @@
|
|
use Magento\Shipping\Model\Tracking\ResultFactory as TrackFactory;
|
|
use Magento\Store\Model\ScopeInterface;
|
|
use Magento\Ups\Helper\Config;
|
|
+use Magento\Ups\Model\UpsAuth;
|
|
use Psr\Log\LoggerInterface;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
@@ -55,6 +57,7 @@
|
|
*
|
|
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
+ * @SuppressWarnings(PHPMD.TooManyFields)
|
|
*/
|
|
class Carrier extends AbstractCarrierOnline implements CarrierInterface
|
|
{
|
|
@@ -116,6 +119,8 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
|
|
protected $_defaultUrls = [
|
|
'ShipConfirm' => 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm',
|
|
'ShipAccept' => 'https://wwwcie.ups.com/ups.app/xml/ShipAccept',
|
|
+ 'AuthUrl' => 'https://wwwcie.ups.com/security/v1/oauth/token',
|
|
+ 'ShipRestConfirm' => 'https://wwwcie.ups.com/api/shipments/v1/ship',
|
|
];
|
|
|
|
/**
|
|
@@ -126,6 +131,8 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
|
|
protected $_liveUrls = [
|
|
'ShipConfirm' => 'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
|
|
'ShipAccept' => 'https://onlinetools.ups.com/ups.app/xml/ShipAccept',
|
|
+ 'AuthUrl' => 'https://onlinetools.ups.com/security/v1/oauth/token',
|
|
+ 'ShipRestConfirm' => 'https://onlinetools.ups.com/api/shipments/v1/ship',
|
|
];
|
|
|
|
/**
|
|
@@ -150,6 +157,11 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
|
|
*/
|
|
protected $configHelper;
|
|
|
|
+ /**
|
|
+ * @var UpsAuth
|
|
+ */
|
|
+ protected $upsAuth;
|
|
+
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
@@ -187,6 +199,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
|
|
* @param StockRegistryInterface $stockRegistry
|
|
* @param FormatInterface $localeFormat
|
|
* @param Config $configHelper
|
|
+ * @param UpsAuth $upsAuth
|
|
* @param ClientFactory $httpClientFactory
|
|
* @param array $data
|
|
* @param AsyncClientInterface|null $asyncHttpClient
|
|
@@ -213,6 +226,7 @@ public function __construct(
|
|
StockRegistryInterface $stockRegistry,
|
|
FormatInterface $localeFormat,
|
|
Config $configHelper,
|
|
+ UpsAuth $upsAuth,
|
|
ClientFactory $httpClientFactory,
|
|
array $data = [],
|
|
?AsyncClientInterface $asyncHttpClient = null,
|
|
@@ -238,6 +252,7 @@ public function __construct(
|
|
);
|
|
$this->_localeFormat = $localeFormat;
|
|
$this->configHelper = $configHelper;
|
|
+ $this->upsAuth = $upsAuth;
|
|
$this->asyncHttpClient = $asyncHttpClient ?? ObjectManager::getInstance()->get(AsyncClientInterface::class);
|
|
$this->deferredProxyFactory = $proxyDeferredFactory
|
|
?? ObjectManager::getInstance()->get(ProxyDeferredFactory::class);
|
|
@@ -417,6 +432,19 @@ public function setRequest(RateRequest $request)
|
|
$unit = $this->getConfigData('unit_of_measure');
|
|
}
|
|
$rowRequest->setUnitMeasure($unit);
|
|
+
|
|
+ $rowRequest->setPackageHeight($request->getPackageHeight());
|
|
+ $rowRequest->setPackageWidth($request->getPackageWidth());
|
|
+ $rowRequest->setPackageDepth($request->getPackageDepth());
|
|
+
|
|
+ if ($rowRequest->getUnitMeasure() == 'KGS') {
|
|
+ $rowRequest->setUnitDimensions('CM');
|
|
+ $rowRequest->setUnitDimensionsDescription('Centimeter');
|
|
+ } else {
|
|
+ $rowRequest->setUnitDimensions('IN');
|
|
+ $rowRequest->setUnitDimensionsDescription('Inches');
|
|
+ }
|
|
+
|
|
$rowRequest->setIsReturn($request->getIsReturn());
|
|
$rowRequest->setBaseSubtotalInclTax($request->getBaseSubtotalInclTax());
|
|
|
|
@@ -505,6 +533,8 @@ protected function _getQuotes()
|
|
return $this->_getCgiQuotes();
|
|
case 'UPS_XML':
|
|
return $this->_getXmlQuotes();
|
|
+ case 'UPS_REST':
|
|
+ return $this->_getRestQuotes();
|
|
default:
|
|
break;
|
|
}
|
|
@@ -692,41 +722,14 @@ protected function _parseCgiResponse($response)
|
|
protected function _getXmlQuotes()
|
|
{
|
|
$url = $this->getConfigData('gateway_xml_url');
|
|
-
|
|
$this->setXMLAccessRequest();
|
|
$xmlRequest = $this->_xmlAccessRequest;
|
|
-
|
|
$rowRequest = $this->_rawRequest;
|
|
- if (self::USA_COUNTRY_ID == $rowRequest->getDestCountry()) {
|
|
- $destPostal = substr((string)$rowRequest->getDestPostal(), 0, 5);
|
|
- } else {
|
|
- $destPostal = $rowRequest->getDestPostal();
|
|
- }
|
|
- $params = [
|
|
- 'accept_UPS_license_agreement' => 'yes',
|
|
- '10_action' => $rowRequest->getAction(),
|
|
- '13_product' => $rowRequest->getProduct(),
|
|
- '14_origCountry' => $rowRequest->getOrigCountry(),
|
|
- '15_origPostal' => $rowRequest->getOrigPostal(),
|
|
- 'origCity' => $rowRequest->getOrigCity(),
|
|
- 'origRegionCode' => $rowRequest->getOrigRegionCode(),
|
|
- '19_destPostal' => $destPostal,
|
|
- '22_destCountry' => $rowRequest->getDestCountry(),
|
|
- 'destRegionCode' => $rowRequest->getDestRegionCode(),
|
|
- '23_weight' => $rowRequest->getWeight(),
|
|
- '47_rate_chart' => $rowRequest->getPickup(),
|
|
- '48_container' => $rowRequest->getContainer(),
|
|
- '49_residential' => $rowRequest->getDestType(),
|
|
- ];
|
|
|
|
- if ($params['10_action'] == '4') {
|
|
- $params['10_action'] = 'Shop';
|
|
- $serviceCode = null;
|
|
- } else {
|
|
- $params['10_action'] = 'Rate';
|
|
- $serviceCode = $rowRequest->getProduct() ? $rowRequest->getProduct() : null;
|
|
- }
|
|
- $serviceDescription = $serviceCode ? $this->getShipmentByCode($serviceCode) : '';
|
|
+ $params = $this->setQuoteRequestData($rowRequest);
|
|
+ $serviceCode = $params['serviceCode'];
|
|
+ $serviceDescription = $params['serviceDescription'];
|
|
+ $params['accept_UPS_license_agreement'] = 'yes';
|
|
|
|
$xmlParams = <<<XMLRequest
|
|
<?xml version="1.0"?>
|
|
@@ -915,6 +918,7 @@ protected function _parseXmlResponse($xmlResponse)
|
|
{
|
|
$costArr = [];
|
|
$priceArr = [];
|
|
+ $errorTitle = '';
|
|
if ($xmlResponse !== null && strlen(trim($xmlResponse)) > 0) {
|
|
$xml = new \Magento\Framework\Simplexml\Config();
|
|
$xml->loadString($xmlResponse);
|
|
@@ -932,7 +936,7 @@ protected function _parseXmlResponse($xmlResponse)
|
|
|
|
$allowedCurrencies = $this->_currencyFactory->create()->getConfigAllowCurrencies();
|
|
foreach ($arr as $shipElement) {
|
|
- $this->processShippingRateForItem(
|
|
+ $this->processShippingXmlRateForItem(
|
|
$shipElement,
|
|
$allowedMethods,
|
|
$allowedCurrencies,
|
|
@@ -952,35 +956,7 @@ protected function _parseXmlResponse($xmlResponse)
|
|
}
|
|
}
|
|
|
|
- $result = $this->_rateFactory->create();
|
|
-
|
|
- if (empty($priceArr)) {
|
|
- $error = $this->_rateErrorFactory->create();
|
|
- $error->setCarrier('ups');
|
|
- $error->setCarrierTitle($this->getConfigData('title'));
|
|
- if ($this->getConfigData('specificerrmsg') !== '') {
|
|
- $errorTitle = $this->getConfigData('specificerrmsg');
|
|
- }
|
|
- if (!isset($errorTitle)) {
|
|
- $errorTitle = __('Cannot retrieve shipping rates');
|
|
- }
|
|
- $error->setErrorMessage($errorTitle);
|
|
- $result->append($error);
|
|
- } else {
|
|
- foreach ($priceArr as $method => $price) {
|
|
- $rate = $this->_rateMethodFactory->create();
|
|
- $rate->setCarrier('ups');
|
|
- $rate->setCarrierTitle($this->getConfigData('title'));
|
|
- $rate->setMethod($method);
|
|
- $methodArr = $this->getShipmentByCode($method);
|
|
- $rate->setMethodTitle($methodArr);
|
|
- $rate->setCost($costArr[$method]);
|
|
- $rate->setPrice($price);
|
|
- $result->append($rate);
|
|
- }
|
|
- }
|
|
-
|
|
- return $result;
|
|
+ return $this->setRatePriceData($priceArr, $costArr, $errorTitle);
|
|
}
|
|
|
|
/**
|
|
@@ -995,7 +971,7 @@ protected function _parseXmlResponse($xmlResponse)
|
|
* @param \Magento\Framework\Simplexml\Config $xml
|
|
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
*/
|
|
- private function processShippingRateForItem(
|
|
+ private function processShippingXmlRateForItem(
|
|
\Magento\Framework\Simplexml\Element $shipElement,
|
|
array $allowedMethods,
|
|
array $allowedCurrencies,
|
|
@@ -1077,214 +1053,768 @@ private function processShippingRateForItem(
|
|
}
|
|
|
|
/**
|
|
- * Get final price for shipping method with handling fee per package
|
|
+ * Get REST rates
|
|
*
|
|
- * @param float $cost
|
|
- * @param string $handlingType
|
|
- * @param float $handlingFee
|
|
- * @return float
|
|
+ * @return Result
|
|
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
+ * @SuppressWarnings(PHPMD.NPathComplexity)
|
|
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
|
*/
|
|
- protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
|
|
+ protected function _getRestQuotes()
|
|
{
|
|
- if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) {
|
|
- return $cost + $cost * $this->_numBoxes * $handlingFee / 100;
|
|
- }
|
|
+ $url = $this->getConfigData('gateway_rest_url');
|
|
+ $accessToken = $this->setAPIAccessRequest();
|
|
+ $rowRequest = $this->_rawRequest;
|
|
|
|
- return $cost + $this->_numBoxes * $handlingFee;
|
|
- }
|
|
+ $params = $this->setQuoteRequestData($rowRequest);
|
|
+ $serviceCode = $params['serviceCode'];
|
|
+ $serviceDescription = $params['serviceDescription'];
|
|
|
|
- /**
|
|
- * Get final price for shipping method with handling fee per order
|
|
- *
|
|
- * @param float $cost
|
|
- * @param string $handlingType
|
|
- * @param float $handlingFee
|
|
- * @return float
|
|
- */
|
|
- protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
|
|
- {
|
|
- if ($handlingType == self::HANDLING_TYPE_PERCENT) {
|
|
- return $cost + $cost * $handlingFee / 100;
|
|
+ $shipperNumber = '';
|
|
+ if ($this->getConfigFlag('negotiated_active') && ($shipperNumber = $this->getConfigData('shipper_number'))) {
|
|
+ $shipperNumber = $this->getConfigData('shipper_number');
|
|
}
|
|
|
|
- return $cost + $handlingFee;
|
|
- }
|
|
+ if ($rowRequest->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'];
|
|
+ }
|
|
|
|
- /**
|
|
- * Get tracking
|
|
- *
|
|
- * @param string|string[] $trackings
|
|
- * @return Result
|
|
- */
|
|
- public function getTracking($trackings)
|
|
- {
|
|
- if (!is_array($trackings)) {
|
|
- $trackings = [$trackings];
|
|
+ $residentialAddressIndicator = '';
|
|
+ if ($params['49_residential'] === '01') {
|
|
+ $residentialAddressIndicator = $params['49_residential'];
|
|
+ }
|
|
+
|
|
+ $rateParams = [
|
|
+ "RateRequest" => [
|
|
+ "Request" => [
|
|
+ "TransactionReference" => [
|
|
+ "CustomerContext" => "Rating and Service"
|
|
+ ]
|
|
+ ],
|
|
+ "Shipment" => [
|
|
+ "Shipper" => [
|
|
+ "Name" => "UPS",
|
|
+ "ShipperNumber" => "{$shipperNumber}",
|
|
+ "Address" => [
|
|
+ "AddressLine" => [
|
|
+ "{$residentialAddressIndicator}",
|
|
+ ],
|
|
+ "City" => "{$shipperCity}",
|
|
+ "StateProvinceCode" => "{$shipperStateProvince}",
|
|
+ "PostalCode" => "{$shipperPostalCode}",
|
|
+ "CountryCode" => "{$shipperCountryCode}"
|
|
+ ]
|
|
+ ],
|
|
+ "ShipTo" => [
|
|
+ "Address" => [
|
|
+ "AddressLine" => ["{$params['49_residential']}"],
|
|
+ "StateProvinceCode" => "{$params['destRegionCode']}",
|
|
+ "PostalCode" => "{$params['19_destPostal']}",
|
|
+ "CountryCode" => "{$params['22_destCountry']}",
|
|
+ "ResidentialAddressIndicator" => "{$residentialAddressIndicator}"
|
|
+ ]
|
|
+ ],
|
|
+ "ShipFrom" => [
|
|
+ "Address" => [
|
|
+ "AddressLine" => [],
|
|
+ "StateProvinceCode" => "{$params['origRegionCode']}",
|
|
+ "PostalCode" => "{$params['15_origPostal']}",
|
|
+ "CountryCode" => "{$params['14_origCountry']}"
|
|
+ ]
|
|
+ ],
|
|
+ ]
|
|
+ ]
|
|
+ ];
|
|
+
|
|
+ if ($this->getConfigFlag('negotiated_active')) {
|
|
+ $rateParams['RateRequest']['Shipment']['ShipmentRatingOptions']['TPFCNegotiatedRatesIndicator'] = "Y";
|
|
+ $rateParams['RateRequest']['Shipment']['ShipmentRatingOptions']['NegotiatedRatesIndicator'] = "Y";
|
|
+ }
|
|
+ if ($this->getConfigFlag('include_taxes')) {
|
|
+ $rateParams['RateRequest']['Shipment']['TaxInformationIndicator'] = "Y";
|
|
}
|
|
|
|
- if ($this->getConfigData('type') == 'UPS') {
|
|
- $this->_getCgiTracking($trackings);
|
|
- } elseif ($this->getConfigData('type') == 'UPS_XML') {
|
|
- $this->setXMLAccessRequest();
|
|
- $this->_getXmlTracking($trackings);
|
|
+ if ($serviceCode !== null) {
|
|
+ $rateParams['RateRequest']['Shipment']['Service']['code'] = $serviceCode;
|
|
+ $rateParams['RateRequest']['Shipment']['Service']['Description'] = $serviceDescription;
|
|
}
|
|
|
|
- return $this->_result;
|
|
+ $height = $rowRequest->getPackageHeight() ?? 0;
|
|
+ $width = $rowRequest->getPackageWidth() ?? 0;
|
|
+ $length = $rowRequest->getPackageDepth() ?? 0;
|
|
+
|
|
+ foreach ($rowRequest->getPackages() as $package) {
|
|
+ $rateParams['RateRequest']['Shipment']['Package'][] = [
|
|
+ "PackagingType" => [
|
|
+ "Code" => "{$params['48_container']}",
|
|
+ "Description" => "Packaging"
|
|
+ ],
|
|
+ "Dimensions" => [
|
|
+ "UnitOfMeasurement" => [
|
|
+ "Code" => "{$rowRequest->getUnitDimensions()}",
|
|
+ "Description" => "{$rowRequest->getUnitDimensionsDescription()}"
|
|
+ ],
|
|
+ "Length" => "{$length}",
|
|
+ "Width" => "{$width}",
|
|
+ "Height" => "{$height}"
|
|
+ ],
|
|
+ "PackageWeight" => [
|
|
+ "UnitOfMeasurement" => [
|
|
+ "Code" => "{$rowRequest->getUnitMeasure()}"
|
|
+ ],
|
|
+ "Weight" => "{$this->_getCorrectWeight($package['weight'])}"
|
|
+ ]
|
|
+ ];
|
|
+ }
|
|
+
|
|
+ $ratePayload = json_encode($rateParams, JSON_PRETTY_PRINT);
|
|
+ /** Rest API Payload */
|
|
+ $version = "v1";
|
|
+ $requestOption = $params['10_action'];
|
|
+ $headers = [
|
|
+ "Authorization" => "Bearer " . $accessToken,
|
|
+ "Content-Type" => "application/json"
|
|
+ ];
|
|
+ $httpResponse = $this->asyncHttpClient->request(
|
|
+ new Request($url.$version . "/" . $requestOption, Request::METHOD_POST, $headers, $ratePayload)
|
|
+ );
|
|
+
|
|
+ $debugData['request'] = $ratePayload;
|
|
+ return $this->deferredProxyFactory->create(
|
|
+ [
|
|
+ 'deferred' => new CallbackDeferred(
|
|
+ function () use ($httpResponse, $debugData) {
|
|
+ $responseResult = null;
|
|
+ $jsonResponse = '';
|
|
+ try {
|
|
+ $responseResult = $httpResponse->get();
|
|
+ } catch (HttpException $e) {
|
|
+ $debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
|
|
+ $this->_logger->critical($e);
|
|
+ }
|
|
+ if ($responseResult) {
|
|
+ $jsonResponse = $responseResult->getStatusCode() >= 400 ? '' : $responseResult->getBody();
|
|
+ }
|
|
+ $debugData['result'] = $jsonResponse;
|
|
+ $this->_debug($debugData);
|
|
+
|
|
+ return $this->_parseRestResponse($jsonResponse);
|
|
+ }
|
|
+ )
|
|
+ ]
|
|
+ );
|
|
}
|
|
|
|
/**
|
|
- * Set xml access request
|
|
+ * Setting common request params for Rate Request
|
|
*
|
|
- * @return void
|
|
+ * @param \Magento\Framework\DataObject|null $rowRequest
|
|
+ * @return array
|
|
*/
|
|
- protected function setXMLAccessRequest()
|
|
+ private function setQuoteRequestData($rowRequest)
|
|
{
|
|
- $userId = $this->getConfigData('username');
|
|
- $userIdPass = $this->getConfigData('password');
|
|
- $accessKey = $this->getConfigData('access_license_number');
|
|
+ if (self::USA_COUNTRY_ID == $rowRequest->getDestCountry()) {
|
|
+ $destPostal = substr((string)$rowRequest->getDestPostal(), 0, 5);
|
|
+ } else {
|
|
+ $destPostal = $rowRequest->getDestPostal();
|
|
+ }
|
|
+ $params = [
|
|
+ '10_action' => $rowRequest->getAction(),
|
|
+ '13_product' => $rowRequest->getProduct(),
|
|
+ '14_origCountry' => $rowRequest->getOrigCountry(),
|
|
+ '15_origPostal' => $rowRequest->getOrigPostal(),
|
|
+ 'origCity' => $rowRequest->getOrigCity(),
|
|
+ 'origRegionCode' => $rowRequest->getOrigRegionCode(),
|
|
+ '19_destPostal' => $destPostal,
|
|
+ '22_destCountry' => $rowRequest->getDestCountry(),
|
|
+ 'destRegionCode' => $rowRequest->getDestRegionCode(),
|
|
+ '23_weight' => $rowRequest->getWeight(),
|
|
+ '47_rate_chart' => $rowRequest->getPickup(),
|
|
+ '48_container' => $rowRequest->getContainer(),
|
|
+ '49_residential' => $rowRequest->getDestType(),
|
|
+ ];
|
|
|
|
- $this->_xmlAccessRequest = <<<XMLAuth
|
|
-<?xml version="1.0" ?>
|
|
-<AccessRequest xml:lang="en-US">
|
|
- <AccessLicenseNumber>$accessKey</AccessLicenseNumber>
|
|
- <UserId>$userId</UserId>
|
|
- <Password>$userIdPass</Password>
|
|
-</AccessRequest>
|
|
-XMLAuth;
|
|
+ if ($params['10_action'] == '4') {
|
|
+ $params['10_action'] = 'Shop';
|
|
+ $params['serviceCode'] = null;
|
|
+ } else {
|
|
+ $params['10_action'] = 'Rate';
|
|
+ $params['serviceCode'] = $rowRequest->getProduct() ? $rowRequest->getProduct() : null;
|
|
+ }
|
|
+ $params['serviceDescription'] = $params['serviceCode'] ? $this->getShipmentByCode($params['serviceCode']) : '';
|
|
+ return $params;
|
|
}
|
|
|
|
/**
|
|
- * Get cgi tracking
|
|
+ * Prepare shipping rate result based on response
|
|
*
|
|
- * @param string[] $trackings
|
|
- * @return TrackFactory
|
|
+ * @param mixed $rateResponse
|
|
+ * @return Result
|
|
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
|
+ * @SuppressWarnings(PHPMD.ElseExpression)
|
|
*/
|
|
- protected function _getCgiTracking($trackings)
|
|
+ protected function _parseRestResponse($rateResponse)
|
|
{
|
|
- //ups no longer support tracking for data streaming version
|
|
- //so we can only reply the popup window to ups.
|
|
- $result = $this->_trackFactory->create();
|
|
- foreach ($trackings as $tracking) {
|
|
- $status = $this->_trackStatusFactory->create();
|
|
- $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);
|
|
- }
|
|
+ $costArr = [];
|
|
+ $priceArr = [];
|
|
+ $errorTitle = '';
|
|
+ if ($rateResponse !== null && strlen($rateResponse) > 0) {
|
|
+ $rateResponseData = json_decode($rateResponse, true);
|
|
+ if ($rateResponseData['RateResponse']['Response']['ResponseStatus']['Description'] === 'Success') {
|
|
+ $arr = $rateResponseData['RateResponse']['RatedShipment'] ?? [];
|
|
+ $allowedMethods = explode(",", $this->getConfigData('allowed_methods') ?? '');
|
|
|
|
- $this->_result = $result;
|
|
+ $allowedCurrencies = $this->_currencyFactory->create()->getConfigAllowCurrencies();
|
|
+ foreach ($arr as $shipElement) {
|
|
+ // Negotiated rates
|
|
+ $negotiatedArr = $shipElement['NegotiatedRateCharges'] ?? [] ;
|
|
+ $negotiatedActive = $this->getConfigFlag('negotiated_active')
|
|
+ && $this->getConfigData('shipper_number')
|
|
+ && !empty($negotiatedArr);
|
|
|
|
- return $result;
|
|
+ $this->processShippingRestRateForItem(
|
|
+ $shipElement,
|
|
+ $allowedMethods,
|
|
+ $allowedCurrencies,
|
|
+ $costArr,
|
|
+ $priceArr,
|
|
+ $negotiatedActive
|
|
+ );
|
|
+ }
|
|
+ } else {
|
|
+ $errorTitle = $rateResponseData['RateResponse']['Response']['ResponseStatus']['Description'];
|
|
+ $error = $this->_rateErrorFactory->create();
|
|
+ $error->setCarrier('ups');
|
|
+ $error->setCarrierTitle($this->getConfigData('title'));
|
|
+ $error->setErrorMessage($this->getConfigData('specificerrmsg'));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return $this->setRatePriceData($priceArr, $costArr, $errorTitle);
|
|
}
|
|
|
|
/**
|
|
- * Get xml tracking
|
|
+ * Set Rate Response Price Data
|
|
*
|
|
- * @param string[] $trackings
|
|
+ * @param array $priceArr
|
|
+ * @param array $costArr
|
|
+ * @param string $errorTitle
|
|
* @return Result
|
|
*/
|
|
- protected function _getXmlTracking($trackings)
|
|
+ private function setRatePriceData($priceArr, $costArr, $errorTitle)
|
|
{
|
|
- $url = $this->getConfigData('tracking_xml_url');
|
|
+ $result = $this->_rateFactory->create();
|
|
|
|
- /** @var HttpResponseDeferredInterface[] $trackingResponses */
|
|
- $trackingResponses = [];
|
|
- $tracking = '';
|
|
- $debugData = [];
|
|
+ if (empty($priceArr)) {
|
|
+ $error = $this->_rateErrorFactory->create();
|
|
+ $error->setCarrier('ups');
|
|
+ $error->setCarrierTitle($this->getConfigData('title'));
|
|
+ if ($this->getConfigData('specificerrmsg') !== '') {
|
|
+ $errorTitle = $this->getConfigData('specificerrmsg');
|
|
+ }
|
|
+ $error->setErrorMessage($errorTitle);
|
|
+ $result->append($error);
|
|
+ } else {
|
|
+ foreach ($priceArr as $method => $price) {
|
|
+ $rate = $this->_rateMethodFactory->create();
|
|
+ $rate->setCarrier('ups');
|
|
+ $rate->setCarrierTitle($this->getConfigData('title'));
|
|
+ $rate->setMethod($method);
|
|
+ $methodArr = $this->getShipmentByCode($method);
|
|
+ $rate->setMethodTitle($methodArr);
|
|
+ $rate->setCost($costArr[$method]);
|
|
+ $rate->setPrice($price);
|
|
+ $result->append($rate);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return $result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Processing rate for ship element
|
|
+ *
|
|
+ * @param array $shipElement
|
|
+ * @param array $allowedMethods
|
|
+ * @param array $allowedCurrencies
|
|
+ * @param array $costArr
|
|
+ * @param array $priceArr
|
|
+ * @param bool $negotiatedActive
|
|
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
+ */
|
|
+ private function processShippingRestRateForItem(
|
|
+ array $shipElement,
|
|
+ array $allowedMethods,
|
|
+ array $allowedCurrencies,
|
|
+ array &$costArr,
|
|
+ array &$priceArr,
|
|
+ bool $negotiatedActive
|
|
+ ): void {
|
|
+ $code = $shipElement['Service']['Code'] ?? '';
|
|
+ if (in_array($code, $allowedMethods)) {
|
|
+ //The location of tax information is in a different place
|
|
+ // depending on whether we are using negotiated rates or not
|
|
+ if ($negotiatedActive) {
|
|
+ $includeTaxesArr = $shipElement['NegotiatedRateCharges']['TotalChargesWithTaxes'] ?? [];
|
|
+ $includeTaxesActive = $this->getConfigFlag('include_taxes') && !empty($includeTaxesArr);
|
|
+ if ($includeTaxesActive) {
|
|
+ $cost = $shipElement['NegotiatedRateCharges']['TotalChargesWithTaxes']['MonetaryValue'];
|
|
+
|
|
+ $responseCurrencyCode = $this->mapCurrencyCode(
|
|
+ (string)$shipElement['NegotiatedRateCharges']['TotalChargesWithTaxes']['CurrencyCode']
|
|
+ );
|
|
+ } else {
|
|
+ $cost = $shipElement['NegotiatedRateCharges']['TotalCharge']['MonetaryValue'];
|
|
+ $responseCurrencyCode = $this->mapCurrencyCode(
|
|
+ (string)$shipElement['NegotiatedRateCharges']['TotalCharge']['CurrencyCode']
|
|
+ );
|
|
+ }
|
|
+ } else {
|
|
+ $includeTaxesArr = $shipElement['TotalChargesWithTaxes'] ?? [];
|
|
+ $includeTaxesActive = $this->getConfigFlag('include_taxes') && !empty($includeTaxesArr);
|
|
+ if ($includeTaxesActive) {
|
|
+ $cost = $shipElement['TotalChargesWithTaxes']['MonetaryValue'];
|
|
+ $responseCurrencyCode = $this->mapCurrencyCode(
|
|
+ (string)$shipElement['TotalChargesWithTaxes']['CurrencyCode']
|
|
+ );
|
|
+ } else {
|
|
+ $cost = $shipElement['TotalCharges']['MonetaryValue'];
|
|
+ $responseCurrencyCode = $this->mapCurrencyCode(
|
|
+ (string)$shipElement['TotalCharges']['CurrencyCode']
|
|
+ );
|
|
+ }
|
|
+ }
|
|
+
|
|
+ //convert price with Origin country currency code to base currency code
|
|
+ $successConversion = true;
|
|
+ if ($responseCurrencyCode) {
|
|
+ if (in_array($responseCurrencyCode, $allowedCurrencies)) {
|
|
+ $cost = (double)$cost * $this->_getBaseCurrencyRate($responseCurrencyCode);
|
|
+ } else {
|
|
+ $errorTitle = __(
|
|
+ 'We can\'t convert a rate from "%1-%2".',
|
|
+ $responseCurrencyCode,
|
|
+ $this->_request->getPackageCurrency()->getCode()
|
|
+ );
|
|
+ $error = $this->_rateErrorFactory->create();
|
|
+ $error->setCarrier('ups');
|
|
+ $error->setCarrierTitle($this->getConfigData('title'));
|
|
+ $error->setErrorMessage($errorTitle);
|
|
+ $successConversion = false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if ($successConversion) {
|
|
+ $costArr[$code] = $cost;
|
|
+ $priceArr[$code] = $this->getMethodPrice((float)$cost, $code);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get final price for shipping method with handling fee per package
|
|
+ *
|
|
+ * @param float $cost
|
|
+ * @param string $handlingType
|
|
+ * @param float $handlingFee
|
|
+ * @return float
|
|
+ */
|
|
+ protected function _getPerpackagePrice($cost, $handlingType, $handlingFee)
|
|
+ {
|
|
+ if ($handlingType == AbstractCarrier::HANDLING_TYPE_PERCENT) {
|
|
+ return $cost + $cost * $this->_numBoxes * $handlingFee / 100;
|
|
+ }
|
|
+
|
|
+ return $cost + $this->_numBoxes * $handlingFee;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get final price for shipping method with handling fee per order
|
|
+ *
|
|
+ * @param float $cost
|
|
+ * @param string $handlingType
|
|
+ * @param float $handlingFee
|
|
+ * @return float
|
|
+ */
|
|
+ protected function _getPerorderPrice($cost, $handlingType, $handlingFee)
|
|
+ {
|
|
+ if ($handlingType == self::HANDLING_TYPE_PERCENT) {
|
|
+ return $cost + $cost * $handlingFee / 100;
|
|
+ }
|
|
+
|
|
+ return $cost + $handlingFee;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get tracking
|
|
+ *
|
|
+ * @param string|string[] $trackings
|
|
+ * @return Result
|
|
+ */
|
|
+ public function getTracking($trackings)
|
|
+ {
|
|
+ if (!is_array($trackings)) {
|
|
+ $trackings = [$trackings];
|
|
+ }
|
|
+
|
|
+ if ($this->getConfigData('type') == 'UPS') {
|
|
+ $this->_getCgiTracking($trackings);
|
|
+ } elseif ($this->getConfigData('type') == 'UPS_XML') {
|
|
+ $this->setXMLAccessRequest();
|
|
+ $this->_getXmlTracking($trackings);
|
|
+ } elseif ($this->getConfigData('type') == 'UPS_REST') {
|
|
+ $this->_getRestTracking($trackings);
|
|
+ }
|
|
+
|
|
+ return $this->_result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Set xml access request
|
|
+ *
|
|
+ * @return void
|
|
+ */
|
|
+ protected function setXMLAccessRequest()
|
|
+ {
|
|
+ $userId = $this->getConfigData('username');
|
|
+ $userIdPass = $this->getConfigData('password');
|
|
+ $accessKey = $this->getConfigData('access_license_number');
|
|
+
|
|
+ $this->_xmlAccessRequest = <<<XMLAuth
|
|
+<?xml version="1.0" ?>
|
|
+<AccessRequest xml:lang="en-US">
|
|
+ <AccessLicenseNumber>$accessKey</AccessLicenseNumber>
|
|
+ <UserId>$userId</UserId>
|
|
+ <Password>$userIdPass</Password>
|
|
+</AccessRequest>
|
|
+XMLAuth;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * To receive access token
|
|
+ *
|
|
+ * @return mixed
|
|
+ * @throws LocalizedException
|
|
+ */
|
|
+ protected function setAPIAccessRequest()
|
|
+ {
|
|
+ $userId = $this->getConfigData('username');
|
|
+ $userIdPass = $this->getConfigData('password');
|
|
+ if ($this->getConfigData('is_account_live')) {
|
|
+ $authUrl = $this->_liveUrls['AuthUrl'];
|
|
+ } else {
|
|
+ $authUrl = $this->_defaultUrls['AuthUrl'];
|
|
+ }
|
|
+ return $this->upsAuth->getAccessToken($userId, $userIdPass, $authUrl);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get cgi tracking
|
|
+ *
|
|
+ * @param string[] $trackings
|
|
+ * @return TrackFactory
|
|
+ */
|
|
+ protected function _getCgiTracking($trackings)
|
|
+ {
|
|
+ //ups no longer support tracking for data streaming version
|
|
+ //so we can only reply the popup window to ups.
|
|
+ $result = $this->_trackFactory->create();
|
|
+ foreach ($trackings as $tracking) {
|
|
+ $status = $this->_trackStatusFactory->create();
|
|
+ $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 string[] $trackings
|
|
+ * @return Result
|
|
+ */
|
|
+ protected function _getXmlTracking($trackings)
|
|
+ {
|
|
+ $url = $this->getConfigData('tracking_xml_url');
|
|
+
|
|
+ /** @var HttpResponseDeferredInterface[] $trackingResponses */
|
|
+ $trackingResponses = [];
|
|
+ $tracking = '';
|
|
+ $debugData = [];
|
|
+ foreach ($trackings as $tracking) {
|
|
+ /**
|
|
+ * RequestOption==>'1' to request all activities
|
|
+ */
|
|
+ $xmlRequest = <<<XMLAuth
|
|
+<?xml version="1.0" ?>
|
|
+<TrackRequest xml:lang="en-US">
|
|
+ <IncludeMailInnovationIndicator/>
|
|
+ <Request>
|
|
+ <RequestAction>Track</RequestAction>
|
|
+ <RequestOption>1</RequestOption>
|
|
+ </Request>
|
|
+ <TrackingNumber>$tracking</TrackingNumber>
|
|
+ <IncludeFreight>01</IncludeFreight>
|
|
+</TrackRequest>
|
|
+XMLAuth;
|
|
+ $debugData[$tracking] = ['request' => $this->filterDebugData($this->_xmlAccessRequest) . $xmlRequest];
|
|
+ $trackingResponses[$tracking] = $this->asyncHttpClient->request(
|
|
+ new Request(
|
|
+ $url,
|
|
+ Request::METHOD_POST,
|
|
+ ['Content-Type' => 'application/xml'],
|
|
+ $this->_xmlAccessRequest . $xmlRequest
|
|
+ )
|
|
+ );
|
|
+ }
|
|
+ foreach ($trackingResponses as $tracking => $response) {
|
|
+ $httpResponse = $response->get();
|
|
+ $xmlResponse = $httpResponse->getStatusCode() >= 400 ? '' : $httpResponse->getBody();
|
|
+
|
|
+ $debugData[$tracking]['result'] = $xmlResponse;
|
|
+ $this->_debug($debugData);
|
|
+ $this->_parseXmlTrackingResponse($tracking, $xmlResponse);
|
|
+ }
|
|
+
|
|
+ return $this->_result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Parse xml tracking response
|
|
+ *
|
|
+ * @param string $trackingValue
|
|
+ * @param string $xmlResponse
|
|
+ * @return null
|
|
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
|
+ */
|
|
+ protected function _parseXmlTrackingResponse($trackingValue, $xmlResponse)
|
|
+ {
|
|
+ $errorTitle = 'For some reason we can\'t retrieve tracking info right now.';
|
|
+ $resultArr = [];
|
|
+ $packageProgress = [];
|
|
+
|
|
+ if ($xmlResponse) {
|
|
+ $xml = new \Magento\Framework\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) {
|
|
+ $index = 1;
|
|
+ foreach ($activityTags as $activityTag) {
|
|
+ $this->processActivityXmlTagInfo($activityTag, $index, $resultArr, $packageProgress);
|
|
+ }
|
|
+ $resultArr['progressdetail'] = $packageProgress;
|
|
+ }
|
|
+ } else {
|
|
+ $arr = $xml->getXpath("//TrackResponse/Response/Error/ErrorDescription/text()");
|
|
+ $errorTitle = (string)$arr[0][0];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return $this->setTrackingResultData($resultArr, $trackingValue, $errorTitle);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Process tracking info from activity tag
|
|
+ *
|
|
+ * @param \Magento\Framework\Simplexml\Element $activityTag
|
|
+ * @param int $index
|
|
+ * @param array $resultArr
|
|
+ * @param array $packageProgress
|
|
+ */
|
|
+ private function processActivityXmlTagInfo(
|
|
+ \Magento\Framework\Simplexml\Element $activityTag,
|
|
+ int &$index,
|
|
+ array &$resultArr,
|
|
+ array &$packageProgress
|
|
+ ) {
|
|
+ $addressArr = [];
|
|
+ if (isset($activityTag->ActivityLocation->Address->City)) {
|
|
+ $addressArr[] = (string)$activityTag->ActivityLocation->Address->City;
|
|
+ }
|
|
+ if (isset($activityTag->ActivityLocation->Address->StateProvinceCode)) {
|
|
+ $addressArr[] = (string)$activityTag->ActivityLocation->Address->StateProvinceCode;
|
|
+ }
|
|
+ if (isset($activityTag->ActivityLocation->Address->CountryCode)) {
|
|
+ $addressArr[] = (string)$activityTag->ActivityLocation->Address->CountryCode;
|
|
+ }
|
|
+ $dateArr = [];
|
|
+ $date = (string)$activityTag->Date;
|
|
+ //YYYYMMDD
|
|
+ $dateArr[] = substr($date, 0, 4);
|
|
+ $dateArr[] = substr($date, 4, 2);
|
|
+ $dateArr[] = substr($date, -2, 2);
|
|
+
|
|
+ $timeArr = [];
|
|
+ $time = (string)$activityTag->Time;
|
|
+ //HHMMSS
|
|
+ $timeArr[] = substr($time, 0, 2);
|
|
+ $timeArr[] = substr($time, 2, 2);
|
|
+ $timeArr[] = substr($time, -2, 2);
|
|
+
|
|
+ if ($index === 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 ($addressArr) {
|
|
+ $resultArr['deliveryto'] = implode(', ', $addressArr);
|
|
+ }
|
|
+ } else {
|
|
+ $tempArr = [];
|
|
+ $tempArr['activity'] = (string)$activityTag->Status->StatusType->Description;
|
|
+ $tempArr['deliverydate'] = implode('-', $dateArr);
|
|
+ //YYYY-MM-DD
|
|
+ $tempArr['deliverytime'] = implode(':', $timeArr);
|
|
+ //HH:MM:SS
|
|
+ if ($addressArr) {
|
|
+ $tempArr['deliverylocation'] = implode(', ', $addressArr);
|
|
+ }
|
|
+ $packageProgress[] = $tempArr;
|
|
+ }
|
|
+ $index++;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Get REST tracking
|
|
+ *
|
|
+ * @param string[] $trackings
|
|
+ * @return Result
|
|
+ */
|
|
+ protected function _getRestTracking($trackings)
|
|
+ {
|
|
+ $url = $this->getConfigData('tracking_rest_url');
|
|
+ $accessToken = $this->setAPIAccessRequest();
|
|
+
|
|
+ /** @var HttpResponseDeferredInterface[] $trackingResponses */
|
|
+ $trackingResponses = [];
|
|
+ $tracking = '';
|
|
+ $debugData = [];
|
|
foreach ($trackings as $tracking) {
|
|
/**
|
|
* RequestOption==>'1' to request all activities
|
|
*/
|
|
- $xmlRequest = <<<XMLAuth
|
|
-<?xml version="1.0" ?>
|
|
-<TrackRequest xml:lang="en-US">
|
|
- <IncludeMailInnovationIndicator/>
|
|
- <Request>
|
|
- <RequestAction>Track</RequestAction>
|
|
- <RequestOption>1</RequestOption>
|
|
- </Request>
|
|
- <TrackingNumber>$tracking</TrackingNumber>
|
|
- <IncludeFreight>01</IncludeFreight>
|
|
-</TrackRequest>
|
|
-XMLAuth;
|
|
- $debugData[$tracking] = ['request' => $this->filterDebugData($this->_xmlAccessRequest) . $xmlRequest];
|
|
+ $queryParams = [
|
|
+ "locale" => "en_US",
|
|
+ "returnSignature" => "false"
|
|
+ ];
|
|
+ $trackParams = (object)[];
|
|
+ $trackPayload = json_encode($trackParams);
|
|
+ $transid = 'track'.uniqid();
|
|
+ $headers = [
|
|
+ "Authorization" => "Bearer " . $accessToken,
|
|
+ "Content-Type" => "application/json",
|
|
+ "transId" => $transid,
|
|
+ "transactionSrc" => "testing"
|
|
+ ];
|
|
+
|
|
+ $debugData[$tracking] = ['request' => $trackPayload];
|
|
$trackingResponses[$tracking] = $this->asyncHttpClient->request(
|
|
new Request(
|
|
- $url,
|
|
- Request::METHOD_POST,
|
|
- ['Content-Type' => 'application/xml'],
|
|
- $this->_xmlAccessRequest . $xmlRequest
|
|
+ $url.'v1/details/'. $tracking . "?" . http_build_query($queryParams),
|
|
+ Request::METHOD_GET,
|
|
+ $headers,
|
|
+ $trackPayload
|
|
)
|
|
);
|
|
}
|
|
foreach ($trackingResponses as $tracking => $response) {
|
|
$httpResponse = $response->get();
|
|
- $xmlResponse = $httpResponse->getStatusCode() >= 400 ? '' : $httpResponse->getBody();
|
|
-
|
|
- $debugData[$tracking]['result'] = $xmlResponse;
|
|
+ $jsonResponse = $httpResponse->getStatusCode() >= 400 ? '' : $httpResponse->getBody();
|
|
+ $debugData[$tracking]['result'] = $jsonResponse;
|
|
$this->_debug($debugData);
|
|
- $this->_parseXmlTrackingResponse($tracking, $xmlResponse);
|
|
+ $this->_parseRestTrackingResponse($tracking, $jsonResponse);
|
|
}
|
|
|
|
return $this->_result;
|
|
}
|
|
|
|
/**
|
|
- * Parse xml tracking response
|
|
+ * Parse REST tracking response
|
|
*
|
|
* @param string $trackingValue
|
|
- * @param string $xmlResponse
|
|
+ * @param string $jsonResponse
|
|
* @return null
|
|
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
|
*/
|
|
- protected function _parseXmlTrackingResponse($trackingValue, $xmlResponse)
|
|
+ protected function _parseRestTrackingResponse($trackingValue, $jsonResponse)
|
|
{
|
|
$errorTitle = 'For some reason we can\'t retrieve tracking info right now.';
|
|
$resultArr = [];
|
|
$packageProgress = [];
|
|
|
|
- if ($xmlResponse) {
|
|
- $xml = new \Magento\Framework\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}";
|
|
+ if ($jsonResponse) {
|
|
+ $responseData = json_decode($jsonResponse, true);
|
|
|
|
- $activityTags = $xml->getXpath("//TrackResponse/Shipment/Package/Activity");
|
|
+ if ($responseData['trackResponse']['shipment']) {
|
|
+ $activityTags = $responseData['trackResponse']['shipment'][0]['package'][0]['activity'] ?? [];
|
|
if ($activityTags) {
|
|
$index = 1;
|
|
foreach ($activityTags as $activityTag) {
|
|
- $this->processActivityTagInfo($activityTag, $index, $resultArr, $packageProgress);
|
|
+ $this->processActivityRestTagInfo($activityTag, $index, $resultArr, $packageProgress);
|
|
}
|
|
$resultArr['progressdetail'] = $packageProgress;
|
|
}
|
|
} else {
|
|
- $arr = $xml->getXpath("//TrackResponse/Response/Error/ErrorDescription/text()");
|
|
- $errorTitle = (string)$arr[0][0];
|
|
+ $errorTitle = $responseData['errors']['message'];
|
|
}
|
|
}
|
|
|
|
+ return $this->setTrackingResultData($resultArr, $trackingValue, $errorTitle);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Set Tracking Response Data
|
|
+ *
|
|
+ * @param array $resultArr
|
|
+ * @param string $trackingValue
|
|
+ * @param string $errorTitle
|
|
+ * @return Result|\Magento\Shipping\Model\Tracking\Result
|
|
+ */
|
|
+ private function setTrackingResultData($resultArr, $trackingValue, $errorTitle)
|
|
+ {
|
|
if (!$this->_result) {
|
|
$this->_result = $this->_trackFactory->create();
|
|
}
|
|
@@ -1311,55 +1841,53 @@ protected function _parseXmlTrackingResponse($trackingValue, $xmlResponse)
|
|
/**
|
|
* Process tracking info from activity tag
|
|
*
|
|
- * @param \Magento\Framework\Simplexml\Element $activityTag
|
|
+ * @param array $activityTag
|
|
* @param int $index
|
|
* @param array $resultArr
|
|
* @param array $packageProgress
|
|
*/
|
|
- private function processActivityTagInfo(
|
|
- \Magento\Framework\Simplexml\Element $activityTag,
|
|
+ private function processActivityRestTagInfo(
|
|
+ array $activityTag,
|
|
int &$index,
|
|
array &$resultArr,
|
|
array &$packageProgress
|
|
) {
|
|
$addressArr = [];
|
|
- if (isset($activityTag->ActivityLocation->Address->City)) {
|
|
- $addressArr[] = (string)$activityTag->ActivityLocation->Address->City;
|
|
+ if (isset($activityTag['location']['address']['city'])) {
|
|
+ $addressArr[] = (string)$activityTag['location']['address']['city'];
|
|
}
|
|
- if (isset($activityTag->ActivityLocation->Address->StateProvinceCode)) {
|
|
- $addressArr[] = (string)$activityTag->ActivityLocation->Address->StateProvinceCode;
|
|
+ if (isset($activityTag['location']['address']['stateProvince'])) {
|
|
+ $addressArr[] = (string)$activityTag['location']['address']['stateProvince'];
|
|
}
|
|
- if (isset($activityTag->ActivityLocation->Address->CountryCode)) {
|
|
- $addressArr[] = (string)$activityTag->ActivityLocation->Address->CountryCode;
|
|
+ if (isset($activityTag['location']['address']['countryCode'])) {
|
|
+ $addressArr[] = (string)$activityTag['location']['address']['countryCode'];
|
|
}
|
|
$dateArr = [];
|
|
- $date = (string)$activityTag->Date;
|
|
+ $date = (string)$activityTag['date'];
|
|
//YYYYMMDD
|
|
$dateArr[] = substr($date, 0, 4);
|
|
$dateArr[] = substr($date, 4, 2);
|
|
$dateArr[] = substr($date, -2, 2);
|
|
|
|
$timeArr = [];
|
|
- $time = (string)$activityTag->Time;
|
|
+ $time = (string)$activityTag['time'];
|
|
//HHMMSS
|
|
$timeArr[] = substr($time, 0, 2);
|
|
$timeArr[] = substr($time, 2, 2);
|
|
$timeArr[] = substr($time, -2, 2);
|
|
|
|
if ($index === 1) {
|
|
- $resultArr['status'] = (string)$activityTag->Status->StatusType->Description;
|
|
+ $resultArr['status'] = (string)$activityTag['status']['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 ($addressArr) {
|
|
$resultArr['deliveryto'] = implode(', ', $addressArr);
|
|
}
|
|
} else {
|
|
$tempArr = [];
|
|
- $tempArr['activity'] = (string)$activityTag->Status->StatusType->Description;
|
|
+ $tempArr['activity'] = (string)$activityTag['status']['description'];
|
|
$tempArr['deliverydate'] = implode('-', $dateArr);
|
|
//YYYY-MM-DD
|
|
$tempArr['deliverytime'] = implode(':', $timeArr);
|
|
@@ -1408,9 +1936,10 @@ public function getAllowedMethods()
|
|
{
|
|
$allowedMethods = explode(',', (string)$this->getConfigData('allowed_methods'));
|
|
$isUpsXml = $this->getConfigData('type') === 'UPS_XML';
|
|
+ $isUpsRest = $this->getConfigData('type') === 'UPS_REST';
|
|
$origin = $this->getConfigData('origin_shipment');
|
|
|
|
- $availableByTypeMethods = $isUpsXml
|
|
+ $availableByTypeMethods = ($isUpsXml || $isUpsRest)
|
|
? $this->configHelper->getCode('originShipment', $origin)
|
|
: $this->configHelper->getCode('method');
|
|
|
|
@@ -1941,11 +2470,19 @@ public function getShipConfirmUrl()
|
|
$url = $this->getConfigData('url');
|
|
if (!$url) {
|
|
if ($this->getConfigData('is_account_live')) {
|
|
- $url = $this->_liveUrls['ShipConfirm'];
|
|
+ if ($this->getConfigData('type') == 'UPS_XML') {
|
|
+ $url = $this->_liveUrls['ShipConfirm'];
|
|
+ } else {
|
|
+ $url = $this->_liveUrls['ShipRestConfirm'];
|
|
+ }
|
|
|
|
return $url;
|
|
} else {
|
|
- $url = $this->_defaultUrls['ShipConfirm'];
|
|
+ if ($this->getConfigData('type') == 'UPS_XML') {
|
|
+ $url = $this->_defaultUrls['ShipConfirm'];
|
|
+ } else {
|
|
+ $url = $this->_defaultUrls['ShipRestConfirm'];
|
|
+ }
|
|
|
|
return $url;
|
|
}
|
|
@@ -1969,8 +2506,14 @@ public function requestToShipment($request)
|
|
|
|
// phpcs:disable
|
|
try {
|
|
- $quoteIds = $this->requestQuotes($request);
|
|
- $labels = $this->requestShipments($quoteIds);
|
|
+ $labels = '';
|
|
+ if ($this->getConfigData('type') == 'UPS_XML') {
|
|
+ $quoteIds = $this->requestQuotes($request);
|
|
+ $labels = $this->requestShipments($quoteIds);
|
|
+ } elseif ($this->getConfigData('type') == 'UPS_REST') {
|
|
+ $labels = $this->requestRestQuotes($request);
|
|
+ }
|
|
+
|
|
} catch (LocalizedException $exception) {
|
|
$this->_logger->critical($exception);
|
|
return new DataObject(['errors' => [$exception->getMessage()]]);
|
|
@@ -1983,6 +2526,307 @@ public function requestToShipment($request)
|
|
return new DataObject(['info' => $labels]);
|
|
}
|
|
|
|
+ /**
|
|
+ * Form REST for shipment request
|
|
+ *
|
|
+ * @param DataObject $request
|
|
+ * @return string
|
|
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
+ * @SuppressWarnings(PHPMD.NPathComplexity)
|
|
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
|
+ */
|
|
+ protected function _formShipmentRestRequest(DataObject $request)
|
|
+ {
|
|
+ $packages = $request->getPackages();
|
|
+ $shipmentItems = [];
|
|
+ foreach ($packages as $package) {
|
|
+ $shipmentItems[] = $package['items'];
|
|
+ }
|
|
+ $shipmentItems = array_merge([], ...$shipmentItems);
|
|
+
|
|
+ /** Shipment API Payload */
|
|
+
|
|
+ $shipParams = [
|
|
+ "ShipmentRequest" => [
|
|
+ "Request" => [
|
|
+ "SubVersion" => "1801",
|
|
+ "RequestOption" => "nonvalidate",
|
|
+ "TransactionReference" => [
|
|
+ "CustomerContext" => "Shipment Request"
|
|
+ ]
|
|
+ ],
|
|
+ "Shipment" => [
|
|
+ "Description" => "{$this->generateShipmentDescription($shipmentItems)}",
|
|
+ "Shipper" => [],
|
|
+ "ShipTo" => [],
|
|
+ "ShipFrom" => [],
|
|
+ "PaymentInformation" => [],
|
|
+ "Service" => [],
|
|
+ "Package" => [],
|
|
+ "ShipmentServiceOptions" => []
|
|
+ ],
|
|
+ "LabelSpecification" => []
|
|
+ ]
|
|
+ ];
|
|
+
|
|
+ if ($request->getIsReturn()) {
|
|
+ $returnPart = &$shipParams['ShipmentRequest']['Shipment'];
|
|
+ $returnPart['ReturnService']['Code'] = '9';
|
|
+ }
|
|
+
|
|
+ /** Shipment Details */
|
|
+ if ($request->getIsReturn()) {
|
|
+ $shipperData = &$shipParams['ShipmentRequest']['Shipment']['Shipper'];
|
|
+
|
|
+ $shipperData['Name'] = $request->getRecipientContactCompanyName();
|
|
+ $shipperData['AttentionName'] = $request->getRecipientContactPersonName();
|
|
+ $shipperData['ShipperNumber'] = $this->getConfigData('shipper_number');
|
|
+ $shipperData['Phone']['Number'] = $request->getRecipientContactPhoneNumber();
|
|
+
|
|
+ $addressData = &$shipperData['Address'];
|
|
+ $addressData['AddressLine'] =
|
|
+ $request->getRecipientAddressStreet1().' '.$request->getRecipientAddressStreet2();
|
|
+ $addressData['City'] = $request->getRecipientAddressCity();
|
|
+ $addressData['CountryCode'] = $request->getRecipientAddressCountryCode();
|
|
+ $addressData['PostalCode'] = $request->getRecipientAddressPostalCode();
|
|
+
|
|
+ if ($request->getRecipientAddressStateOrProvinceCode()) {
|
|
+ $addressData['StateProvinceCode'] = $request->getRecipientAddressStateOrProvinceCode();
|
|
+ }
|
|
+ } else {
|
|
+ $shipperData = &$shipParams['ShipmentRequest']['Shipment']['Shipper'];
|
|
+
|
|
+ $shipperData['Name'] = $request->getShipperContactCompanyName();
|
|
+ $shipperData['AttentionName'] = $request->getShipperContactPersonName();
|
|
+ $shipperData['ShipperNumber'] = $this->getConfigData('shipper_number');
|
|
+ $shipperData['Phone']['Number'] = $request->getShipperContactPhoneNumber();
|
|
+
|
|
+ $addressData = &$shipperData['Address'];
|
|
+ $addressData['AddressLine'] = $request->getShipperAddressStreet1().' '.$request->getShipperAddressStreet2();
|
|
+ $addressData['City'] = $request->getShipperAddressCity();
|
|
+ $addressData['CountryCode'] = $request->getShipperAddressCountryCode();
|
|
+ $addressData['PostalCode'] = $request->getShipperAddressPostalCode();
|
|
+
|
|
+ if ($request->getShipperAddressStateOrProvinceCode()) {
|
|
+ $addressData['StateProvinceCode'] = $request->getShipperAddressStateOrProvinceCode();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ $shipToData = &$shipParams['ShipmentRequest']['Shipment']['ShipTo'];
|
|
+ $shipToData = [
|
|
+ 'Name' => $request->getRecipientContactPersonName(),
|
|
+ 'AttentionName' => $request->getRecipientContactPersonName(),
|
|
+ 'Phone' => ['Number' => $request->getRecipientContactPhoneNumber()],
|
|
+ 'Address' => [
|
|
+ 'AddressLine' => $request->getRecipientAddressStreet1().' '.$request->getRecipientAddressStreet2(),
|
|
+ 'City' => $request->getRecipientAddressCity(),
|
|
+ 'CountryCode' => $request->getRecipientAddressCountryCode(),
|
|
+ 'PostalCode' => $request->getRecipientAddressPostalCode(),
|
|
+ ],
|
|
+ ];
|
|
+ if ($request->getRecipientAddressStateOrProvinceCode()) {
|
|
+ $shipToData['Address']['StateProvinceCode'] = $request->getRecipientAddressRegionCode();
|
|
+ }
|
|
+ if ($this->getConfigData('dest_type') == 'RES') {
|
|
+ $shipToData['Address']['ResidentialAddress'] = '';
|
|
+ }
|
|
+
|
|
+ if ($request->getIsReturn()) {
|
|
+ $shipFrom = &$shipParams['ShipmentRequest']['Shipment']['ShipFrom'];
|
|
+ $shipFrom['Name'] = $request->getShipperContactPersonName();
|
|
+ $shipFrom['AttentionName'] = $request->getShipperContactPersonName();
|
|
+ $address = &$shipFrom['Address'];
|
|
+ $address['AddressLine'] = $request->getShipperAddressStreet1().' '.$request->getShipperAddressStreet2();
|
|
+ $address['City'] = $request->getShipperAddressCity();
|
|
+ $address['CountryCode'] = $request->getShipperAddressCountryCode();
|
|
+ $address['PostalCode'] = $request->getShipperAddressPostalCode();
|
|
+ if ($request->getShipperAddressStateOrProvinceCode()) {
|
|
+ $address['StateProvinceCode'] = $request->getShipperAddressStateOrProvinceCode();
|
|
+ }
|
|
+
|
|
+ $shipToAddress = &$shipToData['Address'];
|
|
+ $shipToAddress['AddressLine'] =
|
|
+ $request->getShipperAddressStreet1().' '.$request->getShipperAddressStreet2();
|
|
+ $shipToAddress['City'] = $request->getShipperAddressCity();
|
|
+ $shipToAddress['CountryCode'] = $request->getShipperAddressCountryCode();
|
|
+ $shipToAddress['PostalCode'] = $request->getShipperAddressPostalCode();
|
|
+ if ($request->getShipperAddressStateOrProvinceCode()) {
|
|
+ $shipToAddress['StateProvinceCode'] = $request->getShipperAddressStateOrProvinceCode();
|
|
+ }
|
|
+ if ($this->getConfigData('dest_type') == 'RES') {
|
|
+ $shipToAddress['ResidentialAddress'] = '';
|
|
+ }
|
|
+ }
|
|
+
|
|
+ $shipParams['ShipmentRequest']['Shipment']['Service']['Code'] = $request->getShippingMethod();
|
|
+
|
|
+ $packagePart = [];
|
|
+ $customsTotal = 0;
|
|
+ $packagingTypes = [];
|
|
+ $deliveryConfirmationLevel = $this->_getDeliveryConfirmationLevel(
|
|
+ $request->getRecipientAddressCountryCode()
|
|
+ );
|
|
+ foreach ($packages as $packageId => $package) {
|
|
+ $packageRestItems = $package['items'];
|
|
+ $packageRestParams = new DataObject($package['params']);
|
|
+ $packagingType = $package['params']['container'];
|
|
+ $packagingTypes[] = $packagingType;
|
|
+ $height = $packageRestParams->getHeight();
|
|
+ $width = $packageRestParams->getWidth();
|
|
+ $length = $packageRestParams->getLength();
|
|
+ $weight = $packageRestParams->getWeight();
|
|
+ $weightUnits = $packageRestParams->getWeightUnits() == Weight::POUND ? 'LBS' : 'KGS';
|
|
+ $dimensionsUnits = $packageRestParams->getDimensionUnits() == Length::INCH ? 'IN' : 'CM';
|
|
+ $deliveryConfirmation = $packageRestParams->getDeliveryConfirmation();
|
|
+ $customsTotal += $packageRestParams->getCustomsValue();
|
|
+
|
|
+ $packagePart[$packageId] = &$shipParams['ShipmentRequest']['Shipment']['Package'];
|
|
+ $packagePart[$packageId]['Description'] = $this->generateShipmentDescription($packageRestItems);
|
|
+ //empirical
|
|
+ $packagePart[$packageId]['Packaging']['Code'] = $packagingType;
|
|
+ $packagePart[$packageId]['PackageWeight'] = [];
|
|
+ $packageWeight = &$packagePart[$packageId]['PackageWeight'];
|
|
+ $packageWeight['Weight'] = $weight;
|
|
+ $packageWeight['UnitOfMeasurement']['Code'] = $weightUnits;
|
|
+ // set dimensions
|
|
+ if ($length || $width || $height) {
|
|
+ $packagePart[$packageId]['Dimensions'] = [];
|
|
+ $packageDimensions = &$packagePart[$packageId]['Dimensions'];
|
|
+ $packageDimensions['UnitOfMeasurement']['Code'] = $dimensionsUnits;
|
|
+ $packageDimensions['Length'] = $length;
|
|
+ $packageDimensions['Width'] = $width;
|
|
+ $packageDimensions['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() . $packageId;
|
|
+ } else {
|
|
+ $referenceData = 'Order #' .
|
|
+ $request->getOrderShipment()->getOrder()->getIncrementId() .
|
|
+ ' P' .
|
|
+ $packageId;
|
|
+ }
|
|
+ $packagePart[$packageId]['ReferenceNumber'] = [];
|
|
+ $referencePart = &$packagePart[$packageId]['ReferenceNumber'];
|
|
+ $referencePart['Code'] = '02';
|
|
+ $referencePart['Value'] = $referenceData;
|
|
+ }
|
|
+ if ($deliveryConfirmation && $deliveryConfirmationLevel === self::DELIVERY_CONFIRMATION_PACKAGE) {
|
|
+ $packagePart[$packageId]['PackageServiceOptions']['DeliveryConfirmation']['DCISType'] =
|
|
+ $deliveryConfirmation;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!empty($deliveryConfirmation) && $deliveryConfirmationLevel === self::DELIVERY_CONFIRMATION_SHIPMENT) {
|
|
+ $shipParams['ShipmentRequest']['Shipment']['ShipmentServiceOptions']['DeliveryConfirmation']['DCISType']
|
|
+ = $deliveryConfirmation;
|
|
+ }
|
|
+
|
|
+ $shipParams['ShipmentRequest']['Shipment']['PaymentInformation']['ShipmentCharge']['Type'] = "01";
|
|
+ $shipParams['ShipmentRequest']['Shipment']['PaymentInformation']['ShipmentCharge']['BillShipper']
|
|
+ ['AccountNumber'] = $this->getConfigData('shipper_number');
|
|
+
|
|
+ if (!in_array($this->configHelper->getCode('container', 'ULE'), $packagingTypes)
|
|
+ && $request->getShipperAddressCountryCode() == self::USA_COUNTRY_ID
|
|
+ && ($request->getRecipientAddressCountryCode() == 'CA'
|
|
+ || $request->getRecipientAddressCountryCode() == 'PR')
|
|
+ ) {
|
|
+ $invoiceLineTotalPart = &$shipParams['ShipmentRequest']['Shipment']['InvoiceLineTotal'];
|
|
+ $invoiceLineTotalPart['CurrencyCode'] = $request->getBaseCurrencyCode();
|
|
+ $invoiceLineTotalPart['MonetaryValue'] = ceil($customsTotal);
|
|
+ }
|
|
+
|
|
+ /** Label Details */
|
|
+
|
|
+ $labelPart = &$shipParams['ShipmentRequest']['LabelSpecification'];
|
|
+ $labelPart['LabelImageFormat']['Code'] = 'GIF';
|
|
+
|
|
+ return json_encode($shipParams);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Request quotes for given packages.
|
|
+ *
|
|
+ * @param DataObject $request
|
|
+ * @return string[] Quote IDs.
|
|
+ * @throws LocalizedException
|
|
+ * @throws RuntimeException
|
|
+ */
|
|
+ private function requestRestQuotes(DataObject $request): array
|
|
+ {
|
|
+ $request->setShipperAddressCountryCode(
|
|
+ $this->getNormalizedCountryCode(
|
|
+ $request->getShipperAddressCountryCode(),
|
|
+ $request->getShipperAddressStateOrProvinceCode(),
|
|
+ $request->getShipperAddressPostalCode(),
|
|
+ )
|
|
+ );
|
|
+
|
|
+ $request->setRecipientAddressCountryCode(
|
|
+ $this->getNormalizedCountryCode(
|
|
+ $request->getRecipientAddressCountryCode(),
|
|
+ $request->getRecipientAddressStateOrProvinceCode(),
|
|
+ $request->getRecipientAddressPostalCode(),
|
|
+ )
|
|
+ );
|
|
+
|
|
+ /** @var HttpResponseDeferredInterface[] $quotesRequests */
|
|
+ //Getting quotes
|
|
+ $this->_prepareShipmentRequest($request);
|
|
+ $rawJsonRequest = $this->_formShipmentRestRequest($request);
|
|
+ $accessToken = $this->setAPIAccessRequest();
|
|
+ $this->_debug(['request_quote' => $rawJsonRequest]);
|
|
+ $headers = [
|
|
+ 'Content-Type' => 'application/json',
|
|
+ 'Authorization' => 'Bearer '. $accessToken,
|
|
+ ];
|
|
+ $shippingRequests[] = $this->asyncHttpClient->request(
|
|
+ new Request(
|
|
+ $this->getShipConfirmUrl(),
|
|
+ Request::METHOD_POST,
|
|
+ $headers,
|
|
+ $rawJsonRequest
|
|
+ )
|
|
+ );
|
|
+
|
|
+ //Processing shipment requests
|
|
+ /** @var DataObject[] $results */
|
|
+ $results = [];
|
|
+ foreach ($shippingRequests as $shippingRequest) {
|
|
+ $httpResponse = $shippingRequest->get();
|
|
+ if ($httpResponse->getStatusCode() >= 400) {
|
|
+ throw new LocalizedException(__('Failed to send the package'));
|
|
+ }
|
|
+ try {
|
|
+ /** @var Element $response */
|
|
+ $response = $httpResponse->getBody();
|
|
+ $this->_debug(['response_shipment' => $response]);
|
|
+ } catch (Throwable $e) {
|
|
+ throw new RuntimeException($e->getMessage());
|
|
+ }
|
|
+ if (isset($response->Error)) {
|
|
+ throw new RuntimeException((string)$response->Error->ErrorDescription);
|
|
+ }
|
|
+
|
|
+ $responseShipment = json_decode($response, true);
|
|
+ $result = new DataObject();
|
|
+ $shippingLabelContent =
|
|
+ (string)$responseShipment['ShipmentResponse']['ShipmentResults']['PackageResults']['ShippingLabel']
|
|
+ ['GraphicImage'];
|
|
+ $trackingNumber =
|
|
+ (string)$responseShipment['ShipmentResponse']['ShipmentResults']['PackageResults']['TrackingNumber'];
|
|
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
|
|
+ $result->setLabelContent(base64_decode($shippingLabelContent));
|
|
+ $result->setTrackingNumber($trackingNumber);
|
|
+ $results[] = $result;
|
|
+ }
|
|
+
|
|
+ return $results;
|
|
+ }
|
|
+
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
diff --git a/vendor/magento/module-ups/Model/Config/Source/Type.php b/vendor/magento/module-ups/Model/Config/Source/Type.php
|
|
index 05e6761e17ce..580d1f37755b 100644
|
|
--- a/vendor/magento/module-ups/Model/Config/Source/Type.php
|
|
+++ b/vendor/magento/module-ups/Model/Config/Source/Type.php
|
|
@@ -7,19 +7,17 @@
|
|
|
|
use Magento\Framework\Data\OptionSourceInterface;
|
|
|
|
-/**
|
|
- * Class Type
|
|
- */
|
|
class Type implements OptionSourceInterface
|
|
{
|
|
/**
|
|
- * {@inheritdoc}
|
|
+ * @inheritdoc
|
|
*/
|
|
public function toOptionArray()
|
|
{
|
|
return [
|
|
['value' => 'UPS', 'label' => __('United Parcel Service')],
|
|
- ['value' => 'UPS_XML', 'label' => __('United Parcel Service XML')]
|
|
+ ['value' => 'UPS_XML', 'label' => __('United Parcel Service XML')],
|
|
+ ['value' => 'UPS_REST', 'label' => __('United Parcel Service REST')]
|
|
];
|
|
}
|
|
}
|
|
diff --git a/vendor/magento/module-ups/Model/UpsAuth.php b/vendor/magento/module-ups/Model/UpsAuth.php
|
|
new file mode 100644
|
|
index 000000000000..e85c6b1aaf92
|
|
--- /dev/null
|
|
+++ b/vendor/magento/module-ups/Model/UpsAuth.php
|
|
@@ -0,0 +1,120 @@
|
|
+<?php
|
|
+/**
|
|
+ * Copyright © Magento, Inc. All rights reserved.
|
|
+ * See COPYING.txt for license details.
|
|
+ */
|
|
+declare(strict_types=1);
|
|
+
|
|
+namespace Magento\Ups\Model;
|
|
+
|
|
+use Magento\Framework\App\Cache\Type\Config as Cache;
|
|
+use Magento\Framework\App\ObjectManager;
|
|
+use Magento\Framework\Exception\LocalizedException;
|
|
+use Magento\Framework\Exception\NoSuchEntityException;
|
|
+use Magento\Framework\HTTP\AsyncClient\Request;
|
|
+use Magento\Framework\HTTP\AsyncClientInterface;
|
|
+use Magento\Quote\Model\Quote\Address\RateRequest;
|
|
+use Magento\Quote\Model\Quote\Address\RateResult\Error;
|
|
+use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
|
|
+use Magento\Shipping\Model\Carrier\AbstractCarrier;
|
|
+
|
|
+class UpsAuth extends AbstractCarrier
|
|
+{
|
|
+ public const CACHE_KEY_PREFIX = 'ups_api_token_';
|
|
+
|
|
+ /**
|
|
+ * @var AsyncClientInterface
|
|
+ */
|
|
+ private $asyncHttpClient;
|
|
+
|
|
+ /**
|
|
+ * @var Cache
|
|
+ */
|
|
+ private $cache;
|
|
+
|
|
+ /**
|
|
+ * @var ErrorFactory
|
|
+ */
|
|
+ public $_rateErrorFactory;
|
|
+
|
|
+ /**
|
|
+ * @param AsyncClientInterface|null $asyncHttpClient
|
|
+ * @param Cache $cacheManager
|
|
+ * @param ErrorFactory $rateErrorFactory
|
|
+ */
|
|
+ public function __construct(
|
|
+ AsyncClientInterface $asyncHttpClient = null,
|
|
+ Cache $cacheManager,
|
|
+ ErrorFactory $rateErrorFactory
|
|
+ ) {
|
|
+ $this->asyncHttpClient = $asyncHttpClient ?? ObjectManager::getInstance()->get(AsyncClientInterface::class);
|
|
+ $this->cache = $cacheManager;
|
|
+ $this->_rateErrorFactory = $rateErrorFactory;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Token Generation
|
|
+ *
|
|
+ * @param String $clientId
|
|
+ * @param String $clientSecret
|
|
+ * @param String $clientUrl
|
|
+ * @return bool|string
|
|
+ * @throws LocalizedException
|
|
+ * @throws \Throwable
|
|
+ */
|
|
+ public function getAccessToken($clientId, $clientSecret, $clientUrl)
|
|
+ {
|
|
+ $cacheKey = self::CACHE_KEY_PREFIX;
|
|
+ $result = $this->cache->load($cacheKey);
|
|
+ if (!$result) {
|
|
+ $headers = [
|
|
+ 'Content-Type' => 'application/x-www-form-urlencoded',
|
|
+ 'x-merchant-id' => 'string',
|
|
+ 'Authorization' => 'Basic ' . base64_encode("$clientId:$clientSecret"),
|
|
+ ];
|
|
+ $authPayload = http_build_query([
|
|
+ 'grant_type' => 'client_credentials',
|
|
+ ]);
|
|
+ try {
|
|
+ $asyncResponse = $this->asyncHttpClient->request(new Request(
|
|
+ $clientUrl,
|
|
+ Request::METHOD_POST,
|
|
+ $headers,
|
|
+ $authPayload
|
|
+ ));
|
|
+ $responseResult = $asyncResponse->get();
|
|
+ $responseData = $responseResult->getBody();
|
|
+ $responseData = json_decode($responseData);
|
|
+ if (isset($responseData->access_token)) {
|
|
+ $result = $responseData->access_token;
|
|
+ $this->cache->save($result, $cacheKey, [], $responseData->expires_in ?: 10000);
|
|
+ } else {
|
|
+ $error = $this->_rateErrorFactory->create();
|
|
+ $error->setCarrier('ups');
|
|
+ $error->setCarrierTitle($this->getConfigData('title'));
|
|
+ if ($this->getConfigData('specificerrmsg') !== '') {
|
|
+ $errorTitle = $this->getConfigData('specificerrmsg');
|
|
+ }
|
|
+ if (!isset($errorTitle)) {
|
|
+ $errorTitle = __('Cannot retrieve shipping rates');
|
|
+ }
|
|
+ $error->setErrorMessage($errorTitle);
|
|
+ }
|
|
+ return $result;
|
|
+ } catch (\Magento\Framework\HTTP\AsyncClient\HttpException $e) {
|
|
+ throw new \Magento\Framework\Exception\LocalizedException(__('Error occurred: %1', $e->getMessage()));
|
|
+ }
|
|
+ }
|
|
+ return $result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @inheritDoc
|
|
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
|
+ * phpcs:disable
|
|
+ */
|
|
+ public function collectRates(RateRequest $request)
|
|
+ {
|
|
+ return ''; // This block is empty as not required.
|
|
+ }
|
|
+}
|
|
diff --git a/vendor/magento/module-ups/etc/adminhtml/system.xml b/vendor/magento/module-ups/etc/adminhtml/system.xml
|
|
index 6890e1bdaf87..67d2110c58f1 100644
|
|
--- a/vendor/magento/module-ups/etc/adminhtml/system.xml
|
|
+++ b/vendor/magento/module-ups/etc/adminhtml/system.xml
|
|
@@ -59,6 +59,10 @@
|
|
<label>Gateway XML URL</label>
|
|
<backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model>
|
|
</field>
|
|
+ <field id="gateway_rest_url" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" canRestore="1">
|
|
+ <label>Gateway REST URL</label>
|
|
+ <backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model>
|
|
+ </field>
|
|
<field id="handling_type" translate="label" type="select" sortOrder="110" showInDefault="1" showInWebsite="1" canRestore="1">
|
|
<label>Calculate Handling Fee</label>
|
|
<source_model>Magento\Shipping\Model\Source\HandlingType</source_model>
|
|
@@ -102,6 +106,10 @@
|
|
<label>Tracking XML URL</label>
|
|
<backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model>
|
|
</field>
|
|
+ <field id="tracking_rest_url" translate="label" type="text" sortOrder="60" showInDefault="1" showInWebsite="1" canRestore="1">
|
|
+ <label>Tracking REST URL</label>
|
|
+ <backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model>
|
|
+ </field>
|
|
<field id="type" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" canRestore="1">
|
|
<label>UPS Type</label>
|
|
<source_model>Magento\Ups\Model\Config\Source\Type</source_model>
|
|
diff --git a/vendor/magento/module-ups/etc/config.xml b/vendor/magento/module-ups/etc/config.xml
|
|
index 73b10dd5ff41..aaeccf87c6a4 100644
|
|
--- a/vendor/magento/module-ups/etc/config.xml
|
|
+++ b/vendor/magento/module-ups/etc/config.xml
|
|
@@ -21,11 +21,13 @@
|
|
<free_method>GND</free_method>
|
|
<gateway_url>https://www.ups.com/using/services/rave/qcostcgi.cgi</gateway_url>
|
|
<gateway_xml_url>https://onlinetools.ups.com/ups.app/xml/Rate</gateway_xml_url>
|
|
+ <gateway_rest_url>https://wwwcie.ups.com/api/rating/</gateway_rest_url>
|
|
<handling>0</handling>
|
|
<model>Magento\Ups\Model\Carrier</model>
|
|
<pickup>CC</pickup>
|
|
<title>United Parcel Service</title>
|
|
<tracking_xml_url>https://onlinetools.ups.com/ups.app/xml/Track</tracking_xml_url>
|
|
+ <tracking_rest_url>https://wwwcie.ups.com/api/track/</tracking_rest_url>
|
|
<unit_of_measure>LBS</unit_of_measure>
|
|
<username backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
|
|
<password backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
|
|
diff --git a/vendor/magento/module-ups/etc/di.xml b/vendor/magento/module-ups/etc/di.xml
|
|
index 08d751fc3e2c..ea53e515f7a1 100644
|
|
--- a/vendor/magento/module-ups/etc/di.xml
|
|
+++ b/vendor/magento/module-ups/etc/di.xml
|
|
@@ -13,7 +13,9 @@
|
|
<item name="carriers/ups/password" xsi:type="string">1</item>
|
|
<item name="carriers/ups/access_license_number" xsi:type="string">1</item>
|
|
<item name="carriers/ups/tracking_xml_url" xsi:type="string">1</item>
|
|
+ <item name="carriers/ups/tracking_rest_url" xsi:type="string">1</item>
|
|
<item name="carriers/ups/gateway_xml_url" xsi:type="string">1</item>
|
|
+ <item name="carriers/ups/gateway_rest_url" xsi:type="string">1</item>
|
|
<item name="carriers/ups/shipper_number" xsi:type="string">1</item>
|
|
<item name="carriers/ups/gateway_url" xsi:type="string">1</item>
|
|
</argument>
|
|
@@ -22,6 +24,7 @@
|
|
<item name="carriers/ups/debug" xsi:type="string">1</item>
|
|
<item name="carriers/ups/gateway_url" xsi:type="string">1</item>
|
|
<item name="carriers/ups/gateway_xml_url" xsi:type="string">1</item>
|
|
+ <item name="carriers/ups/gateway_rest_url" xsi:type="string">1</item>
|
|
<item name="carriers/ups/is_account_live" xsi:type="string">1</item>
|
|
<item name="carriers/ups/password" xsi:type="string">1</item>
|
|
<item name="carriers/ups/username" xsi:type="string">1</item>
|
|
diff --git a/vendor/magento/module-ups/view/adminhtml/templates/system/shipping/carrier_config.phtml b/vendor/magento/module-ups/view/adminhtml/templates/system/shipping/carrier_config.phtml
|
|
index b6b7040a41bc..33e3e4ec97d2 100644
|
|
--- a/vendor/magento/module-ups/view/adminhtml/templates/system/shipping/carrier_config.phtml
|
|
+++ b/vendor/magento/module-ups/view/adminhtml/templates/system/shipping/carrier_config.phtml
|
|
@@ -86,6 +86,8 @@ require(["prototype"], function(){
|
|
this.checkingUpsXmlId = ['carriers_ups_gateway_xml_url','carriers_ups_username',
|
|
'carriers_ups_password','carriers_ups_access_license_number'];
|
|
this.checkingUpsId = ['carriers_ups_gateway_url'];
|
|
+ this.checkingUpsRestId = ['carriers_ups_gateway_rest_url','carriers_ups_username',
|
|
+ 'carriers_ups_password'];
|
|
this.originShipmentTitle = '';
|
|
this.allowedMethodsId = 'carriers_ups_allowed_methods';
|
|
this.freeShipmentId = 'carriers_ups_free_method';
|
|
@@ -94,6 +96,10 @@ require(["prototype"], function(){
|
|
'carriers_ups_origin_shipment','carriers_ups_negotiated_active','carriers_ups_shipper_number',
|
|
'carriers_ups_mode_xml','carriers_ups_include_taxes'];
|
|
this.onlyUpsElements = ['carriers_ups_gateway_url'];
|
|
+ this.onlyUpsRestElements = ['carriers_ups_gateway_rest_url','carriers_ups_tracking_rest_url',
|
|
+ 'carriers_ups_username','carriers_ups_password','carriers_ups_origin_shipment',
|
|
+ 'carriers_ups_negotiated_active','carriers_ups_shipper_number','carriers_ups_mode_xml',
|
|
+ 'carriers_ups_include_taxes'];
|
|
this.authUpsXmlElements = ['carriers_ups_username',
|
|
'carriers_ups_password','carriers_ups_access_license_number'];
|
|
|
|
@@ -170,28 +176,52 @@ $scriptString .= <<<script
|
|
for (a = 0; a < this.checkingUpsXmlId.length; a++) {
|
|
$(this.checkingUpsXmlId[a]).removeClassName('required-entry');
|
|
}
|
|
+ for (a = 0; a < this.checkingUpsRestId.length; a++) {
|
|
+ $(this.checkingUpsRestId[a]).removeClassName('required-entry');
|
|
+ }
|
|
for (a = 0; a < this.checkingUpsId.length; a++) {
|
|
$(this.checkingUpsId[a]).addClassName('required-entry');
|
|
this.changeFieldsDisabledState(this.checkingUpsId, a);
|
|
}
|
|
Event.stopObserving($('carriers_ups_origin_shipment'), 'change', this.changeOriginShipment.bind(this));
|
|
- showRowArrayElements(this.onlyUpsElements);
|
|
hideRowArrayElements(this.onlyUpsXmlElements);
|
|
+ hideRowArrayElements(this.onlyUpsRestElements);
|
|
+ showRowArrayElements(this.onlyUpsElements);
|
|
this.changeOriginShipment(null, 'default');
|
|
- } else {
|
|
+ } else if (\$F(this.carriersUpsTypeId) == 'UPS_REST') {
|
|
for (a = 0; a < this.checkingUpsXmlId.length; a++) {
|
|
- $(this.checkingUpsXmlId[a]).addClassName('required-entry');
|
|
- this.changeFieldsDisabledState(this.checkingUpsXmlId, a);
|
|
+ $(this.checkingUpsXmlId[a]).removeClassName('required-entry');
|
|
}
|
|
for (a = 0; a < this.checkingUpsId.length; a++) {
|
|
$(this.checkingUpsId[a]).removeClassName('required-entry');
|
|
}
|
|
+ for (a = 0; a < this.checkingUpsRestId.length; a++) {
|
|
+ $(this.checkingUpsRestId[a]).addClassName('required-entry');
|
|
+ this.changeFieldsDisabledState(this.checkingUpsRestId, a);
|
|
+ }
|
|
Event.observe($('carriers_ups_origin_shipment'), 'change', this.changeOriginShipment.bind(this));
|
|
+ hideRowArrayElements(this.onlyUpsXmlElements);
|
|
+ hideRowArrayElements(this.onlyUpsElements);
|
|
+ showRowArrayElements(this.onlyUpsRestElements);
|
|
+ this.changeOriginShipment(null, null);
|
|
+ } else {
|
|
+ for (a = 0; a < this.checkingUpsId.length; a++) {
|
|
+ $(this.checkingUpsId[a]).removeClassName('required-entry');
|
|
+ }
|
|
+ for (a = 0; a < this.checkingUpsRestId.length; a++) {
|
|
+ $(this.checkingUpsRestId[a]).removeClassName('required-entry');
|
|
+ }
|
|
+ for (a = 0; a < this.checkingUpsXmlId.length; a++) {
|
|
+ $(this.checkingUpsXmlId[a]).addClassName('required-entry');
|
|
+ this.changeFieldsDisabledState(this.checkingUpsXmlId, a);
|
|
+ }
|
|
+ Event.observe($('carriers_ups_origin_shipment'), 'change', this.changeOriginShipment.bind(this));
|
|
+ hideRowArrayElements(this.onlyUpsElements);
|
|
+ hideRowArrayElements(this.onlyUpsRestElements);
|
|
showRowArrayElements(this.onlyUpsXmlElements);
|
|
if (\$F(this.carriersUpsActiveId) !== '1'){
|
|
hideRowArrayElements(this.authUpsXmlElements);
|
|
}
|
|
- hideRowArrayElements(this.onlyUpsElements);
|
|
this.changeOriginShipment(null, null);
|
|
}
|
|
},
|
|
|