Estoy tratando de construir una colección personalizada para una cuadrícula en el módulo de administración de Magento. He creado un nuevo método de colección llamado "addAttributeHaving" que solo hace lo siguiente:
public function addAttributeHaving($value)
{
$this->getSelect()->having($value);
return $this;
}
Ver código de colección:
$collection->addFieldToSelect(
array(
'entity_id',
'created_at',
'increment_id',
'customer_email',
'customer_firstname',
'customer_lastname',
'grand_total',
'status'
)
);
$collection->getSelect()->joinLeft(array('sfop' => 'sales_flat_order_payment'), 'main_table.entity_id = sfop.parent_id', 'sfop.amount_authorized');
$collection->getSelect()->columns('sum(sfop.amount_authorized) AS AUTHD');
$collection->getSelect()->columns('grand_total - sum(sfop.amount_authorized) AS DIF_AU');
$collection->addFieldToFilter('main_table.state', array('in' => array('new','payment_review')));
$collection->addFieldToFilter('main_table.sd_order_type', array('neq' => 7));
$collection->addFieldToFilter('sfop.method', array('neq' => 'giftcard'));
$collection->addFieldToFilter('main_table.created_at', array('gt' => $this->getFilterDate()));
$collection->getSelect()->group(array('main_table.entity_id'));
$collection->addAttributeHaving('DIF_AU <> 0');
$collection->load(true,true);
$this->setCollection($collection);
Esto produce el siguiente SQL que se ejecuta perfectamente bien y produce los resultados esperados cuando se ejecuta fuera de Magento.
[METHOD=Varien_Data_Collection_Db->printLogQuery] SELECT `main_table`.`entity_id`, `main_table`.`entity_id`, `main_table`.`created_at`, `main_table`.`increment_id`, `main_table`.`customer_email`, `main_table`.`customer_firstname`, `main_table`.`customer_lastname`, `main_table`.`grand_total`, `main_table`.`status`, `sfop`.`amount_authorized`, sum(sfop.amount_authorized) AS `AUTHD`, grand_total - sum(sfop.amount_authorized) AS `DIF_AU` FROM `sales_flat_order` AS `main_table` LEFT JOIN `sales_flat_order_payment` AS `sfop` ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('new', 'payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY `main_table`.`entity_id` HAVING (DIF_AU <> 0)
Sin embargo, cuando intento cargar la cuadrícula dentro de Magento me sale el siguiente error:
SQLSTATE [42S22]: columna no encontrada: 1054 Columna desconocida 'DIF_AU' en 'tener cláusula'
Además, si elimino la cláusula have (que rompe mis resultados), puedo usar la columna DIF_AU para un origen de datos en la cuadrícula.
fuente
sd_order_type
viene eso ?Respuestas:
Realmente voy a responder mi propia pregunta aquí. Lo sé, de mal gusto, pero me topé con la respuesta al mirar mucho más de cerca el rastro real de la pila. La colección se está cargando bien, sin embargo, la falla llega un poco más tarde en la ejecución cuando intentamos obtener el recuento de la colección en Varien_Data_Collection_Db :: getSelectCountSql () . El SQL que se produce a partir de esto es:
SELECT COUNT(*) FROM sales_flat_order AS main_table LEFT JOIN sales_flat_order_payment AS sfop ON main_table.entity_id = sfop.parent_id WHERE (main_table.state in ('payment_review')) AND (main_table.sd_order_type != 7) AND (sfop.method != 'giftcard') AND (main_table.created_at > '2013-04-07') GROUP BY main_table.entity_id HAVING (DIF_AU <> 0)
Notará que la declaración HAVING está adjunta, pero ya no tenemos una definición para la columna DIF_AU. Parece que tendré que extender un getSelectCountSql () personalizado en mi clase de colección para obtener el recuento de registros correcto.
He creado un getSelectCountSql () extendido en la clase de colección personalizada que se agrega de nuevo en la columna faltante requerida para la instrucción have.
fuente
count(distinct main_table.entity_id)
lugar decount(*)
En primer lugar,
$countSelect->reset(Zend_Db_Select::HAVING);
significa que se restableceráHAVING
desde su colección. Eso significa que eliminará la cláusula have. Y no es lo que quieres. Es posible que desee agregarlo a la colección (app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()
aquí).Pero el principal culpable es el
getSize()
método que existe en ellib/Varien/Data/Collection/Db.php
archivo.Ahora hice lo siguiente.
Comprueba que ni siquiera estoy usando el
getSelectCountSql()
. Solo estoy leyendo toda la CONSULTA SQL y obteniendo todos los datos y devuelvo el recuento . Eso es todo.fuente
Solucioné este problema aquí: app / code / core / Mage / Catalog / Model / Resource / Product / Collection.php: 943 agregue esto: $ select-> reset (Zend_Db_Select :: HAVING);
Simplemente copie app / code / core / Mage / Catalog / Model / Resource / Product / Collection.php a app / code / local / Mage / Catalog / Model / Resource / Product / Collection.php
Mi código ahora se ve así:
fuente
Subconsulta: la subconsulta de tabla permite nombres de columna duplicados
fuente
Esto esta funcionando
función pública getSize () {if (is_null ($ this -> _ totalRecords)) {// $ sql = $ this-> getSelectCountSql (); $ sql = $ this-> getSelect (); $ this -> _ totalRecords = count ($ this-> getConnection () -> fetchAll ($ sql, $ this -> _ bindParams)); } return intval ($ this -> _ totalRecords); }
fuente