cartsguru - Version 1.1.0

Version Notes

- Add imageUrl in sent data
- Improve manangment of order state

Download this release

Release Info

Developer Maxime Pruvost
Extension cartsguru
Version 1.1.0
Comparing to
See all releases


Version 1.1.0

app/code/local/Cartsguru/Helper/Data.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class of Magento core helper abstraction
5
+ * Class Cartsguru_Helper_Data
6
+ */
7
+ class Cartsguru_Helper_Data extends Mage_Core_Helper_Abstract
8
+ {
9
+
10
+ }
app/code/local/Cartsguru/Model/Observer.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This class provides methods which calls on magento dispatch events
5
+ * Class Cartsguru_Model_Observer
6
+ */
7
+ class Cartsguru_Model_Observer
8
+ {
9
+ /**
10
+ * This method check api available after save config in admin
11
+ * @param $observer
12
+ */
13
+ public function configSaveAfter($observer)
14
+ {
15
+ $session = Mage::getSingleton('core/session');
16
+ return (Mage::getModel('cartsguru/webservice')->checkAddress()) ?
17
+ $session->addSuccess('Connection checked')
18
+ : $session->addError('Error check connection');
19
+ }
20
+
21
+ /**
22
+ * This method - hook for order save api call
23
+ * @param $observer
24
+ */
25
+ public function orderSaveAfter($observer)
26
+ {
27
+ Mage::getModel('cartsguru/webservice')->sendOrder($observer->getOrder());
28
+ }
29
+
30
+ /**
31
+ * This method add telephone and country code to quote
32
+ * @param $observer
33
+ */
34
+ public function quoteSaveBefore($observer)
35
+ {
36
+ $quote = $observer->getQuote();
37
+ $request = Mage::app()->getRequest()->getParams();
38
+ $cache = Mage::app()->getCache();
39
+
40
+ if (isset($request['billing'])) {
41
+ if (isset($request['billing']['telephone'])) {
42
+ $quote->setTelephone($request['billing']['telephone']);
43
+ }
44
+
45
+ if (isset($request['billing']['country_id'])) {
46
+ $quote->setData('country', $request['billing']['country_id']);
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * This method - hook for customer save api call
53
+ * @param $observer
54
+ */
55
+ public function customerSaveAfter($observer)
56
+ {
57
+ Mage::getModel('cartsguru/webservice')->sendAccount($observer->getCustomer());
58
+ }
59
+
60
+ public function productAddAfter($observer)
61
+ {
62
+ $quote = Mage::getModel('checkout/session')->getQuote();
63
+ $customer = $quote->getCustomer();
64
+ if (isset($customer)) {
65
+ $billingAddress = $customer->getDefaultBillingAddress();
66
+ if ($billingAddress) {
67
+ if (empty($quote->getTelephone())) {
68
+ $quote->setTelephone($billingAddress->getTelephone());
69
+ }
70
+ if (empty($quote->getCountry())) {
71
+ $quote->setData('country', $billingAddress->getCountryId());
72
+ }
73
+ }
74
+ }
75
+
76
+ Mage::getModel('cartsguru/webservice')->sendAbadonnedCart($quote);
77
+ }
78
+
79
+ /**
80
+ * This method set telephone in session
81
+ */
82
+ public function setTelephoneInSession()
83
+ {
84
+ $telephone = Mage::app()->getRequest()->getParams()['billing']['telephone'];
85
+ Mage::getSingleton("core/session")->setData("telephone", $telephone);
86
+ }
87
+ }
app/code/local/Cartsguru/Model/Sales/Order/Api/V2.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Cartsguru_Model_Sales_Order_Api_V2 extends Mage_Sales_Model_Order_Api_V2 {
4
+
5
+ /**
6
+ * Retrieve full order information
7
+ *
8
+ * @param string $orderIncrementId
9
+ * @return array
10
+ */
11
+ public function info($orderIncrementId)
12
+ {
13
+ $order = $this->_initOrder($orderIncrementId);
14
+
15
+ if ($order->getGiftMessageId() > 0) {
16
+ $message = Mage::getSingleton('giftmessage/message')->load($order->getGiftMessageId());
17
+ $order->setGiftMessage($message->getMessage());
18
+ }
19
+
20
+ $attributes = $this->_getAttributes($order, 'order');
21
+ $attributes['shipping_address'] = $this->_getAttributes($order->getShippingAddress(), 'order_address');
22
+ $attributes['billing_address'] = $this->_getAttributes($order->getBillingAddress(), 'order_address');
23
+ $attributes['payment'] = $this->_getAttributes($order->getPayment(), 'order_payment');
24
+
25
+ $attributes['items'] = array();
26
+ foreach ($order->getAllItems() as $item) {
27
+ if ($item->getGiftMessageId() > 0) {
28
+ $message = Mage::getSingleton('giftmessage/message')->load($item->getGiftMessageId());
29
+ $item->setGiftMessage($message->getMessage());
30
+ }
31
+
32
+ $attributes['items'][] = $this->_getAttributes($item, 'order_item');
33
+ }
34
+
35
+ $attributes['status_history'] = array();
36
+ foreach ($order->getAllStatusHistory() as $history) {
37
+ $attributes['status_history'][] = $this->_getAttributes($history, 'order_status_history');
38
+ }
39
+
40
+ return $attributes;
41
+ }
42
+ }
app/code/local/Cartsguru/Model/Webservice.php ADDED
@@ -0,0 +1,404 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This class using to get api answers
5
+ * Class Cartsguru_Model_Webservice
6
+ */
7
+ class Cartsguru_Model_Webservice
8
+ {
9
+ private $apiBaseUrl = 'https://api.carts.guru';
10
+
11
+ /**
12
+ * If value is empty return ''
13
+ * @param $value
14
+ * @return string
15
+ */
16
+ public function notEmpty($value)
17
+ {
18
+ return ($value)? $value : '';
19
+ }
20
+
21
+ /**
22
+ * This method return order data in cartsguru format
23
+ * @param $order
24
+ * @return array
25
+ */
26
+ public function getOrderData($order)
27
+ {
28
+ $items = array();
29
+ foreach ($order->getAllVisibleItems() as $item) {
30
+ $product=$item->getProduct();
31
+ $product=$product->load($product->getId());
32
+ if($product->getImage() && $product->getImage() != 'no_selection') {
33
+ $imageUrl=(string)Mage::helper('catalog/image')->init($item->getProduct(), 'small_image')
34
+ ->constrainOnly(false)
35
+ ->keepAspectRatio(true)
36
+ ->keepFrame(true)
37
+ ->resize(120, 120);
38
+ }
39
+ else {
40
+ $imageUrl=$this->notEmpty(null);
41
+ }
42
+ $categoryNames = $this->getCatNames($item);
43
+ $items[] = array(
44
+ 'id' => $item->getId(), // SKU or product id
45
+ 'label' => $item->getName(), // Designation
46
+ 'quantity' => (int)$item->getQtyOrdered(), // Count
47
+ 'totalET' => (float)$item->getPrice()*(int)$item->getQtyOrdered(), // Subtotal of item
48
+ 'url' => $item->getProduct()->getProductUrl(), // URL of product sheet
49
+ 'imageUrl' => $imageUrl,
50
+ 'universe' => $categoryNames[1],
51
+ 'category' => end($categoryNames)
52
+ );
53
+ }
54
+
55
+ $gender = 'mister';
56
+ $customer = $order->getCustomer();
57
+ if ($customer && $customer->getGender()) {
58
+ $gender = $customer->getGender();
59
+ }
60
+
61
+ $phone = $order->getTelephone();
62
+ $country = $order->getCountry();
63
+ if (!$accountId = $order->getCustomerId()) {
64
+ $accountId = $order->getCustomerEmail();
65
+ }
66
+
67
+ return array(
68
+ 'siteId' => Mage::getStoreConfig('cartsguru/cartsguru_group/siteid', Mage::app()->getStore()), //Site Id
69
+ 'id' => $order->getIncrementId(), //Order reference, the same display to the buyer
70
+ 'creationDate' => $this->formatDate($order->getCreatedAt()), // Date of the order as string in json format
71
+ 'cartId' => $order->getQuoteId(), // Cart identifier, source of the order
72
+ 'totalET' => (float)$order->getSubtotal(), // Amount excluded taxes and excluded shipping
73
+ 'state' => $this->getStatus($order->getStatus()), // waiting, confirmed, cancelled or error
74
+ 'accountId' => $accountId, // Account id of the buyer
75
+ 'ip' => $order->getRemoteIp(),
76
+ 'civility' => $gender, // Use string in this list : 'mister','madam','miss'
77
+ 'lastname' => $this->notEmpty($order->getBillingAddress()->getLastname()), // Lastname of the buyer
78
+ 'firstname' => $this->notEmpty($order->getBillingAddress()->getFirstname()), // Firstname of the buyer
79
+ 'email' => $this->notEmpty($order->getCustomerEmail()), // Email of the buye
80
+ 'phoneNumber' => $this->notEmpty($phone), // Landline phone number of buyer (internationnal format)
81
+ 'countryCode' => $this->notEmpty($country), // Country code of buyer
82
+ 'items' => $items // Details info
83
+ );
84
+ }
85
+
86
+ /**
87
+ * This method send order data by api
88
+ * @param $order
89
+ */
90
+ public function sendOrder($order)
91
+ {
92
+ $orderData = $this->getOrderData($order);
93
+ if (!empty($orderData)) {
94
+ $this->doPostRequest('/orders', $orderData);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * This method format date in json format
100
+ * @param $date
101
+ * @return bool|string
102
+ */
103
+ protected function formatDate($date)
104
+ {
105
+ return date('Y-m-d\TH:i:sP', strtotime($date));
106
+ }
107
+
108
+ /**
109
+ * This method send data on api path
110
+ * @param $apiPath
111
+ * @param $fields
112
+ * @return Zend_Http_Response
113
+ */
114
+ protected function doPostRequest($apiPath, $fields)
115
+ {
116
+ try {
117
+ $url = $this->apiBaseUrl . $apiPath;
118
+ $client = new Zend_Http_Client($url);
119
+ $client->setHeaders('x-auth-key', Mage::getStoreConfig('cartsguru/cartsguru_group/auth', Mage::app()->getStore()));
120
+ $client->setUri($url);
121
+ $client->setRawData(json_encode($fields), 'application/json');
122
+ $response = $client->request(Zend_Http_Client::POST);
123
+ } catch (Exception $e) {}
124
+
125
+ return $response;
126
+ }
127
+
128
+ /**
129
+ * This method map magento status to api status
130
+ * @param $status
131
+ * @return string
132
+ */
133
+ public function getStatus($status)
134
+ {
135
+ $status_map = array(
136
+ 'processing' => 'confirmed',
137
+ 'pending' => 'confirmed',
138
+ 'pending_payment' => 'waiting',
139
+ 'waiting_authorozation' => 'waiting',
140
+ 'payment_review' => 'confirmed',
141
+ 'fraud' => 'paymentFailure',
142
+ 'holded' => 'error',
143
+ 'complete' => 'confirmed',
144
+ 'closed' => 'confirmed',
145
+ 'canceled' => 'cancelled',
146
+ 'pending_ogone' => 'waiting',
147
+ 'processing_ogone' => 'confirmed',
148
+ 'decline_ogone' => 'paymentFailure',
149
+ 'cancel_ogone' => 'paymentFailure',
150
+ 'pending_paypal' => 'waiting',
151
+ 'paypal_canceled_reversal' => 'paymentFailure',
152
+ 'paypal_reversed' => 'paymentFailure',
153
+ );
154
+
155
+ return isset($status_map[$status])?
156
+ $status_map[$status]
157
+ : $status;
158
+ }
159
+
160
+ /** This method return true if connect to server is ok
161
+ * @return bool
162
+ */
163
+ public function checkAddress()
164
+ {
165
+ $baseUrl = Mage::getBaseUrl() . 'api/rest';
166
+ $fields = array(
167
+ 'plugin' => 'magento',
168
+ 'pluginVersion' => '1.1.0',
169
+ 'storeVersion' => Mage::getVersion()
170
+ );
171
+ $siteId = Mage::getStoreConfig('cartsguru/cartsguru_group/siteid', Mage::app()->getStore());
172
+ $requestUrl = '/sites/' . $siteId . '/register-plugin';
173
+
174
+ $response = $this->doPostRequest($requestUrl, $fields);
175
+ return ($response)?
176
+ ($response->getStatus() == 200)
177
+ : false;
178
+ }
179
+
180
+ /**
181
+ * Get category names
182
+ * @param $item
183
+ * @return array
184
+ */
185
+ public function getCatNames($item)
186
+ {
187
+ $product = $item->getProduct();
188
+ $categoryNames = array();
189
+ $categoryIds = $product->getCategoryIds();
190
+ foreach ($categoryIds as $categoryId) {
191
+ $category = Mage::getModel('catalog/category')->load($categoryId);
192
+ $ids = explode('/', $category->getPath());
193
+ foreach ($ids as $id) {
194
+ $category = Mage::getModel('catalog/category')->load($id);
195
+ $categoryNames[] = $category->getName();
196
+ }
197
+ }
198
+
199
+ if (empty($categoryNames)) {
200
+ $categoryNames = array(
201
+ 0 => $this->notEmpty(null),
202
+ 1 => $this->notEmpty(null)
203
+ );
204
+ }
205
+
206
+ return $categoryNames;
207
+ }
208
+
209
+ /**
210
+ * This method return abounded cart data in cartsguru api format
211
+ * @param $quote
212
+ * @return array|void
213
+ */
214
+ public function getAbadonnedCartData($quote)
215
+ {
216
+ $items = array();
217
+ /** @var Mage_Sales_Model_Quote $quote */
218
+ foreach ($quote->getAllVisibleItems() as $item) {
219
+ $product=$item->getProduct();
220
+ $product=$product->load($product->getId());
221
+ if($product->getImage() && $product->getImage() != 'no_selection') {
222
+ $imageUrl=(string)Mage::helper('catalog/image')->init($item->getProduct(), 'small_image')
223
+ ->constrainOnly(false)
224
+ ->keepAspectRatio(true)
225
+ ->keepFrame(true)
226
+ ->resize(120, 120);
227
+ }
228
+ else {
229
+ $imageUrl=$this->notEmpty(null);
230
+ }
231
+ $categoryNames = $this->getCatNames($item);
232
+ $items[] = array(
233
+ 'id' => (string)$item->getProduct()->getSku(), // SKU or product id
234
+ 'label' => $item->getName(), // Designation
235
+ 'quantity' => (int)$item->getQty(), // Count
236
+ 'totalET' => (float)$item->getPrice()*(int)$item->getQty(), // Subtotal of item
237
+ 'url' => $item->getProduct()->getProductUrl(), // URL of product sheet
238
+ 'imageUrl' => $imageUrl,
239
+ 'universe' => $categoryNames[1],
240
+ 'category' => end($categoryNames)
241
+ );
242
+ }
243
+
244
+ $gender = 'mister';
245
+ if ($quote->getCustomerGender()) {
246
+ $gender = $quote->getCustomerGender();
247
+ }
248
+
249
+ $lastname = $quote->getCustomerLastname();
250
+ $firstname = $quote->getCustomerFirstname();
251
+
252
+ $phone = $quote->getTelephone();
253
+ $country = $quote->getCountry();
254
+
255
+ if (!$items) {
256
+ return;
257
+ }
258
+
259
+ if (!$accountId = $quote->getCustomerId()) {
260
+ $accountId = $quote->getCustomerEmail();
261
+ }
262
+
263
+ if (!$accountId && !$phone) {
264
+ return;
265
+ }
266
+
267
+ $siteId = Mage::getStoreConfig('cartsguru/cartsguru_group/siteid', Mage::app()->getStore());
268
+
269
+ return array(
270
+ 'siteId' => $siteId, //SiteId is part of plugin configuration
271
+ 'id' => $quote->getId(), //Order reference, the same display to the buyer
272
+ 'creationDate' => $this->formatDate($quote->getCreatedAt()), // Date of the order as string in json format
273
+ 'totalET' => (float)$quote->getSubtotal(), // Amount excluded taxes and excluded shipping
274
+ 'accountId' => $accountId, // Account id of the buyer
275
+ 'civility' => $gender, // Use string in this list : 'mister','madam','miss'
276
+ 'ip' => $quote->getRemoteIp(),
277
+ 'lastname' => $this->notEmpty($lastname), // Lastname of the buyer
278
+ 'firstname' => $this->notEmpty($firstname), // Firstname of the buyer
279
+ 'email' => $this->notEmpty($quote->getCustomerEmail()), // Email of the buyer
280
+ 'phoneNumber' => $this->notEmpty($phone), // Landline phone number of buyer (internationnal format)
281
+ 'countryCode' => $this->notEmpty($country),
282
+ 'items' => $items
283
+ );
284
+ }
285
+
286
+ /**
287
+ * This method send abounded cart data
288
+ * @param $quote
289
+ */
290
+ public function sendAbadonnedCart($quote)
291
+ {
292
+ $cartData = $this->getAbadonnedCartData($quote);
293
+ $cache = Mage::app()->getCache();
294
+ $data = $cache->load(md5(json_encode($cartData)));
295
+ if (empty($data)) {
296
+ $cache->save(serialize($cartData), md5(json_encode($cartData)));
297
+ if ($cartData) {
298
+ $this->doPostRequest('/carts', $cartData);
299
+ }
300
+ }
301
+ }
302
+
303
+ /**
304
+ * get customer Firstname
305
+ * @param $customer
306
+ * @return string
307
+ */
308
+ public function getFirstname($customer)
309
+ {
310
+ $firstname = $customer->getFirstname();
311
+ if (!$firstname) {
312
+ $address = $customer->getDefaultBillingAddress();
313
+ if ($address) {
314
+ return $address->getFirstname();
315
+ }
316
+ }
317
+
318
+ return $firstname;
319
+ }
320
+
321
+ /**
322
+ * get customer Lastname
323
+ * @param $customer
324
+ * @return string
325
+ */
326
+ public function getLastname($customer)
327
+ {
328
+ $lastname = $customer->getLastname();
329
+ if (!$lastname) {
330
+ $address = $customer->getDefaultBillingAddress();
331
+ if ($address) {
332
+ return $address->getLastname();
333
+ }
334
+ }
335
+
336
+ return $lastname;
337
+ }
338
+
339
+ /**
340
+ * get customer gender and format it
341
+ * @param $customer
342
+ * @return string
343
+ */
344
+ public function getGender($customer)
345
+ {
346
+ return ($customer->getGender())?
347
+ $customer->getGender()
348
+ : 'mister';
349
+ }
350
+
351
+ /**
352
+ * get customer Phone
353
+ * @param $customer
354
+ * @return string
355
+ */
356
+ public function getPhone($customer)
357
+ {
358
+ $address = $customer->getDefaultBillingAddress();
359
+ return ($address)?
360
+ $address->getPhone()
361
+ : '';
362
+ }
363
+
364
+ /**
365
+ * This method get customer data in cartsguru api format
366
+ * @param $customer
367
+ * @return array
368
+ */
369
+ public function getCustomerData($customer)
370
+ {
371
+ $gender = $this->getGender($customer);
372
+ $lastname = $this->getLastname($customer);
373
+ $firstname = $this->getFirstname($customer);
374
+ $phone = '';
375
+ $country = '';
376
+ $address = Mage::getModel('customer/address')->load($customer->getDefaultBillingAddress());
377
+ if ($address) {
378
+ $phone = $address->getTelephone();
379
+ $country = $address->getCountryId();
380
+ }
381
+
382
+ $siteId = Mage::getStoreConfig('cartsguru/cartsguru_group/siteid', Mage::app()->getStore());
383
+ return array(
384
+ 'siteId' => $siteId, //SiteId is part of plugin configuration
385
+ 'accountId' => $customer->getId(), // Account id of the customer
386
+ 'civility' => $gender, // Use string in this list : 'mister','madam','miss'
387
+ 'lastname' => $this->notEmpty($lastname), // Lastname of the buyer
388
+ 'firstname' => $this->notEmpty($firstname), // Firstname of the buyer
389
+ 'email' => $this->notEmpty($customer->getEmail()), // Email of the customer
390
+ 'phoneNumber' => $this->notEmpty($phone), // Landline phone number of buyer (internationnal format)
391
+ 'countryCode' => $this->notEmpty($country)
392
+ );
393
+ }
394
+
395
+ /**
396
+ * This method send customer data on api
397
+ * @param $customer
398
+ */
399
+ public function sendAccount($customer)
400
+ {
401
+ $customerData = $this->getCustomerData($customer);
402
+ $this->doPostRequest('/accounts', $customerData);
403
+ }
404
+ }
app/code/local/Cartsguru/etc/config.xml ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <!-- plugin name -->
4
+ <modules>
5
+ <Cartsguru>
6
+ <version>1.1.0</version>
7
+ </Cartsguru>
8
+ </modules>
9
+ <global>
10
+ <!--add some attributes for easy send it throw api -->
11
+ <sales>
12
+ <quote>
13
+ <customer_attributes>
14
+ <telephone />
15
+ <country />
16
+ </customer_attributes>
17
+ </quote>
18
+ </sales>
19
+ <fieldsets>
20
+ <sales_convert_quote>
21
+ <country>
22
+ <to_order>*</to_order>
23
+ </country>
24
+ <telephone>
25
+ <to_order>*</to_order>
26
+ </telephone>
27
+ </sales_convert_quote>
28
+ <sales_convert_quote>
29
+ <country>
30
+ <to_order>*</to_order>
31
+ </country>
32
+ <telephone>
33
+ <to_order>*</to_order>
34
+ </telephone>
35
+ </sales_convert_quote>
36
+ <sales_convert_order>
37
+ <country>
38
+ <to_order>*</to_order>
39
+ </country>
40
+ <telephone>
41
+ <to_quote>*</to_quote>
42
+ </telephone>
43
+ </sales_convert_order>
44
+ </fieldsets>
45
+ <models>
46
+ <cartsguru>
47
+ <class>Cartsguru_Model</class>
48
+ <resourceModel>cartsguru_resource</resourceModel>
49
+ </cartsguru>
50
+ <cartsguru_resource>
51
+ <class>Cartsguru_Model_Resource</class>
52
+ </cartsguru_resource>
53
+ <!--add rewrite base class for extend it -->
54
+ <sales>
55
+ <rewrite>
56
+ <order_api_v2>Cartsguru_Model_Sales_Order_Api_V2</order_api_v2>
57
+ </rewrite>
58
+ </sales>
59
+ </models>
60
+ <blocks>
61
+ <cartsguru>
62
+ <class>Cartsguru_Block</class>
63
+ </cartsguru>
64
+ </blocks>
65
+ <helpers>
66
+ <cartsguru>
67
+ <class>Cartsguru_Helper</class>
68
+ </cartsguru>
69
+ </helpers>
70
+ <resources>
71
+ <cartsguru_setup>
72
+ <setup>
73
+ <module>Cartsguru</module>
74
+ </setup>
75
+ </cartsguru_setup>
76
+ </resources>
77
+ <!--In this section we register hooks call api-->
78
+ <events>
79
+ <admin_system_config_changed_section_cartsguru>
80
+ <observers>
81
+ <cartsguru_admin_system_config_changed_section_cartsguru>
82
+ <type>singleton</type>
83
+ <class>cartsguru/observer</class>
84
+ <method>configSaveAfter</method>
85
+ </cartsguru_admin_system_config_changed_section_cartsguru>
86
+ </observers>
87
+ </admin_system_config_changed_section_cartsguru>
88
+ <sales_order_place_after>
89
+ <observers>
90
+ <cartsguru_sales_order_save_after>
91
+ <type>singleton</type>
92
+ <class>cartsguru/observer</class>
93
+ <method>orderSaveAfter</method>
94
+ </cartsguru_sales_order_save_after>
95
+ </observers>
96
+ </sales_order_place_after>
97
+ <sales_order_saves_after>
98
+ <observers>
99
+ <cartsguru_sales_order_save_after>
100
+ <type>singleton</type>
101
+ <class>cartsguru/observer</class>
102
+ <method>orderSaveAfter</method>
103
+ </cartsguru_sales_order_save_after>
104
+ </observers>
105
+ </sales_order_saves_after>
106
+ <!-- when customer register this hooks call two times-->
107
+ <customer_save_after>
108
+ <observers>
109
+ <cartsguru_customer_save_after>
110
+ <type>singleton</type>
111
+ <class>cartsguru/observer</class>
112
+ <method>customerSaveAfter</method>
113
+ </cartsguru_customer_save_after>
114
+ </observers>
115
+ </customer_save_after>
116
+ <customer_register_success>
117
+ <observers>
118
+ <cartsguru_customer_register_success>
119
+ <type>singleton</type>
120
+ <class>cartsguru/observer</class>
121
+ <method>customerSaveAfter</method>
122
+ </cartsguru_customer_register_success>
123
+ </observers>
124
+ </customer_register_success>
125
+ <sales_quote_remove_item>
126
+ <observers>
127
+ <cartsguru_sales_quote_remove_item>
128
+ <type>singleton</type>
129
+ <class>cartsguru/observer</class>
130
+ <method>productAddAfter</method>
131
+ </cartsguru_sales_quote_remove_item>
132
+ </observers>
133
+ </sales_quote_remove_item>
134
+ <checkout_cart_product_add_after>
135
+ <observers>
136
+ <cartsguru_cart_product_add_after>
137
+ <type>singleton</type>
138
+ <class>cartsguru/observer</class>
139
+ <method>productAddAfter</method>
140
+ </cartsguru_cart_product_add_after>
141
+ </observers>
142
+ </checkout_cart_product_add_after>
143
+ <sales_quote_save_before>
144
+ <observers>
145
+ <cartsguru_sales_quote_save_before>
146
+ <type>singleton</type>
147
+ <class>cartsguru/observer</class>
148
+ <method>quoteSaveBefore</method>
149
+ </cartsguru_sales_quote_save_before>
150
+ </observers>
151
+ </sales_quote_save_before>
152
+ <sales_quote_save_after>
153
+ <observers>
154
+ <cartsguru_sales_quote_save_after>
155
+ <type>singleton</type>
156
+ <class>cartsguru/observer</class>
157
+ <method>productAddAfter</method>
158
+ </cartsguru_sales_quote_save_after>
159
+ </observers>
160
+ </sales_quote_save_after>
161
+ <customer_login>
162
+ <observers>
163
+ <customer_login>
164
+ <type>singleton</type>
165
+ <class>cartsguru/observer</class>
166
+ <method>productAddAfter</method>
167
+ </customer_login>
168
+ </observers>
169
+ </customer_login>
170
+ </events>
171
+ </global>
172
+ <frontend>
173
+ <routers>
174
+ <webservice>
175
+ <use>standard</use>
176
+ <args>
177
+ <frontName>webservice</frontName>
178
+ <module>Cartsguru</module>
179
+ </args>
180
+ </webservice>
181
+ </routers>
182
+ </frontend>
183
+ <adminhtml>
184
+ <translate>
185
+ <modules>
186
+ <translations>
187
+ <files>
188
+ <default>CartsGuru.csv</default>
189
+ </files>
190
+ </translations>
191
+ </modules>
192
+ </translate>
193
+ <acl>
194
+ <!-- in this section we add acl for admin settings -->
195
+ <resources>
196
+ <all>
197
+ <title>Allow Everything</title>
198
+ </all>
199
+ <admin>
200
+ <children>
201
+ <system>
202
+ <children>
203
+ <config>
204
+ <children>
205
+ <cartsguru>
206
+ <title>Cartsguru - All</title>
207
+ </cartsguru>
208
+ </children>
209
+ </config>
210
+ </children>
211
+ </system>
212
+ </children>
213
+ </admin>
214
+ </resources>
215
+ </acl>
216
+ </adminhtml>
217
+ </config>
app/code/local/Cartsguru/etc/system.xml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <cartsguru module="cartsguru">
5
+ <label>Carts Guru</label>
6
+ <sort_order>100</sort_order>
7
+ </cartsguru>
8
+ </tabs>
9
+ <sections>
10
+ <cartsguru translate="label" module="cartsguru">
11
+ <label>Extension Options</label>
12
+ <tab>cartsguru</tab>
13
+ <sort_order>1000</sort_order>
14
+ <show_in_default>1</show_in_default>
15
+ <show_in_website>1</show_in_website>
16
+ <show_in_store>1</show_in_store>
17
+
18
+ <groups>
19
+ <cartsguru_group translate="label" module="cartsguru">
20
+ <label>Extension Options</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>1000</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+
27
+ <fields>
28
+ <auth translate="label">
29
+ <label>API auth key</label>
30
+ <frontend_type>text</frontend_type>
31
+ <sort_order>20</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </auth>
36
+ <siteid translate="label">
37
+ <label>Site Id</label>
38
+ <frontend_type>text</frontend_type>
39
+ <sort_order>20</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ </siteid>
44
+ </fields>
45
+ </cartsguru_group>
46
+ </groups>
47
+ </cartsguru>
48
+ </sections>
49
+ </config>
app/code/local/Cartsguru/sql/cartsguru_setup/install-1.0.0.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Mage_Core_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+ $connection = $installer->getConnection();
7
+
8
+ $connection->addColumn($this->getTable('sales_flat_quote'), 'telephone', 'varchar(255) NOT NULL');
9
+ $connection->addColumn($this->getTable('sales_flat_order'), 'telephone', 'varchar(255) NOT NULL');
10
+
11
+ $connection->addColumn($this->getTable('sales_flat_quote'), 'country', 'varchar(255) NOT NULL');
12
+ $connection->addColumn($this->getTable('sales_flat_order'), 'country', 'varchar(255) NOT NULL');
13
+
14
+ $setup = Mage::getModel('customer/entity_setup', 'core_setup');
15
+
16
+ $installer_core= new Mage_Sales_Model_Resource_Setup('core_setup');
17
+ $installer_core->addAttribute('catalog_product', 'telephone', array(
18
+ 'group' => 'General',
19
+ 'type' => Varien_Db_Ddl_Table::TYPE_VARCHAR,
20
+ 'backend' => '',
21
+ 'frontend' => '',
22
+ 'label' => 'Telephone',
23
+ 'input' => 'text',
24
+ 'class' => '',
25
+ 'source' => '',
26
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
27
+ 'visible' => true,
28
+ 'required' => false,
29
+ 'user_defined' => true,
30
+ 'default' => '',
31
+ 'searchable' => true,
32
+ 'filterable' => true,
33
+ 'comparable' => true,
34
+ 'visible_on_front' => true,
35
+ 'unique' => false,
36
+ 'apply_to' => 'simple,configurable,virtual',
37
+ 'is_configurable' => false
38
+ ));
39
+
40
+ /**
41
+ * Add 'custom_attribute' attribute for entities
42
+ */
43
+ $entities = array(
44
+ 'quote',
45
+ 'quote_address',
46
+ 'quote_item',
47
+ 'quote_address_item',
48
+ 'order',
49
+ 'order_item'
50
+ );
51
+ $options = array(
52
+ 'type' => Varien_Db_Ddl_Table::TYPE_VARCHAR,
53
+ 'visible' => true,
54
+ 'required' => false
55
+ );
56
+ foreach ($entities as $entity) {
57
+ $installer_core->addAttribute($entity, 'telephone', $options);
58
+ }
59
+ $setup->endSetup();
60
+ $installer_core->endSetup();
61
+ $installer->endSetup();
app/etc/modules/Cartsguru.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Cartsguru>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Cartsguru>
8
+ </modules>
9
+ </config>
app/locale/en_US/CartsGuru.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ "Extension Options","Extension Options"
2
+ "API auth key","API auth key"
3
+ "Site Id","Site Id"
app/locale/fr_FR/CartsGuru.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ "Extension Options","Options"
2
+ "API auth key","Clef d'authentification"
3
+ "Site Id","Identifiant du site"
package.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>cartsguru</name>
4
+ <version>1.1.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/gpl-license.php">GPL</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>The first targeted and automated follow-up solution for abandoned carts through phone and text message !</summary>
10
+ <description>There is a way to transform those abandoned shopping carts into sales !&#xD;
11
+ &#xD;
12
+ Carts Guru enable you to establish automatic contact with your prospective customers who did not finalize their purchase.&#xD;
13
+ &#xD;
14
+ Targets your abandoned shopping carts, define your rules and run actions automatically thought phone and SMS&#xD;
15
+ &#xD;
16
+ - Automatic call &#xD;
17
+ Effortlessly reduce the number of abandoned shopping carts by automating telephone contact between your salespeople and the customers who have just left your site&#xD;
18
+ &#xD;
19
+ - SMS Callback &amp;amp; Push SMS&#xD;
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 imageUrl in sent data&#xD;
22
+ - Improve manangment of order state</notes>
23
+ <authors><author><name>Maxime Pruvost</name><user>cgmaximepruvost</user><email>maxime@carts.guru</email></author></authors>
24
+ <date>2016-02-17</date>
25
+ <time>14:02:51</time>
26
+ <contents><target name="magelocal"><dir name="Cartsguru"><dir name="Helper"><file name="Data.php" hash="f6590d08ba862a169ce43459ddb1193c"/></dir><dir name="Model"><file name="Observer.php" hash="9fddb0f5bac304236535c31f1bb251ed"/><dir name="Sales"><dir name="Order"><dir name="Api"><file name="V2.php" hash="a3b05d6f3931a1be1b2e92618095a123"/></dir></dir></dir><file name="Webservice.php" hash="681b23097ed3519796ebe51b2d6719c0"/></dir><dir name="etc"><file name="config.xml" hash="de2ae20e593abde887fa77ee50e8cdb1"/><file name="system.xml" hash="cb0fbf86d2be47dbd719739ee79c4cba"/></dir><dir name="sql"><dir name="cartsguru_setup"><file name="install-1.0.0.php" hash="c46126ce8ce549d525fb25bddc5090b5"/></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>