Getting Magento to send email when a payment is received - magento

I don't believe Magento has an out of box method of sending an email to inform the owner when a payment has been received so is there any way that this can be programmed?
So far I have read this but it looks like it might be more focused on sending the email to the customer instead of the vendor; and this but apart from being completely lost ( as by the sound of it was the OP ) one person said accepted answer was a bit out of date and also I'm not sure it's what I need anyway.

Basically, what you need is (surprise) an observer module to do exactly that. Also, it is quite the same work in one of the links you provided.
To make a barebones observer module, you only need three files:
/app/etc/modules/Electricjesus_Notifyowner.xml
<?xml version="1.0"?>
<config>
<modules>
<Electricjesus_Notifyowner>
<active>true</active>
<codePool>local</codePool>
</Electricjesus_Notifyowner >
</modules>
</config>
/app/code/local/Electricjesus/Notifyowner/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Electricjesus_Notifyowner>
<version>0.1.0</version>
</Electricjesus_Notifyowner>
</modules>
<global>
<models>
<notifyowner>
<class>Electricjesus_Notifyowner_Model</class>
</notifyowner>
</models>
<events>
<sales_order_payment_pay>
<observers>
<notifyOwnerEvent>
<class>notifyowner/observer</class>
<method>notifyOwnerEvent</method>
</notifyOwnerEvent>
</observers>
</sales_order_payment_pay >
</events>
</global>
</config>
/app/code/local/Electricjesus/Notifyowner/Model/Observer.php
<?php
class Electricjesus_Notifyowner_Model_Observer
{
public function notifyOwnerEvent($observer)
{
// parameters you can get from the $observer parameter:
// array(’payment’ ? $this, ‘invoice’ ? $invoice)
$payment = $observer->getPayment();
$invoice = $observer->getInvoice();
// derivative data
$order = $invoice->getOrder(); // Mage_Sales_Model_Order
$ownerEmail = 'owner#shop.com';
/*
- build data
- build email structure
- send email via any php mailer method you want
*/
return $this; // always return $this.
}
}
You can also use other events in place of sales_order_payment_pay (see config.xml). See this list for a semi-complete list of events along with their parameters. And on this document to is some techniques to check/get an update of the current list of events with their parameters.
I recommend using Zend_Mail to do your mail stuff inside the observer. Nothing special, I'm just biased towards Zend stuff.
http://framework.zend.com/manual/en/zend.mail.html
--- EDIT
if you want a ready-made extension to do this (and more) and if you do not mind paying for it, you can take a look at:
http://www.magentocommerce.com/magento-connect/admin-email-notifications.html

Related

Mage::getModel is returning false

I am trying to get to grips with calling and using models in magento.
My current task is to simply display a string held in a model by calling it from a controller.
When trying to call SimpleOutput.php I get an error message saying that a non object has been called. I have var_dumped it as you will see and it return false.
I have looked at my code and with my limited understanding of what I need to do in Magento I have everything correct. Obviously i'm missing something. Could someone please take a look and if it's a typo tell where to look and if it's more than a simple spelling mistake explain what ive missed and what I should have done and why?
My code is below
Ts/Firstmodule/etc/config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Ts_Firstmodule>
<version>0.1.0</version>
</Ts_Firstmodule>
</modules>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
<frontend>
<routers>
<firstmodule>
<use>standard</use>
<args>
<module>Ts_Firstmodule</module>
<frontName>firstmodule</frontName>
</args>
</firstmodule>
</routers>
</frontend>
</config>
Ts/Firstmodule/controllers/indexController.php
class Ts_Firstmodule_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
$simple = Mage::getModel('ts_firstmodule/simpleoutput');
var_dump($simple);
}
}
Ts/Firstmodule/model/simpleoutput.php
class Ts_Firstmodule_Model_SimpleOutput extends Mage_Core_Model_Abstract
{
public function basicText()
{
echo 'this is some text from the simple output model inside the basic text function';
}
}
You must wrap <models> in <global>, just like this :
<global>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
</global>
Don't hesitate to take a look at the source of the simpler core modules (eg, GoogleAnalytics), to see how they're done and understand the logic behind it.
Like always :
Mage::getModel('ts_firstmodule/simpleoutput');
When you do a getModel / getBlock / helper / etc
The first part of the parameter string is the XML node of the layer definied in the config.xml
The second part is the full path to your file from the layer folder container.
So, in your case : Mage::getModel('firstmodule/simpleoutput'); should load Ts/Firstmodule/Model/Simpleoutput.php
Note : be carefull of the case of your resources (take a look a standard magento for good practices) !
You should modify the config.xml file and add a <global> tag around your <models> tag:
<global>
<models>
<firstmodule>
<class>Ts_Firstmodule_Model</class>
</firstmodule>
</models>
<global>
After this, in order to instantiate a model use it like this:
Mage::getModel('firstmodule/simpleoutput')
The first part of the getModel method (up until /) should be the tag name you set in config.xml right under <models> tag. In your case firstmodule.

how we use product duplicate observer event at custom module?

This is my config.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : config.xml
Created on : July 26, 2012, 1:12 PM
Author : sanjeewani
Description:
Purpose of the document follows.
-->
<config>
<modules>
<Proporta_AmazonBarcode>
<version>0.1.0</version>
</Proporta_AmazonBarcode>
</modules>
<global>
<events>
<catalog_model_product_duplicate>
<observers>
<proporta_amazonbarcode_observer>
<class>Proporta_AmazonBarcode_Model_Observer</class>
<method>duplicate1</method>
</proporta_amazonbarcode_observer>
</observers>
</catalog_model_product_duplicate>
</events>
</global>
</config>
and this is my Observer class function.
public function duplicate1(Varien_Event_Observer $observer) {
$product=$observer->getEvent()->getProduct();
/*
my logic is here
*/
}
It's coming properly to duplicate1() function when I try to duplicate the product from admin.
My problem is, $product is null. I can't get product from event. Anyone have an issue like this?
It's because product is not a key of the event context. If you are unsure, what the context is, it's a good idea to look where the event is dispatched[1]. In this case in app/code/core/Mage/Catalog/Model/Product.php in the method Mage_Catalog_Model_Product::duplicate():
Mage::dispatchEvent(
'catalog_model_product_duplicate',
array('current_product' => $this, 'new_product' => $newProduct)
);
So, what you probably want to do is this:
$product = $observer->getEvent()->getCurrentProduct();
[1] or use a debugger, place a break point and inspect $observer
You have to put product ID , without ID , it wont work. When it comes to debugger , get HTTP Debugger , put BP , and observe response and everything that could look suspicious.

Magento - Convert a module using <rewrite> to use Events for the Sales > Order Grid

I've made a simple module that adds extra fields to the Sales > Order Grid. It works great but the problem is that another module we're using <rewrites> the order grid to add their field to the grid. I wanted to try to change it to use Events instead (besides, it's a better method)...
The issue is that I've been trying and trying and I just can't make it happen. (Maybe I just can't grasp the event/observer concept yet...)
Here is my current module structure:
app/code/local/Artizara/OrderGridAdditions/
app/code/local/Artizara/OrderGridAdditions/Block/Sales/Order/Grid.php
app/code/local/Artizara/OrderGridAdditions/etc/config.xml
app/code/local/Artizara/OrderGridAdditions/controllers [empty]
app/code/local/Artizara/OrderGridAdditions/Helper [empty]
app/code/local/Artizara/OrderGridAdditions/Model [empty]
Inside my Grid.php file, I have copied the main Grid.php file contents into my Grid.php file and edited the _getCollectionClass(), _prepareCollection() and _prepareColumns() functions.
I've changed the _getCollectionClass() to this:
//return 'sales/order_grid_collection';
return 'sales/order_collection';
I've changed the _prepareCollection() to this:
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->getSelect()->joinLeft(array('sfog' => 'sales_flat_order_grid'),'main_table.entity_id = sfog.entity_id',array('sfog.shipping_name','sfog.billing_name'));
$collection->getSelect()->joinLeft(array('sfo'=>'sales_flat_order'),'sfo.entity_id=main_table.entity_id',array('sfo.customer_email','sfo.weight','sfo.discount_description','sfo.increment_id','sfo.store_id','sfo.created_at','sfo.status','sfo.base_grand_total','sfo.grand_total','shipping_description','sfo.total_item_count'));
$collection->getSelect()->joinLeft(array('sfoa'=>'sales_flat_order_address'),'main_table.entity_id = sfoa.parent_id AND sfoa.address_type="shipping"',array('sfoa.street','sfoa.city','sfoa.region','sfoa.postcode','sfoa.telephone'));
//$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'),'main_table.entity_id = sfop.entity_id',array('sfop.method'));
$this->setCollection($collection);
return parent::_prepareCollection();
I've added columns to the _prepareColumns() like this (only added one here as example):
$this->addColumn('total_item_count', array(
'header' => Mage::helper('sales')->__('Total Items'),
'index' => 'total_item_count',
'filter_index' => 'sfo.total_item_count',
'width' => '50px',
));
In my config.xml file I have a simple <rewrite>:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>Artizara_OrderGridAdditions_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
<ordergridadditions>
<class>Artizara_OrderGridAdditions_Block</class>
</ordergridadditions>
</blocks>
</global>
Changing it over to Events/Observers
I've been trying a lot to change this up to a module that uses an Event but am hitting a wall with it. I've been trying to follow some other answers on here (the ones that are not rewrites, but they use a different method to add custom tables to the grid from the database). I'm looking to use the same setup I already have.
I've added /Helper/Data.php container that contains this:
class Artizara_OrderGridAdditions_Helper_Data extends Mage_Core_Helper_Abstract{ }
In /etc/config.xml I've tried many things. Here's my latest attempt:
<modules>
<Artizara_OrderGridAdditions>
<version>0.1.0</version>
</Artizara_OrderGridAdditions>
</modules>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<Artizara_OrderGridAdditions_Observer>
<class>Artizara_OrderGridAdditions_Model_Observer</class>
<method>addAdditionsToGrid</method>
</Artizara_OrderGridAdditions_Observer>
</observers>
</adminhtml_block_html_before>
</events>
</adminhtml>
<global>
<models>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Model</class>
</Artizara_OrderGridAdditions>
</models>
<blocks>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Block</class>
</Artizara_OrderGridAdditions>
</blocks>
<helper>
<Artizara_OrderGridAdditions>
<class>Artizara_OrderGridAdditions_Helper</class>
</Artizara_OrderGridAdditions>
</helper>
</global>
Then in /Model/Observer.php I have:
class Artizara_OrderGridAdditions_Model_Observer {
public function addAdditionsToGrid(Varien_Event_Observer $observer) {
// code here
}
}
Inside addAdditionsToGrid(), I've tried many different things including copying the entire Grid.php file but nothing seems to work (errors) :(
Please help guide me in remaking this simple module using Events please!
There is no (good) way to add a column to Sales Order Grid with Observers, because there is no event call. Take a look yourself for Mage::dispatchEvent inside Mage_Adminhtml_Block_Sales_Order_Grid and all superclasses.
I think the best practice is extend the grid class like this:
class Artizara_OrderGridAdditions_Block_Sales_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid {
protected function _prepareColumns() {
$this->addColumn(/* your definition here */);
}
}
If you really need do this by observers, you can watch the adminhtml_block_html_before event and dig a way out, but a lot of blocks will call this event either.

Custom observer not being triggered

I am trying to write an observer for magento that will be triggered when an order has been marked as shipped and has been given a tracking number.
When I go in through the admin and place an order, invoice and then go to ship the function I need to call is never actually called, and I do not understand why.
I have go through a couple of of pages on the magento website to see what I might be doing wrong, but I just cant figure it out (http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method & http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-2-the-magento-config).
Please note that I do see the module within the admin Advanced area and it is enabled.
If anyone could look over the code I have attached and let me know where my issue is, it would be much appreciated.
Here is my Observer class which is located in app/code/local/WR/TrackingEmail/Model/Observer.php
class WR_TrackingEmail_Model_Observer
{
public function sendTrackEmail($observer)
{
$track = $observer->getEvent()->getTrack();
$shipment = $track->getShipment(true);
$shipment->sendEmail();
}
}
Here is my config.xml for the module
<config>
<global>
<modules>
<wr_trackingemail>
<version>0.1.1</version>
</wr_trackingemail>
</modules>
<events>
<sales_order_shipment_track_save_after>
<observers>
<Wr_trackingemail_model_observer>
<type>singleton</type>
<class>WR_TrackingEmail_Model_Observer</class>
<method>sendTrackEmail</method>
</Wr_trackingemail_model_observer>
</observers>
</sales_order_shipment_track_save_after>
</events>
</global>
</config>
Here is my app/etc/modules/WR_TrackingEmail.xml
<config>
<modules>
<WR_TrackingEmail>
<active>true</active>
<codePool>local</codePool>
</WR_TrackingEmail>
</modules>
</config>
Your statement "Custom observer not being triggered" leaves a lot of room for interpretation. Here's what you'll want to check.
Your observer appears to be setup correctly (although the modules tag belongs outside the global tag, but that doesn't appear to matter for this case). You can test your setup by running the following code yourself from a blank controller action (or other bootstrapped, event loaded, Magento script)
Mage::dispatchEvent('sales_order_shipment_track_save_after');
and then replacing your sendTrackEmail with this
public function sendTrackEmail($observer)
{
exit(__METHOD__);
}
If execution halts with the text
WR_TrackingEmail_Model_Observer::sendTrackEmail
you'll know your event is configured correctly.
If your event IS configured correctly, the next step is to ensure that the event is actually being fired when you perform the steps above. You can log these events in app/Mage.php by adding this temporary logging code
public static function dispatchEvent($name, array $data = array())
{
//brain dead logging
file_put_contents('/tmp/events.log',"$name\n",FILE_APPEND);
Varien_Profiler::start('DISPATCH EVENT:'.$name);
$result = self::app()->dispatchEvent($name, $data);
#$result = self::registry('events')->dispatch($name, $data);
Varien_Profiler::stop('DISPATCH EVENT:'.$name);
return $result;
}
Also, there's a good chance that leaving your exit in above will still result in execution halting if your event is being fired.
If you've determined your observer is configured correctly, AND your event is being fired, then the problem isn't an event being triggered, but your observer code not doing what you think its doing. Re-add your code but keep your exit in place
class WR_TrackingEmail_Model_Observer
{
public function sendTrackEmail($observer)
{
$track = $observer->getEvent()->getTrack();
$shipment = $track->getShipment(true);
$shipment->sendEmail();
exit(__METHOD__);
}
}
This will allow you to reload the browser over and over again to test your observer code. Good luck!
Have you registered your module under app/etc/modules/ in a .xml file?
<?xml version="1.0"?>
<config>
<modules>
<Wr_Trackingemail>
<active>true</active>
<codePool>local</codePool>
</Wr_Trackingemail>
</modules>
</config>

Magento Products Comparison limit

I need to limit the number of products added to compare in Magento. Only wanted to have a maximum of 4 products to be compared.
I'm thinking of doing it in the .phtml (where item display looping is) but have no idea where I should edit to display the message "Compare list is full". Any idea?
Thanks!
I've hooked to the catalog_product_compare_add_product event.
Here is my solution:
Create module.
Directories:
app/code/local/Company //this can be any name
app/code/local/Company/Catalog
app/code/local/Company/Catalog/Helper
app/code/local/Company/Catalog/etc
Module config
Create a file: app/code/local/Company/Catalog/etc/config.xml
File contents:
<?xml version="1.0"?>
<config>
<modules>
<Company_Catalog>
<version>0.1</version>
</Company_Catalog>
</modules>
<frontend>
<events>
<catalog_product_compare_add_product>
<observers>
<company_catalog>
<type>singleton</type>
<class>Company_Catalog_Helper_Observer</class>
<method>limitProductCompare</method>
</company_catalog>
</observers>
</catalog_product_compare_add_product>
</events>
</frontend>
</config>
Helper
Create a file: app/code/local/Company/Catalog/Helper/Observer.php
File contents:
<?php
class Company_Catalog_Helper_Observer extends Mage_Catalog_Helper_Data {
const COMPARE_LIMIT = 4;
function limitProductCompare($event) {
if (Mage::helper('catalog/product_compare')->getItemCount()<self::COMPARE_LIMIT) return;
$session = Mage::getSingleton('catalog/session');
Mage::getSingleton('catalog/product_compare_list')->removeProduct($event->getProduct());
$session->getMessages()->clear();
$session->addNotice($this->__('You have reached the limit of products to compare. Remove one and try again.'));
}
}
Enable module
Create file: app/etc/modules/Company_Catalog.xml
File contents:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Company_Catalog>
<active>true</active>
<codePool>local</codePool>
</Company_Catalog>
</modules>
</config>
Profit!
Everything should work fine now. After adding, 5th product gets removed, and nice notice is displayed. Its not the perfect solution (since it removes a product after it was added), but it does the job well.
compare items are added in Mage_Catalog_Product_CompareController and you can see that there are events dispatched that you can hook your observer to or you can add your limits by extending Mage_Catalog_Model_Product_Compare_List and overriding addProduct() or addProducts() methods or even make this in collection classes

Resources