Version Notes
- Fixed minor issues
- Enhanced grids
- Improved prediction model
Download this release
Release Info
Developer | Reckless |
Extension | Recklessio_Prediction |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0.1 to 1.1.0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Customer/Online/Grid.php +0 -0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Grid.php +0 -0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions.php +0 -0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions/Grid.php +32 -0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions.php +0 -0
- app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions/Grid.php +16 -47
- app/code/local/Reckless/Prediction/Helper/Data.php +75 -23
- app/code/local/Reckless/Prediction/Model/Promotion/Observer.php +10 -4
- app/code/local/Reckless/Prediction/Model/Promotions.php +50 -12
- app/code/local/Reckless/Prediction/Model/Resource/Promotions.php +0 -0
- app/code/local/Reckless/Prediction/Model/Resource/Promotions/Collection.php +0 -0
- app/code/local/Reckless/Prediction/Model/Resource/Setup.php +0 -0
- app/code/local/Reckless/Prediction/controllers/Adminhtml/PredictionController.php +0 -0
- app/code/local/Reckless/Prediction/data/reckless_prediction_setup/data-install-0.1.0.php +1 -1
- app/code/local/Reckless/Prediction/etc/adminhtml.xml +0 -0
- app/code/local/Reckless/Prediction/etc/config.xml +43 -40
- app/code/local/Reckless/Prediction/etc/system.xml +29 -7
- app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-install-0.1.0.php +1 -2
- app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-upgrade-0.1.0-0.1.1.php +15 -0
- app/etc/modules/Reckless_Prediction.xml +0 -0
- package.xml +69 -14
app/code/local/Reckless/Prediction/Block/Adminhtml/Customer/Online/Grid.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Block/Adminhtml/Grid.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions/Grid.php
CHANGED
@@ -15,11 +15,14 @@ class Reckless_Prediction_Block_Adminhtml_Predictions_Grid extends Mage_Adminhtm
|
|
15 |
->getCollection();
|
16 |
|
17 |
$this->setCollection($collection);
|
|
|
18 |
return parent::_prepareCollection();
|
19 |
}
|
20 |
|
21 |
protected function _prepareColumns()
|
22 |
{
|
|
|
|
|
23 |
$this->addColumn(
|
24 |
'entity_id',
|
25 |
array(
|
@@ -73,6 +76,34 @@ class Reckless_Prediction_Block_Adminhtml_Predictions_Grid extends Mage_Adminhtm
|
|
73 |
'index' => 'discount_percent',
|
74 |
)
|
75 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
$this->addColumn(
|
77 |
'created_at',
|
78 |
array(
|
@@ -86,6 +117,7 @@ class Reckless_Prediction_Block_Adminhtml_Predictions_Grid extends Mage_Adminhtm
|
|
86 |
|
87 |
$this->addExportType('*/*/exportPredictionsCsv', 'CSV');
|
88 |
$this->addExportType('*/*/exportPredictionsExcel', 'Excel');
|
|
|
89 |
return parent::_prepareColumns();
|
90 |
}
|
91 |
}
|
15 |
->getCollection();
|
16 |
|
17 |
$this->setCollection($collection);
|
18 |
+
|
19 |
return parent::_prepareCollection();
|
20 |
}
|
21 |
|
22 |
protected function _prepareColumns()
|
23 |
{
|
24 |
+
$currencyCode = Mage::app()->getBaseCurrencyCode();
|
25 |
+
|
26 |
$this->addColumn(
|
27 |
'entity_id',
|
28 |
array(
|
76 |
'index' => 'discount_percent',
|
77 |
)
|
78 |
);
|
79 |
+
$this->addColumn(
|
80 |
+
'aov_global',
|
81 |
+
array(
|
82 |
+
'header' => 'Average Order Value',
|
83 |
+
'align' =>'left',
|
84 |
+
'type' => 'price',
|
85 |
+
'currency_code' => $currencyCode,
|
86 |
+
'index' => 'aov_global',
|
87 |
+
)
|
88 |
+
);
|
89 |
+
$this->addColumn(
|
90 |
+
'ltv_global',
|
91 |
+
array(
|
92 |
+
'header' => 'LifeTime Value',
|
93 |
+
'align' =>'left',
|
94 |
+
'type' => 'price',
|
95 |
+
'currency_code' => $currencyCode,
|
96 |
+
'index' => 'ltv_global',
|
97 |
+
)
|
98 |
+
);
|
99 |
+
$this->addColumn(
|
100 |
+
'total_orders',
|
101 |
+
array(
|
102 |
+
'header' => 'Total Orders',
|
103 |
+
'align' =>'left',
|
104 |
+
'index' => 'total_orders',
|
105 |
+
)
|
106 |
+
);
|
107 |
$this->addColumn(
|
108 |
'created_at',
|
109 |
array(
|
117 |
|
118 |
$this->addExportType('*/*/exportPredictionsCsv', 'CSV');
|
119 |
$this->addExportType('*/*/exportPredictionsExcel', 'Excel');
|
120 |
+
|
121 |
return parent::_prepareColumns();
|
122 |
}
|
123 |
}
|
app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions/Grid.php
CHANGED
@@ -14,32 +14,25 @@ class Reckless_Prediction_Block_Adminhtml_Redemptions_Grid extends Mage_Adminhtm
|
|
14 |
* Add custom column to the grid
|
15 |
*
|
16 |
*/
|
17 |
-
//public function setCollection($collection)
|
18 |
-
//{
|
19 |
-
// $collection->getSelect()->joinLeft(array('coupon_agg'=> 'coupon_aggregated'), 'coupon_agg.coupon_code = main_table.code', array('coupon_agg.coupon_uses'));
|
20 |
-
// parent::setCollection($collection);
|
21 |
-
//}
|
22 |
public function setCollection($collection)
|
23 |
{
|
24 |
$collection->getSelect()->joinLeft(
|
25 |
array('orders'=> 'sales_flat_order'),
|
26 |
'orders.coupon_code = main_table.coupon_code',
|
27 |
-
array('orders.base_grand_total', 'orders.increment_id', 'orders.created_at', 'orders.base_discount_amount', 'orders.customer_is_guest')
|
28 |
);
|
29 |
parent::setCollection($collection);
|
30 |
}
|
31 |
|
32 |
protected function _prepareCollection()
|
33 |
{
|
34 |
-
// $collection = Mage::getModel('salesrule/coupon')
|
35 |
-
// ->getCollection()
|
36 |
-
// ->addFieldToFilter('code',array('like'=>'CEO%'));
|
37 |
$collection = Mage::getModel('prediction/promotions')->getCollection();
|
38 |
$collection->addFieldToSelect(array('checkout_intent', 'coupon_code'));
|
39 |
|
40 |
//Prevent from collection failure if the same coupon has been used more than once
|
41 |
$collection->getSelect()->group('main_table.entity_id');
|
42 |
$this->setCollection($collection);
|
|
|
43 |
return parent::_prepareCollection();
|
44 |
|
45 |
}
|
@@ -78,7 +71,9 @@ class Reckless_Prediction_Block_Adminhtml_Redemptions_Grid extends Mage_Adminhtm
|
|
78 |
array(
|
79 |
'header' => 'Discount Amount',
|
80 |
'align' =>'right',
|
81 |
-
'
|
|
|
|
|
82 |
)
|
83 |
);
|
84 |
$this->addColumn(
|
@@ -103,49 +98,23 @@ class Reckless_Prediction_Block_Adminhtml_Redemptions_Grid extends Mage_Adminhtm
|
|
103 |
array(
|
104 |
'header' => 'Grand Total',
|
105 |
'align' =>'right',
|
|
|
|
|
106 |
'index' => 'base_grand_total',
|
107 |
)
|
108 |
);
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
array(
|
118 |
-
'header' => 'Uses',
|
119 |
-
'align' =>'right',
|
120 |
-
'index' => 'coupon_uses',
|
121 |
-
));
|
122 |
-
$this->addColumn('coupon_uses',
|
123 |
-
array(
|
124 |
-
'header' => 'Uses',
|
125 |
-
'align' =>'right',
|
126 |
-
'index' => 'coupon_uses',
|
127 |
-
));
|
128 |
-
|
129 |
-
$this->addColumn('coupon_uses',
|
130 |
-
array(
|
131 |
-
'header' => 'Uses',
|
132 |
-
'align' =>'right',
|
133 |
-
'index' => 'coupon_uses',
|
134 |
-
));
|
135 |
|
136 |
-
$this->addColumn('coupon_uses',
|
137 |
-
array(
|
138 |
-
'header' => 'Uses',
|
139 |
-
'align' =>'right',
|
140 |
-
'index' => 'coupon_uses',
|
141 |
-
));
|
142 |
-
*/
|
143 |
$this->addExportType('*/*/exportRedemptionsCsv', 'CSV');
|
144 |
$this->addExportType('*/*/exportRedemptionsExcel', 'Excel');
|
|
|
145 |
return parent::_prepareColumns();
|
146 |
}
|
147 |
-
// public function getRowUrl($row)
|
148 |
-
// {
|
149 |
-
// return $this->getUrl('*/*/edit', array('id' => $row->getId()));
|
150 |
-
// }
|
151 |
}
|
14 |
* Add custom column to the grid
|
15 |
*
|
16 |
*/
|
|
|
|
|
|
|
|
|
|
|
17 |
public function setCollection($collection)
|
18 |
{
|
19 |
$collection->getSelect()->joinLeft(
|
20 |
array('orders'=> 'sales_flat_order'),
|
21 |
'orders.coupon_code = main_table.coupon_code',
|
22 |
+
array('orders.base_grand_total','orders.base_to_global_rate', 'orders.increment_id', 'orders.created_at', 'orders.base_discount_amount', 'orders.customer_is_guest', 'orders.global_currency_code')
|
23 |
);
|
24 |
parent::setCollection($collection);
|
25 |
}
|
26 |
|
27 |
protected function _prepareCollection()
|
28 |
{
|
|
|
|
|
|
|
29 |
$collection = Mage::getModel('prediction/promotions')->getCollection();
|
30 |
$collection->addFieldToSelect(array('checkout_intent', 'coupon_code'));
|
31 |
|
32 |
//Prevent from collection failure if the same coupon has been used more than once
|
33 |
$collection->getSelect()->group('main_table.entity_id');
|
34 |
$this->setCollection($collection);
|
35 |
+
|
36 |
return parent::_prepareCollection();
|
37 |
|
38 |
}
|
71 |
array(
|
72 |
'header' => 'Discount Amount',
|
73 |
'align' =>'right',
|
74 |
+
'type' => 'price',
|
75 |
+
'currency_code' => 'USD',
|
76 |
+
'index' => 'base_discount_amount * base_to_global_rate',
|
77 |
)
|
78 |
);
|
79 |
$this->addColumn(
|
98 |
array(
|
99 |
'header' => 'Grand Total',
|
100 |
'align' =>'right',
|
101 |
+
'type' => 'price',
|
102 |
+
'currency_code' => 'USD',
|
103 |
'index' => 'base_grand_total',
|
104 |
)
|
105 |
);
|
106 |
+
$this->addColumn(
|
107 |
+
'global_currency_code',
|
108 |
+
array(
|
109 |
+
'header' => 'Base Currency',
|
110 |
+
'align' =>'right',
|
111 |
+
'index' => 'global_currency_code',
|
112 |
+
)
|
113 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
$this->addExportType('*/*/exportRedemptionsCsv', 'CSV');
|
116 |
$this->addExportType('*/*/exportRedemptionsExcel', 'Excel');
|
117 |
+
|
118 |
return parent::_prepareColumns();
|
119 |
}
|
|
|
|
|
|
|
|
|
120 |
}
|
app/code/local/Reckless/Prediction/Helper/Data.php
CHANGED
@@ -26,14 +26,17 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
26 |
const RECKLESS_PROMOTIONS_ENABLED = 'reckless_prediction/reckless_promotions_section/reckless_dynamic_promotion_enable';
|
27 |
const RECKLESS_PRMOTIONS_THRESHOLD = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promotion_threshould';
|
28 |
const RECKLESS_PROMOTIONS_VAILDITY = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocodevalid_time';
|
|
|
29 |
const RECKLESS_PROMOTIONS_STOPRULESPROCESSING = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_stoprulesprocessing';
|
30 |
const RECKLESS_PROMOTIONS_COUPONTYPE = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_type';
|
31 |
const RECKLESS_PROMOTIONS_USAGEPERCUSTOMER = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_usagepercustomer';
|
32 |
const RECKLESS_PROMOTIONS_COUPONUSAGE = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_usage';
|
33 |
const RECKLESS_PROMOTIONS_COUPONPREFIX = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_prefix';
|
34 |
const RECKLESS_PROMOTIONS_COUPONDESC = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_desc';
|
|
|
35 |
const RECKLESS_PROMOTIONS_COUPONDISCPERCENT = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_percent';
|
36 |
-
const
|
|
|
37 |
|
38 |
/**
|
39 |
* Check if Reckless Module is enabled
|
@@ -46,6 +49,11 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
46 |
return (bool) Mage::getStoreConfig(self::RECKLESS_CORE_ENABLED);
|
47 |
}
|
48 |
|
|
|
|
|
|
|
|
|
|
|
49 |
/**
|
50 |
* Check if Log is Enabled
|
51 |
*
|
@@ -198,6 +206,21 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
198 |
}
|
199 |
}
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
/**
|
202 |
* Method to send notification emails
|
203 |
* @param unknown_type $sendToName
|
@@ -267,46 +290,69 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
267 |
}
|
268 |
}
|
269 |
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
/*
|
276 |
* Function to create
|
277 |
* a) Promotion Rule and
|
278 |
* b) coupon codes for Old and New Magento Versions
|
279 |
*/
|
280 |
|
281 |
-
public function createCouponCode($discount_percent, $store, $customer)
|
282 |
{
|
|
|
|
|
283 |
$coupon= $this->getCouponPrefix() . Mage::helper('core')->getRandomString(4) . "-" . $this->getCouponPostfix($customer);
|
284 |
Mage::log("Creating Coupon " . $coupon);
|
285 |
$model = $this->getRuleModel();
|
286 |
|
287 |
$now = new DateTime('NOW');
|
288 |
-
$couponValidFromDate = new DateTime();
|
289 |
-
$couponValidFromDate
|
|
|
|
|
290 |
$intervalToAdd = "P" . $this->getPromotionValidity() . "D";// Days
|
291 |
$couponValidToDate = $now->add(new DateInterval($intervalToAdd));
|
292 |
|
|
|
|
|
293 |
try {
|
294 |
|
295 |
if ($this->checkVersion() == 2) {
|
296 |
|
297 |
$rule = Mage::getModel('salesrule/rule')
|
298 |
->setName($coupon)
|
299 |
-
->setDescription($this->getCouponDescription() . $customer->getCustomerId())
|
300 |
->setFromDate(date($couponValidFromDate))
|
301 |
->setToDate($couponValidToDate->format('Y-m-d H:i:s'))
|
302 |
->setCustomerGroupIds($this->getCustomerGroups())
|
303 |
->setIsActive(1)
|
304 |
-
|
305 |
-
|
306 |
-
->setSimpleAction('by_percent')
|
307 |
-
->setDiscountAmount(min(100, $this->getCouponDiscountPercent()))
|
308 |
-
//->setDiscountQty
|
309 |
-
//->setDiscountStep
|
310 |
->setStopRulesProcessing($this->getStopRulesProcessing())
|
311 |
->setUseAutoGeneration(0)
|
312 |
->setIsRss(1)
|
@@ -325,16 +371,16 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
325 |
} else {
|
326 |
$model
|
327 |
->setName($coupon)
|
328 |
-
->setDescription($this->getCouponDescription() . $customer->getCustomerId())
|
329 |
->setFromDate(date($couponValidFromDate))
|
330 |
->setCouponCode($coupon)
|
331 |
->setToDate($couponValidToDate->format('Y-m-d H:i:s'))
|
332 |
->setCustomerGroupIds($this->getCustomerGroups())
|
333 |
->setIsActive(1)
|
334 |
-
->setSimpleAction(
|
335 |
-
|
336 |
->setWebsiteIds($this->getAllWebsites())
|
337 |
-
->setDiscountAmount(
|
338 |
->setStopRulesProcessing($this->getStopRulesProcessing())
|
339 |
->setIsRss(1)
|
340 |
->setUsesPerCoupon($this->getMaxCouponUsage())
|
@@ -478,8 +524,14 @@ class Reckless_Prediction_Helper_Data extends Mage_Core_Helper_Abstract
|
|
478 |
{
|
479 |
Mage::getModel('core/config')->saveConfig(self::RECKLESS_CORE_LAST_QUOTE, $id);
|
480 |
}
|
481 |
-
|
482 |
-
public function
|
483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
}
|
485 |
}
|
26 |
const RECKLESS_PROMOTIONS_ENABLED = 'reckless_prediction/reckless_promotions_section/reckless_dynamic_promotion_enable';
|
27 |
const RECKLESS_PRMOTIONS_THRESHOLD = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promotion_threshould';
|
28 |
const RECKLESS_PROMOTIONS_VAILDITY = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocodevalid_time';
|
29 |
+
const RECKLESS_PROMOTIONS_VAILDITY_STARTSFROM = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocodevalid_starts_from';
|
30 |
const RECKLESS_PROMOTIONS_STOPRULESPROCESSING = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_stoprulesprocessing';
|
31 |
const RECKLESS_PROMOTIONS_COUPONTYPE = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_type';
|
32 |
const RECKLESS_PROMOTIONS_USAGEPERCUSTOMER = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_usagepercustomer';
|
33 |
const RECKLESS_PROMOTIONS_COUPONUSAGE = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_usage';
|
34 |
const RECKLESS_PROMOTIONS_COUPONPREFIX = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_prefix';
|
35 |
const RECKLESS_PROMOTIONS_COUPONDESC = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_desc';
|
36 |
+
const RECKLESS_PROMOTIONS_COUPONDESC_TYPE = 'reckless_prediction/reckless_promotions_section/reckless_dynamic_promotion_discount_type';
|
37 |
const RECKLESS_PROMOTIONS_COUPONDISCPERCENT = 'reckless_prediction/reckless_promotions_section/reckless_prediction_promocode_percent';
|
38 |
+
const RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE_YES = 'reckless_prediction/reckless_promotions_section/reckless_prediction_customer_promo_message_yes';
|
39 |
+
const RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE_NO = 'reckless_prediction/reckless_promotions_section/reckless_prediction_customer_promo_message_no';
|
40 |
|
41 |
/**
|
42 |
* Check if Reckless Module is enabled
|
49 |
return (bool) Mage::getStoreConfig(self::RECKLESS_CORE_ENABLED);
|
50 |
}
|
51 |
|
52 |
+
public function isPromoCodeValueAPercentOfCurrentCart()
|
53 |
+
{
|
54 |
+
return (bool) Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_COUPONDESC_TYPE);
|
55 |
+
}
|
56 |
+
|
57 |
/**
|
58 |
* Check if Log is Enabled
|
59 |
*
|
206 |
}
|
207 |
}
|
208 |
|
209 |
+
/**
|
210 |
+
* Get Promotion Valifity Start From
|
211 |
+
* Defaut: 0 Days (Immediately which is Today)
|
212 |
+
* @return string
|
213 |
+
* @author Dhruv Boruah <hello@reckless.io>
|
214 |
+
*/
|
215 |
+
public function getPromotionValidityStartFrom()
|
216 |
+
{
|
217 |
+
if (strlen(Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_VAILDITY_STARTSFROM)) == 0) {
|
218 |
+
return 0;
|
219 |
+
} else {
|
220 |
+
return Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_VAILDITY_STARTSFROM);
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
/**
|
225 |
* Method to send notification emails
|
226 |
* @param unknown_type $sendToName
|
290 |
}
|
291 |
}
|
292 |
|
293 |
+
public function getCouponPostfix($customer)
|
294 |
+
{
|
295 |
+
if ($customer->getCustomerId() == NULL) {
|
296 |
+
return "G";
|
297 |
+
}
|
298 |
+
return $customer->getCustomerId();
|
299 |
+
}
|
300 |
+
|
301 |
+
public function getCouponAction()
|
302 |
+
{
|
303 |
+
if($this->isPromoCodeValueAPercentOfCurrentCart()) {
|
304 |
+
return 'cart_fixed';
|
305 |
+
} else {
|
306 |
+
return 'by_percent';
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
public function getCouponValue($quoteValue)
|
311 |
+
{
|
312 |
+
Mage::log("Getting Coupon Value Total " . $quoteValue);
|
313 |
+
if ($this->isPromoCodeValueAPercentOfCurrentCart()) {
|
314 |
+
return ($quoteValue * $this->getCouponDiscountPercent()) / 100;
|
315 |
+
} else
|
316 |
+
|
317 |
+
return min(100, $this->getCouponDiscountPercent());
|
318 |
+
}
|
319 |
/*
|
320 |
* Function to create
|
321 |
* a) Promotion Rule and
|
322 |
* b) coupon codes for Old and New Magento Versions
|
323 |
*/
|
324 |
|
325 |
+
public function createCouponCode($discount_percent, $store, $customer, $quoteValue)
|
326 |
{
|
327 |
+
//$discount_percent : Not used in current prediction model
|
328 |
+
|
329 |
$coupon= $this->getCouponPrefix() . Mage::helper('core')->getRandomString(4) . "-" . $this->getCouponPostfix($customer);
|
330 |
Mage::log("Creating Coupon " . $coupon);
|
331 |
$model = $this->getRuleModel();
|
332 |
|
333 |
$now = new DateTime('NOW');
|
334 |
+
$couponValidFromDate = new DateTime('NOW');
|
335 |
+
$couponValidFromDate->add(new DateInterval('P' . $this->getPromotionValidityStartFrom() . 'D'));
|
336 |
+
$couponValidFromDate = $couponValidFromDate->format(DateTime::ISO8601);
|
337 |
+
|
338 |
$intervalToAdd = "P" . $this->getPromotionValidity() . "D";// Days
|
339 |
$couponValidToDate = $now->add(new DateInterval($intervalToAdd));
|
340 |
|
341 |
+
$discount_amount = 0;
|
342 |
+
|
343 |
try {
|
344 |
|
345 |
if ($this->checkVersion() == 2) {
|
346 |
|
347 |
$rule = Mage::getModel('salesrule/rule')
|
348 |
->setName($coupon)
|
349 |
+
->setDescription($this->getCouponDescription() . $this->getCouponAction() . $customer->getCustomerId())
|
350 |
->setFromDate(date($couponValidFromDate))
|
351 |
->setToDate($couponValidToDate->format('Y-m-d H:i:s'))
|
352 |
->setCustomerGroupIds($this->getCustomerGroups())
|
353 |
->setIsActive(1)
|
354 |
+
->setSimpleAction($this->getCouponAction())
|
355 |
+
->setDiscountAmount($this->getCouponValue($quoteValue))
|
|
|
|
|
|
|
|
|
356 |
->setStopRulesProcessing($this->getStopRulesProcessing())
|
357 |
->setUseAutoGeneration(0)
|
358 |
->setIsRss(1)
|
371 |
} else {
|
372 |
$model
|
373 |
->setName($coupon)
|
374 |
+
->setDescription($this->getCouponDescription() . $this->getCouponAction() . $customer->getCustomerId())
|
375 |
->setFromDate(date($couponValidFromDate))
|
376 |
->setCouponCode($coupon)
|
377 |
->setToDate($couponValidToDate->format('Y-m-d H:i:s'))
|
378 |
->setCustomerGroupIds($this->getCustomerGroups())
|
379 |
->setIsActive(1)
|
380 |
+
->setSimpleAction($this->getCouponAction())
|
381 |
+
->setUseAutoGeneration(0)
|
382 |
->setWebsiteIds($this->getAllWebsites())
|
383 |
+
->setDiscountAmount($this->getCouponValue($quoteValue))
|
384 |
->setStopRulesProcessing($this->getStopRulesProcessing())
|
385 |
->setIsRss(1)
|
386 |
->setUsesPerCoupon($this->getMaxCouponUsage())
|
524 |
{
|
525 |
Mage::getModel('core/config')->saveConfig(self::RECKLESS_CORE_LAST_QUOTE, $id);
|
526 |
}
|
527 |
+
|
528 |
+
public function getCustomerPromoMessageYES()
|
529 |
+
{
|
530 |
+
return Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE_YES);
|
531 |
+
}
|
532 |
+
|
533 |
+
public function getCustomerPromoMessageNO()
|
534 |
+
{
|
535 |
+
return Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE_NO);
|
536 |
}
|
537 |
}
|
app/code/local/Reckless/Prediction/Model/Promotion/Observer.php
CHANGED
@@ -21,13 +21,19 @@ class Reckless_Prediction_Model_Promotion_Observer
|
|
21 |
->getCollection()
|
22 |
->addFieldToFilter('session_id', session_id());
|
23 |
foreach ($collection as $discount) {
|
24 |
-
|
25 |
-
Mage::
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
Mage::getSingleton('core/session')->setPromotionShowed(true);
|
28 |
}
|
29 |
-
$this->log("**********Observer Called for event : checkout_cart_add_product_complete");
|
30 |
}
|
|
|
31 |
return $this;
|
32 |
}
|
33 |
|
21 |
->getCollection()
|
22 |
->addFieldToFilter('session_id', session_id());
|
23 |
foreach ($collection as $discount) {
|
24 |
+
if (strcasecmp($discount->getCheckoutIntent(),'Y') == 0) {
|
25 |
+
Mage::getSingleton('core/session')->addNotice(
|
26 |
+
Mage::helper('reckless_prediction')->getCustomerPromoMessageYES() . ' ' . $discount->getCouponCode()
|
27 |
+
);
|
28 |
+
} else {
|
29 |
+
Mage::getSingleton('core/session')->addNotice(
|
30 |
+
Mage::helper('reckless_prediction')->getCustomerPromoMessageNO() . ' ' . $discount->getCouponCode()
|
31 |
+
);
|
32 |
+
}
|
33 |
Mage::getSingleton('core/session')->setPromotionShowed(true);
|
34 |
}
|
|
|
35 |
}
|
36 |
+
|
37 |
return $this;
|
38 |
}
|
39 |
|
app/code/local/Reckless/Prediction/Model/Promotions.php
CHANGED
@@ -13,7 +13,7 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
13 |
public static $errorLogFile = "";
|
14 |
public static $emailMessage = "";
|
15 |
|
16 |
-
const RECKLESS_SERVER_URL = 'http://
|
17 |
const TEMP_TRAINING_CSV_FILENAME = "reckless-training-set-v1.csv";
|
18 |
const MAX_NUM_ITEMS = 1000;
|
19 |
|
@@ -97,8 +97,6 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
97 |
// Delta to filter the collection
|
98 |
$lastProcessed = Mage::helper('reckless_prediction')->getLastProcessedQuoteId();
|
99 |
$quote_collection->addFieldToFilter('entity_id', array('gt' => $lastProcessed));
|
100 |
-
// Avoid processing too
|
101 |
-
$quote_collection->addFieldToFilter('entity_id', array('gt' => $lastProcessed));
|
102 |
}
|
103 |
|
104 |
$quote_collection->getSelect()->limit(self::MAX_NUM_ITEMS);
|
@@ -111,7 +109,9 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
111 |
$quote->getBaseSubtotal() - $quote->getBaseSubtotalWithDiscount(),
|
112 |
$quote->getBaseGrandTotal(),
|
113 |
$quote->getItemsQty(),
|
114 |
-
$quote->getCustomerIsGuest()
|
|
|
|
|
115 |
);
|
116 |
if ($id) {
|
117 |
$data[sizeof($data) - 1][] = $quote->getEntityId();
|
@@ -121,6 +121,7 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
121 |
if (isset($lastProcessed) && isset($quote)) {
|
122 |
Mage::helper('reckless_prediction')->setLastProcessedQuoteId($quote->getEntityId());
|
123 |
}
|
|
|
124 |
return $data;
|
125 |
}
|
126 |
|
@@ -146,13 +147,16 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
146 |
$order->getBaseDiscountInvoiced(),
|
147 |
$order->getBaseGrandTotal(),
|
148 |
$order->getTotalQtyOrdered(),
|
149 |
-
$order->getCustomerIsGuest()
|
|
|
|
|
150 |
);
|
151 |
}
|
152 |
// Update delta
|
153 |
if (isset($order)) {
|
154 |
Mage::helper('reckless_prediction')->setLastProcessedOrderId($order->getEntityId());
|
155 |
}
|
|
|
156 |
return $data;
|
157 |
}
|
158 |
|
@@ -235,6 +239,7 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
235 |
->prepare()
|
236 |
->getCollection();
|
237 |
$onlineCustomersCollection->getSelect()->joinLeft(array('log_quote'=> 'log_quote'), 'log_quote.visitor_id = main_table.visitor_id', array('log_quote.quote_id'));
|
|
|
238 |
return $onlineCustomersCollection;
|
239 |
}
|
240 |
|
@@ -271,13 +276,14 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
271 |
|
272 |
}
|
273 |
|
274 |
-
private function createCouponCode($discount_percent, $store, $customer)
|
275 |
{
|
276 |
-
$couponCode = Mage::helper('reckless_prediction')->createCouponCode($discount_percent, null, $customer);
|
|
|
277 |
return $couponCode;
|
278 |
}
|
279 |
|
280 |
-
private function updatePredictionModel($customer, $checkoutIntent, $quoteId, $predictedDiscountPercent)
|
281 |
{
|
282 |
//Check if a record exist for the customer
|
283 |
//If yes, Update the record
|
@@ -286,6 +292,24 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
286 |
->getCollection()
|
287 |
->addFieldToFilter('quote_id', $quoteId);
|
288 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
//If no record
|
290 |
if ($collections->count() < 1) {
|
291 |
$this->log("NEW RECORD : Visitor With ID: " . $customer->getVisitorId() . " will be created");
|
@@ -296,7 +320,12 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
296 |
->setSessionId($this->getSessionID($customer->getVisitorId()))
|
297 |
->setCheckoutIntent($checkoutIntent)
|
298 |
->setDiscountPercent($predictedDiscountPercent)
|
299 |
-
->setCouponCode($this->createCouponCode($predictedDiscountPercent, null, $customer))
|
|
|
|
|
|
|
|
|
|
|
300 |
->save();
|
301 |
|
302 |
} else {
|
@@ -305,11 +334,15 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
305 |
foreach ($collections as $promo) {
|
306 |
$promo->setVisitorId($customer->getVisitorId());
|
307 |
$promo->setCheckoutIntent($checkoutIntent);
|
|
|
|
|
|
|
|
|
308 |
if ($predictedDiscountPercent != $promo->getDiscountPercent()) {
|
309 |
//delete old code
|
310 |
//create a new code
|
311 |
Mage::helper('reckless_prediction')->deleteCouponCode($promo->getCouponCode());
|
312 |
-
$promo->setCouponCode($this->createCouponCode($predictedDiscountPercent, null, $customer));
|
313 |
}
|
314 |
|
315 |
$promo->save();
|
@@ -323,16 +356,21 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
323 |
//Process all Quotes and predict a checkout intent
|
324 |
foreach ($customerQuotes as $customerQuote) {
|
325 |
try {
|
|
|
326 |
$quoteId = $customerQuote[sizeOf($customerQuote) -1];
|
327 |
unset($customerQuote[sizeOf($customerQuote) -1]);
|
|
|
|
|
|
|
328 |
//Step 2: Predict Y/N checkout
|
329 |
$checkoutIntent = $this->getCheckoutIntent($customerQuote);
|
330 |
//Step 3: Record prediction in DB
|
331 |
-
$this->updatePredictionModel($customer, $checkoutIntent, $quoteId, Mage::helper('reckless_prediction')->getCouponDiscountPercent());
|
332 |
$this->log("Customer: " . $customerCtr . ", Quote " . $quoteId . ", Visitor ID : " . $customer->getVisitorId() . ", CustomerId: " . $customer->getCustomerId() . ", Session ID: " . $sessionId . ", Checkout Intent: " . $checkoutIntent);
|
333 |
|
334 |
} catch (Exception $e) {
|
335 |
$this->sendAlertEmail("Error: Reckless Data Predicting", $e->getTraceAsString());
|
|
|
336 |
}
|
337 |
}
|
338 |
}
|
@@ -354,7 +392,7 @@ class Reckless_Prediction_Model_Promotions extends Mage_Core_Model_Abstract
|
|
354 |
if ($customer->getQuoteId()) {
|
355 |
$this->log($customer->getQuoteId());
|
356 |
$customerQuotes = $this->getUnsuccessfulCheckouts($customer->getQuoteId());
|
357 |
-
}
|
358 |
// Attempt to fetch the quote for the logged customer
|
359 |
$customerQuotes = $this->getUnsuccessfulCheckouts($customer->getCustomerId(), 'customer_id');
|
360 |
}
|
13 |
public static $errorLogFile = "";
|
14 |
public static $emailMessage = "";
|
15 |
|
16 |
+
const RECKLESS_SERVER_URL = 'http://app.reckless.io/machinelearning/%s/%s/%s/';
|
17 |
const TEMP_TRAINING_CSV_FILENAME = "reckless-training-set-v1.csv";
|
18 |
const MAX_NUM_ITEMS = 1000;
|
19 |
|
97 |
// Delta to filter the collection
|
98 |
$lastProcessed = Mage::helper('reckless_prediction')->getLastProcessedQuoteId();
|
99 |
$quote_collection->addFieldToFilter('entity_id', array('gt' => $lastProcessed));
|
|
|
|
|
100 |
}
|
101 |
|
102 |
$quote_collection->getSelect()->limit(self::MAX_NUM_ITEMS);
|
109 |
$quote->getBaseSubtotal() - $quote->getBaseSubtotalWithDiscount(),
|
110 |
$quote->getBaseGrandTotal(),
|
111 |
$quote->getItemsQty(),
|
112 |
+
$quote->getCustomerIsGuest(),
|
113 |
+
$quote->getBaseCurrencyCode(),
|
114 |
+
$quote->getGlobalCurrencyCode()
|
115 |
);
|
116 |
if ($id) {
|
117 |
$data[sizeof($data) - 1][] = $quote->getEntityId();
|
121 |
if (isset($lastProcessed) && isset($quote)) {
|
122 |
Mage::helper('reckless_prediction')->setLastProcessedQuoteId($quote->getEntityId());
|
123 |
}
|
124 |
+
|
125 |
return $data;
|
126 |
}
|
127 |
|
147 |
$order->getBaseDiscountInvoiced(),
|
148 |
$order->getBaseGrandTotal(),
|
149 |
$order->getTotalQtyOrdered(),
|
150 |
+
$order->getCustomerIsGuest(),
|
151 |
+
$order->getBaseCurrencyCode(),
|
152 |
+
$order->getGlobalCurrencyCode()
|
153 |
);
|
154 |
}
|
155 |
// Update delta
|
156 |
if (isset($order)) {
|
157 |
Mage::helper('reckless_prediction')->setLastProcessedOrderId($order->getEntityId());
|
158 |
}
|
159 |
+
|
160 |
return $data;
|
161 |
}
|
162 |
|
239 |
->prepare()
|
240 |
->getCollection();
|
241 |
$onlineCustomersCollection->getSelect()->joinLeft(array('log_quote'=> 'log_quote'), 'log_quote.visitor_id = main_table.visitor_id', array('log_quote.quote_id'));
|
242 |
+
|
243 |
return $onlineCustomersCollection;
|
244 |
}
|
245 |
|
276 |
|
277 |
}
|
278 |
|
279 |
+
private function createCouponCode($discount_percent, $store, $customer, $quoteValue)
|
280 |
{
|
281 |
+
$couponCode = Mage::helper('reckless_prediction')->createCouponCode($discount_percent, null, $customer, $quoteValue);
|
282 |
+
|
283 |
return $couponCode;
|
284 |
}
|
285 |
|
286 |
+
private function updatePredictionModel($customer, $checkoutIntent, $quoteId, $predictedDiscountPercent, $quoteValue)
|
287 |
{
|
288 |
//Check if a record exist for the customer
|
289 |
//If yes, Update the record
|
292 |
->getCollection()
|
293 |
->addFieldToFilter('quote_id', $quoteId);
|
294 |
|
295 |
+
//Get the AOV and LTV and TotalSales for the customer
|
296 |
+
//Refactor to Magento Models later
|
297 |
+
$aov_global_currency = 0;
|
298 |
+
$ltv_global_currency = 0;
|
299 |
+
$total_orders = 0;
|
300 |
+
|
301 |
+
if ($customer->getCustomerId() != NULL) {
|
302 |
+
$readConnection = Mage::getSingleton('core/resource')->getConnection('core_read');
|
303 |
+
$query = 'select customer_id, base_grand_total*base_to_global_rate as ltv_global , (base_grand_total*base_to_global_rate)/count(customer_id) as aov_global, count(customer_id) as total_orders from sales_flat_order where customer_id=' . $customer->getCustomerId();
|
304 |
+
$results = $readConnection->fetchAll($query);
|
305 |
+
$aov_global_currency=$results[0]['aov_global'];
|
306 |
+
$ltv_global_currency=$results[0]['ltv_global'];
|
307 |
+
$total_orders=$results[0]['total_orders'];
|
308 |
+
}
|
309 |
+
|
310 |
+
|
311 |
+
$currentTimestamp = Mage::getModel('core/date')->timestamp(time());;
|
312 |
+
|
313 |
//If no record
|
314 |
if ($collections->count() < 1) {
|
315 |
$this->log("NEW RECORD : Visitor With ID: " . $customer->getVisitorId() . " will be created");
|
320 |
->setSessionId($this->getSessionID($customer->getVisitorId()))
|
321 |
->setCheckoutIntent($checkoutIntent)
|
322 |
->setDiscountPercent($predictedDiscountPercent)
|
323 |
+
->setCouponCode($this->createCouponCode($predictedDiscountPercent, null, $customer, $quoteValue))
|
324 |
+
->setAovGlobal($aov_global_currency)
|
325 |
+
->setLtvGlobal($ltv_global_currency)
|
326 |
+
->setTotalOrders($total_orders)
|
327 |
+
->setCreatedAt($currentTimestamp)
|
328 |
+
->setUpdatedAt($currentTimestamp)
|
329 |
->save();
|
330 |
|
331 |
} else {
|
334 |
foreach ($collections as $promo) {
|
335 |
$promo->setVisitorId($customer->getVisitorId());
|
336 |
$promo->setCheckoutIntent($checkoutIntent);
|
337 |
+
$promo->setAovGlobal($aov_global_currency);
|
338 |
+
$promo->setLtvGlobal($ltv_global_currency);
|
339 |
+
$promo->setTotalOrders($total_orders);
|
340 |
+
$promo->setUpdatedAt($currentTimestamp);
|
341 |
if ($predictedDiscountPercent != $promo->getDiscountPercent()) {
|
342 |
//delete old code
|
343 |
//create a new code
|
344 |
Mage::helper('reckless_prediction')->deleteCouponCode($promo->getCouponCode());
|
345 |
+
$promo->setCouponCode($this->createCouponCode($predictedDiscountPercent, null, $customer, $quoteValue));
|
346 |
}
|
347 |
|
348 |
$promo->save();
|
356 |
//Process all Quotes and predict a checkout intent
|
357 |
foreach ($customerQuotes as $customerQuote) {
|
358 |
try {
|
359 |
+
|
360 |
$quoteId = $customerQuote[sizeOf($customerQuote) -1];
|
361 |
unset($customerQuote[sizeOf($customerQuote) -1]);
|
362 |
+
|
363 |
+
$quoteValue = $customerQuote[sizeOf($customerQuote) - 5];
|
364 |
+
|
365 |
//Step 2: Predict Y/N checkout
|
366 |
$checkoutIntent = $this->getCheckoutIntent($customerQuote);
|
367 |
//Step 3: Record prediction in DB
|
368 |
+
$this->updatePredictionModel($customer, $checkoutIntent, $quoteId, Mage::helper('reckless_prediction')->getCouponDiscountPercent() , $quoteValue);
|
369 |
$this->log("Customer: " . $customerCtr . ", Quote " . $quoteId . ", Visitor ID : " . $customer->getVisitorId() . ", CustomerId: " . $customer->getCustomerId() . ", Session ID: " . $sessionId . ", Checkout Intent: " . $checkoutIntent);
|
370 |
|
371 |
} catch (Exception $e) {
|
372 |
$this->sendAlertEmail("Error: Reckless Data Predicting", $e->getTraceAsString());
|
373 |
+
Mage::logException($e);
|
374 |
}
|
375 |
}
|
376 |
}
|
392 |
if ($customer->getQuoteId()) {
|
393 |
$this->log($customer->getQuoteId());
|
394 |
$customerQuotes = $this->getUnsuccessfulCheckouts($customer->getQuoteId());
|
395 |
+
} elseif ($customer->getCustomerId()) {
|
396 |
// Attempt to fetch the quote for the logged customer
|
397 |
$customerQuotes = $this->getUnsuccessfulCheckouts($customer->getCustomerId(), 'customer_id');
|
398 |
}
|
app/code/local/Reckless/Prediction/Model/Resource/Promotions.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Model/Resource/Promotions/Collection.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/Model/Resource/Setup.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/controllers/Adminhtml/PredictionController.php
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/data/reckless_prediction_setup/data-install-0.1.0.php
CHANGED
@@ -6,7 +6,7 @@ $domain = parse_url($baseurl, PHP_URL_HOST);
|
|
6 |
$apikey = md5($domain);
|
7 |
|
8 |
//Mage::log("\n BaseURL: " . $baseurl . ". Domain: " . $domain . " Hash: " . md5($domain));
|
9 |
-
$curl_url = "http://
|
10 |
. $domain
|
11 |
. "/"
|
12 |
. $apikey
|
6 |
$apikey = md5($domain);
|
7 |
|
8 |
//Mage::log("\n BaseURL: " . $baseurl . ". Domain: " . $domain . " Hash: " . md5($domain));
|
9 |
+
$curl_url = "http://app.reckless.io/machinelearning/create/"
|
10 |
. $domain
|
11 |
. "/"
|
12 |
. $apikey
|
app/code/local/Reckless/Prediction/etc/adminhtml.xml
CHANGED
File without changes
|
app/code/local/Reckless/Prediction/etc/config.xml
CHANGED
@@ -2,35 +2,35 @@
|
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Reckless_Prediction>
|
5 |
-
<version>0.1.
|
6 |
</Reckless_Prediction>
|
7 |
</modules>
|
8 |
<global>
|
9 |
-
|
10 |
-
|
11 |
<class>Reckless_Prediction_Model</class>
|
12 |
<resourceModel>prediction_resource</resourceModel>
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
<reckless_prediction>
|
35 |
<class>Reckless_Prediction_Helper</class>
|
36 |
</reckless_prediction>
|
@@ -42,35 +42,35 @@
|
|
42 |
<class>Reckless_Prediction_Model_Resource_Setup</class>
|
43 |
</setup>
|
44 |
</reckless_prediction_setup>
|
45 |
-
|
46 |
<connection>
|
47 |
<use>core_write</use>
|
48 |
</connection>
|
49 |
</reckless_prediction_write>
|
50 |
-
|
51 |
-
|
52 |
<use>core_read</use>
|
53 |
</connection>
|
54 |
</reckless_prediction_read>
|
55 |
</resources>
|
56 |
<events>
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
|
68 |
</global>
|
69 |
<default>
|
70 |
<reckless_prediction>
|
71 |
<reckless_prediction_section>
|
72 |
<reckless_prediction_enable>0</reckless_prediction_enable>
|
73 |
-
<reckless_prediction_sync_customer_email>
|
74 |
<reckless_prediction_notificationemail>hello@reckless.io</reckless_prediction_notificationemail>
|
75 |
<reckless_prediction_enablelog>1</reckless_prediction_enablelog>
|
76 |
<reckless_prediction_logfilename>reckless_prediction.log</reckless_prediction_logfilename>
|
@@ -78,15 +78,18 @@
|
|
78 |
<reckless_promotions_section>
|
79 |
<reckless_dynamic_promotion_enable>0</reckless_dynamic_promotion_enable>
|
80 |
<reckless_prediction_promotion_threshould>10</reckless_prediction_promotion_threshould> <!-- Value in Base Currency Of the Store -->
|
81 |
-
<reckless_prediction_promocodevalid_time>
|
|
|
82 |
<reckless_prediction_promocode_stoprulesprocessing>0</reckless_prediction_promocode_stoprulesprocessing>
|
83 |
<reckless_prediction_promocode_type>2</reckless_prediction_promocode_type>
|
84 |
<reckless_prediction_promocode_usagepercustomer>1</reckless_prediction_promocode_usagepercustomer>
|
85 |
<reckless_prediction_promocode_usage>1</reckless_prediction_promocode_usage>
|
86 |
<reckless_prediction_promocode_prefix>PRSL</reckless_prediction_promocode_prefix>
|
87 |
<reckless_prediction_promocode_desc>Personalised Promo Code for customer </reckless_prediction_promocode_desc>
|
|
|
88 |
<reckless_prediction_promocode_percent>5</reckless_prediction_promocode_percent>
|
89 |
-
<
|
|
|
90 |
</reckless_promotions_section>
|
91 |
</reckless_prediction>
|
92 |
</default>
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Reckless_Prediction>
|
5 |
+
<version>0.1.1</version>
|
6 |
</Reckless_Prediction>
|
7 |
</modules>
|
8 |
<global>
|
9 |
+
<models>
|
10 |
+
<prediction>
|
11 |
<class>Reckless_Prediction_Model</class>
|
12 |
<resourceModel>prediction_resource</resourceModel>
|
13 |
+
</prediction>
|
14 |
+
<prediction_resource>
|
15 |
+
<class>Reckless_Prediction_Model_Resource</class>
|
16 |
+
<entities>
|
17 |
+
<promotions>
|
18 |
+
<table>reckless_promotions</table>
|
19 |
+
</promotions>
|
20 |
+
</entities>
|
21 |
+
</prediction_resource>
|
22 |
+
</models>
|
23 |
+
<blocks>
|
24 |
+
<adminhtml>
|
25 |
+
<rewrite>
|
26 |
+
<customer_online_grid>Reckless_Prediction_Block_Adminhtml_Customer_Online_Grid</customer_online_grid>
|
27 |
+
</rewrite>
|
28 |
+
</adminhtml>
|
29 |
+
<reckless_prediction>
|
30 |
+
<class>Reckless_Prediction_Block</class>
|
31 |
+
</reckless_prediction>
|
32 |
+
</blocks>
|
33 |
+
<helpers>
|
34 |
<reckless_prediction>
|
35 |
<class>Reckless_Prediction_Helper</class>
|
36 |
</reckless_prediction>
|
42 |
<class>Reckless_Prediction_Model_Resource_Setup</class>
|
43 |
</setup>
|
44 |
</reckless_prediction_setup>
|
45 |
+
<reckless_prediction_write>
|
46 |
<connection>
|
47 |
<use>core_write</use>
|
48 |
</connection>
|
49 |
</reckless_prediction_write>
|
50 |
+
<reckless_prediction_read>
|
51 |
+
<connection>
|
52 |
<use>core_read</use>
|
53 |
</connection>
|
54 |
</reckless_prediction_read>
|
55 |
</resources>
|
56 |
<events>
|
57 |
+
<checkout_cart_add_product_complete>
|
58 |
+
<observers>
|
59 |
+
<reckless_prediction_promotion_observer>
|
60 |
+
<type>singleton</type>
|
61 |
+
<class>Reckless_Prediction_Model_Promotion_Observer</class>
|
62 |
+
<method>show_predicted_coupon_code</method>
|
63 |
+
</reckless_prediction_promotion_observer>
|
64 |
+
</observers>
|
65 |
+
</checkout_cart_add_product_complete>
|
66 |
+
</events>
|
67 |
|
68 |
</global>
|
69 |
<default>
|
70 |
<reckless_prediction>
|
71 |
<reckless_prediction_section>
|
72 |
<reckless_prediction_enable>0</reckless_prediction_enable>
|
73 |
+
<reckless_prediction_sync_customer_email>0</reckless_prediction_sync_customer_email>
|
74 |
<reckless_prediction_notificationemail>hello@reckless.io</reckless_prediction_notificationemail>
|
75 |
<reckless_prediction_enablelog>1</reckless_prediction_enablelog>
|
76 |
<reckless_prediction_logfilename>reckless_prediction.log</reckless_prediction_logfilename>
|
78 |
<reckless_promotions_section>
|
79 |
<reckless_dynamic_promotion_enable>0</reckless_dynamic_promotion_enable>
|
80 |
<reckless_prediction_promotion_threshould>10</reckless_prediction_promotion_threshould> <!-- Value in Base Currency Of the Store -->
|
81 |
+
<reckless_prediction_promocodevalid_time>60</reckless_prediction_promocodevalid_time> <!-- In Days, Default: 60 Days -->
|
82 |
+
<reckless_prediction_promocodevalid_starts_from>0</reckless_prediction_promocodevalid_starts_from> <!-- In days, Defaule : 0 which is The same day" -->
|
83 |
<reckless_prediction_promocode_stoprulesprocessing>0</reckless_prediction_promocode_stoprulesprocessing>
|
84 |
<reckless_prediction_promocode_type>2</reckless_prediction_promocode_type>
|
85 |
<reckless_prediction_promocode_usagepercustomer>1</reckless_prediction_promocode_usagepercustomer>
|
86 |
<reckless_prediction_promocode_usage>1</reckless_prediction_promocode_usage>
|
87 |
<reckless_prediction_promocode_prefix>PRSL</reckless_prediction_promocode_prefix>
|
88 |
<reckless_prediction_promocode_desc>Personalised Promo Code for customer </reckless_prediction_promocode_desc>
|
89 |
+
<reckless_dynamic_promotion_discount_type>0</reckless_dynamic_promotion_discount_type>
|
90 |
<reckless_prediction_promocode_percent>5</reckless_prediction_promocode_percent>
|
91 |
+
<reckless_prediction_customer_promo_message_yes>Thank you for choosing us. As a token of appreciation, we would like to offer you 5% off next time. Please use code:</reckless_prediction_customer_promo_message_yes>
|
92 |
+
<reckless_prediction_customer_promo_message_no>Thank you for choosing us. As a token of appreciation, we would like to offer you 5% off next time. Please use code:</reckless_prediction_customer_promo_message_no>
|
93 |
</reckless_promotions_section>
|
94 |
</reckless_prediction>
|
95 |
</default>
|
app/code/local/Reckless/Prediction/etc/system.xml
CHANGED
@@ -50,7 +50,7 @@
|
|
50 |
<label>Enable Customer Email Sync</label>
|
51 |
<frontend_type>select</frontend_type>
|
52 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
53 |
-
<comment><![CDATA[If enabled, Customer emails will be used for analysis. If disabled, only customer id will be used. Default:
|
54 |
<sort_order>40</sort_order>
|
55 |
<show_in_default>1</show_in_default>
|
56 |
</reckless_prediction_sync_customer_email>
|
@@ -101,6 +101,13 @@
|
|
101 |
<comment><![CDATA[*** DO NOT USE. Feature not enabled in this version. Maximum promotions budget for Reckless to Giveaway in a 24 hour period. Default: 10 GBP]]></comment>
|
102 |
<show_in_default>1</show_in_default>
|
103 |
</reckless_prediction_promotion_threshould>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
<reckless_prediction_promocodevalid_time>
|
105 |
<label>Promotion Code Validity (days)</label>
|
106 |
<frontend_type>text</frontend_type>
|
@@ -108,11 +115,19 @@
|
|
108 |
<comment><![CDATA[The time limit for the dynamically generated promocode from Created Date.Default: 60 Days]]></comment>
|
109 |
<show_in_default>1</show_in_default>
|
110 |
</reckless_prediction_promocodevalid_time>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
<reckless_prediction_promocode_percent>
|
112 |
<label>Percentage Discount</label>
|
113 |
<frontend_type>text</frontend_type>
|
114 |
<sort_order>40</sort_order>
|
115 |
-
<comment><![CDATA[Discount Percentage for Promo Code.Default: 5%]]></comment>
|
116 |
<show_in_default>1</show_in_default>
|
117 |
</reckless_prediction_promocode_percent>
|
118 |
<reckless_prediction_promocode_desc>
|
@@ -159,13 +174,20 @@
|
|
159 |
<comment><![CDATA[Stop Further Rules from Processing.Default: Disabled]]></comment>
|
160 |
<show_in_default>1</show_in_default>
|
161 |
</reckless_prediction_promocode_stoprulesprocessing>
|
162 |
-
<
|
163 |
-
|
164 |
<frontend_type>textarea</frontend_type>
|
165 |
-
<sort_order>
|
166 |
-
<comment><![CDATA[Message that will be displayed to the customer in the view cart page. The coupon code will always be the last word in the sentence. Default: Thank you for choosing us. As a token of appreciation, we would like to offer you 5% off next time. Please use code: {Coupon Code}]]></comment>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
<show_in_default>1</show_in_default>
|
168 |
-
</
|
169 |
</fields>
|
170 |
</reckless_promotions_section>
|
171 |
</groups>
|
50 |
<label>Enable Customer Email Sync</label>
|
51 |
<frontend_type>select</frontend_type>
|
52 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
53 |
+
<comment><![CDATA[*** For this version, ONLY Customer ID will be used. If enabled, Customer emails will be used for analysis. If disabled, only customer id will be used. Default: Disabled]]></comment>
|
54 |
<sort_order>40</sort_order>
|
55 |
<show_in_default>1</show_in_default>
|
56 |
</reckless_prediction_sync_customer_email>
|
101 |
<comment><![CDATA[*** DO NOT USE. Feature not enabled in this version. Maximum promotions budget for Reckless to Giveaway in a 24 hour period. Default: 10 GBP]]></comment>
|
102 |
<show_in_default>1</show_in_default>
|
103 |
</reckless_prediction_promotion_threshould>
|
104 |
+
<reckless_prediction_promocodevalid_starts_from>
|
105 |
+
<label>Promotion Code Validity Starts in (days)</label>
|
106 |
+
<frontend_type>text</frontend_type>
|
107 |
+
<sort_order>30</sort_order>
|
108 |
+
<comment><![CDATA[When should the promotion code be valid from. Default: 0 (days) which is immediately]]></comment>
|
109 |
+
<show_in_default>1</show_in_default>
|
110 |
+
</reckless_prediction_promocodevalid_starts_from>
|
111 |
<reckless_prediction_promocodevalid_time>
|
112 |
<label>Promotion Code Validity (days)</label>
|
113 |
<frontend_type>text</frontend_type>
|
115 |
<comment><![CDATA[The time limit for the dynamically generated promocode from Created Date.Default: 60 Days]]></comment>
|
116 |
<show_in_default>1</show_in_default>
|
117 |
</reckless_prediction_promocodevalid_time>
|
118 |
+
<reckless_dynamic_promotion_discount_type>
|
119 |
+
<label>Coupon Discount is Percentage of Current Cart</label>
|
120 |
+
<frontend_type>select</frontend_type>
|
121 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
122 |
+
<comment><![CDATA[If enabled, Coupon Value will be a percentage of current cart value. If disabled, coupon code will offer a percentage off in the next cart. Default: Disabled]]></comment>
|
123 |
+
<sort_order>35</sort_order>
|
124 |
+
<show_in_default>1</show_in_default>
|
125 |
+
</reckless_dynamic_promotion_discount_type>
|
126 |
<reckless_prediction_promocode_percent>
|
127 |
<label>Percentage Discount</label>
|
128 |
<frontend_type>text</frontend_type>
|
129 |
<sort_order>40</sort_order>
|
130 |
+
<comment><![CDATA[Discount Percentage for Promo Code; either on current cart value for future checkout OR percentage off in the next checkout. This is driven by the above configuration. Default: 5%]]></comment>
|
131 |
<show_in_default>1</show_in_default>
|
132 |
</reckless_prediction_promocode_percent>
|
133 |
<reckless_prediction_promocode_desc>
|
174 |
<comment><![CDATA[Stop Further Rules from Processing.Default: Disabled]]></comment>
|
175 |
<show_in_default>1</show_in_default>
|
176 |
</reckless_prediction_promocode_stoprulesprocessing>
|
177 |
+
<reckless_prediction_customer_promo_message_yes>
|
178 |
+
<label>Message for Predicted Checkout: YES</label>
|
179 |
<frontend_type>textarea</frontend_type>
|
180 |
+
<sort_order>110</sort_order>
|
181 |
+
<comment><![CDATA[Message that will be displayed to the customer in the view cart page if the predicted checkot intent is YES. The coupon code will always be the last word in the sentence. Default: Thank you for choosing us. As a token of appreciation, we would like to offer you 5% off next time. Please use code: {Coupon Code}]]></comment>
|
182 |
+
<show_in_default>1</show_in_default>
|
183 |
+
</reckless_prediction_customer_promo_message_yes>
|
184 |
+
<reckless_prediction_customer_promo_message_no>
|
185 |
+
<label>Message for Predicted Checkout: NO</label>
|
186 |
+
<frontend_type>textarea</frontend_type>
|
187 |
+
<sort_order>120</sort_order>
|
188 |
+
<comment><![CDATA[Message that will be displayed to the customer in the view cart page if the predicted checkot intent is NO. The coupon code will always be the last word in the sentence. Default: Thank you for choosing us. As a token of appreciation, we would like to offer you 5% off next time. Please use code: {Coupon Code}]]></comment>
|
189 |
<show_in_default>1</show_in_default>
|
190 |
+
</reckless_prediction_customer_promo_message_no>
|
191 |
</fields>
|
192 |
</reckless_promotions_section>
|
193 |
</groups>
|
app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-install-0.1.0.php
CHANGED
@@ -3,7 +3,6 @@ $installer = $this;
|
|
3 |
|
4 |
$installer->startSetup();
|
5 |
|
6 |
-
|
7 |
$table = $installer->getConnection()
|
8 |
->newTable($installer->getTable('prediction/promotions'))
|
9 |
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
@@ -58,4 +57,4 @@ $table = $installer->getConnection()
|
|
58 |
Varien_Db_Ddl_Table::ACTION_SET_NULL, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
59 |
->setComment('Reckless Promotions Entity');
|
60 |
$installer->getConnection()->createTable($table);
|
61 |
-
$installer->endSetup();
|
3 |
|
4 |
$installer->startSetup();
|
5 |
|
|
|
6 |
$table = $installer->getConnection()
|
7 |
->newTable($installer->getTable('prediction/promotions'))
|
8 |
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
57 |
Varien_Db_Ddl_Table::ACTION_SET_NULL, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
58 |
->setComment('Reckless Promotions Entity');
|
59 |
$installer->getConnection()->createTable($table);
|
60 |
+
$installer->endSetup();
|
app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-upgrade-0.1.0-0.1.1.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$installer = $this;
|
3 |
+
|
4 |
+
$installer->startSetup();
|
5 |
+
|
6 |
+
$installer->run("
|
7 |
+
ALTER TABLE {$this->getTable('prediction/promotions')}
|
8 |
+
ADD COLUMN(
|
9 |
+
`aov_global` decimal(12,4) DEFAULT NULL COMMENT 'Average Order Value',
|
10 |
+
`ltv_global` decimal(12,4) DEFAULT NULL COMMENT 'Life time Value',
|
11 |
+
`total_orders` smallint(5) unsigned DEFAULT '0' COMMENT 'Total orders')
|
12 |
+
;
|
13 |
+
");
|
14 |
+
|
15 |
+
$installer->endSetup();
|
app/etc/modules/Reckless_Prediction.xml
CHANGED
File without changes
|
package.xml
CHANGED
@@ -1,24 +1,79 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Recklessio_Prediction</name>
|
4 |
-
<version>1.0
|
5 |
<stability>stable</stability>
|
6 |
<license>GNU General Public License (GPL)</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
-
<summary>
|
10 |
-
<description>
|
11 |
-

|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
<authors><author><name>Reckless</name><user>recklessio</user><email>hello@reckless.io</email></author></authors>
|
19 |
-
<date>2014-
|
20 |
-
<time>
|
21 |
-
<contents><target name="magelocal"><dir name="Reckless"><dir name="Prediction"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Online"><file name="Grid.php" hash="6be15ebd43a6f04c56c77735429d618d"/></dir></dir><file name="Grid.php" hash="594b39a6b04566f12b520ea4188938d2"/><dir name="Predictions"><file name="Grid.php" hash="
|
22 |
<compatible/>
|
23 |
-
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>
|
24 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Recklessio_Prediction</name>
|
4 |
+
<version>1.1.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license>GNU General Public License (GPL)</license>
|
7 |
<channel>community</channel>
|
8 |
<extends/>
|
9 |
+
<summary>Use machine learning to predict if a customer will checkout and take an action before the cart abandonment.</summary>
|
10 |
+
<description>Reckless - Realtime Cart Abandonment Detection and Prevention
|
11 |
+

|
12 |
+
About Reckless Data
|
13 |
+

|
14 |
+
We are building accessible decision support tools; to empower retailers with tools like those of Amazon.
|
15 |
+

|
16 |
+
Reckless Prediction
|
17 |
+

|
18 |
+
This Magento extension learns from your historic Magento operational data and predicts whether a given online customer or guest will checkout or not.
|
19 |
+
The system analyses user behaviour in realtime and predicts the checkout intention of the user.
|
20 |
+

|
21 |
+
Depending on the predicted checkout intent (Y/N), a personalised coupon code can be generated to either convert the leaving customer and prevent a cart abandonment; or increase the cart vale of the engaged customer. We also use external variables like holidays, weather etc. in our machine learning models.
|
22 |
+

|
23 |
+
By default, coupon codes are generated every 5 minutes for online customers and the coupon code gets displayed to the customer when he/she adds another item to their cart.
|
24 |
+

|
25 |
+
Why use Reckless Prediction ?
|
26 |
+

|
27 |
+
a) Increase Average Order Value: If the predicted checkout intent is a “YES” and the AOV for this customer is higher that the current quote, you can offer targeted promotion to increase the Cart value.
|
28 |
+

|
29 |
+
b) Increase conversion & reduce abandoned cart : If the predicted checkout intent is a “NO”, you can entice the customer to checkout by giving a time limited coupon code or free shipping.
|
30 |
+

|
31 |
+
c) Increase Lifetime value: If the predicted checkout intent is a “YES”, you can offer a coupon code, valid from another date and entice him to come back before the coupon expiry date.
|
32 |
+

|
33 |
+
Data Privacy
|
34 |
+

|
35 |
+
- Customer email is never used unless specified in the extension configuration
|
36 |
+
- Customer ID is the only information used for a customer. No name, address, billing or any other information is processed by Reckless.
|
37 |
+
Features
|
38 |
+

|
39 |
+
- Works for both logged in(registered) and guest customers 
|
40 |
+
- Promotion Budget control with Coupon validity Days and maximum limit 
|
41 |
+
- Customizable messages, coupon code/ discount percent/ and other basic configurations 
|
42 |
+
Reporting
|
43 |
+

|
44 |
+
insi Report 1 : Promotions Report
|
45 |
+
Reports the predicted checkout intent for all the online customers, their quotes and the corresponding coupon code offered to the customer.
|
46 |
+
Access: Magento Admin Panel : Customers > Reckless Promotions
|
47 |
+

|
48 |
+
Report 2: Promotions redemption Report
|
49 |
+
Reports on a day basis, how many times the generated coupons have been redeemed, the total discounted value and the customer status along with the relevant order number.
|
50 |
+
Access: Magento Admin Panel : Reports-> Reckless Redemptions
|
51 |
+

|
52 |
+
**The daily discounted value can be limited.
|
53 |
+
Demo Store
|
54 |
+

|
55 |
+
> Store: http://magento.reckless.io 
|
56 |
+
> Admin Back-end: http://magento.reckless.io/admin (Admin Username: admin Password: password1234)
|
57 |
+
Key Configuration ( Access: Magento Admin Panel : System > Configurations > Reckless Data > Predictions )
|
58 |
+
API Key: Configured by Reckless Servers, Please do not change.
|
59 |
+
Registered Domain: Configured by Reckless Servers, Please do not change.
|
60 |
+
Enable Customer Email Sync : By default this is disabled for data privacy control.
|
61 |
+
Max promotion budget in 24hrs: Max coupon value that you want to give out in 24 hours. (Can be 5% of the customer quote value).
|
62 |
+
Promotion Code Prefix: Prefix for every coupon code created.
|
63 |
+
Message to show to customer: This is a message that will be shown in the cart to the customer.
|
64 |
+
Con Jobs
|
65 |
+

|
66 |
+
1) reckless_prediction_heartbeat: Runs every 5 minutes to update online customers with predicted checkout intents and generates relevant coupon codes.
|
67 |
+
2) reckless_start_training : Runs every 30 minutes to train the prediction model in Reckless.io
|
68 |
+

|
69 |
+
This extension is free to download and use for up-to 1,000,000 rows for the first 6 months. For any queries please email hello@reckless.io and we are more than happy to help you out.</description>
|
70 |
+
<notes>- Fixed minor issues
|
71 |
+
- Enhanced grids
|
72 |
+
- Improved prediction model</notes>
|
73 |
<authors><author><name>Reckless</name><user>recklessio</user><email>hello@reckless.io</email></author></authors>
|
74 |
+
<date>2014-07-12</date>
|
75 |
+
<time>15:29:21</time>
|
76 |
+
<contents><target name="magelocal"><dir name="Reckless"><dir name="Prediction"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Online"><file name="Grid.php" hash="6be15ebd43a6f04c56c77735429d618d"/></dir></dir><file name="Grid.php" hash="594b39a6b04566f12b520ea4188938d2"/><dir name="Predictions"><file name="Grid.php" hash="f416ec3d6556f1198756edf40820eba7"/></dir><file name="Predictions.php" hash="492539cb45eea7c1157dc86b253afa2a"/><dir name="Redemptions"><file name="Grid.php" hash="6a5305885f5b7e95ed18827063fb3f9c"/></dir><file name="Redemptions.php" hash="7e00d2e4b98b819b9662605009b0a23c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="54cdda06c8d3c4899237ed906ed9ada5"/></dir><dir name="Model"><dir name="Promotion"><file name="Observer.php" hash="f13c5196ffbc05ca706df89d4b18b239"/></dir><file name="Promotions.php" hash="ff60c1e2c9268328e95e26d1c5f8fe01"/><dir name="Resource"><dir name="Promotions"><file name="Collection.php" hash="25eb76955e8ebc45196143449394cd11"/></dir><file name="Promotions.php" hash="abb8647d9872b0db04687eac0acb8cc2"/><file name="Setup.php" hash="c711d1e3a93c01fe04dd668203a4fe0e"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="PredictionController.php" hash="fab9e8f6a6038cdb9b6afd67a1a87b4f"/></dir></dir><dir name="data"><dir name="reckless_prediction_setup"><file name="data-install-0.1.0.php" hash="ccbe78831f94afc5758ce62bea43024c"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="190aa60726698e82c99983eb533e119b"/><file name="config.xml" hash="a5b53d4ad8bb8e5a6268c906d8b594c5"/><file name="system.xml" hash="464f8afa7923a9c93a7e0899a067db7b"/></dir><dir name="sql"><dir name="reckless_prediction_setup"><file name="mysql4-install-0.1.0.php" hash="cd8d9a222cf31368a593aa13d35005e9"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="5c32bead580db7ee0cba1b352f18ce7e"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Reckless_Prediction.xml" hash="2b822e3b624ed0437395ee8ee9ab7190"/></dir></target></contents>
|
77 |
<compatible/>
|
78 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>comminuity</channel><min>1.0.0.0</min><max>1.9</max></package></required></dependencies>
|
79 |
</package>
|