Exemple #1
1
 /**
  * Set inventory data to custom attribute
  *
  * @param Product $object
  * @return $this
  */
 public function afterLoad($object)
 {
     $stockItemDo = $this->stockItemService->getStockItem($object->getId());
     $object->setData($this->getAttribute()->getAttributeCode(), array('is_in_stock' => $stockItemDo->getIsInStock(), 'qty' => $stockItemDo->getQty()));
     return parent::afterLoad($object);
 }
Exemple #2
0
 /**
  * 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);
 }
 public function testGetStockItem()
 {
     $productId = 123;
     $stockItemData = ['some_key' => 'someValue'];
     $stockItemModel = $this->getMockBuilder('Magento\\CatalogInventory\\Model\\Stock\\Item')->disableOriginalConstructor()->getMock();
     $stockItemModel->expects($this->once())->method('getData')->will($this->returnValue($stockItemData));
     $this->stockItemRegistry->expects($this->once())->method('retrieve')->with($productId)->will($this->returnValue($stockItemModel));
     $this->stockItemBuilder->expects($this->once())->method('populateWithArray')->with($stockItemData);
     $stockItemDo = $this->getMockBuilder('Magento\\CatalogInventory\\Service\\V1\\Data\\StockItem')->disableOriginalConstructor()->getMock();
     $this->stockItemBuilder->expects($this->once())->method('create')->will($this->returnValue($stockItemDo));
     $this->assertEquals($stockItemDo, $this->model->getStockItem($productId));
 }
Exemple #4
0
 /**
  * @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;
 }
Exemple #5
0
 /**
  * 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;
 }
Exemple #6
0
 /**
  * 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);
 }
Exemple #7
0
 /**
  * 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;
 }
Exemple #8
0
 /**
  * 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;
 }
Exemple #9
0
 /**
  * Retrieve Catalog Inventory  Stock Item Model
  *
  * @return \Magento\CatalogInventory\Service\V1\Data\StockItem
  */
 public function getStockItemDo()
 {
     return $this->stockItemService->getStockItem($this->getProduct()->getId());
 }
Exemple #10
0
 /**
  * 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;
 }
Exemple #11
0
 /**
  * Setup product for quote item
  *
  * @param \Magento\Catalog\Model\Product $product
  * @return $this
  */
 public function setProduct($product)
 {
     if ($this->getQuote()) {
         $product->setStoreId($this->getQuote()->getStoreId());
         $product->setCustomerGroupId($this->getQuote()->getCustomerGroupId());
     }
     $this->setData('product', $product)->setProductId($product->getId())->setProductType($product->getTypeId())->setSku($this->getProduct()->getSku())->setName($product->getName())->setWeight($this->getProduct()->getWeight())->setTaxClassId($product->getTaxClassId())->setBaseCost($product->getCost());
     /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */
     $stockItemDo = $this->stockItemService->getStockItem($product->getId());
     if ($stockItemDo->getStockId()) {
         $this->setIsQtyDecimal($stockItemDo->getIsQtyDecimal());
     }
     $this->_eventManager->dispatch('sales_quote_item_set_product', array('product' => $product, 'quote_item' => $this));
     return $this;
 }
 /**
  * Processing additional validation to check if carrier applicable.
  *
  * @param RateRequest $request
  * @return $this|bool|Error
  */
 public function proccessAdditionalValidation(RateRequest $request)
 {
     //Skip by item validation if there is no items in request
     if (!count($this->getAllItems($request))) {
         return $this;
     }
     $maxAllowedWeight = (double) $this->getConfigData('max_package_weight');
     $errorMsg = '';
     $configErrorMsg = $this->getConfigData('specificerrmsg');
     $defaultErrorMsg = __('The shipping module is not available.');
     $showMethod = $this->getConfigData('showmethod');
     /** @var $item \Magento\Sales\Model\Quote\Item */
     foreach ($this->getAllItems($request) as $item) {
         $product = $item->getProduct();
         if ($product && $product->getId()) {
             $weight = $product->getWeight();
             $stockItemData = $this->stockItemService->getStockItem($product->getId());
             $doValidation = true;
             if ($stockItemData->getIsQtyDecimal() && $stockItemData->getIsDecimalDivided()) {
                 if ($this->stockItemService->getEnableQtyIncrements($product->getId()) && $this->stockItemService->getQtyIncrements($product->getId())) {
                     $weight = $weight * $this->stockItemService->getQtyIncrements($product->getId());
                 } else {
                     $doValidation = false;
                 }
             } elseif ($stockItemData->getIsQtyDecimal() && !$stockItemData->getIsDecimalDivided()) {
                 $weight = $weight * $item->getQty();
             }
             if ($doValidation && $weight > $maxAllowedWeight) {
                 $errorMsg = $configErrorMsg ? $configErrorMsg : $defaultErrorMsg;
                 break;
             }
         }
     }
     if (!$errorMsg && !$request->getDestPostcode() && $this->isZipCodeRequired($request->getDestCountryId())) {
         $errorMsg = __('This shipping method is not available. Please specify the zip code.');
     }
     if ($errorMsg && $showMethod) {
         $error = $this->_rateErrorFactory->create();
         $error->setCarrier($this->_code);
         $error->setCarrierTitle($this->getConfigData('title'));
         $error->setErrorMessage($errorMsg);
         return $error;
     } elseif ($errorMsg) {
         return false;
     }
     return $this;
 }