Creating a coupon code for product with custom options
-
13-12-2019 - |
Question
I need to generate coupon codes for products with specific custom options. My sales rules have conditions for product SKU's and quantities. However, I don't know a good way to obtain the SKU for a product that has specific options. I tried the solution outlined on this site: http://inchoo.net/magento/magento-shopping-cart-promotion-rule-for-product-with-custom-options/
Unfortunately, generating SKU's in the format
[main product SKU]-[first option SKU]-...
is completely unreliable, since even the Magento test database has products with different SKU's in it. For example, an XL chealsea tee should have the SKU mtk000-XL
, but the actual SKU is mtk000xl
.
I understand that adding the product to the shopping cart with custom options might work, but I want to avoid using the cart for this purpose. I have access to the following data:
- The product object, which is loaded by its url using the method below
- The array which contains the custom options
Load item by URL:
public function getItemByUrl($url) {
$itemUrl = str_replace(Mage::getBaseUrl(), "", $url);
if (strpos($itemUrl, "/" === 0)) {
$itemUrl = substr($itemUrl, 1);
}
$oRewrite = Mage::getModel('core/url_rewrite')
->setStoreId(Mage::app()->getStore()->getId())
->loadByRequestPath($itemUrl);
if ($oRewrite == null) return null;
$item_id = $oRewrite->getProductId();
if ($item_id == null) return null;
$product = Mage::getModel('catalog/product')->load($item_id);
return $product;
}
Array format:
attribute id => selected option id
For example, a medium khaki shirt has the following options array associated with it:
array(2) {
[92] => "28"
[180] => "78"
}
To be clear, I only need a way to figure out the SKU that belongs to the specific product, for example, the medium khaki shirt. Once I have that, I have no problems with generating coupon codes.
Solution
Eventually, I've been able to come up with a method that does exactly what I need.
private function getSkuForOptions($product, $options) {
$usedProducts = $product->getTypeInstance(true)->getUsedProducts(null, $product);
$sku = -1;
foreach ($usedProducts as $childProduct) {
if (!$childProduct->isSaleable()) {
continue;
}
$data = $childProduct->getData();
$match = true;
foreach ($options as $id => $value) {
if (!isset($data[$id]) || $data[$id] !== $value) {
$match = false;
}
}
if ($match) {
$sku = $childProduct->getSku();
break;
}
}
return $sku;
}
The $product
parameter is the object returned by the method getItemByUrl
, described in my original question. The parameter $options
is an array in the following format:
attribute_code => value_id
For example, the red XL shirt is associated with the following options array:
array(2) {
'color' => 28
'size' => 78
}
My method looks for the saleable instances of the base product and tries to match their options to the ones supplied.
This idea came to me after many hours of reverse-engineering the magento core and reading this article: http://www.divisionlab.com/solvingmagento/magento-configurable-product-type-tutorial/