J'essaie de créer une collection personnalisée pour une grille dans le module d'administration Magento. J'ai créé une nouvelle méthode de collecte appelée "addAttributeHaving" qui fait juste ce qui suit:
public function addAttributeHaving($value)
{
$this->getSelect()->having($value);
return $this;
}
Voir le code de collection:
$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);
Cela produit le SQL suivant qui s'exécute parfaitement et produit les résultats attendus lorsqu'il est exécuté en dehors 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)
Cependant, lorsque j'essaie de charger la grille dans Magento, j'obtiens l'erreur suivante:
SQLSTATE [42S22]: Colonne introuvable: 1054 Colonne inconnue 'DIF_AU' dans 'clause d'avoir'
De plus, si je supprime la clause having (qui casse mes résultats), je peux utiliser la colonne DIF_AU pour une source de données dans la grille.
la source
sd_order_type
vient-il?Réponses:
Je vais effectivement répondre à ma propre question ici. Je sais, collant, mais je suis tombé sur la réponse en regardant de plus près la trace réelle de la pile. La collection se charge bien cependant, l'échec survient un peu plus tard lors de l'exécution lorsque nous essayons d'obtenir le nombre de collections dans Varien_Data_Collection_Db :: getSelectCountSql () . Le SQL qui en résulte est:
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)
Vous remarquerez que l'instruction HAVING est jointe, mais nous n'avons plus de définition pour la colonne DIF_AU. Il semble que j'aurai besoin d'étendre un getSelectCountSql () personnalisé dans ma classe de collection pour obtenir le bon nombre d'enregistrements.
J'ai créé un getSelectCountSql () étendu dans la classe de collection personnalisée qui s'ajoute dans la colonne manquante requise pour l'instruction having.
la source
count(distinct main_table.entity_id)
au lieu decount(*)
Tout d'abord
$countSelect->reset(Zend_Db_Select::HAVING);
, cela signifie qu'il sera réinitialisé àHAVING
partir de votre collection. Cela signifie qu'il supprimera la clause having. Et ce n'est pas ce que vous voulez. Vous pouvez l'ajouter à la collection (app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()
ici.)Mais le principal coupable c'est la
getSize()
méthode qui existe enlib/Varien/Data/Collection/Db.php
dossier.Maintenant, je l'ai fait ci-dessous.
Vérifiez que je n'utilise même pas le
getSelectCountSql()
. Je suis en train de lire l'intégralité de SQL QUERY et de récupérer toutes les données et d'en renvoyer le nombre . C'est tout.la source
J'ai résolu ce problème ici: app / code / core / Mage / Catalogue / Model / Resource / Product / Collection.php: 943 ajoutez ceci: $ select-> reset (Zend_Db_Select :: HAVING);
Copiez simplement app / code / core / Mage / Catalogue / Model / Resource / Product / Collection.php dans app / code / local / Mage / Catalog / Model / Resource / Product / Collection.php
Mon code ressemble maintenant à ceci:
la source
Sous-requête: la sous-requête de table autorise les noms de colonne en double
la source
Cela fonctionne
fonction publique 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); }
la source