I need to be able to get the discount type applied in the cart.
I can get the discount amount like so:
$cart = Mage::getModel('checkout/cart')->getQuote();
$totals = $cart->getTotals();
$discount = $totals["discount"]->getValue();
How can i check what type of discount it is - whether it is a percentage or fixed amount off?
Take a look at applied_rule_ids in sales_flat_quote and sales_flat_quote_item
You could try something like
//if the item has not had a rule applied to it skip it
if($item->getAppliedRuleIds() == '')continue;
/*
* I cant remember in the database they might be comma separated or space if multiple rules were applied
* the getAppliedRuleIds() function is the one you want
*/
foreach(explode(",",$item->getAppliedRuleIds()) as $ruleID){
//Load the rule object
$rule = Mage::getModel('catalogrule/rule')->load($ruleID);
// Throw out some information like the rule name what product it was applied to
echo "<p>".$item->getSku()." had rule ".$rule->getName()."(".$item->getAppliedRuleIds().") applied </p>";
}
See Magento - get price rules from order
Related
I just found out that Magento seems to have a bug since 1.8 relating to cart rules.
let's say we have some configurable products and want to add a "discount" for a specific product if the qty is less then 50. In my case it a surcharge not a discount (you can easily add negative discount so it'll get surcharge by changing two files see http://php.quicoto.com/extra-fee-shopping-cart-price-rules-magento/).
so what does magento do?
1) checks if rule is valid for that product
2) if not it checks if it is a configurable product, then takes the first simple product, and check the rule against that.
in this case true cause qty is less then 50 ( cause this simple product is not even in cart.... )
extending the rule by a "less then 50 and more then 1" didn't worked.
$product = $object->getProduct();
if (!($product instanceof Mage_Catalog_Model_Product)) {
$product = Mage::getModel('catalog/product')->load($object->getProductId());
}
// here, everythign correct. $valid is false cause item is less then x times in cart..
$valid = parent::validate($object);
// this part makes no sense, cause he's checking on a child which is not in cart.
/** /
if (!$valid && $product->getTypeId() == Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE) {
$children = $object->getChildren();
$valid = $children && $this->validate($children[0]);
}/**/
this small snippet is related to it, and in my eyes it doesn't make any sense. why the rule should be checked against the first product of a configurable one? why randomly check the rule against some other product?
does anyone has an idea about that?
my solution for now, just comment this line out ... ;-) and the rule get applied as it should.
greets
felix
here's an image about the rule in magento backend
Looks like $object is instance of Mage_Sales_Quote_Item. If so, it explains why rule is being checked against first child - because it is the only child of configurable product in cart. It can't be more than one child of particular configurable product item in the cart at the same time
I have added new rule in Magneto for buying x product and getting y free . I have added a configurable product with multiple simple products . This rule works fine if I buy two of simple products with same sku values. What I want is that if user buys two simple products with different sku they should get second free .
How can i achieve this ?
This cannot be done with the default implementation of cart rules. You need to create new module and add your own type of rule to the list. I have made once such a module, in the following manner:
1) I add my own option to action dropdown. Luckily there is an event adminhtml_block_salesrule_actions_prepareform where you can hook. I used something like this
$form = $observer->getEvent()->getForm();
$options = $form->getElement('simple_action')->getValues();
$options[] = array(
'value' => self::BUY_ANY_X_GET_Y_ACTION,
'label' => Mage::helper('mymodule')->__('Extended Buy X get Y free (search all cart, discount amount is Y)'),
);
$form->getElement('simple_action')->setValues($options);
2) Then I hook into salesrule_validator_process where I checked whether cart items match the rule.
This was a little bit tricky as this validator is run for each cart item so you have to count how many times it was called and which items you have checked. I used conditions tab to prepare rules that says which X items have to be bought in order to get Y items according to conditions in actions tab.
With the first run of the validator you iterate over all cart collection and divides all products in two groups: one contains items that met criteria set by conditions tab, the second one met the criteria set by actions tab. In other words you form two arrays that contains items for X and items for Y.
foreach($quote->getItemsCollection() as $item) {
if (!$item->hasParentItemId()) {
if ($rule->getActions()->validate($item)) {
$ruleItems['y'][] = $item;
}
foreach($rule->getConditions()->getConditions() as $condition) {
foreach($condition->getConditions() as $check) {
if ($check->validate($item)) {
$ruleItems['x'][] = $item;
}
}
}
}
}
You calculate how many X's are there and how many Y's products will get discount. The when the event is called for each item you check if the item is in Y array and if there is enough discounts left for that item. If so you need to set discount amount and base discount amount calculated as item_qty * price and item_qty * base_price respectively. You need to set those values on result object that is in data passed to the observer method like:
$item = $observer->getEvent()->getItem();
$result = $observer->getEvent()->getResult();
$result->setDiscountAmount($item->getQty * $item->getPrice());
$result->setBaseDiscountAmount($item->getQty * $item->getBasePrice());
I want to add discount to the product when that product exceeds more than 15 days from created date.
Generally i know how to add discount to the product, but i felt this is difficult to set the discount with that condition. It make me as so confused. I have found where to add that attribute in combo box.
\app\code\core\Mage\SalesRule\Model\Rule\Condition\address.php
I got created date of product by $product->getCreatedAt()
But i totally confused "how to do that action?". If anybody know, Please help me guys!
Here i am givin you some brief idea to make customization in catalog rule to check if your product is old from created with 15 days and more.
Try to build your own module to manage this kind of catalog rule in your applicaion
you can take understand from this tutorial to manage catalog rule
specially just go throw last 4 slides to make your own rule to achieve your goal.
I have simply used shopping cart price rules by the following way.
first i had created product attribute named as days. Then I have set the value to that days textbox as programmatically as follows
require_once("app/Mage.php");
Mage::app();
$productCollection = Mage::getModel('catalog/product')->getCollection();
$date2=Date("Y-m-d");
foreach($productCollection as $_product)
{
$product = Mage::getModel('catalog/product')->load($_product->getEntityId());
$date1=$product->getCreatedAt();
$diff = abs(strtotime($date2) - strtotime($date1));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
$product->setDays($days);
$product->save();
}
After that i have added that product attribute promo rules. Then i set the condition as if differerence between dates which are from product creation date to now is more than 15 days, to add discount to that particular product.
Let's say a customer is in group A and for the group A a final price of a product is 10$. Now, in a module I need to find out what price he would get if he was in another group B. Is it possible?
I have used the following solution after some digging in Mage. Please let me know if this solution is problematic (so far it is working well though). Given a quote item:
$product = $quoteItem->getProduct();
$qty = $quoteItem->getQty();
$product->setCustomerGroupId($targetGroup->getId());
$price = $product->getPriceModel()->getFinalPrice($qty, $product);
I met with a requirement for my magento project, according this I need to provide special discount to specific customer group on their purchase. This discount must be shown in customer account,if they belong to that particular group, and when user want to use that particular discount, price of that item must be discounted according to that discount offer to them.
I know how to create a customer group, but how can I give them desired discount and make it show at time of purchase. so that customer can use it.
please suggest me any method or refer any document.
Thanks!
Since you want a discount to show "at time of purchase", use a Shopping Cart Price Rule from the Promotions menu. It can be restricted to certain customer groups.
A customer's group can be set by editing their account from Customers > Manage Customers menu, then look in Account Information for the Customer Group control.
The links I gave are both from the Magento User Guide. Please read it all.
http://www.magentocommerce.com/wiki/welcome_to_the_magento_user_s_guide/welcome_to_the_magento_user_s_guide
<?php
/**
* Get the resource model
*/
$resource = Mage::getSingleton('core/resource');
/**
* Retrieve the read connection
*/
$readConnection = $resource->getConnection('core_read');
/**
* Retrieve current users groupId
*/
$currentUserGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
/**
* Creating the custom query to fetch coupons
*/
$query = '
SELECT sr.rule_id, sr.name, sr.is_active, src.code, src.expiration_date
FROM `salesrule` sr
JOIN `salesrule_coupon` src ON (sr.`rule_id` = src.`rule_id`)
JOIN `salesrule_customer_group` scg ON(scg.`rule_id` = src.`rule_id`)
where scg.customer_group_id = '.$currentUserGroupId.'
AND sr.is_active = 1
AND ( ( src.expiration_date is null ) or ( src.expiration_date > now() ) )
';
//store result set in $rules
$rules = $readConnection->fetchAll($query);
// $rules will contain the array of all the coupons available to the current user
// This array contains all the data required
print_r($rules);
?>