ShipmentResponseMapper.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Rest\EntityMapper;
  6. use Temando\Shipping\Model\DocumentationInterface;
  7. use Temando\Shipping\Model\Shipment\CapabilityInterface;
  8. use Temando\Shipping\Model\Shipment\CapabilityInterfaceFactory;
  9. use Temando\Shipping\Model\Shipment\ExportDeclarationInterface;
  10. use Temando\Shipping\Model\Shipment\ExportDeclarationInterfaceFactory;
  11. use Temando\Shipping\Model\Shipment\FulfillmentInterface;
  12. use Temando\Shipping\Model\Shipment\FulfillmentInterfaceFactory;
  13. use Temando\Shipping\Model\Shipment\LocationInterface;
  14. use Temando\Shipping\Model\Shipment\LocationInterfaceFactory;
  15. use Temando\Shipping\Model\Shipment\PackageInterface;
  16. use Temando\Shipping\Model\Shipment\ShipmentItemInterface;
  17. use Temando\Shipping\Model\Shipment\ShipmentItemInterfaceFactory;
  18. use Temando\Shipping\Model\ShipmentInterface;
  19. use Temando\Shipping\Model\ShipmentInterfaceFactory;
  20. use Temando\Shipping\Rest\Response\DataObject\Shipment;
  21. use Temando\Shipping\Rest\Response\Fields\Generic\Documentation;
  22. use Temando\Shipping\Rest\Response\Fields\Generic\Item;
  23. use Temando\Shipping\Rest\Response\Fields\Generic\Package;
  24. use Temando\Shipping\Rest\Response\Fields\LocationAttributes;
  25. use Temando\Shipping\Rest\Response\Fields\Shipment\Fulfill;
  26. /**
  27. * Map API data to application data object
  28. *
  29. * @package Temando\Shipping\Rest
  30. * @author Sebastian Ertner <sebastian.ertner@netresearch.de>
  31. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  32. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  33. * @link http://www.temando.com/
  34. */
  35. class ShipmentResponseMapper
  36. {
  37. /**
  38. * @var ShipmentInterfaceFactory
  39. */
  40. private $shipmentFactory;
  41. /**
  42. * @var LocationInterfaceFactory
  43. */
  44. private $locationFactory;
  45. /**
  46. * @var FulfillmentInterfaceFactory
  47. */
  48. private $fulfillmentFactory;
  49. /**
  50. * @var ShipmentItemInterfaceFactory
  51. */
  52. private $shipmentItemFactory;
  53. /**
  54. * @var ExportDeclarationInterfaceFactory
  55. */
  56. private $exportDeclarationFactory;
  57. /**
  58. * @var PackageResponseMapper
  59. */
  60. private $packageMapper;
  61. /**
  62. * @var DocumentationResponseMapper
  63. */
  64. private $documentationMapper;
  65. /**
  66. * @var CapabilityInterfaceFactory
  67. */
  68. private $capabilityFactory;
  69. /**
  70. * ShipmentResponseMapper constructor.
  71. * @param ShipmentInterfaceFactory $shipmentFactory
  72. * @param LocationInterfaceFactory $locationFactory
  73. * @param FulfillmentInterfaceFactory $fulfillmentFactory
  74. * @param ShipmentItemInterfaceFactory $shipmentItemFactory
  75. * @param ExportDeclarationInterfaceFactory $exportDeclarationFactory
  76. * @param PackageResponseMapper $packageMapper
  77. * @param DocumentationResponseMapper $documentationMapper
  78. * @param CapabilityInterfaceFactory $capabilityFactory
  79. */
  80. public function __construct(
  81. ShipmentInterfaceFactory $shipmentFactory,
  82. LocationInterfaceFactory $locationFactory,
  83. FulfillmentInterfaceFactory $fulfillmentFactory,
  84. ShipmentItemInterfaceFactory $shipmentItemFactory,
  85. ExportDeclarationInterfaceFactory $exportDeclarationFactory,
  86. PackageResponseMapper $packageMapper,
  87. DocumentationResponseMapper $documentationMapper,
  88. CapabilityInterfaceFactory $capabilityFactory
  89. ) {
  90. $this->shipmentFactory = $shipmentFactory;
  91. $this->locationFactory = $locationFactory;
  92. $this->fulfillmentFactory = $fulfillmentFactory;
  93. $this->shipmentItemFactory = $shipmentItemFactory;
  94. $this->exportDeclarationFactory = $exportDeclarationFactory;
  95. $this->packageMapper = $packageMapper;
  96. $this->documentationMapper = $documentationMapper;
  97. $this->capabilityFactory = $capabilityFactory;
  98. }
  99. /**
  100. * @param Fulfill|null $apiFulfillment
  101. * @return FulfillmentInterface|null
  102. */
  103. private function mapFulfillment(?Fulfill $apiFulfillment): ?FulfillmentInterface
  104. {
  105. if (!$apiFulfillment) {
  106. return null;
  107. }
  108. $booking = $apiFulfillment->getCarrierBooking();
  109. $fulfillment = $this->fulfillmentFactory->create(['data' => [
  110. FulfillmentInterface::TRACKING_REFERENCE => $booking->getTrackingReference(),
  111. FulfillmentInterface::TRACKING_URL => $booking->getTrackingUrl(),
  112. FulfillmentInterface::SERVICE_NAME => $booking->getServiceName(),
  113. FulfillmentInterface::CARRIER_NAME => $booking->getCarrierName(),
  114. ]]);
  115. return $fulfillment;
  116. }
  117. /**
  118. * @param LocationAttributes|null $apiLocation
  119. * @return LocationInterface|null
  120. */
  121. private function mapLocation(?LocationAttributes $apiLocation): ?LocationInterface
  122. {
  123. if (!$apiLocation) {
  124. return null;
  125. }
  126. $contact = $apiLocation->getContact();
  127. $location = $this->locationFactory->create(['data' => [
  128. LocationInterface::NAME => '',
  129. LocationInterface::COMPANY => $contact ? $contact->getOrganisationName() : '',
  130. LocationInterface::PERSON_FIRST_NAME => $contact ? $contact->getPersonFirstName() : '',
  131. LocationInterface::PERSON_LAST_NAME => $contact ? $contact->getPersonLastName() : '',
  132. LocationInterface::EMAIL => $contact ? $contact->getEmail() : '',
  133. LocationInterface::PHONE_NUMBER => $contact ? $contact->getPhoneNumber() : '',
  134. LocationInterface::STREET => $apiLocation->getAddress()->getLines(),
  135. LocationInterface::CITY => $apiLocation->getAddress()->getLocality(),
  136. LocationInterface::POSTAL_CODE => $apiLocation->getAddress()->getPostalCode(),
  137. LocationInterface::REGION_CODE => $apiLocation->getAddress()->getAdministrativeArea(),
  138. LocationInterface::COUNTRY_CODE => $apiLocation->getAddress()->getCountryCode(),
  139. LocationInterface::TYPE => $apiLocation->getType(),
  140. ]]);
  141. return $location;
  142. }
  143. /**
  144. * @param Shipment $apiShipment
  145. * @return DocumentationInterface[]
  146. */
  147. private function mapDocumentation(Shipment $apiShipment): array
  148. {
  149. // collect documentation from shipment and packages
  150. $apiDocs = $apiShipment->getAttributes()->getDocumentation();
  151. foreach ($apiShipment->getAttributes()->getPackages() as $package) {
  152. foreach ($package->getDocumentation() as $apiDoc) {
  153. $apiDocs[]= $apiDoc;
  154. }
  155. }
  156. // map collected documentation
  157. $documentation = array_map(function (Documentation $apiDoc) {
  158. return $this->documentationMapper->map($apiDoc);
  159. }, $apiDocs);
  160. return $documentation;
  161. }
  162. /**
  163. * @param Shipment $apiShipment
  164. * @return ExportDeclarationInterface
  165. */
  166. private function mapExportDeclaration(Shipment $apiShipment): ?ExportDeclarationInterface
  167. {
  168. $apiDeclaration = $apiShipment->getAttributes()->getExportDeclaration();
  169. if (!$apiDeclaration) {
  170. return null;
  171. }
  172. /** @var \Temando\Shipping\Model\Shipment\ExportDeclaration $exportDeclaration */
  173. $exportDeclaration = $this->exportDeclarationFactory->create();
  174. $exportDeclaration->setData(
  175. ExportDeclarationInterface::IS_DUTIABLE,
  176. $apiShipment->getAttributes()->getIsDutiable()
  177. );
  178. $apiDeclaredValue = $apiDeclaration->getDeclaredValue();
  179. if ($apiDeclaredValue) {
  180. $exportDeclaration->setData(
  181. ExportDeclarationInterface::DECLARED_VALUE,
  182. "{$apiDeclaredValue->getAmount()} {$apiDeclaredValue->getCurrency()}"
  183. );
  184. }
  185. $exportDeclaration->setData(
  186. ExportDeclarationInterface::EXPORT_CATEGORY,
  187. $apiDeclaration->getExportCategory()
  188. );
  189. $exportDeclaration->setData(
  190. ExportDeclarationInterface::EXPORT_REASON,
  191. $apiDeclaration->getExportReason()
  192. );
  193. $exportDeclaration->setData(
  194. ExportDeclarationInterface::INCOTERM,
  195. $apiDeclaration->getIncoterm()
  196. );
  197. // dependent properties: signatory
  198. $apiSignatory = $apiDeclaration->getSignatory();
  199. if ($apiSignatory) {
  200. $exportDeclaration->setData(
  201. ExportDeclarationInterface::SIGNATORY_PERSON_TITLE,
  202. $apiSignatory->getPersonTitle()
  203. );
  204. $exportDeclaration->setData(
  205. ExportDeclarationInterface::SIGNATORY_PERSON_FIRST_NAME,
  206. $apiSignatory->getPersonFirstName()
  207. );
  208. $exportDeclaration->setData(
  209. ExportDeclarationInterface::SIGNATORY_PERSON_LAST_NAME,
  210. $apiSignatory->getPersonLastName()
  211. );
  212. }
  213. // dependent properties: export codes
  214. $apiExportCodes = $apiDeclaration->getExportCodes();
  215. if ($apiExportCodes) {
  216. $exportDeclaration->setData(
  217. ExportDeclarationInterface::EDN,
  218. $apiExportCodes->getExportDeclarationNumber()
  219. );
  220. $exportDeclaration->setData(
  221. ExportDeclarationInterface::EEI,
  222. $apiExportCodes->getElectronicExportInformation()
  223. );
  224. $exportDeclaration->setData(
  225. ExportDeclarationInterface::ITN,
  226. $apiExportCodes->getInternalTransactionNumber()
  227. );
  228. $exportDeclaration->setData(
  229. ExportDeclarationInterface::EEL,
  230. $apiExportCodes->getExemptionExclusionLegend()
  231. );
  232. }
  233. return $exportDeclaration;
  234. }
  235. /**
  236. * @param Item[] $apiItems
  237. * @return ShipmentItemInterface[]
  238. */
  239. private function mapItems(array $apiItems): array
  240. {
  241. $shipmentItems = array_map(function (Item $apiItem) {
  242. return $this->shipmentItemFactory->create(['data' => [
  243. ShipmentItemInterface::QTY => $apiItem->getQuantity(),
  244. ShipmentItemInterface::SKU => $apiItem->getProduct()->getSku(),
  245. ]]);
  246. }, $apiItems);
  247. return $shipmentItems;
  248. }
  249. /**
  250. * @param Package[] $apiPackages
  251. * @return PackageInterface[]
  252. */
  253. private function mapPackages(array $apiPackages): array
  254. {
  255. // map collected packages
  256. $packages = array_map(function (Package $apiPackage) {
  257. return $this->packageMapper->map($apiPackage);
  258. }, $apiPackages);
  259. return $packages;
  260. }
  261. /**
  262. * @param mixed[][] $apiCapabilities
  263. * @return CapabilityInterface[]
  264. */
  265. public function mapCapabilities(array $apiCapabilities): array
  266. {
  267. $capabilities = [];
  268. foreach ($apiCapabilities as $capabilityCode => $capabilityProperties) {
  269. if (!is_array($capabilityProperties)) {
  270. $capabilityProperties = [$capabilityProperties];
  271. }
  272. $capability = $this->capabilityFactory->create(['data' => [
  273. CapabilityInterface::CAPABILITY_ID => $capabilityCode,
  274. CapabilityInterface::PROPERTIES => $capabilityProperties
  275. ]]);
  276. $capabilities[]= $capability;
  277. }
  278. return $capabilities;
  279. }
  280. /**
  281. * @param Shipment $apiShipment
  282. * @return ShipmentInterface
  283. */
  284. public function map(Shipment $apiShipment)
  285. {
  286. $shipmentId = $apiShipment->getId();
  287. $shipmentOrderId = $apiShipment->getAttributes()->getOrderId();
  288. $shipmentOriginId = $apiShipment->getAttributes()->getOriginId();
  289. $shipmentOrder = $apiShipment->getAttributes()->getOrder();
  290. $isPaperless = $apiShipment->getAttributes()->getIsPaperless();
  291. $status = $apiShipment->getAttributes()->getStatus();
  292. $createdAt = $apiShipment->getAttributes()->getCreatedAt();
  293. $isCancelable = $apiShipment->getMeta() ? $apiShipment->getMeta()->getIsCancelable() : false;
  294. $documentation = $this->mapDocumentation($apiShipment);
  295. $exportDeclaration = $this->mapExportDeclaration($apiShipment);
  296. $origin = $this->mapLocation($apiShipment->getAttributes()->getOrigin());
  297. $destination = $this->mapLocation($apiShipment->getAttributes()->getDestination());
  298. $finalRecipient = $this->mapLocation($apiShipment->getAttributes()->getFinalRecipient());
  299. $shipmentFulfillment = $this->mapFulfillment($apiShipment->getAttributes()->getFulfill());
  300. $items = $this->mapItems($apiShipment->getAttributes()->getItems());
  301. $packages = $this->mapPackages($apiShipment->getAttributes()->getPackages());
  302. $capabilities = $this->mapCapabilities($apiShipment->getAttributes()->getCapabilities());
  303. $shipment = $this->shipmentFactory->create(['data' => [
  304. ShipmentInterface::SHIPMENT_ID => $shipmentId,
  305. ShipmentInterface::ORDER_ID => $shipmentOrderId,
  306. ShipmentInterface::ORIGIN_ID => $shipmentOriginId,
  307. ShipmentInterface::CUSTOMER_REFERENCE => $shipmentOrder ? $shipmentOrder->getCustomerReference() : '',
  308. ShipmentInterface::ORIGIN_LOCATION => $origin,
  309. ShipmentInterface::DESTINATION_LOCATION => $destination,
  310. ShipmentInterface::FINAL_RECIPIENT_LOCATION => $finalRecipient,
  311. ShipmentInterface::FULFILLMENT => $shipmentFulfillment,
  312. ShipmentInterface::ITEMS => $items,
  313. ShipmentInterface::PACKAGES => $packages,
  314. ShipmentInterface::DOCUMENTATION => $documentation,
  315. ShipmentInterface::IS_PAPERLESS => $isPaperless,
  316. ShipmentInterface::EXPORT_DECLARATION => $exportDeclaration,
  317. ShipmentInterface::STATUS => $status,
  318. ShipmentInterface::CAPABILITIES => $capabilities,
  319. ShipmentInterface::CREATED_AT => $createdAt,
  320. ShipmentInterface::IS_CANCELABLE => $isCancelable,
  321. ]]);
  322. return $shipment;
  323. }
  324. }