Version Notes
- Add logs
- Use cache to reduce SQL queries
Download this release
Release Info
Developer | Maxime Pruvost |
Extension | cartsguru |
Version | 1.2.10 |
Comparing to | |
See all releases |
Code changes from version 1.2.9 to 1.2.10
app/code/local/Cartsguru/Model/Observer.php
CHANGED
@@ -6,26 +6,32 @@
|
|
6 |
*/
|
7 |
class Cartsguru_Model_Observer
|
8 |
{
|
|
|
|
|
9 |
/**
|
10 |
* Check api is available after save config in admin
|
11 |
* @param $observer
|
12 |
*/
|
13 |
public function configSaveAfter($observer)
|
14 |
{
|
|
|
|
|
15 |
$session = Mage::getSingleton('core/session');
|
16 |
$webservice = Mage::getModel('cartsguru/webservice');
|
17 |
-
|
18 |
$result = $webservice->checkAddress();
|
19 |
-
|
20 |
if ($result == false){
|
21 |
return $session->addError('Error check connection');
|
22 |
}
|
23 |
-
|
24 |
$session->addSuccess('Connection checked');
|
25 |
-
|
26 |
if ($result->isNew){
|
27 |
$webservice->sendHistory();
|
28 |
}
|
|
|
|
|
29 |
}
|
30 |
|
31 |
/**
|
@@ -34,10 +40,14 @@ class Cartsguru_Model_Observer
|
|
34 |
*/
|
35 |
public function customerSaveAfter($observer)
|
36 |
{
|
|
|
|
|
37 |
$customer = $observer->getCustomer();
|
38 |
Mage::getModel('cartsguru/webservice')->sendAccount($customer);
|
39 |
-
|
40 |
-
|
|
|
|
|
41 |
/**
|
42 |
* Set token before quote is save
|
43 |
* @param $observer
|
@@ -45,20 +55,30 @@ class Cartsguru_Model_Observer
|
|
45 |
public function quoteSaveBefore($observer)
|
46 |
{
|
47 |
$quote = $observer->getEvent()->getQuote();
|
|
|
|
|
|
|
48 |
if (!$quote->getData('cartsguru_token')){
|
49 |
$tools = Mage::helper('cartsguru/tools');
|
50 |
$quote->setData('cartsguru_token',$tools::generateUUID());
|
51 |
}
|
|
|
|
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
-
* Handle quote is saved, and push it to carts guru
|
56 |
* @param $observer
|
57 |
*/
|
58 |
public function quoteSaveAfter($observer)
|
59 |
{
|
60 |
$quote = $observer->getEvent()->getQuote();
|
|
|
|
|
|
|
61 |
Mage::getModel('cartsguru/webservice')->sendAbadonnedCart($quote);
|
|
|
|
|
62 |
}
|
63 |
|
64 |
/**
|
@@ -68,10 +88,15 @@ class Cartsguru_Model_Observer
|
|
68 |
public function orderSaveAfter($observer) {
|
69 |
/* @var Mage_Sales_Model_Order $order */
|
70 |
$order = $observer->getOrder();
|
71 |
-
|
|
|
|
|
|
|
72 |
// Only trigger when order status change
|
73 |
if ($order->getStatus() != $order->getOrigData('status')) {
|
74 |
Mage::getModel('cartsguru/webservice')->sendOrder($order);
|
75 |
-
}
|
76 |
-
|
77 |
-
|
|
|
|
6 |
*/
|
7 |
class Cartsguru_Model_Observer
|
8 |
{
|
9 |
+
const LOG_FILE = "cartsguru.log";
|
10 |
+
|
11 |
/**
|
12 |
* Check api is available after save config in admin
|
13 |
* @param $observer
|
14 |
*/
|
15 |
public function configSaveAfter($observer)
|
16 |
{
|
17 |
+
Mage::log('Observer: Start handle configSaveAfter', null, Cartsguru_Model_Observer::LOG_FILE);
|
18 |
+
|
19 |
$session = Mage::getSingleton('core/session');
|
20 |
$webservice = Mage::getModel('cartsguru/webservice');
|
21 |
+
|
22 |
$result = $webservice->checkAddress();
|
23 |
+
|
24 |
if ($result == false){
|
25 |
return $session->addError('Error check connection');
|
26 |
}
|
27 |
+
|
28 |
$session->addSuccess('Connection checked');
|
29 |
+
|
30 |
if ($result->isNew){
|
31 |
$webservice->sendHistory();
|
32 |
}
|
33 |
+
|
34 |
+
Mage::log('Observer: End handle configSaveAfter', null, Cartsguru_Model_Observer::LOG_FILE);
|
35 |
}
|
36 |
|
37 |
/**
|
40 |
*/
|
41 |
public function customerSaveAfter($observer)
|
42 |
{
|
43 |
+
Mage::log('Observer: Start handle customerSaveAfter', null, Cartsguru_Model_Observer::LOG_FILE);
|
44 |
+
|
45 |
$customer = $observer->getCustomer();
|
46 |
Mage::getModel('cartsguru/webservice')->sendAccount($customer);
|
47 |
+
|
48 |
+
Mage::log('Observer: End handle customerSaveAfter', null, Cartsguru_Model_Observer::LOG_FILE);
|
49 |
+
}
|
50 |
+
|
51 |
/**
|
52 |
* Set token before quote is save
|
53 |
* @param $observer
|
55 |
public function quoteSaveBefore($observer)
|
56 |
{
|
57 |
$quote = $observer->getEvent()->getQuote();
|
58 |
+
|
59 |
+
Mage::log('Observer: Start handle quoteSaveBefore for ' . $quote->getId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
60 |
+
|
61 |
if (!$quote->getData('cartsguru_token')){
|
62 |
$tools = Mage::helper('cartsguru/tools');
|
63 |
$quote->setData('cartsguru_token',$tools::generateUUID());
|
64 |
}
|
65 |
+
|
66 |
+
Mage::log('Observer: End handle quoteSaveBefore for ' . $quote->getId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
67 |
}
|
68 |
|
69 |
/**
|
70 |
+
* Handle quote is saved, and push it to carts guru
|
71 |
* @param $observer
|
72 |
*/
|
73 |
public function quoteSaveAfter($observer)
|
74 |
{
|
75 |
$quote = $observer->getEvent()->getQuote();
|
76 |
+
|
77 |
+
Mage::log('Observer: Start handle quoteSaveAfter for ' . $quote->getId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
78 |
+
|
79 |
Mage::getModel('cartsguru/webservice')->sendAbadonnedCart($quote);
|
80 |
+
|
81 |
+
Mage::log('Observer: End handle quoteSaveAfter for ' . $quote->getId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
82 |
}
|
83 |
|
84 |
/**
|
88 |
public function orderSaveAfter($observer) {
|
89 |
/* @var Mage_Sales_Model_Order $order */
|
90 |
$order = $observer->getOrder();
|
91 |
+
|
92 |
+
|
93 |
+
Mage::log('Observer: Start handle orderSaveAfter for ' . $order->getIncrementId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
94 |
+
|
95 |
// Only trigger when order status change
|
96 |
if ($order->getStatus() != $order->getOrigData('status')) {
|
97 |
Mage::getModel('cartsguru/webservice')->sendOrder($order);
|
98 |
+
}
|
99 |
+
|
100 |
+
Mage::log('Observer: End handle orderSaveAfter for ' . $order->getIncrementId(), null, Cartsguru_Model_Observer::LOG_FILE);
|
101 |
+
}
|
102 |
+
}
|
app/code/local/Cartsguru/Model/Webservice.php
CHANGED
@@ -6,9 +6,18 @@
|
|
6 |
*/
|
7 |
class Cartsguru_Model_Webservice
|
8 |
{
|
9 |
-
private $apiBaseUrl = '
|
|
|
10 |
private $configBasePath = 'cartsguru/cartsguru_group/';
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
protected function getStoreFromAdmin(){
|
14 |
$store_id;
|
@@ -23,9 +32,9 @@ class Cartsguru_Model_Webservice
|
|
23 |
}
|
24 |
elseif (strlen($code = Mage::app()->getRequest()->getParam('website'))) {
|
25 |
$website_id = Mage::getModel('core/website')->load($code)->getId();
|
26 |
-
$store_id = Mage::app()->getWebsite($website_id)->getDefaultStore()->getId();
|
27 |
}
|
28 |
-
|
29 |
if ($store_id){
|
30 |
return Mage::app()->getStore($store_id);
|
31 |
}
|
@@ -33,32 +42,32 @@ class Cartsguru_Model_Webservice
|
|
33 |
return Mage::app()->getStore();
|
34 |
}
|
35 |
}
|
36 |
-
|
37 |
protected function setStoreConfig($key, $value, $store = null)
|
38 |
{
|
39 |
if (!$store){
|
40 |
$store = Mage::app()->getStore();
|
41 |
}
|
42 |
-
|
43 |
$store->setConfig($this->configBasePath . $key, $value);
|
44 |
}
|
45 |
-
|
46 |
protected function getStoreConfig($key, $store = null){
|
47 |
if (!$store){
|
48 |
$store = Mage::app()->getStore();
|
49 |
}
|
50 |
-
|
51 |
return $store->getConfig($this->configBasePath . $key);
|
52 |
}
|
53 |
-
|
54 |
protected function isStoreConfigured($store = null){
|
55 |
if (!$store){
|
56 |
$store = Mage::app()->getStore();
|
57 |
}
|
58 |
-
|
59 |
return $this->getStoreConfig('siteid',$store) && $this->getStoreConfig('auth',$store);
|
60 |
}
|
61 |
-
|
62 |
/**
|
63 |
* If value is empty return ''
|
64 |
* @param $value
|
@@ -78,7 +87,7 @@ class Cartsguru_Model_Webservice
|
|
78 |
{
|
79 |
return date('Y-m-d\TH:i:sP', strtotime($date));
|
80 |
}
|
81 |
-
|
82 |
/**
|
83 |
* Get category names
|
84 |
* @param $item
|
@@ -106,7 +115,7 @@ class Cartsguru_Model_Webservice
|
|
106 |
|
107 |
return $categoryNames;
|
108 |
}
|
109 |
-
|
110 |
/**
|
111 |
* This method calculate total taxes included, shipping excluded
|
112 |
* @param $obj order or quote
|
@@ -114,53 +123,70 @@ class Cartsguru_Model_Webservice
|
|
114 |
*/
|
115 |
public function getTotalATI($items){
|
116 |
$totalATI = (float)0;
|
117 |
-
|
118 |
foreach ($items as $item) {
|
119 |
$totalATI += $item['totalATI'];
|
120 |
}
|
121 |
-
|
122 |
return $totalATI;
|
123 |
}
|
124 |
-
|
125 |
/**
|
126 |
* This method build items from order or quote
|
127 |
* @param $obj order or quote
|
128 |
* @return array
|
129 |
*/
|
130 |
public function getItemsData($obj){
|
|
|
131 |
$items = array();
|
132 |
foreach ($obj->getAllVisibleItems() as $item) {
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
else {
|
139 |
-
$
|
140 |
-
}
|
141 |
-
|
142 |
-
$categoryNames = $this->getCatNames($product);
|
143 |
-
|
144 |
-
$quantity = (int)$item->getQtyOrdered();
|
145 |
-
if ($quantity == 0){
|
146 |
-
$quantity = (int)$item->getQty();
|
147 |
}
|
148 |
-
|
|
|
|
|
149 |
$items[] = array(
|
150 |
'id' => $item->getId(), // SKU or product id
|
151 |
'label' => $item->getName(), // Designation
|
152 |
'quantity' => $quantity, // Count
|
153 |
-
'totalET' => (float)$item->getPrice()*$quantity,
|
154 |
'totalATI' => (float)$item->getPriceInclTax()*$quantity, // Subtotal of item, taxe included
|
155 |
-
'url' => $
|
156 |
-
'imageUrl' => $imageUrl,
|
157 |
-
'universe' => $
|
158 |
-
'category' => $
|
159 |
);
|
160 |
}
|
161 |
return $items;
|
162 |
}
|
163 |
-
|
164 |
/**
|
165 |
* This method return order data in cartsguru format
|
166 |
* @param $order
|
@@ -172,14 +198,14 @@ class Cartsguru_Model_Webservice
|
|
172 |
if (!$order->getStatus()){
|
173 |
return null;
|
174 |
}
|
175 |
-
|
176 |
//Customer data
|
177 |
$gender = $this->genderMapping($order->getCustomerGender());
|
178 |
$email = $order->getCustomerEmail();
|
179 |
-
|
180 |
//Address
|
181 |
$address = $order->getBillingAddress();
|
182 |
-
|
183 |
//Items details
|
184 |
$items = $this->getItemsData($order);
|
185 |
|
@@ -212,22 +238,22 @@ class Cartsguru_Model_Webservice
|
|
212 |
public function sendOrder($order)
|
213 |
{
|
214 |
$store = Mage::app()->getStore($order->getStoreId());
|
215 |
-
|
216 |
//Check is well configured
|
217 |
if (!$this->isStoreConfigured($store)){
|
218 |
return;
|
219 |
}
|
220 |
-
|
221 |
//Get data, stop if none
|
222 |
$orderData = $this->getOrderData($order,$store);
|
223 |
if (empty($orderData)) {
|
224 |
return;
|
225 |
}
|
226 |
-
|
227 |
//Push data to api
|
228 |
$this->doPostRequest('/orders', $orderData, $store);
|
229 |
-
}
|
230 |
-
|
231 |
/**
|
232 |
* Map int of geder to string
|
233 |
* @param $gender
|
@@ -235,7 +261,7 @@ class Cartsguru_Model_Webservice
|
|
235 |
*/
|
236 |
public function genderMapping($gender){
|
237 |
switch((int)$gender){
|
238 |
-
case 1:
|
239 |
return 'mister';
|
240 |
case 2:
|
241 |
return 'madam';
|
@@ -243,7 +269,7 @@ class Cartsguru_Model_Webservice
|
|
243 |
return '';
|
244 |
}
|
245 |
}
|
246 |
-
|
247 |
/**
|
248 |
* This method return abounded cart data in cartsguru api format
|
249 |
* @param $quote
|
@@ -257,14 +283,14 @@ class Cartsguru_Model_Webservice
|
|
257 |
$lastname = $quote->getCustomerLastname();
|
258 |
$firstname = $quote->getCustomerFirstname();
|
259 |
$email = $quote->getCustomerEmail();
|
260 |
-
|
261 |
//Lookup for phone & country
|
262 |
$customer = $quote->getCustomer();
|
263 |
$address = $quote->getBillingAddress();
|
264 |
$request = Mage::app()->getRequest()->getParams();
|
265 |
$phone = '';
|
266 |
$country = '';
|
267 |
-
|
268 |
if (isset($request['billing'])) {
|
269 |
if (isset($request['billing']['telephone'])) {
|
270 |
$phone = $request['billing']['telephone'];
|
@@ -274,7 +300,7 @@ class Cartsguru_Model_Webservice
|
|
274 |
$country = $request['billing']['country_id'];
|
275 |
}
|
276 |
}
|
277 |
-
|
278 |
if ($address){
|
279 |
if (!$phone){
|
280 |
$phone = $address->getTelephone();
|
@@ -283,23 +309,23 @@ class Cartsguru_Model_Webservice
|
|
283 |
$country = $address->getCountryId();
|
284 |
}
|
285 |
}
|
286 |
-
|
287 |
if ($customer){
|
288 |
$customerAddress = $customer->getDefaultBillingAddress();
|
289 |
-
|
290 |
if ($customerAddress && !$phone){
|
291 |
-
$phone = $customerAddress->getTelephone();
|
292 |
}
|
293 |
if ($customerAddress && !$country){
|
294 |
$country = $customerAddress->getCountryId();
|
295 |
}
|
296 |
}
|
297 |
-
|
298 |
//Recover link
|
299 |
$recoverUrl = ($quote->getData('cartsguru_token')) ?
|
300 |
Mage::getBaseUrl() . 'cartsguru/recovercart?cart_id=' . $quote->getId() . '&cart_token=' . $quote->getData('cartsguru_token') :
|
301 |
'';
|
302 |
-
|
303 |
//Items details
|
304 |
$items = $this->getItemsData($quote);
|
305 |
|
@@ -307,7 +333,7 @@ class Cartsguru_Model_Webservice
|
|
307 |
if (!$email || sizeof($items) == 0) {
|
308 |
return;
|
309 |
}
|
310 |
-
|
311 |
return array(
|
312 |
'siteId' => $this->getStoreConfig('siteid', $store), // SiteId is part of plugin configuration
|
313 |
'id' => $quote->getId(), // Order reference, the same display to the buyer
|
@@ -335,18 +361,18 @@ class Cartsguru_Model_Webservice
|
|
335 |
public function sendAbadonnedCart($quote)
|
336 |
{
|
337 |
$store = Mage::app()->getStore($quote->getStoreId());
|
338 |
-
|
339 |
//Check is well configured
|
340 |
if (!$this->isStoreConfigured($store)){
|
341 |
return;
|
342 |
}
|
343 |
-
|
344 |
//Get data and continue only if exist
|
345 |
$cartData = $this->getAbadonnedCartData($quote, $store);
|
346 |
if (!$cartData){
|
347 |
return;
|
348 |
}
|
349 |
-
|
350 |
//Check not already sent
|
351 |
$cache = Mage::app()->getCache();
|
352 |
$cacheId = 'cg-quote-' . $quote->getId();
|
@@ -357,12 +383,13 @@ class Cartsguru_Model_Webservice
|
|
357 |
return;
|
358 |
}
|
359 |
|
360 |
-
$
|
|
|
|
|
361 |
|
362 |
-
|
363 |
$this->doPostRequest('/carts', $cartData, $store);
|
364 |
}
|
365 |
-
|
366 |
/**
|
367 |
* Get customer Firstname
|
368 |
* @param $customer
|
@@ -401,7 +428,7 @@ class Cartsguru_Model_Webservice
|
|
401 |
public function getCustomerData($customer, $store = null)
|
402 |
{
|
403 |
$address = $customer->getDefaultBillingAddress();
|
404 |
-
|
405 |
$gender = $this->genderMapping($customer->getGender());
|
406 |
$lastname = $this->getLastname($customer, $address);
|
407 |
$firstname = $this->getFirstname($customer, $address);
|
@@ -434,11 +461,11 @@ class Cartsguru_Model_Webservice
|
|
434 |
if (!$this->isStoreConfigured()){
|
435 |
return;
|
436 |
}
|
437 |
-
|
438 |
$customerData = $this->getCustomerData($customer);
|
439 |
$this->doPostRequest('/accounts', $customerData);
|
440 |
}
|
441 |
-
|
442 |
|
443 |
|
444 |
/** This method return true if connect to server is ok
|
@@ -447,23 +474,23 @@ class Cartsguru_Model_Webservice
|
|
447 |
public function checkAddress()
|
448 |
{
|
449 |
$store = $this->getStoreFromAdmin();
|
450 |
-
|
451 |
$requestUrl = '/sites/' . $this->getStoreConfig('siteid', $store) . '/register-plugin';
|
452 |
$fields = array(
|
453 |
'plugin' => 'magento',
|
454 |
-
'pluginVersion' => '1.2.
|
455 |
'storeVersion' => Mage::getVersion()
|
456 |
);
|
457 |
|
458 |
$response = $this->doPostRequest($requestUrl, $fields, $store);
|
459 |
-
|
460 |
if (!$response || $response->getStatus() != 200){
|
461 |
return false;
|
462 |
}
|
463 |
-
|
464 |
return json_decode($response->getBody());
|
465 |
-
}
|
466 |
-
|
467 |
|
468 |
/* Send quote and order history
|
469 |
*
|
@@ -473,49 +500,27 @@ class Cartsguru_Model_Webservice
|
|
473 |
*/
|
474 |
public function sendHistory()
|
475 |
{
|
476 |
-
$store =
|
477 |
-
|
478 |
$lastOrder = $this->sendLastOrders($store);
|
479 |
if ($lastOrder){
|
480 |
$this->sendLastQuotes($store, $lastOrder->getCreatedAt());
|
481 |
}
|
482 |
}
|
483 |
-
|
484 |
private function sendLastOrders($store){
|
485 |
$orders = array();
|
486 |
$last = null;
|
487 |
$items = Mage::getModel('sales/order')
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
->addFieldToFilter('created_at', array('gt' => date("Y-m-d H:i:s", strtotime('-1 month'))));
|
494 |
-
|
495 |
-
//Check count of items
|
496 |
-
if (count($items) > $this->historySize){
|
497 |
-
$items = Mage::getModel('sales/order')
|
498 |
-
->getCollection()
|
499 |
-
->setOrder('created_at', 'desc')
|
500 |
-
->join(array('stores' => 'core/store'), 'main_table.store_id=stores.store_id')
|
501 |
-
->addFieldToFilter('stores.website_id', $store->getWebsiteId())
|
502 |
-
->addFieldToFilter('created_at', array('gt' => date("Y-m-d H:i:s", strtotime('-1 month'))))
|
503 |
-
->setPageSize($this->historySize);
|
504 |
-
}
|
505 |
-
else {
|
506 |
-
$items = Mage::getModel('sales/order')
|
507 |
-
->getCollection()
|
508 |
-
->setOrder('created_at', 'desc')
|
509 |
-
->join(array('stores' => 'core/store'), 'main_table.store_id=stores.store_id')
|
510 |
-
->addFieldToFilter('stores.website_id', $store->getWebsiteId())
|
511 |
-
->addFieldToFilter('created_at', array('gt' => date("Y-m-d H:i:s", strtotime('-12 month'))))
|
512 |
-
->setPageSize($this->historySize);
|
513 |
-
}
|
514 |
-
|
515 |
foreach($items as $item){
|
516 |
-
$order = Mage::getModel("sales/order")->load($item->getId());
|
517 |
$last = $order;
|
518 |
-
|
519 |
//Get order data
|
520 |
$orderData = $this->getOrderData($order, $store);
|
521 |
|
@@ -527,29 +532,28 @@ class Cartsguru_Model_Webservice
|
|
527 |
|
528 |
//Push orders to api
|
529 |
if (!empty($orders)){
|
530 |
-
$this->doPostRequest('/import/orders', $orders, $store);
|
531 |
}
|
532 |
-
|
533 |
return $last;
|
534 |
}
|
535 |
-
|
536 |
private function sendLastQuotes($store, $since){
|
537 |
$quotes = array();
|
538 |
$last = null;
|
539 |
$items = Mage::getModel('sales/quote')
|
540 |
->getCollection()
|
541 |
->setOrder('created_at', 'asc')
|
542 |
-
->
|
543 |
-
->addFieldToFilter('stores.website_id', $store->getWebsiteId())
|
544 |
->addFieldToFilter('created_at', array('gt' => $since));
|
545 |
|
546 |
foreach($items as $item){
|
547 |
$quote = Mage::getModel("sales/quote")->loadByIdWithoutStore($item->getId());
|
548 |
$last = $quote;
|
549 |
-
|
550 |
if ($quote){
|
551 |
//Get quote data
|
552 |
-
$quoteData = $this->getAbadonnedCartData($quote, $store);
|
553 |
|
554 |
//Append only if we get it
|
555 |
if ($quoteData){
|
@@ -560,13 +564,13 @@ class Cartsguru_Model_Webservice
|
|
560 |
|
561 |
//Push quotes to api
|
562 |
if (!empty($quotes)){
|
563 |
-
$this->doPostRequest('/import/carts', $quotes, $store);
|
564 |
}
|
565 |
-
|
566 |
return $last;
|
567 |
}
|
568 |
-
|
569 |
-
|
570 |
/**
|
571 |
* This method send data on api path
|
572 |
* @param $apiPath
|
@@ -587,4 +591,4 @@ class Cartsguru_Model_Webservice
|
|
587 |
return $response;
|
588 |
}
|
589 |
|
590 |
-
}
|
6 |
*/
|
7 |
class Cartsguru_Model_Webservice
|
8 |
{
|
9 |
+
private $apiBaseUrl = 'http://api.cartninja.io';
|
10 |
+
//private $apiBaseUrl = 'https://api.carts.guru';
|
11 |
private $configBasePath = 'cartsguru/cartsguru_group/';
|
12 |
+
|
13 |
+
private $historySize = 250;
|
14 |
+
|
15 |
+
/* Main cache tag constant */
|
16 |
+
const CACHE_TAG = 'cartsguru';
|
17 |
+
const PRODUCT_CACHE_TAG = 'cartsguru_products';
|
18 |
+
const PRODUCT_CACHE_TTL = 7200; // 2h in seconds
|
19 |
+
const QUOTES_CACHE_TAG = 'cartsguru_carts';
|
20 |
+
const QUOTES_CACHE_TTL = 1800; // 30min in seconds
|
21 |
|
22 |
protected function getStoreFromAdmin(){
|
23 |
$store_id;
|
32 |
}
|
33 |
elseif (strlen($code = Mage::app()->getRequest()->getParam('website'))) {
|
34 |
$website_id = Mage::getModel('core/website')->load($code)->getId();
|
35 |
+
$store_id = Mage::app()->getWebsite($website_id)->getDefaultStore()->getId();
|
36 |
}
|
37 |
+
|
38 |
if ($store_id){
|
39 |
return Mage::app()->getStore($store_id);
|
40 |
}
|
42 |
return Mage::app()->getStore();
|
43 |
}
|
44 |
}
|
45 |
+
|
46 |
protected function setStoreConfig($key, $value, $store = null)
|
47 |
{
|
48 |
if (!$store){
|
49 |
$store = Mage::app()->getStore();
|
50 |
}
|
51 |
+
|
52 |
$store->setConfig($this->configBasePath . $key, $value);
|
53 |
}
|
54 |
+
|
55 |
protected function getStoreConfig($key, $store = null){
|
56 |
if (!$store){
|
57 |
$store = Mage::app()->getStore();
|
58 |
}
|
59 |
+
|
60 |
return $store->getConfig($this->configBasePath . $key);
|
61 |
}
|
62 |
+
|
63 |
protected function isStoreConfigured($store = null){
|
64 |
if (!$store){
|
65 |
$store = Mage::app()->getStore();
|
66 |
}
|
67 |
+
|
68 |
return $this->getStoreConfig('siteid',$store) && $this->getStoreConfig('auth',$store);
|
69 |
}
|
70 |
+
|
71 |
/**
|
72 |
* If value is empty return ''
|
73 |
* @param $value
|
87 |
{
|
88 |
return date('Y-m-d\TH:i:sP', strtotime($date));
|
89 |
}
|
90 |
+
|
91 |
/**
|
92 |
* Get category names
|
93 |
* @param $item
|
115 |
|
116 |
return $categoryNames;
|
117 |
}
|
118 |
+
|
119 |
/**
|
120 |
* This method calculate total taxes included, shipping excluded
|
121 |
* @param $obj order or quote
|
123 |
*/
|
124 |
public function getTotalATI($items){
|
125 |
$totalATI = (float)0;
|
126 |
+
|
127 |
foreach ($items as $item) {
|
128 |
$totalATI += $item['totalATI'];
|
129 |
}
|
130 |
+
|
131 |
return $totalATI;
|
132 |
}
|
133 |
+
|
134 |
/**
|
135 |
* This method build items from order or quote
|
136 |
* @param $obj order or quote
|
137 |
* @return array
|
138 |
*/
|
139 |
public function getItemsData($obj){
|
140 |
+
$cache = Mage::app()->getCache();
|
141 |
$items = array();
|
142 |
foreach ($obj->getAllVisibleItems() as $item) {
|
143 |
+
|
144 |
+
//Check not already sent
|
145 |
+
$cacheId = 'cg-product-' . $item->getProductId();
|
146 |
+
$productData = $cache->load($cacheId);
|
147 |
+
if (!$productData) {
|
148 |
+
$product = Mage::getModel('catalog/product')->load($item->getProductId());
|
149 |
+
|
150 |
+
if ($product->getImage() == 'no_selection' || !$product->getImage()){
|
151 |
+
$imageUrl = $this->notEmpty(null);
|
152 |
+
}
|
153 |
+
else {
|
154 |
+
$imageUrl = $product->getSmallImageUrl(120, 120);
|
155 |
+
}
|
156 |
+
|
157 |
+
$categoryNames = $this->getCatNames($product);
|
158 |
+
|
159 |
+
$productData = array(
|
160 |
+
'url' => $product->getProductUrl(), // URL of product sheet
|
161 |
+
'imageUrl' => $imageUrl, // URL of product image
|
162 |
+
'universe' => $this->notEmpty($categoryNames[1]), // Main category
|
163 |
+
'category' => $this->notEmpty(end($categoryNames)) // Child category
|
164 |
+
);
|
165 |
+
|
166 |
+
$tags = array(Cartsguru_Model_Webservice::CACHE_TAG, Cartsguru_Model_Webservice::PRODUCT_CACHE_TAG);
|
167 |
+
$cache->save(json_encode($productData), $cacheId, $tags, Cartsguru_Model_Webservice::PRODUCT_CACHE_TTL);
|
168 |
}
|
169 |
else {
|
170 |
+
$productData = json_decode($productData, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
172 |
+
|
173 |
+
$quantity = (int)$item->getQtyOrdered() > 0 ? (int)$item->getQtyOrdered() : (int)$item->getQty();
|
174 |
+
|
175 |
$items[] = array(
|
176 |
'id' => $item->getId(), // SKU or product id
|
177 |
'label' => $item->getName(), // Designation
|
178 |
'quantity' => $quantity, // Count
|
179 |
+
'totalET' => (float)$item->getPrice()*$quantity, // Subtotal of item, taxe excluded
|
180 |
'totalATI' => (float)$item->getPriceInclTax()*$quantity, // Subtotal of item, taxe included
|
181 |
+
'url' => $productData['url'],
|
182 |
+
'imageUrl' => $productData['imageUrl'],
|
183 |
+
'universe' => $productData['universe'],
|
184 |
+
'category' => $productData['category']
|
185 |
);
|
186 |
}
|
187 |
return $items;
|
188 |
}
|
189 |
+
|
190 |
/**
|
191 |
* This method return order data in cartsguru format
|
192 |
* @param $order
|
198 |
if (!$order->getStatus()){
|
199 |
return null;
|
200 |
}
|
201 |
+
|
202 |
//Customer data
|
203 |
$gender = $this->genderMapping($order->getCustomerGender());
|
204 |
$email = $order->getCustomerEmail();
|
205 |
+
|
206 |
//Address
|
207 |
$address = $order->getBillingAddress();
|
208 |
+
|
209 |
//Items details
|
210 |
$items = $this->getItemsData($order);
|
211 |
|
238 |
public function sendOrder($order)
|
239 |
{
|
240 |
$store = Mage::app()->getStore($order->getStoreId());
|
241 |
+
|
242 |
//Check is well configured
|
243 |
if (!$this->isStoreConfigured($store)){
|
244 |
return;
|
245 |
}
|
246 |
+
|
247 |
//Get data, stop if none
|
248 |
$orderData = $this->getOrderData($order,$store);
|
249 |
if (empty($orderData)) {
|
250 |
return;
|
251 |
}
|
252 |
+
|
253 |
//Push data to api
|
254 |
$this->doPostRequest('/orders', $orderData, $store);
|
255 |
+
}
|
256 |
+
|
257 |
/**
|
258 |
* Map int of geder to string
|
259 |
* @param $gender
|
261 |
*/
|
262 |
public function genderMapping($gender){
|
263 |
switch((int)$gender){
|
264 |
+
case 1:
|
265 |
return 'mister';
|
266 |
case 2:
|
267 |
return 'madam';
|
269 |
return '';
|
270 |
}
|
271 |
}
|
272 |
+
|
273 |
/**
|
274 |
* This method return abounded cart data in cartsguru api format
|
275 |
* @param $quote
|
283 |
$lastname = $quote->getCustomerLastname();
|
284 |
$firstname = $quote->getCustomerFirstname();
|
285 |
$email = $quote->getCustomerEmail();
|
286 |
+
|
287 |
//Lookup for phone & country
|
288 |
$customer = $quote->getCustomer();
|
289 |
$address = $quote->getBillingAddress();
|
290 |
$request = Mage::app()->getRequest()->getParams();
|
291 |
$phone = '';
|
292 |
$country = '';
|
293 |
+
|
294 |
if (isset($request['billing'])) {
|
295 |
if (isset($request['billing']['telephone'])) {
|
296 |
$phone = $request['billing']['telephone'];
|
300 |
$country = $request['billing']['country_id'];
|
301 |
}
|
302 |
}
|
303 |
+
|
304 |
if ($address){
|
305 |
if (!$phone){
|
306 |
$phone = $address->getTelephone();
|
309 |
$country = $address->getCountryId();
|
310 |
}
|
311 |
}
|
312 |
+
|
313 |
if ($customer){
|
314 |
$customerAddress = $customer->getDefaultBillingAddress();
|
315 |
+
|
316 |
if ($customerAddress && !$phone){
|
317 |
+
$phone = $customerAddress->getTelephone();
|
318 |
}
|
319 |
if ($customerAddress && !$country){
|
320 |
$country = $customerAddress->getCountryId();
|
321 |
}
|
322 |
}
|
323 |
+
|
324 |
//Recover link
|
325 |
$recoverUrl = ($quote->getData('cartsguru_token')) ?
|
326 |
Mage::getBaseUrl() . 'cartsguru/recovercart?cart_id=' . $quote->getId() . '&cart_token=' . $quote->getData('cartsguru_token') :
|
327 |
'';
|
328 |
+
|
329 |
//Items details
|
330 |
$items = $this->getItemsData($quote);
|
331 |
|
333 |
if (!$email || sizeof($items) == 0) {
|
334 |
return;
|
335 |
}
|
336 |
+
|
337 |
return array(
|
338 |
'siteId' => $this->getStoreConfig('siteid', $store), // SiteId is part of plugin configuration
|
339 |
'id' => $quote->getId(), // Order reference, the same display to the buyer
|
361 |
public function sendAbadonnedCart($quote)
|
362 |
{
|
363 |
$store = Mage::app()->getStore($quote->getStoreId());
|
364 |
+
|
365 |
//Check is well configured
|
366 |
if (!$this->isStoreConfigured($store)){
|
367 |
return;
|
368 |
}
|
369 |
+
|
370 |
//Get data and continue only if exist
|
371 |
$cartData = $this->getAbadonnedCartData($quote, $store);
|
372 |
if (!$cartData){
|
373 |
return;
|
374 |
}
|
375 |
+
|
376 |
//Check not already sent
|
377 |
$cache = Mage::app()->getCache();
|
378 |
$cacheId = 'cg-quote-' . $quote->getId();
|
383 |
return;
|
384 |
}
|
385 |
|
386 |
+
$tags = array(Cartsguru_Model_Webservice::CACHE_TAG, Cartsguru_Model_Webservice::QUOTES_CACHE_TAG);
|
387 |
+
$cache->save($dataMd5, $cacheId, $tags, Cartsguru_Model_Webservice::QUOTES_CACHE_TTL);
|
388 |
+
|
389 |
|
|
|
390 |
$this->doPostRequest('/carts', $cartData, $store);
|
391 |
}
|
392 |
+
|
393 |
/**
|
394 |
* Get customer Firstname
|
395 |
* @param $customer
|
428 |
public function getCustomerData($customer, $store = null)
|
429 |
{
|
430 |
$address = $customer->getDefaultBillingAddress();
|
431 |
+
|
432 |
$gender = $this->genderMapping($customer->getGender());
|
433 |
$lastname = $this->getLastname($customer, $address);
|
434 |
$firstname = $this->getFirstname($customer, $address);
|
461 |
if (!$this->isStoreConfigured()){
|
462 |
return;
|
463 |
}
|
464 |
+
|
465 |
$customerData = $this->getCustomerData($customer);
|
466 |
$this->doPostRequest('/accounts', $customerData);
|
467 |
}
|
468 |
+
|
469 |
|
470 |
|
471 |
/** This method return true if connect to server is ok
|
474 |
public function checkAddress()
|
475 |
{
|
476 |
$store = $this->getStoreFromAdmin();
|
477 |
+
|
478 |
$requestUrl = '/sites/' . $this->getStoreConfig('siteid', $store) . '/register-plugin';
|
479 |
$fields = array(
|
480 |
'plugin' => 'magento',
|
481 |
+
'pluginVersion' => '1.2.10',
|
482 |
'storeVersion' => Mage::getVersion()
|
483 |
);
|
484 |
|
485 |
$response = $this->doPostRequest($requestUrl, $fields, $store);
|
486 |
+
|
487 |
if (!$response || $response->getStatus() != 200){
|
488 |
return false;
|
489 |
}
|
490 |
+
|
491 |
return json_decode($response->getBody());
|
492 |
+
}
|
493 |
+
|
494 |
|
495 |
/* Send quote and order history
|
496 |
*
|
500 |
*/
|
501 |
public function sendHistory()
|
502 |
{
|
503 |
+
$store = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStore();
|
504 |
+
|
505 |
$lastOrder = $this->sendLastOrders($store);
|
506 |
if ($lastOrder){
|
507 |
$this->sendLastQuotes($store, $lastOrder->getCreatedAt());
|
508 |
}
|
509 |
}
|
510 |
+
|
511 |
private function sendLastOrders($store){
|
512 |
$orders = array();
|
513 |
$last = null;
|
514 |
$items = Mage::getModel('sales/order')
|
515 |
+
->getCollection()
|
516 |
+
->setOrder('created_at', 'desc')
|
517 |
+
->setPageSize($this->historySize)
|
518 |
+
->addFieldToFilter('store_id', $store->getStoreId());
|
519 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
foreach($items as $item){
|
521 |
+
$order = Mage::getModel("sales/order")->load($item->getId());
|
522 |
$last = $order;
|
523 |
+
|
524 |
//Get order data
|
525 |
$orderData = $this->getOrderData($order, $store);
|
526 |
|
532 |
|
533 |
//Push orders to api
|
534 |
if (!empty($orders)){
|
535 |
+
$this->doPostRequest('/import/orders', $orders, $store);
|
536 |
}
|
537 |
+
|
538 |
return $last;
|
539 |
}
|
540 |
+
|
541 |
private function sendLastQuotes($store, $since){
|
542 |
$quotes = array();
|
543 |
$last = null;
|
544 |
$items = Mage::getModel('sales/quote')
|
545 |
->getCollection()
|
546 |
->setOrder('created_at', 'asc')
|
547 |
+
->addFieldToFilter('store_id', $store->getStoreId())
|
|
|
548 |
->addFieldToFilter('created_at', array('gt' => $since));
|
549 |
|
550 |
foreach($items as $item){
|
551 |
$quote = Mage::getModel("sales/quote")->loadByIdWithoutStore($item->getId());
|
552 |
$last = $quote;
|
553 |
+
|
554 |
if ($quote){
|
555 |
//Get quote data
|
556 |
+
$quoteData = $this->getAbadonnedCartData($quote, $store);
|
557 |
|
558 |
//Append only if we get it
|
559 |
if ($quoteData){
|
564 |
|
565 |
//Push quotes to api
|
566 |
if (!empty($quotes)){
|
567 |
+
$this->doPostRequest('/import/carts', $quotes, $store);
|
568 |
}
|
569 |
+
|
570 |
return $last;
|
571 |
}
|
572 |
+
|
573 |
+
|
574 |
/**
|
575 |
* This method send data on api path
|
576 |
* @param $apiPath
|
591 |
return $response;
|
592 |
}
|
593 |
|
594 |
+
}
|
app/code/local/Cartsguru/etc/config.xml
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
<!-- plugin name -->
|
4 |
<modules>
|
5 |
<Cartsguru>
|
6 |
-
<version>1.2.
|
7 |
</Cartsguru>
|
8 |
</modules>
|
9 |
<global>
|
@@ -125,6 +125,6 @@
|
|
125 |
<frontName>cartsguru</frontName>
|
126 |
</args>
|
127 |
</cartsguru>
|
128 |
-
</routers>
|
129 |
</frontend>
|
130 |
-
</config>
|
3 |
<!-- plugin name -->
|
4 |
<modules>
|
5 |
<Cartsguru>
|
6 |
+
<version>1.2.10</version>
|
7 |
</Cartsguru>
|
8 |
</modules>
|
9 |
<global>
|
125 |
<frontName>cartsguru</frontName>
|
126 |
</args>
|
127 |
</cartsguru>
|
128 |
+
</routers>
|
129 |
</frontend>
|
130 |
+
</config>
|
app/code/local/Cartsguru/sql/cartsguru_setup/upgrade-1.2.9-1.2.10.php
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
3 |
+
$installer = $this;
|
4 |
+
|
5 |
+
$installer->startSetup();
|
6 |
+
$installer->endSetup();
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>cartsguru</name>
|
4 |
-
<version>1.2.
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/gpl-license.php">GPL</license>
|
7 |
<channel>community</channel>
|
@@ -18,11 +18,12 @@ Effortlessly reduce the number of abandoned shopping carts by automating telepho
|
|
18 |

|
19 |
- SMS Callback &amp; Push SMS
|
20 |
Send to your prospective customers having abandoned a cart, an SMS suggesting a free call back from your customer relations service, a straightforward SMS reminder or an SMS offering a personalized discount</description>
|
21 |
-
<notes>-
|
|
|
22 |
<authors><author><name>Maxime Pruvost</name><user>cgmaximepruvost</user><email>maxime@carts.guru</email></author></authors>
|
23 |
-
<date>2016-
|
24 |
-
<time>
|
25 |
-
<contents><target name="magelocal"><dir name="Cartsguru"><dir name="Helper"><file name="Data.php" hash="f6590d08ba862a169ce43459ddb1193c"/><file name="Tools.php" hash="612133db113c08e7de7ab94a86d23e34"/></dir><dir name="Model"><file name="Observer.php" hash="
|
26 |
<compatible/>
|
27 |
<dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
|
28 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>cartsguru</name>
|
4 |
+
<version>1.2.10</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/gpl-license.php">GPL</license>
|
7 |
<channel>community</channel>
|
18 |

|
19 |
- SMS Callback &amp; Push SMS
|
20 |
Send to your prospective customers having abandoned a cart, an SMS suggesting a free call back from your customer relations service, a straightforward SMS reminder or an SMS offering a personalized discount</description>
|
21 |
+
<notes>- Add logs
|
22 |
+
- Use cache to reduce SQL queries</notes>
|
23 |
<authors><author><name>Maxime Pruvost</name><user>cgmaximepruvost</user><email>maxime@carts.guru</email></author></authors>
|
24 |
+
<date>2016-09-13</date>
|
25 |
+
<time>12:46:27</time>
|
26 |
+
<contents><target name="magelocal"><dir name="Cartsguru"><dir name="Helper"><file name="Data.php" hash="f6590d08ba862a169ce43459ddb1193c"/><file name="Tools.php" hash="612133db113c08e7de7ab94a86d23e34"/></dir><dir name="Model"><file name="Observer.php" hash="93ad478de9ac40d76c65dd1054d9f5a5"/><file name="Webservice.php" hash="2612a01cb2b738eda9f9fac5e1fe3f90"/></dir><dir name="controllers"><file name="IndexController.php" hash="108acaab218e2a5e79a12677f83ebc29"/><file name="RecovercartController.php" hash="fab55c8774843ed11e939ee6df1ce0ed"/></dir><dir name="etc"><file name="config.xml" hash="3354bc95b0ddc451865cbb2648df9bbd"/><file name="system.xml" hash="cb0fbf86d2be47dbd719739ee79c4cba"/></dir><dir name="sql"><dir name="cartsguru_setup"><file name="install-1.0.0.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.0.0-1.0.1.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.0.1-1.0.2.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.0.2-1.1.0.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.0-1.1.1.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.1-1.1.2.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.2-1.1.3.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.3-1.1.4 .php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.4-1.1.5.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.1.5-1.2.0.php" hash="066c5cfb9870c04737cba2d2edb30a40"/><file name="upgrade-1.2.0-1.2.1.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.1-1.2.2.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.2-1.2.3.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.3-1.2.4.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.4-1.2.5.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.5-1.2.6.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.6-1.2.7.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.7-1.2.8.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.8-1.2.9.php" hash="381716ae5001678f8bcc6680bad68015"/><file name="upgrade-1.2.9-1.2.10.php" hash="84cb92331d31afda4f06aca50dbd597e"/></dir></dir></dir></target><target name="magelocale"><dir name="fr_FR"><file name="CartsGuru.csv" hash="b6d51893c33ddef1d53372d3a23b036c"/></dir><dir name="en_US"><file name="CartsGuru.csv" hash="921cb4133db47471456759443bb269f5"/></dir></target><target name="mageetc"><dir name="modules"><file name="Cartsguru.xml" hash="32bfa7d63b1a5b6b8f7977bf31af4e28"/></dir></target></contents>
|
27 |
<compatible/>
|
28 |
<dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
|
29 |
</package>
|