PlaceOrderOnDefaultStockTest.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\InventorySales\Test\Integration\Order;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Framework\Api\SearchCriteriaBuilder;
  10. use Magento\Framework\Exception\CouldNotSaveException;
  11. use Magento\Framework\Exception\InputException;
  12. use Magento\Framework\Exception\LocalizedException;
  13. use Magento\Framework\Exception\NoSuchEntityException;
  14. use Magento\Framework\Registry;
  15. use Magento\Framework\Validation\ValidationException;
  16. use Magento\Quote\Api\CartManagementInterface;
  17. use Magento\Quote\Api\CartRepositoryInterface;
  18. use Magento\Quote\Api\Data\CartInterface;
  19. use Magento\Quote\Api\Data\CartItemInterface;
  20. use Magento\Quote\Api\Data\CartItemInterfaceFactory;
  21. use Magento\Sales\Api\OrderManagementInterface;
  22. use Magento\Sales\Api\OrderRepositoryInterface;
  23. use PHPUnit\Framework\TestCase;
  24. use Magento\TestFramework\Helper\Bootstrap;
  25. use Magento\InventoryCatalogApi\Api\DefaultStockProviderInterface;
  26. use Magento\InventoryReservationsApi\Model\CleanupReservationsInterface;
  27. use Magento\Catalog\Api\ProductRepositoryInterface;
  28. /**
  29. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  30. */
  31. class PlaceOrderOnDefaultStockTest extends TestCase
  32. {
  33. /**
  34. * @var DefaultStockProviderInterface
  35. */
  36. private $defaultStockProvider;
  37. /**
  38. * @var CleanupReservationsInterface
  39. */
  40. private $cleanupReservations;
  41. /**
  42. * @var ProductRepositoryInterface
  43. */
  44. private $productRepository;
  45. /**
  46. * @var CartManagementInterface
  47. */
  48. private $cartManagement;
  49. /**
  50. * @var CartRepositoryInterface
  51. */
  52. private $cartRepository;
  53. /**
  54. * @var CartItemInterfaceFactory
  55. */
  56. private $cartItemFactory;
  57. /**
  58. * @var SearchCriteriaBuilder
  59. */
  60. private $searchCriteriaBuilder;
  61. /**
  62. * @var OrderRepositoryInterface
  63. */
  64. private $orderRepository;
  65. /**
  66. * @var Registry
  67. */
  68. private $registry;
  69. /**
  70. * @var OrderManagementInterface
  71. */
  72. private $orderManagement;
  73. protected function setUp()
  74. {
  75. $this->registry = Bootstrap::getObjectManager()->get(Registry::class);
  76. $this->cartManagement = Bootstrap::getObjectManager()->get(CartManagementInterface::class);
  77. $this->cartRepository = Bootstrap::getObjectManager()->get(CartRepositoryInterface::class);
  78. $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
  79. $this->searchCriteriaBuilder = Bootstrap::getObjectManager()->get(SearchCriteriaBuilder::class);
  80. $this->cartItemFactory = Bootstrap::getObjectManager()->get(CartItemInterfaceFactory::class);
  81. $this->defaultStockProvider = Bootstrap::getObjectManager()->get(DefaultStockProviderInterface::class);
  82. $this->cleanupReservations = Bootstrap::getObjectManager()->get(CleanupReservationsInterface::class);
  83. $this->orderRepository = Bootstrap::getObjectManager()->get(OrderRepositoryInterface::class);
  84. $this->orderManagement = Bootstrap::getObjectManager()->get(OrderManagementInterface::class);
  85. }
  86. /**
  87. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  88. * @magentoDataFixture ../../../../app/code/Magento/InventoryCatalog/Test/_files/source_items_on_default_source.php
  89. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/quote.php
  90. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  91. */
  92. public function testPlaceOrderWithInStockProduct()
  93. {
  94. $sku = 'SKU-1';
  95. $quoteItemQty = 4;
  96. $cart = $this->getCart();
  97. $product = $this->productRepository->get($sku);
  98. $cartItem = $this->getCartItem($product, $quoteItemQty, (int)$cart->getId());
  99. $cart->addItem($cartItem);
  100. $this->cartRepository->save($cart);
  101. $orderId = $this->cartManagement->placeOrder($cart->getId());
  102. self::assertNotNull($orderId);
  103. //cleanup
  104. $this->deleteOrderById((int)$orderId);
  105. }
  106. /**
  107. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  108. * @magentoDataFixture ../../../../app/code/Magento/InventoryCatalog/Test/_files/source_items_on_default_source.php
  109. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/quote.php
  110. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  111. */
  112. public function testPlaceOrderWithOutOffStockProduct()
  113. {
  114. $sku = 'SKU-1';
  115. $quoteItemQty = 8.5;
  116. $cart = $this->getCart();
  117. $product = $this->productRepository->get($sku);
  118. $cartItem = $this->getCartItem($product, $quoteItemQty, (int)$cart->getId());
  119. $cart->addItem($cartItem);
  120. $this->cartRepository->save($cart);
  121. self::expectException(LocalizedException::class);
  122. $orderId = $this->cartManagement->placeOrder($cart->getId());
  123. self::assertNull($orderId);
  124. }
  125. /**
  126. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  127. * @magentoDataFixture ../../../../app/code/Magento/InventoryCatalog/Test/_files/source_items_on_default_source.php
  128. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/quote.php
  129. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  130. * @magentoConfigFixture current_store cataloginventory/item_options/backorders 1
  131. */
  132. public function testPlaceOrderWithOutOffStockProductAndBackOrdersTurnedOn()
  133. {
  134. $sku = 'SKU-1';
  135. $quoteItemQty = 8.5;
  136. $cart = $this->getCart();
  137. $product = $this->productRepository->get($sku);
  138. $cartItem = $this->getCartItem($product, $quoteItemQty, (int)$cart->getId());
  139. $cart->addItem($cartItem);
  140. $this->cartRepository->save($cart);
  141. $orderId = $this->cartManagement->placeOrder($cart->getId());
  142. self::assertNotNull($orderId);
  143. //cleanup
  144. $this->deleteOrderById((int)$orderId);
  145. }
  146. /**
  147. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  148. * @magentoDataFixture ../../../../app/code/Magento/InventoryCatalog/Test/_files/source_items_on_default_source.php
  149. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/quote.php
  150. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  151. * @magentoConfigFixture current_store cataloginventory/item_options/manage_stock 0
  152. */
  153. public function testPlaceOrderWithOutOffStockProductAndManageStockTurnedOff()
  154. {
  155. $sku = 'SKU-1';
  156. $quoteItemQty = 8;
  157. $cart = $this->getCart();
  158. $product = $this->productRepository->get($sku);
  159. $cartItem = $this->getCartItem($product, $quoteItemQty, (int)$cart->getId());
  160. $cart->addItem($cartItem);
  161. $this->cartRepository->save($cart);
  162. $orderId = $this->cartManagement->placeOrder($cart->getId());
  163. self::assertNotNull($orderId);
  164. //cleanup
  165. $this->deleteOrderById((int)$orderId);
  166. }
  167. /**
  168. * @return CartInterface
  169. */
  170. private function getCart(): CartInterface
  171. {
  172. $searchCriteria = $this->searchCriteriaBuilder
  173. ->addFilter('reserved_order_id', 'test_order_1')
  174. ->create();
  175. /** @var CartInterface $cart */
  176. $cart = current($this->cartRepository->getList($searchCriteria)->getItems());
  177. $cart->setStoreId(1);
  178. return $cart;
  179. }
  180. /**
  181. * @param int $orderId
  182. */
  183. private function deleteOrderById(int $orderId)
  184. {
  185. $this->registry->unregister('isSecureArea');
  186. $this->registry->register('isSecureArea', true);
  187. $this->orderManagement->cancel($orderId);
  188. $this->orderRepository->delete($this->orderRepository->get($orderId));
  189. $this->registry->unregister('isSecureArea');
  190. $this->registry->register('isSecureArea', false);
  191. }
  192. /**
  193. * @param ProductInterface $product
  194. * @param float $quoteItemQty
  195. * @param int $cartId
  196. * @return CartItemInterface
  197. */
  198. private function getCartItem(ProductInterface $product, float $quoteItemQty, int $cartId): CartItemInterface
  199. {
  200. /** @var CartItemInterface $cartItem */
  201. $cartItem =
  202. $this->cartItemFactory->create(
  203. [
  204. 'data' => [
  205. CartItemInterface::KEY_SKU => $product->getSku(),
  206. CartItemInterface::KEY_QTY => $quoteItemQty,
  207. CartItemInterface::KEY_QUOTE_ID => $cartId,
  208. 'product_id' => $product->getId(),
  209. 'product' => $product
  210. ]
  211. ]
  212. );
  213. return $cartItem;
  214. }
  215. protected function tearDown()
  216. {
  217. $this->cleanupReservations->execute();
  218. }
  219. }