How to check if Configurable Product is out of stock? - magento

We all know that a configurable product in magento is associated with simple product.
If the simple products associated to the configurable product becomes Inventory = 0, it means that the configurable product is out of stock
So the question is how do i detect if Configurable Product is out of stock? i want to detect so I can display in front-end the "Out of Stock" text.
something like this
if($configurable_product->isOutOfStock()) {
echo "Out of Stock";
}
How can i do this in Magento?

if (!$configurable->isSaleable() ||$configurable_product->getIsInStock()==0){
// out of stock
}
For checking child simple product:
$allProducts = $configurable->getTypeInstance(true)
->getUsedProducts(null, $configurable);
foreach ($allProducts as $product) {
if (!$product->isSaleable()|| $product->getIsInStock()==0) {
//out of stock for check child simple product
}
}

$_productCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToFilter('type_id', array('eq' => 'configurable'));
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($_productCollection);
This shows only the configurable products that are in stock.

Just a slight update/correction to Quovadisqc's answer. When defining $qty it should be
$qty = $stockItem->getData('qty'); // correct
Instead of what's currently there,
$qty = $stockItem->setData('qty'); // incorrect
I'd post this as a comment but I don't have enough rep.

In the foreach loop of products the following if statement works.
if ($product->getIsInStock() === '1' && $product->isSaleable() === true) {
echo 'this product is in stock';
}

$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
$stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product->getId());
$qty = $stockItem->getData('qty');
$inStock = $stockItem->getData('is_in_stock');
if ($qty < 1 || $inStock == 0) {
// OutOfStock
}
I prefer to double check with qty since products won't always be out of stock on qty == 0 depending on config settings.

Related

How to get correct quantity for child product in cart

I get cart items information using following code:
$cart_items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
foreach( $cart_items as $items )
{
$items->getQty();
}
In above code $items->getQty() always return "float(1)" while more than 1 quantity add in cart for child product.
How to get correct quantity for child product?
Thanks in advance.
Finally I found my solution:
$cart_items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
foreach( $cart_items as $items )
{
STATIC $qty='';
if($items->getProductType() == 'configurable') //configurable products
{
$qty = $items->getQty();
continue;
}
else // non-configurable product
{
if (!$items->getParentItem()) // product which has not parent product
{
$qty = $items->getQty();
}
}
echo $qty;
}
For simple products your code should work.
Try using a model call to see if it makes a difference. Also check sales_flat_quote table and see what items/quantity is found under the sales_flat_quote_item table and if they mismatch with the frontend display.
$oQuote = Mage::getModel( 'checkout/cart' )->getQuote();
// For all items.
$iTotalItemQty = $oQuote->getItemsQty();
echo $iTotalItemQty;
Also are you seeing this show up from a simple product with quantity > 1 or a different product type?
Did you tried getAllVisibleItems() instead of getAllItems()?
$cart_items = Mage::getSingleton('checkout/session')->getQuote()->getAllVisibleItems();
foreach( $cart_items as $items )
{
$items->getQty();
}

magento : get unit price from cart

i m developping an extension for custom price and i wanna know how to get the unit price from cart i've tried this :
$itemProduct = $this->getProduct();
$cart = Mage::getModel('checkout/cart')->getQuote();
foreach ($cart->getAllItems() as $item) {
$productId = $item->getProduct()->getProductId();
$productPrice = $item->getProduct()->getPrice();
if($productId == $itemProduct->getId()){
/*
* do our check for 'same product' here.
* Returns true if attribute is the same thus it is hte same product
*/
if ($productPrice == $itemProduct->getPrice()) {
return true; //same product
} else {
return false; //different product
}
}
but it returns always false i guess i didn't get the unit price
how to do that ?
try direct to database like :
if you want to looking for quote unit price check ( table name : sales_flat_quote then column subtotal )
if you are looking for sales uni price take a look under ( table name : sales_flat_order then column subtotal )
this help you to improve your extension speed ( only to get content not add )
Thanks
Solved change this :
$productId = $item->getProduct()->getProductId();
$productPrice = $item->getProduct()->getPrice();
to this :
$productId = $item->getProductId();
$productPrice = $item->getPrice();

Get configurable sku from simple SKU or ID

I'm attempting to get a parent configurable product SKU from one of it's child simple products' SKU or ID. My understanding is that a simple can belong to multiple configurables, but I want the specific configurable the customer added to their cart. I read a related question but it gets all parent configurables.
I'm using Magento EE 1.12
EDIT: More detail on what I'm doing. When a customer checks out successfully I'm attempting to get SKU's of simples and the configurable the customer checked out with.
Attempting to apply code to:
app/design/frontend/enterprise/mytheme/template/checkout/success.phtml
If the configurable is in the cart already I think you can interrogate the cart to find the configurable and its simple ID.
$myTargetSimpleProductId = $someIdThatYouKnow;
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
foreach ($cartItems as $item){
if ($option = $item->getOptionByCode('simple_product')) {
$productIdArray[] = $option->getProduct()->getId(); //for the record
if ($option->getProduct()->getId()==$myTargetSimpleProductId ){
$myMatchingConfigurableProductId = $item->getProductId(); //capture the ID of the configurable
}
}
}
//$productIdArray holds a list of all the IDs of simple products that are in the basket due to configurables.
echo("The answer is ".$myMatchingConfigurableProductId);
Code adapted from this Q&A and that Q&A and not tested so let me know if this bombs horribly and you can't figure out all the corrections.
****EDIT to explain the code a bit more following the comment below ***
Overall, it helps to understand that when someone adds a configurable product to the cart Magento principally stores the product ID of the configurable not the product ID of the underlying simple product. But Magento being Magento the configured product in the cart is a complex object, part of which is a reference to the underlying simple product.
So:
$item->getProductId(); //Really means [pseudo code] $item->getConfiguredProductId()
$item->getOptionByCode('simple-product') //Accesses the underlying simple product object, hence
$item->getOptionByCode('simple-product')->getProduct()->getId() //gives accesse to the ID of the underlying simple product - ie the thing you want to test.
Now, if you are on the success page the challenge is how to access the order items. There are a sprinkling of answers on Stack Overflow for that and here is a sampling:
$_order = Mage::getModel('sales/order')->loadByIncrementId($this->getOrderId());
foreach ($_order->getAllItems() as $item) {
due to this Q&A. Or
$_customerId = Mage::getSingleton('customer/session')->getCustomerId();
$lastOrderId = Mage::getSingleton('checkout/session')->getLastOrderId();
$order = Mage::getSingleton('sales/order');
$order->load($lastOrderId);
foreach ($order->getItemsCollection() as $item) {
or from an observer function:
$order = $observer->getOrder();
/* #var $item Mage_Sales_Model_Order_Item */
foreach ($order->getItemsCollection() as $item) {
both due to this Q&A.
But I think you might benefit most from this tutorial from the Magento savvy Yireo:
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
$cartItems = $order->getAllItems();
foreach($cartItems as $item) {
due to Jisse Reitsma of Yireo.com
So you should be all set. There are a few bits and pieces to string together into your final code but I think you are either putting your code in template/checkout/success.phtml or in an observer on checkout_type_onepage_save_order_after and the snippets above will guide you.
****FURTHER EDITS***
If you have a $product that is product_type = 'configurable' then to get its SKU you should call $product->getData('sku'); if you only call $product->getSku(); that will always return the simple SKU due to
//file: app/code/core/Mage/Core/Catalog/Model/Product.php
//class: Mage_Catalog_Model_Product
public function getSku()
{
return $this->getTypeInstance(true)->getSku($this);
}
and if you follow the code, you find
//file: app/code/core/Mage/Core/Catalog/Model/Product/Type/Configurable.php
//class: Mage_Catalog_Model_Product_Type_Configurable
public function getSku($product = null)
{
$sku = $this->getProduct($product)->getData('sku');
if ($this->getProduct($product)->getCustomOption('option_ids')) {
$sku = $this->getOptionSku($product,$sku);
}
return $sku;
}
I would add that I have been running lots of code tests. When I set up an observer on the event checkout_type_onepage_save_order_after then
$cartItems = $observer->getEvent()->getOrder()->getAllVisibileItems();
foreach ($cartItems as $item){
if ($item->getProductType() == 'configurable') {
$skuConfigurable = $item->getProduct()->getData('sku');
$skuMatchingSimple = $item->getProduct()->getSku();
Mage::log("skuConfigurable ".$skuConfigurable." has skuMatchingSimple ".$skuMatchingSimple, null, 'mylogfile.log');
}else{
Mage::log("Configurable SKU"." (not configurable product)", null, 'mylogfile.log');
}
}
Works a treat, but when I access the order items from within success.phtml then both getSku() and getData('sku') both return the SKU of the configurable. Which leads me to think that I am not loading the sales/order correctly or not understanding how to ascertain the 'configurable option' from the configurable $item. But I can't figure out why there is that difference between `$item' in the observer compared to the success.phtml.
You probably know this already but I thought I would add: If you catch the event then you can access both the sale/quote and the sale/order objects but by the time you get to success.phtml the sales/quote object has been reset and you can only access sale/order (which I think is okay for you if all you need is the configurable sku).
Here is the code I am running in success.phtml, for me it only returns the config SKU
<?php //TEST CODE to retrieve SKUs from the order
$_checkoutSession = Mage::getSingleton('checkout/session');
$_customerSession = Mage::getSingleton('customer/session');
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
echo("<br>Order Id".$orderId);
$myTargetSimpleProductId = 42;//$someIdThatYouKnow;
//$cartItems = $order->getAllVisibleItems(); //returns the configurable items only
$cartItems = $order->getAllItems();
Mage::log(':PHTML--PHTML--PHTML--PHTML--PHTML--PHTML--PHTML--PHTML--', null, 'mylogfile.log');
Mage::log(':', null, 'mylogfile.log');
Mage::log('cartItems (from order):', null, 'mylogfile.log');
foreach ($cartItems as $item){
Mage::log("product_id".$item->getProductId(), null, 'mylogfile.log');
Mage::log("product_type".$item->getProductType(), null, 'mylogfile.log');
Mage::log("product_real_type".$item->getRealProductType(), null, 'mylogfile.log');
if ($option = $item->getOptionByCode('simple_product')) { //NEVER RETURNS TRUE, why?
Mage::log("item_opByCode_getProd_getId".$item->getOptionByCode('simple_product')->getProduct()->getId(), null, 'mylogfile.log');
}else{
Mage::log("item_opByCode_getProd_getId"." (not simple_product option)", null, 'mylogfile.log');
}
if ($item->getProductType() == 'configurable') {
$dummy = $item->getProduct()->getData('sku');
Mage::log("Configurable SKU ".$dummy, null, 'mylogfile.log'); $myAnswers[]=array('simpleSku'=>$item->getProduct()->getSku(),'configurableSku'=>$item->getProduct()->getData('sku')); //in success.phtml these two are always the same (the configurable SKU)
}else{
Mage::log("Configurable SKU"." (not configurable product)", null, 'mylogfile.log');
}
Mage::log("item options".print_r($item->getOptions(),true), null, 'mylogfile.log');
Mage::log("getProduct()->getId()".$item->getProduct()->getId(), null, 'mylogfile.log');
Mage::log("getProduct()->getSku".$item->getProduct()->getSku(), null, 'mylogfile.log');
Mage::log("getProduct()->getName()".$item->getProduct()->getName(), null, 'mylogfile.log');
Mage::log("SKUs : ".print_r($myAnswers,true), null, 'mylogfile.log');
Mage::log("<br>********************************", null, 'mylogfile.log');
if($item->getOptions()){ //NEVER RUNS - how get the configurable product options?
echo("OPTIONS".print_r($item->getOptions(),true));
}
}
echo("SKU's array".print_r($myAnswers,true));
I hope something here works for you. One time in the past I wrote a theme that only puts the simple product in the cart even if it originated as a configurable option so maybe worth checking your theme isn't doing that (by developing this code in the default theme until it works)
I just needed the SKUs for an AJAX cart function. This worked for me:
$cart = Mage::helper('checkout/cart')->getCart();
$items = $cart->getItems();
foreach ($items as $item) {
if ($item->getProductType() == 'configurable') {
$sku = $item->getProduct()->getData('sku');
} else {
$sku = $item->getSku(); // simple product
}
}
Answer pulled mostly from Malachy's dissertation...
There have any direct function to fetch parent Product sku
<?php
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($childproid);
/* $parentIds is array of ids */
foreach( $parentIds as $eachProID)
$child=Mage::getModel('catalog/product')->load($eachProID);
}
?>

Show inventory of simple product of configurable products in Magento

I am quite new to Magento. As far as I understand, I need to form configurable products, to manage different size of a product. I want to show stock qty of each size seperately in the product view page. Is this possible? My attribute name is 'size'. I have used the following code to get stock qty. However, it is unable to get stock qty of indivual simple product of a configurable product.
<?php
$__manStock = $_product->getStockItem()->getManageStock();
$__invAmt =(int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty('small');
if ($__manStock > 0)
{
echo $this->__("$__invAmt");
}
?>
$_product is your configurable product.
To get all its simple products use :
$_product->getTypeInstance(true)->getUsedProducts ( null, $_product);
So you might have something like :
foreach ($_product->getTypeInstance(true)->getUsedProducts ( null, $_product) as $simple) {
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple)->getQty();
echo $simple->getName()." with size ".$simple->getSize()." have a stock of $stock";
echo '<br/>';
}
I let you adapt to your precise needs and ask question if needed
I sum all products to a number and round it withouts commas:
$itemsinstock = 0;
foreach ($_product->getTypeInstance(true)->getUsedProducts ( null, $_product) as $simple) {
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple)->getQty();
$stock = round($stock,2);
echo $simple->getName()." : $stock pieces";
echo '<br/>';
$itemsinstock+= $stock;
}
echo $itemsinstock;
Please tell me about file location where the bellow code will be added.
foreach ($_product->getTypeInstance(true)->getUsedProducts ( null, $_product) as $simple) {
$stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($simple)->getQty();
echo $simple->getName()." with size ".$simple->getSize()." have a stock of $stock";
echo '<br/>';
}

Magento: Increase "Qty" upon cancel a shipped order

I'm on Magento 1.7.0.2. I'm using "Cash On Delivery" as my payment method.I'll tell you exactly the steps That i follow on any order. When an order is placed(Qty decreased 1 item), I create a shipment for it and if customer paid the order grand total price. I create an invoice for that order.
My problem, If an order is placed(Qty decreased 1 item), I create a shipment for this order. If the customer refused to pay, I open this order and "Cancel" it and on this case the "Qty" doesn't increase so How can I make it increase?
If order status is Processing
Create a custom module with observer for 'order_cancel_before' (see example # Change Magento default status for duplicated products change <catalog_model_product_duplicate> to <order_cancel_before>
since <order_cancel_before> is not defined in app/code/core/Mage/Sales/Model/Order.php
You could override/rewrite order model class see e.g http://phprelated.myworks.ro/how-to-override-rewrite-model-class-in-magento/
In your local module do
public function cancel()
{
if ($this->canCancel()) {
Mage::dispatchEvent('order_cancel_before', array('order' => $this));
$this->getPayment()->cancel();
$this->registerCancellation();
Mage::dispatchEvent('order_cancel_after', array('order' => $this));
}
return $this;
}
Or you could create a new method increaseProductQty() in your model and copy the code below into it (this way you would not need an observer). Then replace the line Mage::dispatchEvent('order_cancel_before'... with $this->increaseProductQty()
In your observer method (pseudo code)
$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();
foreach ($order->getItemsCollection() as $item)
{
$productId = $item->getProductId();
$qty = $item->getQty();
// you need to check order status to make sure it processing
//$order->getStatus() (assuming you are canceling entire order)
//$order->getPayment();
$product = Mage::getModel('catalog/product')->load($product_id);
$stock_obj = Mage::getModel('cataloginventory/stock_item')->load($product_id);
$stockData = $stock_obj->getData();
$product_qty_before = (int)$stock_obj->getQty();
$product_qty_after = (int)($product_qty_before + $qty);
$stockData['qty'] = $product_qty_after;
$productInfoData = $product->getData();
$productInfoData['updated_at'] = $curr_date;
$product->setData($productInfoData);
$product->setStockData($stockData);
$product->save();
}
If you have issue with updating stock see Set default product values when adding new product in Magento 1.7
Reference http://pragneshkaria.com/programatically-change-products-quantity-after-order-cancelled-magento/
If order status is Pending
Take a look at System > Configuration > Inventory
Set Items’ Status to be In Stock When Order is Cancelled — Controls whether products in pending orders automatically return to the stock if orders are cancelled. Scope: STORE VIEW.
Read more #
How to Manage Magento Store Inventory?
ADMIN: System → Configuration → Inventory Tab
Thanks to R.S as he helped me more & more.
I followed all instructions on R.S's reply https://stackoverflow.com/a/13330543/1794834 and I've only changed the observer code. Here is the observer code that worked with me on Magento 1.7.0.2.
$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();
foreach ($order->getItemsCollection() as $item)
{
$productId = $item->getProductId();
$qty = (int)$item->getQtyOrdered();
$product = Mage::getModel('catalog/product')->load($productId);
$stock_obj = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
$stockData = $stock_obj->getData();
$product_qty_before = (int)$stock_obj->getQty();
$product_qty_after = (int)($product_qty_before + $qty);
$stockData['qty'] = $product_qty_after;
/*
* it may be case that admin has enabled product add in stock, after product sold,
* he set is_in_stock = 0 and if order cancelled then we need to update only qty not is_in_stock status.
* make a note of it
*/
if($product_qty_after != 0) {
$stockData['is_in_stock'] = 1;
}else{
$stockData['is_in_stock'] = 0;
}
$productInfoData = $product->getData();
$productInfoData['updated_at'] = $curr_date;
$product->setData($productInfoData);
$product->setStockData($stockData);
$product->save();
}

Resources