Ayaline_BestSales - Version 1.1.0

Version Notes

Enhance your site content by displaying most saled products

Download this release

Release Info

Developer Magento Core Team
Extension Ayaline_BestSales
Version 1.1.0
Comparing to
See all releases


Version 1.1.0

Files changed (24) hide show
  1. app/code/community/Ayaline/BestSales/Block/List.php +56 -0
  2. app/code/community/Ayaline/BestSales/Block/Sidebar.php +107 -0
  3. app/code/community/Ayaline/BestSales/Block/Widget/BestSales.php +24 -0
  4. app/code/community/Ayaline/BestSales/Helper/Data.php +21 -0
  5. app/code/community/Ayaline/BestSales/Model/Adminhtml/System/Config/Source/ListMode.php +24 -0
  6. app/code/community/Ayaline/BestSales/Model/BestSales.php +152 -0
  7. app/code/community/Ayaline/BestSales/Model/BestSalesIndex.php +72 -0
  8. app/code/community/Ayaline/BestSales/Model/Mysql4/BestSales.php +74 -0
  9. app/code/community/Ayaline/BestSales/Model/Mysql4/BestSales/Collection.php +161 -0
  10. app/code/community/Ayaline/BestSales/Model/Mysql4/BestSalesIndex.php +82 -0
  11. app/code/community/Ayaline/BestSales/Model/Observer.php +96 -0
  12. app/code/community/Ayaline/BestSales/controllers/Catalog/BestsalesController.php +30 -0
  13. app/code/community/Ayaline/BestSales/etc/adminhtml.xml +33 -0
  14. app/code/community/Ayaline/BestSales/etc/config.xml +153 -0
  15. app/code/community/Ayaline/BestSales/etc/system.xml +143 -0
  16. app/code/community/Ayaline/BestSales/etc/widget.xml +57 -0
  17. app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-install-0.1.0.php +35 -0
  18. app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.0-0.1.1.php +52 -0
  19. app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.1-0.1.2.php +44 -0
  20. app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.2-0.1.3.php +53 -0
  21. app/etc/modules/Ayaline_BestSales.xml +23 -0
  22. app/locale/en_US/Ayaline_BestSales.csv +29 -0
  23. app/locale/fr_FR/Ayaline_BestSales.csv +29 -0
  24. package.xml +23 -0
app/code/community/Ayaline/BestSales/Block/List.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Block_List extends Mage_Catalog_Block_Product_List {
17
+
18
+ protected $_collection;
19
+
20
+ public function _construct(){
21
+ parent::_construct();
22
+ $this->_collection = $this->_getProductCollection();
23
+ }
24
+
25
+ public function getListName() {
26
+ return Mage::helper('ayalinebestsales')->__('Best sales');
27
+ }
28
+
29
+ protected function _getProductCollection() {
30
+ if(!$this->_collection) {
31
+ /* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
32
+ $collection = parent::_getProductCollection();
33
+
34
+ $collection = Mage::getSingleton('ayalinebestsales/bestSales')
35
+ ->addToProductCollection($collection, true, $this->_getLastXDays() - 1)
36
+ ;
37
+ $collection->getSelect()->order('best_sales DESC');
38
+
39
+ $this->_collection = $collection;
40
+ }
41
+
42
+ return $this->_collection;
43
+ }
44
+
45
+ protected function _getLastXDays() {
46
+ return Mage::getStoreConfig('ayalinebestsales/list/size');
47
+ }
48
+
49
+ protected function _beforeToHtml() {
50
+ parent::_beforeToHtml();
51
+
52
+ $this->getToolbarBlock()->setData('_current_grid_mode', Mage::getStoreConfig('ayalinebestsales/list/display_mode'));
53
+
54
+ return $this;
55
+ }
56
+ }
app/code/community/Ayaline/BestSales/Block/Sidebar.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Block_Sidebar extends Mage_Catalog_Block_Product_Abstract
17
+ {
18
+ const XML_PATH_NB_DAYS = 'ayalinebestsales/sidebar/nb_days';
19
+ const XML_PATH_COUNT = 'ayalinebestsales/sidebar/count';
20
+ const XML_PATH_TRUNCATE_NAME = 'ayalinebestsales/sidebar/truncate_name';
21
+
22
+ protected $_nbDays = null;
23
+ protected $_count = null;
24
+ protected $_useStrictMode = true;
25
+
26
+ /**
27
+ * Number of days used to calculate the best sales
28
+ * Should be called in layouts
29
+ */
30
+ public function setNbDays($nbDays) {
31
+ $this->_nbDays = $nbDays;
32
+ }
33
+
34
+ public function getNbDays() {
35
+ if($this->_nbDays) {
36
+ return $this->_nbDays;
37
+ } else {
38
+ return Mage::getStoreConfig(self::XML_PATH_NB_DAYS);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Number of products displayed in sidebar
44
+ * Should be called in layouts
45
+ */
46
+ public function setCount($count) {
47
+ $this->_count = $count;
48
+ }
49
+
50
+ public function getCount() {
51
+ if($this->_count) {
52
+ return $this->_count;
53
+ } else {
54
+ return Mage::getStoreConfig(self::XML_PATH_COUNT);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Define the mode. If not strict, products never viewed are still loadeds
60
+ * Should be called in layouts
61
+ */
62
+ public function setUseStrictMode($strict) {
63
+ $this->_useStrictMode = $strict;
64
+ }
65
+
66
+ public function getUseStrictMode() {
67
+ return (bool)$this->_useStrictMode;
68
+ }
69
+
70
+ /**
71
+ * Return best sales products collection
72
+ *
73
+ * @return Mage_Catalog_Model_Resource_Product_Collection
74
+ */
75
+ public function getProductCollection() {
76
+ $productCollection = Mage::getResourceModel('ayalinebestsales/bestSales_collection')
77
+ ->addLastDaysFilter($this->getNbDays())
78
+ ->useStrictMode($this->getUseStrictMode())
79
+ ->getProductCollection()
80
+ ->addStoreFilter(Mage::app()->getStore()->getId())
81
+ ->addAttributeToSelect('name')
82
+ ->addAttributeToFilter('status', array('eq' => 1))
83
+ ->setPageSize($this->getCount())
84
+ ;
85
+
86
+ if($category = Mage::registry('current_category')) {
87
+ $productCollection->addCategoryFilter($category);
88
+ }
89
+
90
+ $productCollection = $this->_addProductAttributesAndPrices($productCollection);
91
+
92
+ Mage::dispatchEvent('ayalinebestsales_sidebar_prepare_collection', array('collection' => $productCollection));
93
+
94
+ return $productCollection;
95
+ }
96
+
97
+ public function getProductName($product) {
98
+ $name = $this->helper('catalog/output')->productAttribute($product, $product->getName(), 'name');
99
+
100
+ if($nb = Mage::getStoreConfig(self::XML_PATH_TRUNCATE_NAME)) {
101
+ $useless = '';
102
+ return Mage::helper('core/string')->truncate($name, $nb, '...', $useless, false);
103
+ }
104
+
105
+ return $name;
106
+ }
107
+ }
app/code/community/Ayaline/BestSales/Block/Widget/BestSales.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Block_Widget_BestSales extends Ayaline_BestSales_Block_Sidebar implements Mage_Widget_Block_Interface {
17
+
18
+ protected function _construct() {
19
+ parent::_construct();
20
+ $this->setCount($this->getData('products_count')); // nb products in template
21
+ $this->setColumnCount($this->getData('column_count')); // if grid template, number of columns
22
+ }
23
+
24
+ }
app/code/community/Ayaline/BestSales/Helper/Data.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Helper_Data extends Mage_Core_Helper_Abstract
17
+ {
18
+ public function listIsActive() {
19
+ return Mage::getStoreConfig('ayalinebestsales/list/is_active');
20
+ }
21
+ }
app/code/community/Ayaline/BestSales/Model/Adminhtml/System/Config/Source/ListMode.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_Adminhtml_System_Config_Source_ListMode
17
+ {
18
+ public function toOptionArray() {
19
+ return array(
20
+ array('value'=>'grid', 'label'=>Mage::helper('ayalinebestsales')->__('Grid')),
21
+ array('value'=>'list', 'label'=>Mage::helper('ayalinebestsales')->__('List')),
22
+ );
23
+ }
24
+ }
app/code/community/Ayaline/BestSales/Model/BestSales.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_BestSales extends Mage_Core_Model_Abstract
17
+ {
18
+ /**
19
+ * XML configuration paths
20
+ */
21
+ const XML_PATH_NB_DAYS_EXPIRY = 'ayalinebestsales/general/nb_days_expiry';
22
+ const XML_PATH_DECREASE_IF_CANCELED = 'ayalinebestsales/general/decrease_if_canceled';
23
+ const XML_PATH_SIDEBAR_NB_DAYS = 'ayalinebestsales/sidebar/nb_days';
24
+ const XML_PATH_GENERAL_SHOW_OUT_OF_STOCK = 'ayalinebestsales/general/show_out_of_stock';
25
+
26
+ protected function _construct() {
27
+ $this->_init('ayalinebestsales/bestSales');
28
+ }
29
+
30
+ public function getNbDaysExpiry($storeId=null) {
31
+ return Mage::getStoreConfig(self::XML_PATH_NB_DAYS_EXPIRY, $storeId);
32
+ }
33
+
34
+ public function decreaseIfCanceled($storeId=null) {
35
+ return (bool)Mage::getStoreConfig(self::XML_PATH_DECREASE_IF_CANCELED, $storeId);
36
+ }
37
+
38
+ public function cleanOld($storeIds=null) {
39
+ if($storeIds instanceof Mage_Cron_Model_Schedule) {
40
+ $storeIds = null;
41
+ }
42
+
43
+ if(is_null($storeIds)) {
44
+ $storeIds = Mage::app()->getStores(true);
45
+ } elseif(!is_array($storeIds)) {
46
+ $storeIds = array($storeIds);
47
+ }
48
+
49
+ foreach($storeIds as $store) {
50
+ $storeId = $store->getId();
51
+
52
+ $date = new Zend_Date();
53
+ $nbDaysExpiry = $this->getNbDaysExpiry($storeId);
54
+ $date->sub($nbDaysExpiry, Zend_Date::DAY);
55
+
56
+ $this->_getResource()->cleanOlderThan($storeId, $date->get('YYYY-MM-dd'));
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Increase sales count for the given parameters.
62
+ *
63
+ * @param int $productId
64
+ * @param int $storeId
65
+ * @param string $date
66
+ * @param int $qty
67
+ * @param string $zdFormat : date format for $date (see Zend_Date)
68
+ *
69
+ * @return bool : true if updates
70
+ */
71
+ public function increaseSalesCount($productId, $storeId, $date, $qty, $zdFormat='YYYY-MM-dd HH:mm:ss') {
72
+ $zd = new Zend_Date($date, $zdFormat);
73
+
74
+ $this->_getResource()->increaseSalesCount($productId, $storeId, $zd->get('YYYY-MM-dd'), $qty);
75
+ }
76
+
77
+ /**
78
+ * Decrease sales count for the given parameters.
79
+ * If no count if found for these parameters, do nothing.
80
+ *
81
+ * @param int $productId
82
+ * @param int $storeId
83
+ * @param string $date
84
+ * @param int $qty
85
+ * @param string $zdFormat : date format for $date (see Zend_Date)
86
+ *
87
+ * @return bool : true if updates
88
+ */
89
+ public function decreaseSalesCount($productId, $storeId, $date, $qty, $zdFormat='YYYY-MM-dd HH:mm:ss') {
90
+ $zd = new Zend_Date($date, $zdFormat);
91
+
92
+ return $this->_getResource()->decreaseSalesCount($productId, $storeId, $zd->get('YYYY-MM-dd'), $qty);
93
+ }
94
+
95
+ /**
96
+ *
97
+ * Prepare collection with sales_count attribute
98
+ *
99
+ * @param Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $collection
100
+ * @param boolean $strict : get also the products already viewed or not
101
+ * @param int $nbDays : number of days before today
102
+ * @param int $store : store id (default : current store)
103
+ * @param string $alias : the name of the alias
104
+ *
105
+ * @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
106
+ */
107
+ public function addToProductCollection($collection, $strict = false, $nbDays = null, $store = null, $alias = 'best_sales'){
108
+ /** Manage strict Param **/
109
+ if($strict === true){
110
+ $join = 'joinInner';
111
+ }else{
112
+ $join = 'joinLeft';
113
+ }
114
+
115
+ /** Manage store Param **/
116
+ if(!$store){
117
+ $store = Mage::app()->getStore()->getId();
118
+ }
119
+
120
+ /** Manage nbDays Param **/
121
+ if($nbDays == null){
122
+ $nbDays = Mage::getStoreConfig(self::XML_PATH_SIDEBAR_NB_DAYS, $store);
123
+ }
124
+
125
+ $joinConditions = array('e.entity_id = absi.product_id',
126
+ "absi.store_id = '".$store."'",
127
+ "absi.day = '".$nbDays."'");
128
+
129
+ $collection
130
+ ->getSelect()
131
+ ->$join(
132
+ array('absi' => $collection->getTable('ayalinebestsales/best_sales_index')),
133
+ implode(' AND ', $joinConditions),
134
+ array($alias => 'absi.nb_sales')
135
+ )
136
+ ;
137
+
138
+ if(!Mage::getStoreConfig(self::XML_PATH_GENERAL_SHOW_OUT_OF_STOCK)) {
139
+ $collection->getSelect()
140
+ ->joinInner(
141
+ array('ciss' => $collection->getTable('cataloginventory/stock_status')),
142
+ "ciss.product_id = e.entity_id AND ciss.website_id = '".Mage::app()->getStore($store)->getWebsiteId()."'",
143
+ array()
144
+ )
145
+ ->where('ciss.stock_status = ?', Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK)
146
+ ;
147
+ }
148
+
149
+ return $collection;
150
+ }
151
+
152
+ }
app/code/community/Ayaline/BestSales/Model/BestSalesIndex.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_BestSalesIndex extends Mage_Core_Model_Abstract {
17
+
18
+ protected function _construct() {
19
+ $this->_init('ayalinebestsales/bestSalesIndex');
20
+ }
21
+
22
+ /**
23
+ * Création de la table d'index des produits les vendus
24
+ *
25
+ * @param array(Mage_Core_Model_Store) $stores
26
+ * @param bool $withDefault
27
+ */
28
+ public function indexBestSales($stores = null, $withDefault = true) {
29
+ if((is_array($stores) && empty($stores)) || is_null($stores) || $stores instanceof Mage_Cron_Model_Schedule) {
30
+ $stores = Mage::app()->getStores();
31
+ } elseif(!is_array($stores)) {
32
+ $stores = array($stores);
33
+ }
34
+
35
+ try {
36
+ $this->_getResource()->truncateIdxTable();
37
+
38
+ foreach($stores as $_store) {
39
+ if($_store instanceof Mage_Core_Model_Store) {
40
+ $storeId = $_store->getStoreId();
41
+ } else {
42
+ $storeId = $_store;
43
+ }
44
+ try {
45
+ $this->_getResource()->indexBestSales($storeId);
46
+ } catch(Exception $e) {
47
+ $notificationObject = new Varien_Object(array(
48
+ 'title' => Mage::helper('ayalinebestsales')->__('An error occurred while indexing "%s" to the store %s', Mage::helper('ayalinebestsales')->__('Best sales'), $_store->getName()),
49
+ 'date' => date('Y-m-d H:i:s'),
50
+ 'url' => '#',
51
+ 'description' => $e->getMessage().'<br />'.Mage::helper('ayalinecore')->__('See exception.log'),
52
+ ));
53
+ Mage::helper('ayalinecore')->addCustomAdminNotification($notificationObject);
54
+ Mage::logException($e);
55
+ }
56
+ }
57
+
58
+ $this->_getResource()->renameTables();
59
+
60
+ } catch(Exception $e) {
61
+ $notificationObject = new Varien_Object(array(
62
+ 'title' => Mage::helper('ayalinemostviewed')->__('An error occurred while indexing "%s"', Mage::helper('ayalinebestsales')->__('Best sales')),
63
+ 'date' => date('Y-m-d H:i:s'),
64
+ 'url' => '#',
65
+ 'description' => $e->getMessage().'<br />'.Mage::helper('ayalinecore')->__('See exception.log'),
66
+ ));
67
+ Mage::helper('ayalinecore')->addCustomAdminNotification($notificationObject);
68
+ Mage::logException($e);
69
+ }
70
+ }
71
+
72
+ }
app/code/community/Ayaline/BestSales/Model/Mysql4/BestSales.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_Mysql4_BestSales extends Mage_Core_Model_Mysql4_Abstract
17
+ {
18
+ protected function _construct() {
19
+ $this->_init('ayalinebestsales/best_sales', 'best_sales_id');
20
+ }
21
+
22
+ public function increaseSalesCount($productId, $storeId, $date, $qty) {
23
+ if(!$this->_getRow($productId, $storeId, $date)) {
24
+ $this->_getWriteAdapter()->insert($this->getMainTable(), array(
25
+ 'product_id' => $productId,
26
+ 'store_id' => $storeId,
27
+ 'sales_date' => $date,
28
+ 'sales_count' => $qty,
29
+ ));
30
+ } else {
31
+ $conditions = array();
32
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('product_id = ?', $productId);
33
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('store_id = ?', $storeId);
34
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('sales_date = ?', $date);
35
+
36
+ $this->_getWriteAdapter()->update($this->getMainTable(), array('sales_count' => new Zend_Db_Expr('sales_count + ' . $qty)), $conditions);
37
+ }
38
+ }
39
+
40
+ public function decreaseSalesCount($productId, $storeId, $date, $qty) {
41
+ if(!$this->_getRow($productId, $storeId, $date)) {
42
+ return false;
43
+ }
44
+
45
+ $conditions = array();
46
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('product_id = ?', $productId);
47
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('store_id = ?', $storeId);
48
+ $conditions[] = $this->_getWriteAdapter()->quoteInto('sales_date = ?', $date);
49
+
50
+ $this->_getWriteAdapter()->update($this->getMainTable(), array('sales_count' => new Zend_Db_Expr('sales_count - ' . $qty)), $conditions);
51
+
52
+ return true;
53
+ }
54
+
55
+ public function cleanOlderThan($storeId, $date) {
56
+ $this->_getWriteAdapter()->delete(
57
+ $this->getMainTable(),
58
+ array(
59
+ $this->_getWriteAdapter()->quoteInto('sales_date < ?', $date),
60
+ $this->_getWriteAdapter()->quoteInto('store_id = ?', $storeId),
61
+ )
62
+ );
63
+ }
64
+
65
+ protected function _getRow($productId, $storeId, $date) {
66
+ $select = $this->_getReadAdapter()->select()
67
+ ->from($this->getMainTable())
68
+ ->where('product_id = ?', $productId)
69
+ ->where('store_id = ?', $storeId)
70
+ ->where('sales_date = ?', $date)
71
+ ;
72
+ return $this->_getReadAdapter()->fetchRow($select);
73
+ }
74
+ }
app/code/community/Ayaline/BestSales/Model/Mysql4/BestSales/Collection.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_Mysql4_BestSales_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
17
+ {
18
+ protected $_storeFilterApplied = false;
19
+ protected $_useStrictMode = false;
20
+
21
+ public function _construct() {
22
+ $this->_init('ayalinebestsales/bestSales');
23
+ }
24
+
25
+ /**
26
+ * Returns a new product collection after joining with current collection
27
+ * Only $fields are added to product collection select
28
+ *
29
+ * @param array $fields
30
+ * @param string $sortOrder
31
+ * @param string $sortDirection
32
+ */
33
+ public function getProductCollection($fields=array(), $sortOrder='sales_count', $sortDirection='desc') {
34
+ if(sizeof($fields) == 0) {
35
+ $fields = array('sales_count' => new Zend_Db_Expr('SUM(sales_count)'));
36
+ }
37
+
38
+ /* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product */
39
+ $collection = Mage::getModel('catalog/product')->getCollection();
40
+
41
+ $bestSalesCollection = clone($this);
42
+ $bestSalesCollection->load();
43
+
44
+ if($this->_useStrictMode) {
45
+ $collection->getSelect()
46
+ ->joinInner(
47
+ array('abs' => $bestSalesCollection->getSelect()),
48
+ 'e.entity_id = abs.product_id',
49
+ $fields
50
+ );
51
+ } else {
52
+ $collection->getSelect()
53
+ ->joinLeft(
54
+ array('abs' => $bestSalesCollection->getSelect()),
55
+ 'e.entity_id = abs.product_id',
56
+ $fields
57
+ );
58
+ }
59
+ $collection->getSelect()
60
+ ->group('e.entity_id')
61
+ ->order("$sortOrder $sortDirection")
62
+ ;
63
+
64
+ return $collection;
65
+ }
66
+
67
+ protected function _beforeLoad() {
68
+ if(!$this->_storeFilterApplied) {
69
+ $this->addStoreFilter(Mage::app()->getStore()->getId());
70
+ }
71
+ return parent::_beforeLoad();
72
+ }
73
+
74
+ public function useStrictMode($strict=true) {
75
+ $this->_useStrictMode = $strict;
76
+ return $this;
77
+ }
78
+
79
+ public function addLastDaysFilter($nbDays, $strict=false) {
80
+ $date = new Zend_Date();
81
+ $date->sub($nbDays, Zend_Date::DAY);
82
+ $this->addAfterDateFilter($date->get('YYYY-MM-dd'), $strict);
83
+ return $this;
84
+ }
85
+
86
+ /**
87
+ * @param string $date
88
+ * @param bool $strict
89
+ * @param string $zdFormat : date format for $date (see Zend_Date)
90
+ */
91
+ public function addAfterDateFilter($date, $strict=false, $zdFormat='YYYY-MM-dd') {
92
+ $operand = $strict ? 'gt' : 'gteq';
93
+
94
+ return $this->_addDateFilter($date, $zdFormat, $operand);
95
+ }
96
+
97
+ /**
98
+ * @param string $date
99
+ * @param bool $strict
100
+ * @param string $zdFormat : date format for $date (see Zend_Date)
101
+ */
102
+ public function addBeforeDateFilter($date, $strict=false, $zdFormat='YYYY-MM-dd') {
103
+ $operand = $strict ? 'lt' : 'lteq';
104
+
105
+ return $this->_addDateFilter($date, $zdFormat, $operand);
106
+ }
107
+
108
+ /**
109
+ * @param string $date
110
+ * @param string $zdFormat : date format for $date (see Zend_Date)
111
+ */
112
+ public function addDateFilter($date, $zdFormat='YYYY-MM-dd') {
113
+ return $this->_addDateFilter($date, $zdFormat, 'eq');
114
+ }
115
+
116
+ protected function _addDateFilter($date, $zdFormat, $operand) {
117
+ $zd = new Zend_Date($date, $zdFormat);
118
+
119
+ $this->addFieldToFilter('main_table.sales_date', array($operand => $zd->get('YYYY-MM-dd')));
120
+
121
+ return $this;
122
+ }
123
+
124
+ /**
125
+ * Add Products Filter
126
+ *
127
+ * @param int|array $productId
128
+ * @return Ayaline_BestSales_Model_Mysql4_BestSales_Collection
129
+ */
130
+ public function addProductFilter($productId) {
131
+ if(!is_array($productId)) {
132
+ $productId = array($productId);
133
+ }
134
+
135
+ $this->addFieldToFilter('main_table.product_id', array('in' => $productId));
136
+
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * Add Stores Filter
142
+ *
143
+ * @param int|array $storeId
144
+ * @return Ayaline_BestSales_Model_Mysql4_BestSales_Collection
145
+ */
146
+ public function addStoreFilter($storeId, $withAdmin = true) {
147
+ if(!is_array($storeId)) {
148
+ $storeId = array($storeId);
149
+ }
150
+
151
+ if($withAdmin) {
152
+ $storeId[] = 0;
153
+ }
154
+
155
+ $this->addFieldToFilter('main_table.store_id', array('in' => $storeId));
156
+
157
+ $this->_storeFilterApplied = true;
158
+
159
+ return $this;
160
+ }
161
+ }
app/code/community/Ayaline/BestSales/Model/Mysql4/BestSalesIndex.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_Mysql4_BestSalesIndex extends Mage_Core_Model_Mysql4_Abstract {
17
+
18
+ const XML_PATH_GENERAL_NB_DAYS_EXPIRY = 'ayalinebestsales/general/nb_days_expiry';
19
+
20
+ protected function _construct() {
21
+ $this->_init('ayalinebestsales/best_sales_index', 'index_id');
22
+ }
23
+
24
+
25
+ /**
26
+ * Table d'index
27
+ *
28
+ * @param int $storeId
29
+ */
30
+ public function indexBestSales($storeId) {
31
+ $indexSize = $this->_getIndexSize($storeId);
32
+
33
+ for($i = 0; $i <= $indexSize; $i++) {
34
+ $date = new Zend_Date();
35
+ $date->subDay($i);
36
+
37
+ $select = $this->_getReadAdapter()->select()
38
+ ->from(
39
+ $this->getTable('ayalinebestsales/best_sales'),
40
+ array('product_id', 'day' => new Zend_Db_Expr($i), 'store_id', 'nb_sales' => 'SUM(sales_count)'))
41
+ ->where('sales_date >= ?', $date->toString('y-MM-dd'))
42
+ ->where('store_id = ?', $storeId)
43
+ ->group('product_id')
44
+ ;
45
+
46
+ $query = $select->insertFromSelect($this->getTable('ayalinebestsales/best_sales_index_idx'), array('product_id', 'day', 'store_id', 'nb_sales'));
47
+ $this->_getWriteAdapter()->query($query);
48
+ }
49
+
50
+ }
51
+
52
+
53
+ public function truncateIdxTable() {
54
+ $this->_getWriteAdapter()->truncate($this->getTable('ayalinebestsales/best_sales_index_idx'));
55
+ }
56
+
57
+ public function renameTables() {
58
+ $sql = "
59
+ RENAME TABLE
60
+ `{$this->getTable('ayalinebestsales/best_sales_index_idx')}` TO `ayalinebestsales_best_sales_index_tmp`,
61
+ `{$this->getMainTable()}` TO `{$this->getTable('ayalinebestsales/best_sales_index_idx')}`,
62
+ `ayalinebestsales_best_sales_index_tmp` TO `{$this->getMainTable()}`;
63
+ ";
64
+
65
+ $this->_getWriteAdapter()->query($sql);
66
+ }
67
+
68
+ protected function _getIndexSize($storeId) {
69
+ $indexSize = Mage::getStoreConfig(self::XML_PATH_GENERAL_NB_DAYS_EXPIRY, $storeId);
70
+ return $indexSize-1;
71
+ }
72
+
73
+ protected function _getRow($productId, $day, $storeId) {
74
+ $select = $this->_getReadAdapter()->select()
75
+ ->from($this->getMainTable())
76
+ ->where('product_id = ?', $productId)
77
+ ->where('day = ?', $day)
78
+ ->where('store_id = ?', $storeId)
79
+ ;
80
+ return $this->_getReadAdapter()->fetchRow($select);
81
+ }
82
+ }
app/code/community/Ayaline/BestSales/Model/Observer.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Model_Observer extends Mage_Core_Model_Abstract
17
+ {
18
+ /**
19
+ * Event : sales_order_save_before
20
+ *
21
+ * @param Varien_Event_Observer $observer
22
+ * @return Ayaline_BestSales_Model_Observer
23
+ */
24
+ public function beforeSaveOrder(Varien_Event_Observer $observer) {
25
+ $order = $observer->getEvent()->getOrder();
26
+ if(!$order->getId()) {
27
+ // The order is going to be saved
28
+ Mage::register('ayalinebestsales_process_count', 1);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Event : sales_order_save_after
34
+ *
35
+ * @param Varien_Event_Observer $observer
36
+ * @return Ayaline_BestSales_Model_Observer
37
+ */
38
+ public function afterSaveOrder(Varien_Event_Observer $observer) {
39
+ $order = $observer->getEvent()->getOrder();
40
+
41
+ if(Mage::registry('ayalinebestsales_process_count') && $order->getId()) {
42
+ // Increase sales counts
43
+ /* @var $item Mage_Sales_Model_Order_Item */
44
+ foreach($order->getAllVisibleItems() as $item) {
45
+ if($item->getParentItem()) {
46
+ continue;
47
+ }
48
+
49
+ $_productId = $item->getProductId();
50
+ if(Mage::helper('core')->isModuleOutputEnabled('OrganicInternet_SimpleConfigurableProducts')) { // SCP ?
51
+ if($item->getProductOptionByCode('info_buyRequest') && array_key_exists('cpid', $item->getProductOptionByCode('info_buyRequest'))) { // if it's a configurable product
52
+ $infoBuyRequest = $item->getProductOptionByCode('info_buyRequest');
53
+ $_productId = $infoBuyRequest['cpid']; // parent product id
54
+ }
55
+ }
56
+ Mage::getSingleton('ayalinebestsales/bestSales')->increaseSalesCount($_productId, $item->getStoreId(), $item->getCreatedAt(), $item->getQtyOrdered());
57
+ }
58
+ }
59
+
60
+ Mage::unregister('ayalinebestsales_process_count');
61
+
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Decrease sales count
67
+ *
68
+ * Event : sales_order_item_cancel
69
+ *
70
+ * @param Varien_Event_Observer $observer
71
+ * @return Ayaline_BestSales_Model_Observer
72
+ */
73
+ public function cancelOrderItem(Varien_Event_Observer $observer) {
74
+ if(!Mage::getSingleton('ayalinebestsales/bestSales')->decreaseIfCanceled()) {
75
+ return $this;
76
+ }
77
+ /* @var $item Mage_Sales_Model_Order_Item */
78
+ $item = $observer->getEvent()->getItem();
79
+ if($item->getParentItem()) {
80
+ return $this;
81
+ }
82
+
83
+ $_productId = $item->getProductId();
84
+ if(Mage::helper('core')->isModuleOutputEnabled('OrganicInternet_SimpleConfigurableProducts')) { // SCP ?
85
+ if($item->getProductOptionByCode('info_buyRequest') && array_key_exists('cpid', $item->getProductOptionByCode('info_buyRequest'))) { // if it's a configurable product
86
+ $infoBuyRequest = $item->getProductOptionByCode('info_buyRequest');
87
+ $_productId = $infoBuyRequest['cpid']; // parent product id
88
+ }
89
+ }
90
+
91
+ Mage::getSingleton('ayalinebestsales/bestSales')->decreaseSalesCount($_productId, $item->getStoreId(), $item->getCreatedAt(), $item->getQtyOrdered());
92
+
93
+ return $this;
94
+ }
95
+
96
+ }
app/code/community/Ayaline/BestSales/controllers/Catalog/BestsalesController.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ class Ayaline_BestSales_Catalog_BestsalesController extends Mage_Core_Controller_Front_Action {
17
+
18
+ protected function _construct() {
19
+ $this->_realModuleName = 'Ayaline_BestSales';
20
+ }
21
+
22
+ public function indexAction() {
23
+ if(!Mage::helper('ayalinebestsales')->listIsActive()) {
24
+ $this->_forward('cms/index/noRoute');
25
+ return;
26
+ }
27
+ $this->loadLayout();
28
+ $this->renderLayout();
29
+ }
30
+ }
app/code/community/Ayaline/BestSales/etc/adminhtml.xml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * created : 07/04/2011
5
+ *
6
+ * @category Ayaline
7
+ * @package Ayaline_BestSales
8
+ * @author aYaline
9
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
10
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
11
+ */
12
+ -->
13
+ <config>
14
+ <acl>
15
+ <resources>
16
+ <admin>
17
+ <children>
18
+ <system>
19
+ <children>
20
+ <config>
21
+ <children>
22
+ <ayalinebestsales translate="title" module="ayalinebestsales">
23
+ <title>Ayaline Best Sales</title>
24
+ </ayalinebestsales>
25
+ </children>
26
+ </config>
27
+ </children>
28
+ </system>
29
+ </children>
30
+ </admin>
31
+ </resources>
32
+ </acl>
33
+ </config>
app/code/community/Ayaline/BestSales/etc/config.xml ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * created : 07/04/2011
5
+ *
6
+ * @category Ayaline
7
+ * @package Ayaline_BestSales
8
+ * @author aYaline
9
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
10
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
11
+ */
12
+ -->
13
+ <config>
14
+ <modules>
15
+ <Ayaline_BestSales>
16
+ <version>1.1</version>
17
+ </Ayaline_BestSales>
18
+ </modules>
19
+ <global>
20
+ <blocks>
21
+ <ayalinebestsales>
22
+ <class>Ayaline_BestSales_Block</class>
23
+ </ayalinebestsales>
24
+ </blocks>
25
+ <models>
26
+ <ayalinebestsales>
27
+ <class>Ayaline_BestSales_Model</class>
28
+ <resourceModel>ayalinebestsales_mysql4</resourceModel>
29
+ </ayalinebestsales>
30
+ <ayalinebestsales_mysql4>
31
+ <class>Ayaline_BestSales_Model_Mysql4</class>
32
+ <entities>
33
+ <best_sales>
34
+ <table>ayaline_best_sales</table>
35
+ </best_sales>
36
+ <best_sales_index>
37
+ <table>ayaline_best_sales_index</table>
38
+ </best_sales_index>
39
+ <best_sales_index_idx>
40
+ <table>ayaline_best_sales_index_idx</table>
41
+ </best_sales_index_idx>
42
+ </entities>
43
+ </ayalinebestsales_mysql4>
44
+ </models>
45
+ <resources>
46
+ <ayalinebestsales_setup>
47
+ <setup>
48
+ <module>Ayaline_BestSales</module>
49
+ </setup>
50
+ </ayalinebestsales_setup>
51
+ </resources>
52
+ <helpers>
53
+ <ayalinebestsales>
54
+ <class>Ayaline_BestSales_Helper</class>
55
+ </ayalinebestsales>
56
+ </helpers>
57
+ <events>
58
+ <sales_order_item_cancel>
59
+ <observers>
60
+ <ayalinebestsales_cancel_order_item>
61
+ <class>ayalinebestsales/observer</class>
62
+ <method>cancelOrderItem</method>
63
+ </ayalinebestsales_cancel_order_item>
64
+ </observers>
65
+ </sales_order_item_cancel>
66
+ <sales_order_save_before>
67
+ <observers>
68
+ <ayalinebestsales_before_save_order>
69
+ <class>ayalinebestsales/observer</class>
70
+ <method>beforeSaveOrder</method>
71
+ </ayalinebestsales_before_save_order>
72
+ </observers>
73
+ </sales_order_save_before>
74
+ <sales_order_save_after>
75
+ <observers>
76
+ <ayalinebestsales_after_save_order>
77
+ <class>ayalinebestsales/observer</class>
78
+ <method>afterSaveOrder</method>
79
+ </ayalinebestsales_after_save_order>
80
+ </observers>
81
+ </sales_order_save_after>
82
+ </events>
83
+ </global>
84
+ <adminhtml>
85
+ <translate>
86
+ <modules>
87
+ <Ayaline_BestSales>
88
+ <files>
89
+ <default>Ayaline_BestSales.csv</default>
90
+ </files>
91
+ </Ayaline_BestSales>
92
+ </modules>
93
+ </translate>
94
+ </adminhtml>
95
+ <frontend>
96
+ <translate>
97
+ <modules>
98
+ <Ayaline_BestSales>
99
+ <files>
100
+ <default>Ayaline_BestSales.csv</default>
101
+ </files>
102
+ </Ayaline_BestSales>
103
+ </modules>
104
+ </translate>
105
+ <layout>
106
+ <updates>
107
+ <ayalinebestsales>
108
+ <file>ayaline/best_sales.xml</file>
109
+ </ayalinebestsales>
110
+ </updates>
111
+ </layout>
112
+ <routers>
113
+ <catalog>
114
+ <args>
115
+ <modules>
116
+ <ayalinebestsales before="Mage_Catalog">Ayaline_BestSales_Catalog</ayalinebestsales>
117
+ </modules>
118
+ </args>
119
+ </catalog>
120
+ </routers>
121
+ </frontend>
122
+ <default>
123
+ <ayalinebestsales>
124
+ <general>
125
+ <nb_days_expiry>30</nb_days_expiry>
126
+ <decrease_if_canceled>1</decrease_if_canceled>
127
+ <show_out_of_stock>0</show_out_of_stock>
128
+ </general>
129
+ <sidebar>
130
+ <count>5</count>
131
+ <nb_days>30</nb_days>
132
+ <truncate_name>0</truncate_name>
133
+ </sidebar>
134
+ <list>
135
+ <is_active>1</is_active>
136
+ <size>30</size>
137
+ <display_mode>grid</display_mode>
138
+ </list>
139
+ </ayalinebestsales>
140
+ </default>
141
+ <crontab>
142
+ <jobs>
143
+ <ayalinebestsales_clean_old>
144
+ <schedule><cron_expr>0 0 * * *</cron_expr></schedule>
145
+ <run><model>ayalinebestsales/bestSales::cleanOld</model></run>
146
+ </ayalinebestsales_clean_old>
147
+ <ayalinebestsales_index_best_sales>
148
+ <schedule><cron_expr>0 1 * * *</cron_expr></schedule>
149
+ <run><model>ayalinebestsales/bestSalesIndex::indexBestSales</model></run>
150
+ </ayalinebestsales_index_best_sales>
151
+ </jobs>
152
+ </crontab>
153
+ </config>
app/code/community/Ayaline/BestSales/etc/system.xml ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * created : 07/04/2011
5
+ *
6
+ * @category Ayaline
7
+ * @package Ayaline_BestSales
8
+ * @author aYaline
9
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
10
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
11
+ */
12
+ -->
13
+ <config>
14
+ <sections>
15
+ <ayalinebestsales translate="label" module="ayalinebestsales">
16
+ <label>Best sales</label>
17
+ <tab>ayaline</tab>
18
+ <header_css>ayaline-header</header_css>
19
+ <frontend_type>text</frontend_type>
20
+ <sort_order>100</sort_order>
21
+ <show_in_default>1</show_in_default>
22
+ <show_in_website>1</show_in_website>
23
+ <show_in_store>1</show_in_store>
24
+ <groups>
25
+ <general translate="label">
26
+ <label>General options</label>
27
+ <frontend_type>text</frontend_type>
28
+ <sort_order>100</sort_order>
29
+ <show_in_default>1</show_in_default>
30
+ <show_in_website>1</show_in_website>
31
+ <show_in_store>1</show_in_store>
32
+ <fields>
33
+ <nb_days_expiry translate="label">
34
+ <label>Number of days before expiry</label>
35
+ <frontend_type>text</frontend_type>
36
+ <frontend_class>validate-number</frontend_class>
37
+ <sort_order>10</sort_order>
38
+ <show_in_default>1</show_in_default>
39
+ <show_in_website>1</show_in_website>
40
+ <show_in_store>1</show_in_store>
41
+ </nb_days_expiry>
42
+ <decrease_if_canceled translate="label comment">
43
+ <label>Decrease if order is canceled</label>
44
+ <frontend_type>select</frontend_type>
45
+ <source_model>adminhtml/system_config_source_yesno</source_model>
46
+ <sort_order>20</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ <comment>If yes, ordered quantities will be decreased in best sales for all ordered items of the canceled order.</comment>
51
+ </decrease_if_canceled>
52
+ <show_out_of_stock translate="label">
53
+ <label>Display Out of Stock Products</label>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>adminhtml/system_config_source_yesno</source_model>
56
+ <sort_order>30</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <show_in_website>1</show_in_website>
59
+ <show_in_store>1</show_in_store>
60
+ </show_out_of_stock>
61
+ </fields>
62
+ </general>
63
+ <sidebar translate="label">
64
+ <label>Best sales sidebar</label>
65
+ <frontend_type>text</frontend_type>
66
+ <sort_order>200</sort_order>
67
+ <show_in_default>1</show_in_default>
68
+ <show_in_website>1</show_in_website>
69
+ <show_in_store>1</show_in_store>
70
+ <fields>
71
+ <count translate="label">
72
+ <label>Max products displayed</label>
73
+ <frontend_type>text</frontend_type>
74
+ <frontend_class>validate-number</frontend_class>
75
+ <sort_order>10</sort_order>
76
+ <show_in_default>1</show_in_default>
77
+ <show_in_website>1</show_in_website>
78
+ <show_in_store>1</show_in_store>
79
+ </count>
80
+ <nb_days translate="label">
81
+ <label>Number of days</label>
82
+ <frontend_type>text</frontend_type>
83
+ <frontend_class>validate-number</frontend_class>
84
+ <sort_order>20</sort_order>
85
+ <show_in_default>1</show_in_default>
86
+ <show_in_website>1</show_in_website>
87
+ <show_in_store>1</show_in_store>
88
+ <comment>Best sales sidebar will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.</comment>
89
+ </nb_days>
90
+ <truncate_name translate="label comment">
91
+ <label>Max characters number displayed in product name</label>
92
+ <frontend_type>text</frontend_type>
93
+ <frontend_class>validate-number</frontend_class>
94
+ <sort_order>30</sort_order>
95
+ <show_in_default>1</show_in_default>
96
+ <show_in_website>1</show_in_website>
97
+ <show_in_store>1</show_in_store>
98
+ <comment>Use 0 value for no limit.</comment>
99
+ </truncate_name>
100
+ </fields>
101
+ </sidebar>
102
+ <list translate="label">
103
+ <label>Best sales list</label>
104
+ <frontend_type>text</frontend_type>
105
+ <sort_order>300</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ <fields>
110
+ <is_active translate="label">
111
+ <label>Is active</label>
112
+ <frontend_type>select</frontend_type>
113
+ <source_model>adminhtml/system_config_source_yesno</source_model>
114
+ <sort_order>10</sort_order>
115
+ <show_in_default>1</show_in_default>
116
+ <show_in_website>1</show_in_website>
117
+ <show_in_store>1</show_in_store>
118
+ </is_active>
119
+ <size translate="label comment">
120
+ <label>Number of days</label>
121
+ <frontend_type>text</frontend_type>
122
+ <frontend_class>validate-number</frontend_class>
123
+ <sort_order>20</sort_order>
124
+ <show_in_default>1</show_in_default>
125
+ <show_in_website>1</show_in_website>
126
+ <show_in_store>1</show_in_store>
127
+ <comment><![CDATA[Best sales list will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.]]></comment>
128
+ </size>
129
+ <display_mode translate="label">
130
+ <label>Display mode</label>
131
+ <frontend_type>select</frontend_type>
132
+ <source_model>ayalinebestsales/adminhtml_system_config_source_listMode</source_model>
133
+ <sort_order>30</sort_order>
134
+ <show_in_default>1</show_in_default>
135
+ <show_in_website>1</show_in_website>
136
+ <show_in_store>1</show_in_store>
137
+ </display_mode>
138
+ </fields>
139
+ </list>
140
+ </groups>
141
+ </ayalinebestsales>
142
+ </sections>
143
+ </config>
app/code/community/Ayaline/BestSales/etc/widget.xml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * created : 07/04/2011
5
+ *
6
+ * @category Ayaline
7
+ * @package Ayaline_BestSales
8
+ * @author aYaline
9
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
10
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
11
+ */
12
+ -->
13
+ <widgets>
14
+
15
+ <ayalinebestsales_widgets_bestsales type="ayalinebestsales/widget_bestSales" module="ayalinebestsales" translate="name description label">
16
+ <name>Best Sales Products</name>
17
+ <description>Display best sales products (if widget is displayed in category, products will be filter by it)</description>
18
+ <parameters>
19
+ <products_count>
20
+ <visible>1</visible>
21
+ <required>1</required>
22
+ <value>5</value>
23
+ <label>Number of Products to Display</label>
24
+ <type>text</type>
25
+ <sort_order>10</sort_order>
26
+ </products_count>
27
+ <column_count>
28
+ <visible>1</visible>
29
+ <required>1</required>
30
+ <value>3</value>
31
+ <label>Number of Columns</label>
32
+ <type>text</type>
33
+ <sort_order>15</sort_order>
34
+ <depends><template><value>ayaline/best_sales/widget/grid.phtml</value></template></depends>
35
+ </column_count>
36
+ <template>
37
+ <label>Template</label>
38
+ <visible>1</visible>
39
+ <required>1</required>
40
+ <type>select</type>
41
+ <value>ayaline/best_sales/widget/list.phtml</value>
42
+ <values>
43
+ <default>
44
+ <value>ayaline/best_sales/widget/list.phtml</value>
45
+ <label>Products list template</label>
46
+ </default>
47
+ <grid>
48
+ <value>ayaline/best_sales/widget/grid.phtml</value>
49
+ <label>Products grid template</label>
50
+ </grid>
51
+ </values>
52
+ <sort_order>20</sort_order>
53
+ </template>
54
+ </parameters>
55
+ </ayalinebestsales_widgets_bestsales>
56
+
57
+ </widgets>
app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 07/04/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ $installer = $this;
17
+ /* @var $installer Mage_Catalog_Model_Resource_Eav_Mysql4_Setup */
18
+
19
+ $installer->run("
20
+
21
+ DROP TABLE IF EXISTS {$this->getTable('ayalinebestsales/best_sales')};
22
+ CREATE TABLE {$this->getTable('ayalinebestsales/best_sales')} (
23
+ `best_sales_id` int(10) unsigned NOT NULL auto_increment,
24
+ `product_id` int(10) unsigned NOT NULL,
25
+ `store_id` smallint(5) unsigned NOT NULL,
26
+ `sales_date` date NOT NULL default '0000-00-00',
27
+ `sales_count` int(10) unsigned NOT NULL default '0',
28
+ PRIMARY KEY (`best_sales_id`),
29
+ UNIQUE KEY `UK_AYALINE_BESTSALES` (`product_id`,`store_id`,`sales_date`),
30
+ CONSTRAINT `FK_AYALINE_BESTSALES_PRODUCT` FOREIGN KEY (`product_id`) REFERENCES {$this->getTable('catalog/product')} (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE,
31
+ CONSTRAINT `FK_AYALINE_BESTSALES_STORE` FOREIGN KEY (`store_id`) REFERENCES {$this->getTable('core_store')} (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE
32
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
33
+
34
+
35
+ ");
app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.0-0.1.1.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 27/05/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ $installer = $this;
17
+ /* @var $installer Mage_Catalog_Model_Resource_Eav_Mysql4_Setup */
18
+
19
+ $installer->startSetup();
20
+
21
+ $installer->run("
22
+ CREATE TABLE IF NOT EXISTS `{$installer->getTable('ayalinebestsales/best_sales_index')}` (
23
+ `index_id` INT(10) NOT NULL AUTO_INCREMENT ,
24
+ `product_id` INT(10) UNSIGNED NOT NULL ,
25
+ `day` SMALLINT(5) UNSIGNED NOT NULL ,
26
+ `store_id` SMALLINT(5) UNSIGNED NOT NULL ,
27
+ `nb_sales` INT(10) UNSIGNED NOT NULL ,
28
+ PRIMARY KEY (`index_id`) ,
29
+
30
+ INDEX `AYALINE_BEST_SALES_INDEX_DAY_IDX` (`day` ASC) ,
31
+ INDEX `AYALINE_BEST_SALES_INDEX_PRODUCT_ID_IDX` (`product_id` ASC) ,
32
+ INDEX `AYALINE_BEST_SALES_INDEX_STORE_ID_IDX` (`store_id` ASC) ,
33
+
34
+ UNIQUE INDEX `AYALINE_BEST_SALES_INDEX_UNIQUE_KEY` (`product_id` ASC, `day` ASC, `store_id` ASC) ,
35
+
36
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_PRODUCT_ID`
37
+ FOREIGN KEY (`product_id` )
38
+ REFERENCES `{$installer->getTable('catalog/product')}` (`entity_id` )
39
+ ON DELETE NO ACTION
40
+ ON UPDATE NO ACTION,
41
+
42
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_STORE_ID`
43
+ FOREIGN KEY (`store_id` )
44
+ REFERENCES `{$installer->getTable('core/store')}` (`store_id` )
45
+ ON DELETE NO ACTION
46
+ ON UPDATE NO ACTION)
47
+
48
+ ENGINE = InnoDB;
49
+
50
+ ");
51
+
52
+ $installer->endSetup();
app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.1-0.1.2.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 27/05/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ $installer = $this;
17
+ /* @var $installer Mage_Catalog_Model_Resource_Eav_Mysql4_Setup */
18
+
19
+ $installer->startSetup();
20
+
21
+ $installer->run("
22
+
23
+ ALTER TABLE `{$installer->getTable('ayalinebestsales/best_sales_index')}` DROP FOREIGN KEY `FK_AYALINE_BEST_SALES_INDEX_PRODUCT_ID`;
24
+ ALTER TABLE `{$installer->getTable('ayalinebestsales/best_sales_index')}` DROP FOREIGN KEY `FK_AYALINE_BEST_SALES_INDEX_STORE_ID`;
25
+
26
+ ALTER TABLE `{$installer->getTable('ayalinebestsales/best_sales_index')}` ADD
27
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_PRODUCT_ID`
28
+ FOREIGN KEY (`product_id` )
29
+ REFERENCES `{$installer->getTable('catalog/product')}` (`entity_id` )
30
+ ON DELETE CASCADE
31
+ ON UPDATE CASCADE
32
+ ;
33
+
34
+ ALTER TABLE `{$installer->getTable('ayalinebestsales/best_sales_index')}` ADD
35
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_STORE_ID`
36
+ FOREIGN KEY (`store_id` )
37
+ REFERENCES `{$installer->getTable('core/store')}` (`store_id` )
38
+ ON DELETE CASCADE
39
+ ON UPDATE CASCADE
40
+ ;
41
+
42
+ ");
43
+
44
+ $installer->endSetup();
app/code/community/Ayaline/BestSales/sql/ayalinebestsales_setup/mysql4-upgrade-0.1.2-0.1.3.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * created : 27/05/2011
4
+ *
5
+ * @category Ayaline
6
+ * @package Ayaline_BestSales
7
+ * @author aYaline
8
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
9
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
10
+ */
11
+
12
+ /**
13
+ *
14
+ * @package Ayaline_BestSales
15
+ */
16
+ $installer = $this;
17
+ /* @var $installer Mage_Catalog_Model_Resource_Eav_Mysql4_Setup */
18
+
19
+ $installer->startSetup();
20
+
21
+ $installer->run("
22
+
23
+ CREATE TABLE IF NOT EXISTS `{$installer->getTable('ayalinebestsales/best_sales_index_idx')}` (
24
+ `index_id` INT(10) NOT NULL AUTO_INCREMENT ,
25
+ `product_id` INT(10) UNSIGNED NOT NULL ,
26
+ `day` SMALLINT(5) UNSIGNED NOT NULL ,
27
+ `store_id` SMALLINT(5) UNSIGNED NOT NULL ,
28
+ `nb_sales` INT(10) UNSIGNED NOT NULL ,
29
+ PRIMARY KEY (`index_id`) ,
30
+
31
+ INDEX `AYALINE_BEST_SALES_INDEX_IDX_DAY_IDX` (`day` ASC) ,
32
+ INDEX `AYALINE_BEST_SALES_INDEX_IDX_PRODUCT_ID_IDX` (`product_id` ASC) ,
33
+ INDEX `AYALINE_BEST_SALES_INDEX_IDX_STORE_ID_IDX` (`store_id` ASC) ,
34
+
35
+ UNIQUE INDEX `AYALINE_BEST_SALES_INDEX_IDX_UNIQUE_KEY` (`product_id` ASC, `day` ASC, `store_id` ASC) ,
36
+
37
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_IDX_PRODUCT_ID`
38
+ FOREIGN KEY (`product_id` )
39
+ REFERENCES `{$installer->getTable('catalog/product')}` (`entity_id` )
40
+ ON DELETE CASCADE
41
+ ON UPDATE CASCADE,
42
+
43
+ CONSTRAINT `FK_AYALINE_BEST_SALES_INDEX_IDX_STORE_ID`
44
+ FOREIGN KEY (`store_id` )
45
+ REFERENCES `{$installer->getTable('core/store')}` (`store_id` )
46
+ ON DELETE CASCADE
47
+ ON UPDATE CASCADE)
48
+
49
+ ENGINE = InnoDB;
50
+
51
+ ");
52
+
53
+ $installer->endSetup();
app/etc/modules/Ayaline_BestSales.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * created : 07/04/2011
5
+ *
6
+ * @category Ayaline
7
+ * @package Ayaline_BestSales
8
+ * @author aYaline
9
+ * @copyright Ayaline - 2012 - http://magento-shop.ayaline.com
10
+ * @license http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html
11
+ */
12
+ -->
13
+ <config>
14
+ <modules>
15
+ <Ayaline_BestSales>
16
+ <active>true</active>
17
+ <codePool>community</codePool>
18
+ <depends>
19
+ <Ayaline_Core />
20
+ </depends>
21
+ </Ayaline_BestSales>
22
+ </modules>
23
+ </config>
app/locale/en_US/Ayaline_BestSales.csv ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Ayaline Best Sales","Ayaline Best Sales"
2
+ "Best sales","Best sales"
3
+ "General options","General options"
4
+ "Number of days before expiry","Number of days before expiry"
5
+ "Decrease if order is canceled","Decrease if order is canceled"
6
+ "If yes, ordered quantities will be decreased in best sales for all ordered items of the canceled order.","If yes, ordered quantities will be decreased in best sales for all ordered items of the canceled order."
7
+ "Best sales sidebar","Best sales sidebar"
8
+ "Max products displayed","Max products displayed"
9
+ "Number of days","Number of days"
10
+ "Best sales sidebar will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.","Best sales sidebar will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value."
11
+ "Max characters number displayed in product name","Max characters number displayed in product name"
12
+ "Use 0 value for no limit.","Use 0 value for no limit."
13
+ "Best sales list","Best sales list"
14
+ "Best sales list will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.","Best sales list will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value."
15
+ "Display Out of Stock Products","Display Out of Stock Products"
16
+ "View all best sales","View all best sales"
17
+ "Grid","Grid"
18
+ "List","List"
19
+ "Display mode","Display mode"
20
+ "Is active","Is active"
21
+ "An error occurred while indexing ""%s"" to the store %s","An error occurred while indexing ""%s"" to the store %s"
22
+ "An error occurred while indexing ""%s""",""An error occurred while indexing ""%s"""
23
+ "Best Sales Products","Best Sales Products"
24
+ "Display best sales products (if widget is displayed in category, products will be filter by it)","Display best sales products (if widget is displayed in category, products will be filter by it)"
25
+ "Number of Products to Display","Number of Products to Display"
26
+ "Number of Columns","Number of Columns"
27
+ "Template","Template"
28
+ "Products list template","Products list template"
29
+ "Products grid template","Products grid template"
app/locale/fr_FR/Ayaline_BestSales.csv ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Ayaline Best Sales","Ayaline meilleures ventes"
2
+ "Best sales","Meilleures ventes"
3
+ "General options","Options générales"
4
+ "Number of days before expiry","Nombre de jours avant expiration"
5
+ "Decrease if order is canceled","Décompter en cas d'annulation de commande"
6
+ "If yes, ordered quantities will be decreased in best sales for all ordered items of the canceled order.","Si oui, les quantités commandées seront décomptées des meilleures ventes pour tous les articles de la commande annulée."
7
+ "Best sales sidebar","Barre latérale des meilleures ventes"
8
+ "Max products displayed","Nombre maximum de produits affichés"
9
+ "Number of days","Nombre de jours"
10
+ "Best sales sidebar will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.","La barre latérale des meilleures ventes affichera les produits achetés les N derniers jours. La valeur doit être inférieure à la valeur 'Nombre de jours avant expiration'."
11
+ "Max characters number displayed in product name","Nombre maximum de caractères affichés dans le nom du produit"
12
+ "Use 0 value for no limit.","Utiliser 0 pour ne pas limiter."
13
+ "Best sales list","Liste des meilleures ventes"
14
+ "Best sales list will display products bought the last N days. The value should be smaller than 'Number of days before expiry' value.","La liste des meilleures ventes affichera les produits achetés les N derniers jours. La valeur doit être inférieure à la valeur 'Nombre de jours avant expiration'."
15
+ "Display Out of Stock Products","Afficher les produits hors stock"
16
+ "View all best sales","Voir toutes les meilleures ventes"
17
+ "Grid","Grille"
18
+ "List","Liste"
19
+ "Display mode","Mode d'affichage"
20
+ "Is active","Activé"
21
+ "An error occurred while indexing ""%s"" to the store %s","Une erreur est survenue lors de l'indexation de ""%s"", pour le magasin %s"
22
+ "An error occurred while indexing ""%s""","Une erreur est survenue lors de l'indexation de ""%s"""
23
+ "Best Sales Products","Produits en Meilleures Ventes"
24
+ "Display best sales products (if widget is displayed in category, products will be filter by it)","Affiche les produits en meilleures ventes (si le widget est affiché dans une catégorie, les produits seront filtrés sur celle-ci)"
25
+ "Number of Products to Display","Nombre de produits à afficher"
26
+ "Number of Columns","Nombre de colonnes"
27
+ "Template","Gabarit"
28
+ "Products list template","Liste de produits"
29
+ "Products grid template","Grille de produits"
package.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Ayaline_BestSales</name>
4
+ <version>1.1.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://magento-shop.ayaline.com/fr/conditions-generales-de-vente.html">aYaline Custom License</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Enhance your site content by displaying most saled products</summary>
10
+ <description>Ayaline BestSales extension allows you to display the best sales performed on your site during the last days.&#xD;
11
+ This module doesn&#x2019;t rely on Magento&#x2019;s core reporting tables but uses it&#x2019;s own set of data for performance reasons.&#xD;
12
+ Ayaline BestSales will allow you to present the most saled products in front-office.&#xD;
13
+ The included block &#x201C;sidebar&#x201D; display most saled products for the current category.&#xD;
14
+ Outside the scope of a category, best sales all category together are displayed.&#xD;
15
+ Ayaline BestSales also offers a dedicated list page showing all the sites most saled products. This page can be enable or not.</description>
16
+ <notes>Enhance your site content by displaying most saled products</notes>
17
+ <authors><author><name>aYaline Team</name><user>auto-converted</user><email>magento@ayaline.com</email></author></authors>
18
+ <date>2012-03-26</date>
19
+ <time>13:15:50</time>
20
+ <contents><target name="magecommunity"><dir name="Ayaline"><dir name="BestSales"><dir name="Block"><dir name="Widget"><file name="BestSales.php" hash="aa35250333964df6fb53be428316b9f5"/></dir><file name="List.php" hash="aa6b89fe8cb60982aa399a0c10a724d3"/><file name="Sidebar.php" hash="219bc33dd5a7927c9d04a759a76659c3"/></dir><dir name="Helper"><file name="Data.php" hash="1a8046eb88953786c284747566f4c32c"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Source"><file name="ListMode.php" hash="0f18f985c261c47472bc683ec695731d"/></dir></dir></dir></dir><dir name="Mysql4"><dir name="BestSales"><file name="Collection.php" hash="87b91973337447b0f5ff2c29e0b95efb"/></dir><file name="BestSales.php" hash="e15fe9891379b440f920bb3c963aa7c7"/><file name="BestSalesIndex.php" hash="c28a9b4143426aaecf0880d99cc9ee2c"/></dir><file name="BestSales.php" hash="a410e83fd95e75f406814d772997f9c5"/><file name="BestSalesIndex.php" hash="6c5dfeda4f76e16c1cb4086cf86b8f57"/><file name="Observer.php" hash="6deebbf33235de011afe98d30f02d1a8"/></dir><dir name="controllers"><dir name="Catalog"><file name="BestsalesController.php" hash="5bb917d0054f725c3b0fed2fbf13b8a8"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="5dfc297d8cc54b1a952593f36bbc3188"/><file name="config.xml" hash="d9bc0a64b670d3497431db8778657932"/><file name="system.xml" hash="7928ba777217b03b734f2d3d06cdcf28"/><file name="widget.xml" hash="0cdf8b6b5579a526174baf811151b949"/></dir><dir name="sql"><dir name="ayalinebestsales_setup"><file name="mysql4-install-0.1.0.php" hash="9c50db65c07e8eaba8de1a141c15e775"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="7794d28ebc977ca3ea032d81dcd735b5"/><file name="mysql4-upgrade-0.1.1-0.1.2.php" hash="287c7c36a60c0acf746f66bdac8df61e"/><file name="mysql4-upgrade-0.1.2-0.1.3.php" hash="02a8c161c1407010dc1dfba3cd5a896a"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="ayaline"><file name="best_sales.xml" hash=""/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Ayaline_BestSales.xml" hash="fab2bfda97cf8149989fb59ced233c6c"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Ayaline_BestSales.csv" hash="38950d9a5133872843417e13549702f6"/></dir><dir name="fr_FR"><file name="Ayaline_BestSales.csv" hash="6ab618f202f128fa519e256e5a6a1a54"/></dir></target></contents>
21
+ <compatible/>
22
+ <dependencies><required><package><name>Ayaline_Core</name><channel>community</channel><min></min><max></max></package></required></dependencies>
23
+ </package>