Primeiro de tudo, você precisa gerar um módulo personalizado, criar os seguintes arquivos:
/app/etc/modules/Mycompany_Mymodule.xml
/app/design/adminhtml/default/default/layout/mymodule.xml
/app/code/local/Mycompany/Mymodule/Block/adminhtml/Mymodule/Grid.php
/app/code/local/Mycompany/Mymodule/Block/adminhtml/Mymodule.php
/app/code/local/Mycompany/Mymodule/Block/Mymodule.php
/app/code/local/Mycompany/Mymodule/controllers/Adminhtml/MymoduleController.php
/app/code/local/Mycompany/Mymodule/etc/config.xml
/app/code/local/Mycompany/Mymodule/Helper/Data.php
/app/code/local/Mycompany/Mymodule/Model/Mymodule.php
Defina seu módulo em /app/etc/modules/Mycompany_Mymodule.xml :
<?xml version="1.0"?>
<config>
<modules>
<Mycompany_Mymodule>
<active>true</active>
<codePool>local</codePool>
</Mycompany_Mymodule>
</modules>
</config>
Conclua o arquivo de layout que atualizará a visualização do administrador (sempre faço isso primeiro porque não quero esquecê-lo).
/app/design/adminhtml/default/default/layout/mymodule.xml
<?xml version="1.0"?>
<layout version="0.1.0">
<mymodule_adminhtml_mymodule_index>
<reference name="content">
<block type="mymodule/adminhtml_mymodule" name="mymodule" />
</reference>
</mymodule_adminhtml_mymodule_index>
</layout>
Crie o arquivo de configuração com este conteúdo /app/code/local/Mycompany/Mymodule/etc/config.xml :
<?xml version="1.0"?>
<!--
/**
* @category Mycompany
* @package Mycompany_Mymodule
* @author Damian Alberto Pastorini
*/
-->
<config>
<modules>
<Mycompany_Mymodule>
<version>0.1.0</version>
</Mycompany_Mymodule>
</modules>
<admin>
<routers>
<mymodule>
<use>admin</use>
<args>
<module>Mycompany_Mymodule</module>
<frontName>mymodule</frontName>
</args>
</mymodule>
</routers>
</admin>
<adminhtml>
<menu>
<report>
<children>
<mymodule translate="title" module="mymodule">
<title>Mymodule Report</title>
<action>mymodule/adminhtml_mymodule</action>
</mymodule>
</children>
</report>
</menu>
<acl>
<resources>
<all>
<title>Allow Everything</title>
</all>
<admin>
<children>
<report>
<children>
<mymodule translate="title" module="mymodule">
<title>Mymodule Report</title>
<action>mymodule/adminhtml_mymodule</action>
</mymodule>
</children>
</report>
</children>
</admin>
</resources>
</acl>
<layout>
<updates>
<mymodule>
<file>mymodule.xml</file>
</mymodule>
</updates>
</layout>
</adminhtml>
<global>
<models>
<mymodule>
<class>Mycompany_Mymodule_Model</class>
<resourceModel>mymodule</resourceModel>
</mymodule>
</models>
<resources>
<mymodule_setup>
<setup>
<module>Mycompany_Mymodule</module>
</setup>
<connection>
<use>core_setup</use>
</connection>
</mymodule_setup>
<mymodule_write>
<connection>
<use>core_write</use>
</connection>
</mymodule_write>
<mymodule_read>
<connection>
<use>core_read</use>
</connection>
</mymodule_read>
</resources>
<blocks>
<mymodule>
<class>Mycompany_Mymodule_Block</class>
</mymodule>
</blocks>
<helpers>
<mymodule>
<class>Mycompany_Mymodule_Helper</class>
</mymodule>
</helpers>
</global>
</config>
Aqui, definimos o controlador, o acesso e as permissões do menu, o modelo, os blocos e o auxiliar.
Crie a grade e especifique todas as colunas /app/code/local/Mycompany/Mymodule/Block/adminhtml/Mymodule/Grid.php :
<?php
class Mycompany_Mymodule_Block_Adminhtml_Mymodule_Grid extends Mage_Adminhtml_Block_Report_Grid {
public function __construct() {
parent::__construct();
$this->setId('mymoduleGrid');
$this->setDefaultSort('created_at');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
$this->setSubReportSize(false);
}
protected function _prepareCollection() {
parent::_prepareCollection();
$this->getCollection()->initReport('mymodule/mymodule');
return $this;
}
protected function _prepareColumns() {
$this->addColumn('ordered_qty', array(
'header' =>Mage::helper('reports')->__('Quantity Ordered'),
'align' =>'right',
'index' =>'ordered_qty',
'total' =>'sum',
'type' =>'number'
));
$this->addColumn('item_id', array(
'header' => Mage::helper('mymodule')->__('Item ID'),
'align' => 'right',
'index' => 'item_id',
'type' => 'number',
'total' => 'sum',
));
$this->addExportType('*/*/exportCsv', Mage::helper('mymodule')->__('CSV'));
$this->addExportType('*/*/exportXml', Mage::helper('mymodule')->__('XML'));
return parent::_prepareColumns();
}
public function getRowUrl($row) {
return false;
}
public function getReport($from, $to) {
if ($from == '') {
$from = $this->getFilter('report_from');
}
if ($to == '') {
$to = $this->getFilter('report_to');
}
$totalObj = Mage::getModel('reports/totals');
$totals = $totalObj->countTotals($this, $from, $to);
$this->setTotals($totals);
$this->addGrandTotals($totals);
return $this->getCollection()->getReport($from, $to);
}
}
Este arquivo é mais claro, mas eu dou algumas dicas sobre linhas específicas:
// esta linha indica o modelo a ser usado para obter os dados.
$this->getCollection()->initReport('mymodule/mymodule'); // it's used to indicate that this field must be totalized at the end.
'total' =>'sum', // this is executed when you click on the rows grid, in case you return false (like the example) nothing will happen when you click on the rows grid.
public function getRowUrl($row) {
Para a próxima etapa, crie o bloco de contêiner de grade /app/code/local/Mycompany/Mymodule/Block/adminhtml/Mymodule.php :
<?php
class Mycompany_Mymodule_Block_Adminhtml_Mymodule extends Mage_Adminhtml_Block_Widget_Grid_Container {
public function __construct() {
$this->_controller = 'adminhtml_mymodule';
$this->_blockGroup = 'mymodule';
$this->_headerText = Mage::helper('mymodule')->__('Mymodule Report');
parent::__construct();
$this->_removeButton('add');
}
}
Aqui nós adicionamos esta linha para remover o botão Adicionar: // Isso deve ser sempre após a parent::__construct();
linha.$this->_removeButton('add');
Crie o contêiner de bloco /app/code/local/Mycompany/Mymodule/Block/Mymodule.php :
<?php
class Mycompany_Mymodule_Block_Mymodule extends Mage_Core_Block_Template {
public function _prepareLayout() {
return parent::_prepareLayout();
}
public function getMymodule() {
if (!$this->hasData('mymodule')) {
$this->setData('mymodule', Mage::registry('mymodule'));
}
return $this->getData('mymodule');
}
}
Crie o controlador /app/code/local/Mycompany/Mymodule/controllers/Adminhtml/MymoduleController.php :
<?php
class Mycompany_Mymodule_Adminhtml_MymoduleController extends Mage_Adminhtml_Controller_Action {
protected function _initAction() {
$this->loadLayout();
return $this;
}
public function indexAction() {
$this->_initAction()
->renderLayout();
}
public function exportCsvAction() {
$fileName = 'mymodule.csv';
$content = $this->getLayout()->createBlock('mymodule/adminhtml_mymodule_grid')
->getCsv();
$this->_sendUploadResponse($fileName, $content);
}
public function exportXmlAction() {
$fileName = 'mymodule.xml';
$content = $this->getLayout()->createBlock('mymodule/adminhtml_mymodule_grid')
->getXml();
$this->_sendUploadResponse($fileName, $content);
}
protected function _sendUploadResponse($fileName, $content, $contentType='application/octet-stream') {
$response = $this->getResponse();
$response->setHeader('HTTP/1.1 200 OK', '');
$response->setHeader('Pragma', 'public', true);
$response->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
$response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName);
$response->setHeader('Last-Modified', date('r'));
$response->setHeader('Accept-Ranges', 'bytes');
$response->setHeader('Content-Length', strlen($content));
$response->setHeader('Content-type', $contentType);
$response->setBody($content);
$response->sendResponse();
die;
}
}
Em seguida, o auxiliar vazio /app/code/local/Mycompany/Mymodule/Helper/Data.php :
<?php
class Mycompany_Mymodule_Helper_Data extends Mage_Core_Helper_Abstract
{
}
E, por último, criamos o modelo que trará os dados /app/code/local/Mycompany/Mymodule/Model/Mymodule.php :
<?php
class Mycompany_Mymodule_Model_Mymodule extends Mage_Reports_Model_Mysql4_Order_Collection
{
function __construct() {
parent::__construct();
$this->setResourceModel('sales/order_item');
$this->_init('sales/order_item','item_id');
}
public function setDateRange($from, $to) {
$this->_reset();
$this->getSelect()
->joinInner(array(
'i' => $this->getTable('sales/order_item')),
'i.order_id = main_table.entity_id'
)
->where('i.parent_item_id is null')
->where("i.created_at BETWEEN '".$from."' AND '".$to."'")
->where('main_table.state = \'complete\'')
->columns(array('ordered_qty' => 'count(distinct `main_table`.`entity_id`)'));
// uncomment next line to get the query log:
// Mage::log('SQL: '.$this->getSelect()->__toString());
return $this;
}
public function setStoreIds($storeIds)
{
return $this;
}
}
?>
Este é um modelo personalizado que obtém os dados dos modelos principais do Magento. Aqui você pode definir qualquer modelo ou, se você já possui seu próprio banco de dados / tabelas, pode obter os dados do relatório. // essa linha redefine a consulta original que vem por padrão.$this->_reset();
Tentei adicionar todos esses arquivos, mas quando clico no novo item de menu do relatório, uma página em branco é exibida.