0

I am using Magento 1.9.0.1 and right now i am developing a magento extension to add new custom attribute to the order.

I am doing everything by this guide: https://stackoverflow.com/questions/12936470/adding-a-new-attribute-to-order-in-magento You can see the guide as an answer to the question.

So let me show all the files i've created:

1: /app/code/community/VivasIndustries/Vshippingone/etc/config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <VivasIndustries_Vshippingone>
            <version>1.1</version>
        </VivasIndustries_Vshippingone>
    </modules>

    <global> 
         <fieldsets>
            <sales_convert_quote>                           
                <my_custom_input_field_one><to_order>*</to_order></my_custom_input_field_one>
            </sales_convert_quote>

            <sales_convert_order>                                              
                <my_custom_input_field_one><to_quote>*</to_quote></my_custom_input_field_one>
            </sales_convert_order>
        </fieldsets>
        <helpers>
            <vshippingone>
                <class>VivasIndustries_Vshippingone_Helper</class>
            </vshippingone>            
        </helpers>

        <models>
            <vshippingone>
                <class>VivasIndustries_Vshippingone_Model</class>
                <resourceModel>vshippingone_mysql4</resourceModel>
            </vshippingone>
        </models>
        <resources>
            <vshippingone_setup>
                <setup>
                    <module>VivasIndustries_Vshippingone</module>
                    <class>Mage_Sales_Model_Mysql4_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </vshippingone_setup>
            <vshippingone_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </vshippingone_write>
            <vshippingone_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </vshippingone_read>
        </resources>

        <events>
            <adminhtml_sales_order_create_process_data_before>
                <observers>
                    <vshippingone>
                        <type>singleton</type>
                        <class>vshippingone/observer</class>
                        <method>saveCustomDataOne</method>
                    </vshippingone>
                </observers>
            </adminhtml_sales_order_create_process_data_before>
        </events>

        <blocks>
            <vshippingone>
                <class>VivasIndustries_Vshippingone_Block</class>
            </vshippingone>
        </blocks>
    </global>
</config>

2: /app/code/community/VivasIndustries/Vshippingone/Model/Observer.php:

<?PHP
class VivasIndustries_Vshippingone_Model_Observer 
{
    public function saveCustomDataOne($event)
    {
        $quote = $event->getSession()->getQuote();
        $quote->setData('my_custom_input_field_one', $event->getRequestModel()->getPost('my_custom_input_field_one'));

        return $this;
    }
}

3: /app/code/community/VivasIndustries/Vshippingone/sql/vshippingone_setup/mysql4-install-1.1.php

<?php
$installer = $this;
$installer->startSetup();

$installer->addAttribute("order", "my_custom_input_field_one", array("type"=>"varchar"));
$installer->addAttribute("quote", "my_custom_input_field_one", array("type"=>"varchar"));
$installer->endSetup();

4: /app/etc/modules/VivasIndustries_Vshippingone.xml:

<?xml version="1.0"?>
<config>
  <modules>
    <VivasIndustries_Vshippingone>
      <active>true</active>
      <codePool>community</codePool>
      <version>1.1</version>
    </VivasIndustries_Vshippingone>
  </modules>
</config>

By my understanding i've added the following:

In: /app/design/frontend/base/default/template/checkout/onepage/shipping_method/available.phtml - I've added the following line so i can see the input field in the checkout page:

<input type="text" name="my_custom_input_field_one" id="my_custom_input_field_one"></input>

Then in: /app/design/adminhtml/default/default/template/sales/order/view/tab/info.phtml:

I've added the following:

<?php if($_order->getMyCustomInputFieldOne()): ?>
<tr>
    <td class="label"><label><?php echo Mage::helper('sales')->__('My Custom Input Field One') ?></label></td>
    <td class="value"><strong><?php echo $_order->getMyCustomInputFieldOne() ?></strong></td>
</tr>
<?php endif; ?>         

Then i go and submit a new order. Then i go back in the admin panel to see that new order and i can not see the information shown in the admin order view page.

When i remove the if statements i simply see this text My Custom Input Field One but nothing more. I can not see the information inserted in the input field in the checkout page before submiting the order.

This are all the files i have created and edited. Nothing else was made or changed. Perhaps i am forgetting something, but i do not know what, or i have mistake somewhere.

Can you help me out fix it ?

  • Did you clear cache after adding the field to the table? Is the information save to the database? – Renon Stewart Sep 15 '15 at 13:20
  • It seems that the information is saved to the database. I have cleared the cache! – Venelin Vasilev Sep 15 '15 at 13:26
  • What is the value of $_order->getMyCustomInputFieldOne() – Renon Stewart Sep 15 '15 at 13:27
  • In the order i've inserted 12345 but in the admin order view page nothing is shown. I hope i understand your question right. – Venelin Vasilev Sep 15 '15 at 13:34
  • So in sales_flat_order. my_custom_input_field_one = 12345? and when you go to that order in admin it is displaying blank? – Renon Stewart Sep 15 '15 at 13:36
4

For Adding custom attribute, we have to create new column for custom attribute field in sales_flat_order and sales_flat_quote

We can create it By 2 ways

  1. By custom Module Mysql setup file (file path- app/code/local/pwt/singlepagecheckout/sql/singlepagecheckout_setup/mysql4-install-1.1.php)

    Here (pwt -NameSpace, singlepagecheckout-Module)

    $installer = $this;
    $installer->startSetup();
    $installer->addAttribute("order", "delivery_date", array("type"=>"varchar"));
    $installer->addAttribute("quote", "delivery_date", array("type"=>"varchar"));
    $installer->endSetup();
    
  2. If you don't have a own module, simply create a php file in the project's root folder with the below code and run this file manually

    <?php require_once('app/Mage.php');
    Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));
    $installer = new Mage_Sales_Model_Mysql4_Setup;
    $attribute  = array(
        'type'          => 'varchar',
        'backend_type'  => 'varchar',
        'frontend_input' => 'varchar',
        'is_user_defined' => true,
        'label'         => 'Delivery Date,
        'visible'       => true,
        'required'      => false,
        'user_defined'  => false,
        'searchable'    => false,
        'filterable'    => false,
        'comparable'    => false,
        'default'       => "
    );
    $installer->addAttribute('order', 'delivery_date', $attribute);
    $installer->addAttribute('quote', 'delivery_date', $attribute);
    $installer->endSetup();
    
    echo "success";
    

    Run this file on root folder

Now we have allotted a space for our custom attribute in DB (Created new column in sales_flat_order and sales_flat_quote table)

After this, we have to add this custom attribute to global scope in config.xml.

(if you have been using custom module file path is-app/code/local/pwt/singlepagecheckout/etc/config.xml

if not, app/code/core/mage/sales/etc/config.xml. But editing core file isn't good practice )

<global>
   ...
    <fieldsets>
        <sales_convert_quote>                           
            <delivery_date><to_order>*</to_order></delivery_date>
        </sales_convert_quote>

        <sales_convert_order>                                              
            <delivery_date><to_quote>*</to_quote></delivery_date>
        </sales_convert_order>
    </fieldsets>
    ...
</global>

Then create an event in this same config.xml file

<global>
    ...
    <events>
        <checkout_type_onepage_save_order>
        <observers>
            <delivery_date_observer>
                <type>singleton</type>
                <class>singlepagecheckout/observer</class>
                <method>saveCustomData</method>
            </delivery_date_observer>
        </observers>
        </checkout_type_onepage_save_order>
    </events>
    ...
</global>

<class>singlepagecheckout/observer</class> –Edit as per your custom module name (in core file you can simply put sales/observer)

The above event triggers the following observer method

public function saveCustomData($observer)
{
    $event = $observer->getEvent();
    $order = $event->getOrder();
    $fieldVal = Mage::app()->getFrontController()->getRequest()->getParams();
    $order->setDeliveryDate($fieldVal['delivery_date']);
}
0

You can follow the following steps and I am sure it will work.

Step 1: Adding HTML

The following code will add a text field to the billing.phtml file. For magento 1.6(-) the file to edit is checkout/onepage/billing.phtml and for magento 1.6(+) you need to edit file persistent/checkout/onepage/billing.phtml. Open the phtml file, find the code

<?php if ($this->canShip()): ?>

and just above the line add this

<li class="fields">
    <div class="field">
        <label for="billing:ssn" class="required"><em>*</em><?php echo $this->__('SSN') ?></label>
        <div class="input-box">
            <input type="text" name="custom[ssn]" value="<?php echo $this->htmlEscape($this->getQuote()->getSsn()) ?>" title="<?php echo $this->__('SSN') ?>" class="input-text required-entry" id="billing:ssn" />
        </div>
    </div>
</li>

Step2: Save the field in Quote and Order Tables

Create two tables. ‘sales_quote_custom’ for sales and ‘sales_order_custom’for order. Open phpmyadmin and confirm if the quote and order tables are created. Next we need to write some event observers to capture quote save, and load events. So open your modules config.xml file and inside the tag put in

<events>
    <sales_quote_save_before> <!-- Event Called Before Quote Object is saved -->
        <observers>
            <save_before>
                <type>singleton</type>
                <class>Excellence_Custom_Model_Observer</class> <!-- Over Model Class -->
                <method>saveQuoteBefore</method> <!-- name of function -->
            </save_before>
        </observers>
    </sales_quote_save_before>
    <sales_quote_save_after> <!-- Event called After Quote Object is saved -->
        <observers>
            <save_after>
                <type>singleton</type>
                <class>Excellence_Custom_Model_Observer</class> <!-- Over Model Class -->
                <method>saveQuoteAfter</method> <!-- name of function -->
            </save_after>
        </observers>
    </sales_quote_save_after>
    <sales_quote_load_after> <!-- Event called when Quote Object is loaded -->
        <observers>
            <load_after>
                <type>singleton</type>
                <class>Excellence_Custom_Model_Observer</class> <!-- Over Model Class -->
                <method>loadQuoteAfter</method> <!-- name of function -->
            </load_after>
        </observers>
    </sales_quote_load_after>
    <sales_model_service_quote_submit_after> <!-- Event called after order placed -->
        <observers>
            <sales_model_service_quote_submit_after>
                <type>singleton</type>
                <class>Excellence_Custom_Model_Observer</class> <!-- Over Model Class -->
                <method>saveOrderAfter</method> <!-- name of function -->
            </sales_model_service_quote_submit_after>
        </observers>
    </sales_model_service_quote_submit_after>
    <sales_order_load_after> <!-- Event called after Order Object is loaded -->
        <observers>
            <sales_order_load_after>
                <type>singleton</type>
                <class>Excellence_Custom_Model_Observer</class> <!-- Over Model Class -->
                <method>loadOrderAfter</method> <!-- name of function -->
            </sales_order_load_after>
        </observers>
    </sales_order_load_after>
</events>

and next we need to create our Observer classes in Model folder. So create an Observer.php in your modules Model folder.

<?php
class Excellence_Custom_Model_Observer
{

    public function saveQuoteBefore($evt)
    {
        $quote = $evt->getQuote();
        $post = Mage::app()->getFrontController()->getRequest()->getPost();
        if (isset($post['custom']['ssn'])) {
            $var = $post['custom']['ssn'];
            $quote->setSsn($var);
        }
    }

    public function saveQuoteAfter($evt)
    {
        $quote = $evt->getQuote();
        if ($quote->getSsn()) {
            $var = $quote->getSsn();
            if (!empty($var)) {
                $model = Mage::getModel('custom/custom_quote');
                $model->deteleByQuote($quote->getId(), 'ssn');
                $model->setQuoteId($quote->getId());
                $model->setKey('ssn');
                $model->setValue($var);
                $model->save();
            }
        }
    }

    public function loadQuoteAfter($evt)
    {
        $quote = $evt->getQuote();
        $model = Mage::getModel('custom/custom_quote');
        $data = $model->getByQuote($quote->getId());
        foreach ($data as $key => $value) {
            $quote->setData($key, $value);
        }
    }

    public function saveOrderAfter($evt)
    {
        $order = $evt->getOrder();
        $quote = $evt->getQuote();
        if ($quote->getSsn()) {
            $var = $quote->getSsn();
            if (!empty($var)) {
                $model = Mage::getModel('custom/custom_order');
                $model->deleteByOrder($order->getId(), 'ssn');
                $model->setOrderId($order->getId());
                $model->setKey('ssn');
                $model->setValue($var);
                $order->setSsn($var);
                $model->save();
            }
        }
    }

    public function loadOrderAfter($evt)
    {
        $order = $evt->getOrder();
        $model = Mage::getModel('custom/custom_order');
        $data = $model->getByOrder($order->getId());
        foreach ($data as $key => $value) {
            $order->setData($key, $value);
        }
    }

}

Step3: Display Our Field in My Account -> View Order

After the order is placed by the customer, our custom fields needs to be visible in My Account. So to do this in our module fronted layout file, in my case its custom.xml.

<?xml version="1.0"?>
<layout version="0.1.0">
    <sales_order_view>
        <reference name="my.account.wrapper">
            <block type="custom/custom_order" name="custom.order" template="custom/order.phtml" after='sales.order.info' />
        </reference>
    </sales_order_view>
</layout>

This layout file is simple and understandable. Basically, we are taking reference of my.account.wrapper block and adding a child block to it. Our block type is custom/order_view and template file is custom/order.phtml. So we need to create our block class

<?php

class Excellence_Custom_Block_Custom_Order extends Mage_Core_Block_Template
{

    public function getCustomVars()
    {
        $model = Mage::getModel('custom/custom_order');
        return $model->getByOrder($this->getOrder()->getId());
    }

    public function getOrder()
    {
        return Mage::registry('current_order');
    }

}

and our order.phtml file

<div class="col-set order-info-box">
    <div class="col">
        <div class="box">
            <div class="box-title">
                <h2><?php echo $this->__('Custom Fields') ?></h2>
            </div>
            <div class="box-content">
                <?php
                $custom = $this->getCustomVars();
                foreach ($custom as $key => $value) {
                    ?>
                    <b><?php echo $this->__($key); ?></b> : <?php echo $value; ?> <br/>
                <?php } ?>
            </div>
        </div>
    </div>
</div>

Step4: Admin Order View Page

Next we need to show our custom field in Admin -> Order -> View Order page. To do this, in our adminhtml layout file, in my case custom.xml we will put in this code.

<?xml version="1.0"?>
<layout version="0.1.0">
    <adminhtml_sales_order_view>
        <reference name="order_info">
            <action method='setTemplate'>
                <template>custom/sales/order/info.phtml</template>
            </action>
            <block type="adminhtml/sales_order_view_info" name="order_info2" template="sales/order/view/info.phtml"></block>
            <block type="custom/adminhtml_custom_order" name="custom.order" template='custom/order.phtml'/>
        </reference>
    </adminhtml_sales_order_view>
</layout>

So basically here we have added my block “custom.order” to the existing order_info block. So the code for block class custom/adminhtml_custom_order would be

<?php

class Excellence_Custom_Block_Adminhtml_Custom_Order extends Mage_Adminhtml_Block_Sales_Order_Abstract
{

    public function getCustomVars()
    {
        $model = Mage::getModel('custom/custom_order');
        return $model->getByOrder($this->getOrder()->getId());
    }

}

and next we need to create their phtml files

custom/order.phtml

<?php $_order = $this->getOrder() ?>
<div class="box-left">
    <div class="entry-edit">
        <div class="entry-edit-head">
            <h4 class="icon-head head-account"><?php echo Mage::helper('sales')->__('Custom Fields') ?></h4>
        </div>
        <div class="fieldset">
            <table cellspacing="0" class="form-list">
                <?php
                $custom = $this->getCustomVars();
                foreach ($custom as $key => $value) {
                    ?>
                    <tr>
                        <td style="width:10%" class="label"><strong><?php echo Mage::helper('sales')->__($key) ?></strong></td>
                        <td class="value"><?php echo $value; ?></td>
                    </tr>
                <?php } ?>
            </table>
        </div>
    </div>
</div>
<div class="clear"></div>

custom/sales/order/info.phtml

<?php echo $this->getChildHtml('order_info2');?>
<?php echo $this->getChildHtml('custom.order');?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.