/** * @param bool $canReturnToStock * @param bool $manageStock * @param bool $result * @dataProvider canReturnItemsToStockDataProvider */ public function testCanReturnItemsToStock($canReturnToStock, $manageStock, $result) { $productId = 7; $property = new \ReflectionProperty($this->items, '_canReturnToStock'); $property->setAccessible(true); $this->assertNull($property->getValue($this->items)); $this->scopeConfig->expects($this->once())->method('getValue')->with($this->equalTo(\Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT), $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE))->will($this->returnValue($canReturnToStock)); if ($canReturnToStock) { $orderItem = $this->getMock('Magento\\Sales\\Model\\Order\\Item', ['getProductId', '__wakeup'], [], '', false); $orderItem->expects($this->once())->method('getProductId')->will($this->returnValue($productId)); $creditMemoItem = $this->getMock('Magento\\Sales\\Model\\Order\\Creditmemo\\Item', ['setCanReturnToStock', 'getOrderItem', '__wakeup'], [], '', false); $creditMemo = $this->getMock('Magento\\Sales\\Model\\Order\\Creditmemo', [], [], '', false); $creditMemo->expects($this->once())->method('getAllItems')->will($this->returnValue([$creditMemoItem])); $creditMemoItem->expects($this->once())->method('getOrderItem')->will($this->returnValue($orderItem)); $this->stockItemMock->expects($this->once())->method('getManageStock')->with($this->equalTo($productId))->will($this->returnValue($manageStock)); $creditMemoItem->expects($this->once())->method('setCanReturnToStock')->with($this->equalTo($manageStock))->will($this->returnSelf()); $order = $this->getMock('Magento\\Sales\\Model\\Order', ['setCanReturnToStock', '__wakeup'], [], '', false); $order->expects($this->once())->method('setCanReturnToStock')->with($this->equalTo($manageStock))->will($this->returnSelf()); $creditMemo->expects($this->once())->method('getOrder')->will($this->returnValue($order)); $this->registryMock->expects($this->any())->method('registry')->with('current_creditmemo')->will($this->returnValue($creditMemo)); } $this->assertSame($result, $this->items->canReturnItemsToStock()); $this->assertSame($result, $property->getValue($this->items)); // lazy load test $this->assertSame($result, $this->items->canReturnItemsToStock()); }
public function testSuggestItemsQty() { $data = [[], ['qty' => -2], ['qty' => 3], ['qty' => 3.5], ['qty' => 5], ['qty' => 4]]; $quote = $this->getMock('Magento\\Sales\\Model\\Quote', [], [], '', false); $quote->expects($this->any())->method('getItemById')->will($this->returnValueMap([[2, $this->prepareQuoteItemMock(2)], [3, $this->prepareQuoteItemMock(3)], [4, $this->prepareQuoteItemMock(4)], [5, $this->prepareQuoteItemMock(5)]])); $this->stockItemMock->expects($this->any())->method('suggestQty')->will($this->returnValueMap([[4, 3.0, 3.0], [5, 3.5, 3.5]])); $this->checkoutSessionMock->expects($this->once())->method('getQuote')->will($this->returnValue($quote)); $this->assertSame([[], ['qty' => -2], ['qty' => 3.0, 'before_suggest_qty' => 3.0], ['qty' => 3.5, 'before_suggest_qty' => 3.5], ['qty' => 5], ['qty' => 4]], $this->cart->suggestItemsQty($data)); }
/** * Copy product inventory data (used for product duplicate functionality) * * @param \Magento\Catalog\Model\Product $product * @param \Magento\Catalog\Model\Product $duplicate * @return void */ public function build(\Magento\Catalog\Model\Product $product, \Magento\Catalog\Model\Product $duplicate) { $stockData = ['use_config_min_qty' => 1, 'use_config_min_sale_qty' => 1, 'use_config_max_sale_qty' => 1, 'use_config_backorders' => 1, 'use_config_notify_stock_qty' => 1]; /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $currentStockItemDo */ $currentStockItemDo = $this->stockItemService->getStockItem($product->getId()); if ($currentStockItemDo->getStockId()) { $stockData += ['use_config_enable_qty_inc' => $currentStockItemDo->isUseConfigEnableQtyInc(), 'enable_qty_increments' => $currentStockItemDo->isEnableQtyIncrements(), 'use_config_qty_increments' => $currentStockItemDo->isUseConfigQtyIncrements(), 'qty_increments' => $currentStockItemDo->getQtyIncrements()]; } $duplicate->setStockData($stockData); }
/** * @param int $productId * @param int $qtyInc * @param bool $isSaleable * @param int|bool $result * @dataProvider getProductQtyIncrementsDataProvider */ public function testGetProductQtyIncrements($productId, $qtyInc, $isSaleable, $result) { $this->stockItemService->expects($this->once())->method('getQtyIncrements')->with($this->equalTo($productId))->will($this->returnValue($qtyInc)); $product = $this->getMock('Magento\\Catalog\\Model\\Product', [], [], '', false); $product->expects($this->once())->method('getId')->will($this->returnValue($productId)); $product->expects($this->once())->method('isSaleable')->will($this->returnValue($isSaleable)); $this->registryMock->expects($this->any())->method('registry')->with('current_product')->will($this->returnValue($product)); $this->assertSame($result, $this->block->getProductQtyIncrements()); // test lazy load $this->assertSame($result, $this->block->getProductQtyIncrements()); }
public function testBuildWithCurrentProductStockItem() { $expectedData = array('use_config_min_qty' => 1, 'use_config_min_sale_qty' => 1, 'use_config_max_sale_qty' => 1, 'use_config_backorders' => 1, 'use_config_notify_stock_qty' => 1, 'use_config_enable_qty_inc' => 'use_config_enable_qty_inc', 'enable_qty_increments' => 'enable_qty_increments', 'use_config_qty_increments' => 'use_config_qty_increments', 'qty_increments' => 'qty_increments'); $this->stockItemServiceMock->expects($this->once())->method('getStockItem')->will($this->returnValue($this->stockItemDoMock)); $this->stockItemDoMock->expects($this->any())->method('getStockId')->will($this->returnValue(50)); $this->stockItemDoMock->expects($this->any())->method('isUseConfigEnableQtyInc')->will($this->returnValue('use_config_enable_qty_inc')); $this->stockItemDoMock->expects($this->any())->method('isEnableQtyIncrements')->will($this->returnValue('enable_qty_increments')); $this->stockItemDoMock->expects($this->any())->method('isUseConfigQtyIncrements')->will($this->returnValue('use_config_qty_increments')); $this->stockItemDoMock->expects($this->any())->method('getQtyIncrements')->will($this->returnValue('qty_increments')); $this->duplicateMock->expects($this->once())->method('setStockData')->with($expectedData); $this->model->build($this->productMock, $this->duplicateMock); }
public function testInitWithNonDecimalQty() { $quoteItemMock = $this->getMock('\\Magento\\Sales\\Model\\Quote\\Item', ['getStockId', 'getIsQtyDecimal', '__wakeup'], [], '', false); $this->stockItemServiceMock->expects($this->once())->method('getStockItem')->will($this->returnValue($this->getStockItemDo(false))); $this->productMock->expects($this->once())->method('getId')->will($this->returnSelf()); $this->productMock->expects($this->never())->method('setIsQtyDecimal'); $this->productMock->expects($this->once())->method('setCartQty')->will($this->returnSelf()); $this->configMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(10)); $this->configMock->expects($this->once())->method('setQty')->will($this->returnSelf()); $this->quoteMock->expects($this->once())->method('addProduct')->will($this->returnValue($quoteItemMock)); $this->assertInstanceOf('Magento\\Sales\\Model\\Quote\\Item', $this->model->init($this->quoteMock, $this->productMock, $this->configMock)); }
/** * @param \Magento\Sales\Model\Quote $quote * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\Object $config * @return \Magento\Sales\Model\Quote\Item|string */ public function init(\Magento\Sales\Model\Quote $quote, \Magento\Catalog\Model\Product $product, \Magento\Framework\Object $config) { /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */ $stockItemDo = $this->stockItemService->getStockItem($product->getId()); if ($stockItemDo->getStockId() && $stockItemDo->getIsQtyDecimal()) { $product->setIsQtyDecimal(1); } else { $config->setQty((int) $config->getQty()); } $product->setCartQty($config->getQty()); $item = $quote->addProduct($product, $config, \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL); return $item; }
/** * Get items * * @return Item[] */ public function getItems() { $items = $this->getParentBlock()->getItems(); $oldSuperMode = $this->getQuote()->getIsSuperMode(); $this->getQuote()->setIsSuperMode(false); foreach ($items as $item) { // To dispatch inventory event sales_quote_item_qty_set_after, set item qty $item->setQty($item->getQty()); if (!$item->getMessage()) { //Getting product ids for stock item last quantity validation before grid display $stockItemToCheck = array(); $childItems = $item->getChildren(); if (count($childItems)) { foreach ($childItems as $childItem) { $stockItemToCheck[] = $childItem->getProduct()->getId(); } } else { $stockItemToCheck[] = $item->getProduct()->getId(); } foreach ($stockItemToCheck as $productId) { $check = $this->stockItemService->checkQuoteItemQty($productId, $item->getQty(), $item->getQty(), $item->getQty()); $item->setMessage($check->getMessage()); $item->setHasError($check->getHasError()); } } if ($item->getProduct()->getStatus() == ProductStatus::STATUS_DISABLED) { $item->setMessage(__('This product is disabled.')); $item->setHasError(true); } } $this->getQuote()->setIsSuperMode($oldSuperMode); return $items; }
/** * @param int $productStockQty * @param int|null $productId * @param int|null $dataQty * @param int $expectedQty * @dataProvider getStockQtyDataProvider */ public function testGetStockQty($productStockQty, $productId, $dataQty, $expectedQty) { $this->assertNull($this->block->getData('product_stock_qty')); if ($dataQty) { $this->setDataArrayValue('product_stock_qty', $dataQty); } else { $product = $this->getMock('Magento\\Catalog\\Model\\Product', ['getId', '__wakeup'], [], '', false); $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); $this->registryMock->expects($this->any())->method('registry')->with('current_product')->will($this->returnValue($product)); if ($productId) { $this->stockItemService->expects($this->once())->method('getStockQty')->with($this->equalTo($productId))->will($this->returnValue($productStockQty)); } } $this->assertSame($expectedQty, $this->block->getStockQty()); $this->assertSame($expectedQty, $this->block->getData('product_stock_qty')); }
/** * @covers \Magento\Sales\Block\Adminhtml\Order\Create\Items\Grid::getItems */ public function testGetItems() { $productId = 8; $itemQty = 23; $layoutMock = $this->getMock('Magento\\Framework\\View\\LayoutInterface'); $blockMock = $this->getMock('Magento\\Framework\\View\\Element\\AbstractBlock', ['getItems'], [], '', false); $itemMock = $this->getMock('Magento\\Sales\\Model\\Quote\\Item', array('getProduct', 'setHasError', 'setQty', 'getQty', '__sleep', '__wakeup'), array(), '', false); $productMock = $this->getMock('Magento\\Catalog\\Model\\Product', array('getStockItem', 'getID', '__sleep', '__wakeup'), array(), '', false); $checkMock = $this->getMock('Magento\\Framework\\Object', ['getMessage', 'getHasError'], [], '', false); $layoutMock->expects($this->once())->method('getParentName')->will($this->returnValue('parentBlock')); $layoutMock->expects($this->once())->method('getBlock')->with('parentBlock')->will($this->returnValue($blockMock)); $blockMock->expects($this->once())->method('getItems')->will($this->returnValue(array($itemMock))); $itemMock->expects($this->any())->method('getChildren')->will($this->returnValue(array($itemMock))); $itemMock->expects($this->any())->method('getProduct')->will($this->returnValue($productMock)); $itemMock->expects($this->any())->method('getQty')->will($this->returnValue($itemQty)); $productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); $productMock->expects($this->any())->method('getStatus')->will($this->returnValue(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)); $checkMock->expects($this->any())->method('getMessage')->will($this->returnValue('Message')); $checkMock->expects($this->any())->method('getHasError')->will($this->returnValue(false)); $this->stockItemService->expects($this->once())->method('checkQuoteItemQty')->with($this->equalTo($productId), $this->equalTo($itemQty), $this->equalTo($itemQty))->will($this->returnValue($checkMock)); $this->block->getQuote()->setIsSuperMode(true); $items = $this->block->setLayout($layoutMock)->getItems(); $this->assertEquals('Message', $items[0]->getMessage()); $this->assertEquals(true, $this->block->getQuote()->getIsSuperMode()); }
/** * Update item in shopping cart (quote) * $requestInfo - either qty (int) or buyRequest in form of array or \Magento\Framework\Object * $updatingParams - information on how to perform update, passed to Quote->updateItem() method * * @param int $itemId * @param int|array|\Magento\Framework\Object $requestInfo * @param null|array|\Magento\Framework\Object $updatingParams * @return \Magento\Sales\Model\Quote\Item|string * @throws \Magento\Framework\Model\Exception * * @see \Magento\Sales\Model\Quote::updateItem() */ public function updateItem($itemId, $requestInfo = null, $updatingParams = null) { try { $item = $this->getQuote()->getItemById($itemId); if (!$item) { throw new \Magento\Framework\Model\Exception(__('This quote item does not exist.')); } $productId = $item->getProduct()->getId(); $product = $this->_getProduct($productId); $request = $this->_getProductRequest($requestInfo); if ($productId) { $minimumQty = $this->stockItemService->getMinSaleQty($productId); // If product was not found in cart and there is set minimal qty for it if ($minimumQty && $minimumQty > 0 && $request->getQty() < $minimumQty && !$this->getQuote()->hasProductId($productId)) { $request->setQty($minimumQty); } } $result = $this->getQuote()->updateItem($itemId, $request, $updatingParams); } catch (\Magento\Framework\Model\Exception $e) { $this->_checkoutSession->setUseNotice(false); $result = $e->getMessage(); } /** * We can get string if updating process had some errors */ if (is_string($result)) { if ($this->_checkoutSession->getUseNotice() === null) { $this->_checkoutSession->setUseNotice(true); } throw new \Magento\Framework\Model\Exception($result); } $this->_eventManager->dispatch('checkout_cart_product_update_after', array('quote_item' => $result, 'product' => $product)); $this->_checkoutSession->setLastAddedProductId($productId); return $result; }
/** * Check item product availability for reorder * * @param \Magento\Sales\Model\Order\Item $orderItem * @return boolean */ public function isItemAvailableForReorder(\Magento\Sales\Model\Order\Item $orderItem) { if ($orderItem->getProduct()) { return $this->stockItemService->getIsInStock($orderItem->getProduct()->getId()); } return false; }
/** * @param string $productSku * @param int $productId * @param int $websiteId * @param array $productStockStatusArray * @param int $stockQty * @param array $array * @dataProvider getProductStockStatusBySkuDataProvider */ public function testGetProductStockStatusBySku($productSku, $productId, $websiteId, $productStockStatusArray, $stockQty, $array) { // 1. Create mocks /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ $product = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->getMock(); /** @var \Magento\Framework\App\ScopeInterface|\PHPUnit_Framework_MockObject_MockObject $scope */ $scope = $this->getMockBuilder('Magento\\Framework\\App\\ScopeInterface')->disableOriginalConstructor()->getMock(); /** * @var \Magento\CatalogInventory\Service\V1\Data\StockStatus|\PHPUnit_Framework_MockObject_MockObject $scope */ $stockStatusDataObject = $this->getMockBuilder('Magento\\CatalogInventory\\Service\\V1\\Data\\StockStatus')->disableOriginalConstructor()->getMock(); // 2. Set fixtures $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([[$productSku, $product]])); $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); $this->scopeResolver->expects($this->any())->method('getScope')->will($this->returnValue($scope)); $scope->expects($this->any())->method('getId')->will($this->returnValue($websiteId)); $this->stockStatusBuilder->expects($this->any())->method('create')->will($this->returnValue($stockStatusDataObject)); // 3. Set expectations $this->stockStatus->expects($this->any())->method('getProductStockStatus')->with([$productId], $websiteId)->will($this->returnValue($productStockStatusArray)); $this->stockItemService->expects($this->any())->method('getStockQty')->will($this->returnValueMap([[$productId, $stockQty]])); $this->stockStatusBuilder->expects($this->any())->method('populateWithArray')->with($array); // 4. Run tested method $result = $this->model->getProductStockStatusBySku($productSku); // 5. Compare actual result with expected result $this->assertEquals($stockStatusDataObject, $result); }
public function testSave() { $this->item->setData('key', 'value'); $this->eventManager->expects($this->at(0))->method('dispatch')->with('model_save_before', ['object' => $this->item]); $this->eventManager->expects($this->at(1))->method('dispatch')->with('cataloginventory_stock_item_save_before', ['data_object' => $this->item, 'item' => $this->item]); $this->resource->expects($this->once())->method('addCommitCallback')->will($this->returnValue($this->resource)); $this->stockItemService->expects($this->any())->method('isQty')->will($this->returnValue(true)); $this->assertEquals($this->item, $this->item->save()); }
/** * Retrieve product qty increments * * @return float|false */ public function getProductQtyIncrements() { if ($this->_qtyIncrements === null) { $this->_qtyIncrements = $this->stockItemService->getQtyIncrements($this->getProduct()->getId()); if (!$this->getProduct()->isSaleable()) { $this->_qtyIncrements = false; } } return $this->_qtyIncrements; }
public function testProcessIsInStock() { $stockData = ['product_id' => 333]; $stockItemModel = $this->getMockBuilder('Magento\\CatalogInventory\\Model\\Stock\\Item')->setMethods(['getData', 'setData', 'processIsInStock', '__wakeup'])->disableOriginalConstructor()->getMock(); $this->stockItemRegistry->expects($this->once())->method('retrieve')->with($this->equalTo($stockData['product_id']))->will($this->returnValue($stockItemModel)); $stockItemModel->expects($this->once())->method('setData')->with($this->equalTo($stockData)); $stockItemModel->expects($this->once())->method('processIsInStock'); $stockItemModel->expects($this->once())->method('getData')->will($this->returnValue($stockData)); $this->assertEquals($stockData, $this->model->processIsInStock($stockData)); }
/** * Load some inventory configuration settings * * @return void */ protected function _initConfig() { if (!$this->_isConfig) { $configMap = array('_isConfigManageStock' => \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MANAGE_STOCK, '_isConfigBackorders' => \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_BACKORDERS, '_configMinQty' => \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MIN_QTY, '_configNotifyStockQty' => \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_NOTIFY_STOCK_QTY); foreach ($configMap as $field => $const) { $this->{$field} = (int) $this->_scopeConfig->getValue($const, \Magento\Store\Model\ScopeInterface::SCOPE_STORE); } $this->_isConfig = true; $this->_stock = $this->_stockFactory->create(); $this->_configTypeIds = array_keys($this->stockItemService->getIsQtyTypeIds(true)); } }
/** * {inheritdoc} */ public function getProductStockStatusBySku($sku) { $product = $this->productLoader->load($sku); $productId = $product->getId(); if (!$productId) { throw new NoSuchEntityException("Product with SKU \"{$sku}\" does not exist"); } $data = $this->stockStatus->getProductStockStatus([$productId], $this->scopeResolver->getScope()->getId()); $stockStatus = (bool) $data[$productId]; $result = [Data\StockStatus::STOCK_STATUS => $stockStatus, Data\StockStatus::STOCK_QTY => $this->stockItemService->getStockQty($productId)]; $this->stockStatusBuilder->populateWithArray($result); return $this->stockStatusBuilder->create(); }
/** * Get back to stock (when order is canceled or whatever else) * * @param int $productId * @param int|float $qty * @return $this */ public function backItemQty($productId, $qty) { /** @var Item $stockItem */ $stockItem = $this->_stockItemFactory->create()->loadByProduct($productId); if ($stockItem->getId() && $this->stockItemService->isQty($this->getProductType($productId))) { $stockItem->addQty($qty); if ($stockItem->getCanBackInStock() && $stockItem->getQty() > $stockItem->getMinQty()) { $stockItem->setIsInStock(true)->setStockStatusChangedAutomaticallyFlag(true); } $stockItem->save(); } return $this; }
/** * @param string $productSku * @param int $productId * @dataProvider saveStockItemBySkuWithExceptionDataProvider * @expectedException \Magento\Framework\Exception\NoSuchEntityException */ public function testSaveStockItemBySkuWithException($productSku, $productId) { // 1. Get mocks /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ $product = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->getMock(); /** @var Data\StockItemDetails|\PHPUnit_Framework_MockObject_MockObject $stockItemDetailsDo */ $stockItemDetailsDo = $this->getMockBuilder('Magento\\CatalogInventory\\Service\\V1\\Data\\StockItemDetails')->disableOriginalConstructor()->getMock(); // 2. Set fixtures $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([[$productSku, $product]])); $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); // 3. Run tested method $this->model->saveStockItemBySku($productSku, $stockItemDetailsDo); }
public function testExecuteThatProductIdsAreObtainedFromAttributeHelper() { $this->attributeHelper->expects($this->any())->method('getProductIds')->will($this->returnValue([5])); $this->attributeHelper->expects($this->any())->method('getSelectedStoreId')->will($this->returnValue([1])); $this->inventoryHelper->expects($this->any())->method('getConfigItemOptions')->will($this->returnValue([])); $this->product->expects($this->any())->method('isProductsHasSku')->with([5])->will($this->returnValue(true)); $this->stockItemService->expects($this->any())->method('getStockItem')->with(5)->will($this->returnValue($this->stockItem)); $this->stockIndexerProcessor->expects($this->any())->method('reindexList')->with([5]); $this->request->expects($this->any())->method('getParam')->will($this->returnValueMap([['inventory', [], [7]]])); $this->messageManager->expects($this->never())->method('addError'); $this->messageManager->expects($this->never())->method('addException'); $this->object->execute(); }
/** * @param int|bool $productId * @param bool $result * @dataProvider isItemAvailableForReorderDataProvider */ public function testIsItemAvailableForReorder($productId, $result) { if ($productId) { $product = $this->getMock('Magento\\Catalog\\Model\\Product', ['getId', '__wakeup'], [], '', false); $product->expects($this->once())->method('getId')->will($this->returnValue($productId)); $this->stockItemService->expects($this->once())->method('getIsInStock')->with($this->equalTo($productId))->will($this->returnValue($result)); } else { $product = false; } $orderItem = $this->getMock('Magento\\Sales\\Model\\Order\\Item', [], [], '', false); $orderItem->expects($this->any())->method('getProduct')->will($this->returnValue($product)); $this->createBlockObject(); $this->assertSame($result, $this->block->isItemAvailableForReorder($orderItem)); }
/** * Whether to show 'Return to stock' checkbox for item * * @param Item $item * @return bool */ public function canReturnItemToStock($item = null) { if (null !== $item) { if (!$item->hasCanReturnToStock()) { $productId = $item->getOrderItem()->getProductId(); if ($productId && $this->stockItemService->getManageStock($productId)) { $item->setCanReturnToStock(true); } else { $item->setCanReturnToStock(false); } } $canReturnToStock = $item->getCanReturnToStock(); } else { $canReturnToStock = $this->_scopeConfig->getValue(\Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT, \Magento\Store\Model\ScopeInterface::SCOPE_STORE); } return $canReturnToStock; }
/** * Prepare items to pieces * * @return array */ protected function _getAllItems() { $allItems = $this->_request->getAllItems(); $fullItems = array(); foreach ($allItems as $item) { if ($item->getProductType() == Type::TYPE_BUNDLE && $item->getProduct()->getShipmentType()) { continue; } $qty = $item->getQty(); $changeQty = true; $checkWeight = true; $decimalItems = array(); if ($item->getParentItem()) { if (!$item->getParentItem()->getProduct()->getShipmentType()) { continue; } if ($item->getIsQtyDecimal()) { $qty = $item->getParentItem()->getQty(); } else { $qty = $item->getParentItem()->getQty() * $item->getQty(); } } $itemWeight = $item->getWeight(); if ($item->getIsQtyDecimal() && $item->getProductType() != Type::TYPE_BUNDLE) { $productId = $item->getProduct()->getId(); $isDecimalDivided = $this->stockItemService->getStockItem($productId)->getIsDecimalDivided(); if ($isDecimalDivided) { if ($this->stockItemService->getEnableQtyIncrements($productId) && $this->stockItemService->getQtyIncrements($productId)) { $itemWeight = $itemWeight * $this->stockItemService->getQtyIncrements($productId); $qty = round($item->getWeight() / $itemWeight * $qty); $changeQty = false; } else { $itemWeight = $this->_getWeight($itemWeight * $item->getQty()); $maxWeight = $this->_getWeight($this->_maxWeight, true); if ($itemWeight > $maxWeight) { $qtyItem = floor($itemWeight / $maxWeight); $decimalItems[] = array('weight' => $maxWeight, 'qty' => $qtyItem); $weightItem = $this->mathDivision->getExactDivision($itemWeight, $maxWeight); if ($weightItem) { $decimalItems[] = array('weight' => $weightItem, 'qty' => 1); } $checkWeight = false; } } } else { $itemWeight = $itemWeight * $item->getQty(); } } if ($checkWeight && $this->_getWeight($itemWeight) > $this->_getWeight($this->_maxWeight, true)) { return array(); } if ($changeQty && !$item->getParentItem() && $item->getIsQtyDecimal() && $item->getProductType() != Type::TYPE_BUNDLE) { $qty = 1; } if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { $fullItems = array_merge($fullItems, array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight'])); } } else { $fullItems = array_merge($fullItems, array_fill(0, $qty, $this->_getWeight($itemWeight))); } } sort($fullItems); return $fullItems; }
/** * Compose Packages For Carrier. * Divides order into items and items into parts if it's necessary * * @param \Magento\Shipping\Model\Carrier\AbstractCarrier $carrier * @param \Magento\Sales\Model\Quote\Address\RateRequest $request * @return array [int, float] */ public function composePackagesForCarrier($carrier, $request) { $allItems = $request->getAllItems(); $fullItems = array(); $maxWeight = (double) $carrier->getConfigData('max_package_weight'); /** @var $item \Magento\Sales\Model\Quote\Item */ foreach ($allItems as $item) { if ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE && $item->getProduct()->getShipmentType()) { continue; } $qty = $item->getQty(); $changeQty = true; $checkWeight = true; $decimalItems = array(); if ($item->getParentItem()) { if (!$item->getParentItem()->getProduct()->getShipmentType()) { continue; } $qty = $item->getIsQtyDecimal() ? $item->getParentItem()->getQty() : $item->getParentItem()->getQty() * $item->getQty(); } $itemWeight = $item->getWeight(); if ($item->getIsQtyDecimal() && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { $productId = $item->getProduct()->getId(); if ($this->stockItemService->getStockItem($productId)->getIsDecimalDivided()) { if ($this->stockItemService->getEnableQtyIncrements($productId) && $this->stockItemService->getQtyIncrements($productId)) { $itemWeight = $itemWeight * $this->stockItemService->getQtyIncrements($productId); $qty = round($item->getWeight() / $itemWeight * $qty); $changeQty = false; } else { $itemWeight = $itemWeight * $item->getQty(); if ($itemWeight > $maxWeight) { $qtyItem = floor($itemWeight / $maxWeight); $decimalItems[] = array('weight' => $maxWeight, 'qty' => $qtyItem); $weightItem = $this->mathDivision->getExactDivision($itemWeight, $maxWeight); if ($weightItem) { $decimalItems[] = array('weight' => $weightItem, 'qty' => 1); } $checkWeight = false; } else { $itemWeight = $itemWeight * $item->getQty(); } } } else { $itemWeight = $itemWeight * $item->getQty(); } } if ($checkWeight && $maxWeight && $itemWeight > $maxWeight) { return array(); } if ($changeQty && !$item->getParentItem() && $item->getIsQtyDecimal() && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { $qty = 1; } if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { $fullItems = array_merge($fullItems, array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight'])); } } else { $fullItems = array_merge($fullItems, array_fill(0, $qty, $itemWeight)); } } sort($fullItems); return $this->_makePieces($fullItems, $maxWeight); }
/** * Prepare stock item data for save * * @param \Magento\Catalog\Model\Product $product * @return $this */ protected function saveStockItemData($product) { $stockItemData = $product->getStockData(); $stockItemData['product_id'] = $product->getId(); /** * @todo Should be refactored together with \Magento\CatalogInventory\Model\Stock\Item::getStockId */ $stockItemData['stock_id'] = \Magento\CatalogInventory\Model\Stock\Item::DEFAULT_STOCK_ID; foreach ($this->paramListToCheck as $dataKey => $configPath) { if (null !== $product->getData($configPath['item']) && null === $product->getData($configPath['config'])) { $stockItemData[$dataKey] = false; } } $originalQty = $product->getData('stock_data/original_inventory_qty'); if (strlen($originalQty) > 0) { $stockItemData['qty_correction'] = $stockItemData['qty'] - $originalQty; } $stockItemDo = $this->stockItemService->getStockItem($product->getId()); $this->stockItemService->saveStockItem($this->stockItemBuilder->mergeDataObjectWithArray($stockItemDo, $stockItemData)); return $this; }
/** * Checking availability of items with decimal qty * * @return bool */ public function hasItemsWithDecimalQty() { foreach ($this->getAllItems() as $item) { /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */ $stockItemDo = $this->stockItemService->getStockItem($item->getProduct()->getId()); if ($stockItemDo->getStockId() && $stockItemDo->getIsQtyDecimal()) { return true; } } return false; }
/** * Stock item saving. * * @return $this */ protected function _saveStockItem() { /** @var $stockResource \Magento\CatalogInventory\Model\Resource\Stock\Item */ $stockResource = $this->_stockResItemFac->create(); $entityTable = $stockResource->getMainTable(); while ($bunch = $this->_dataSourceModel->getNextBunch()) { $stockData = array(); $productIdsToReindex = array(); // Format bunch to stock data rows foreach ($bunch as $rowNum => $rowData) { if (!$this->isRowAllowedToImport($rowData, $rowNum)) { continue; } // only SCOPE_DEFAULT can contain stock data if (self::SCOPE_DEFAULT != $this->getRowScope($rowData)) { continue; } $row = array(); $row['product_id'] = $this->_newSku[$rowData[self::COL_SKU]]['entity_id']; $productIdsToReindex[] = $row['product_id']; $row['stock_id'] = \Magento\CatalogInventory\Model\Stock\Item::DEFAULT_STOCK_ID; $stockItemDo = $this->stockItemService->getStockItem($row['product_id']); $existStockData = $stockItemDo->__toArray(); $row = array_merge($this->defaultStockData, array_intersect_key($existStockData, $this->defaultStockData), array_intersect_key($rowData, $this->defaultStockData), $row); $row = $this->stockItemService->processIsInStock($row); if ($this->stockItemService->isQty($this->_newSku[$rowData[self::COL_SKU]]['type_id'])) { if ($this->stockItemService->verifyNotification($row['product_id'])) { $row['low_stock_date'] = $this->_localeDate->date(null, null, null, false)->toString(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT); } $row['stock_status_changed_auto'] = (int) (!$this->stockItemService->verifyStock($row['product_id'])); } else { $row['qty'] = 0; } $stockData[] = $row; } // Insert rows if (!empty($stockData)) { $this->_connection->insertOnDuplicate($entityTable, $stockData); } if ($productIdsToReindex) { $this->newIndexer->load('catalog_product_category')->reindexList($productIdsToReindex); } } return $this; }
/** * Before save prepare process * * @return $this */ protected function _beforeSave() { parent::_beforeSave(); /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productFactory->create(); $product->load($this->getProductId()); $typeId = $product->getTypeId() ? $product->getTypeId() : $this->getTypeId(); $isQty = $this->stockItemService->isQty($typeId); if ($isQty) { if (!$this->getId()) { $this->processIsInStock(); } if ($this->getManageStock() && !$this->verifyStock()) { $this->setIsInStock(false)->setStockStatusChangedAutomaticallyFlag(true); } // if qty is below notify qty, update the low stock date to today date otherwise set null $this->setLowStockDate(null); if ($this->verifyNotification()) { $this->setLowStockDate($this->_localeDate->date(null, null, null, false)->toString(\Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT)); } $this->setStockStatusChangedAuto(0); if ($this->hasStockStatusChangedAutomaticallyFlag()) { $this->setStockStatusChangedAuto((int) $this->getStockStatusChangedAutomaticallyFlag()); } } else { $this->setQty(0); } return $this; }
/** * Retrieve Catalog Inventory Stock Item Model * * @return \Magento\CatalogInventory\Service\V1\Data\StockItem */ public function getStockItemDo() { return $this->stockItemService->getStockItem($this->getProduct()->getId()); }