RmaShipmentRepository.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Model\ResourceModel\Rma;
  6. use Magento\Framework\Api\FilterBuilder;
  7. use Magento\Framework\Api\Search\FilterGroupBuilder;
  8. use Magento\Framework\Api\SearchCriteriaBuilder;
  9. use Magento\Framework\Api\SearchCriteriaInterface;
  10. use Magento\Framework\Exception\CouldNotDeleteException;
  11. use Magento\Framework\Exception\CouldNotSaveException;
  12. use Magento\Framework\Exception\LocalizedException;
  13. use Magento\Rma\Api\Data\RmaInterface;
  14. use Magento\Sales\Api\ShipmentRepositoryInterface as SalesShipmentRepositoryInterface;
  15. use Temando\Shipping\Api\Data\Shipment\ShipmentReferenceInterface;
  16. use Temando\Shipping\Model\ResourceModel\Repository\RmaShipmentRepositoryInterface;
  17. use Temando\Shipping\Model\ResourceModel\Repository\ShipmentReferenceRepositoryInterface;
  18. use Temando\Shipping\Model\ResourceModel\Repository\ShipmentRepositoryInterface;
  19. use Temando\Shipping\Model\ResourceModel\Rma\RmaShipment as RmaShipmentResource;
  20. use Temando\Shipping\Model\ShipmentInterface;
  21. /**
  22. * Temando RMA Shipment Repository
  23. *
  24. * @package Temando\Shipping\Model
  25. * @author Sebastian Ertner <sebastian.ertner@netresearch.de>
  26. * @author Benjamin Heuer <benjamin.heuer@netresearch.de>
  27. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  28. * @link http://www.temando.com/
  29. */
  30. class RmaShipmentRepository implements RmaShipmentRepositoryInterface
  31. {
  32. /**
  33. * @var RmaShipmentResource
  34. */
  35. private $resource;
  36. /**
  37. * @var ShipmentReferenceRepositoryInterface
  38. */
  39. private $shipmentReferenceRepository;
  40. /**
  41. * @var ShipmentRepositoryInterface
  42. */
  43. private $shipmentRepository;
  44. /**
  45. * @var SalesShipmentRepositoryInterface
  46. */
  47. private $salesShipmentRepository;
  48. /**
  49. * @var RmaAccess
  50. */
  51. private $rmaAccess;
  52. /**
  53. * @var FilterBuilder
  54. */
  55. private $filterBuilder;
  56. /**
  57. * @var FilterGroupBuilder
  58. */
  59. private $filterGroupBuilder;
  60. /**
  61. * @var SearchCriteriaBuilder
  62. */
  63. private $searchCriteriaBuilder;
  64. /**
  65. * RmaShipmentRepository constructor.
  66. *
  67. * @param RmaShipmentResource $resource
  68. * @param ShipmentReferenceRepositoryInterface $shipmentReferenceRepository
  69. * @param ShipmentRepositoryInterface $shipmentRepository
  70. * @param SalesShipmentRepositoryInterface $salesShipmentRepository,
  71. * @param RmaAccess $rmaAccess
  72. * @param FilterBuilder $filterBuilder
  73. * @param FilterGroupBuilder $filterGroupBuilder
  74. * @param SearchCriteriaBuilder $searchCriteriaBuilder
  75. */
  76. public function __construct(
  77. RmaShipmentResource $resource,
  78. ShipmentReferenceRepositoryInterface $shipmentReferenceRepository,
  79. ShipmentRepositoryInterface $shipmentRepository,
  80. SalesShipmentRepositoryInterface $salesShipmentRepository,
  81. RmaAccess $rmaAccess,
  82. FilterBuilder $filterBuilder,
  83. FilterGroupBuilder $filterGroupBuilder,
  84. SearchCriteriaBuilder $searchCriteriaBuilder
  85. ) {
  86. $this->resource = $resource;
  87. $this->shipmentReferenceRepository = $shipmentReferenceRepository;
  88. $this->shipmentRepository = $shipmentRepository;
  89. $this->salesShipmentRepository = $salesShipmentRepository;
  90. $this->rmaAccess = $rmaAccess;
  91. $this->filterBuilder = $filterBuilder;
  92. $this->filterGroupBuilder = $filterGroupBuilder;
  93. $this->searchCriteriaBuilder = $searchCriteriaBuilder;
  94. }
  95. /**
  96. * @param SearchCriteriaInterface $criteria
  97. * @return string
  98. */
  99. private function extractRmaId(SearchCriteriaInterface $criteria)
  100. {
  101. $rmaId = '';
  102. foreach ($criteria->getFilterGroups() as $filterGroup) {
  103. foreach ($filterGroup->getFilters() as $filter) {
  104. if ($filter->getField() == 'id') {
  105. $rmaId = $filter->getValue();
  106. } elseif ($filter->getField() == RmaShipmentResource::RMA_ID) {
  107. $rmaId = $filter->getValue();
  108. }
  109. }
  110. }
  111. return $rmaId;
  112. }
  113. /**
  114. * Prepare filters for available return shipments:
  115. * - must be assigned to current RMA
  116. * - must have a platform reference id
  117. * - must not exist amongst added shipments
  118. *
  119. * @param RmaInterface $rma
  120. * @return \Magento\Framework\Api\Search\FilterGroup[]
  121. */
  122. private function getAvailableShipmentFilters(RmaInterface $rma)
  123. {
  124. $filterGroups = [];
  125. // (1) available return shipments must be assigned to any of the RMA order's shipments
  126. $searchCriteria = $this->searchCriteriaBuilder
  127. ->addFilter(\Magento\Sales\Api\Data\ShipmentInterface::ORDER_ID, $rma->getOrderId())
  128. ->create();
  129. $searchResult = $this->salesShipmentRepository->getList($searchCriteria);
  130. $salesShipmentIds = array_map(function (\Magento\Sales\Api\Data\ShipmentInterface $shipment) {
  131. return $shipment->getEntityId();
  132. }, $searchResult->getItems());
  133. $this->filterBuilder->setField(ShipmentReferenceInterface::SHIPMENT_ID);
  134. $this->filterBuilder->setValue($salesShipmentIds);
  135. $this->filterBuilder->setConditionType('in');
  136. $salesShipmentIdsFilter = $this->filterBuilder->create();
  137. $filterGroups[]= $this->filterGroupBuilder->addFilter($salesShipmentIdsFilter)->create();
  138. // (2) available return shipments must have a shipment id at the platform
  139. $this->filterBuilder->setField(ShipmentReferenceInterface::EXT_RETURN_SHIPMENT_ID);
  140. $this->filterBuilder->setConditionType('notnull');
  141. $hasReturnShipmentFilter = $this->filterBuilder->create();
  142. $filterGroups[]= $this->filterGroupBuilder->addFilter($hasReturnShipmentFilter)->create();
  143. // (3) available return shipments must not have been added yet
  144. $extReturnShipmentIds = $this->resource->getShipmentIds($rma->getEntityId());
  145. if (!empty($extReturnShipmentIds)) {
  146. $this->filterBuilder->setField(ShipmentReferenceInterface::EXT_RETURN_SHIPMENT_ID);
  147. $this->filterBuilder->setValue($extReturnShipmentIds);
  148. $this->filterBuilder->setConditionType('nin');
  149. $notAddedFilter = $this->filterBuilder->create();
  150. $filterGroups[]= $this->filterGroupBuilder->addFilter($notAddedFilter)->create();
  151. }
  152. return $filterGroups;
  153. }
  154. /**
  155. * @param SearchCriteriaInterface $criteria
  156. * @return ShipmentInterface[]
  157. */
  158. public function getAvailableShipments(SearchCriteriaInterface $criteria)
  159. {
  160. $rmaId = $this->extractRmaId($criteria);
  161. $rma = $this->rmaAccess->getById($rmaId);
  162. $filters = $this->getAvailableShipmentFilters($rma);
  163. $this->searchCriteriaBuilder->setFilterGroups($filters);
  164. $searchCriteria = $this->searchCriteriaBuilder->create();
  165. $shipmentReferenceCollection = $this->shipmentReferenceRepository->getList($searchCriteria);
  166. $shipmentIds = $shipmentReferenceCollection->getColumnValues('ext_return_shipment_id');
  167. $availableShipments = array_map(function ($shipmentId) {
  168. return $this->shipmentRepository->getById($shipmentId);
  169. }, $shipmentIds);
  170. return $availableShipments;
  171. }
  172. /**
  173. * @param SearchCriteriaInterface $criteria
  174. * @return ShipmentInterface[]
  175. */
  176. public function getAddedShipments(SearchCriteriaInterface $criteria)
  177. {
  178. $shipments = [];
  179. $rmaId = $this->extractRmaId($criteria);
  180. $shipmentIds = $this->resource->getShipmentIds($rmaId);
  181. foreach ($shipmentIds as $shipmentId) {
  182. try {
  183. $shipments[] = $this->shipmentRepository->getById($shipmentId);
  184. } catch (LocalizedException $exception) {
  185. continue;
  186. }
  187. }
  188. return $shipments;
  189. }
  190. /**
  191. * Save external shipment IDs to be associated with core RMA entity.
  192. *
  193. * @param int $rmaId
  194. * @param string[] $shipmentIds
  195. * @return int Number of saved shipments
  196. * @throws CouldNotSaveException
  197. */
  198. public function saveShipmentIds($rmaId, array $shipmentIds)
  199. {
  200. try {
  201. return $this->resource->saveShipmentIds($rmaId, $shipmentIds);
  202. } catch (\Exception $exception) {
  203. throw new CouldNotSaveException(__('Unable to assign shipments.'), $exception);
  204. }
  205. }
  206. /**
  207. * Revoke assignment of external shipment IDs with core RMA entity.
  208. *
  209. * @param int $rmaId
  210. * @param string[] $shipmentIds
  211. * @return int Number of saved shipments
  212. * @throws CouldNotDeleteException
  213. */
  214. public function deleteShipmentIds($rmaId, array $shipmentIds)
  215. {
  216. try {
  217. return $this->resource->deleteShipmentIds($rmaId, $shipmentIds);
  218. } catch (\Exception $exception) {
  219. throw new CouldNotDeleteException(__('Unable to remove shipment assignments.'), $exception);
  220. }
  221. }
  222. }