I'm using Magento 1.9.1 and i'm trying to create a module which is giving a 50% discount from the grand total.
Here is my code:
/app/code/local/VivasIndustries/PercentPayment/etc/config.xml :
<?xml version="1.0"?>
<config>
<modules>
<VivasIndustries_PercentPayment>
<version>0.1.0</version>
</VivasIndustries_PercentPayment>
</modules>
<global>
<sales>
<quote>
<totals>
<discount>
<class>VivasIndustries_PercentPayment_Model_Discount</class>
<after>subtotal</after>
</discount>
</totals>
</quote>
<order_invoice>
<totals>
<discount>
<class>VivasIndustries_PercentPayment_Model_Invoice</class>
<after>subtotal</after>
</discount>
</totals>
</order_invoice>
<order_creditmemo>
<totals>
<discount>
<class>VivasIndustries_PercentPayment_Model_Creditmemo</class>
<after>subtotal</after>
</discount>
</totals>
</order_creditmemo>
</sales>
</global>
</config>
/app/code/local/VivasIndustries/PercentPayment/controllers/IndexController.php :
<?PHP
class VivasIndustries_PercentPayment_Model_Discount extends Mage_Sales_Model_Quote_Address_Total_Abstract {
public function collect(Mage_Sales_Model_Quote_Address $address) {
if ($address->getData('address_type') == 'billing')
return $this;
$discount = 50; //your discount percent
$grandTotal = $address->getGrandTotal();
$baseGrandTotal = $address->getBaseGrandTotal();
$totals = array_sum($address->getAllTotalAmounts());
$baseTotals = array_sum($address->getAllBaseTotalAmounts());
$address->setFeeAmount(-$totals * $discount / 100);
$address->setBaseFeeAmount(-$baseTotals * $discount / 100);
$address->setGrandTotal($grandTotal + $address->getFeeAmount());
$address->setBaseGrandTotal($baseGrandTotal + $address->getBaseFeeAmount());
return $this;
}
public function fetch(Mage_Sales_Model_Quote_Address $address) {
if ($address->getData('address_type') == 'billing')
return $this;
$amt = $address->getDiscountAmount();
if ($amt != 0) {
$address->addTotal(array(
'code' => 'Discount',
'title' => 'Discount',
'value' => $amt
));
}
return $address;
}
}
?>
/app/etc/modules/VivasIndustries_PercentPayment.xml :
<?xml version="1.0"?>
<config>
<modules>
<VivasIndustries_PercentPayment>
<active>true</active>
<codePool>local</codePool>
</VivasIndustries_PercentPayment>
</modules>
</config>
This are all files which i've created for my new module. All what i've done.
I was using this guide: http://magento.ikantam.com/qa/how-add-discount-total-magento
Now when i try to open my checkout page i got error - There has been an error processing your request
When i open my error_log i can see this thing:
[09-Nov-2014 18:22:35 UTC] CSRF state token does not match one provided.
Can you please help me fix this problem and make my new Module works like intended ?
Thanks in advance!
Modifying total is always difficult part. And it's hard find out the problem in your code unless I have set up of that module in my system. Anyway here I have shared some codes for modifying total during checkout process. I explained as much I can.
For this you have to update lot of things. Quote, Address, Order, Creditmemo , Invoice, shipping, multi shipping etc. Okay here we go,
First we need to create our configuration file that's called config.xml,
config.xml
Update:
<config>
<modules>
<VivasIndustries_PercentPayment>
<version>0.1.0</version>
</VivasIndustries_PercentPayment>
</modules>
<global>
<helpers>
<percentpayment>
<class>VivasIndustries_PercentPayment_Helper</class>
</percentpayment>
</helpers>
<models>
<percentpayment>
<class>VivasIndustries_PercentPayment_Model</class>
<resourceModel>percentpayment_mysql4</resourceModel>
</percentpayment>
</models>
<resources>
<salesattribute1416562342_setup>
<setup>
<module>VivasIndustries_PercentPayment</module>
<class>Mage_Sales_Model_Mysql4_Setup</class>
</setup>
<connection>
<use>core_setup</use>
</connection>
</salesattribute1416562342_setup>
<salesattribute1416562342_write>
<connection>
<use>core_write</use>
</connection>
</salesattribute1416562342_write>
<salesattribute1416562342_read>
<connection>
<use>core_read</use>
</connection>
</salesattribute1416562342_read>
</resources>
<events>
<checkout_type_onepage_save_order_after> <!-- identifier of the event we want to catch -->
<observers>
<checkout_type_onepage_save_order_after_discount_handler> <!-- identifier of the event handler -->
<type>model</type> <!-- class method call type; valid are model, object and singleton -->
<class>percentpayment/newordertotalobserver</class> <!-- observers class alias -->
<method>saveDiscountTotal</method> <!-- observer's method to be called -->
<args></args> <!-- additional arguments passed to observer -->
</checkout_type_onepage_save_order_after_discount_handler>
</observers>
</checkout_type_onepage_save_order_after>
<checkout_type_multishipping_create_orders_single> <!-- identifier of the event we want to catch -->
<observers>
<checkout_type_multishipping_create_orders_single_discount_handler> <!-- identifier of the event handler -->
<type>model</type> <!-- class method call type; valid are model, object and singleton -->
<class>percentpayment/newordertotalobserver</class> <!-- observers class alias -->
<method>saveDiscountTotalForMultishipping</method> <!-- observer's method to be called -->
<args></args> <!-- additional arguments passed to observer -->
</checkout_type_multishipping_create_orders_single_discount_handler>
</observers>
</checkout_type_multishipping_create_orders_single>
</events>
<sales>
<quote>
<totals>
<discount_total>
<class>percentpayment/quote_address_total_discount</class>
<after>subtotal,freeshipping,tax_subtotal,shipping</after>
<before>grand_total</before>
</discount_total>
</totals>
</quote>
<order_invoice>
<totals>
<discount_total>
<class>percentpayment/order_invoice_total_discount</class>
<after>subtotal,freeshipping,tax_subtotal,shipping</after>
<before>grand_total</before>
</discount_total>
</totals>
</order_invoice>
<order_creditmemo>
<totals>
<discount_total>
<class>percentpayment/order_creditmemo_total_discount</class>
<after>subtotal,freeshipping,tax_subtotal,shipping</after>
<before>grand_total</before>
</discount_total>
</totals>
</order_creditmemo>
</sales>
</global>
</config>
change other things as per this configuration. before that go to your database using phpmyadmin open core_resources table. and delete your module entry if it is there. that's it.
Please comment here, if you have any doubt.
Related
I have custom module jewellery. Tabs used in the admin form in category edit. Below code is used to add tabs in the admin form. it give fatal error
Fatal error: Call to a member function toHtml() on a non-object in D:\wamp\www\avita\app\code\local\Mage\Adminhtml\Block\Catalog\Category\Tabs.php on line 158
Below are my files
1.) local/Mage/Adminhtml/Block/Catalog/Category/Tabs.php
$this->addTab('upload_prices', array(
'label' => Mage::helper('catalog')->__('Upload prices'),
'content' => $this->getLayout()->createBlock('jewellery/adminhtml_catalog_category_product_tab')->toHtml(),
));
2.app/code/local/Subora/Jewellery/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Subora_Jewellery>
<version>0.1.0</version>
</Subora_Jewellery>
</modules>
<global>
<models>
<jewellery>
<class>Subora_Jewellery_Model</class>
</jewellery>
</models>
<helpers>
<jewellery>
<class>Subora_Jewellery_Helper</class>
</jewellery>
</helpers>
<blocks>
<jewellery>
<class>Subora_Jewellery_Block</class>
</jewellery>
</blocks>
<resources>
<jewellery_setup>
<setup>
<module>Subora_Jewellery</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</jewellery_setup>
<jewellery_write>
<connection>
<use>core_write</use>
</connection>
</jewellery_write>
<jewellery_read>
<connection>
<use>core_read</use>
</connection>
</jewellery_read>
</resources>
</global>
<adminhtml>
<layout>
<updates>
<jewellery>
<file>jewellery.xml</file>
</jewellery>
</updates>
</layout>
<events>
<adminhtml_catalog_product_edit_prepare_form>
<observers>
<jewellery_product_edit_prepare_form>
<class>jewellery/observer</class>
<method>productEditPrepareForm</method>
</jewellery_product_edit_prepare_form>
</observers>
</adminhtml_catalog_product_edit_prepare_form>
<catalog_product_save_after>
<observers>
<jewellery_save_product_data>
<type>singleton</type>
<class>jewellery/observer</class>
<method>saveProductTabData</method>
</jewellery_save_product_data>
</observers>
</catalog_product_save_after>
<catalog_category_save_after>
<observers>
<jewellery_save_category_data>
<type>singleton</type>
<class>jewellery/observer</class>
<method>saveCategoryTabData</method>
</jewellery_save_category_data>
</observers>
</catalog_category_save_after>
</events>
</adminhtml>
</config>
3 app\design\frontend\base\default\layout\jewellery.xml
<?xml version="1.0"?>
<layout version="0.1.0">
<jewellery_adminhtml_jewellerybackend_index>
<reference name="content">
<block type="jewellery/adminhtml_jewellerybackend" name="jewellerybackend"/>
</reference>
</jewellery_adminhtml_jewellerybackend_index>
<jewellery_adminhtml_jewellerybackend_save>
<reference name="content">
<block type="jewellery/adminhtml_jewellerybackend_save" name="jewellerybackend_save" template="jewellery/jewellerybackend.phtml" />
</reference>
</jewellery_adminhtml_jewellerybackend_save>
<adminhtml_catalog_product_edit>
<reference name="product_tabs">
<action method="addTab">
<name>subora_jewellery_tab</name>
<block>jewellery/adminhtml_catalog_product_tab</block>
</action>
</reference>
</adminhtml_catalog_product_edit>
<adminhtml_catalog_product_new>
<reference name="product_tabs">
<action method="addTab">
<name>subora_jewellery_tab</name>
<block>jewellery/adminhtml_catalog_product_tab</block>
</action>
</reference>
</adminhtml_catalog_product_new>
</layout>
4.local\Subora\Jewellery\Block\Adminhtml\Catalog\Category\Product\Tab.php
<?php
class Subora_Jewellery_Block_Adminhtml_Catalog_Category_Product_Tab extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm() {
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('category_import_prices', array('legend'=>Mage::helper('catalog')->__('Import prices')));
$fieldset->addField('prices', 'file', array(
'label' => Mage::helper('catalog')->__('Prices file (CSV only)'),
'name'=> 'prices',
));
return parent::_prepareForm();
}
}
Now what to do i have tried but cant add tab??
The problem persists here
$this->getLayout()->createBlock('jewellery/adminhtml_catalog_category_product_tab')->toHtml();
toHtml() is calling in a non-object means, createBlock('jewellery/adminhtml_catalog_category_product_tab') is not working correctly. createBlock() is used to create a new block and add it to the layout. This function has 3 parameters.
type 2. name 3. attributes
you have specified type as jewellery/adminhtml_catalog_category_product_tab. SO magento will look for app/code/local/Subora/Jewellery/Block/Adminhtml/Catalog/Category/Product/Tab.php and the file should be properly declared.
Next, you need to specify a block name. It is necessary. Magento needs all blocks has unique names. Name is absent here.
Next parameter is attribute. It is optionnal. You can set a template by using this parameter. So you can try this code.
$this->getLayout()->createBlock(
'jewellery/adminhtml_catalog_category_product_tab',
'jewellery.tab',
array('template' => 'your/template.phtml') //if any
)->toHtml();
EDIT
First you need to ensure, your module is active or not. You can do this via admin. System > Configuration > Advanced. Check your module is active there.
Next thing is, your layout file is in wrong postion. jewellery.xml is an admin layout file. It should reside in app\design\adminhtml\default\default\layout\jewellery.xml instead of app\design\frontend\base\default\layout\jewellery.xml
I'm trying to create new product type in magento and it is showing up in admin panel create new product page's product type options, but when I select it and continue, i get fatal error:
Fatal error: Call to a member function setConfig() on a non-object in
/home/shop/public_html/shop/app/code/core/Mage/Catalog/Model/Product/Type.php
on line 82
Line 82 is:
$typeModel->setConfig($types[$typeId]);
Module config file (app/code/local/Pood/Toodep6hi/etc/config.xml):
<?xml version="1.0"?>
<config>
<modules>
<Pood_Toodep6hi>
<version>0.1.0</version>
</Pood_Toodep6hi>
</modules>
<adminhtml>
<translate>
<modules>
<Pood_Toodep6hi>
<files>
<default>Pood_Toodep6hi.csv</default>
</files>
</Pood_Toodep6hi>
</modules>
</translate>
</adminhtml>
<global>
<models>
<Toodep6hi>
<class>Pood_Toodep6hi_Model</class>
</Toodep6hi>
</models>
<catalog>
<product>
<type>
<p6hitoode translate="label" module="Toodep6hi">
<label>Pohitoode</label>
<model>Toodep6hi/Product_Type_P6hitoode</model>
<price_model>Toodep6hi/Product_Price</price_model>
<index_data_retreiver>Toodep6hi/catalogIndex_Data_P6hitoode</index_data_retreiver>
<is_qty>1</is_qty>
</p6hitoode>
</type>
</product>
</catalog>
<helpers>
<Toodep6hi>
<class>Pood_Toodep6hi_Helper</class>
</Toodep6hi>
</helpers>
</global>
</config>
app/code/local/Pood/Model/Product/Type/P6hitoode.php:
<?php
class Pood_Toodep6hi_Model_Product_Type_P6hitoode extends Mage_Catalog_Model_Toodep6hi_Type_Abstract
{
const TYPE_P6HITOODE = "p6hitoode";
public function isVirtual()
{
return true;
}
}
I found a sililar problem: http://www.magentocommerce.com/boards/viewthread/196886/#t248371, but it did not help.
Every bit of help would be very appreciated.
Thank you!
the problem is case sensititve
<model>Toodep6hi/product_type_p6hitoode</model>
it should be
<model>toodep6hi/product_type_p6hitoode</model>
Try to extend Mage_Catalog_Model_Toodep6hi_Type_Abstract from Mage_Catalog_Model_Product_Type_Virtual
Use lower case here:
<model>Toodep6hi/Product_Type_P6hitoode</model>
so it will be:
<model>Toodep6hi/product_type_p6hitoode</model>
If will not help, try to use lower case for model:
<models>
<toodep6hi>
<class>Pood_Toodep6hi_Model</class>
</toodep6hi>
</models>
and lower case here then
<model>toodep6hi/product_type_p6hitoode</model>
Try this
<type>
<p6hitoode translate="label" module="Toodep6hi">
<label>Pohitoode</label>
<model>Toodep6hi/product_type_p6hitoode</model>
<price_model>Toodep6hi/product_price</price_model>
<index_data_retreiver>Toodep6hi/catalogIndex_data_p6hitoode</index_data_retreiver>
<is_qty>1</is_qty>
</p6hitoode>
</type>
Following this post I've finally managed to capture an event by extending the Magento_Adminhtml_Controller_Action and carry out some actions before it. But now I'm trying to improve it so I can capture another event triggered on the admin panel and from there pass an array through the request variable to another event on the frontend. I've these SO questions/answers, here and here but no way I can achieve what I need. I've tested the observer code using die() to be sure that the execution thread goes into the correct call and it is ok. I'm using the CommerceBug from AlanStorm, in case it can be used to get some light on this issue.
This is my Observer.php code.
<?php
class Dts_Videotestimonials_Model_Observer {
public function hookToAdminhtmlControllerActionPreDispatch($observer)
{
if($observer->getEvent()->getControllerAction()->getFullActionName() == 'videotestimonials_adminhtml_videotestimonialsbackend_post')
{
// dispatching our own event before action upload video is run and sending parameters we need
Mage::dispatchEvent("upload_video_before", array('request' => $observer->getControllerAction()->getRequest()));
}
}
public function hookToUploadVideoBefore($observer)
{
//Hooking to our own event
$request = $observer->getEvent()->getRequest()->getParams();
// do something with product
$user = Mage::getSingleton('admin/session');
$userName = $user->getUser()->getFirstname();
$userEmail = $user->getUser()->getEmail();
$request['product_id'] = "16"; #$_product->getId(),
$request['author_email'] = $userEmail;
$request['author_name'] = $userName;
$request['video_link'] = "http://www.youtube.com/watch?v=y435u6kfExA&feature=youtube_gdata_player";
$request['video_type'] = "link";
$request['title'] = "AT&T Phone Nokia 2610";
$request['comment'] = "this is a comment";
Mage::dispatchEvent("vidtest_youtube_post", $request);
}
}
EDITED:
Here is the full config.xml
<?xml version="1.0"?>
<config>
<modules>
<Dts_Videotestimonials>
<version>0.1.0</version>
</Dts_Videotestimonials>
</modules>
<global>
<models>
<videotestimonials>
<class>Dts_Videotestimonials_Model</class>
<resourceModel>videotestimonials_mysql4</resourceModel>
</videotestimonials>
</models>
<events>
<controller_action_predispatch>
<observers>
<controller_action_before>
<type>singleton</type>
<class>videotestimonials/observer</class>
<method>hookToAdminhtmlControllerActionPreDispatch</method>
</controller_action_before>
</observers>
</controller_action_predispatch>
<upload_video_before>
<observers>
<upload_video_before>
<type>singleton</type>
<class>videotestimonials/observer</class>
<method>hookToUploadVideoBefore</method>
</upload_video_before>
</observers>
</upload_video_before>
</events>
<helpers>
<videotestimonials>
<class>Dts_Videotestimonials_Helper</class>
</videotestimonials>
</helpers>
<blocks>
<videotestimonials>
<class>Dts_Videotestimonials_Block</class>
</videotestimonials>
</blocks>
</global>
<admin>
<routers>
<videotestimonials>
<use>admin</use>
<args>
<module>Dts_Videotestimonials</module>
<frontName>videotestimonials</frontName>
</args>
</videotestimonials>
</routers>
</admin>
<adminhtml>
<menu>
<videotestimonials module="videotestimonials">
<title>Videotestimonials</title>
<sort_order>100</sort_order>
<children>
<videotestimonialsbackend module="videotestimonials">
<title>VideoTestimonials_Admin</title>
<sort_order>0</sort_order>
<action>videotestimonials/adminhtml_videotestimonialsbackend</action>
</videotestimonialsbackend>
<pending_video translate="title">
<title>Videos pendientes</title>
<sort_order>20</sort_order>
<action>videotestimonials/adminhtml_pendingvideos/pending</action>
</pending_video>
</children>
</videotestimonials>
</menu>
<acl>
<resources>
<all>
<title>Allow Everything</title>
</all>
<admin>
<children>
<videotestimonials translate="title" module="videotestimonials">
<title>Videotestimonials</title>
<sort_order>1000</sort_order>
<children>
<videotestimonialsbackend translate="title">
<title>VideoTestimonials_Admin</title>
</videotestimonialsbackend>
<pending_video translate="title">
<title>Videos pendientes</title>
<sort_order>20</sort_order>
</pending_video>
</children>
</videotestimonials>
</children>
</admin>
</resources>
</acl>
<layout>
<updates>
<videotestimonials>
<file>videotestimonials.xml</file>
</videotestimonials>
</updates>
</layout>
</adminhtml>
<crontab>
<jobs>
<videotestimonials_videotestimonialscron>
<schedule><cron_expr>59 0 * */1 0</cron_expr></schedule>
<run><model>videotestimonials/cron::VideoTestimonialscron</model></run>
</videotestimonials_videotestimonialscron>
</jobs>
</crontab>
</config>
Here is what is happening. Your configuration of the admin controller is wrong. The proper way to include your controller in the admin section is this (you'll need to change out the module name, to match yours):
<?xml version="1.0" ?>
<config>
<modules>
<Video_Awesome>
<version>0.0.1</version>
</Video_Awesome>
</modules>
<global>
<models>
<Video_Awesome>
<class>Video_Awesome_Model</class>
<!-- No resource model used currently -->
</Video_Awesome>
</models>
<events>
<controller_action_predispatch>
<observers>
<controller_action_before>
<type>singleton</type>
<class>Video_Awesome/Observer</class>
<method>controllerActionPredispatch</method>
</controller_action_before>
</observers>
</controller_action_predispatch>
<upload_video_before>
<observers>
<Video_Awesome>
<type>singleton</type>
<class>Video_Awesome/Observer</class>
<method>uploadVideoBefore</method>
</Video_Awesome>
</observers>
</upload_video_before>
</events>
</global>
<admin>
<routers>
<adminhtml>
<!-- we are not creating our own router, but tapping into the adminhtml router -->
<args>
<modules>
<!-- Your module name, and then
the path to the controller (minus
the controllers folder name). So,
in this instance, I put the router
in a "Adminhtml" folder inside of
the controllers folder, like thus:
Video/Awesome/controllers/Adminhtml/videotestimonialsController.php -->
<Video_Awesome before="Mage_Adminhtml">Video_Awesome_Adminhtml</Video_Awesome>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
And, then, in your router (you don't need to call getEvent before getting the controller action):
public function controllerActionPredispatch ($observer)
{
if($observer->getControllerAction()->getFullActionName() == 'adminhtml_videotestimonials_post') {
// dispatching our own event before action upload video is run and sending parameters we need
Mage::dispatchEvent("upload_video_before", array('request' => $observer->getControllerAction()->getRequest()));
}
}
And finally, it doesn't sound as if you have a debugging setup for your Magento development. I would highly recommend one. I use PHPStorm (I don't have any stake in the company - this is not an advertisement :), and it works awesome. Set a breakpoint there to see if what the variables are.
I would also recommend using adminhtml_controller_action_predispatch_start, instead of the global controller_action_predispatch, as it will only trigger in the backend (a very, very small performance difference).
Also, as a small sidenote, I saw in your config.xml, that you were specifying menu items/acl there. You probably didn't know, but that is deprecated functionality, and those items should be put it adminhtml.xml.
I have a situation where the customer wants the special price to be rounded to the nearest whole number (Example: 1922.25 => 1922.00, 1256.85 => 1257.00)
This should be only for Special prices says the customer which means, if there's no special price for the product, the price should come as it is.
Note this is not only for display. This rule applies everywhere, even invoices. So is there a way to do this easily or we should only modify the core files?
EDIT
If we modify the core framework files like Product.php or Price.php, they will get overwritten with an update right? So this should be a safe way too preferably.
This is pretty easy.
Just observe catalog_product_load_after event, and overwrite special_price with a rounded value.
Create a bootstrap file for your module:
app/etc/modules/Danslo_RoundSpecialPrice.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Danslo_RoundSpecialPrice>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Catalog />
</depends>
</Danslo_RoundSpecialPrice>
</modules>
</config>
Specify that we want to observe the product load event:
app/code/local/Danslo/RoundSpecialPrice/etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<global>
<models>
<roundspecialprice>
<class>Danslo_RoundSpecialPrice_Model</class>
</roundspecialprice>
</models>
<events>
<catalog_product_load_after>
<observers>
<round_special_price>
<class>roundspecialprice/observer</class>
<type>singleton</type>
<method>roundSpecialPrice</method>
</round_special_price>
</observers>
</catalog_product_load_after>
<catalog_product_collection_load_after>
<observers>
<round_special_price>
<class>roundspecialprice/observer</class>
<type>singleton</type>
<method>roundSpecialPriceInCollection</method>
</round_special_price>
</observers>
</catalog_product_collection_load_after>
</events>
</global>
</config>
Then just write your observer implementation:
app/code/local/Danslo/RoundSpecialPrice/Model/Observer.php:
class Danslo_RoundSpecialPrice_Model_Observer
{
public function roundSpecialPrice($observer)
{
$product = $observer->getProduct();
if ($product->getSpecialPrice()) {
$product->setSpecialPrice(round($product->getSpecialPrice()));
}
}
public function roundSpecialPriceInCollection($observer)
{
foreach ($observer->getCollection() as $product) {
if ($product->getSpecialPrice()) {
$product->setSpecialPrice(round($product->getSpecialPrice()));
}
}
}
}
In PHP:
if (special price)
price = round(price);
Which database are you using? Maybe you could do this at database level and leave application intact. For example, if you use Firebird, you can use a computed field defined like this:
alter table prices
add customer_price
computed by (
case when special_price
then round(price,0)
else price
end)
I am developing a payment module. I don't find proper documentation anywhere for Magento System.
As of now I am facing a problem in capture method of Payment Method Model. Please help me.
I don't know why the CURL request for REST API is not being created and sent. It executes first two or three lines only. I don't think the way I wrote code below is right, Please suggest best way. After Placing order I "Got Info Instance" and amount in Log file as given in code. The other data for which I have called Mage::Log() doesn't appear in System log file.
I have payment Method code like this
<?php
class Company_Cashondelivery_Model_Createorder extends Mage_Payment_Model_Method_Abstract
{
protected $_code = 'cashondelivery';
protected $_canCapture = true;
protected $_canUseCheckout = true;
public function capture(Varien_Object $payment, $amount)
{
$paymentInfo = $this->getInfoInstance();
Mage::Log('Got Info Instance'); //This is shown in Log file.
Mage::Log($amount); //This is shown in Log file
Mage::Log($payment);
$xml='<?xml version="1.0" encoding="utf-8" ?>'.
'<transaction>'.
'<customerDetails>'.
'<address>This is, address, Purple Talk, 600100</address>'. //I dont know how to get Address as string here
'<contactNo>'.$paymentInfo->getOrder()->getBillingAddress()->getTelephone().'</contactNo>'.
'<email>'.$paymentInfo->getOrder()->getBillingAddress()->email().'</email>'.
'<firstName>'.$paymentInfo->getOrder()->getBillingAddress()->getFirstName().'</firstName>'.
'<lastName>'.$paymentInfo->getOrder()->getBillingAddress()->getLastName().'</lastName>'.
'</customerDetails>'.
'<orderDetails>'.
'<pincode>'.$paymentInfo->getOrder()->getBillingAddress()->getPostCode().'</pincode>'.
'<clientOrderID>'.$paymentInfo->getOrder()->getIncrementId().'</clientOrderID>'.
'<deliveryDate>20-7-20111</deliveryDate>'.
'<orderAmount>'.$amount.'</orderAmount>'.
'<productDetails>';
Mage::Log($xml);//This is not there in log file
foreach ($paymentInfo->getOrder()->getAllItems() as $item)
{
$xml.='<productDetails>'.
'<productID>'.$item->getProductId().'</productID>'.
'<productQuantity>'.$item->getQtyOrdered().'</productQuantity>'.
'<unitCost>'.$item->getPrice().'</unitCost>'.
'</productDetails>';
}
$xml.='</orderDetails>'.
'<additionalInformation>'.
'<parameters>'.
'<name>Some Name</name>'.
'<value>Some Value</value>'.
'</parameters>'.
'<parameters>'.
'<name>Some Name2</name>'.
'<value>Some value2</value>'.
'</parameters>'.
'</additionalInformation>'.
'</transaction>';
Mage::Log($xml);
$url = "http://services.abc.com/rest/service/createOrder";
Mage::Log('Loading url : '.$url); //This is not there in Log;
$ch = curl_init($url) ;
curl_setopt($ch, CURLOPT_HEADER,true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('username:xxxxx','password:xxxxxx','Content-Type:application/xml'));
$response = curl_exec($ch);
Mage::Log($response); //This is not there in Log file;
return $this;
}
}
?>
The Config.xml file is like this
<?xml version="1.0"?>
<config>
<modules>
<Company_Cashondelivery>
<!-- declare module's version information for database updates -->
<version>0.1.0</version>
</Company_Cashondelivery>
</modules>
<global>
<!-- declare model group for new module -->
<models>
<!-- model group alias to be used in Mage::getModel('newmodule/...') -->
<cashondelivery>
<!-- base class name for the model group -->
<class>Company_Cashondelivery_Model</class>
</cashondelivery>
</models>
<helpers>
<cashondelivery>
<class>Company_Cashondelivery_Helper</class>
</cashondelivery>
</helpers>
<!-- declare resource setup for new module -->
<resources>
<!-- resource identifier -->
<cashondelivery_setup>
<!-- specify that this resource is a setup resource and used for upgrades -->
<setup>
<!-- which module to look for install/upgrade files in -->
<module>Company_Cashondelivery</module>
</setup>
<!-- specify database connection for this resource -->
<connection>
<!-- do not create new connection, use predefined core setup connection -->
<use>core_setup</use>
</connection>
</cashondelivery_setup>
<cashondelivery_write>
<connection>
<use>core_write</use>
</connection>
</cashondelivery_write>
<cashondelivery_read>
<connection>
<use>core_read</use>
</connection>
</cashondelivery_read>
</resources>
</global>
<!-- declare default configuration values for this module -->
<default>
<payment>
<cashondelivery>
<active>1</active>
<model>cashondelivery/createorder</model>
<order_status>pending</order_status>
<payment_action>authorize_capture</payment_action>
<title>Company</title>
</cashondelivery>
</payment>
</default>
</config>
The system.xml file is like this
<?xml version="1.0"?>
<config>
<sections>
<payment>
<groups>
<cashondelivery translate="label" module="cashondelivery">
<label>Company Cash On delivery</label>
<sort_order>670</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<fields>
<active translate="label">
<label>Enabled</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_yesno</source_model>
<sort_order>1</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</active>
<order_status translate="label">
<label>New order status</label>
<frontend_type>select</frontend_type>
<source_model>adminhtml/system_config_source_order_status_processing</source_model>
<sort_order>4</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</order_status>
<title translate="label">
<label>Title</label>
<frontend_type>text</frontend_type>
<sort_order>2</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
</title>
</fields>
</cashondelivery>
</groups>
</payment>
</sections>
</config>
The etc/module/Company_Cashondelivery.xml is like this
<?xml version="1.0"?>
<config>
<modules>
<Company_Cashondelivery>
<active>true</active>
<codePool>local</codePool>
</Company_Cashondelivery>
</modules>
<depends>
<Mage_Payment />
</depends>
</config>
Let me know If I am not clear with anything.
Problem in your code is on this line
'<email>'.$paymentInfo->getOrder()->getBillingAddress()->email().'</email>'.
There is no email() function, you can use `''.$paymentInfo->getOrder()->getBillingAddress()->getEmail().''. to retrive email.
This error is btw sent to store owner email. If you are developing on localhost, I would recommed you to use some emulation of smtp, for example (for win) http://www.toolheap.com/test-mail-server-tool/ and then you can see all email sent by Magento.
And second note. Instead of ugly curl, you can use Varien_Http_Client (Zend_Http_Client) shipped with Magento. You can see example in my post - https://stackoverflow.com/a/9233290/858586
The problem was Mag::Log($payment) I removed it and its working like a magic.