2011-12-04 6 views
3

이것은 꽤 오랫동안 나를 괴롭 히고 있습니다. 기본적으로, 우리가 달성하려고 노력하는 것은 제품의 판매량을 나열하기 위해 프론트 페이지의 베스트셀러에 있습니다. 단순한 제품의 경우이 기능이 제대로 작동하지만 구성 가능한 제품의 경우 0으로 주문한 수량으로 표시됩니다.Magento BestSeller Module - 구성 가능 제품 합산 및 다시 추가

구성 가능한 제품을 얻는 방법을 찾으려면 어떻게해야할까요? 이러한 단순한 제품을 판매하고이를 구성 가능한 제품 ID에 다시 추가하고이 정보를 다시 입력하면 판매 된 적정 금액의 구성 가능한 제품이 나열됩니다.

나는 변화가 필요한 코드 영역을 배치했다고 생각합니다. 누구든지 도움을받을 수 있다면 대단히 감사하겠습니다!

Collection.php

class Luxe_Bestsellers_Model_Mysql4_Product_Collection extends Mage_Reports_Model_Mysql4_Product_Collection 
{ 
public function addOrderedQty($from = '', $to = '', $getComplexProducts=false) 
{ 
    $qtyOrderedTableName = $this->getTable('sales/order_item'); 
    $qtyOrderedFieldName = 'qty_ordered'; 

    $productIdFieldName = 'product_id'; 

    if (!$getComplexProducts) { 
     $compositeTypeIds = Mage::getSingleton('catalog/product_type')->getCompositeTypes(); 
     $productTypes = $this->getConnection()->quoteInto(' AND (e.type_id NOT IN (?))', $compositeTypeIds); 
    } else { 
     $productTypes = ''; 
    } 

    if ($from != '' && $to != '') { 
     $dateFilter = " AND `order`.created_at BETWEEN '{$from}' AND '{$to}'"; 
    } else { 
     $dateFilter = ""; 
    } 

    $this->getSelect()->reset()->from(
     array('order_items' => $qtyOrderedTableName), 
     array('ordered_qty' => "SUM(order_items.{$qtyOrderedFieldName})") 
    ); 

    $_joinCondition = $this->getConnection()->quoteInto(
      'order.entity_id = order_items.order_id AND order.state<>?', Mage_Sales_Model_Order::STATE_CANCELED 
    ); 
    $_joinCondition .= $dateFilter; 
    $this->getSelect()->joinInner(
     array('order' => $this->getTable('sales/order')), 
     $_joinCondition, 
     array() 
    ); 


    $this->getSelect() 
     ->joinInner(array('e' => $this->getProductEntityTableName()), 
      "e.entity_id = order_items.{$productIdFieldName} AND e.entity_type_id = {$this->getProductEntityTypeId()}{$productTypes}") 
     ->group('e.entity_id') 
     ->having('ordered_qty > 0'); 

    return $this; 
} 

} 

List.php는

class Luxe_Bestsellers_Block_List extends Mage_Catalog_Block_Product_List 
{ 
protected $_defaultToolbarBlock = 'bestsellers/list_toolbar'; 

protected function _beforeToHtml() { 
    $this->addPriceBlockType('bundle', 'bundle/catalog_product_price', 'bundle/catalog/product/price.phtml'); 
    return parent::_beforeToHtml();  
} 

public function _toHtml() 
{ 
    if ($this->_productCollection->count()) { 
     return parent::_toHtml(); 
    } else { 
     return ''; 
    } 
} 

public function getTimeLimit() 
{ 
    if ($this->getData('time_limit_in_days')) { 
     return intval($this->getData('time_limit_in_days')); 
    } else { 
     return intval(Mage::getStoreConfig('bestsellers/bestsellers/time_limit_in_days')); 
    } 
} 

public function getBlockTitle() 
{ 
    if ($this->getData('title')) { 
     return $this->getData('title'); 
    } else { 
     return Mage::getStoreConfig('bestsellers/bestsellers/title'); 
    } 
} 

public function isShowOutOfStock() { 
    return (bool)Mage::getStoreConfig('bestsellers/bestsellers/show_out_of_stock'); 
} 

public function getProductsLimit() 
{ 
    if ($this->getData('limit')) { 
     return intval($this->getData('limit')); 
    } else { 
     return $this->getToolbarBlock()->getLimit(); 
    } 
} 

public function getDisplayMode() 
{ 
    return $this->getData('display_mode'); 
} 

/** 
* Retrieve loaded category collection 
* 
* @return Mage_Eav_Model_Entity_Collection_Abstract 
*/ 
protected function _getProductCollection() 
{ 
    if (is_null($this->_productCollection)) { 
     $layer = Mage::getModel('catalog/layer'); 
     $bestsellers = Mage::getResourceModel('reports/product_collection'); 
     if ($this->getTimeLimit()) { 
      $product = Mage::getModel('catalog/product'); 
      $todayDate = $product->getResource()->formatDate(time()); 
      $startDate = $product->getResource()->formatDate(time() - 60 * 60 * 24 * $this->getTimeLimit()); 
      $bestsellers->addOrderedQty($startDate, $todayDate, true); 
     } else { 
      $bestsellers->addOrderedQty('', '', true); 
     } 

     $bestsellers->addStoreFilter() 
       ->setOrder('ordered_qty', 'desc') 
       ->setPageSize($this->getProductsLimit()); 

     Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($bestsellers); 

     if ($layer->getCurrentCategory()->getId() != Mage::app()->getStore()->getRootCategoryId()) { 
      $bestsellers->addCategoryFilter($layer->getCurrentCategory()); 
      Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($bestsellers); 
     } 

     if (!$this->isShowOutOfStock()) { 
      Mage::getModel('cataloginventory/stock')->addInStockFilterToCollection($bestsellers); 
     } 

     $bestsellers->getSelect()->where('order.store_id = ?', Mage::app()->getStore()->getId()); 

     $productIds = array(); 
     foreach ($bestsellers as $p) { 
      $productIds[] = $p->getId(); 
     } 
     $collection = Mage::getResourceModel('catalog/product_collection'); 

     Mage::getModel('catalog/layer')->prepareProductCollection($collection); 

     $attributes = Mage::getSingleton('catalog/config')->getProductAttributes(); 
     $collection->addIdFilter($productIds) 
        ->addAttributeToSelect($attributes) 
        ->addMinimalPrice() 
        ->addFinalPrice(); 
     $this->_productCollection = $collection; 
    } 
    return $this->_productCollection; 
} 

/** 
* Translate block sentence 
* 
* @return string 
*/ 
public function __() 
{ 
    $args = func_get_args(); 
    $expr = new Mage_Core_Model_Translate_Expr(array_shift($args), 'Mage_Catalog'); 
    array_unshift($args, $expr); 
    return Mage::app()->getTranslator()->translate($args); 
} 
} 
+0

이 정확한 문제가 있습니다. 해결책을 찾으면 알려 드리겠습니다. –

+0

코드를 테스트 한 Magento 버전은 무엇입니까?귀하의 코드를 시도했지만 구성 가능한 제품이 버전 1.6.2에서 전혀 나타나지 않습니다. – user1258365

답변

0

당신은 구성 제품에 부착 된 간단한 제품을 얻기 위해 다음 코드 조각을 사용할 수 있습니다. 이것이 100 % 맞는지 확실하지 않습니다. 직접 시도하지 않았습니다.

$simpleProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $product); 
+0

답장을 보내 주셔서 감사합니다. 그러나 이것을 구현하는 방법에 대해 나는 그것에 대해 갈 것이라고 확신하지 못한다. 다른 누군가가 더 깊은 통찰력을 더할 수 있다면 크게 감사 할 것이다. – user994319

2

샘플 코드를 게시 해 주셔서 감사합니다! 나는 우리 모두를 위해 잘 작동 할 해결책을 만들기 위해 그것을 사용할 수있었습니다.

구성 가능한 제품 판매가 정확하게 합산되고 있지만 결과에 포함되지 않은 것으로 나타났습니다. 자녀 제품이 대신 나타납니다. 제 솔루션은 구성 가능한 제품을 포함하고 catalog_product_super_link 테이블에 왼쪽 조인을 수행하고 parent_id을 갖는 모든 것을 필터링하는 것이 었습니다.

Collection.php을 : 다음은 변경해야하는 부분은

public function addOrderedQty($from = '', $to = '', $getComplexProducts=false, $getComplexChildProducts = true, $getRemovedProducts = true) 
    { 
     $qtyOrderedTableName = $this->getTable('sales/order_item'); 
     $qtyOrderedFieldName = 'qty_ordered'; 

     $productIdFieldName = 'product_id'; 

     if (!$getComplexProducts) { 
      $compositeTypeIds = Mage::getSingleton('catalog/product_type')->getCompositeTypes(); 
      $productTypes = $this->getConnection()->quoteInto(' AND (e.type_id NOT IN (?))', $compositeTypeIds); 
     } else { 
      $productTypes = ''; 
     } 

     if ($from != '' && $to != '') { 
      $dateFilter = " AND `order`.created_at BETWEEN '{$from}' AND '{$to}'"; 
     } else { 
      $dateFilter = ""; 
     } 

     $this->getSelect()->reset()->from(
      array('order_items' => $qtyOrderedTableName), 
      array(
       'ordered_qty' => "SUM(order_items.{$qtyOrderedFieldName})", 
       'order_items_name' => 'order_items.name' 
      ) 
     ); 

     $_joinCondition = $this->getConnection()->quoteInto(
       'order.entity_id = order_items.order_id AND order.state<>?', Mage_Sales_Model_Order::STATE_CANCELED 
     ); 
     $_joinCondition .= $dateFilter; 
     $this->getSelect()->joinInner(
      array('order' => $this->getTable('sales/order')), 
      $_joinCondition, 
      array() 
     ); 

     // Add join to get the parent id for configurables 
     $this->getSelect()->joinLeft(
      array('cpsl' => $this->getTable('catalog/product_super_link')), 
      'cpsl.product_id = order_items.product_id', 
      'cpsl.parent_id' 
     ); 

     if(!$getComplexChildProducts) 
      $this->getSelect()->having('parent_id IS NULL'); 

     if($getRemovedProducts) 
     { 
      $this->getSelect() 
       ->joinLeft(array('e' => $this->getProductEntityTableName()), 
        "e.entity_id = order_items.{$productIdFieldName} AND e.entity_type_id = {$this->getProductEntityTypeId()}{$productTypes}") 
       ->group('order_items.product_id'); 
     } 
     else 
     { 
      $this->getSelect() 
       ->joinInner(array('e' => $this->getProductEntityTableName()), 
        "e.entity_id = order_items.{$productIdFieldName} AND e.entity_type_id = {$this->getProductEntityTypeId()}{$productTypes}") 
       ->group('e.entity_id'); 
     } 


     $this->getSelect()->having('ordered_qty > 0'); 

     // This line is for debug purposes, in case you'd like to see what the SQL looks like 
     // $x = $this->getSelect()->__toString(); 

     return $this; 
    } 

List.php - ...

$bestsellers->addOrderedQty($startDate, $todayDate, true); 
$bestsellers->addOrderedQty('', '', true); 

... 다음 두 줄을 찾기 변경

$bestsellers->addOrderedQty($startDate, $todayDate, true, false, false); 
$bestsellers->addOrderedQty('', '', true, false, false); 

내 변화는 두 가지 새로운 선택적 매개 변수를 추가 true에있는 모두 기본적 ㄱ 여부에 : 그들에 기존 기능을 재개하십시오. $getComplexChildProductsfalse로 설정하면

  • 는 구성 가능한 제품의 모든 하위 항목은 결과에서 제거됩니다.
  • $getRemovedProducts은 이전에 주문한 제품 (이후 Magento에서 삭제 된 제품)이 나타나야하는지 여부를 결정합니다.

정확한 결과를 얻으려면 보고서 통계가 최신이어야합니다.

희망이 도움이됩니다. 궁금한 점이 있으면 알려주세요.

+0

소리가 정말 멋지다 - 어디에 추가해야합니까? MyExt_Block_Product_Bestsellerlist 클래스의 Block 코드에 Mage_Catalog_Block_Product_List를 확장하여 추가했습니다 .... 그러나 그것은 나던 것 같습니다. –

관련 문제