我想在Magento管理面板中可见的发票网格中预过滤*数据。
Here是我之前提出的一个问题,这个问题与为此提出的解决方案有关,因此它可能是一个很好的解释。
所以,我正在修改Mage_Adminhtml_Block_Sales_Invoice_Grid :: _ prepareCollection方法,以便它首先获取登录管理员引用的客户。然后它将从这些客户获取订单 - 理想情况下只有订单ID - 然后将此集合加入 sales / order_invoice_grid ,以便为此管理员列出发票。
根据最后一个答案并使用these文档,以下是我尝试加入此信息的3种方式:(代码示例1)
$collection = Mage::getResourceModel('customer/customer_collection');
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('*'));
$collection->joinTable('sales/invoice_grid', 'order_id=main_table.entity_id', array('*'));
当我执行上述操作时,我看到以下错误:
A joint field with this alias (0) is already declared.
#0 /var/www/magento/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php(706): Mage::exception('Mage_Eav', 'A joint field w...')
#1 /var/www/magento/app/code/local/Myproject/Adminhtml/Block/Sales/Invoice/Grid.php(41): Mage_Eav_Model_Entity_Collection_Abstract->joinTable('sales/invoice_g...', 'order_id=main_t...', Array)
#2 /var/www/magento/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(576): Myproject_Adminhtml_Block_Sales_Invoice_Grid->_prepareCollection()
#3 /var/www/magento/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php(582): Mage_Adminhtml_Block_Widget_Grid->_prepareGrid()
如果我删除对joinTable的第二次调用,上面的代码可以正常工作,但这不是我想要的。
我尝试的另一种方法是使用此代码:
$collection = Mage::getResourceModel('customer/customer_collection');
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('entity_id as order_entity_id'));
$collection->joinTable('sales/invoice_grid', 'order_id=main_table.entity_id', array('*'));
这里错误出现在第二行,我实际上试图将字段order.entity_id别名,以便它不与发票表entity_id冲突。但是会产生如下错误:
物品(Mage_Customer_Model_Customer) 具有相同ID“1”已存在
我只需要订单ID,以便我可以获得相关的发票,这表明我也可以使用joinField函数,我尝试如下:
$collection = Mage::getResourceModel('customer/customer_collection');
$collection->joinField('order_entity_id', 'sales/order_grid', 'entity_id', 'customer_id=entity_id' , null, 'left');
但它给了我以下错误:
具有相同ID“1”的项目(Mage_Customer_Model_Customer)已存在
我正在寻找加入客户>发票的解决方案。
通过预过滤我的意思是即使在网格中出现任何内容之前,网格中列出的数据也会被过滤。
好的,现在我的代码看起来像:
$collection =
Mage::getResourceModel('customer/customer_collection');
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('entity_id' => 'order_entity_id'));
我得到的错误是:
SELECT `e`.*, `sales_flat_order_grid`.`order_entity_id` AS `entity_id` FROM `customer_entity` AS `e`
INNER JOIN `sales_flat_order_grid` ON (sales_flat_order_grid.customer_id=e.entity_id) WHERE (e.entity_type_id = '1') ORDER BY `e`.`created_at` desc, `e`.`created_at` desc LIMIT 20
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sales_flat_order_grid.order_entity_id' in 'field list'
答案 0 :(得分:9)
以下是我的测试脚本的总数。要使用它放在Magento根目录下的文件中并直接在浏览器中输入它的URL,Magento的控制器不会处理它。这是一种很好的实验方法,因为它不受其他模块,页面布局等的影响。
<pre><?php
require 'app/Mage.php';
Mage::app();
$collection = Mage::getResourceModel('customer/customer_collection');
$collection->getSelect()->reset('columns');
$collection->joinTable('sales/order_grid', 'customer_id=entity_id', array('order_entity_id' => 'entity_id'));
$collection->joinTable('sales/invoice_grid', 'order_id=order_entity_id', array('*'));
foreach ($collection as $invoice)
print_r($invoice->debug());
?></pre>
与上一个问题一样,我选择重置初始列,因为我不相信为数据库提供超出必要的工作量。然而,它并不重要,没有它,测试仍然会成功。
如果这在您的安装中不起作用,那么我们需要考虑外部影响可能是什么。
答案 1 :(得分:2)
错误“已声明具有此别名(0)的联合字段。”因为它使用数组键作为别名而发生。由于你有两个joinTable()
调用,每个都有一个数组,它试图使用两者的从零开始的索引,显然存在冲突。
而不是
array('entity_id as order_entity_id')
试
array('entity_id' => 'order_entity_id')
避免冲突。
答案 2 :(得分:2)
我终于通过发票 - &gt;订单 - &gt;客户实现了这一点,因为'Anda B'建议。我只是在这里粘贴我的解决方案作为参考,但将使用来自this的clockworkgeek解决方案,因为它看起来更清晰。而且我的解决方案仍然需要通过在运行时从数据库中获取eav_attribute(agent_id)的'id'而不是硬编码,如此粘贴在这里:
class Myproject_Adminhtml_Block_Sales_Invoice_Grid extends Mage_Adminhtml_Block_Sales_Invoice_Grid
{
const AGENT_ID_ATTRIBUTE_ID = 118;
protected function _prepareCollection()
{
$collection = Mage::getResourceModel($this->_getCollectionClass());
$collection->join('order_grid', 'order_id = order_grid.entity_id', array ('order_entity_id' => 'order_grid.entity_id'));
$collection->getSelect()->join( 'customer_entity', 'customer_id = customer_entity.entity_id', array('customer_entity_id' => 'entity_id', 'email'));
$collection->getSelect()->joinLeft( 'customer_entity_int', 'customer_entity_int.entity_id = customer_entity.entity_id AND attribute_id = ' . Myproject_Adminhtml_Block_Sales_Invoice_Grid::AGENT_ID_ATTRIBUTE_ID,
array('attribute_entity_id' => 'customer_entity_int.entity_id', 'attribute_id' , 'value'));
//Apply Desired Data Filters here
$this->setCollection($collection);
return $collection;
答案 3 :(得分:1)
它给你这个错误“具有相同id”1“的Item(Mage_Customer_Model_Customer)已经存在”因为一个客户可以有多个订单,因此可能有两个或多个具有相同客户ID的条目 - 你正在创建一个集合客户和您必须在集合中具有唯一条目。 您必须从发票开始并与客户一起加入。
答案 4 :(得分:1)
我从magento论坛发现的最简单的方法,
在
中protected function _prepareCollection()
{
$collection = Mage::getResourceModel('customer/customer_collection')
我们可以将自定义查询用作
$collection->getSelect()->columns(array('filename' => new Zend_Db_Expr ("(SELECT filename FROM cat WHERE customer_id =e.entity_id)")));
并且有效
$this->setCollection($collection);
var_dump($collection);