1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: 29: 30: 31: 32: 33: 34:
35: class Mage_Reports_Model_Resource_Quote_Collection extends Mage_Sales_Model_Resource_Quote_Collection
36: {
37:
38: const SELECT_COUNT_SQL_TYPE_CART = 1;
39:
40: protected $_selectCountSqlType = 0;
41:
42: 43: 44: 45: 46:
47: protected $_joinedFields = array();
48:
49: 50: 51: 52: 53:
54: protected $_map = array('fields' => array('store_id' => 'main_table.store_id'));
55:
56: 57: 58: 59: 60: 61:
62: public function setSelectCountSqlType($type)
63: {
64: $this->_selectCountSqlType = $type;
65: return $this;
66: }
67:
68: protected function _construct()
69: {
70: parent::_construct();
71: 72: 73:
74: $this->_useAnalyticFunction = true;
75: }
76:
77:
78: 79: 80: 81: 82: 83: 84:
85: public function prepareForAbandonedReport($storeIds, $filter = null)
86: {
87: $this->addFieldToFilter('items_count', array('neq' => '0'))
88: ->addFieldToFilter('main_table.is_active', '1')
89: ->addSubtotal($storeIds, $filter)
90: ->addCustomerData($filter)
91: ->setOrder('updated_at');
92: if (is_array($storeIds) && !empty($storeIds)) {
93: $this->addFieldToFilter('store_id', array('in' => $storeIds));
94: }
95:
96:
97: return $this;
98: }
99:
100: 101: 102: 103: 104:
105: public function prepareForProductsInCarts()
106: {
107: $productEntity = Mage::getResourceSingleton('catalog/product_collection');
108: $productAttrName = $productEntity->getAttribute('name');
109: $productAttrNameId = (int) $productAttrName->getAttributeId();
110: $productAttrNameTable = $productAttrName->getBackend()->getTable();
111: $productAttrPrice = $productEntity->getAttribute('price');
112: $productAttrPriceId = (int) $productAttrPrice->getAttributeId();
113: $productAttrPriceTable = $productAttrPrice->getBackend()->getTable();
114:
115: $ordersSubSelect = clone $this->getSelect();
116: $ordersSubSelect->reset()
117: ->from(
118: array('oi' => $this->getTable('sales/order_item')),
119: array(
120: 'orders' => new Zend_Db_Expr('COUNT(1)'),
121: 'product_id'))
122: ->group('oi.product_id');
123:
124: $this->getSelect()
125: ->useStraightJoin(true)
126: ->reset(Zend_Db_Select::COLUMNS)
127: ->joinInner(
128: array('quote_items' => $this->getTable('sales/quote_item')),
129: 'quote_items.quote_id = main_table.entity_id',
130: null)
131: ->joinInner(
132: array('e' => $this->getTable('catalog/product')),
133: 'e.entity_id = quote_items.product_id',
134: null)
135: ->joinInner(
136: array('product_name' => $productAttrNameTable),
137: "product_name.entity_id = e.entity_id AND product_name.attribute_id = {$productAttrNameId}",
138: array('name'=>'product_name.value'))
139: ->joinInner(
140: array('product_price' => $productAttrPriceTable),
141: "product_price.entity_id = e.entity_id AND product_price.attribute_id = {$productAttrPriceId}",
142: array('price' => new Zend_Db_Expr('product_price.value * main_table.base_to_global_rate')))
143: ->joinLeft(
144: array('order_items' => new Zend_Db_Expr(sprintf('(%s)', $ordersSubSelect))),
145: 'order_items.product_id = e.entity_id',
146: array()
147: )
148: ->columns('e.*')
149: ->columns(array('carts' => new Zend_Db_Expr('COUNT(quote_items.item_id)')))
150: ->columns('order_items.orders')
151: ->where('main_table.is_active = ?', 1)
152: ->group('quote_items.product_id');
153:
154: return $this;
155: }
156:
157: 158: 159: 160: 161: 162:
163: public function addStoreFilter($storeIds)
164: {
165: $this->addFieldToFilter('store_id', array('in' => $storeIds));
166: return $this;
167: }
168:
169: 170: 171: 172: 173: 174:
175: public function addCustomerData($filter = null)
176: {
177: $customerEntity = Mage::getResourceSingleton('customer/customer');
178: $attrFirstname = $customerEntity->getAttribute('firstname');
179: $attrFirstnameId = (int) $attrFirstname->getAttributeId();
180: $attrFirstnameTableName = $attrFirstname->getBackend()->getTable();
181:
182: $attrLastname = $customerEntity->getAttribute('lastname');
183: $attrLastnameId = (int) $attrLastname->getAttributeId();
184: $attrLastnameTableName = $attrLastname->getBackend()->getTable();
185:
186: $attrEmail = $customerEntity->getAttribute('email');
187: $attrEmailTableName = $attrEmail->getBackend()->getTable();
188:
189: $adapter = $this->getSelect()->getAdapter();
190: $customerName = $adapter->getConcatSql(array('cust_fname.value', 'cust_lname.value'), ' ');
191: $this->getSelect()
192: ->joinInner(
193: array('cust_email' => $attrEmailTableName),
194: 'cust_email.entity_id = main_table.customer_id',
195: array('email' => 'cust_email.email')
196: )
197: ->joinInner(
198: array('cust_fname' => $attrFirstnameTableName),
199: implode(' AND ', array(
200: 'cust_fname.entity_id = main_table.customer_id',
201: $adapter->quoteInto('cust_fname.attribute_id = ?', (int)$attrFirstnameId),
202: )),
203: array('firstname' => 'cust_fname.value')
204: )
205: ->joinInner(
206: array('cust_lname' => $attrLastnameTableName),
207: implode(' AND ', array(
208: 'cust_lname.entity_id = main_table.customer_id',
209: $adapter->quoteInto('cust_lname.attribute_id = ?', (int)$attrLastnameId)
210: )),
211: array(
212: 'lastname' => 'cust_lname.value',
213: 'customer_name' => $customerName
214: )
215: );
216:
217: $this->_joinedFields['customer_name'] = $customerName;
218: $this->_joinedFields['email'] = 'cust_email.email';
219:
220: if ($filter) {
221: if (isset($filter['customer_name'])) {
222: $likeExpr = '%' . $filter['customer_name'] . '%';
223: $this->getSelect()->where($this->_joinedFields['customer_name'] . ' LIKE ?', $likeExpr);
224: }
225: if (isset($filter['email'])) {
226: $likeExpr = '%' . $filter['email'] . '%';
227: $this->getSelect()->where($this->_joinedFields['email'] . ' LIKE ?', $likeExpr);
228: }
229: }
230:
231: return $this;
232: }
233:
234: 235: 236: 237: 238: 239: 240:
241: public function addSubtotal($storeIds = '', $filter = null)
242: {
243: if (is_array($storeIds)) {
244: $this->getSelect()->columns(array(
245: 'subtotal' => '(main_table.base_subtotal_with_discount*main_table.base_to_global_rate)'
246: ));
247: $this->_joinedFields['subtotal'] =
248: '(main_table.base_subtotal_with_discount*main_table.base_to_global_rate)';
249: } else {
250: $this->getSelect()->columns(array('subtotal' => 'main_table.base_subtotal_with_discount'));
251: $this->_joinedFields['subtotal'] = 'main_table.base_subtotal_with_discount';
252: }
253:
254: if ($filter && is_array($filter) && isset($filter['subtotal'])) {
255: if (isset($filter['subtotal']['from'])) {
256: $this->getSelect()->where(
257: $this->_joinedFields['subtotal'] . ' >= ?',
258: $filter['subtotal']['from'], Zend_Db::FLOAT_TYPE
259: );
260: }
261: if (isset($filter['subtotal']['to'])) {
262: $this->getSelect()->where(
263: $this->_joinedFields['subtotal'] . ' <= ?',
264: $filter['subtotal']['to'], Zend_Db::FLOAT_TYPE
265: );
266: }
267: }
268:
269: return $this;
270: }
271:
272: 273: 274: 275: 276:
277: public function getSelectCountSql()
278: {
279: $countSelect = clone $this->getSelect();
280: $countSelect->reset(Zend_Db_Select::ORDER);
281: $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
282: $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
283: $countSelect->reset(Zend_Db_Select::COLUMNS);
284: $countSelect->reset(Zend_Db_Select::GROUP);
285: $countSelect->resetJoinLeft();
286:
287: if ($this->_selectCountSqlType == self::SELECT_COUNT_SQL_TYPE_CART) {
288: $countSelect->columns("COUNT(DISTINCT e.entity_id)");
289: } else {
290: $countSelect->columns("COUNT(DISTINCT main_table.entity_id)");
291: }
292:
293: return $countSelect;
294: }
295: }
296: