Skip to content

Instantly share code, notes, and snippets.

@denvit
Last active May 28, 2024 10:22
Show Gist options
  • Save denvit/c105c615fb19eb2772d83426cb698e1f to your computer and use it in GitHub Desktop.
Save denvit/c105c615fb19eb2772d83426cb698e1f to your computer and use it in GitHub Desktop.
It checks through the 3rd party API (ITscope) if distributor already sent ordered products to the customer.
<?php
namespace Vendor\Distributors\Jobs;
use DateTime;
use DateTimeZone;
use Vendor\Distributors\Helpers\DistributorData;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Sales\Api\ShipmentRepositoryInterface;
use Magento\Sales\Model\Order\Shipment\TrackFactory;
use Magento\Sales\Model\ResourceModel\Order\Shipment\CollectionFactory;
use Psr\Log\LoggerInterface;
use GuzzleHttp\Client;
/**
* Class CheckIfOrdersSent
*
* @package Vendor\Distributors\Jobs
*/
class CheckIfOrdersSent
{
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var \Vendor\Distributors\Helpers\DistributorData
*/
protected $distributorData;
/**
* @var \GuzzleHttp\Client
*/
protected $guzzleClient;
/**
* @var \Magento\Framework\Api\SearchCriteriaBuilder
*/
protected $searchCriteriaBuilder;
/**
* @var \Magento\Sales\Api\ShipmentRepositoryInterface
*/
protected $shipmentRepository;
/**
* @var \Magento\Sales\Model\ResourceModel\Order\Shipment\CollectionFactory
*/
protected $shipmentCollectionFactory;
/**
* @var \Magento\Sales\Model\Order\Shipment\TrackFactory
*/
protected $trackFactory;
/**
* CheckIfOrdersSent constructor.
*
* @param \Psr\Log\LoggerInterface $logger
* @param \Vendor\Distributors\Helpers\DistributorData $distributorData
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Sales\Api\ShipmentRepositoryInterface $shipmentRepository
* @param \Magento\Sales\Model\ResourceModel\Order\Shipment\CollectionFactory $shipmentCollectionFactory
* @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory
*/
public function __construct(
LoggerInterface $logger,
DistributorData $distributorData,
SearchCriteriaBuilder $searchCriteriaBuilder,
ShipmentRepositoryInterface $shipmentRepository,
CollectionFactory $shipmentCollectionFactory,
TrackFactory $trackFactory
) {
$this->logger = $logger;
$this->distributorData = $distributorData;
$this->guzzleClient = new Client([
'base_uri' => 'https://api.itscope.com/2.0/business/deals/',
'auth' => [
$this->distributorData->getITScopeApiUsername(),
$this->distributorData->getITScopeApiPassword(),
],
]);
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->shipmentRepository = $shipmentRepository;
$this->shipmentCollectionFactory = $shipmentCollectionFactory;
$this->trackFactory = $trackFactory;
}
/**
* Check if orders sent by suppliers.
*/
public function execute() : void
{
$shipments = $this->getItScopeShipments();
// use itscope_transaction_id and check status of order on IT Scope API
/** @var \Magento\Sales\Model\Order\Shipment $shipment */
foreach ($shipments as $shipment) {
// get ITScopeOrderId first
$orderId = $shipment->getItscopeOrderId();
// send get request on ITScope API
try {
$response = $this->guzzleClient->request('GET',
'search/' . urlencode('orderId=' . $orderId) . '/deal.xml?businessType=PURCHASE');
if ($response->getStatusCode() === 200 && $response->getReasonPhrase() === 'OK') {
$responseBody = (string) $response->getBody();
$data = $this->getDealDetails($responseBody);
// save shipment status if it was changed and add comment.
if ($data['status'] !== $shipment->getItscopeShipmentStatus()) {
$shipment->setItscopeShipmentStatus($data['status']);
$datetime = new DateTime($data['date']);
$europeTimezone = new DateTimeZone('Europe/Vienna');
$datetime->setTimezone($europeTimezone);
$comment = "({$data['status']}) {$data['message']}" . __(' - ') . $datetime->format('d.m.Y') . ' at ' . $datetime->format('H:i:s');
$shipment->addComment($comment);
}
//if we have ASN (tracking number), save it if it doesn't exist yet on shipment
$dispatchNotification = $this->getDispatchNotifications($responseBody);
if ($dispatchNotification !== null) {
/** @var \Magento\Sales\Model\Order\Shipment\Track $trackingNumber */
$trackingNumber = $this->trackFactory->create()->addData([
'carrier_code' => 'custom',
'title' => $dispatchNotification['current_place'],
'number' => $dispatchNotification['trackingNumber'],
]);
$shipment->addTrack($trackingNumber);
}
$shipment->save();
}
} catch (GuzzleException $e) {
$this->logger->error($e->getMessage());
} catch (Exception $e) {
$this->logger->error($e->getMessage());
}
}
}
/**
* Get all shipments that has itscope_order_id assigned.
*
* @return array
*/
private function getItScopeShipments() : array
{
/** @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection $shipmentsItems */
$shipmentsItems = $this->shipmentCollectionFactory->create()
->addAttributeToSelect('*')
->addFieldToFilter('itscope_order_id', ['notnull' => true]);
return $shipmentsItems->getItems();
}
/**
* @param string $responseBody
* @return array
*/
private function getDealDetails(string $responseBody) : array
{
$xml = simplexml_load_string($responseBody);
return [
'status' => (string) $xml->deal->status,
'message' => (string) $xml->deal->statusMessage,
'date' => (string) $xml->deal->statusDate,
];
}
/**
* @param string $responseBody
* @return string[]|null
*/
private function getDispatchNotifications(string $responseBody)
{
$xml = simplexml_load_string($responseBody);
if (!empty((string) $xml->deal->dispatchnotifications)) {
return [
'trackingNumber' => (string) $xml->deal->dispatchnotifications->dispatchnotification
->logistic_details_info->package_info->package->package_id,
'current_place' => (string) $xml->deal->dispatchnotifications->dispatchnotification->remarks,
];
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment