Get configurable sku from simple SKU or ID - magento

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);
}
?>

Related

How to check if Configurable Product is out of stock?

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.

Magento Collection get clients by payment method

I would like to know if anyone already coded a Magento Collection to get the customer name by the payment method? I used the code bellow and now I have the payment method that I need, now I just have to get the client's first and last name. Thank you all for the help.
$collection = Mage::getResourceModel('sales/order_payment_collection')
->addFieldToSelect('*');
foreach ($collection as $method) {
if ($method->getMethod() == "mundipagg_boleto") {
print $method->getMethod()."<br>";
}
}
$collection = Mage::getResourceModel('sales/order_payment_collection')
->addFieldToSelect('*')
->addFieldToFilter('method', "mundipagg_boleto");
foreach ($collection as $orderPayment) {
$orderId = $orderPayment->getParentId();
$order = Mage::getModel('sales/order')->load($orderId);
$customerId = $order->getCustomerId();
}
After that you can load customer's model by customerId

Magento Multiple Wishlist creation programmatically

I know how to add products to a customer's wishlist programmatically however it only adds to one wishlist. I have the multiple wishlist option set to enabled however I do not know how to create a new wishlist instead of merging products into the existing wishlist.
public function submitQuote(Mage_Adminhtml_Model_Session_Quote $quote)
{
$currentQuote = $quote->getQuote();
$customer = $currentQuote->getCustomer();
$items = $currentQuote->getAllVisibleItems();
//$wishlist = Mage::helper('wishlist')->getWishlist();
//Mage::register('wishlist', $wishlist);
$wishlist = Mage::getModel('wishlist/wishlist');
$curretDate = date('m/d/Y', time());
$wishlist->setCustomerId($customer->getId());
$wishlist->setName('Quote ' . $curretDate)
->setVisibility(false)
->generateSharingCode()
->save();
foreach ($items as $item)
{
$productId = $item->getProductId();
$product = Mage::getModel('catalog/product')->load($productId);
$buyRequest = $item->getBuyRequest();
$result = $wishlist->addNewItem($product, $buyRequest);
if(is_string($result))
{
Mage::throwException($result);
}
$wishlist->save();
}
//Mage::unregister('wishlist');
}
I've had this problem before. To add a product to a customer's wishlist you need to start a wishlist model and call the addNewItem method passing the product object. Here is how I do it.
$customer = Mage::getModel('customer/customer');
$wishlist = Mage::getModel('wishlist/wishlist');
$product = Mage::getModel('catalog/product');
$customer_id = 1;
$product_id = 1;
$customer->load($customer_id);
$wishlist->loadByCustomer($customer_id);
$wishlist->addNewItem($product->load($product_id));
Hope this helps!
EDITED:
$customerid= "YOUR CUSTOMER ID "; // Modify This
$customer=Mage::getModel("customer/customer")->load($customerid);
$wishlist=Mage::getModel("wishlist/wishlist")->loadByCustomer($customer,true);
Check for reference this: app/code/core/Mage/Wishlist/Model/Wishlist.php
LATEST EDIT:
I see that your problem is here:
$result = $wishlist->addNewItem($product, $buyRequest);
FINAL EDIT:
Then create another function and add the items and wishlist you want to add it to (as parameters). This should add items to the wishlist that you have passed as an argument when calling the function. Its the only solution I can come up with. Hope this helps!
I just stumbled across this question because I'm trying to do something similar - your code part helped me to create a new wishlist, and I've managed to do the rest so thought I'd share.
This code will;
Create a new wishlist with the name 'Quote dd/mm/YY h:m:s'
Load the wishlist collection for the current user, ordered by highest ID first
Load the newest wishlist
Add all basket items to it
Redirect the user to the new wishlist view.
public function addToQuoteAction() {
if(Mage::getSingleton('customer/session')->isLoggedIn()) {
$customerData = Mage::getSingleton('customer/session')->getCustomer();
$customerId = $customerData->getId();
} else {
Mage::getSingleton('core/session')->addError($this->__('Please login to use this feature'));
return $this->_redirectUrl($this->_getRefererUrl());
}
// Create the wishlist
$newWishlist = Mage::getModel('wishlist/wishlist');
$curretDate = date('d/m/Y h:m:s', time());
$newWishlist->setCustomerId($customerId);
$newWishlist->setName('Quote ' . $curretDate)
->setVisibility(false)
->generateSharingCode()
->save();
// Find the newly create list and load it
$wishlistCollection = Mage::getModel('wishlist/wishlist')->getCollection()
->addFieldToFilter('customer_id',$customerId)->setOrder('wishlist_id');;
$firstWish = $wishlistCollection->getFirstItem();
$wishlist = Mage::getModel('wishlist/wishlist')->load($firstWish->getWishlistId());
$cart = Mage::getModel('checkout/cart')->getQuote();
//getAllItems
foreach ($cart->getAllVisibleItems() as $item) {
$productId = $item->getProductId();
$buyRequest = $item->getBuyRequest();
$result = $wishlist->addNewItem($productId, $buyRequest);
$wishlist->save();
}
Mage::getSingleton('core/session')->addSuccess($this->__('All items have been moved to your quote'));
return $this->_redirectUrl(Mage::getBaseUrl().'wishlist/index/index/wishlist_id/'.$firstWish->getWishlistId().'/');
}

How to get a particular item from the cart using the item id in cart?

I want to get a particular item from the cart using id of item in cart (not product id).
http://localhost/magento81/index.php/checkout/cart/configure/id/1/
I want to load using this id, id/1
How to get that ?
$cart = Mage::getModel('checkout/cart')->getQuote();
foreach ($cart->getAllItems() as $item) {
if($item->getId() == 1)
{
$productId = $item->getProduct()->getId();
$productPrice = $item->getProduct()->getPrice();
}
}
In general if you use print_r($item->getProduct()->getData()) it will disaplay all the information related to product in the cart.
$this should do the trick.
$itemId = 1;
$item = Mage::getModel('sales/quote_item')->load($itemId);
If you want to get the product object associated to the item continue with this
$product = $item->getProduct();

Get Simple Product from Configurable in Cart

I'm trying to load the simple products that have been added to a customer's cart, but when I retrieve the items, it's showing the parent configurable.
$cart = Mage::getSingleton('checkout/cart');
$productIds = array();
foreach ($cart->getQuote()->getAllVisibleItems() as $item) {
$productIds[] = $item->getProduct()->getId();
}
var_dump($productIds);
For instance, this will return all the same configurable id when I've added a small, medium, and large to my cart. How can I get the individual simple products? I'm trying to retrieve an attribute value that's set on the simple product level.
After taking a look at how Magento renders the items in your cart on the checkout/cart page, I was able to find this in app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Configurable.php
/**
* Get item configurable child product
*
* #return Mage_Catalog_Model_Product
*/
public function getChildProduct()
{
if ($option = $this->getItem()->getOptionByCode('simple_product')) {
return $option->getProduct();
}
return $this->getProduct();
}
So, applying it to the snippet in the question, it would be
foreach ($cart->getQuote()->getAllVisibleItems() as $item) {
$productId = $item->getProduct()->getId();
if ($option = $item->getOptionByCode('simple_product')) {
$productId = $option->getProduct()->getId();
}
$productIds[] = $productId;
}

Resources