Is there a simple way to add the username of the person who is making the comment in the admin history to the comment thread on the order?
-- edit --
Another way of asking this would be how do I add an additional field to the comment history model so that I can override the appropriate models and templates inserting that data into the data structure.
If you want to add the username who is currently logged in and making change in order or commenting on order. you need to add an attribute to magento.
Create a Module say Audit
app / etc / modules / Namespace_Audit.xml
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Audit>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Sales/>
</depends>
</Namespace_Audit>
</modules>
</config>
then Create a folder Audit in you namespace and create the config file. purpose of this is to rewrite the core class and extending for modified method
app / code / local / Namespace / Audit / etc / config.xml
`<?xml version="1.0"?>
<config>
<modules>
<Namespace_Audit>
<version>0.1.0</version>
</Namespace_Audit>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_view_tab_history before="Mage_Adminhtml_Block">Namespace_Audit_Block_Sales_Order_View_Tab_History<sales_order_view_tab_history>
</rewrite>
</adminhtml>
</blocks>
<global>
<models>
<audit>
<class>Bigadda_Audit_Model</class>
</audit>
</models>
<resources>
<audit_setup>
<setup>
<module>Bigadda_Audit</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</audit_setup>
<audit_write>
<connection>
<use>core_write</use>
</connection>
</audit_write>
<audit_read>
<connection>
<use>core_read</use>
</connection>
</audit_read>
</resources>
</global>
</global>
</config>`
create a setup to make a new attribute in database
local / Namespace / Audit / sql / audit_setup / mysql4-install-0.1.0.php
`
<?php
$installer = $this;
$installer->startSetup();
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttribute('order_status_history', 'track_user', array('type' => 'varchar'));
$installer->endSetup();
`
Now extending the existing class . create a class file History.php
Namespace/Audit/Block/Sales/Order/View/Tab/History
and copy the functions in that
`
public function getFullHistory()
{
$order = $this->getOrder();
$history = array();
foreach ($order->getAllStatusHistory() as $orderComment){
$history[$orderComment->getEntityId()] = $this->_prepareHistoryItem(
$orderComment->getStatusLabel(),
$orderComment->getIsCustomerNotified(),
$orderComment->getCreatedAtDate(),
$orderComment->getComment(),
$orderComment->getTrackUser(),
$orderComment->getTrackUserName()
);
}
foreach ($order->getCreditmemosCollection() as $_memo){
$history[$_memo->getEntityId()] =
$this->_prepareHistoryItem($this->__('Credit Memo #%s created', $_memo->getIncrementId()),
$_memo->getEmailSent(), $_memo->getCreatedAtDate());
foreach ($_memo->getCommentsCollection() as $_comment){
$history[$_comment->getEntityId()] =
$this->_prepareHistoryItem($this->__('Credit Memo #%s comment added', $_memo->getIncrementId()),
$_comment->getIsCustomerNotified(), $_comment->getCreatedAtDate(), $_comment->getComment(),$_comment->getTrackUser(),$_comment->getTrackUserName());
}
}
foreach ($order->getShipmentsCollection() as $_shipment){
$history[$_shipment->getEntityId()] =
$this->_prepareHistoryItem($this->__('Shipment #%s created', $_shipment->getIncrementId()),
$_shipment->getEmailSent(), $_shipment->getCreatedAtDate());
foreach ($_shipment->getCommentsCollection() as $_comment){
$history[$_comment->getEntityId()] =
$this->_prepareHistoryItem($this->__('Shipment #%s comment added', $_shipment->getIncrementId()),
$_comment->getIsCustomerNotified(), $_comment->getCreatedAtDate(), $_comment->getComment(),$_comment->getTrackUser(),$_comment->getTrackUserName());
}
}
foreach ($order->getInvoiceCollection() as $_invoice){
$history[$_invoice->getEntityId()] =
$this->_prepareHistoryItem($this->__('Invoice #%s created', $_invoice->getIncrementId()),
$_invoice->getEmailSent(), $_invoice->getCreatedAtDate());
foreach ($_invoice->getCommentsCollection() as $_comment){
$history[$_comment->getEntityId()] =
$this->_prepareHistoryItem($this->__('Invoice #%s comment added', $_invoice->getIncrementId()),
$_comment->getIsCustomerNotified(), $_comment->getCreatedAtDate(), $_comment->getComment(),$_comment->getTrackUser(),$_comment->getTrackUserName());
}
}
foreach ($order->getTracksCollection() as $_track){
$history[$_track->getEntityId()] =
$this->_prepareHistoryItem($this->__('Tracking number %s for %s assigned', $_track->getNumber(), $_track->getTitle()),
false, $_track->getCreatedAtDate());
}
krsort($history);
return $history;
}`
protected function _prepareHistoryItem($label, $notified, $created, $comment = '' , $trackUser = '' , $trackUserName ='')
{
return array(
'title' => $label,
'notified' => $notified,
'track_user' => $trackUser,
'track_user_name' => $trackUserName,
'comment' => $comment,
'created_at' => $created
);
}
extend the class order.php and add this method to set the comment to update the database.
app / code / local / Mynamespace / Sales / Model / Order.php
public function addStatusHistoryComment($comment, $status = false)
{
if (false === $status) {
$status = $this->getStatus();
} elseif (true === $status) {
$status = $this->getConfig()->getStateDefaultStatus($this->getState());
} else {
$this->setStatus($status);
}
$UserInfo = Mage::getSingleton('admin/session')->getUser();
$UserName='';
$UserName=$UserInfo->getUsername();
$history = Mage::getModel('sales/order_status_history')
->setStatus($status)
->setComment($comment)
->setTrackUser($UserName); //added by vipul dadhich to add audits in the
$this->addStatusHistory($history);
return $history;
}
finally updating the phtml files.
app / design / adminhtml / default / default / template / sales / order / view / history.phtml
place this code wherever u want to show the username
<?php if ($_item->getTrackUser()): ?>
<br/><?php echo "<b>Updated By ( User ) :- </b>".$this->htmlEscape($_item->getTrackUser(), array('b','br','strong','i','u')) ?>
<?php endif; ?>
app / design / adminhtml / default / default / template / sales / order / view / tab / history.phtml
<?php if ($_comment = $this->getItemTrackUser($_item)): ?>
<br/><?php echo "<b>Updated By (User) :- </b>".$_comment ?>
<?php endif; ?>
Thats All folks..
Vipul Dadhich
A different take by observing the event *sales_order_status_history_save_before*
Define the setup and observer in your config:
<config>
<modules>
<Name_Module>
<version>0.0.1</version>
</Name_Module>
</modules>
<global>
<resources>
<module_setup>
<setup>
<module>Name_Module</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</module_setup>
</resources>
<events>
<sales_order_status_history_save_before>
<observers>
<sales_order_status_history_save_before_observer>
<type>singleton</type>
<class>Name_Module_Model_Observer</class>
<method>orderStatusHistorySaveBefore</method>
</sales_order_status_history_save_before_observer>
</observers>
</sales_order_status_history_save_before>
</events>
<!-- and so on ->
In your module_setup file app\code\local\Name\Module\sql\module_setup\install-0.0.1.php
$installer = $this;
$installer->startSetup();
$table = $installer->getTable('sales/order_status_history');
$installer->getConnection()
->addColumn($table, 'username', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'length' => 40,
'nullable' => true,
'comment' => 'Admin user name'
));
$installer->getConnection()
->addColumn($table, 'userrole', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'length' => 50,
'nullable' => true,
'comment' => 'Admin user role'
));
$installer->endSetup();
Then in Name_Module_Model_Observer:
public function orderStatusHistorySaveBefore($observer)
{
$session = Mage::getSingleton('admin/session');
if ($session->isLoggedIn()) { //only for login admin user
$user = $session->getUser();
$history = $observer->getEvent()->getStatusHistory();
if (!$history->getId()) { //only for new entry
$history->setData('username', $user->getUsername());
$role = $user->getRole(); //if you have the column userrole
$history->setData('userrole', $role->getRoleName()); //you can save it too
}
}
}
In Magento 2
You need to override the AddComment.php file in vendor/magento/module-sales
If you want to edit the core file AddComment.php then you can add the following code to your AddComment.php file
$username = $this->authSession->getUser()->getUsername();
$append = " (by ".$username.")";
$history = $order->addStatusHistoryComment($data['comment'].$append, $data['status']);
But this is not a good practice to modify core files directly. You need to make your new module and override
Vendor/Module/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Sales\Controller\Adminhtml\Order\AddComment" type="Vendor\Module\Controller\Adminhtml\Order\AddComment" />
</config>
Vendor\Module\Controller\Adminhtml\Order\AddComment.php
<?php
namespace Vendor\Module\Controller\Adminhtml\Order;
use Magento\Backend\App\Action;
use Magento\Sales\Model\Order\Email\Sender\OrderCommentSender;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\InputException;
use Psr\Log\LoggerInterface;
class AddComment extends \Magento\Sales\Controller\Adminhtml\Order
{
/**
* Authorization level of a basic admin session
*
* #see _isAllowed()
*/
const ADMIN_RESOURCE = 'Magento_Sales::comment';
/**
* Core registry
*
* #var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* #var \Magento\Framework\App\Response\Http\FileFactory
*/
protected $_fileFactory;
/**
* #var \Magento\Framework\Translate\InlineInterface
*/
protected $_translateInline;
/**
* #var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
/**
* #var \Magento\Framework\Controller\Result\JsonFactory
*/
protected $resultJsonFactory;
/**
* #var \Magento\Framework\View\Result\LayoutFactory
*/
protected $resultLayoutFactory;
/**
* #var \Magento\Framework\Controller\Result\RawFactory
*/
protected $resultRawFactory;
/**
* #var OrderManagementInterface
*/
protected $orderManagement;
/**
* #var OrderRepositoryInterface
*/
protected $orderRepository;
/**
* #var LoggerInterface
*/
protected $logger;
protected $authSession;
public function __construct(
Action\Context $context,
\Magento\Framework\Registry $coreRegistry,
\Magento\Framework\App\Response\Http\FileFactory $fileFactory,
\Magento\Framework\Translate\InlineInterface $translateInline,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
\Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory,
\Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
OrderManagementInterface $orderManagement,
OrderRepositoryInterface $orderRepository,
LoggerInterface $logger,
\Magento\Backend\Model\Auth\Session $authSession
) {
$this->authSession = $authSession;
parent::__construct($context, $coreRegistry,$fileFactory,$translateInline,$resultPageFactory,$resultJsonFactory,$resultLayoutFactory,$resultRawFactory,$orderManagement,$orderRepository,$logger);
}
/**
* Add order comment action
*
* #return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
$order = $this->_initOrder();
if ($order) {
try {
$data = $this->getRequest()->getPost('history');
if (empty($data['comment']) && $data['status'] == $order->getDataByKey('status')) {
throw new \Magento\Framework\Exception\LocalizedException(__('Please enter a comment.'));
}
$notify = isset($data['is_customer_notified']) ? $data['is_customer_notified'] : false;
$visible = isset($data['is_visible_on_front']) ? $data['is_visible_on_front'] : false;
$username = $this->authSession->getUser()->getUsername();
$append = " (by ".$username.")";
$history = $order->addStatusHistoryComment($data['comment'].$append, $data['status']);
$history->setIsVisibleOnFront($visible);
$history->setIsCustomerNotified($notify);
$history->save();
$comment = trim(strip_tags($data['comment']));
$order->save();
/** #var OrderCommentSender $orderCommentSender */
$orderCommentSender = $this->_objectManager
->create(\Magento\Sales\Model\Order\Email\Sender\OrderCommentSender::class);
$orderCommentSender->send($order, $notify, $comment);
return $this->resultPageFactory->create();
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$response = ['error' => true, 'message' => $e->getMessage()];
} catch (\Exception $e) {
$response = ['error' => true, 'message' => __('We cannot add order history.')];
}
if (is_array($response)) {
$resultJson = $this->resultJsonFactory->create();
$resultJson->setData($response);
return $resultJson;
}
}
return $this->resultRedirectFactory->create()->setPath('sales/*/');
}
}
Related
I am creating a module for a new payment gateway (Pay On Account) that has a form field in the checkout (Only shows if user is logged in and has an account).
Mostly everything is working: The form field is captured correctly at checkout and saved in the sales_flat_order & sales_flat_quote tables.
The order code is being recorded correctly in the tables also (payonaccount)
The issue is when I try to view the order in the admin I get the following error:
Cannot retrieve the payment method model object.
Other SO answers mentioning I should correct the payment type in the DB don't work (as the payment type is correct)
Here is my code (all of it! Sorry but thanks!):
File structure:
app\code\local\Sulman\PayOnAccount\Block\Form\Payonaccount.php
<?php
class Sulman_PayOnAccount_Block_Form_Payonaccount extends Mage_Payment_Block_Form
{
protected function _construct()
{
parent::_construct();
$this->setTemplate('payment/form/payonaccount.phtml');
}
}
app\code\local\Sulman\PayOnAccount\Block\Info\Payonaccount.php
<?php
class Sulman_PayOnAccount_Block_Info_Payonaccount extends Mage_Payment_Block_Form
{
protected function _construct()
{
parent::_construct();
$this->setTemplate('payment/info/payonaccount.phtml');
}
public function getMethod()
{
return parent::getMethod();
}
}
app\code\local\Sulman\PayOnAccount\etc\config.xml
<?xml version="1.0"?>
<config>
<modules>
<Sulman_PayOnAccount>
<version>0.1.0</version>
</Sulman_PayOnAccount>
</modules>
<global>
<blocks>
<payonaccount>
<class>Sulman_PayOnAccount_Block</class>
</payonaccount>
</blocks>
<models>
<payonaccount>
<class>Sulman_PayOnAccount_Model</class>
</payonaccount>
</models>
<helpers>
<payonaccount>
<class>Sulman_PayOnAccount_Helper</class>
</payonaccount>
</helpers>
<payment>
<groups>
<payonaccount>PayOnAccount</payonaccount>
</groups>
</payment>
<!-- define install scripts -->
<resources>
<payonaccount_setup>
<setup>
<module>Sulman_PayOnAccount</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</payonaccount_setup>
</resources>
<fieldsets>
<sales_convert_quote_payment>
<poa_ponumber>
<to_order_payment>*</to_order_payment>
</poa_ponumber>
</sales_convert_quote_payment>
<sales_convert_quote_payment>
<poa_ponumber>
<to_order_payment>*</to_order_payment>
</poa_ponumber>
</sales_convert_quote_payment>
<sales_convert_quote>
<poa_ponumber>
<to_order>*</to_order>
</poa_ponumber>
</sales_convert_quote>
</fieldsets>
</global>
<default>
<payment>
<payonaccount>
<model>payonaccount/payonaccount</model>
<active>1</active>
<order_status>pending</order_status>
<title>Pay On Account</title>
<payment_action>sale</payment_action>
<allowspecific>0</allowspecific>
<sort_order>1</sort_order>
</payonaccount>
</payment>
</default>
</config>
app\code\local\Sulman\PayOnAccount\Model\Payonaccount.php
<?php
class Sulman_PayOnAccount_Model_Payonaccount extends Mage_Payment_Model_Method_Abstract
{
protected $_code = 'payonaccount';
protected $_formBlockType = 'payonaccount/form_payonaccount';
protected $_infoBlockType = 'payonaccount/info_payonaccount';
public function isAvailable($quote = null) {
$isLoggedIn = Mage::helper('customer')->isLoggedIn();
$canPayOnAccount = false;
if(Mage::getSingleton('customer/session')->isLoggedIn()) {
$customerData = Mage::getSingleton('customer/session')->getCustomer();
$customerObj = Mage::getModel('customer/customer')->load($customerData->getId());
$hasAccount = $customerObj->getData('has_account'); // 1 = No, 2 = Yes
if( is_null($hasAccount) OR $hasAccount == 1){
$canPayOnAccount = false;
} elseif($hasAccount == 2){
$canPayOnAccount = true;
}
}
return parent::isAvailable($quote) && $canPayOnAccount;
}
public function assignData($data)
{
if (!($data instanceof Varien_Object)) {
$data = new Varien_Object($data);
}
Mage::log("getPoaPonumber: ".$data->getPoaPonumber(), null, 'sulman.log');
$this->getInfoInstance()->setPoaPonumber($data->getPoaPonumber());
return $this;
}
}
app\code\local\Sulman\PayOnAccount\sql\payonaccount_setup\mysql4-install-0.1.0.php
<?php
$installer = $this;
$installer->startSetup();
$installer->run("
ALTER TABLE `{$installer->getTable('sales/quote')}` ADD `poa_ponumber` VARCHAR( 255 ) NOT NULL ;
ALTER TABLE `{$installer->getTable('sales/order')}` ADD `poa_ponumber` VARCHAR( 255 ) NOT NULL ;
");
$installer->endSetup();
app\design\adminhtml\default\default\template\payment\info\payonaccount.phtml
<?php
echo $this->getMethod();
?>
<p><?php //echo $this->escapeHtml($this->getMethod()->getTitle()) ?></p>
app\design\frontend\cmtgroup\default\template\payment\form\payonaccount.phtml
<ul class="form-list" id="payment_form_<?php echo $this->getMethodCode() ?>" style="display:none;">
<li>
<label for="poa_ponumber" class="required"><em>*</em><?php echo $this->__('Purchase Order Number') ?></label>
<div class="input-box">
<input type="text" id="poa_ponumber" name="payment[poa_ponumber]" title="<?php echo $this->__('Purchase Order Number') ?>" class="input-text" value="<?php echo $this->escapeHtml($this->getInfoData('poa_ponumber')) ?>" />
</div>
</li>
</ul>
If I try and load the order elsewhere and get the poa_number like so:
$_order->getPoaNumber();
It doesn't return anything.
Any ideas? Thanks.
Ok so I have solved this... I added an observer on the sales_order_save_after event that gets the payment info and records the poa_ponumber against the order like so:
public function saveBefore(Varien_Event_Observer $observer){
// get the quote of the order so we can get the quote payment type poa_ponumber
$order = $observer->getEvent()->getOrder();
$quote = Mage::getModel('sales/quote')->loadByIdWithoutStore($order->getQuoteId());
$poaponumber = $quote->getPayment()->getPoaPonumber();
$order->setPoaPonumber($poaponumber);
}
This saves the poa_ponumber to the flat order table and can then be easily extracted the normal way: $_order->getPoaPonumber();
I'm sure this isn't quite the right way but it works.
Please check exist $_code in your payment method model.
You can refer :
Mage_Payment_Model_Method_Abstract
Line : 343
public function getCode()
{
if (empty($this->_code)) {
Mage::throwException(Mage::helper('payment')->__('Cannot retrieve the payment method code.'));
}
return $this->_code;
}
I am learning Magento and I have start learning events and observers. A percentage of amount is added to product by setting in admin product area.
It works fine but the discounted price shows only on product page. Can anybody suggest me how can I change the price through out Magento. I mean change price should go to cart, order etc.
Below is the code for observer
<?php
class Xyz_Catalog_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Xyz_Catalog_Model_Price_Observer
*/
public function apply_discount_percent($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$percentDiscount = $product->getPercentDiscount();
if (is_numeric($percentDiscount)) {
$today = floor(time()/86400)*86400;
$from = floor(strtotime($product->getSpecialFromDate())/86400)*86400;
$to = floor(strtotime($product->getSpecialToDate())/86400)*86400;
if ($product->getSpecialFromDate() && $today < $from) {
} elseif ($product->getSpecialToDate() && $today > $to) {
} else {
$price = $product->getPrice();
$finalPriceNow = $product->getData('final_price');
$specialPrice = $price - $price * $percentDiscount / 100;
// if special price is negative - negate the discount - this may be a mistake in data
if ($specialPrice < 0)
$specialPrice = $finalPriceNow;
if ($specialPrice < $finalPriceNow)
$product->setFinalPrice($specialPrice); // set the product final price
}
}
}
return $this;
}
}
config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<xyz_catalog_price_observer>
<type>singleton</type>
<class>Xyz_Catalog_Model_Price_Observer</class>
<method>apply_discount_percent</method>
</xyz_catalog_price_observer>
</observers>
</catalog_product_get_final_price>
</events>
</global>
</config>
Please advise how I can use the new discounted price throughout Magento. Thanks
Here is solution
config.xml
<?xml version="1.0"?>
<config>
<modules>
<Seta_DiscountPrice>
<version>0.1.0</version> <!-- Version number of your module -->
</Seta_DiscountPrice>
</modules>
<global>
<models>
<setadiscountprice>
<class>Seta_DiscountPrice_Model</class>
</setadiscountprice>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_10</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_get_final_price>
<catalog_product_collection_load_after>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_view</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_collection_load_after>
</events>
</global>
</config>
Observer.php
<?php
class Seta_DiscountPrice_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Seta_DiscountPrice_Model_Price_Observer
*/
public function apply_10($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$product->setFinalPrice(10);
}
return $this;
}
public function apply_view($observer)
{
$event = $observer->getEvent();
$myCustomPrice = 10;
$products = $observer->getCollection();
foreach( $products as $product )
{
$product->setPrice( $myCustomPrice );
$product->setFinalPrice( $myCustomPrice );
}
return $this;
}
}
Why not using 'catalog price rules' or 'special price' function of products? These are inbuilt functions to do this kind of stuff.
For add to cart price change, you need another event to observe. Crash course:
You have to build an observer that catches the add-to-cart event sales_quote_add_item and then you can do the php-stuff in the observer like you did on the product page to change the price for the product added to card with:
$observer->getEvent()->getQuoteItem()->setOriginalCustomPrice([your price])
Exactly for this task it's better to use Catalog Price Rules from Promotions menu.
But as I understand you are making this with learning purposes. So when you are not sure for an event you could just log the dispatched events. In app/Mage.php you have a method called dispatchEvent. Then you could just log every dispatched event:
public static function dispatchEvent($name, array $data = array())
{
if(strpos($name, 'product') || strpos($name, 'price')) { // optional
Mage::log($name, null, 'events.log', true);
}
Varien_Profiler::start('DISPATCH EVENT:'.$name);
$result = self::app()->dispatchEvent($name, $data);
Varien_Profiler::stop('DISPATCH EVENT:'.$name);
return $result;
}
Your log file will be created in var/log folder. Of course don't forget to revert Mage.php to it's original version when you're done. It's not a good idea to change core files.
Hi friends i am not expert in magento but i have some good knowledge of its themng but i dont have a very good knowledge of modules , i need to create a
custom registration form with contact info and company info
details ,
i need to create this on my own custom page , i need the magento
default registration page also
, i have check the
app\code\core\Mage\Customer\controllers/AccountController
in which i got the
public function createPostAction()
{
$session = $this->_getSession();
if ($session->isLoggedIn()) {
$this->_redirect('*/*/');
return;
}
$session->setEscapeMessages(true); // prevent XSS injection in user input
if ($this->getRequest()->isPost()) {
$errors = array();
if (!$customer = Mage::registry('current_customer')) {
$customer = Mage::getModel('customer/customer')->setId(null);
}
/* #var $customerForm Mage_Customer_Model_Form */
$customerForm = Mage::getModel('customer/form');
$customerForm->setFormCode('customer_account_create')
->setEntity($customer);
$customerData = $customerForm->extractData($this->getRequest());
if ($this->getRequest()->getParam('is_subscribed', false)) {
$customer->setIsSubscribed(1);
}
/**
* Initialize customer group id
*/
$customer->getGroupId();
if ($this->getRequest()->getPost('create_address')) {
/* #var $address Mage_Customer_Model_Address */
$address = Mage::getModel('customer/address');
/* #var $addressForm Mage_Customer_Model_Form */
$addressForm = Mage::getModel('customer/form');
$addressForm->setFormCode('customer_register_address')
->setEntity($address);
$addressData = $addressForm->extractData($this->getRequest(), 'address', false);
$addressErrors = $addressForm->validateData($addressData);
if ($addressErrors === true) {
$address->setId(null)
->setIsDefaultBilling($this->getRequest()->getParam('default_billing', false))
->setIsDefaultShipping($this->getRequest()->getParam('default_shipping', false));
$addressForm->compactData($addressData);
$customer->addAddress($address);
$addressErrors = $address->validate();
if (is_array($addressErrors)) {
$errors = array_merge($errors, $addressErrors);
}
} else {
$errors = array_merge($errors, $addressErrors);
}
}
try {
$customerErrors = $customerForm->validateData($customerData);
if ($customerErrors !== true) {
$errors = array_merge($customerErrors, $errors);
} else {
$customerForm->compactData($customerData);
$customer->setPassword($this->getRequest()->getPost('password'));
$customer->setConfirmation($this->getRequest()->getPost('confirmation'));
$customerErrors = $customer->validate();
if (is_array($customerErrors)) {
$errors = array_merge($customerErrors, $errors);
}
}
$validationResult = count($errors) == 0;
if (true === $validationResult) {
$customer->save();
Mage::dispatchEvent('customer_register_success',
array('account_controller' => $this, 'customer' => $customer)
);
if ($customer->isConfirmationRequired()) {
$customer->sendNewAccountEmail(
'confirmation',
$session->getBeforeAuthUrl(),
Mage::app()->getStore()->getId()
);
$session->addSuccess($this->__('Account confirmation is required. Please, check your email for the confirmation link. To resend the confirmation email please click here.', Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail())));
$this->_redirectSuccess(Mage::getUrl('*/*/index', array('_secure'=>true)));
return;
} else {
$session->setCustomerAsLoggedIn($customer);
$url = $this->_welcomeCustomer($customer);
$this->_redirectSuccess($url);
return;
}
} else {
$session->setCustomerFormData($this->getRequest()->getPost());
if (is_array($errors)) {
foreach ($errors as $errorMessage) {
$session->addError($errorMessage);
}
} else {
$session->addError($this->__('Invalid customer data'));
}
}
} catch (Mage_Core_Exception $e) {
$session->setCustomerFormData($this->getRequest()->getPost());
if ($e->getCode() === Mage_Customer_Model_Customer::EXCEPTION_EMAIL_EXISTS) {
$url = Mage::getUrl('customer/account/forgotpassword');
$message = $this->__('There is already an account with this email address. If you are sure that it is your email address, click here to get your password and access your account.', $url);
$session->setEscapeMessages(false);
} else {
$message = $e->getMessage();
}
$session->addError($message);
} catch (Exception $e) {
$session->setCustomerFormData($this->getRequest()->getPost())
->addException($e, $this->__('Cannot save the customer.'));
}
}
$this->_redirectError(Mage::getUrl('*/*/create', array('_secure' => true)));
}
which is for creating new account
,
but i don't want to edit this function because i need the magento
default registration page als
o , so please suggest me how can i create a new function from where i can make the customer provide there information and can register and i can store that in database , basically i need to store the contact info and company info in address tables so that the information can be shown in admin
Your custom module should contain something similar:
Package/Module/etc/config.xml
Package/Module/controllers/contactController.php
Package/Module/sql/modulename_setup/mysql4-install-1.0.0.php
app/design/frontend/default/default/layout/customercontact.xml
config.xml:
<config>
...
<modules>
<Package_Module>
<version>1.0.0</version>
</Package_Module>
</modules>
<frontend>
<!--configure your controllers-->
<routers>
<modulename>
<use>standard</use>
<args>
<module>Package_Module</module>
<frontName>modulename</frontName>
</args>
</modulename>
</routers>
<layout>
<updates>
<modulename>
<file>customercontact.xml</file>
</modulename>
</updates>
</layout>
</frontend>
<global>
<blocks></blocks><!--you can read some blogs etc-->
<models></models><!--you can read some blogs etc-->
<helpers></helpers><!--you can read some blogs etc-->
<resources>
<modulename_setup>
<setup>
<module>Package_Module</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</modulename_setup>
<modulename_write>
<connection>
<use>core_write</use>
</connection>
</modulename_write>
<modulename_read>
<connection>
<use>core_read</use>
</connection>
</modulename_read>
</resources>
</global>
...
</config>
ContactController.php
public function customerDetailsAction(){
/*render your form
Use layout handle to set your own blocks
*/
}
public function customerDetailsPostAction(){
/*borrow some logic from AccountController or Build your own
get posted data, validate and set to model & save
*/
}
mysql4-install-1.0.0.php
Used below script in few of my similar tasks:
$installer = $this;
$installer->startSetup();
$setup = Mage::getModel('customer/entity_setup', 'core_setup');//invoke customer entity setup class
// add your attribute to customer entity
$setup->addAttribute(
'customer',
'attribute_code',
array(
'type' => 'varchar',
'input' => 'text',
'label' => 'Company name',
'global' => 1,
'visible' => 1,
'required' => 0,
'user_defined' => 1,
'visible_on_front' => 1,
)
);
if (version_compare(Mage::getVersion(), '1.6.0', '<='))
{
$customer = Mage::getModel('customer/customer');
$attrSetId = $customer->getResource()->getEntityType()->getDefaultAttributeSetId();
$setup->addAttributeToSet('customer', $attrSetId, 'General', 'attribute_code');
}
if (version_compare(Mage::getVersion(), '1.4.2', '>='))
{
/*
* To get new attribute listed for customer/form various models, example checl line 275 to 277 AccountController.php
*/
Mage::getSingleton('eav/config')
->getAttribute('customer', 'attribute_code')
->setData(
'used_in_forms',
array(
'adminhtml_customer',//will make new attribute appear in admin
'customer_account_create',//will make new attribute appear on registration
'customer_account_edit',//will make new attribute appear in account dashboard
'checkout_register'// on checkout page
)
)
->save();
}
customercontact.xml
<layout>
...
<modulename_contact_customerDetails>
<update handle="customer_account_create"/><!--if only some additional fields are needed-->
<referene name="customer_form_register"><!--set your template based on customer/form/register.phtml-->
<action method="setTemplate">path to your template</action>
</reference>
</modulename_contact_customerDetails>
...
</layout>
Hope this gives an idea of what needed to be done !
The seemingly easiest path ahead for you would be to create a custom module, with a frontend controller, a single table model and an admin grid if you wish to present the data collected by the contact form to the admin users in the way other magento modules show the data.
Creating magento extensions is quite easy if right set of tools are used, you can use this module creator to create an extension quite instantly.
As we send shippment emails to customers, in this shippment email, we get tracking number from track.phtml and now the subject part of the email is like, order number and shippment number. I would like to change the subject of the email in which we are senidng as shippment emails. The subject has to be with tracking number. For order number we can get with "order.increment_id", But I dont know how to get the tracking number. SO how can I display tracking number in subject of email?
This cannot be done only by using a variable name like "order.increment_id" in the email template. You have to send the tracking data to the email template processor to achieve this with an example in 4 steps.
Step1>> Add Module configuration
In app/etc/modules/Eglobe_Sales.xml
<?xml version="1.0"?>
<config>
<modules>
<Eglobe_Sales>
<active>true</active>
<codePool>local</codePool>
</Eglobe_Sales>
</modules>
</config>
Step2>> Add config.xml(app/code/local/Eglobe/Sales/etc/config.xml)
<?xml version="1.0"?>
<config>
<modules>
<Eglobe_Sales>
<version>0.1.0</version>
</Eglobe_Sales>
</modules>
<global>
<models>
<sales>
<rewrite>
<order_shipment>Eglobe_Sales_Model_Order_Shipment</order_shipment>
</rewrite>
</sales>
</models>
</global>
</config>
Step3>> Override Mage_Sales_Model_Order_Shipment::sendEmail()
<?php
class Eglobe_Sales_Model_Order_Shipment extends Mage_Sales_Model_Order_Shipment {
/**
* Send email with shipment data
*
* #param boolean $notifyCustomer
* #param string $comment
* #return Mage_Sales_Model_Order_Shipment
*/
public function sendEmail($notifyCustomer = true, $comment = '')
{
$order = $this->getOrder();
$storeId = $order->getStore()->getId();
if (!Mage::helper('sales')->canSendNewShipmentEmail($storeId)) {
return $this;
}
// Get the destination email addresses to send copies to
$copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
$copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $storeId);
// Check if at least one recepient is found
if (!$notifyCustomer && !$copyTo) {
return $this;
}
// Start store emulation process
$appEmulation = Mage::getSingleton('core/app_emulation');
$initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($storeId);
try {
// Retrieve specified view block from appropriate design package (depends on emulated store)
$paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
->setIsSecureMode(true);
$paymentBlock->getMethod()->setStore($storeId);
$paymentBlockHtml = $paymentBlock->toHtml();
} catch (Exception $exception) {
// Stop store emulation process
$appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
throw $exception;
}
// Stop store emulation process
$appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
// Retrieve corresponding email template id and customer name
if ($order->getCustomerIsGuest()) {
$templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $storeId);
$customerName = $order->getBillingAddress()->getName();
} else {
$templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $storeId);
$customerName = $order->getCustomerName();
}
$mailer = Mage::getModel('core/email_template_mailer');
if ($notifyCustomer) {
$emailInfo = Mage::getModel('core/email_info');
$emailInfo->addTo($order->getCustomerEmail(), $customerName);
if ($copyTo && $copyMethod == 'bcc') {
// Add bcc to customer email
foreach ($copyTo as $email) {
$emailInfo->addBcc($email);
}
}
$mailer->addEmailInfo($emailInfo);
}
// Email copies are sent as separated emails if their copy method is 'copy' or a customer should not be notified
if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
foreach ($copyTo as $email) {
$emailInfo = Mage::getModel('core/email_info');
$emailInfo->addTo($email);
$mailer->addEmailInfo($emailInfo);
}
}
// Set all required params and send emails
$mailer->setSender(Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId));
$mailer->setStoreId($storeId);
$mailer->setTemplateId($templateId);
$mailer->setTemplateParams(array(
'order' => $order,
'shipment' => $this,
'comment' => $comment,
'billing' => $order->getBillingAddress(),
'payment_html' => $paymentBlockHtml,
//setting the `track number here, A shihpment can have more than one track numbers so seperating by comma`
'tracks' => new Varien_Object(array('tracking_number' => implode(',', $this->getTrackingNumbers())))
)
);
$mailer->send();
return $this;
}
//Creating track number array
public function getTrackingNumbers()
{
$tracks = $this->getAllTracks();
$trackingNumbers = array();
if (count($tracks)) {
foreach ($tracks as $track) {
$trackingNumbers[] = $track->getNumber();
}
}
return $trackingNumbers;
}
}
Step4>> Modify your shipment email tempate subject by adding {{var tracks.track_number}}
I'm trying to write module for add item to row totals in pdf invoice. This is my modules config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Devpassion_Rowtotal>
<version>0.0.1</version>
</Devpassion_Rowtotal>
</modules>
<global>
<pdf>
<totals>
<rowtotal translate="title">
<title>Subtotal less discount</title>
<source_field>rowtotal</source_field>
<model>rowtotal_pdf_model_totalpdf</model>
<font_size>7</font_size>
<display_zero>1</display_zero>
<sort_order>200</sort_order>
</rowtotal>
</totals>
</pdf>
And this is my model class:
class Devpassion_Rowtotal_Pdf_Model_Totalpdf extends Mage_Sales_Model_Order_Pdf_Total_Default {
public function getTotalsForDisplay () {
$order = $this->getOrder();
$item = $this->getItem();
$subtotaldisc = $item->getRowTotal() + $item->getTaxAmount() + $item->getHiddenTaxAmount() ; - $item->getDiscountAmount();
$result = $order->formatPriceTxt($subtotaldisc) ;
$totals = array(array(
'label' => 'Cijena sa popustom',
'amount' => $result,
'font_size' => $fontSize,
)
);
return $totals;
}
}
And nothing shows up on pdf invoice. Can anybody advice please what can be wrong here. Thanks.
I solved my problem, after I looked at my code, there is some mistakes. But my problem is not like yours.
I noticed that you have incorrect code in your config.xml and also in your model class. Try this.
config.xml
<global>
<pdf>
<totals>
<rowtotal translate="title">
<title>Subtotal less discount</title>
<source_field>rowtotal</source_field>
<model>Devpassion_Rowtotal_Pdf_Model_Totalpdf</model>
<font_size>7</font_size>
<display_zero>1</display_zero>
<sort_order>200</sort_order>
</rowtotal>
</totals>
</pdf>
</global>
Model class, Totalpdf.php
class Devpassion_Rowtotal_Pdf_Model_Totalpdf extends Mage_Sales_Model_Order_Pdf_Total_Default {
public function getTotalsForDisplay() {
$order = $this->getOrder();
$item = $this->getItem();
$subtotaldisc = $item->getRowTotal() + $item->getTaxAmount() + $item->getHiddenTaxAmount() - $item->getDiscountAmount();
$result = $order->formatPriceTxt($subtotaldisc);
if($this->getAmountPrefix()){
$result= $this->getAmountPrefix().$result;
}
$fontSize = $this->getFontSize() ? $this->getFontSize() : 7;
$totals = array(array(
'label' => 'Cijena sa popustom:',
'amount' => $result,
'font_size' => $fontSize,
)
);
return $totals;
}
}
I have tried the above code, it doesn't get the value of $item. I have get the subtotal value and discount value from $order object and it worked.
$order = $this->getOrder ();
$subtotaldisc = $order ['subtotal'] + $order ['discount_amount']; //discount amount returns negative value, so add
$result = $order->formatPriceTxt ( $subtotaldisc );
$fontSize = $this->getFontSize () ? $this->getFontSize () : 10;
$totals = array (
array (
'label' => 'Subtotal with Discount',
'amount' => $result,
'font_size' => $fontSize
)
);
return $totals;
I follow #Wakanina answer and change config.xml - path to pdf mode:
<pdf>
<totals>
<rowtotalbezpdv translate="title">
<title>Ukupno s popustom</title>
<source_field>rowtot_alamount</source_field>
<model>Devpassion_Rowtotalbezpdv_Model_Pdf_Total_Totalbezpdf</model>
<font_size>7</font_size>
<display_zero>0</display_zero>
<sort_order>300</sort_order>
</rowtotalbezpdv>
</totals>
</pdf>
And totalpdf Model class:
class Devpassion_Rowtotalbezpdv_Model_Pdf_Total_Totalbezpdf extends Mage_Sales_Model_Order_Pdf_Total_Default
{
public function getTotalsForDisplay(){
$amount = $this->getAmount();
$fontSize = $this->getFontSize() ? $this->getFontSize() : 7;
if(floatval($amount)){
$amount = $this->getOrder()->formatPriceTxt($amount);
$totals = array(
array(
'label' => 'Cijena knjige/a s popustom bez PDV-a',
'amount' => $amount,
'font_size' => $fontSize,
)
);
return $totals;
}
}
public function getAmount(){
$order = $this->getOrder();
$subtotaldiscnopdv = 0;
foreach ($order->getAllItems() as $item) {
$subtotaldiscnopdv += $item->getRowTotal() - $item->getDiscountAmount();
}
return $subtotaldiscnopdv;
}
}
This helps me out and solve my issue.