How can I add estimate delivery date for UPS shipping method. I searching over google but not luck and I try to following link for magento 1 UPS estimate delivery date but not work. I also check ups inTransit api but not convert in magento 2 any one know how can I achieve this.
3 Answers
step1:- Override carrier.php file in local module Vendor\module-ups\Model\Carrier.php
Find function setRequest() and add DestCity.
public function setRequest(RateRequest $request)
{
$rowRequest->setDestCity($request->getDestCity());
$this->_rawRequest = $rowRequest;
return $this;
}
step2:- Find function _getXmlQuotes().
protected function _getXmlQuotes()
{
$url = $this->getConfigData('gateway_xml_url');
$this->setXMLAccessRequest();
$xmlRequest = $this->_xmlAccessRequest;
$debugData['accessRequest'] = $this->filterDebugData($xmlRequest);
$rowRequest = $this->_rawRequest;
if (self::USA_COUNTRY_ID == $rowRequest->getDestCountry()) {
$destPostal = substr($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(),
];
// start change action name Shop to Shoptimeintransit
if ($params['10_action'] == '4') {
$params['10_action'] = 'Shoptimeintransit';
$serviceCode = null;
} else {
$params['10_action'] = 'Rate';
$serviceCode = $rowRequest->getProduct() ? $rowRequest->getProduct() : '';
}
// end
$serviceDescription = $serviceCode ? $this->getShipmentByCode($serviceCode) : '';
$xmlParams = <<<XMLRequest
<?xml version="1.0"?>
<RatingServiceSelectionRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Rating and Service</CustomerContext>
<XpciVersion>1.0</XpciVersion>
</TransactionReference>
<RequestAction>Rate</RequestAction>
<RequestOption>{$params['10_action']}</RequestOption>
</Request>
<PickupType>
<Code>{$params['47_rate_chart']['code']}</Code>
<Description>{$params['47_rate_chart']['label']}</Description>
</PickupType>
<Shipment>
XMLRequest;
if ($serviceCode !== null) {
$xmlParams .= "<Service>" .
"<Code>{$serviceCode}</Code>" .
"<Description>{$serviceDescription}</Description>" .
"</Service>";
}
$xmlParams .= <<<XMLRequest
<Shipper>
XMLRequest;
if ($this->getConfigFlag('negotiated_active') && ($shipper = $this->getConfigData('shipper_number'))) {
$xmlParams .= "<ShipperNumber>{$shipper}</ShipperNumber>";
}
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'];
}
$xmlParams .= <<<XMLRequest
<Address>
<City>{$shipperCity}</City>
<PostalCode>{$shipperPostalCode}</PostalCode>
<CountryCode>{$shipperCountryCode}</CountryCode>
<StateProvinceCode>{$shipperStateProvince}</StateProvinceCode>
</Address>
</Shipper>
<ShipTo>
XMLRequest;
/* ------- Start XML Mod to add city ---------*/
$xmlRequest .= <<< XMLRequest
<City>{$rowRequest->getDestCity()}</City>
XMLRequest;
/* ---------------- End of XML Mod --------------------*/
$xmlRequest .= <<< XMLRequest
/* ------- XML Mod For Time In Transit Params ---------*/
<PostalCode>{$params['19_destPostal']}</PostalCode>
<CountryCode>{$params['22_destCountry']}</CountryCode>
<ResidentialAddress>{$params['49_residential']}</ResidentialAddress>
<StateProvinceCode>{$params['destRegionCode']}</StateProvinceCode>
XMLRequest;
if ($params['49_residential'] === '01') {
$xmlParams .= "<ResidentialAddressIndicator>{$params['49_residential']}</ResidentialAddressIndicator>";
}
$xmlParams .= <<<XMLRequest
</Address>
</ShipTo>
<ShipFrom>
<Address>
<PostalCode>{$params['15_origPostal']}</PostalCode>
<CountryCode>{$params['14_origCountry']}</CountryCode>
<StateProvinceCode>{$params['origRegionCode']}</StateProvinceCode>
</Address>
</ShipFrom>
<Package>
<PackagingType><Code>{$params['48_container']}</Code></PackagingType>
<PackageWeight>
<UnitOfMeasurement><Code>{$rowRequest->getUnitMeasure()}</Code></UnitOfMeasurement>
<Weight>{$params['23_weight']}</Weight>
</PackageWeight>
</Package>
/* ------- XML Mod Start for deliverytime ---------*/
<DeliveryTimeInformation>
<PackageBillType>03</PackageBillType>
</DeliveryTimeInformation>
/* ---------------- End of XML Mod --------------------*/
XMLRequest;
if ($this->getConfigFlag('negotiated_active')) {
$xmlParams .= "<RateInformation><NegotiatedRatesIndicator/></RateInformation>";
}
/* ---------------- End of XML Mod --------------------*/
$xmlParams .= <<<XMLRequest
</Shipment>
</RatingServiceSelectionRequest>
XMLRequest;
$xmlRequest .= $xmlParams;
$xmlResponse = $this->_getCachedQuotes($xmlRequest);
if ($xmlResponse === null) {
$debugData['request'] = $xmlParams;
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlRequest);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (bool)$this->getConfigFlag('mode_xml'));
$xmlResponse = curl_exec($ch);
if ($xmlResponse !== false) {
$debugData['result'] = $xmlResponse;
$this->_setCachedQuotes($xmlRequest, $xmlResponse);
} else {
$debugData['result'] = ['error' => curl_error($ch)];
}
curl_close($ch);
} catch (\Exception $e) {
$debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
$xmlResponse = '';
}
$this->_debug($debugData);
}
return $this->_parseXmlResponse($xmlResponse);
}
step3:- Find Function _parseXmlResponse()
protected function _parseXmlResponse($xmlResponse)
{
$costArr = [];
$priceArr = [];
if (strlen(trim($xmlResponse)) > 0) {
$xml = new \Magento\Framework\Simplexml\Config();
$xml->loadString($xmlResponse);
$arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/ResponseStatusCode/text()");
$success = (int)$arr[0];
if ($success === 1) {
$arr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment");
$allowedMethods = explode(",", $this->getConfigData('allowed_methods'));
// Negotiated rates
$negotiatedArr = $xml->getXpath("//RatingServiceSelectionResponse/RatedShipment/NegotiatedRates");
$negotiatedActive = $this->getConfigFlag(
'negotiated_active'
) && $this->getConfigData(
'shipper_number'
) && !empty($negotiatedArr);
$allowedCurrencies = $this->_currencyFactory->create()->getConfigAllowCurrencies();
foreach ($arr as $shipElement) {
$code = (string)$shipElement->Service->Code;
if (in_array($code, $allowedMethods)) {
if ($negotiatedActive) {
$cost = $shipElement->NegotiatedRates->NetSummaryCharges->GrandTotal->MonetaryValue;
} else {
$cost = $shipElement->TotalCharges->MonetaryValue;
}
/* ------------ Time In Transit Mod ------------*/
$daysInTransit = $shipElement->TimeInTransit->ServiceSummary->EstimatedArrival->TotalTransitDays;
//print_r($daysInTransit);die;
$etaDate = $shipElement->TimeInTransit->ServiceSummary->EstimatedArrival->Arrival->Date;
$etaTime = $shipElement->TimeInTransit->ServiceSummary->EstimatedArrival->Arrival->Time;
$eta = new \DateTime();
$eta->setDate(substr($etaDate, 0, 4), substr($etaDate, 4, 2), substr($etaDate, 6, 2));
$eta->setTime(substr($etaTime, 0, 2), substr($etaTime, 4, 2), substr($etaTime, 4, 2));
/* ----------- End Time In Transit Mod ---------*/
//convert price with Origin country currency code to base currency code
$successConversion = true;
$responseCurrencyCode = $this->mapCurrencyCode(
(string)$shipElement->TotalCharges->CurrencyCode
);
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(floatval($cost), $code);
/* ------------ Time In Transit Mod ------------*/
$timeInTransitArr[$code] = $daysInTransit;
$etaArr[$code] = $eta;
/* ----------- End Time In Transit Mod ---------*/
}
}
}
} else {
$arr = $xml->getXpath("//RatingServiceSelectionResponse/Response/Error/ErrorDescription/text()");
$errorTitle = (string)$arr[0][0];
$error = $this->_rateErrorFactory->create();
$error->setCarrier('ups');
$error->setCarrierTitle($this->getConfigData('title'));
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
}
}
$result = $this->_rateFactory->create();
if (empty($priceArr)) {
$error = $this->_rateErrorFactory->create();
$error->setCarrier('ups');
$error->setCarrierTitle($this->getConfigData('title'));
if (!isset($errorTitle)) {
$errorTitle = __('Cannot retrieve shipping rates');
}
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
/* ------------ Time In Transit Mod ------------*/
$error->setErrorMessage($errorTitle);
/* ----------- End Time In Transit Mod ---------*/
$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);
/* ------------ Time In Transit Mod ------------*/
//$transitDays = intval($timeInTransitArr[$method]);
$rate->setMethodTitle($methodArr . ' (ETA: ' . $etaArr[$method]->format('d-m-Y H:i'). ')');
/* ----------- End Time In Transit Mod ---------*/
// $rate->setMethodTitle($methodArr);
$rate->setCost($costArr[$method]);
$rate->setPrice($price);
$result->append($rate);
}
}
return $result;
}
-
I get a blank page with:"Estimate Shipping and Tax" when I edit this page. Is there any additional step or maybe I didn't insert the dest city at the right place. Any imput would be appreciated– EmiliCommented May 10, 2019 at 16:45
-
Please replace
$daysInTransit = $shipElement->TimeInTransit->ServiceSummary->EstimatedArrival->TotalTransitDays;
with
$daysInTransit = (string)$shipElement->TimeInTransit->ServiceSummary->EstimatedArrival->BusinessDaysInTransit;
-
With above code, i was facing this error also and this code help me.– Soni5041Commented Jul 13, 2020 at 13:24
-
Then you need to print $shipElement and check the data. Commented Jul 14, 2020 at 12:11
I am using Magento 2.4. I modified Carier.php
file of UPS Module to fetch Estimate delivery Date and time from UPS API. I used above code but it was throwing error "Invalid weight" so I used additional parameter in <shipment>
tag
Below code is required because when you pass $params['10_action'] = 'Shoptimeintransit';
,so you need to add new element ShipmentTotalWeight
in shipment
container
<Shipment>
........
<ShipmentTotalWeight>
<UnitOfMeasurement>
<Code>{$rowRequest->getUnitMeasure()}</Code>
</UnitOfMeasurement>
<Weight>{$params['23_weight']}</Weight>
</ShipmentTotalWeight>
.......
</Shipment>