AddSalesQuoteItemOnNotDefaultStockTest.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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\SalesQuoteItem;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Catalog\Api\ProductRepositoryInterface;
  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\Validation\ValidationException;
  15. use Magento\InventoryApi\Api\Data\StockInterface;
  16. use Magento\InventoryApi\Api\StockRepositoryInterface;
  17. use Magento\InventoryReservationsApi\Model\CleanupReservationsInterface;
  18. use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;
  19. use Magento\Quote\Api\Data\CartItemInterface;
  20. use Magento\Quote\Model\Quote;
  21. use Magento\Store\Api\Data\StoreInterface;
  22. use Magento\Store\Api\StoreRepositoryInterface;
  23. use Magento\Store\Model\StoreManagerInterface;
  24. use Magento\TestFramework\Helper\Bootstrap;
  25. use PHPUnit\Framework\TestCase;
  26. /**
  27. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  28. */
  29. class AddSalesQuoteItemOnNotDefaultStockTest extends TestCase
  30. {
  31. /**
  32. * @var ProductRepositoryInterface
  33. */
  34. private $productRepository;
  35. /**
  36. * @var StockRepositoryInterface
  37. */
  38. private $stockRepository;
  39. /**
  40. * @var StoreRepositoryInterface
  41. */
  42. private $storeRepository;
  43. /**
  44. * @var CleanupReservationsInterface
  45. */
  46. private $cleanupReservations;
  47. /**
  48. * @var StoreManagerInterface
  49. */
  50. private $storeManager;
  51. /**
  52. * @inheritdoc
  53. */
  54. protected function setUp()
  55. {
  56. parent::setUp();
  57. $this->cleanupReservations = Bootstrap::getObjectManager()->get(CleanupReservationsInterface::class);
  58. $this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
  59. $this->stockRepository = Bootstrap::getObjectManager()->get(StockRepositoryInterface::class);
  60. $this->storeRepository = Bootstrap::getObjectManager()->get(StoreRepositoryInterface::class);
  61. $this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
  62. $this->cleanupReservations->execute();
  63. }
  64. /**
  65. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  66. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php
  67. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php
  68. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_links.php
  69. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
  70. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/websites_with_stores.php
  71. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/stock_website_sales_channels.php
  72. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  73. *
  74. * @param string $sku
  75. * @param int $stockId
  76. * @param float $qty
  77. *
  78. * @throws LocalizedException
  79. * @throws NoSuchEntityException
  80. * @throws CouldNotSaveException
  81. * @throws InputException
  82. * @throws ValidationException
  83. *
  84. * @dataProvider productsInStockDataProvider
  85. *
  86. * @magentoDbIsolation disabled
  87. */
  88. public function testAddInStockProductToQuote(
  89. string $sku,
  90. int $stockId,
  91. float $qty
  92. ) {
  93. $quote = $this->getQuote($stockId);
  94. $product = $this->getProductBySku($sku);
  95. $quote->addProduct($product, $qty);
  96. /** @var CartItemInterface $quoteItem */
  97. $quoteItem = current($quote->getAllItems());
  98. self::assertEquals($qty, $quoteItem->getQty());
  99. }
  100. /**
  101. * @see ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
  102. * @return array
  103. */
  104. public function productsInStockDataProvider(): array
  105. {
  106. return [
  107. ['SKU-1', 10, 4],
  108. ['SKU-1', 10, 2],
  109. ['SKU-2', 30, 3],
  110. ['SKU-2', 30, 1]
  111. ];
  112. }
  113. /**
  114. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/products.php
  115. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php
  116. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php
  117. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_links.php
  118. * @magentoDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
  119. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/websites_with_stores.php
  120. * @magentoDataFixture ../../../../app/code/Magento/InventorySalesApi/Test/_files/stock_website_sales_channels.php
  121. * @magentoDataFixture ../../../../app/code/Magento/InventoryIndexer/Test/_files/reindex_inventory.php
  122. *
  123. * @param string $sku
  124. * @param int $stockId
  125. * @param float $qty
  126. *
  127. * @throws LocalizedException
  128. * @throws NoSuchEntityException
  129. * @throws CouldNotSaveException
  130. * @throws InputException
  131. * @throws ValidationException
  132. *
  133. * @dataProvider notSalableProductsDataProvider
  134. *
  135. * @magentoDbIsolation disabled
  136. */
  137. public function testAddOutOffStockProductToQuote(
  138. string $sku,
  139. int $stockId,
  140. float $qty
  141. ) {
  142. $quote = $this->getQuote($stockId);
  143. $product = $this->getProductBySku($sku);
  144. self::expectException(LocalizedException::class);
  145. $quote->addProduct($product, $qty);
  146. $quoteItemCount = count($quote->getAllItems());
  147. self::assertEquals(0, $quoteItemCount);
  148. }
  149. /**
  150. * @see ../../../../app/code/Magento/InventoryApi/Test/_files/source_items.php
  151. * @return array
  152. */
  153. public function notSalableProductsDataProvider(): array
  154. {
  155. return [
  156. ['SKU-1', 20, 6],
  157. ['SKU-1', 30, 9],
  158. ['SKU-2', 10, 1.5],
  159. ['SKU-2', 30, 5.5],
  160. ['SKU-3', 20, 1.9]
  161. ];
  162. }
  163. /**
  164. * @param string $sku
  165. * @return ProductInterface
  166. * @throws NoSuchEntityException
  167. */
  168. private function getProductBySku(string $sku): ProductInterface
  169. {
  170. return $this->productRepository->get($sku);
  171. }
  172. /**
  173. * @param int $stockId
  174. * @return Quote
  175. * @throws NoSuchEntityException
  176. */
  177. private function getQuote(int $stockId): Quote
  178. {
  179. /** @var StockInterface $stock */
  180. $stock = $this->stockRepository->get($stockId);
  181. /** @var SalesChannelInterface[] $salesChannels */
  182. $salesChannels = $stock->getExtensionAttributes()->getSalesChannels();
  183. $storeCode = 'store_for_';
  184. foreach ($salesChannels as $salesChannel) {
  185. if ($salesChannel->getType() == SalesChannelInterface::TYPE_WEBSITE) {
  186. $storeCode .= $salesChannel->getCode();
  187. break;
  188. }
  189. }
  190. /** @var StoreInterface $store */
  191. $store = $this->storeRepository->get($storeCode);
  192. $this->storeManager->setCurrentStore($storeCode);
  193. return Bootstrap::getObjectManager()->create(
  194. Quote::class,
  195. [
  196. 'data' => [
  197. 'store_id' => $store->getId(),
  198. 'is_active' => 0,
  199. 'is_multi_shipping' => 0,
  200. 'id' => 1
  201. ]
  202. ]
  203. );
  204. }
  205. protected function tearDown()
  206. {
  207. $this->cleanupReservations->execute();
  208. }
  209. }