CollectionPointManagement.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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\CollectionPointSearchRequestInterface;
  13. use Temando\Shipping\Api\Data\Delivery\CollectionPointSearchRequestInterfaceFactory;
  14. use Temando\Shipping\Api\Data\Delivery\CollectionPointSearchResultInterface;
  15. use Temando\Shipping\Api\Data\Delivery\QuoteCollectionPointInterface;
  16. use Temando\Shipping\Model\Delivery\QuoteCollectionPoint;
  17. use Temando\Shipping\Model\ResourceModel\Repository\CollectionPointSearchRepositoryInterface;
  18. use Temando\Shipping\Model\ResourceModel\Repository\QuoteCollectionPointRepositoryInterface;
  19. /**
  20. * Manage Collection Point Access
  21. *
  22. * @package Temando\Shipping\Model
  23. * @author Benjamin Heuer <benjamin.heuer@netresearch.de>
  24. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  25. * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  26. * @link https://www.temando.com/
  27. */
  28. class CollectionPointManagement
  29. {
  30. /**
  31. * @var CollectionPointSearchRepositoryInterface
  32. */
  33. private $searchRequestRepository;
  34. /**
  35. * @var CollectionPointSearchRequestInterfaceFactory
  36. */
  37. private $searchRequestFactory;
  38. /**
  39. * @var QuoteCollectionPointRepositoryInterface
  40. */
  41. private $collectionPointRepository;
  42. /**
  43. * @var SearchCriteriaBuilder
  44. */
  45. private $searchCriteriaBuilder;
  46. /**
  47. * @var FilterBuilder
  48. */
  49. private $filterBuilder;
  50. /**
  51. * @var SortOrderBuilder
  52. */
  53. private $sortOrderBuilder;
  54. /**
  55. * CollectionPointManagement constructor.
  56. *
  57. * @param CollectionPointSearchRepositoryInterface $searchRequestRepository
  58. * @param CollectionPointSearchRequestInterfaceFactory $searchRequestFactory
  59. * @param QuoteCollectionPointRepositoryInterface $collectionPointRepository
  60. * @param SearchCriteriaBuilder $searchCriteriaBuilder
  61. * @param FilterBuilder $filterBuilder
  62. * @param SortOrderBuilder $sortOrderBuilder
  63. */
  64. public function __construct(
  65. CollectionPointSearchRepositoryInterface $searchRequestRepository,
  66. CollectionPointSearchRequestInterfaceFactory $searchRequestFactory,
  67. QuoteCollectionPointRepositoryInterface $collectionPointRepository,
  68. SearchCriteriaBuilder $searchCriteriaBuilder,
  69. FilterBuilder $filterBuilder,
  70. SortOrderBuilder $sortOrderBuilder
  71. ) {
  72. $this->searchRequestRepository = $searchRequestRepository;
  73. $this->searchRequestFactory = $searchRequestFactory;
  74. $this->collectionPointRepository = $collectionPointRepository;
  75. $this->searchCriteriaBuilder = $searchCriteriaBuilder;
  76. $this->filterBuilder = $filterBuilder;
  77. $this->sortOrderBuilder = $sortOrderBuilder;
  78. }
  79. /**
  80. * Save new search parameters, delete previous search results.
  81. *
  82. * @param int $addressId
  83. * @param string $countryId
  84. * @param string $postcode
  85. * @param bool $pending
  86. * @return CollectionPointSearchRequestInterface
  87. * @throws CouldNotSaveException
  88. */
  89. public function saveSearchRequest(
  90. int $addressId,
  91. string $countryId,
  92. string $postcode,
  93. bool $pending = false
  94. ): CollectionPointSearchRequestInterface {
  95. $data = [
  96. CollectionPointSearchRequestInterface::SHIPPING_ADDRESS_ID => $addressId,
  97. CollectionPointSearchRequestInterface::PENDING => $pending,
  98. ];
  99. if ($countryId && $postcode) {
  100. $data[CollectionPointSearchRequestInterface::COUNTRY_ID] = $countryId;
  101. $data[CollectionPointSearchRequestInterface::POSTCODE] = $postcode;
  102. }
  103. $searchRequest = $this->searchRequestFactory->create(['data' => $data]);
  104. try {
  105. $this->searchRequestRepository->save($searchRequest);
  106. $this->deleteCollectionPoints($addressId);
  107. } catch (LocalizedException $exception) {
  108. throw new CouldNotSaveException(__('Unable to save search parameters.'), $exception);
  109. }
  110. return $searchRequest;
  111. }
  112. /**
  113. * Delete search parameters, delete previous search results.
  114. *
  115. * @param int $addressId
  116. * @return bool
  117. * @throws CouldNotDeleteException
  118. */
  119. public function deleteSearchRequest(int $addressId): bool
  120. {
  121. try {
  122. $this->searchRequestRepository->delete($addressId);
  123. $this->deleteCollectionPoints($addressId);
  124. } catch (LocalizedException $exception) {
  125. throw new CouldNotDeleteException(__('Unable to delete search parameters.'), $exception);
  126. }
  127. return true;
  128. }
  129. /**
  130. * Load all collection point search results for a given shipping address id.
  131. *
  132. * Sort by pseudo field `sort_distance` that gets added to handle null values.
  133. *
  134. * @see QuoteCollectionPointRepository::getList
  135. * @param int $addressId
  136. * @return QuoteCollectionPointInterface[]
  137. */
  138. public function getCollectionPoints(int $addressId): array
  139. {
  140. $filter = $this->filterBuilder
  141. ->setField(QuoteCollectionPointInterface::RECIPIENT_ADDRESS_ID)
  142. ->setValue($addressId)
  143. ->setConditionType('eq')
  144. ->create();
  145. $distanceSortOrder = $this->sortOrderBuilder
  146. ->setField('sort_distance')
  147. ->setAscendingDirection()
  148. ->create();
  149. $nameSortOrder = $this->sortOrderBuilder
  150. ->setField(QuoteCollectionPointInterface::NAME)
  151. ->setAscendingDirection()
  152. ->create();
  153. $this->searchCriteriaBuilder->addFilters([$filter]);
  154. $this->searchCriteriaBuilder->setSortOrders([$distanceSortOrder, $nameSortOrder]);
  155. $criteria = $this->searchCriteriaBuilder->create();
  156. $searchResult = $this->collectionPointRepository->getList($criteria);
  157. return $searchResult->getItems();
  158. }
  159. /**
  160. * Delete all collection point search results for a given shipping address id.
  161. *
  162. * @param int $addressId
  163. * @return CollectionPointSearchResultInterface
  164. * @throws CouldNotDeleteException
  165. */
  166. public function deleteCollectionPoints(int $addressId): CollectionPointSearchResultInterface
  167. {
  168. $filter = $this->filterBuilder
  169. ->setField(QuoteCollectionPointInterface::RECIPIENT_ADDRESS_ID)
  170. ->setValue($addressId)
  171. ->setConditionType('eq')
  172. ->create();
  173. $this->searchCriteriaBuilder->addFilters([$filter]);
  174. $criteria = $this->searchCriteriaBuilder->create();
  175. try {
  176. $searchResult = $this->collectionPointRepository->getList($criteria);
  177. $collectionPoints = $searchResult->getItems();
  178. array_walk($collectionPoints, function (QuoteCollectionPointInterface $collectionPoint) {
  179. $this->collectionPointRepository->delete($collectionPoint);
  180. });
  181. } catch (LocalizedException $exception) {
  182. throw new CouldNotDeleteException(__('Unable to delete collection points.'), $exception);
  183. }
  184. return $searchResult;
  185. }
  186. /**
  187. * Mark a collection point search result as selected for a given shipping address id.
  188. *
  189. * @param int $addressId
  190. * @param string $collectionPointId
  191. * @return bool
  192. * @throws CouldNotSaveException
  193. */
  194. public function selectCollectionPoint(int $addressId, string $collectionPointId): bool
  195. {
  196. $collectionPoints = $this->getCollectionPoints($addressId);
  197. try {
  198. $updateSelection = function (QuoteCollectionPointInterface $collectionPoint) use ($collectionPointId) {
  199. $isSelected = ($collectionPointId == $collectionPoint->getCollectionPointId());
  200. /** @var QuoteCollectionPoint $collectionPoint */
  201. $collectionPoint->setData(QuoteCollectionPointInterface::SELECTED, $isSelected);
  202. $this->collectionPointRepository->save($collectionPoint);
  203. };
  204. array_walk($collectionPoints, $updateSelection);
  205. } catch (LocalizedException $exception) {
  206. throw new CouldNotSaveException(__('Unable to select collection point.'), $exception);
  207. }
  208. return true;
  209. }
  210. }