* @author Benjamin Heuer * @author Sebastian Ertner * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * @link https://www.temando.com/ */ class BatchResponseMapper { /** * @var BatchInterfaceFactory * */ private $batchFactory; /** * @var ShipmentSummaryInterfaceFactory */ private $shipmentFactory; /** * @var ShipmentErrorInterfaceFactory */ private $errorFactory; /** * @var OrderAddressInterfaceFactory */ private $addressFactory; /** * @var Renderer */ private $addressRenderer; /** * DispatchResponseMapper constructor. * * @param BatchInterfaceFactory $batchFactory * @param ShipmentSummaryInterfaceFactory $shipmentFactory * @param ShipmentErrorInterfaceFactory $errorFactory * @param OrderAddressInterfaceFactory $addressFactory * @param Renderer $addressRenderer */ public function __construct( BatchInterfaceFactory $batchFactory, ShipmentSummaryInterfaceFactory $shipmentFactory, ShipmentErrorInterfaceFactory $errorFactory, OrderAddressInterfaceFactory $addressFactory, Renderer $addressRenderer ) { $this->batchFactory = $batchFactory; $this->shipmentFactory = $shipmentFactory; $this->errorFactory = $errorFactory; $this->addressFactory = $addressFactory; $this->addressRenderer = $addressRenderer; } /** * @param LocationAttributes $location * * @return string */ private function getFormattedDestinationAddress(LocationAttributes $location) { $addressData = [ 'region' => $location->getAddress()->getAdministrativeArea(), 'postcode' => $location->getAddress()->getPostalCode(), 'street' => implode(' ', $location->getAddress()->getLines()), 'city' => $location->getAddress()->getLocality(), 'country_id' => $location->getAddress()->getCountryCode(), 'company' => $location->getContact()->getOrganisationName() ]; /** @var \Magento\Sales\Api\Data\OrderAddressInterface|\Magento\Sales\Model\Order\Address $address */ $address = $this->addressFactory->create(['data' => $addressData]); $formattedAddress = $this->addressRenderer->format($address, 'html'); return (string)$formattedAddress; } /** * @param ShipmentReference $apiShipmentReference * @param Shipment $apiShipment * * @return ShipmentSummaryInterface */ private function mapShipment(ShipmentReference $apiShipmentReference, Shipment $apiShipment) { $errors = []; foreach ($apiShipmentReference->getErrors() as $apiError) { $errors[]= $this->errorFactory->create(['data' => [ ShipmentErrorInterface::TITLE => $apiError->getTitle(), ShipmentErrorInterface::DETAIL => $apiError->getDetail(), ]]); } $destination = $apiShipment->getAttributes()->getDestination(); // fixme(nr): this is wrong! mappers do not prepare for display. pass on full location instead $address = $this->getFormattedDestinationAddress($destination); $recipientName = [ $destination->getContact()->getPersonFirstName(), $destination->getContact()->getPersonLastName(), ]; // fixme(nr): fatal error, shipment.order is not a required field $shipment = $this->shipmentFactory->create(['data' => [ ShipmentSummaryInterface::ORDER_ID => $apiShipment->getAttributes()->getOrder()->getReference(), ShipmentSummaryInterface::SHIPMENT_ID => $apiShipment->getId(), ShipmentSummaryInterface::STATUS => $apiShipment->getAttributes()->getStatus(), ShipmentSummaryInterface::ERRORS => $errors, ShipmentSummaryInterface::RECIPIENT_ADDRESS => $address, ShipmentSummaryInterface::RECIPIENT_NAME => implode(' ', $recipientName), ]]); return $shipment; } /** * @param Batch $apiBatch * * @return BatchInterface */ public function map(Batch $apiBatch) { $batchId = $apiBatch->getId(); $status = $apiBatch->getAttributes()->getStatus(); $createdAtDate = $apiBatch->getAttributes()->getCreatedAt(); $updatedAtDate = $apiBatch->getAttributes()->getModifiedAt(); $failedShipments = []; $includedShipments = []; $documentation = $apiBatch->getAttributes()->getDocumentation(); $shipments = []; foreach ($apiBatch->getShipments() as $shipment) { $shipments[$shipment->getId()] = $shipment; } // split shipments into failed and successfully created foreach ($apiBatch->getAttributes()->getShipments() as $shipmentReference) { $mappedShipment = $this->mapShipment($shipmentReference, $shipments[$shipmentReference->getId()]); if ($shipmentReference->getStatus() === 'error') { $failedShipments[$shipmentReference->getId()] = $mappedShipment; } else { $includedShipments[$shipmentReference->getId()] = $mappedShipment; } } $batch = $this->batchFactory->create(['data' => [ BatchInterface::BATCH_ID => $batchId, BatchInterface::STATUS => $status, BatchInterface::CREATED_AT_DATE => $createdAtDate, BatchInterface::UPDATED_AT_DATE => $updatedAtDate, BatchInterface::INCLUDED_SHIPMENTS => $includedShipments, BatchInterface::FAILED_SHIPMENTS => $failedShipments, BatchInterface::DOCUMENTATION => $documentation, ]]); return $batch; } }