I solved it like that
Just change process
function in Validator.php to
public function process($_quote) {
$i = 0;
$quote = $_quote;
$customerSession = Mage::getSingleton('customer/session');
foreach ($this->_rules as $rule) {
// @var $rule FME_Affiliates_Model_Program
// already tried to validate and failed
if ($rule->getIsValid() === false) {
continue;
}
if ($rule->getIsValid() !== true) {
$rule->afterLoad();
if (!$rule->validate($quote)) { // quote does not meet rule's conditions , //Call Found.php
$rule->setIsValid(false);
continue;
}
$rule->setIsValid(true); // passed all validations, remember to be valid
}
$this->_appliedProductsIds[] = Mage::getSingleton('checkout/session')->getReturnProductRuleValues();
$this->_appliedProductsIds[$i]['program_id'] = $rule->getProgramId();
Mage::getSingleton('checkout/session')->unsReturnProductRuleValues($this->_ReturnValues);
$i = $i + 1;
}
return $this;
}
And validate
function in Found.php to
public function validate(Varien_Object $object) {
//Called form Validator.php
$all = $this->getAggregator() === 'all';
$true = (bool)$this->getValue();
$found = false;
$Count = count($object->getAllItems());
$i = 0;
foreach ($object->getAllItems() as $item) {
$found = $all ? true : false;
foreach ($this->getConditions() as $cond) {
$validated = $cond->validate($item); // Call to Product.php's function 'validate'
if($validated) {
$this->_ProductId[] = $item->getProductId();
}
if($i == $Count) {
if ($all && !$validated) {
$found = false;
break;
} elseif (!$all && $validated) {
$found = true;
break 2;
}
}
}
if($i == $Count) {
if ($found && $true) {
break;
}
}
$i = $i + 1;
}
$this->_ReturnValues['Product_Id'] = $this->_ProductId;
if(!empty($this->_ProductId)) {
$this->_ReturnValues['Bool'] = true;
} else {
$this->_ReturnValues['Bool'] = false;
}
if ($found && $true) {
// found an item and we're looking for existing one
Mage::getSingleton('checkout/session')->setReturnProductRuleValues($this->_ReturnValues);
return true;
} elseif (!$found && !$true) {
// not found and we're making sure it doesn't exist
Mage::getSingleton('checkout/session')->setReturnProductRuleValues($this->_ReturnValues);
return true;
}
Mage::getSingleton('checkout/session')->setReturnProductRuleValues($this->_ReturnValues);
return false;
}
And access the values in Observer
with Vadidator class object like $appliedProductsIds = $validator->_appliedProductsIds;
Hop this will help someone..
I just ran into this with a client recently. I wound up writing a module that creates a new quote item attribute, sets it from an observer, and displays it below the product details in the cart, on the checkout page, in the new order e-mail, and in the admin order/invoice view.
In order to display the custom quote item where I wanted to show it, I call a helper method from whatever template I need to modify. I might turn this into an actual generic module some day, and when I do I'll figure out a better way to display that attribute rather hacking a bunch of templates. Due to time constraints, I had to use the "quick and dirty" method.
Following is the code I used to create, set, and get the attribute, plus a list of the templates I modified:
config.xml
<config>
<modules>
<Company_PromoName>
<version>0.2.0</version>
</Company_PromoName>
</modules>
<global>
<models>
<company_promoname>
<class>Company_PromoName_Model</class>
</company_promoname>
</models>
<helpers>
<company_promoname>
<class>Company_PromoName_Helper</class>
</company_promoname>
</helpers>
<resources>
<company_promoname_setup>
<setup>
<module>Company_PromoName</module>
<class>Company_PromoName_Model_Resource_Setup</class>
</setup>
</company_promoname_setup>
</resources>
<events>
<sales_quote_add_item>
<observers>
<company_promoname>
<class>company_promoname/observer</class>
<method>salesQuoteAddItem</method>
</company_promoname>
</observers>
</sales_quote_add_item>
</events>
<fieldsets>
<sales_convert_quote_item>
<promo_name>
<to_order_item>*</to_order_item>
</promo_name>
</sales_convert_quote_item>
<sales_convert_order_item>
<promo_name>
<to_quote_item>*</to_quote_item>
<to_invoice_item>*</to_invoice_item>
</promo_name>
</sales_convert_order_item>
</fieldsets>
</global>
</config>
Model/Resource/Setup.php
class Company_PromoName_Model_Resource_Setup extends Mage_Sales_Model_Resource_Setup
{
}
data-install-1.0.0.php
$installer = $this;
$entities = array(
'quote_item',
'order_item',
'invoice_item',
);
$options = array(
'type' => Varien_Db_Ddl_Table::TYPE_VARCHAR,
'visible' => true,
'required' => false
);
$installer->startSetup();
foreach ($entities as $entity) {
$installer->addAttribute($entity, 'promo_name', $options);
}
$installer->endSetup();
Observer.php
class Company_PromoName_Model_Observer
{
/**
* Adds the promo name to the quote item if it is a promo item when the item
* is added to the quote
*
* @param Varien_Event_Observer $observer Object containing data passed
* from the event
* @see Mage_Sales_Model_Quote::addItem()
* @return void
*/
public function salesQuoteAddItem(Varien_Event_Observer $observer)
{
$quoteItem = $observer->getEvent()->getQuoteItem();
$amPromoRule = $quoteItem->getOptionByCode('ampromo_rule');
if ($amPromoRule && $amPromoRule->getValue()) {
$rule = Mage::getModel('salesrule/rule')->load($amPromoRule->getValue());
if ($rule) {
$quoteItem->setPromoName($rule->getName());
}
}
}
}
Helper/Data.php
class Company_PromoName_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
* Gets the name of the promotion from a custom item attribute
*
* @param Mage_Core_Model_Abstract $item The promo item
* @return string
*/
public function getPromoName(Mage_Core_Model_Abstract $item)
{
$promoName = '';
if ($item->getPromoName()) {
$promoName = $item->getPromoName();
}
return $promoName;
}
}
Modified templates:
frontend:
checkout/cart/item/default.phtml
checkout/onepage/review/item.phtml
adminhtml:
sales/items/column/name.phtml
Screenshot of the promo item in the cart:
Note: The name of the extension and the screenshot have been redacted to protect the privacy of the client.
I hope the code I provided gets you on your way. Enjoy!
Best Answer
We experienced the same problem with a Magento 1.7.0.2 webshop.
Fortunately this bug was fixed in Magento 1.8.1.0 (I didn't check 1.8.0.0) and can easily by ported over to Magento 1.7.
You have to take a look at the difference between the method
changeQuoteCustomerGroupId
of the classMage_Sales_Model_Observer
from Magento 1.7.0.2 and 1.8.1.0 Those differences are the fix for the bug.