Hi i have an attribute that calculates the margin of an product, in all attribute sets. Question is how can i set a rule to prevent customer check out if the margin(or profit) of a cart is less than required?
You can create an observer for the event controller_action_predispatch_checkout_onepage_index - this will fire when the customer starts the onepage checkout process.
This can be achieved like so in your modules config.xml:
<events>
<controller_action_predispatch_checkout_onepage_index>
<observers>
<YOUR_MODULE_checkout_onepage_index>
<type>singleton</type>
<class>YOUR_MODULE_Model_Observer</class>
<method>calculateProductMargin</method>
</YOUR_MODULE_checkout_onepage_index>
</observers>
</controller_action_predispatch_checkout_onepage_index>
</events>
If you are unaware about how to create a module then look here
So in your app/code/local/YOUR/MODULE/Model/Observer.php:
class YOUR_MODULE_Model_Observer extends Varien_Event_Observer {
public function setStore($observer) {
// Your logic here
}
}
In here you can $cart = Mage::getModel('checkout/cart')->getQuote(); and loop through the cart items, calculate your product margin and _goBack() potentially if it fails your requirements.
Enjoy! I hope this helps.
Related
I am building a module that adds a free product to the cart when a specific coupon code is entered.
I have an event observer which fires when a new coupon code is applied in the basket:
The event in my config is this:
<events>
<salesrule_validator_process>
<observers>
<checkoutApplyCouponToProduct>
<type>singleton</type>
<class>Sulman_Giftwithcoupon_Model_Checkout_Observer</class>
<method>applyCoupon</method>
</checkoutApplyCouponToProduct>
</observers>
</salesrule_validator_process>
</events>
This works correctly and I can add the free product succesully if the correct coupon code is added.
Now what I need to do is to remove the free product if the coupon code is canceled by the customer.
But the event I'm using does not fire when the coupon is canceled.
Is there an event I can use to check if the coupon code is removed?
Thanks
I would probably observe the controller_action_predispatch_checkout_cart_couponPost event and check whether the remove param is set, which is what triggers Mage_Checkout_CartController::couponPostAction to remove the coupon.
etc/config.xml
<config>
<global>
<events>
<controller_action_predispatch_checkout_cart_couponPost>
<observers>
<checkoutRemoveCouponProduct>
<type>singleton</type>
<class>Sulman_Giftwithcoupon_Model_Checkout_Observer</class>
<method>removeCoupon</method>
</checkoutRemoveCouponProduct>
</observers>
</controller_action_predispatch_checkout_cart_couponPost>
</events>
</global>
</config>
Model/Observer.php
public function removeCoupon(Varien_Event_Observer $observer)
{
/* #var Mage_Core_Controller_Front_Action $controller */
$controller = $observer->getControllerAction();
if ($controller->getRequest()->getParam('remove') == 1) {
// #TODO add logic to remove free product
}
return $this;
}
you can fire your custom event in couponPostAction() action in
app/code/core/Mage/Checkout/controllers/CartController.php
in this you will see a code which handles the wrong coupon and also if the coupon form has no value. You can fire your custom event there and listen that event in your module.
Hope this will do your work.
thanks
I would like to have the categories in magento made use of the attributes/filter.
Let say I have an attribute "CupAttr" which is a NOT used in layered navigation. Then I create a category called CupCat, and it uses the "CupAttr" to pull products to display them within the CupCat category.
is that possible? The reason why i want to do this is I want to minimize the maintenance of categorizing products.
Thanks
EDITED:
Amit's solution works perfectly, but that bring in another issue. the products showing in the list is different from the products can be filtered from the layered navigation.
I actually need to select all products for any category (because i won't add any products to any category, they are all blank), then i start filter the products for that specific category by attribute.
thanks again.
In this case,you can use magento event/observer.
Hook an observer on event catalog_block_product_list_collection.
Then using addAttributeToFilter('CupAttrAttibiteCode'); filter the collection by CupAttr.
config.xml code:
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<catalog_block_product_list_collection> <!-- event -->
<observers>
<xyz_catalog_block_product_list_collection>
<type>singleton</type>
<class>Xyz_Catalog_Model_Observer</class>
<method>apply_CupAttr_filter</method>
</xyz_catalog_block_product_list_collection>
</observers>
</catalog_block_product_list_collection>
</events>
</global>
</config>
Observer code location:
Create the directory structure - app/code/local/Xyz/Catalog/Model/Observer.php
First "CupAttr" which is used in prouct listing for use this attribute to filtering
<?php
class Xyz_Catalog_Model__Observer
{
public function __construct()
{
}
public function apply_CupAttr_filter($observer){
//apply filter when category is CupCat
if(Mage::registry('current_category') &&(Mage::registry('current_category')->getId()=='CupCatCatrgoryId') ):
$collection=$observer->getEvent()->getCollection();
$collection->addAttributeToFilter('CupAttrAttibiteCode','FilterExpression');
endif;
return $this;
}
}
i need to get Alert or Commands or Notification message if Quantity increase or Decrease in magento? i am the new guy in magento?How to configure on this?
There only is an RSS feed notifying you if the quantity drops belowe a certain level. You would need to find or create an extension if you want a more sophisticated behavior.
Such an extension could be based on something like this:
You hook into the cataloginventory_stock_item_save_after event like this:
<events>
<cataloginventory_stock_item_save_after>
<observers>
<package_module_stocknote>
<type>singleton</type>
<class>Package_Module_Model_Observer</class>
<method>stocknote</method>
</package_module_stocknote>
</observers>
</cataloginventory_stock_item_save_after>
</events>
Then create an observer at Package/Module/Model/Observer.php:
class Package_Module_Model_Observer extends Varien_Event_Observer {
public function stocknote($observer) {
$stockItem = $observer->getEvent()->getItem();
//Insert your logic here
}
}
I want to show the Magento existing inbuilt payment method based on store Id.I have two store and want to show Cash on delivery and pay pal on one store and do not want these payment method on another store.Please help
When deciding which payment methods to show Magento will issue an event. You can register observer for that event and filter payment list by store ID. Here is how to do it.
Create new module for the observer. Register observer in your config.xml:
<confg>
...
<frontend>
...
<events>
<payment_method_is_active>
<observers>
<company_module>
<type>singleton</type>
<class>Company_Module_Model_Observer</class>
<method>frontendPaymentMethods</method>
</company_module>
</observers>
</payment_method_is_active>
</events>
</frontend>
</config>
And then create model for the observer class Model/Observer.php with frontendPaymentMethods function:
<?php
class Company_Module_Model_Observer {
public function frontendPaymentMethods($observer) {
$quote = $observer->getData('quote');
$result = $observer->getData('result');
$method = $observer->getData('method_instance');
if($method->getCode() == 'banktransfer' && Mage::app()->getStore() == 5) {
$result->isAvailable = false;
}
}
}
This will disable banktransfer payment method for store with id 5.
You can do this in Magento configuration under System > Configuration. Choose one of the stores in the dropdown list at the top left corner of the configuration page. And disable Cash on delivery and paypal payment methods. This will be a store specific configuration, that means these payment methods will be disabled only in that store and available in other.
http://www.magentocommerce.com/knowledge-base/entry/overview-how-multiple-websites-stores-work/
I'm working on an extension that will receive product information from Magento when saved and do custom processing on the product.
I've spent 2 days until now trying to figure out why Magento is not triggering the event "catalog_product_status_update".
Simply, I change product status by going to Catalog->Manage Products, then select one or more products and use the "Actions" field above the products grid to change product(s) status to "disabled".
When I do that, the product(s) status changes just fine, but the problem is that I don't receive the event for it.
Here's the code I use:
<?xml version="1.0"?>
<config>
<global>
<models>
<mage4ucustomredirect>
<class>Mage4u_Customredirect</class>
</mage4ucustomredirect>
</models>
<events>
<catalog_product_save_after>
<observers>
<abc>
<type>singleton</type>
<class>Mage4u_Customredirect_Model_Observer</class>
<method>on_catalog_product_save_after</method>
</abc>
</observers>
</catalog_product_save_after>
<catalog_product_status_update>
<observers>
<abc>
<type>singleton</type>
<class>Mage4u_Customredirect_Model_Observer</class>
<method>on_catalog_product_status_update</method>
</abc>
</observers>
</catalog_product_status_update>
</events>
</global>
</config>
And this is the observer:
class Mage4u_Customredirect_Model_Observer
{
public function on_catalog_product_status_update(Varien_Event_Observer $observer)
{
Mage::log( "on_catalog_product_status_update" );
}
public function on_catalog_product_save_after(Varien_Event_Observer $observer)
{
Mage::log( "on_catalog_product_save_after" );
}
}
?>
Strange enough, when I try to save a product manually, I receive the event "on_catalog_product_save_after" which tells me that my code is working fine, but it doesn't work for this "on_catalog_product_status_update" event.
Any help is appreciated!
NOTE: I'm using Magento v1.6.2.0
I believe your problem is that the update status option at the top of the grid doesn't use any models to achieve the task, it access the database directly. If you look at the updateAttributes method in Mage_Catalog_Model_Product_Action and Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Action respectively, you will see that no product or product_status model is loaded.
Unfortunately for you, at a quick glance I don't see any events that you can hook into to capture this. It might require rewriting of the model.
Your two observers have the same name "abc". This should be unique inside Magento observers list.
Try changing one of them to "abc1", refresh your cache and it should work.
This question was asked somewhere in 2012, but in more recent Magento versions, the mass action update for the product grid is processed by the catalog/product_action model its updateAttributes method:
Mage_Catalog_Model_Product_Action::updateAttributes()
An event is dispatched there:
Mage::dispatchEvent('catalog_product_attribute_update_before', array(
'attributes_data' => &$attrData,
'product_ids' => &$productIds,
'store_id' => &$storeId
));
attributes_data is a key-value list with data to be stored for product_ids in the store_id scope. In your observer for catalog_product_attribute_update_before you can check if the status attribute is being updated:
$event = $observer->getEvent();
$attributesData = $event->getData('attributes_data');
if (! isset($attributesData['status'])) {
// we are not updating the status
return;
}
// do something, for example - if the product will be disabled
if ($attributesData['status'] != Mage_Catalog_Model_Product_Status::STATUS_ENABLED) {
// api call
}
Hope this helps for anyone who tries to intercept a mass status update.