MyPage is a personalized page based on your interests.The page is customized to help you to find content that matters you the most.


I'm not curious

How to Create a Custom Product Option for your Magento Store?

Published on 11 May 15
0
2
There are times when you want to add a custom option for a particular product listed on your Magento store. As an example, we will consider using Delivery Date as the custom option. With this custom option, customers can easily choose the delivery date for the product ordered by them. There is a need to add a special sales grid at the backend. The new grid will have all the options from the existing grid plus the delivery option that has been added.

Open any product (Example product) in the backend of your store, go to Catalog>Manage Products>Custom Option tab. Add delivery date option in here. With this you have set the custom product option for a particular product. Now, you need to know how to create a grid for this custom option.

Begin with Announcing the Module
You will need to create a new module Example_DateOrder.xml in this path app/etc/modules. Paste the following code to this xml file.

<?xml version="1.0"?>
<config>
<modules>
<Example_DateOrder>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Adminhtml />
</depends>
</Example_DateOrder>
</modules>
</config>

Create the Necessary Configuration File
Create config.xml in the following path app/code/local/Example/DateOrder/etc/. Paste the following code to this file

<?xml version="1.0"?>
<config>
<modules>
<Example_DateOrder>
<version>1.0.0.0</version>
</Example_DateOrder>
</modules>
<global>
<blocks>
<operations_adminhtml>
<class>Example_DateOrder_Block_Adminhtml</class>
</operations_adminhtml>
</blocks>
<helpers>
<operations>
<class>Example_DateOrder_Helper</class>
</operations>
</helpers>
</global>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<Example_dateorder after="Mage_Adminhtml">Example_DateOrder_Adminhtml</Example_dateorder>
</modules>
</args>
</adminhtml>
</routers>
</admin>
<adminhtml>
<!-- <translate> -->
<!-- <modules> -->
<!-- <Example_DateOrder> -->
<!-- <files> -->
<!-- <default>Example_DateOrder.csv</default> -->
<!-- </files> -->
<!-- </Example_DateOrder> -->
<!-- </modules> -->
<!-- </translate> -->
<layout>
<updates>
<operations>
<file>operations.xml</file>
</operations>
</updates>
</layout>
</adminhtml>
</config>

The translate node has been written down under the adminhtml xml node. In case you want the sentences to be translated into some other language, you will need to uncomment the lines and missing sentences.

Create Menu Items with ACL Permissions
Create adminhtml.xml in the app/code/local/example/dateorder/etc path. You can paste the following code to this path

<?xml version="1.0"?>
<config>
<menu>
<sales>
<children>
<operations translate="title" module="operations">
<title>Operations</title>
<sort_order>1</sort_order>
<action>adminhtml/operations_order</action>
</operations>
</children>
</sales>
</menu>
<acl>
<resources>
<admin>
<children>
<sales>
<children>
<operations translate="title">
<title>Operations</title>
<sort_order>1</sort_order>
</operations>
</children>
</sales>
</children>
</admin>
</resources>
</acl>
</config>

Create the Controller File
The next step is to create a controller file along the path

app/code/local/Example/DateOrder/controllers/Adminhtml/Operations/OrderController.php

Paste the following code to this path

<?php

/**
* Adminhtml sales operations controller
*
* @category Example
* @package Example_DateOrder
*/
class Example_DateOrder_Adminhtml_Operations_OrderController extends Mage_Adminhtml_Controller_Action
{

/**
* Additional initialization
*
*/
protected function _construct()
{
$this->setUsedModuleName('Example_DateOrder');
}

/**
* Init layout, menu and breadcrumb
*
* @return Example_DateOrder_Adminhtml_Operations_OrderController
*/
protected function _initAction()
{
$this->loadLayout()
->_setActiveMenu('sales/order')
->_addBreadcrumb($this->__('Sales'), $this->__('Sales'))
->_addBreadcrumb($this->__('Operations'), $this->__('Operations'));
return $this;
}

/**
* Orders grid
*/
public function indexAction()
{
$this->_title($this->__('Sales'))->_title($this->__('Operations'));

$this->_initAction()
->renderLayout();
}

/**
* Order grid
*/
public function gridAction()
{
$this->loadLayout(false);
$this->renderLayout();
}

/**
* Export order grid to CSV format
*/
public function exportCsvAction()
{
$fileName = 'operations.csv';
$grid = $this->getLayout()->createBlock('operations_adminhtml/operations_order_grid');
$this->_prepareDownloadResponse($fileName, $grid->getCsvFile());
}

/**
* Export order grid to Excel XML format
*/
public function exportExcelAction()
{
$fileName = 'operations.xml';
$grid = $this->getLayout()->createBlock('operations_adminhtml/operations_order_grid');
$this->_prepareDownloadResponse($fileName, $grid->getExcelFile($fileName));
}

}

Create the Helper File
Paste the following code to the path app/code/local/Example/DateOrder/Helper/Data.php

<?php
/**
* Operations data helper
*
* @category Example
* @package Example_DateOrder
*/
class Example_DateOrder_Helper_Data extends Mage_Core_Helper_Abstract
{
}

Create the Block

Begin with creating initial block. Create the initial block along the path app/code/local/Example/DateOrder/Block/Adminhtml/Operations/Order.php

Paste the following code to this block

<?php

/**
* Adminhtml operations orders block
*
* @category Example
* @package Example_DateOrder
*/
class Example_DateOrder_Block_Adminhtml_Operations_Order extends Mage_Adminhtml_Block_Widget_Grid_Container
{

public function __construct()
{
$this->_controller = 'operations_order';
$this->_blockGroup = 'operations_adminhtml';
$this->_headerText = Mage::helper('operations')->__('Operations');
$this->_addButtonLabel = Mage::helper('sales')->__('Create New Order');
parent::__construct();
if (!Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/create')) {
$this->_removeButton('add');
}
}
}

Next, you will need to create the grid block along the path app/code/local/Example/DateOrder/Block/Adminhtml/Operations/Order/Grid.php

Paste the following code to this path

<?php

/**
* Adminhtml operations orders grid
*
* @category Example
* @package Example_DateOrder
*/
class Example_DateOrder_Block_Adminhtml_Operations_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
/**
* Note that I could extend Mage_Adminhtml_Block_Sales_Order_Grid instead of Mage_Adminhtml_Block_Widget_Grid
* and overwrite only methods __construct() & _prepareColumns()
*/

public function __construct()
{
parent::__construct();
$this->setId('operations_order_grid');
$this->setUseAjax(true);
$this->setDefaultSort('created_at');
$this->setDefaultDir('DESC');
$this->setSaveParametersInSession(true);
}

/**
* Retrieve collection class
*
* @return string
*/
protected function _getCollectionClass()
{
return 'sales/order_grid_collection';
}

protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
$this->setCollection($collection);
return parent::_prepareCollection();
}

protected function _prepareColumns()
{

$this->addColumn('real_order_id', array(
'header'=> Mage::helper('sales')->__('Order #'),
'width' => '80px',
'type' => 'text',
'index' => 'increment_id',
));

if (!Mage::app()->isSingleStoreMode()) {
$this->addColumn('store_id', array(
'header' => Mage::helper('sales')->__('Purchased From (Store)'),
'index' => 'store_id',
'type' => 'store',
'store_view'=> true,
'display_deleted' => true,
));
}

$this->addColumn('created_at', array(
'header' => Mage::helper('sales')->__('Purchased On'),
'index' => 'created_at',
'type' => 'datetime',
'width' => '100px',
));

$this->addColumn('billing_name', array(
'header' => Mage::helper('sales')->__('Bill to Name'),
'index' => 'billing_name',
));

$this->addColumn('shipping_name', array(
'header' => Mage::helper('sales')->__('Ship to Name'),
'index' => 'shipping_name',
));

$this->addColumn('delivery_date', array(
'header' => Mage::helper('operations')->__('Delivery Date'),
'index' => 'entity_id',
'sortable' => false,
'filter' => false,
'renderer' => 'operations_adminhtml/operations_order_renderer_delivery',
));

$this->addColumn('base_grand_total', array(
'header' => Mage::helper('sales')->__('G.T. (Base)'),
'index' => 'base_grand_total',
'type' => 'currency',
'currency' => 'base_currency_code',
));

$this->addColumn('grand_total', array(
'header' => Mage::helper('sales')->__('G.T. (Purchased)'),
'index' => 'grand_total',
'type' => 'currency',
'currency' => 'order_currency_code',
));

$this->addColumn('status', array(
'header' => Mage::helper('sales')->__('Status'),
'index' => 'status',
'type' => 'options',
'width' => '70px',
'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
));

if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
$this->addColumn('action',
array(
'header' => Mage::helper('sales')->__('Action'),
'width' => '50px',
'type' => 'action',
'getter' => 'getId',
'actions' => array(
array(
'caption' => Mage::helper('sales')->__('View'),
'url' => array('base'=>'*/sales_order/view'),
'field' => 'order_id'
)
),
'filter' => false,
'sortable' => false,
'index' => 'stores',
'is_system' => true,
));
}
$this->addRssList('rss/order/new', Mage::helper('sales')->__('New Order RSS'));

$this->addExportType('*/*/exportCsv', Mage::helper('sales')->__('CSV'));
$this->addExportType('*/*/exportExcel', Mage::helper('sales')->__('Excel XML'));

return parent::_prepareColumns();
}

protected function _prepareMassaction()
{
$this->setMassactionIdField('entity_id');
$this->getMassactionBlock()->setFormFieldName('order_ids');
$this->getMassactionBlock()->setUseSelectAll(false);

if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/cancel')) {
$this->getMassactionBlock()->addItem('cancel_order', array(
'label'=> Mage::helper('sales')->__('Cancel'),
'url' => $this->getUrl('*/sales_order/massCancel'),
));
}

if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/hold')) {
$this->getMassactionBlock()->addItem('hold_order', array(
'label'=> Mage::helper('sales')->__('Hold'),
'url' => $this->getUrl('*/sales_order/massHold'),
));
}

if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/unhold')) {
$this->getMassactionBlock()->addItem('unhold_order', array(
'label'=> Mage::helper('sales')->__('Unhold'),
'url' => $this->getUrl('*/sales_order/massUnhold'),
));
}

$this->getMassactionBlock()->addItem('pdfinvoices_order', array(
'label'=> Mage::helper('sales')->__('Print Invoices'),
'url' => $this->getUrl('*/sales_order/pdfinvoices'),
));

$this->getMassactionBlock()->addItem('pdfshipments_order', array(
'label'=> Mage::helper('sales')->__('Print Packingslips'),
'url' => $this->getUrl('*/sales_order/pdfshipments'),
));

$this->getMassactionBlock()->addItem('pdfcreditmemos_order', array(
'label'=> Mage::helper('sales')->__('Print Credit Memos'),
'url' => $this->getUrl('*/sales_order/pdfcreditmemos'),
));

$this->getMassactionBlock()->addItem('pdfdocs_order', array(
'label'=> Mage::helper('sales')->__('Print All'),
'url' => $this->getUrl('*/sales_order/pdfdocs'),
));

$this->getMassactionBlock()->addItem('print_shipping_label', array(
'label'=> Mage::helper('sales')->__('Print Shipping Labels'),
'url' => $this->getUrl('*/sales_order_shipment/massPrintShippingLabel'),
));

return $this;
}

public function getRowUrl($row)
{
if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
return $this->getUrl('*/sales_order/view', array('order_id' => $row->getId()));
}
return false;
}

public function getGridUrl()
{
return $this->getUrl('*/*/grid', array('_current'=>true));
}
}

Finally, you need to create a renderer file for the grid block. You can create this file along the path app/code/local/Example/DateOrder/Block/Adminhtml/Operations/Order/Renderer/Delivery.php

Paste the following code to this path

<?php

/**
* Adminhtml operations orders grid renderer
*
* @category Example
* @package Example_DateOrder
*/
class Example_DateOrder_Block_Adminhtml_Operations_Order_Renderer_Delivery
extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
//load first item of the order
$orderItem = Mage::getResourceModel('sales/order_item_collection')
->addFieldToFilter('order_id', $row->getId())
->getFirstItem()
;

$orderItemOptions = $orderItem->getProductOptions();

//if product doesn't have options stop with rendering
if (!array_key_exists('options', $orderItemOptions)) {
return;
}

$orderItemOptions = $orderItemOptions['options'];

//if product options isn't array stop with rendering
if (!is_array($orderItemOptions)) {
return;
}

foreach ( $orderItemOptions as $orderItemOption) {

if ($orderItemOption['label'] === 'Delivery Date') {
if (array_key_exists('value', $orderItemOption)) {
return $orderItemOption['value'];
}
}
}
//if product options doesn't have Delivery Date custom option return void
return;
}
}

Add the Blocks to the Layout
Finally, you will need to add the blocks you have just created to the Magento layout. Create the necessary file along the path app/design/adminhtml/default/default/layout/operations.xml. Paste the following code to this path

<?xml version="1.0"?>
<layout>
<adminhtml_operations_order_grid>
<update handle="formkey"/>
<block type="operations_adminhtml/operations_order_grid" name="operations_order.grid" output="toHtml"></block>
</adminhtml_operations_order_grid>

<adminhtml_operations_order_index>
<reference name="content">
<block type="operations_adminhtml/operations_order" name="operations_order.grid.container"></block>
</reference>
</adminhtml_operations_order_index>
</layout>

With this, you have created and added the custom product option to your Magento store. with the operations menu added to the admin panel, you can get started with this new grid in the backend.

Conclusion
This is just an example of adding the custom option to your store. Similar to delivery date, there are other custom options that your customer might want to enter from the front end. You can make provisions for the same using the code given above.

Note: Don't forget to take a backup before you get started with this coding.
This blog is listed under Development & Implementations and E-Commerce Community

Related Posts:
Post a Comment

Please notify me the replies via email.

Important:
  • We hope the conversations that take place on MyTechLogy.com will be constructive and thought-provoking.
  • To ensure the quality of the discussion, our moderators may review/edit the comments for clarity and relevance.
  • Comments that are promotional, mean-spirited, or off-topic may be deleted per the moderators' judgment.
You may also be interested in
 
Awards & Accolades for MyTechLogy
Winner of
REDHERRING
Top 100 Asia
Finalist at SiTF Awards 2014 under the category Best Social & Community Product
Finalist at HR Vendor of the Year 2015 Awards under the category Best Learning Management System
Finalist at HR Vendor of the Year 2015 Awards under the category Best Talent Management Software
Hidden Image Url

Back to Top