Disable 'General' group sales in Magento - magento

I'm looking to disable sales on our Magento site for any customers in the 'General' customer group. We have a tiered customer group system setup, with different tax rules etc., but I can't figure out how to disable 'general' as a group that can purchase from the site. I don't want new customers signing up able to purchase without being assigned a group first.
Thanks.

Here is my idea: set up observer on controller_action_predispatch_checkout_onepage_index event, which will fire before checkout page is loaded. In observer we check if customer belongs to certain group and if so we redirect him to cart page and show error message.
Translated to Magento code, it would look like this:
Firs we hook on the event in our config.xml
<frontend>
<events>
<controller_action_predispatch_checkout_onepage_index>
<observers>
<your_module>
<class>your_module/observer</class>
<method>banCheckout</method>
</your_module>
</observers>
</controller_action_predispatch_checkout_onepage_index>
</events>
</frontend>
and in our observer:
public function banCheckout(Varien_Event_Observer $observer)
{
$customerSession = Mage::getSingleton('customer/session');
if (!$customerSession->isLoggedIn()) {
return $this;
}
$groupId = $customerSession->getCustomer()->getGroupId();
if ($groupId == 1) {
Mage::getSingleton('checkout/session')->addError(
Mage::helper('checkout')->__('Your error message.')
);
$action = $observer->getEvent()->getControllerAction();
$action->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));
$action->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true);
}
return $this;
}
Keep in mind this is just an example, and a pretty simple one.

Related

[Magento]How to Enable/Disable COD based on city and not on countries?

I would like to enable/disable COD option based on a particular city (seller city) rather than particular countries. How to achieve that?
I have searched for this and found some topics but those are not very clear to me because this is my first magento website.
Can anybody please guide me exactly how to do this? I know for this I might need to build a module so if that is the case then please guide me from scratch.
You can do this by Magento Event/Observer
First,using payment_method_is_active disable on depends current quote shippiping address /billing address city you can disable.
Code for this:
Module config.xml code:
<global>
<events>
<payment_method_is_active>
<observers>
<paymentfilter_payment_method_is_active>
<type>singleton</type>
<class>yourmodel/observer</class>
<method>filterpaymentmethod</method>
</paymentfilter_payment_method_is_active>
</observers>
</payment_method_is_active>
</events>
</global>
On Observer you can get current quote shipping /billing address using below code
$observer->getEvent()->getQuote()->getShippingAddress()/$observer->getEvent()->getQuote()->getBillingAddress()
Observer code is:
<?php
class YOURNANESPACE_YOURMODULE_Model_Observer {
public function filterpaymentmethod(Varien_Event_Observer $observer) {
/* call get payment method */
$method = $observer->getEvent()->getMethodInstance();
/* get Quote */
$quote = $observer->getEvent()->getQuote();
/* check quote exit or not */
if($quote):
$Billing=$observer->getEvent()->getQuote()->getBillingAddress();
$Shipping =$observer->getEvent()->getQuote()->getShippingAddress()
$observer->getEvent()->getQuote()->getBillingAddress();
/* Disable Your payment method by city */
if($method->getCode()=='YOUR_PAYMENT_METHOD_CODE' ){
$result->isAvailable = false
// dis payment method depends on city
if($Shipping->getCity=='YOUR_CITY'):
$result->isAvailable = true;
else:
$result->isAvailable = false;
endif;
}
endif;
}
}
Here the another sample of this type of works:
displaying certain payment methods for customer groups
Payment methods based on billing region?
This extension will work as per your requirement.
http://www.magentocommerce.com/magento-connect/advance-cash-on-delivery.html
You need to mentioned the applicable zipcodes

How can I set the inbuilt payment method based on store id

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/

Implementing an event observer in Magento

Im starting to understand how Magento Event Observers work and hoping someone could help me figure out what Event I would need to seek out to get my potential module to work. I have certain products that have an attribute called "child skus" which is an array of SKU numbers of other products in my inventory.
Example:
Name: Totally Awesome Product
SKU: TP-1212
Child SKUS: GP-3232,FD-4332,VC-5332
Every time someone purchases TP-1212 I also need Magento to deduct that quantity from those child skus behind the scenes. Does anyone know if there is an event dispatcher for after a purchase has been completed that would handle something like that??
This is a little tricky and there are most likely some edge cases not covered in the below code - Also the answer assumes the following:
You wish to reduce the stock level of all associated products of the parent just purchased
You wish to reduce by only 1
There are no further complications or other conditions that must be met/dealt with
Code:
So, you obviously need to create a module first. The config.xml needs to declare the observer which will listen to checkout_type_onepage_save_order_after. (Note: there are other events you can listen to in order to achieve your goal).
The config.xml will contain the following code at a minimum:
<?xml version="1.0"?>
<config>
<modules>
<YourCmpany_YourModule>
<version>1.0.0</version>
</YourCmpany_YourModule>
</modules>
<frontend>
<events>
<checkout_type_onepage_save_order_after>
<observers>
<yourmodule_save_order_observer>
<class>YourCompany_YourModule_Model_Observer</class>
<method>checkout_type_onepage_save_order_after</method>
</yourmodule_save_order_observer>
</observers>
</checkout_type_onepage_save_order_after>
</events>
</frontend>
<global>
<models>
<yourmodule>
<class>YourCompany_YourModule_Model</class>
</yourmodule>
</models>
</global>
</config>
Then in your observer:
<?php
class YourCompany_YourModule_Model_Observer
{
public function checkout_type_onepage_save_order_after(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
/**
* Grab all product ids from the order
*/
$productIds = array();
foreach ($order->getItemsCollection() as $item) {
$productIds[] = $item->getProductId();
}
foreach ($productIds as $productId) {
$product = Mage::getModel('catalog/product')
->setStoreId(Mage::app()->getStore()->getId())
->load($productId);
if (! $product->isConfigurable()) {
continue;
}
/**
* Grab all of the associated simple products
*/
$childProducts = Mage::getModel('catalog/product_type_configurable')
->getUsedProducts(null, $product);
foreach($childProducts as $childProduct) {
/**
* in_array check below, makes sure to exclude the simple product actually
* being sold as we dont want its stock level decreased twice :)
*/
if (! in_array($childProduct->getId(), $productIds)) {
/**
* Finally, load up the stock item and decrease its qty by 1
*/
$stockItem = Mage::getModel('cataloginventory/stock_item')
->loadByProduct($childProduct)
->subtractQty(1)
->save()
;
}
}
}
}
}
There are several possibilities with simplest being just checkout_type_onepage_save_order_after
however do you also need to revert the stock if order get's cancelled or execute this only when payment is made or items are shipped?

Magento "Product Status Update" event is not triggered

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.

How to send category based order emails in magento?

I have two root categories in my magento site. One is "Home Products" and the other is "Office products".
These two root categories have some sub categories also.
I want to send "Home Products" related orders to this email address "email_home#example.com",
And to send "Office Products" related orders to this email address "email_office#example.com".
How will I do this?
I suggest you to write own Observer to order.
sales_order_place_after
event suits best for your purpose.
If buyer can add to shopping cart items only from 1 cateogry.
Your module should:
Get order via observer.
Get order first item and get it's category
Choose email based on category
Send email
public function sendOrder(){
$order = $observer->getEvent()->getOrder();
...
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('your_template');
$emailTemplateVariables = array();
$emailTemplateVariables['order'] = $order;
$emailTemplate->setSenderName('Your shops name');
$emailTemplate->setSenderEmail('addres#from.com');
$emailTemplate->setTemplateSubject(Subject');
$emailTemplate->send('to#addres.com','Name', $emailTemplateVariables);
}
Update 1
First of all I insist that you see the link I provide in the comments area.
Then:
To create module:
Create in app/etc/modules/ Company_Module.xml file. With the content similiar to this one:
true
local
This eill tell magento, that in app/code/local/Company/Module there is something interesting to watch.
Create proper folder and file structure.
For you module I think it would be enough:
Company
-Module
--etc
---config.xml
--Model
---Observer.php
--Helper
---Data.php
Magento should know everything about your module. Moreover you should define observer for event.
Important note: we will catch Magento's event. Not ours.
config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Company_Module>
<version>0.1.0</version>
</Company_Module>
</modules>
<global>
<models>
<company_module>
<class>Company_Module_Model</class>
</company_module>
</models>
<helpers>
<cmod>
<class>Company_Module_Helper</class>
</cmod>
</helpers>
<events>
<sales_order_place_after>
<observers>
<sales_order_place_after_observer>
<class>company_module/observer</class>
<method>handleOrder</method>
</sales_order_place_after_observer>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
Data.php - It is empty but it should be.
class Company_Module_Helper_Data extends Mage_Core_Helper_Abstract{
}
Observer.php
class Company_Module_Model_Observer{
public function handleOrder($observer){
$order = $observer->getEvent()->getOrder();
...
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('your_template');
$emailTemplateVariables = array();
$emailTemplateVariables['order'] = $order;
$emailTemplate->setSenderName('Your shops name');
$emailTemplate->setSenderEmail('addres#from.com');
$emailTemplate->setTemplateSubject(Subject');
$emailTemplate->send('to#addres.com','Name', $emailTemplateVariables);
}
}
#Jevgeni (and anyone else needing the link), the Link for Magento has moved
http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method

Resources