Configurable Product turn Out of Stock when all child product are out of stock - magento

Hey guys i got a little dilema. I am running Magento ver. 1.7.0.2
When you create a configurable product you must set the stock "in stock" and then you add the other additional products with different stock.
When the additional products stock goes to 0 the main configurable product still is "in stock".
I want that when all the additional products stock goes to 0 then the main configurable product stock to turn into "out of stock".
I am using this custom code for "out of stock" products to appear always at the bottom page. And unless the configurable product dont receive the option "out of stock" it cant go to bottom page.
$this->getSelect()->joinLeft(array('_inventory_table'=>$this->getTable('cataloginventory/stock_item')),"_inventory_table.product_id = e.entity_id",array('is_in_stock', 'manage_stock'));
$this->addExpressionAttributeToSelect('on_top','(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',array());
$this->getSelect()->order('on_top DESC');

Have you made sure you have the correct Magento settings?
Inventory "Show Out Of Stock" = "No"
Configurable product Manage Stock = "No"
Simple product /Manage Stock = "Yes"

I don't know if this would work for you but I think you can solve this from the template itself on the file "app/base/default/template/catalog/product/view.phtml", the line of code that says:
<?php if ($_product->isSaleable() && $this->hasOptions()):?>
<?php echo $this->getChildChildHtml('container2', '', true, true) ?>
<? else : ?>
enter code here
<?php endif ?>
if you base it from the original file in the base template you may see this code starting from line 100 as you can see if all the options of the configurable product is empty it means that all products are already sold out causing it not to display the form fields necessary for adding it to the cart.
I hope this helps. :)

Add this code
$this->getSelect()->joinLeft(
array('_inventory_table'=>$this->getTable('cataloginventory/stock_item')),
"_inventory_table.product_id = e.entity_id",
array('is_in_stock', 'manage_stock')
);
$this->addExpressionAttributeToSelect('on_top',
'(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
array());
$this->getSelect()->order('on_top DESC');
before line:
if ($attribute == 'price' && $storeId != 0) {
in files:
app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php
or in app/code/core/Mage/Catalog/Model/Product/Collection.php if you have Magento 1.7.0.0 +

Related

Magento - get categories and subcategories in a collection

I have the following category structure in my magento store
- root
- category 0 (ID 26)
- category 1 (main)
- category A (sub)
- category V (sub)
- category 2 (main)
- category G (sub)
- category J (sub)
- category E (sub)
- category 3 (main)
- category L (sub)
and so on...
On a page i want to be able to output the following:
1. get each (main) category and its name and url
2. get the first (sub) category in (main) and its icon (custom attribute)
So it would output this for each:
<img src="main-cat-first-sub-icon">
main-cat-name
Giving something like:
<category 1 link><category A icon img></link>
<category 1 link><category 1 name>
<category 2 link><category G icon img>
<category 2 link><category 2 link>
<category 3 link><category L icon img>
<category 3 link><category 3 link>
What is the best way of doing so? So far I have:
<?php
$_id = 26 // category 0
$_main_categories = Mage::getModel('catalog/category')
->getCollection()
->addFieldToFilter('parent_id', array('eq'=>$_id))
->addAttributeToFilter('is_active', 1)
->addAttributeToSelect(array('id','name','url'))
foreach($_main_categories as $_main_cat)
{
// load full main category
$_category = Mage::getModel('catalog/category')->load($_main_cat->getId());
// get sub category's children
$_main_cat_subs = $_category->getChildrenCategories();
// loop through sub catagories, get icon in first and break
foreach($_main_cat_subs as $_sub_cat)
{
// load full sub category
$_sub = Mage::getModel('catalog/category')->load($_sub_cat->getId());
$i++;
$_icon = $_sub_cat->getIcon();
}
if( $i >= 1 ){
break; // as i only want the first one
}
}
// output
?>
<a href="<?php echo $_main_cat->getUrl() ?>">
<img src="<?php echo $_icon ?>">
</a>
<a href="<?php echo $_main_cat->getUrl() ?>">
<?php echo $_main_cat->getName() ?>
</a>
<?php
}
?>
This works but seems very bad practice to load the full category models in a foreach loop twice and when the site grows could take a long time.
What is the best way of doing the above performance wise?
What you could optimize is this:
$_category = Mage::getModel('catalog/category')->load($_main_cat->getId());
Here you are loading the category (again) from the database. Though you already loaded a collection, you should put all the categories you need in that collection with the right attributes.
Then instead of the code above, use this handful collection function to get the category entity:
$_category = $_main_categories->getItemById($_main_cat->getId());
//...
$_sub = $_main_categories->getItemById($_sub_cat->getId());
You should see a clear improvement in the performance, especially if you have a lot of categories.

How to limit maximum items of order by country in Magento?

How can I limit maximum items of order by country or by continent?
I know we can set the limit in the config just as this answer says.
But what about I just want to limit it by country or by continent?
For instance, I just want to allow max items of 120 per product that are shipped to France and then 60 items only for the shipping outside France.
My store is set in France.
tealuo, i have find a temporary solution for this works
Here step on details:
1.copy app>code>core>Mage>CatalogInventory>Model>Observer.php to app>code>local>Mage>CatalogInventory>Model>Observer.php
And goto function checkQuoteItemQty() add below
$county=null;
$country=$quoteItem->getQuote()->getShippingAddress()->getData('country_id');
after
if (!$quoteItem || !$quoteItem->getProductId() || !$quoteItem->getQuote()
|| $quoteItem->getQuote()->getIsSuperMode()) {
return $this;
}
Then in this function change
$result = $stockItem->checkQuoteItemQty($rowQty, $qtyForCheck, $qty);
to
$result = $stockItem->checkQuoteItemQty($rowQty, $qtyForCheck, $qty,$country);
And
from
$result = $stockItem->checkQuoteItemQty($optionQty, $qtyForCheck, $optionValue);
to
$result = $stockItem->checkQuoteItemQty($optionQty, $qtyForCheck, $optionValue,$country);
copy app>code>core>Mage>CatalogInventory>Model>Stock>Item.php
to app>code>local>Mage>CatalogInventory>Model>Stock>Item.php
edit checkQuoteItemQty function:
edit below code
if ($this->getMaxSaleQty() && $qty > $this->getMaxSaleQty()) {
$result->setHasError(true)
->setMessage(
Mage::helper('cataloginventory')->__('The maximum quantity allowed for purchase is %s. %s', $this->getMaxSaleQty() * 1,$county_id)
)
->setErrorCode('qty_max')
->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products cannot be ordered in requested quantity.'))
->setQuoteMessageIndex('qty');
return $result;
}
To:
if(!is_null($county_id) && $county_id=='IN'){
if ($this->getMaxSaleQty() && $qty > 2) {
$result->setHasError(true)
->setMessage(
Mage::helper('cataloginventory')->__('The maximum quantity allowed for purchase is %s. %s', $this->getMaxSaleQty() * 1,$county_id)
)
->setErrorCode('qty_max')
->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products cannot be ordered in requested quantity.'))
->setQuoteMessageIndex('qty');
return $result;
}
}
else{
if ($this->getMaxSaleQty() && $qty > $this->getMaxSaleQty()) {
$result->setHasError(true)
->setMessage(
Mage::helper('cataloginventory')->__('The maximum quantity allowed for purchase is %s. %s', $this->getMaxSaleQty() * 1,$county_id)
)
->setErrorCode('qty_max')
->setQuoteMessage(Mage::helper('cataloginventory')->__('Some of the products cannot be ordered in requested quantity.'))
->setQuoteMessageIndex('qty');
return $result;
}
}
See code
if(!is_null($county_id) && $county_id=='IN'){
means IN=India country code of India,Just change country IN to FR France country code
And see condition if ($this->getMaxSaleQty() && $qty > 2) change 2 to 60
And According to your reference
Magento: limit product max quantity to 1 per order. quantity 2 = 2 orders
make Maximum Allow Qty in Shopping cart to 120
Importnote: this->getProductId() is given product id.

Get category name in php feed Magento with main and subcategories

We have a producfeed for Magento that is made in php and is making an .xml productfeed. In the image below you can see how we run the loop to get the products in the xml feed. We are also getting the categories with the following code:
//Prepare the loop
foreach($prodIds as $productId) {
$product->load($productId);
$product_data = array();
//Get product data
$product_data['title']=$product->getName();
$product_data['description']= strip_tags($product->getDescription());
$product_data['sku']=$product->getSku();
$product_data['color']=$product->getResource()->getAttribute('color')->getFrontend()->getValue($product);
if($product->getSpecialPrice())
$product_data['price']=number_format($product->getSpecialPrice(), 2);
else
$product_data['price']=number_format($product->getPrice(), 2);
$product_data['specialprice']=number_format($product->getSpecialPrice(), 2);
$product_data['old_price']=number_format($product->getPrice(), 2);
$product_data['availability']="Op voorraad";
$product_data['shippingcost']="6.95";
$product_data['delivery_time']="2 tot 5 werkdagen";
$product_data['link']=Mage::getBaseUrl().$product->getUrlPath();
$product_data['image_link']=Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'catalog/product'.$product->getImage();
$product_data['image_link_small']= Mage::helper('catalog/image')->init($product, 'small_image')->resize(200,200);
//Get feed category data
$childIds = Mage::getModel('catalog/product_type_configurable')->getChildrenIds($product->getId());
// Echo run the loop
?>
<product>
<sku><![CDATA[<?php echo $product_data['sku'] ?>]]></sku>
<link><![CDATA[<?php echo $product_data['link'].$source ?>]]></link>
<title><![CDATA[<?php echo $product_data['title'] ?>]]></title>
<description><![CDATA[<?php echo $product_data['description'] ?>]]></description>
<image_link><![CDATA[<?php echo $product_data['image_link'] ?>]]></image_link>
<image_link_small><![CDATA[<?php echo $product_data['image_link_small'] ?>]]></image_link_small>
<price><![CDATA[<?php echo $product_data['price'] ?>]]></price>
<old_price><![CDATA[<?php echo $product_data['old_price'] ?>]]></old_price>
<availability><![CDATA[<?php echo $product_data['availability'] ?>]]></availability>
<delivery_time><![CDATA[<?php echo $product_data['delivery_time'] ?>]]></delivery_time>
<id><![CDATA[<?php echo $product_data['sku'] ?>]]></id>
<delivery_costs><![CDATA[<?php echo $product_data['shippingcost'] ?>]]></delivery_costs>
<special_price><![CDATA[<?php echo $product_data['specialprice'] ?>]]></special_price>
<categories><?php $categoryCollection = $product->getCategoryCollection()->addAttributeToSelect('name');?><?php foreach($categoryCollection as $cat): ?><subcat><?php echo htmlentities($cat->getName()); ?></subcat><?php endforeach; ?></categories>
</product>
<?php } //End of loop ?>
</products>
Now we want to make a difference between the main categories and the subcategories. With the code above we get a list with all categories and it should be two fields, one with main categories and one with subcategories.
Can someone help me modify the code?
You can check if a category is top category by it's level.
if ($category->getLevel() == 2){
//is top category
}
elseif ($category->getLevel() > 2){
//is subcategory
}
and next time post the code, not the screenshot. What is this, a question for ants? :)

Show backorder status on magento frontend

I need to show on the product page (frontend) that the current item is for backorder ONLY and is not in stock.
I have at the moment those in stock showing qty of what is available and those products on backorder doesn't show anything.
Does anyone know a code I can put in the view.phtml file that will ONLY show a message on those products set as backorder?
Thanks!
Simon.
To do this make sure you have enabled backorders from inventory tab.
If you are on product page then first of all retrieve product qty.
<?php
$inventory = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product);
if( (int)$inventory->getQty() == 0 && $inventory->getBackorders() )
{
// No Backorders => getBackorders() = 0
// Allow Qty Below 0 => getBackorders() = 1
// Allow Qty Below 0 and Notify Customer => getBackorders() = 2
echo "display your backordedr message";
}
?>
You can also put this code in
app\design\frontend\base\default\template\catalog\product\view\type\default.phtml file where availability message of product come from.
Here is the code that you need to add in view.phtml. This will show the backorder message:
$inventory = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product);
$inv_qty = (int)$inventory->getQty();
if($inventory->getBackorders() >= 0 && $inv_qty == 0)
{
echo "Your backorder message goes here";
}

How to echo the number of reviews of the product on the product page in Magento?

I am unable to echo the number of my products reviews on one of my tabs.
Now the title of my reviews tab is Product’s Reviews and I would like to change it to Reviews(0)
I need to have a number of reviews in the brackets.
How to echo the nuber of reviews from this product?
FYI this is NOT working for me:
<?php echo $this->__(\'%d Review(s)\', $this->getReviewsCount()) ?>
Try the following code ( the code taken from Inchoo.com site ) :
// Get product review info (independent) of review page
<?php
$storeId = Mage::app()->getStore()->getId();
$summaryData = Mage::getModel('review/review_summary')
->setStoreId($storeId)
->load($_product->getId());
/* #var $summaryData Mage_Review_Model_Review_Summary */
/*
array(
['primary_id'] => 147
['entity_pk_value'] => 166
['entity_type'] => 1
['reviews_count'] => 1
['rating_summary'] => 80
['store_id'] => 1
)
*/
?>
and Echo this as <?php echo $summaryData['reviews_count']; ?>
$reviewsCount = Mage::getModel('review/review')
->getTotalReviews($product_id, true, Mage::app()->getStore()->getId());
i followed the code from Mage_Rating_Block_Entity_Detailed
as the second argument is set true in getTotalReviews so it will only get count of approved reviews.
i have found that the review summary count and ratings are taken from the code ...
$product=166;//demo product id
$storeId=Mage::app()->getStore()->getId();
$product=Mage::getModel('catalog/product')->load($product_id);
$product_review=Mage::getModel('review/review_summary')
->setStoreId($storeId)
->load($product_id);
echo $val->getReviewsCount();
echo $val->getRatingSummary();
Please try very simple code It's work for me.
<?php echo $this->getReviewsSummaryHtml($_product, 'short')?>
It's look like attached screenshot.

Resources