/** * @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->stockConfiguration->expects($this->once())->method('canSubtractQty')->will($this->returnValue($canReturnToStock)); if ($canReturnToStock) { $orderItem = $this->getMock('Magento\\Sales\\Model\\Order\\Item', ['getProductId', '__wakeup', 'getStore'], [], '', false); $store = $this->getMock('Magento\\Store\\Model\\Store', ['getWebsiteId'], [], '', false); $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue(10)); $orderItem->expects($this->any())->method('getStore')->will($this->returnValue($store)); $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->any())->method('getOrderItem')->will($this->returnValue($orderItem)); $this->stockItemMock->expects($this->once())->method('getManageStock')->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 testModifyData() { $modelId = 1; $this->productMock->expects($this->any())->method('getId')->willReturn($modelId); $this->stockItemMock->expects($this->once())->method('getData')->willReturn($this->getSampleData()); $this->assertArrayHasKey($modelId, $this->getModel()->modifyData([])); }
/** * Disable creation for default stock item on product save. * * @param \Magento\CatalogInventory\Model\StockRegistry $subject * @param \Closure $proceed * @param string $productSku * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem * @return int */ public function aroundUpdateStockItemBySku(\Magento\CatalogInventory\Model\StockRegistry $subject, \Closure $proceed, $productSku, \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem) { $result = null; $stockId = $stockItem->getStockId(); if ($stockId) { $result = $proceed($productSku, $stockItem); } return $result; }
/** * Initialize stock item * * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem * @param \Magento\Quote\Model\Quote\Item $quoteItem * @param int $qty * * @return \Magento\Framework\DataObject * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function initialize(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem, \Magento\Quote\Model\Quote\Item $quoteItem, $qty) { /** * When we work with subitem */ if ($quoteItem->getParentItem()) { $rowQty = $quoteItem->getParentItem()->getQty() * $qty; /** * we are using 0 because original qty was processed */ $qtyForCheck = $this->quoteItemQtyList->getQty($quoteItem->getProduct()->getId(), $quoteItem->getId(), $quoteItem->getQuoteId(), 0); } else { $increaseQty = $quoteItem->getQtyToAdd() ? $quoteItem->getQtyToAdd() : $qty; $rowQty = $qty; $qtyForCheck = $this->quoteItemQtyList->getQty($quoteItem->getProduct()->getId(), $quoteItem->getId(), $quoteItem->getQuoteId(), $increaseQty); } $productTypeCustomOption = $quoteItem->getProduct()->getCustomOption('product_type'); if ($productTypeCustomOption !== null) { // Check if product related to current item is a part of product that represents product set if ($this->typeConfig->isProductSet($productTypeCustomOption->getValue())) { $stockItem->setIsChildItem(true); } } $stockItem->setProductName($quoteItem->getProduct()->getName()); $result = $this->stockState->checkQuoteItemQty($quoteItem->getProduct()->getId(), $rowQty, $qtyForCheck, $qty, $quoteItem->getProduct()->getStore()->getWebsiteId()); if ($stockItem->hasIsChildItem()) { $stockItem->unsIsChildItem(); } if ($result->getItemIsQtyDecimal() !== null) { $quoteItem->setIsQtyDecimal($result->getItemIsQtyDecimal()); if ($quoteItem->getParentItem()) { $quoteItem->getParentItem()->setIsQtyDecimal($result->getItemIsQtyDecimal()); } } /** * Just base (parent) item qty can be changed * qty of child products are declared just during add process * exception for updating also managed by product type */ if ($result->getHasQtyOptionUpdate() && (!$quoteItem->getParentItem() || $quoteItem->getParentItem()->getProduct()->getTypeInstance()->getForceChildItemQtyChanges($quoteItem->getParentItem()->getProduct()))) { $quoteItem->setData('qty', $result->getOrigQty()); } if ($result->getItemUseOldQty() !== null) { $quoteItem->setUseOldQty($result->getItemUseOldQty()); } if ($result->getMessage() !== null) { $quoteItem->setMessage($result->getMessage()); } if ($result->getItemBackorders() !== null) { $quoteItem->setBackorders($result->getItemBackorders()); } return $result; }
/** * @param int $productId * @param int $qtyInc * @param bool $isSaleable * @param int|bool $result * @dataProvider getProductQtyIncrementsDataProvider */ public function testGetProductQtyIncrements($productId, $qtyInc, $isSaleable, $result) { $this->stockItem->expects($this->once())->method('getQtyIncrements')->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)); $store = $this->getMock('Magento\\Store\\Model\\Store', ['getWebsiteId', '__wakeup'], [], '', false); $store->expects($this->any())->method('getWebsiteId')->willReturn(0); $product->expects($this->any())->method('getStore')->will($this->returnValue($store)); $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()); }
/** * @param \Praxigento\Odoo\Data\Odoo\Inventory\Product\Warehouse\Lot[] $lots * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem */ public function processLots($lots, $stockItem) { $qtyTotal = 0; $stockItemId = $stockItem->getItemId(); foreach ($lots as $lot) { $qtyTotal += $this->_subLot->processLot($stockItemId, $lot); } /* update stock item qty */ $stockItem->setQty($qtyTotal); $isInStock = $qtyTotal > 0; $stockItem->setIsInStock($isInStock); $this->_mageRepoStockItem->save($stockItem); /* cleanup extra lots */ $this->_subLot->cleanupLots($stockItemId, $lots); }
public function testAfterGetQuantityValidators() { $result = ['validate-item-quantity' => ['minAllowed' => 2, 'maxAllowed' => 5, 'qtyIncrements' => 3]]; $validators = []; $productViewBlock = $this->getMockBuilder('Magento\\Catalog\\Block\\Product\\View')->disableOriginalConstructor()->getMock(); $productMock = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->disableOriginalConstructor()->setMethods(['_wakeup', 'getId', 'getStore'])->getMock(); $storeMock = $this->getMockBuilder('Magento\\Store\\Model\\Store')->disableOriginalConstructor()->setMethods(['getWebsiteId', '_wakeup'])->getMock(); $productViewBlock->expects($this->any())->method('getProduct')->willReturn($productMock); $productMock->expects($this->once())->method('getId')->willReturn('productId'); $productMock->expects($this->once())->method('getStore')->willReturn($storeMock); $storeMock->expects($this->once())->method('getWebsiteId')->willReturn('websiteId'); $this->stockRegistry->expects($this->once())->method('getStockItem')->with('productId', 'websiteId')->willReturn($this->stockItem); $this->stockItem->expects($this->once())->method('getQtyMinAllowed')->willReturn(2); $this->stockItem->expects($this->any())->method('getQtyMaxAllowed')->willReturn(5); $this->stockItem->expects($this->any())->method('getQtyIncrements')->willReturn(3); $this->assertEquals($result, $this->block->afterGetQuantityValidators($productViewBlock, $validators)); }
public function testUpdateStockItemBySku() { $itemId = 1; $this->stockItem->expects($this->once())->method('setProductId')->willReturnSelf(); $this->stockItem->expects($this->once())->method('getData')->willReturn([]); $this->stockItem->expects($this->once())->method('addData')->willReturnSelf(); $this->stockItem->expects($this->atLeastOnce())->method('getItemId')->willReturn($itemId); $this->assertEquals($itemId, $this->stockRegistry->updateStockItemBySku($this->productSku, $this->stockItem)); }
public function testGetStockItem() { $this->stockItemCriteriaFactory->expects($this->once())->method('create')->willReturn($this->stockItemCriteria); $this->stockItemCriteria->expects($this->once())->method('setProductsFilter')->willReturn(null); $stockItemCollection = $this->getMock('\\Magento\\CatalogInventory\\Model\\ResourceModel\\Stock\\Item\\Collection', ['getFirstItem', '__wakeup', 'getItems'], [], '', false); $stockItemCollection->expects($this->once())->method('getItems')->willReturn([$this->stockItem]); $this->stockItemRepository->expects($this->once())->method('getList')->willReturn($stockItemCollection); $this->stockItem->expects($this->once())->method('getItemId')->willReturn(true); $this->assertEquals($this->stockItem, $this->stockRegistryProvider->getStockItem($this->productId, $this->scopeId)); }
/** * @expectedException \Magento\Framework\Exception\LocalizedException * @expectedExceptionMessage Invalid stock item id: 35. Assigned stock item id is 40 */ public function testAroundSaveWithNotAssignedStockItemId() { $stockId = 80; $stockItemId = 35; $defaultScopeId = 100; $defaultStockId = 80; $storedStockitemId = 40; $this->stockItem->expects($this->once())->method('getStockId')->willReturn($stockId); $this->stockRegistry->expects($this->once())->method('getStock')->with($defaultScopeId)->willReturn($this->defaultStock); $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn($defaultScopeId); $this->defaultStock->expects($this->once())->method('getStockId')->willReturn($defaultStockId); $this->product->expects($this->once())->method('getExtensionAttributes')->willReturn($this->productExtension); $this->productExtension->expects($this->once())->method('getStockItem')->willReturn($this->stockItem); $this->stockItem->expects($this->once())->method('getItemId')->willReturn($stockItemId); $storedStockItem = $this->getMockBuilder(StockItemInterface::class)->setMethods(['getItemId'])->getMockForAbstractClass(); $storedStockItem->expects($this->once())->method('getItemId')->willReturn($storedStockitemId); $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($storedStockItem); $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product); }
public function testAroundSave() { $productId = 5494; $websiteId = 1; $storeId = 2; $sku = 'my product that needs saving'; $this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($this->productExtensionMock); $this->productExtensionMock->expects($this->once())->method('getStockItem')->willReturn($this->stockItemMock); $storeMock = $this->getMockBuilder('\\Magento\\Store\\Model\\Store')->disableOriginalConstructor()->getMock(); $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId); $this->storeManager->expects($this->once())->method('getStore')->with($storeId)->willReturn($storeMock); $this->savedProductMock->expects($this->once())->method('getId')->willReturn($productId); $this->savedProductMock->expects($this->atLeastOnce())->method('getStoreId')->willReturn($storeId); $this->savedProductMock->expects($this->atLeastOnce())->method('getSku')->willReturn($sku); $this->stockItemMock->expects($this->once())->method('setProductId')->with($productId); $this->stockItemMock->expects($this->once())->method('setWebsiteId')->with($websiteId); $this->stockRegistry->expects($this->once())->method('updateStockItemBySku')->with($sku, $this->stockItemMock); $newProductMock = $this->getMockBuilder('Magento\\Catalog\\Api\\Data\\ProductInterface')->disableOriginalConstructor()->getMock(); $this->productRepositoryMock->expects($this->once())->method('get')->with($sku, false, $storeId, true)->willReturn($newProductMock); $this->assertEquals($newProductMock, $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)); }
/** * @inheritdoc */ public function updateStockItemBySku($productSku, \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem) { $productId = $this->resolveProductId($productSku); $websiteId = $stockItem->getWebsiteId() ?: null; $origStockItem = $this->getStockItem($productId, $websiteId); $data = $stockItem->getData(); if ($origStockItem->getItemId()) { if (isset($data['item_id'])) { unset($data['item_id']); } } $origStockItem->addData($data); $origStockItem->setProductId($productId); return $this->stockItemRepository->save($origStockItem)->getItemId(); }
/** * Check if is possible subtract value from item qty * * @param StockItemInterface $stockItem * @return bool */ protected function canSubtractQty(StockItemInterface $stockItem) { return $stockItem->getManageStock() && $this->stockConfiguration->canSubtractQty(); }
/** * @param ProductInterface $product * @param StockItemInterface $stockItem * @throws LocalizedException * @return void */ private function validateStockItem(ProductInterface $product, StockItemInterface $stockItem) { $defaultScopeId = $this->stockConfiguration->getDefaultScopeId(); $defaultStockId = $this->stockRegistry->getStock($defaultScopeId)->getStockId(); $stockId = $stockItem->getStockId(); if ($stockId !== null && $stockId != $defaultStockId) { throw new LocalizedException(__('Invalid stock id: %1. Only default stock with id %2 allowed', $stockId, $defaultStockId)); } $stockItemId = $stockItem->getItemId(); if ($stockItemId !== null && (!is_numeric($stockItemId) || $stockItemId <= 0)) { throw new LocalizedException(__('Invalid stock item id: %1. Should be null or numeric value greater than 0', $stockItemId)); } $defaultStockItemId = $this->stockRegistry->getStockItem($product->getId())->getItemId(); if ($defaultStockItemId && $stockItemId !== null && $defaultStockItemId != $stockItemId) { throw new LocalizedException(__('Invalid stock item id: %1. Assigned stock item id is %2', $stockItemId, $defaultStockItemId)); } }
/** * Retrieve stock qty whether product is composite or no * * @param StockItemInterface $stockItem * @return float * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function getStockQty(StockItemInterface $stockItem) { if (!$stockItem->hasStockQty()) { $stockItem->setStockQty(0); $product = $this->productFactory->create(); $product->load($stockItem->getProductId()); // prevent possible recursive loop if (!$product->isComposite()) { $stockQty = $stockItem->getQty(); } else { $stockQty = null; $productsByGroups = $product->getTypeInstance()->getProductsToPurchaseByReqGroups($product); foreach ($productsByGroups as $productsInGroup) { $qty = 0; foreach ($productsInGroup as $childProduct) { $qty += $this->getStockQty($stockItem); } if (null === $stockQty || $qty < $stockQty) { $stockQty = $qty; } } } $stockQty = (double) $stockQty; if ($stockQty < 0 || !$stockItem->getManageStock() || !$stockItem->getIsInStock() || !$product->isSaleable()) { $stockQty = 0; } $stockItem->setStockQty($stockQty); } return (double) $stockItem->getData('stock_qty'); }
/** * @inheritdoc */ public function save(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem) { try { /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productFactory->create(); $product->load($stockItem->getProductId()); if (!$product->getId()) { return $stockItem; } $typeId = $product->getTypeId() ?: $product->getTypeInstance()->getTypeId(); $isQty = $this->stockConfiguration->isQty($typeId); if ($isQty) { $isInStock = $this->stockStateProvider->verifyStock($stockItem); if ($stockItem->getManageStock() && !$isInStock) { $stockItem->setIsInStock(false)->setStockStatusChangedAutomaticallyFlag(true); } // if qty is below notify qty, update the low stock date to today date otherwise set null $stockItem->setLowStockDate(null); if ($this->stockStateProvider->verifyNotification($stockItem)) { $stockItem->setLowStockDate((new \DateTime())->format('Y-m-d H:i:s')); } $stockItem->setStockStatusChangedAuto(0); if ($stockItem->hasStockStatusChangedAutomaticallyFlag()) { $stockItem->setStockStatusChangedAuto((int) $stockItem->getStockStatusChangedAutomaticallyFlag()); } } else { $stockItem->setQty(0); } $stockItem->setWebsiteId($stockItem->getWebsiteId()); $stockItem->setStockId($stockItem->getStockId()); $this->resource->save($stockItem); $this->indexProcessor->reindexRow($stockItem->getProductId()); } catch (\Exception $exception) { throw new CouldNotSaveException(__($exception->getMessage())); } return $stockItem; }
public function testModifyData() { $modelId = 1; $someData = 1; $this->productMock->expects($this->any())->method('getId')->willReturn($modelId); $this->stockItemMock->expects($this->once())->method('getData')->willReturn(['someData']); $this->stockItemMock->expects($this->once())->method('getManageStock')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMinQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMinSaleQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMaxSaleQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsQtyDecimal')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsDecimalDivided')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getBackorders')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getNotifyStockQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getEnableQtyIncrements')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getQtyIncrements')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsInStock')->willReturn($someData); $this->assertArrayHasKey($modelId, $this->getModel()->modifyData([])); }
/** * Check if is possible subtract value from item qty * * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem * @return bool */ protected function _canSubtractQty(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem) { $result = $stockItem->getManageStock() && $this->_configStock->canSubtractQty(); return $result; }
public function testModifyData() { $modelId = 1; $someData = 1; $this->productMock->expects($this->any())->method('getId')->willReturn($modelId); $this->stockConfigurationMock->expects($this->any())->method('getDefaultConfigValue')->willReturn("a:0:{}"); $this->stockItemMock->expects($this->once())->method('getData')->willReturn(['someData']); $this->stockItemMock->expects($this->once())->method('getManageStock')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMinQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMinSaleQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getMaxSaleQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsQtyDecimal')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsDecimalDivided')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getBackorders')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getNotifyStockQty')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getEnableQtyIncrements')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getQtyIncrements')->willReturn($someData); $this->stockItemMock->expects($this->once())->method('getIsInStock')->willReturn($someData); $this->arrayManagerMock->expects($this->once())->method('set')->with('1/product/stock_data/min_qty_allowed_in_shopping_cart')->willReturnArgument(1); $this->assertArrayHasKey($modelId, $this->getModel()->modifyData([])); }
/** * Get Stock Data * * @param StockItemInterface $stockItem * @return array */ private function getData(StockItemInterface $stockItem) { $result = $stockItem->getData(); $result[StockItemInterface::MANAGE_STOCK] = (int) $stockItem->getManageStock(); $result[StockItemInterface::QTY] = (double) $stockItem->getQty(); $result[StockItemInterface::MIN_QTY] = (double) $stockItem->getMinQty(); $result[StockItemInterface::MIN_SALE_QTY] = (double) $stockItem->getMinSaleQty(); $result[StockItemInterface::MAX_SALE_QTY] = (double) $stockItem->getMaxSaleQty(); $result[StockItemInterface::IS_QTY_DECIMAL] = (int) $stockItem->getIsQtyDecimal(); $result[StockItemInterface::IS_DECIMAL_DIVIDED] = (int) $stockItem->getIsDecimalDivided(); $result[StockItemInterface::BACKORDERS] = (int) $stockItem->getBackorders(); $result[StockItemInterface::NOTIFY_STOCK_QTY] = (double) $stockItem->getNotifyStockQty(); $result[StockItemInterface::ENABLE_QTY_INCREMENTS] = (int) $stockItem->getEnableQtyIncrements(); $result[StockItemInterface::QTY_INCREMENTS] = (double) $stockItem->getQtyIncrements(); $result[StockItemInterface::IS_IN_STOCK] = (int) $stockItem->getIsInStock(); return $result; }