Magento संग्रह में "होने" का उपयोग कर मुद्दा


20

मैं Magento के व्यवस्थापक मॉड्यूल में ग्रिड के लिए एक कस्टम संग्रह बनाने की कोशिश कर रहा हूं। मैंने "addAttributeHaving" नामक एक नई संग्रह विधि बनाई है, जो निम्नलिखित कार्य करती है:

public function addAttributeHaving($value)
{
    $this->getSelect()->having($value);
    return $this;
}

संग्रह कोड देखें:

$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);

यह निम्न SQL का उत्पादन करता है जो पूरी तरह से ठीक निष्पादित करता है और 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)

हालाँकि, जब मैं Magento के अंदर ग्रिड को लोड करने की कोशिश करता हूँ तो मुझे निम्नलिखित त्रुटि मिलती है:

SQLSTATE [42S22]: कॉलम नहीं मिला: 1054 अज्ञात कॉलम 'DIF_AU' में 'क्लॉज' होना

इसके अतिरिक्त, यदि मैं होने वाले क्लॉज (जो मेरे परिणाम तोड़ता है) को हटा देता हूं, तो मैं ग्रिड में एक डेटा स्रोत के लिए DIF_AU कॉलम का उपयोग करने में सक्षम हूं।


1
अद्यतन: मैं मूल getSelectCountSql () विधि के लिए समस्या को ट्रैक करने में सक्षम था। यह वास्तव में वह जगह है जहां संग्रह गिनती प्राप्त करने की कोशिश करते समय समस्या हो रही है।
एंथनी लीच जूनियर

1
उत्तर पोस्ट करें! WTH है कि से sd_order_typeआ रहा है?
बेंचमार्क

1
शीर्ष गुप्त कस्टम ऑर्डर प्रकार का सामान जो फ्लैट तालिकाओं में जोड़ा गया है। मैं अभी भी जवाब दे रहा हूं।
एन्थोनी लीच जूनियर

1
"10 से कम प्रतिष्ठा वाले उपयोगकर्ता पूछने के बाद 8 घंटे के लिए अपने स्वयं के प्रश्न का उत्तर नहीं दे सकते। आप 7 घंटे में जवाब दे सकते हैं। तब तक कृपया टिप्पणियों का उपयोग करें, या इसके बजाय अपने प्रश्न को संपादित करें।" (समाधान 7 घंटे में आने के लिए)।
एंथनी लीच जूनियर

1
कोई व्यक्ति इस व्यक्ति को एक
उत्थान देता है

जवाबों:


12

मैं वास्तव में यहाँ अपने प्रश्न का उत्तर देने जा रहा हूँ। मुझे पता है, निपटने के लिए, लेकिन मैं वास्तविक स्टैक ट्रेस पर बहुत करीब से देखने पर जवाब पर ठोकर खाई। हालांकि संग्रह ठीक लोड हो रहा है, विफलता निष्पादन में थोड़ी देर बाद आती है जब हम Varien_Data_Collection_Db :: getSelectCountSql () में संग्रह संख्या प्राप्त करने का प्रयास करते हैं । इस से उत्पन्न होने वाली SQL है:

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)

आप देखेंगे कि HAVING स्टेटमेंट संलग्न है फिर भी DIF_AU कॉलम के लिए हमारी कोई परिभाषा नहीं है। ऐसा प्रतीत होता है जैसे मुझे सही रिकॉर्ड गणना प्राप्त करने के लिए अपने संग्रह वर्ग में एक कस्टम getSelectCountSql () का विस्तार करना होगा।

मैंने कस्टम कलेक्शन क्लास में एक विस्तारित getSelectCountSql () बनाया है जो होने वाले स्टेटमेंट के लिए आवश्यक अनुपलब्ध कॉलम में वापस जुड़ जाता है।


public function getSelectCountSql()
  {
    $countSelect = parent::getSelectCountSql();
    $countSelect->columns('grand_total - sum(sfop.amount_authorized) AS DIF_AU');
    $countSelect->reset(Zend_Db_Select::GROUP);
    return $countSelect;
  }

1
यदि आप पहले समाधान का पता लगाते हैं, तो यह बिल्कुल भी चिंतित नहीं है। अन्य लोग संभवतः इसे सड़क के नीचे सहायक पाएंगे। +1 :)
डेविडलगर

आपको एक बग रिपोर्ट दर्ज करनी चाहिए! magentocommerce.com/bug-tracking
चिह्न

यह एक ऐसा मुद्दा है जिसे मैंने भी देखा है, और एक उत्तर खोजने पर अच्छा किया है। हालाँकि, मुझे नहीं लगता कि आपका समाधान सही है - क्योंकि आप समूह का उपयोग कर रहे हैं, आपके SelectCountSql को समूहों की संख्या लौटाने की आवश्यकता है। तो आपको या तो एक गिनती (fetchAll) () की आवश्यकता है, या अपनी क्वेरी को फिर से लिखने के count(distinct main_table.entity_id)बजायcount(*)
Benubird

मुझे लगता है कि आप बहुत सही हैं। यह परियोजना इस पोस्टिंग के बाद से बैक बर्नर पर है, और अभी इसे वापस मिल रहा है। पिछले हफ्ते एक डेमो में, मैंने देखा कि ग्रिड में गलत रिकॉर्ड गणना की जा रही है। एक बार हल करने के बाद मैं अपने निष्कर्षों की रिपोर्ट करूंगा।
एंथोनी लीच जूनियर

@AnthonyLeachJr अपने निष्कर्षों पर कोई खबर?
शमौन

0

सबसे पहले $countSelect->reset(Zend_Db_Select::HAVING);इसका मतलब है कि यह HAVINGआपके संग्रह से रीसेट हो जाएगा । इसका मतलब है कि यह होने वाले क्लॉज को हटा देगा। और यह वह नहीं है जो आप चाहते हैं। आप इसे संग्रह में जोड़ना चाहते हैं ( app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php->_getSelectCountSql()यहां)

लेकिन मुख्य अपराधी इसे getSize()विधि है जो lib/Varien/Data/Collection/Db.phpफ़ाइल में मौजूद है ।

मैंने @ समाधान द्वारा उल्लिखित उपरोक्त समाधान की कोशिश की, लेकिन वह काम नहीं किया।

अब मैंने नीचे किया।

public function 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);
}

जांचें कि मैं भी उपयोग नहीं कर रहा हूं getSelectCountSql()। मैं अभी पूरी SQL QUERY पढ़ रहा हूं और सभी डेटा प्राप्त कर रहा हूं और इसकी गिनती वापस कर रहा हूं । बस इतना ही।


0

मैंने इस मुद्दे को यहां तय किया: ऐप / कोड / कोर / मैज / कैटलॉग / मॉडल / संसाधन / उत्पाद / संग्रह.php: 943 इसे जोड़ें: $ चयन-> रीसेट (Zend_Db_Select :: HAVING);

बस एप्लिकेशन / कोड / कोर / दाना / सूची / मॉडल / संसाधन / उत्पाद / संग्रह। एप्लिकेशन / कोड / स्थानीय / दाना / सूची / मॉडल / संसाधन / उत्पाद / संग्रह के लिए। पीपी।

मेरा कोड अब इस तरह दिखता है:

/**
 * Build clear select
 *
 * @param Varien_Db_Select $select
 * @return Varien_Db_Select
 */
protected function _buildClearSelect($select = null)
{
    if (is_null($select)) {
        $select = clone $this->getSelect();
    }
    $select->reset(Zend_Db_Select::ORDER);
    $select->reset(Zend_Db_Select::LIMIT_COUNT);
    $select->reset(Zend_Db_Select::LIMIT_OFFSET);
    $select->reset(Zend_Db_Select::COLUMNS);
    $select->reset(Zend_Db_Select::HAVING);

0

यदि आपके चयनित कॉलम में अद्वितीय नाम हैं, तो यह समाधान काम करेगा क्योंकि उप-चयन सूची के किसी भी कॉलम में अद्वितीय नाम होने चाहिए

उपश्रेणी: तालिका उपकथा नकली कॉलम नामों की अनुमति देती है

public function getSelectCountSql()
{
    $this->_renderFilters();
    $select = clone $this->getSelect();
    $select->reset(Zend_Db_Select::ORDER);
    $select->reset(Zend_Db_Select::LIMIT_COUNT);
    $select->reset(Zend_Db_Select::LIMIT_OFFSET);        

    $countSelect = clone $this->getSelect();
    $countSelect->reset();
    $countSelect->from(array('a' => $select), 'COUNT(*)');
    return $countSelect;
}

पुनश्च: यह उत्तर सामान्य मैगनेटो संग्रह के लिए है। केवल उत्पाद संग्रह से संबंधित नहीं है।


0

यह काम कर रहा है

सार्वजनिक समारोह getSize () {if (is_null ($ - _ कुल ग्राहक)) {// $ sql = $ this-> getSelectCountSql (); $ sql = $ this-> getSelect (); $ यह -> _ कुल राशि = गिनती ($ यह-> getConnection () -> fetchAll ($ sql, $ this -> _ bindParams)); } रिटर्न इंटवल ($ यह -> _ कुल धन); }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.