Magento 2: Get Product Stock Quantity and Other Stock Information - magento2

Magento 2: Get Product Stock Quantity and Other Stock Information
How to get the product stock quantity and information in magento 2

If we look at the StockItemRepository class the get method wants parameter $stockItemId, not $productId. Reference:
https://github.com/magento/magento2/blob/develop/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php#L202
I've seen many sites where stock item id IS NOT the same as product id and we should not assume it's the same ID.
To get this working you could use \Magento\CatalogInventory\Model\Stock\Item class instead and load the model by product_id field instead. I am also aware of the website_id and stock_id fields, but as far as I know it's not used (yet) and also existed in M1.
It should look something like this (code not tested):
<?php
namespace Vendor\Module\Model;
use \Magento\CatalogInventory\Model\Stock\Item;
class Mymodel
{
/**
* #var Item
*/
protected $stockItem;
/**
* Mymodel constructor.
*
* #param Item $stockItem
*/
public function __construct(Item $stockItem)
{
$this->stockItem = $stockItem;
}
/**
* Description
*
* #param $productModel
*/
public function getStockQtyByProductId($productModel)
{
try {
$stockItem = $this->stockItem->load($productModel->getId(), 'product_id');
return $stockItem->getQty();
} catch (\Exception $e) {
echo 'Something went wrong and was not handled: ' . $e->getMessage();
exit;
}
}
}

if you have product object then just use following:
echo $_product->getExtensionAttributes()->getStockItem()->getQty();
conplete object can be find as follow:
var_dump($_product->getExtensionAttributes()->getStockItem()->getData());

Actually this operation should be performed using \Magento\CatalogInventory\Api\StockRegistryInterface and here we can obtain \Magento\CatalogInventory\Api\Data\StockItemInterface, by product id or sku and we can use bunch of usefull methods to get stock information - linked product. For general stock information I recommend explore other service contracts declared in Magento\CatalogInventory\Api
Example of usage:
<?php
namespace Test\Test\Model;
class Test
{
protected $_stockRegistry;
public function __construct(\Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry)
{
$this->_stockRegistry = $stockRegistry;
}
public function getStockItem($productId)
{
return $this->_stockRegistry->getStockItem($productId);
}
}

this code help you to get product quantity
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
echo $StockState->getStockQty($productId);
?>

If you have the product object and do not want to use the other classes, You can try in the following way.
// For phtml file
$prodObj = $_product->load($_product->getId()); // $_product object in list.phtml
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();
// For php class file
$stockItem = $prodObj->getExtensionAttributes()->getStockItem();
$stockQty = $stockItem->getQty(); // $stockItemData = $stockItem->getData();

Credits:
https://github.com/magento/magento2/issues/7057#issuecomment-256052729
Actually \Magento\CatalogInventory\Api\Data\StockStatusInterface
should answer to all your questions.
Long story short:
Magento has StockItem entity which represents amount (Qty) of specific product (productId) on a concrete stock (stockId).
StockItemInterface should be used when you would like to "write" data into the data storage (like update amount of products to sync up Magento with your ERP system or to make deduction of stock during the checkout process).
StockStatusInterface is opposite to it. It should be used to "read" data for representation (on front-end). Consider StockStatus as an index which contains aggregated stock data for each specific product.
So, if you would like to get product stock status (in stock, out of stock) by product_id.
You need using StockStatusRepositoryInterface::getList(StockStatusCriteriaInterface $searchCriteria);
get StockStatus entity for specified product
/** #var \Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory **/
$criteria = $stockStatusCriteriaFactory->create();
$criteria->setProductsFilter($productId);
/** #var \Magento\CatalogInventory\Api\Data\StockStatusRepositoryInterface $stockStatusRepository **/
$result = $stockStatusRepository->getList($criteria);
$stockStatus = current($result->getItems());
$stockStatus->getProductId(); // product id
$stockStatus->getQty(); // quantity of specified product
$stockStatus->getStockStatus(); // Could be
// Magento\CatalogInventory\Model\Stock\Status::STATUS_OUT_OF_STOCK = 0;
// or
// Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK = 1;

Related

how insert sys_categories with extbase

in a extbase extension i us sys_category. In list action there is no problem, all categories work as expected. But i want to write category entries with a custom database finisher from tx_form.
In the model all seems correct:
/**
* Sets the categories
*
* #param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $categories
* #return void
*/
public function setCategories($categories)
{
$this->categories = $categories;
}
in my finisher:
$newAddress->setCategories($newCat);
$this->addressRepository->add($newAddress);
The form gives me only the uid of the category but for "setCategories" i need an \TYPO3\CMS\Extbase\Persistence\ObjectStorage.
How do i get a \TYPO3\CMS\Extbase\Persistence\ObjectStorage from the uid of the category?
Thanks!
You need a setter method for the categories like this:
public function addCategory($category)
{
$this->categories->attach($category);
}
This method will add one model to your object storage.
As you need the category model to be added, you need to get the corresponding model of the uid with $categoryRepository->findByUid($uid);

I have made a category and want to make sub category, how can I add dynamically?

I made a form in which I have titlte, image, pdf, content and category and all are working fine, but I want to add submenu in my form and also want to make this dynamic so can show all sub-menu on my website.
You must have to intruduce a key parent_id with categories table.
And in category model do create the relation like this.
class Category extends Model
{
public $fillable = ['title','parent_id'];
/**
* Get the index name for the model.
*
* #return string
*/
public function childs() {
return $this->hasMany('App\Category','parent_id','id') ;
}
}
Here you can find the complete example..https://itsolutionstuff.com/post/laravel-5-category-treeview-hierarchical-structure-example-with-demoexample.html
Hopefully this could help you.

conversion of magento 1 into magento 2

I was using fetch_assoc() method in magento 1 .
I want to convert it into Magento 2 . there is no fetch_assoc() method in magento 2.
if(is_object($result))
{
while ($resultsArray =$result->fetch_assoc())
{
if(empty($data))
{
$data[] = array_keys($resultsArray);
}
$data[] = $resultsArray;
} var_dump($data);
}
I'm not sure my proposed solution is useful for you or not but the best approach to fetch data in Magento 2 is based on Models and Collections.
Step 1: Firstly, you have to create a Model file in your module
<?php
namespace <Vendor_Name>\<Module_Name>\Model;
use Magento\Framework\Model\AbstractModel;
class Data extends AbstractModel
{
protected function _construct()
{
$this->_init('<Vendor_Name>\<Module_Name>\Model\ResourceModel\Data');
}
}
Step 2: Create ResourceModel file in your custom module
<?php
namespace <Vendor_Name>\<Module_Name>\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Data extends AbstractDb
{
protected function _construct()
{
// Second parameter is a primary key of the table
$this->_init('Table_Name', 'id');
}
}
Step 3: Create Collection file to initialize Model and ResourceModel files.
namespace <Vendor_Name>\<Module_Name>\Model\ResourceModel\Data;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection
{
protected function _construct()
{
$this->_init(
'<Vendor_Name>\<Module_Name>\Model\Data',
'<Vendor_Name>\<Module_Name>\Model\ResourceModel\Data'
);
}
}
Step 4: Last thing that you need to do is create a Block file in the same module and utilize collection, something like this:
namespace <Vendor_Name>\<Module_Name>\Block;
use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\View\Element\Template;
use <Vendor_Name>\<Module_Name>\Model\Data as DataCollection;
class Custom_Module extends Template
{
protected $dataCollection;
public function __construct(Context $context, DataCollection $dataCollection)
{
$this->_dataCollection = $dataCollection;
parent::__construct($context);
}
public function getDataCollecton()
{
$collection = $this->_dataCollection->getCollection();
return $collection;
}
}
Another Solution
You can also use fetchAll instead of fetch_assoc() in Magento 2, if you don't want to implement models and collections based solution, something like this:
// Select Data from table
$sql = "Select * FROM " . $tableName;
$result = $connection->fetchAll($sql);
and for reference, you can also have a look into Magento2 – Write Custom Mysql Query (Without Using Model)
I think we can use something like below :
$adapter = $this->resourceConnection->getConnection($resource);
$stmt = $adapter->query($sql);
// Use FETCH_NUM so we are not dependent on the CASE attribute of the PDO connection
$results = $stmt->fetchAll(\Zend_Db::FETCH_ASSOC);
Or if we have $connection instanceof \Magento\Framework\DB\Adapter\AdapterInterface
$connection->fetchAll($sql, $binds, \PDO::FETCH_ASSOC);
By using those, i think you're gonna get the same result to magento 1 fetch_assoc
Alternative of the fetch_assoc() in magento 2 is fetchAssoc($SQL_QUERY)
Below is the example.
For get order where status is pending data using fetchAssoc(SQL_QUERY)
<?php
namespace Path\To\Class;
use Magento\Framework\App\ResourceConnection;
class fetchAssoc {
const ORDER_TABLE = 'sales_order';
/**
* #var ResourceConnection
*/
private $resourceConnection;
public function __construct(
ResourceConnection $resourceConnection
) {
$this->resourceConnection = $resourceConnection;
}
/**
* fetchAssoc Sql Query
*
* #return string[]
*/
public function fetchAssocQuery()
{
$connection = $this->resourceConnection->getConnection();
$tableName = $connection->getTableName(self::ORDER_TABLE);
$query = $connection->select()
->from($tableName,['entity_id','status','grand_total'])
->where('status = ?', 'pending');
$fetchData = $connection->fetchAssoc($query);
return $fetchData;
}
}
In magento 2 you can use same but for that you need to create database connection.
I suggest you to use resource or collection models to get the result and if you want to get the first row in object format then you should use
getFirstItem();
I think Magento 2 has support for this in class \Magento\Framework\DB\Adapter\AdapterInterface. You can create an instance for AdapterInterface by dependency injection or directly by object manager.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
/** #var \Magento\Framework\App\ResourceConnection $resourceConnection */
$resourceConnection = $objectManager->get(\Magento\Framework\App\ResourceConnection::class);
/** #var \Magento\Framework\DB\Adapter\AdapterInterface $connection */
$connection = $resourceConnection->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);
$sql = "YOUR SELECT QUERY HERE";
$data = $connection->fetchAssoc($sql);

How to get current WordPress category in FishPig in Magento 2?

What is the most straightforward way to get the current category in the view? I notice that there is a getTerm method in the Term class:
public function getEntity()
{
return $this->getTerm();
}
/**
* Returns the current Wordpress category
* This is just a wrapper for getCurrentCategory()
*
* #return \FishPig\WordPress\Model\Term
*/
public function getTerm()
{
if (!$this->hasTerm()) {
$this->setTerm($this->_registry->registry(Term::ENTITY));
}
return $this->_getData('term');
}
However if I try to utilize the method within a template (for example, the default post list wrapper.phtml template which utilizes the Term block in the layout) it throws an error:
<?php echo $this->getTerm() ?>
Recoverable Error: Object of class FishPig\WordPress\Model\Term could
not be converted to string in
I'm probably just missing something simple, any help would be greatly appreciated. Thanks!
$term = \Magento\Framework\App\ObjectManager::getInstance()
->get('Magento\Framework\Registry')
->registry('wordpress_term');

Laravel 5.2 get the closest date from eloquent collection

I have Eloquent Event model, which is related towards multiple dates like this:
$event->dates // shows Collection of 8 Eloquent date models
After that i need to pick the only date, what is closest to current time. I know how to do this using query of raw SQL, or DB class. But isnt there any better solution? I dont want to jump into database for data, I already have.
Date format in eloquent models is surprisingly string.
You can use what we call in laravel mutators like this ->
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
public function dates()
{
return $this->hasMany('Date');
}
/**
* Get Dates for the event.
*
* #param string $value
* #return array
*/
public function getDates()
{
$dates = $this->dates()->getQuery()->orderBy('created_at', 'asc')->get();
return $dates;
}
}
Hope this helps.
UPDATE
I think now you can also directly do this in the model definition like this -
return $this->hasMany('Date')->orderBy('created_at', 'asc')