QualificationResponseMapper.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 Magento\Framework\Exception\LocalizedException;
  7. use Psr\Log\LoggerInterface;
  8. use Temando\Shipping\Api\Data\Delivery\QuoteCollectionPointInterface;
  9. use Temando\Shipping\Api\Data\Delivery\QuotePickupLocationInterface;
  10. use Temando\Shipping\Api\Data\Order\ShippingExperienceInterface;
  11. use Temando\Shipping\Rest\Response\DataObject\CollectionPoint;
  12. use Temando\Shipping\Rest\Response\DataObject\OrderQualification;
  13. use Temando\Shipping\Webservice\Response\Type\QualificationResponseType;
  14. use Temando\Shipping\Webservice\Response\Type\QualificationResponseTypeFactory;
  15. /**
  16. * Map API data to application data object
  17. *
  18. * @package Temando\Shipping\Rest
  19. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  20. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  21. * @link https://www.temando.com/
  22. */
  23. class QualificationResponseMapper
  24. {
  25. /**
  26. * @var QualificationResponseTypeFactory
  27. */
  28. private $qualificationResponseFactory;
  29. /**
  30. * @var ShippingExperienceMapper
  31. */
  32. private $shippingExperienceMapper;
  33. /**
  34. * @var DeliveryLocationResponseMapper
  35. */
  36. private $deliveryLocationMapper;
  37. /**
  38. * @var LoggerInterface
  39. */
  40. private $logger;
  41. /**
  42. * QualificationResponseMapper constructor.
  43. * @param QualificationResponseTypeFactory $qualificationResponseFactory
  44. * @param ShippingExperienceMapper $shippingExperienceMapper
  45. * @param DeliveryLocationResponseMapper $deliveryLocationMapper
  46. * @param LoggerInterface $logger
  47. */
  48. public function __construct(
  49. QualificationResponseTypeFactory $qualificationResponseFactory,
  50. ShippingExperienceMapper $shippingExperienceMapper,
  51. DeliveryLocationResponseMapper $deliveryLocationMapper,
  52. LoggerInterface $logger
  53. ) {
  54. $this->qualificationResponseFactory = $qualificationResponseFactory;
  55. $this->shippingExperienceMapper = $shippingExperienceMapper;
  56. $this->deliveryLocationMapper = $deliveryLocationMapper;
  57. $this->logger = $logger;
  58. }
  59. /**
  60. * @param OrderQualification[] $apiQualifications
  61. * @return ShippingExperienceInterface[]
  62. */
  63. private function mapAddressQualifications(array $apiQualifications)
  64. {
  65. $shippingExperiences = [];
  66. $apiQualifications = array_filter($apiQualifications, function (OrderQualification $apiQualification) {
  67. return ($apiQualification->getType() === 'shippingMethod');
  68. });
  69. foreach ($apiQualifications as $apiQualification) {
  70. try {
  71. $shippingExperiences[]= $this->shippingExperienceMapper->map($apiQualification);
  72. } catch (LocalizedException $exception) {
  73. continue;
  74. }
  75. }
  76. return $shippingExperiences;
  77. }
  78. /**
  79. * @param OrderQualification[] $apiQualifications
  80. * @return QuoteCollectionPointInterface[]
  81. */
  82. private function mapCollectionPointQualifications(array $apiQualifications)
  83. {
  84. $collectionPoints = [];
  85. $apiQualifications = array_reduce($apiQualifications, function (array $carry, OrderQualification $apiQualification) {
  86. if ($apiQualification->getType() === 'collectionPointMethod') {
  87. // extract collection point qualifications
  88. $apiCollectionPoint = current($apiQualification->getCollectionPoints());
  89. if (!$apiCollectionPoint instanceof CollectionPoint) {
  90. return $carry;
  91. }
  92. if (!isset($carry[$apiCollectionPoint->getId()])) {
  93. $carry[$apiCollectionPoint->getId()]['location'] = $apiCollectionPoint;
  94. $carry[$apiCollectionPoint->getId()]['qualifications'] = [];
  95. }
  96. // group qualifications by collection point
  97. $carry[$apiCollectionPoint->getId()]['qualifications'][] = $apiQualification;
  98. }
  99. return $carry;
  100. }, []);
  101. foreach ($apiQualifications as $collectionPointId => $data) {
  102. $apiCollectionPoint = $data['location'];
  103. $apiCollectionPointQualifications = $data['qualifications'];
  104. $collectionPoint = $this->deliveryLocationMapper->mapCollectionPoint(
  105. $apiCollectionPoint,
  106. $apiCollectionPointQualifications
  107. );
  108. if (!empty($collectionPoint->getShippingExperiences())) {
  109. // only add collection point qualification if valid shipping experiences were found
  110. $collectionPoints[]= $collectionPoint;
  111. }
  112. }
  113. return $collectionPoints;
  114. }
  115. /**
  116. * @param OrderQualification[] $apiQualifications
  117. * @return QuotePickupLocationInterface[]
  118. */
  119. private function mapPickupLocationQualifications(array $apiQualifications)
  120. {
  121. $pickupLocations = [];
  122. $apiQualifications = array_reduce($apiQualifications, function (array $carry, OrderQualification $apiQualification) {
  123. if ($apiQualification->getType() === 'clickAndCollectMethod') {
  124. // extract pickup location qualifications
  125. $apiLocation = current($apiQualification->getLocations());
  126. if (!$apiLocation) {
  127. return $carry;
  128. }
  129. if (!isset($carry[$apiLocation->getId()])) {
  130. $carry[$apiLocation->getId()]['location'] = $apiLocation;
  131. $carry[$apiLocation->getId()]['qualifications'] = [];
  132. }
  133. // group qualifications by pickup location
  134. $carry[$apiLocation->getId()]['qualifications'][] = $apiQualification;
  135. }
  136. return $carry;
  137. }, []);
  138. foreach ($apiQualifications as $locationId => $data) {
  139. $apiLocation = $data['location'];
  140. $apiLocationQualifications = $data['qualifications'];
  141. $pickupLocation = $this->deliveryLocationMapper->mapPickupLocation(
  142. $apiLocation,
  143. $apiLocationQualifications
  144. );
  145. if (!empty($pickupLocation->getShippingExperiences())) {
  146. // only add pickup location qualification if valid shipping experiences were found
  147. $pickupLocations[]= $pickupLocation;
  148. }
  149. }
  150. return $pickupLocations;
  151. }
  152. /**
  153. * Create qualification object from platform data.
  154. *
  155. * Aggregate experiences by collection point/pickup location.
  156. *
  157. * @param OrderQualification[] $apiQualifications
  158. * @return QualificationResponseType
  159. */
  160. public function map(array $apiQualifications)
  161. {
  162. if (empty($apiQualifications)) {
  163. $qualificationResponse = $this->qualificationResponseFactory->create();
  164. return $qualificationResponse;
  165. }
  166. $shippingExperiences = $this->mapAddressQualifications($apiQualifications);
  167. $collectionPoints = $this->mapCollectionPointQualifications($apiQualifications);
  168. $pickupLocations = $this->mapPickupLocationQualifications($apiQualifications);
  169. if (empty($shippingExperiences) && empty($collectionPoints) && empty($pickupLocations)) {
  170. $this->logger->error(__('No applicable shipping cost found in webservice response.'));
  171. }
  172. $qualificationResponse = $this->qualificationResponseFactory->create([
  173. 'shippingExperiences' => $shippingExperiences,
  174. 'collectionPoints' => $collectionPoints,
  175. 'pickupLocations' => $pickupLocations,
  176. ]);
  177. return $qualificationResponse;
  178. }
  179. }