Skip to content

Commit

Permalink
#2 — Add Extension Attribute Delivery Date
Browse files Browse the repository at this point in the history
  • Loading branch information
andresams committed May 12, 2020
1 parent 0ef5932 commit c5e8309
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 1 deletion.
244 changes: 243 additions & 1 deletion fedex-extended/Model/Carrier.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/
namespace Prestafy\FedexExtended\Model;

use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Webapi\Soap\ClientFactory;
use Magento\Framework\Xml\Security;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

Expand All @@ -17,6 +20,87 @@
*/
class Carrier extends \Magento\Fedex\Model\Carrier implements \Magento\Shipping\Model\Carrier\CarrierInterface
{
/**
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
*/
protected $_timezone;

/**
* Carrier constructor.
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
* @param \Psr\Log\LoggerInterface $logger
* @param Security $xmlSecurity
* @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
* @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
* @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
* @param \Magento\Shipping\Model\Tracking\ResultFactory $trackFactory
* @param \Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory
* @param \Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory
* @param \Magento\Directory\Model\RegionFactory $regionFactory
* @param \Magento\Directory\Model\CountryFactory $countryFactory
* @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
* @param \Magento\Directory\Helper\Data $directoryData
* @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Module\Dir\Reader $configReader
* @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone
* @param array $data
* @param Json|null $serializer
* @param ClientFactory|null $soapClientFactory]
*/
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
\Psr\Log\LoggerInterface $logger,
Security $xmlSecurity,
\Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
\Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
\Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
\Magento\Shipping\Model\Tracking\ResultFactory $trackFactory,
\Magento\Shipping\Model\Tracking\Result\ErrorFactory $trackErrorFactory,
\Magento\Shipping\Model\Tracking\Result\StatusFactory $trackStatusFactory,
\Magento\Directory\Model\RegionFactory $regionFactory,
\Magento\Directory\Model\CountryFactory $countryFactory,
\Magento\Directory\Model\CurrencyFactory $currencyFactory,
\Magento\Directory\Helper\Data $directoryData,
\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Module\Dir\Reader $configReader,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone,
array $data = [],
Json $serializer = null,
ClientFactory $soapClientFactory = null
) {
parent::__construct(
$scopeConfig,
$rateErrorFactory,
$logger,
$xmlSecurity,
$xmlElFactory,
$rateFactory,
$rateMethodFactory,
$trackFactory,
$trackErrorFactory,
$trackStatusFactory,
$regionFactory,
$countryFactory,
$currencyFactory,
$directoryData,
$stockRegistry,
$storeManager,
$configReader,
$productCollectionFactory,
$data,
$serializer,
$soapClientFactory
);

$this->_timezone = $timezone;
}

/**
* Collect and get rates
*
Expand All @@ -31,7 +115,6 @@ public function collectRates(RateRequest $request)

$this->setRequest($request);
$this->_getQuotes();
$this->_updateFreeMethodQuote($request);

return $this->getResult();
}
Expand Down Expand Up @@ -76,4 +159,163 @@ protected function _updateFreeMethodQuote($request)
}
}
}

/**
* Forming request for rate estimation depending to the purpose
*
* @param string $purpose
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
protected function _formRateRequest($purpose)
{
$r = $this->_rawRequest;

$ratesRequest = [
'WebAuthenticationDetail' => [
'UserCredential' => ['Key' => $r->getKey(), 'Password' => $r->getPassword()],
],
'ClientDetail' => ['AccountNumber' => $r->getAccount(), 'MeterNumber' => $r->getMeterNumber()],
'Version' => $this->getVersionInfo(),
'RequestedShipment' => [
'DropoffType' => $r->getDropoffType(),
'ShipTimestamp' => $this->_timezone->date()->format('c'),
'PackagingType' => $r->getPackaging(),
'Shipper' => [
'Address' => ['PostalCode' => $r->getOrigPostal(), 'CountryCode' => $r->getOrigCountry()],
],
'Recipient' => [
'Address' => [
'PostalCode' => $r->getDestPostal(),
'CountryCode' => $r->getDestCountry(),
'StateOrProvinceCode' => $r->getDestRegionCode(),
'Residential' => (bool)$this->getConfigData('residence_delivery'),
],
],
'ShippingChargesPayment' => [
'PaymentType' => 'SENDER',
'Payor' => ['AccountNumber' => $r->getAccount(), 'CountryCode' => $r->getOrigCountry()],
],
'CustomsClearanceDetail' => [
'CustomsValue' => ['Amount' => $r->getValue(), 'Currency' => $this->getCurrencyCode()],
],
'RateRequestTypes' => 'LIST',
'PackageCount' => '1',
'PackageDetail' => 'INDIVIDUAL_PACKAGES',
'RequestedPackageLineItems' => [
'0' => [
'Weight' => [
'Value' => (double)$r->getWeight(),
'Units' => $this->getConfigData('unit_of_measure'),
],
'GroupPackageCount' => 1,
],
],
],
];

if ($r->getDestCity()) {
$ratesRequest['RequestedShipment']['Recipient']['Address']['City'] = $r->getDestCity();
}

if ($purpose != self::RATE_REQUEST_GENERAL && $purpose == self::RATE_REQUEST_SMARTPOST) {
$ratesRequest['RequestedShipment']['ServiceType'] = self::RATE_REQUEST_SMARTPOST;
$ratesRequest['RequestedShipment']['SmartPostDetail'] = [
'Indicia' => (double)$r->getWeight() >= 1 ? 'PARCEL_SELECT' : 'PRESORTED_STANDARD',
'HubId' => $this->getConfigData('smartpost_hubid'),
];
}

//Request Estimated Delivery Date
$ratesRequest['ReturnTransitAndCommit'] = true;

return $ratesRequest;
}

/**
* Prepare shipping rate result based on response
*
* @param mixed $response
* @return Result
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function _prepareRateResponse($response)
{
$costArr = [];
$priceArr = [];
$deliveryDateArr = [];
$errorTitle = 'For some reason we can\'t retrieve tracking info right now.';

if (is_object($response)) {
if ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') {
if (is_array($response->Notifications)) {
$notification = array_pop($response->Notifications);
$errorTitle = (string)$notification->Message;
} else {
$errorTitle = (string)$response->Notifications->Message;
}
} elseif (isset($response->RateReplyDetails)) {
$allowedMethods = explode(",", $this->getConfigData('allowed_methods'));

if (is_array($response->RateReplyDetails)) {
foreach ($response->RateReplyDetails as $rate) {
$serviceName = (string)$rate->ServiceType;
if (in_array($serviceName, $allowedMethods)) {
$amount = $this->_getRateAmountOriginBased($rate);
$costArr[$serviceName] = $amount;
$priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
if (!empty($rate->DeliveryTimestamp)) {
$deliveryDateArr[$serviceName] = $this->formatEstimatedDeliveryDate($rate->DeliveryTimestamp);
}
}
}
asort($priceArr);
} else {
$rate = $response->RateReplyDetails;
$serviceName = (string)$rate->ServiceType;
if (in_array($serviceName, $allowedMethods)) {
$amount = $this->_getRateAmountOriginBased($rate);
$costArr[$serviceName] = $amount;
$priceArr[$serviceName] = $this->getMethodPrice($amount, $serviceName);
}
}
}
}

$result = $this->_rateFactory->create();
if (empty($priceArr)) {
$error = $this->_rateErrorFactory->create();
$error->setCarrier($this->_code);
$error->setCarrierTitle($this->getConfigData('title'));
$error->setErrorMessage($errorTitle);
$error->setErrorMessage($this->getConfigData('specificerrmsg'));
$result->append($error);
} else {
foreach ($priceArr as $method => $price) {
$rate = $this->_rateMethodFactory->create();
$rate->setCarrier($this->_code);
$rate->setCarrierTitle($this->getConfigData('title'));
$rate->setMethod($method);
$rate->setMethodTitle($this->getCode('method', $method));
$rate->setCost($costArr[$method]);
$rate->setPrice($price);
$rate->setDeliveryDate($deliveryDateArr[$method]);
$result->append($rate);
}
}

return $result;
}

/**
* Format Delivery Timestamp
*
* @param $deliveryTimeStamp
* @return \Magento\Framework\Phrase
*/
public function formatEstimatedDeliveryDate($deliveryTimeStamp)
{
return __('Get it %1', date('l, F d', strtotime($deliveryTimeStamp)));
}
}
53 changes: 53 additions & 0 deletions fedex-extended/Plugin/Carrier/DeliveryDate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* @category Prestafy
* @package Prestafy_FedexExtended
* @author Andresa Martins <[email protected]>
* @copyright Copyright (c) 2020 Prestafy eCommerce Solutions (https://www.prestafy.com.br)
* @license https://prestafy.com.br/licenses/free-for-use PRESTAFY FREE FOR USE
*/
namespace Prestafy\FedexExtended\Plugin\Carrier;

use Magento\Quote\Api\Data\ShippingMethodExtensionFactory;

/**
* Class DeliveryDate
* @package Prestafy\FedexExtended\Plugin\Carrier
*/
class DeliveryDate
{
/**
* @var ShippingMethodExtensionFactory
*/
protected $extensionFactory;

/**
* DeliveryDate constructor.
* @param ShippingMethodExtensionFactory $extensionFactory
*/
public function __construct(
ShippingMethodExtensionFactory $extensionFactory
) {
$this->extensionFactory = $extensionFactory;
}

/**
* Add extension attribute delivery_date to Shipping method
*
* @param $subject
* @param \Magento\Quote\Api\Data\ShippingMethodInterface $result
* @param \Magento\Quote\Model\Quote\Address\Rate $rateModel
*
* @return \Magento\Quote\Api\Data\ShippingMethodInterface
*/
public function afterModelToDataObject($subject, $result, $rateModel)
{
$extensionAttribute = $result->getExtensionAttributes() ? $result->getExtensionAttributes() :
$this->extensionFactory->create();

$extensionAttribute->setDeliveryDate($rateModel->getDeliveryDate());
$result->setExtensionAttributes($extensionAttribute);

return $result;
}
}
32 changes: 32 additions & 0 deletions fedex-extended/Plugin/Quote/Address/Rate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* @category Prestafy
* @package Prestafy_FedexExtended
* @author Andresa Martins <[email protected]>
* @copyright Copyright (c) 2020 Prestafy eCommerce Solutions (https://www.prestafy.com.br)
* @license https://prestafy.com.br/licenses/free-for-use PRESTAFY FREE FOR USE
*/
namespace Prestafy\FedexExtended\Plugin\Quote\Address;
/**
* Class Rate
* @package Prestafy\FedexExtended\Plugin\Quote\Address
*/
class Rate
{
/**
* Add extension attribute delivery_date to Result model
*
* @param \Magento\Quote\Model\Quote\Address\AbstractResult $rate
* @return \Magento\Quote\Model\Quote\Address\Rate
*/
public function afterImportShippingRate($subject, $result, $rate)
{
if ($rate instanceof \Magento\Quote\Model\Quote\Address\RateResult\Method) {
$result->setDeliveryDate(
$rate->getDeliveryDate()
);
}

return $result;
}
}
6 changes: 6 additions & 0 deletions fedex-extended/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Fedex\Model\Carrier" type="Prestafy\FedexExtended\Model\Carrier"/>
<preference for="Magento\Quote\Model\Quote\Address\FreeShippingInterface" type="Prestafy\FedexExtended\Model\Quote\Address\FreeShipping" />
<type name="Magento\Quote\Model\Cart\ShippingMethodConverter">
<plugin name="add_shipping_rate_delivery_date" type="Prestafy\FedexExtended\Plugin\Carrier\DeliveryDate" disabled="false" sortOrder="1"/>
</type>
<type name="Magento\Quote\Model\Quote\Address\Rate">
<plugin name="add_shipping_method_delivery_date" type="Prestafy\FedexExtended\Plugin\Quote\Address\Rate" disabled="false" sortOrder="2"/>
</type>
</config>
18 changes: 18 additions & 0 deletions fedex-extended/etc/extension_attributes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!--
/**
* @category Prestafy
* @package Prestafy_FedexExtended
* @author Andresa Martins <[email protected]>
* @copyright Copyright (c) 2020 Prestafy eCommerce Solutions (https://www.prestafy.com.br)
* @license https://prestafy.com.br/licenses/free-for-use PRESTAFY FREE FOR USE
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Quote\Api\Data\ShippingMethodInterface">
<attribute code="delivery_date" type="string"/>
</extension_attributes>
<extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
<attribute code="delivery_date" type="string"/>
</extension_attributes>
</config>

0 comments on commit c5e8309

Please sign in to comment.