/**
  * @param \Magento\Sales\Api\Data\OrderInterface $order
  */
 public function splitQty(\Magento\Sales\Api\Data\OrderInterface $order)
 {
     $storeId = $order->getStoreId();
     /* get stock ID for the store view */
     $stockId = $this->_manStock->getStockIdByStoreId($storeId);
     /** @var \Magento\Sales\Api\Data\OrderItemInterface[] $items */
     $items = $order->getItems();
     $itemsData = [];
     /** @var \Magento\Sales\Api\Data\OrderItemInterface $item */
     foreach ($items as $item) {
         $prodId = $item->getProductId();
         $itemId = $item->getItemId();
         /* qty of the product can be changed in invoice, but we use ordered only  */
         $qty = $item->getQtyOrdered();
         /* register sale item (fragment total qty by lots) */
         $itemData = $this->_manObj->create(\Praxigento\Warehouse\Service\QtyDistributor\Data\Item::class);
         $itemData->setItemId($itemId);
         $itemData->setProductId($prodId);
         $itemData->setQuantity($qty);
         $itemData->setStockId($stockId);
         $itemsData[] = $itemData;
     }
     $reqSale = $this->_manObj->create(\Praxigento\Warehouse\Service\QtyDistributor\Request\RegisterSale::class);
     $reqSale->setSaleItems($itemsData);
     $this->_callQtyDistributor->registerSale($reqSale);
 }
 /**
  * Update stock item on the stock and distribute qty by lots.
  *
  * @param \Magento\CatalogInventory\Model\StockManagement $subject
  * @param \Closure $proceed
  * @param array $items
  * @param int $websiteId is not used
  * @throws \Magento\Framework\Exception\LocalizedException
  * @return null
  */
 public function aroundRegisterProductsSale(\Magento\CatalogInventory\Model\StockManagement $subject, \Closure $proceed, array $items, $websiteId)
 {
     /* This code is moved from original 'registerProductsSale' method. */
     /* replace websiteId by stockId */
     $stockId = $this->_manStock->getCurrentStockId();
     $def = $this->_manTrans->begin();
     $lockedItems = $this->_resourceStock->lockProductsStock(array_keys($items), $stockId);
     $fullSaveItems = $registeredItems = [];
     foreach ($lockedItems as $lockedItemRecord) {
         $productId = $lockedItemRecord['product_id'];
         $orderedQty = $items[$productId];
         /** @var \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem */
         $stockItem = $this->_providerStockRegistry->getStockItem($productId, $stockId);
         $stockItemId = $stockItem->getItemId();
         $canSubtractQty = $stockItemId && $this->_canSubtractQty($stockItem);
         if (!$canSubtractQty || !$this->_configStock->isQty($lockedItemRecord['type_id'])) {
             continue;
         }
         if (!$stockItem->hasAdminArea() && !$this->_stockState->checkQty($productId, $orderedQty)) {
             $this->_manTrans->rollback($def);
             throw new \Magento\Framework\Exception\LocalizedException(__('Not all of your products are available in the requested quantity.'));
         }
         if ($this->_canSubtractQty($stockItem)) {
             $stockItem->setQty($stockItem->getQty() - $orderedQty);
         }
         $registeredItems[$productId] = $orderedQty;
         if (!$this->_stockState->verifyStock($productId) || $this->_stockState->verifyNotification($productId)) {
             $fullSaveItems[] = $stockItem;
         }
     }
     $this->_resourceStock->correctItemsQty($registeredItems, $stockId, '-');
     $this->_manTrans->commit($def);
     return $fullSaveItems;
 }
 /**
  * Replace default stock id in the where clause by stock id corresponded with store id.
  *
  * @param \Magento\CatalogInventory\Model\ResourceModel\Stock\Status $subject
  * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $result
  * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
  */
 public function afterAddStockDataToCollection(\Magento\CatalogInventory\Model\ResourceModel\Stock\Status $subject, \Magento\Catalog\Model\ResourceModel\Product\Collection $result)
 {
     /** @var \Magento\Framework\Db\Select $select */
     $select = $result->getSelect();
     $from = $select->getPart('from');
     $join = $from['stock_status_index'];
     $cond = $join['joinCondition'];
     $stockId = $this->_manStock->getCurrentStockId();
     $fixed = str_replace('.stock_id = 1', '.stock_id = ' . $stockId, $cond);
     $join['joinCondition'] = $fixed;
     $from['stock_status_index'] = $join;
     $select->setPart('from', $from);
     return $result;
 }
 /**
  * @param \Magento\Sales\Api\Data\OrderInterface $order
  * @return \Praxigento\Pv\Service\Sale\Data\Item[]
  */
 public function getServiceItemsForMageSaleOrder(\Magento\Sales\Api\Data\OrderInterface $order)
 {
     $result = [];
     $storeId = $order->getStoreId();
     /* get stock ID for the store view */
     $stockId = $this->_manStock->getStockIdByStoreId($storeId);
     /** @var \Magento\Sales\Api\Data\OrderItemInterface[] $items */
     $items = $order->getItems();
     /** @var \Magento\Sales\Api\Data\OrderItemInterface $item */
     foreach ($items as $item) {
         $itemData = $this->getServiceItemForMageItem($item, $stockId);
         $result[] = $itemData;
     }
     return $result;
 }
 /**
  * @param \Magento\Sales\Api\Data\OrderInterface $mageOrder
  * @return \Praxigento\Odoo\Data\Odoo\SaleOrder\Line[]
  */
 public function getSaleOrderLines(\Magento\Sales\Api\Data\OrderInterface $mageOrder)
 {
     $lines = [];
     /* collect data */
     $orderId = $mageOrder->getId();
     $storeId = $mageOrder->getStoreId();
     $stockId = $this->_manStock->getStockIdByStoreId($storeId);
     $aggSaleOrderItems = $this->_repoAggSaleOrderItem->getByOrderAndStock($orderId, $stockId);
     foreach ($aggSaleOrderItems as $item) {
         $productIdOdoo = $item->getOdooIdProduct();
         /* process order line */
         if (isset($lines[$productIdOdoo])) {
             $line = $lines[$productIdOdoo];
         } else {
             $line = $this->_extractLine($item);
         }
         /* process lot for order line ($item is a flat structure - if one sale item consists of 2 lots then
            two entries will be in aggregated results) */
         $lots = $line->getLots();
         $lot = $this->_extractLineLot($item);
         /* save Odoo data object into Odoo line */
         $lots[] = $lot;
         $line->setLots($lots);
         $lines[$productIdOdoo] = $line;
     }
     /* remove keys from array */
     $result = array_values($lines);
     return $result;
 }
 /**
  * @param \Magento\CatalogSearch\Model\Search\IndexBuilder $subject
  * @param \Closure $proceed
  * @param \Magento\Framework\Search\RequestInterface $request
  * @return \Magento\Framework\DB\Select
  */
 public function aroundBuild(\Magento\CatalogSearch\Model\Search\IndexBuilder $subject, \Closure $proceed, \Magento\Framework\Search\RequestInterface $request)
 {
     /** @var \Magento\Framework\DB\Select $result */
     $result = $proceed($request);
     $from = $result->getPart(\Magento\Framework\DB\Select::FROM);
     if (isset($from[self::AS_STOCK_INDEX])) {
         $dimensions = $request->getDimensions();
         /** @var \Magento\Framework\Search\Request\Dimension $dimension */
         $dimension = reset($dimensions);
         $storeId = $dimension->getValue();
         $stockId = (int) $this->_manStock->getStockIdByStoreId($storeId);
         $byStockId = self::AS_STOCK_INDEX . '.' . Cfg::E_CATINV_STOCK_STATUS_A_STOCK_ID . '=' . $stockId;
         $result->where($byStockId);
     }
     return $result;
 }
 /**
  * Detect current stock and get appropriate stock item.
  *
  * @param \Magento\CatalogInventory\Model\StockRegistryProvider $subject
  * @param \Closure $proceed
  * @param int $productId
  * @param int $scopeId
  * @return \Magento\CatalogInventory\Api\Data\StockItemInterface
  */
 public function aroundGetStockItem(\Magento\CatalogInventory\Model\StockRegistryProvider $subject, \Closure $proceed, $productId, $scopeId)
 {
     $result = $this->_storageStockRegistry->getStockItem($productId, $scopeId);
     if (null === $result) {
         $criteria = $this->_factoryStockItemCrit->create();
         $criteria->setProductsFilter($productId);
         $stockId = $this->_toolStockManager->getCurrentStockId();
         $criteria->setStockFilter($stockId);
         $collection = $this->_repoStockItem->getList($criteria);
         $result = current($collection->getItems());
         if ($result && $result->getItemId()) {
             $this->_storageStockRegistry->setStockItem($productId, $scopeId, $result);
         } else {
             $result = $this->_factoryStockItem->create();
         }
     }
     return $result;
 }