PickupLocationManagement.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Model\Checkout\Delivery;
  6. use Magento\Framework\Api\FilterBuilder;
  7. use Magento\Framework\Api\SearchCriteriaBuilder;
  8. use Magento\Framework\Api\SortOrderBuilder;
  9. use Magento\Framework\Exception\CouldNotDeleteException;
  10. use Magento\Framework\Exception\CouldNotSaveException;
  11. use Magento\Framework\Exception\LocalizedException;
  12. use Temando\Shipping\Api\Data\Delivery\PickupLocationSearchRequestInterface;
  13. use Temando\Shipping\Api\Data\Delivery\PickupLocationSearchRequestInterfaceFactory;
  14. use Temando\Shipping\Api\Data\Delivery\PickupLocationSearchResultInterface;
  15. use Temando\Shipping\Api\Data\Delivery\QuotePickupLocationInterface;
  16. use Temando\Shipping\Model\Delivery\QuotePickupLocation;
  17. use Temando\Shipping\Model\ResourceModel\Repository\PickupLocationSearchRepositoryInterface;
  18. use Temando\Shipping\Model\ResourceModel\Repository\QuotePickupLocationRepositoryInterface;
  19. /**
  20. * Manage Pickup Location Access
  21. *
  22. * @package Temando\Shipping\Model
  23. * @author Sebastian Ertner <sebastian.ertner@netresearch.de>
  24. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. * @link https://www.temando.com/
  26. */
  27. class PickupLocationManagement
  28. {
  29. /**
  30. * @var PickupLocationSearchRepositoryInterface
  31. */
  32. private $searchRequestRepository;
  33. /**
  34. * @var PickupLocationSearchRequestInterfaceFactory
  35. */
  36. private $searchRequestFactory;
  37. /**
  38. * @var QuotePickupLocationRepositoryInterface
  39. */
  40. private $pickupLocationRepository;
  41. /**
  42. * @var SearchCriteriaBuilder
  43. */
  44. private $searchCriteriaBuilder;
  45. /**
  46. * @var FilterBuilder
  47. */
  48. private $filterBuilder;
  49. /**
  50. * @var SortOrderBuilder
  51. */
  52. private $sortOrderBuilder;
  53. /**
  54. * PickupLocationManagement constructor.
  55. *
  56. * @param PickupLocationSearchRepositoryInterface $searchRequestRepository
  57. * @param PickupLocationSearchRequestInterfaceFactory $searchRequestFactory
  58. * @param QuotePickupLocationRepositoryInterface $pickupLocationRepository
  59. * @param SearchCriteriaBuilder $searchCriteriaBuilderFactory
  60. * @param FilterBuilder $filterBuilder
  61. * @param SortOrderBuilder $sortOrderBuilder
  62. */
  63. public function __construct(
  64. PickupLocationSearchRepositoryInterface $searchRequestRepository,
  65. PickupLocationSearchRequestInterfaceFactory $searchRequestFactory,
  66. QuotePickupLocationRepositoryInterface $pickupLocationRepository,
  67. SearchCriteriaBuilder $searchCriteriaBuilderFactory,
  68. FilterBuilder $filterBuilder,
  69. SortOrderBuilder $sortOrderBuilder
  70. ) {
  71. $this->searchRequestRepository = $searchRequestRepository;
  72. $this->searchRequestFactory = $searchRequestFactory;
  73. $this->pickupLocationRepository = $pickupLocationRepository;
  74. $this->searchCriteriaBuilder = $searchCriteriaBuilderFactory;
  75. $this->filterBuilder = $filterBuilder;
  76. $this->sortOrderBuilder = $sortOrderBuilder;
  77. }
  78. /**
  79. * Save new search parameters, delete previous search results.
  80. *
  81. * @param int $addressId
  82. * @param bool $active
  83. * @return PickupLocationSearchRequestInterface
  84. * @throws CouldNotSaveException
  85. */
  86. public function saveSearchRequest(int $addressId, bool $active): PickupLocationSearchRequestInterface
  87. {
  88. $searchRequest = $this->searchRequestFactory->create(['data' => [
  89. PickupLocationSearchRequestInterface::SHIPPING_ADDRESS_ID => $addressId,
  90. PickupLocationSearchRequestInterface::ACTIVE => $active,
  91. ]]);
  92. try {
  93. $this->searchRequestRepository->save($searchRequest);
  94. $this->deletePickupLocations($addressId);
  95. } catch (LocalizedException $exception) {
  96. throw new CouldNotSaveException(__('Unable to save search parameters.'), $exception);
  97. }
  98. return $searchRequest;
  99. }
  100. /**
  101. * Delete search parameters, delete previous search results.
  102. *
  103. * @param int $addressId
  104. * @return bool
  105. * @throws CouldNotDeleteException
  106. */
  107. public function deleteSearchRequest(int $addressId): bool
  108. {
  109. try {
  110. $this->searchRequestRepository->delete($addressId);
  111. $this->deletePickupLocations($addressId);
  112. } catch (LocalizedException $exception) {
  113. throw new CouldNotDeleteException(__('Unable to delete search parameters.'), $exception);
  114. }
  115. return true;
  116. }
  117. /**
  118. * Load all collection location results for a given shipping address id.
  119. *
  120. * Sort by pseudo field `sort_distance` that gets added to handle null values.
  121. *
  122. * @see QuotePickupLocationRepository::getList
  123. * @param int $addressId
  124. * @return QuotePickupLocationInterface[]
  125. */
  126. public function getPickupLocations(int $addressId): array
  127. {
  128. $filter = $this->filterBuilder
  129. ->setField(QuotePickupLocationInterface::RECIPIENT_ADDRESS_ID)
  130. ->setValue($addressId)
  131. ->setConditionType('eq')
  132. ->create();
  133. $distanceSortOrder = $this->sortOrderBuilder
  134. ->setField('sort_distance')
  135. ->setAscendingDirection()
  136. ->create();
  137. $nameSortOrder = $this->sortOrderBuilder
  138. ->setField(QuotePickupLocationInterface::NAME)
  139. ->setAscendingDirection()
  140. ->create();
  141. $this->searchCriteriaBuilder->addFilters([$filter]);
  142. $this->searchCriteriaBuilder->setSortOrders([$distanceSortOrder, $nameSortOrder]);
  143. $criteria = $this->searchCriteriaBuilder->create();
  144. $searchResult = $this->pickupLocationRepository->getList($criteria);
  145. return $searchResult->getItems();
  146. }
  147. /**
  148. * Delete all collect location search results for a given shipping address id.
  149. *
  150. * @param int $addressId
  151. * @return PickupLocationSearchResultInterface
  152. * @throws CouldNotDeleteException
  153. */
  154. public function deletePickupLocations(int $addressId): PickupLocationSearchResultInterface
  155. {
  156. $filter = $this->filterBuilder
  157. ->setField(QuotePickupLocationInterface::RECIPIENT_ADDRESS_ID)
  158. ->setValue($addressId)
  159. ->setConditionType('eq')
  160. ->create();
  161. $this->searchCriteriaBuilder->addFilters([$filter]);
  162. $criteria = $this->searchCriteriaBuilder->create();
  163. try {
  164. $searchResult = $this->pickupLocationRepository->getList($criteria);
  165. $pickupLocations = $searchResult->getItems();
  166. array_walk($pickupLocations, function (QuotePickupLocationInterface $pickupLocation) {
  167. $this->pickupLocationRepository->delete($pickupLocation);
  168. });
  169. } catch (LocalizedException $exception) {
  170. throw new CouldNotDeleteException(__('Unable to delete collect locations.'), $exception);
  171. }
  172. return $searchResult;
  173. }
  174. /**
  175. * Mark a pickup location search result as selected for a given shipping address id.
  176. *
  177. * @param int $addressId
  178. * @param string $pickupLocationId
  179. * @return bool
  180. * @throws CouldNotSaveException
  181. */
  182. public function selectPickupLocation(int $addressId, string $pickupLocationId): bool
  183. {
  184. $pickupLocations = $this->getPickupLocations($addressId);
  185. try {
  186. $updateSelection = function (QuotePickupLocationInterface $pickupLocation) use ($pickupLocationId) {
  187. $isSelected = ($pickupLocationId == $pickupLocation->getPickupLocationId());
  188. /** @var QuotePickupLocation $pickupLocation */
  189. $pickupLocation->setData(QuotePickupLocationInterface::SELECTED, $isSelected);
  190. $this->pickupLocationRepository->save($pickupLocation);
  191. };
  192. array_walk($pickupLocations, $updateSelection);
  193. } catch (LocalizedException $exception) {
  194. throw new CouldNotSaveException(__('Unable to select pickup location.'), $exception);
  195. }
  196. return true;
  197. }
  198. }