I have created an event observer that will send email on order completion.
I am sending email to email_address1 when a product is ordered from the category1 and sending email to email_address2 when a product is ordered from the cateogory2. Therefore I have created an observer event for this.
But when I click on the "Place Order" button nothing happens. What is the problem?
in magento/app/etc/modules/Custom_Email.xml:
<?xml version="1.0"?>
<config>
<modules>
<Custom_Email>
<codePool>local</codePool>
<active>true</active>
</Custom_Email>
</modules>
</config>
in magento/app/code/local/Custom/Email/etc/config.xml:
<?xml version="1.0"?>
<config>
<global>
<models>
<customemail>
<class>Custom_Email_Model</class>
</customemail>
</models>
<events>
<sales_order_place_after>
<observers>
<custom_email_order_observer>
<type>singleton</type>
<class>customemail/order_observer</class>
<method>sendOrder</method>
</custom_email_order_observer>
</observers>
</sales_order_place_after>
</events>
</global>
</config>
in magento/app/code/local/Custom/Email/Model/Order/Observer.php:
<?php
class Custom_Email_Model_Order_Observer
{
public function __contruct()
{
}
/**
* Exports new orders to an xml file
* #param Varien_Event_Observer $observer
* #return Feed_Sales_Model_Order_Observer
*/
public function sendOrder($observer){
$order = $observer->getEvent()->getOrder();
$cat_id = Mage::getModel('catalog/layer')->getCurrentCategory()->getId();
echo $cat_id;
//Implement logic here
...
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('rehab');
$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);
echo 'email sent';
}
}
?>
So any one know where is the problem?
The layer does not exist in the order context, nor is the category from which the product was selected available as a property of quote or order items. It's a known deficiency in Magento which unfortunately limits segmentation.
Related
I have been pulling my hair out over trying to get a hole punched out for the price block on the product page. I have looked at numerous sources, including some from you good people at stackoverflow, but I have been getting a fatal error, so something is incorrect. Here are some sources that I used:
http://invisiblezero.net/magento-ee-punch-hole-in-full-page-cache/
http://www.kingletas.com/2012/09/how-does-magento-full-page-cache-works.html
Magento full page cache
Trying get dynamic content hole-punched through Magento's Full Page Cache
How to implement magento cache hole punching for shopping cart block
As you can see, I have been all over, and I have read more in addition to this but some of them conflict a litt, and I think that is where I have my issue, now let me post some code for you.
cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<placeholders>
<SpecialPrice>
<block>catalog/product_price</block>
<name>product.pricing</name>
<placeholder>CATALOG_PRODUCT_PRICE</placeholder>
<container>MyStore_SpecialPrice_Model_Container_Cache</container>
<cache_lifetime>8640</cache_lifetime>
</SpecialPrice>
</placeholders>
</config>
cache.php
<?php
class MyStore_SpecialPrice_Model_Container_Cache extends Enterprise_PageCache_Model_Container_Abstract
{
/**
* Get customer identifier from cookies
*
* #return string
*/
protected function _getIdentifier()
{
return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}
/**
* Get cache identifier
*
* #return string
*/
protected function _getCacheId()
{
return 'CATALOG_PRODUCT_PRICE' . md5($this->_placeholder->getAttribute('cache_id') . $this->_getIdentifier());
}
/**
* Render block content
*
* #return string
*/
protected function _renderBlock()
{
$blockClass = $this->_placeholder->getAttribute('block');
$template = $this->_placeholder->getAttribute('template');
$block = new $blockClass;
$block->setTemplate($template);
return $block->toHtml();
}
}
congig.xml
<?xml version="1.0"?>
<config>
<modules>
<MyStore_SpecialPrice>
<version>0.1.0</version>
</MyStore_SpecialPrice>
</modules>
<frontend>
<events>
<catalog_product_get_final_price>
<observers>
<MyStore_SpecialPrice_Model_Observer>
<class>MyStore_SpecialPrice_Model_Observer</class>
<method>setSpecialPrice</method>
</MyStore_SpecialPrice_Model_Observer>
</observers>
</catalog_product_get_final_price>
</events>
</frontend>
<admin>
<routers>
<SpecialPrice>
<use>admin</use>
<args>
<module>MyStore_SpecialPrice</module>
<frontName>SpecialPrice</frontName>
</args>
</SpecialPrice>
</routers>
</admin>
<global>
<models>
<SpecialPrice>
<class>MyStore_SpecialPrice_Model</class>
</SpecialPrice>
</models>
</global>
</config>
snippet from local.xml
<reference name="right">
<block type="catalog/product_price" name="product.pricing" template="catalog/product/product-price-block.phtml" before="-" >
Let me know if there is anything that jumps out to you.
I have created custom checkout_cart_save_before observer in magento by create the following files
app/etc/modules/Cart_Override.xml
<?xml version="1.0"?>
<config>
<modules>
<Cart_Override>
<codePool>local</codePool>
<active>true</active>
<depends>
<Mage_Contacts />
</depends>
</Cart_Override>
</modules>
</config>
app/code/local/Cart/Override/etc/config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<cartoverride>
<class>Cart_Override_Model</class>
</cartoverride>
</models>
<events>
<checkout_cart_save_before>
<observers>
<cart_override_qty_observer>
<type>singleton</type>
<class>Cart_Override_Model_Qtyc_Observer</class>
<method>checkout_cart_save_before</method>
</cart_override_qty_observer>
</observers>
</checkout_cart_save_before>
</events>
</global>
</config>
and app/code/local/Cart/Override/Model/Qtyc/Observer.php
class Cart_Override_Model_Qtyc_Observer extends Varien_Event_Observer
{
public function checkout_cart_save_before($observer)
{
$action = Mage::app()->getFrontController()->getAction();
$product = $observer->getProduct();
echo "<pre>";
print_r($product);
echo "</pre>";
die();
}
}
The observer is working fine, when i click the add to cart button it is going to checkout_cart_save_before function. But i could not get the product values from the observer using the following code inside the checkout_cart_save_before function
$product = $observer->getProduct();
I have to add something for get the product details from the observer parameter?....any guess??
Have a look at Mage_Checkout_Model_Cart::save() where the event is dispatched:
Mage::dispatchEvent('checkout_cart_save_before', array('cart'=>$this));
You can access the cart data with $cart = $observer->getEvent()->getCart(); and the quote items with $cart->getItems().
I'm pretty new to Magento, and having problems trying to set a custom shipping method programmatically. I'm converting an xml from a thrid party into an order, and everything else (that I've worked on so far) is working fine. Also I'm having problems spelling "programmatically" but I won't ask for you help with that.
I set up my custom shipping method as follows:
To activate the shipping module in
app/etc/modules/Extension_Shipping.xml
<?xml version=
"1.0"?>
<config>
<modules>
<Extension_Shipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Shipping/>
</depends>
</Extension_Shipping>
</modules>
</config>
then to configure it in
app/code/local/Extension/Shipping/etc/config.xml
<?xml version=
"1.0" ?>
<config>
<modules>
<Extension_Shipping>
<version>0.1.0</version>
</Extension_Shipping>
</modules>
<global>
<models>
<extension_shipping>
<class>Extension_Shipping_Model</class>
</extension_shipping>
</models>
</global>
<default>
<carriers>
<extension_myrate>
<active>1</active>
<model>extension_shipping/carrier_myrate</model>
<title>Extension Shipping</title>
<name>Default Rate</name>
</extension_myrate>
</carriers>
</default>
</config>
then to add the class in
app/code/local/Extension/Shipping/Model/Carrier/MyRate.php
<?php
class Extension_Shipping_Model_Carrier_MyRate
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
{
protected $_code = 'extension_myrate';
protected $_isFixed = true;
public function collectRates(Mage_Shipping_Model_Rate_Request
$request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
$result = Mage::getModel('shipping/rate_result');
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('extension_myrate');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('extension_myrate');
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice(5);
$method->setCost(2);
$result->append($method);
return $result;
}
public function getAllowedMethods()
{
return array('extension_myrate' => $this->getConfigData('name'));
}
}
Basically I followed http://www.magentotricks.com/creating-a-customer-magento-shipping-method/
I thought it all worked fine, as the shipping method now shows up in the checkout screen, and can be set both by customers or in the admin "create new order." However, I'm not able to set it programmatically.
In my controller I'm trying to set the shipping method using the code
$shippingAddress = $quote->getShippingAddress()->addData($addressData);
$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('extension_myrate')
->setPaymentMethod('checkmo');
To add to my confusion, it worked once. but only once out of quite a few test orders. changing the "setShippingMethod" to "freeshipping_freeshipping" or "flatrate_flatrate" makes it update the shipping to those correctly. because of that and because I'm new and still having problems with the file structure, I'm guessing my problem is with setShippingMethod('extension_myrate') but I'm not entirely sure. Any advice would be helpful and appreciated.
Im trying to call an Observer after the order has been created, and AFTER payment has been captured.
So far I've tried;
checkout_submit_all_after,
sales_order_payment_place_end,
sales_order_place_after,
sales_order_payment_pay,
sales_order_payment_capture,
sales_order_payment_transaction_save_after
Just to name the main ones.
I've also logged all Event Dispaches inside dispatchEvent() but found nothing that stands out and is only fired when i need it.
the issue i'm having is that the status of the order is always ether 'Payment Pending' or something that predated this; meaning that i don't know whether the order will fail or succeed.
My aim, is to fire a function only on successful orders.
thanks.
after much more testing i found the following Observer to do the trick;
checkout_onepage_controller_success_action
This returns just the order id, so;
$order_id = $observer->getData('order_ids');
$order = Mage::getModel('sales/order')->load($order_id);
and you see that the order status is 'processing' and the payment is aproved (or not).
1 ) here is custom config.xml for call observer file
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Modulename>
<version>0.1.0</version>
</Namespace_Modulename>
</modules>
<frontend>
<events>
<checkout_submit_all_after>
<observers>
<Namespace_Modulename_Customevent>
<type>singleton</type>
<class>Namespace_Modulename_Model_Observer</class>
<method>customFunction</method>
</Namespace_Modulename_Customevent>
</observers>
</checkout_submit_all_after>
</events>
</frontend>
</config>
2 ) create observer.php file inside your module/Model directory and paste this code
<?php
class Namespace_Modulename_Model_Observer
{
public function customFunction(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
//here you can add your custom code
}
}
please try this.. sure it will help you !
I have also tried all event but didn't get success. Then I moved to override Mage OnePageController and called my custom function. Below is the code to override onestep checkout.
app\etc\modules\Namespace_Module.xml
<Namespace_Checkout>
<active>true</active>
<codePool>local</codePool>
</Namespace_Checkout>
app\code\local\Namespace\Checkout\etc\config.xml
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Checkout>
<version>0.1.0</version>
</Namespace_Checkout>
</modules>
<frontend>
<routers>
<checkout>
<args>
<modules>
<Namespace_Checkout before="Mage_OneStepCheckout">Namespace_Checkout</Namespace_Checkout>
</modules>
</args>
</checkout>
</routers>
</frontend>
</config>
app\code\local\Namespace\Checkout\controllers\OnepageController.php
<?php
require_once 'Mage/Checkout/controllers/OnepageController.php';
class Namespace_Checkout_OnepageController extends Mage_Checkout_OnepageController{
public function successAction(){
$session = $this->getOnepage()->getCheckout();
if (!$session->getLastSuccessQuoteId()) {
$this->_redirect('checkout/cart');
return;
}
$lastQuoteId = $session->getLastQuoteId();
$lastOrderId = $session->getLastOrderId();
$lastRecurringProfiles = $session->getLastRecurringProfileIds();
if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
$this->_redirect('checkout/cart');
return;
}
$this->customFunction(); // Custom function to call
$session->clear();
$this->loadLayout();
$this->_initLayoutMessages('checkout/session');
Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
$this->renderLayout();
}
function customFunction(){
// This function is calling before clearing order session
//Here you can put all your custom code
}
}
?>
In the above controller, I have added customFunction() wher you can put your custom code.
Hope it will help you!
In order to develop an automated order status changer based on payment method and event type, I created the following module:
/GT/OrderFlo/etc/config.xml
<!--?xml version="1.0"?-->
<config>
<modules>
<gt_orderflow>
<version>1.0</version>
</gt_orderflow>
</modules>
<global>
<models>
<orderflow>
<class>GT_OrderFlow_Model</class>
</orderhook>
</models>
<events>
<sales_order_place_after>
<observers>
<order_payment_pending_autostatus>
<type>singleton</type>
<class>orderflow/observer</class>
<method>implementOrderStatus</method>
</order_payment_pending_autostatus>
</observers>
</sales_order_place_after>
<sales_order_shipment_save_after>
<observers>
<order_invoice_pending_autostatus>
<type>singleton</type>
<class>orderflow/observer</class>
<method>implementOrderStatus</method>
</order_invoice_pending_autostatus>
</observers>
</sales_order_shipment_save_after>
<sales_order_invoice_save_commit_after>
<observers>
<order_complete_autostatus>
<type>singleton</type>
<class>orderflow/observer</class>
<method>implementOrderStatus</method>
</order_complete_autostatus>
</observers>
</sales_order_invoice_save_commit_after>
</events>
</global>
</config>
/GT/OrderFlow/Model/Observer.php
class GT_OrderFlow_Model_Observer
{
public function implementOrderStatus($event)
{
$order = $event->getOrder();
$payment_method = $this->_getPaymentMethod($order);
$this->_log('In implementOrderStatus with payment method: '.$payment_method);
Mage::log('In implementOrderStatus with payment method: '.$payment_method);
$next_status = "";
return $this;
}
private function _getPaymentMethod($order)
{
return $order->getPayment()->getMethodInstance()->getCode();
}
private function _log($message)
{
return Mage::log($message, null, 'gt_orderflow.log');
}
}
The code was replicated from http://www.atwix.com/magento/auto-invoice-and-custom-order-status-upon-checkout/.
But how can I get it to fire the observer after sales_order_place_after event?
Is your module loaded at all? You will need a file in /app/etc/modules. On a related note, I see that you refer to your module as <gt_orderflow> but the class prefix is GT_OrderFlow. On a case sensitive filesystem, this is important and will not work this way. The nodes under config/modules are mapped to the module path.
I think you have a typo
<models>
<orderflow>
-----^
<class>GT_OrderFlow_Model</class>
</orderhook>
-----^
</models>