Recklessio_Prediction - Version 1.1.0

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

Files changed (21) hide show
  1. app/code/local/Reckless/Prediction/Block/Adminhtml/Customer/Online/Grid.php +0 -0
  2. app/code/local/Reckless/Prediction/Block/Adminhtml/Grid.php +0 -0
  3. app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions.php +0 -0
  4. app/code/local/Reckless/Prediction/Block/Adminhtml/Predictions/Grid.php +32 -0
  5. app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions.php +0 -0
  6. app/code/local/Reckless/Prediction/Block/Adminhtml/Redemptions/Grid.php +16 -47
  7. app/code/local/Reckless/Prediction/Helper/Data.php +75 -23
  8. app/code/local/Reckless/Prediction/Model/Promotion/Observer.php +10 -4
  9. app/code/local/Reckless/Prediction/Model/Promotions.php +50 -12
  10. app/code/local/Reckless/Prediction/Model/Resource/Promotions.php +0 -0
  11. app/code/local/Reckless/Prediction/Model/Resource/Promotions/Collection.php +0 -0
  12. app/code/local/Reckless/Prediction/Model/Resource/Setup.php +0 -0
  13. app/code/local/Reckless/Prediction/controllers/Adminhtml/PredictionController.php +0 -0
  14. app/code/local/Reckless/Prediction/data/reckless_prediction_setup/data-install-0.1.0.php +1 -1
  15. app/code/local/Reckless/Prediction/etc/adminhtml.xml +0 -0
  16. app/code/local/Reckless/Prediction/etc/config.xml +43 -40
  17. app/code/local/Reckless/Prediction/etc/system.xml +29 -7
  18. app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-install-0.1.0.php +1 -2
  19. app/code/local/Reckless/Prediction/sql/reckless_prediction_setup/mysql4-upgrade-0.1.0-0.1.1.php +15 -0
  20. app/etc/modules/Reckless_Prediction.xml +0 -0
  21. 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
- 'index' => 'base_discount_amount',
 
 
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
- $this->addColumn('coupon_uses',
111
- array(
112
- 'header' => 'Uses',
113
- 'align' =>'right',
114
- 'index' => 'coupon_uses',
115
- ));
116
- $this->addColumn('coupon_uses',
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 RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE = 'reckless_prediction/reckless_promotions_section/reckless_prediction_customer_promo_message';
 
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
- public function getCouponPostfix($customer){
271
- if ($customer->getCustomerId() == NULL)
272
- return "G";
273
- return $customer->getCustomerId();
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 = $now->format(DateTime::ISO8601);
 
 
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
- //->setStopRulesProcessing
305
- //->setIsAdvanced
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('by_percent')
335
- ->setUseAutoGeneration(0)
336
  ->setWebsiteIds($this->getAllWebsites())
337
- ->setDiscountAmount(min(100, $this->getCouponDiscountPercent()))
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 getCustomerPromoMessage(){
483
- return Mage::getStoreConfig(self::RECKLESS_PROMOTIONS_CUSTOMER_PROMO_MESSAGE);
 
 
 
 
 
 
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
- Mage::getSingleton('core/session')->addNotice(
25
- Mage::helper('reckless_prediction')->getCustomerPromoMessage() . ' ' . $discount->getCouponCode()
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://javi-awesome-bi.appspot.com/machinelearning/%s/%s/%s/';
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
- } else if ($customer->getCustomerId()) {
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://javi-awesome-bi.appspot.com/machinelearning/create/"
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.0</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,35 +42,35 @@
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>1</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>86400</reckless_prediction_promocodevalid_time> <!-- In Minutes, Default: 60 Days -->
 
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
- <reckless_prediction_customer_promo_message>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>
 
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: Enabled]]></comment>
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
- <reckless_prediction_customer_promo_message>
163
- <label>Message to show to customer</label>
164
  <frontend_type>textarea</frontend_type>
165
- <sort_order>80</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
- </reckless_prediction_customer_promo_message>
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.1</version>
5
  <stability>stable</stability>
6
  <license>GNU General Public License (GPL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>Magento Prediction Machine Learning System</summary>
10
- <description>This Magento extension learns from your historic Magento operational data and predicts whether a given online customer or guest will checkout or not. We use external variables like holidays, weather etc. in our models.&#xD;
11
- &#xD;
12
- Depending on the predicted checkout intent (Y/N), a promo code can be generated to either convert the customer and reduce another abandoned cart or to increase his average order value.&#xD;
13
- </description>
14
- <notes>- First version&#xD;
15
- - Works for both logged in(registered) and guest customers&#xD;
16
- - Promotion Budget control with Coupon validity Days and maximum limit&#xD;
17
- - Customizable messages, coupon code/ discount percent/ and other basic configurations</notes>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  <authors><author><name>Reckless</name><user>recklessio</user><email>hello@reckless.io</email></author></authors>
19
- <date>2014-06-30</date>
20
- <time>18:26:45</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="3aaee4a1b20597f77d4ed697913071f3"/></dir><file name="Predictions.php" hash="492539cb45eea7c1157dc86b253afa2a"/><dir name="Redemptions"><file name="Grid.php" hash="89fe19b650d14f595dd1f7a53484c4b1"/></dir><file name="Redemptions.php" hash="7e00d2e4b98b819b9662605009b0a23c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="f7bc89cf9f9eaa4b336595292dbaba86"/></dir><dir name="Model"><dir name="Promotion"><file name="Observer.php" hash="622782d27dbcc6aa574b768f99714787"/></dir><file name="Promotions.php" hash="c4daffe562c0c275ce557ee151c09857"/><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="358f68c28d18f02af84fee4b1b11691a"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="190aa60726698e82c99983eb533e119b"/><file name="config.xml" hash="33919d473722f72c26be0015a7c867e8"/><file name="system.xml" hash="9545d30dcfc88d7e194fc40f54d47ed6"/></dir><dir name="sql"><dir name="reckless_prediction_setup"><file name="mysql4-install-0.1.0.php" hash="f058cf3da3900069ee364d5ed211390d"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Reckless_Prediction.xml" hash="2b822e3b624ed0437395ee8ee9ab7190"/></dir></target></contents>
22
  <compatible/>
23
- <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.0.0.0</min><max>1.9</max></package></required></dependencies>
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&#xD;
11
+ &#xD;
12
+ About Reckless Data&#xD;
13
+ &#xD;
14
+ We are building accessible decision support tools; to empower retailers with tools like those of Amazon.&#xD;
15
+ &#xD;
16
+ Reckless Prediction&#xD;
17
+ &#xD;
18
+ This Magento extension learns from your historic Magento operational data and predicts whether a given online customer or guest will checkout or not.&#xD;
19
+ The system analyses user behaviour in realtime and predicts the checkout intention of the user.&#xD;
20
+ &#xD;
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.&#xD;
22
+ &#xD;
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.&#xD;
24
+ &#xD;
25
+ Why use Reckless Prediction ?&#xD;
26
+ &#xD;
27
+ a) Increase Average Order Value: If the predicted checkout intent is a &#x201C;YES&#x201D; and the AOV for this customer is higher that the current quote, you can offer targeted promotion to increase the Cart value.&#xD;
28
+ &#xD;
29
+ b) Increase conversion &amp; reduce abandoned cart : If the predicted checkout intent is a &#x201C;NO&#x201D;, you can entice the customer to checkout by giving a time limited coupon code or free shipping.&#xD;
30
+ &#xD;
31
+ c) Increase Lifetime value: If the predicted checkout intent is a &#x201C;YES&#x201D;, you can offer a coupon code, valid from another date and entice him to come back before the coupon expiry date.&#xD;
32
+ &#xD;
33
+ Data Privacy&#xD;
34
+ &#xD;
35
+ - Customer email is never used unless specified in the extension configuration&#xD;
36
+ - Customer ID is the only information used for a customer. No name, address, billing or any other information is processed by Reckless.&#xD;
37
+ Features&#xD;
38
+ &#xD;
39
+ - Works for both logged in(registered) and guest customers &#xD;
40
+ - Promotion Budget control with Coupon validity Days and maximum limit &#xD;
41
+ - Customizable messages, coupon code/ discount percent/ and other basic configurations &#xD;
42
+ Reporting&#xD;
43
+ &#xD;
44
+ insi Report 1 : Promotions Report&#xD;
45
+ Reports the predicted checkout intent for all the online customers, their quotes and the corresponding coupon code offered to the customer.&#xD;
46
+ Access: Magento Admin Panel : Customers &gt; Reckless Promotions&#xD;
47
+ &#xD;
48
+ Report 2: Promotions redemption Report&#xD;
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.&#xD;
50
+ Access: Magento Admin Panel : Reports-&gt; Reckless Redemptions&#xD;
51
+ &#xD;
52
+ **The daily discounted value can be limited.&#xD;
53
+ Demo Store&#xD;
54
+ &#xD;
55
+ &gt; Store: http://magento.reckless.io &#xD;
56
+ &gt; Admin Back-end: http://magento.reckless.io/admin (Admin Username: admin Password: password1234)&#xD;
57
+ Key Configuration ( Access: Magento Admin Panel : System &gt; Configurations &gt; Reckless Data &gt; Predictions )&#xD;
58
+ API Key: Configured by Reckless Servers, Please do not change.&#xD;
59
+ Registered Domain: Configured by Reckless Servers, Please do not change.&#xD;
60
+ Enable Customer Email Sync : By default this is disabled for data privacy control.&#xD;
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).&#xD;
62
+ Promotion Code Prefix: Prefix for every coupon code created.&#xD;
63
+ Message to show to customer: This is a message that will be shown in the cart to the customer.&#xD;
64
+ Con Jobs&#xD;
65
+ &#xD;
66
+ 1) reckless_prediction_heartbeat: Runs every 5 minutes to update online customers with predicted checkout intents and generates relevant coupon codes.&#xD;
67
+ 2) reckless_start_training : Runs every 30 minutes to train the prediction model in Reckless.io&#xD;
68
+ &#xD;
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&#xD;
71
+ - Enhanced grids&#xD;
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>