Poq_Integration - Version 2.0.0.2.4

Version Notes

- Minor bug fixes.
- Product description and barcode fields configuration added.

Download this release

Release Info

Developer Oyvind Henriksen
Extension Poq_Integration
Version 2.0.0.2.4
Comparing to
See all releases


Code changes from version 2.0.0.2.3 to 2.0.0.2.4

app/code/community/Poq/Integration/Helper/Data.php CHANGED
@@ -79,6 +79,26 @@ class Poq_Integration_Helper_Data extends Mage_Core_Helper_Data {
79
  */
80
  public $send_order_emails;
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * Get settings
84
  */
@@ -116,11 +136,20 @@ class Poq_Integration_Helper_Data extends Mage_Core_Helper_Data {
116
 
117
  // Get safe referer list
118
  $this->safe_referer_list = Mage::getStoreConfig('integration/integration_checkoutsecurity_group/integration_checkout_safereferrerlist_input', Mage::app()->getStore());
119
- $this->safe_referer_list = explode(',', $this->safe_referer_list);
120
 
121
  // Get tracking code
122
  $this->tracking_code = Mage::getStoreConfig('integration/integration_checkout_group/integration_checkout_trackingcode_input', Mage::app()->getStore());
123
 
 
 
 
 
 
 
 
 
 
124
  // return settings
125
  return $this;
126
  }
79
  */
80
  public $send_order_emails;
81
 
82
+ /**
83
+ * Description Field Names
84
+ * @var string
85
+ */
86
+ public $description_fields;
87
+
88
+ /**
89
+ * Description Headers
90
+ * @var string
91
+ */
92
+ public $description_values;
93
+
94
+
95
+ /**
96
+ * Description Headers
97
+ * @var string
98
+ */
99
+ public $barcode_field;
100
+
101
+
102
  /**
103
  * Get settings
104
  */
136
 
137
  // Get safe referer list
138
  $this->safe_referer_list = Mage::getStoreConfig('integration/integration_checkoutsecurity_group/integration_checkout_safereferrerlist_input', Mage::app()->getStore());
139
+ $this->safe_referer_list = split(',', $this->safe_referer_list);
140
 
141
  // Get tracking code
142
  $this->tracking_code = Mage::getStoreConfig('integration/integration_checkout_group/integration_checkout_trackingcode_input', Mage::app()->getStore());
143
 
144
+ // Get description field names
145
+ $this->description_fields = Mage::getStoreConfig('integration/integration_feed_group/integration_feed_description_fields', Mage::app()->getStore());
146
+
147
+ // Get description values
148
+ $this->description_values = Mage::getStoreConfig('integration/integration_feed_group/integration_feed_description_values', Mage::app()->getStore());
149
+
150
+ // Get barcode field name
151
+ $this->barcode_field = Mage::getStoreConfig('integration/integration_feed_group/integration_feed_barcode_field', Mage::app()->getStore());
152
+
153
  // return settings
154
  return $this;
155
  }
app/code/community/Poq/Integration/controllers/IndexController.php CHANGED
@@ -1,776 +1,843 @@
1
- <?php
2
-
3
- /**
4
- * Poq Integration model
5
- *
6
- * @author Poq Studio
7
- */
8
- class Poq_Integration_IndexController extends Mage_Core_Controller_Front_Action
9
- {
10
-
11
- /**
12
- * Info page for checking extension status
13
- */
14
- public function indexAction()
15
- {
16
-
17
- echo "Poq Studio";
18
-
19
- // Show settings
20
- //Set CSV content type
21
- if ($_GET['debug'] == '1')
22
- {
23
- // Get extension settings
24
- $settings = Mage::helper('poq_integration')->getSettings();
25
- var_dump($settings);
26
- }
27
- }
28
-
29
- /**
30
- * Gets all categories indexed by id
31
- * @return array
32
- */
33
- private function getCategories()
34
- {
35
- // Init category name and url arrays indexed by id
36
- $activeCategorNamesById = array();
37
- $activeCategoryUrlsById = array();
38
-
39
- // Composite category array
40
- $categories = array();
41
-
42
- // Load all categories (flat)
43
- $activeCategoryCollection = Mage::getModel('catalog/category')
44
- ->getCollection()
45
- ->addAttributeToSelect('*');
46
-
47
- // Load all categories (tree)
48
- $categoriesArray = Mage::getModel('catalog/category')
49
- ->getCollection()
50
- ->addAttributeToSelect('name')
51
- ->addAttributeToSort('path', 'asc')
52
- ->load()
53
- ->toArray();
54
-
55
- // Expose category name and urls and index by id
56
- foreach ($activeCategoryCollection as $activeCategory)
57
- {
58
- $activeCategorNamesById[$activeCategory->getId()] = $activeCategory->getName();
59
- $activeCategoryUrlsById[$activeCategory->getId()] = $activeCategory->getUrl();
60
- }
61
-
62
-
63
- // Find root category
64
- $rootCategory = array();
65
- foreach ($categoriesArray as $category)
66
- {
67
- if ($category['level'] == 1)
68
- {
69
- $rootCategory = $category;
70
- break;
71
- }
72
- }
73
-
74
-
75
- // Expose composite category data
76
- foreach ($categoriesArray as $categoryId => $category)
77
- {
78
- // Check if category is not at root category level
79
- if (isset($category['name']) && isset($category['level']) && $category['level'] > $rootCategory['level'])
80
- {
81
-
82
- // Remove root category path from category
83
- $path = str_replace($rootCategory['path'] . '/', '', $category['path']);
84
-
85
- // Explode parent categories
86
- $parents = explode('/', $path);
87
- $name = '';
88
- $url = '';
89
-
90
- // Get category name and urls for each parent
91
- foreach ($parents as $parent)
92
- {
93
- $name .= $activeCategorNamesById[$parent] . '>';
94
- $url .= $activeCategoryUrlsById[$parent] . '>';
95
- }
96
-
97
- // Get products in category with their positions
98
- $currentCategory = Mage::getModel('catalog/category')->load($categoryId);
99
- $collection = $currentCategory->getProductCollection()->addAttributeToSort('position');
100
- Mage::getModel('catalog/layer')->prepareProductCollection($collection);
101
-
102
- // Index category data
103
- $categories[$categoryId] = array(
104
- 'name' => substr($name, 0, -1),
105
- 'level' => $category['level'],
106
- 'ids' => str_replace('/', '>', $path),
107
- 'url' => substr($url, 0, -1),
108
- 'id' => $categoryId,
109
- 'products' => $currentCategory->getProductsPosition()
110
- );
111
- }
112
- }
113
-
114
- return $categories;
115
- }
116
-
117
- public function showcategoriesAction()
118
- {
119
- var_dump($this->getCategories());
120
- }
121
-
122
- /**
123
- * Create csv feed file with respecto extension settings
124
- */
125
- public function feedAction()
126
- {
127
-
128
- // Get extension settings
129
-
130
- try
131
- {
132
-
133
- $settings = Mage::helper('poq_integration')->getSettings();
134
- }
135
- catch (Exception $e)
136
- {
137
- echo "An error occured while getting integration settings.";
138
- }
139
-
140
-
141
- // Check null values for the first time extension installed
142
- if (is_null($settings->store_id))
143
- {
144
- $settings->store_id = Mage::app()->getStore()->getStoreId();
145
- }
146
- else if (empty($settings->store_id))
147
- {
148
-
149
- $settings->store_id = Mage::app()->getStore()->getStoreId();
150
- }
151
-
152
- if (is_null($settings->image_base_url))
153
- {
154
- $settings->image_base_url = "";
155
- }
156
-
157
- if (is_null($settings->image_ignore_string))
158
- {
159
- $settings->image_ignore_string = "";
160
- }
161
-
162
- try
163
- {
164
-
165
-
166
-
167
- $store_id = $settings->store_id;
168
- $image_base_url = $settings->image_base_url;
169
- $image_ignore_strings = $settings->image_ignore_string;
170
- $tax_rates_enabled = $settings->tax_enabled;
171
-
172
- //Set CSV content type
173
- if ($_GET['debug'] == '1')
174
- {
175
- header("Content-type: text/plain");
176
- }
177
- else
178
- {
179
- header("Content-type: text/csv");
180
- header("Content-Disposition: attachment; filename=feed.csv");
181
- }
182
- header("Pragma: no-cache");
183
- header("Expires: 0");
184
-
185
-
186
- // Init product attribute arrays
187
- $productSizeDescriptions = array();
188
- $parentProductIds = array();
189
- $productColors = array();
190
-
191
-
192
- // Attribute label configurations
193
- // These can be moved to integration settings
194
- // They always be lowercase for code convention
195
- $colorAttributeLabel = "color";
196
- $sizeAttributeLabel = "size";
197
-
198
- $conn = Mage::getSingleton('core/resource')->getConnection('core_setup');
199
- $collection = Mage::getModel('catalog/product')->getCollection()
200
- ->joinField(
201
- 'qty', 'cataloginventory/stock_item', 'qty', 'product_id=entity_id', '{{table}}.stock_id=1', 'left'
202
- )
203
- ->addAttributeToFilter('status', 1) // enabled
204
- ->addUrlRewrite()
205
- ->addPriceData()
206
- ->addStoreFilter($store_id)
207
- ->addAttributeToSelect('*');
208
- Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($collection);
209
- Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
210
- $collection->setOrder('sku', 'desc');
211
-
212
- if ($_GET['debug'] == '1')
213
- {
214
- //only get the first hundred rows, useful for faster testing. Also enable profiler, so we can see performance data.
215
- $collection->setPageSize(200)->setCurPage(1);
216
- $conn->getProfiler()->setEnabled(true);
217
- echo $collection->getSelect()->__toString() . "\n\n";
218
- }
219
-
220
- //Read the dataset into memory
221
- $collection->load();
222
-
223
- //Preload the media_gallery image data into memory
224
- //For use with Option #1 below
225
- $_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
226
- $_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
227
-
228
- // Get media gallery table name
229
- $mediaGalleryTableName = Mage::getSingleton('core/resource')->getTableName('catalog_product_entity_media_gallery');
230
- $mediaGalleryValueTableName = Mage::getSingleton('core/resource')->getTableName('catalog_product_entity_media_gallery_value');
231
-
232
- if ($_GET['debug'] == '1')
233
- {
234
- var_dump($mediaGalleryTableName);
235
- var_dump($mediaGalleryValueTableName);
236
- }
237
- $_mediaGalleryData = $_read->fetchAll('SELECT
238
- main.entity_id, `main`.`value_id`, `main`.`value` AS `file`,
239
- `value`.`label`, `value`.`position`, `value`.`disabled`, `default_value`.`label` AS `label_default`,
240
- `default_value`.`position` AS `position_default`,
241
- `default_value`.`disabled` AS `disabled_default`
242
- FROM ' . $mediaGalleryTableName . ' AS `main`
243
- LEFT JOIN ' . $mediaGalleryValueTableName . ' AS `value`
244
- ON main.value_id=value.value_id AND value.store_id=' . $store_id . '
245
- LEFT JOIN ' . $mediaGalleryValueTableName . ' AS `default_value`
246
- ON main.value_id=default_value.value_id AND default_value.store_id=0
247
- WHERE (
248
- main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
249
- AND (main.entity_id IN (' . $_read->quote($collection->getAllIds()) . '))
250
- ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC
251
- ');
252
- $_mediaGalleryByProductId = array();
253
- foreach ($_mediaGalleryData as $_galleryImage)
254
- {
255
- $k = $_galleryImage['entity_id'];
256
- unset($_galleryImage['entity_id']);
257
- if (!isset($_mediaGalleryByProductId[$k]))
258
- {
259
- $_mediaGalleryByProductId[$k] = array();
260
- }
261
- $_mediaGalleryByProductId[$k][] = $_galleryImage;
262
- }
263
- unset($_mediaGalleryData);
264
- foreach ($collection as &$_product)
265
- {
266
- $_productId = $_product->getData('entity_id');
267
- if (isset($_mediaGalleryByProductId[$_productId]))
268
- {
269
- $_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
270
- }
271
- }
272
- unset($_mediaGalleryByProductId);
273
-
274
-
275
- // End of media_gallery queries for Option #1
276
- //Go through configurable products, and preload data into $parentProductIds and $productSizeDescriptions
277
- foreach ($collection as $product)
278
- {
279
- if ($product->getTypeId() == "configurable")
280
- {
281
-
282
- //Get list of related sub-products
283
- $productids = $product->getTypeInstance()->getUsedProductIds();
284
- foreach ($productids as $productid)
285
- {
286
- $parentProductIds[$productid] = $product->getId(); //Add to array of related products, so we can look up when we loop through the main products later.
287
- }
288
-
289
- // Collect options applicable to the configurable product
290
- $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($product);
291
-
292
- // Get all attributes of the super products
293
- $productAttributeOptions = $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
294
-
295
- // Group attributes of children products
296
- foreach ($productAttributeOptions as $productAttribute)
297
- {
298
-
299
- $code = $productAttribute["attribute_code"];
300
-
301
- // Find attribute contains "color"
302
- if (strpos($code, $colorAttributeLabel) !== false)
303
- {
304
- // Get children products used attribute code
305
- $col = $conf->getUsedProductCollection()->addAttributeToSelect($code)->addFilterByRequiredOptions();
306
- foreach ($col as $simple_product)
307
- {
308
- $productColors[$simple_product->getId()] = $simple_product->getAttributeText($code);
309
- }
310
- }
311
-
312
-
313
- // Find attribute contains "size"
314
- if (strpos($code, $sizeAttributeLabel) !== false)
315
- {
316
- // Get children products used attribute code
317
- $col = $conf->getUsedProductCollection()->addAttributeToSelect($code)->addFilterByRequiredOptions();
318
- foreach ($col as $simple_product)
319
- {
320
- $productSizeDescriptions[$simple_product->getId()] = $simple_product->getAttributeText($code);
321
- }
322
- }
323
- }
324
- }
325
- }
326
-
327
- // Get all active categories
328
- $categories = $this->getCategories();
329
-
330
-
331
-
332
- //Add one line of headers above the actual content.
333
- echo "\"id\"";
334
- echo ",\"name\"";
335
- echo ",\"description\"";
336
- echo ",\"ean\"";
337
- echo ",\"price\"";
338
- echo ",\"specialprice\"";
339
- echo ",\"parentproductid\"";
340
- echo ",\"sku\"";
341
- echo ",\"isinstock\"";
342
- echo ",\"quantity\"";
343
- echo ",\"size\"";
344
- echo ",\"color\"";
345
- echo ",\"colorGroupId\"";
346
- echo ",\"productURL\"";
347
- echo ",\"pictureurls\"";
348
- echo ",\"categoryid\"";
349
- echo ",\"categoryname\"";
350
- echo ",\"categoryurl\"";
351
- echo ",\"categorysortindex\"";
352
- echo "\n";
353
-
354
- // Get tax rates if enabled
355
- $tax_classes;
356
-
357
- if ($tax_rates_enabled)
358
- {
359
-
360
- // Get all tax classes with their values
361
- $tax_classes = Mage::helper('tax')->getAllRatesByProductClass();
362
- }
363
-
364
- //Loop through the products, get the values and write them in CSV format
365
- foreach ($collection as $product)
366
- {
367
-
368
- $description = strip_tags($product->getDescription()); //Remove HTML tags from the description
369
- $description = addslashes($description); //Escape quotes etc from the text
370
- $description = preg_replace('#\s{2,}#', '\\n', $description); //Remove line breaks, "\\n" will be put back in as line breaks when importing.
371
- //$description = preg_replace('/(?<!,)"(?!,)/', '""', $description); //double up any double quote that is not immediately preceded or followed by a comma
372
- $description = preg_replace('/\"/', '""', $description); //double up any double quote
373
-
374
- echo "\"" . $product->getId() . "\"";
375
- echo ",\"" . addslashes($product->getName()) . "\"";
376
- echo ",\"" . $description . "\"";
377
-
378
- // get barcode of product and expose it as ean
379
- $barcode = $product->getData('barcode');
380
- echo ",\"" .$barcode. "\"";
381
-
382
- // Original price might have been tax rates applied on live site
383
- // Fix by macromania
384
- //echo ",\"" . $product->getPrice() . "\""; )
385
- try
386
- {
387
-
388
- // Original price without tax
389
- $product_price = $product->getPrice();
390
- $special_price = $product->getFinalPrice();
391
-
392
- if ($tax_rates_enabled)
393
- {
394
-
395
- // Get product tax class id
396
- $tax_class_id = $_product->getData('tax_class_id');
397
-
398
- // $tax_classes is returned as string. So parsing is needed to get the value
399
- // an example $tax_classes could be like {"value_2":20,"value_4":20,"value_5":20,"value_6":0,"value_7":5}
400
- $tax_classes = str_replace('{', '', $tax_classes);
401
- $tax_classes = str_replace('}', '', $tax_classes);
402
- $tax_class_value_array = explode(',', $tax_classes);
403
-
404
- // Tax value
405
- $product_tax_value = 0;
406
-
407
- foreach ($tax_class_value_array as $tax_class)
408
- {
409
-
410
- $values = explode(':', $tax_class);
411
- if ($values[0] == '"value_' . $tax_class_id . '"')
412
- {
413
- // Get the rate
414
- $product_tax_value = $values[1];
415
- }
416
- }
417
-
418
- // Apply tax rate
419
- if ($product_tax_value > 0)
420
- {
421
- $product_price += $product_price * $product_tax_value / 100;
422
- $special_price += $special_price * $product_tax_value / 100;
423
- }
424
-
425
- echo ",\"" . ceil($product_price) . "\"";
426
- echo ",\"" . ceil($special_price) . "\"";
427
- }
428
- else
429
- {
430
- echo ",\"" . $product_price . "\"";
431
- echo ",\"" . $special_price . "\"";
432
- }
433
-
434
-
435
-
436
- //echo '<p style="color:red">------<br/>Caught exception: ', ceil($product_price),'----',$product->getPrice(), '<br/>-----</p>';
437
- }
438
- catch (Exception $eproductprice)
439
- {
440
- echo '<p style="color:red">------<br/>Caught exception: ', $e2->getMessage(), '<br/>-----</p>';
441
- }
442
-
443
-
444
- // Parent product id
445
- $parentProductIdCombined = $parentProductIds[$product->getId()];
446
- if ($productColors[$product->getId()])
447
- {
448
- if (!empty($productColors[$product->getId()]))
449
- {
450
- $parentProductIdCombined .= "-" . $productColors[$product->getId()];
451
- }
452
- }
453
-
454
-
455
- echo ",\"" . $parentProductIdCombined . "\"";
456
-
457
- // SKU
458
- echo ",\"" . $product->getSku() . "\"";
459
-
460
- // Stock
461
- echo ",\"" . $product->getStockItem()->getIsInStock() . "\"";
462
-
463
- // Stock Quantity
464
- echo ",\"" . $product->getQty() . "\"";
465
-
466
- // Size
467
- echo ",\"" . $productSizeDescriptions[$product->getId()] . "\"";
468
-
469
- // Color name
470
- echo ",\"" . $productColors[$product->getId()] . "\"";
471
-
472
- // Color group id
473
- echo ",\"" . $parentProductIds[$product->getId()] . "\"";
474
-
475
-
476
- if ($product->getVisibility() == 4)
477
- { //Only products that are individually visible need URLs, pictures, categories.
478
- //Get product URL
479
- echo ",\"" . $product->getProductUrl() . "\"";
480
-
481
- //Get main image
482
- $imageString = $product->getMediaConfig()->getMediaUrl($product->getData('image'));
483
-
484
- //attempt to audo-detect base image url, if necessary
485
- if ($image_base_url == '')
486
- {
487
- $image_base_url = substr($imageString, 0, strrpos($imageString, 'media/catalog/product')) . 'media/catalog/product';
488
- }
489
-
490
- //Option #1 - Fast way to get all media gallery images from preloaded array
491
- $_images = $product->getData('media_gallery');
492
- foreach ($_images as $imagegallery)
493
- {
494
- foreach ($imagegallery as $add_image)
495
- {
496
-
497
- //Check if image should be filtered.
498
- $image_should_be_added = true;
499
- if ($image_ignore_strings != '')
500
- {
501
- //echo "\n image_ignore_strings: " . $image_ignore_strings;
502
- $image_ignore_string_array = explode(",", $image_ignore_strings);
503
- foreach ($image_ignore_string_array as $image_ignore_string)
504
- {
505
- //echo "\n image_ignore_string: " . $image_ignore_string;
506
- if (strpos($add_image['file'], $image_ignore_string) !== false)
507
- {
508
- //echo "\n IGNORING: " . $add_image['file'];
509
- $image_should_be_added = false;
510
- }
511
- }
512
- }
513
- if ($image_should_be_added)
514
- {
515
- $imageString .= ',' . $image_base_url . $add_image['file'];
516
- }
517
- }
518
- }
519
-
520
- //Option #2 - Slower, but more reliable way to get all images. Try this is option #1 does not run
521
- // $_images = Mage::getModel('catalog/product')->load($product->getId())->getMediaGalleryImages();
522
- // foreach ($_images as $imagegallery) {
523
- // $imageString .= ';' . $imagegallery['url'];
524
- // }
525
- echo ",\"" . $imageString . "\"";
526
-
527
-
528
-
529
- //List the categories this product should be listed in
530
- $cats = $product->getCategoryIds();
531
- $category_id_list = "";
532
- $category_name_list = "";
533
- $category_url_list = "";
534
- $category_sort_list = "";
535
-
536
- foreach ($cats as $category_id)
537
- {
538
- $category_id_list .= $categories[$category_id]['ids'] . ';';
539
- $category_name_list .= $categories[$category_id]['name'] . ';';
540
- $category_url_list .= $categories[$category_id]['url'] . ';';
541
-
542
- // Check if this category has products
543
-
544
- if (count($categories[$category_id]['products']) > 0)
545
- {
546
- $category_sort_list .= $categories[$category_id]['products'][$product->getId()] . ';';
547
- }
548
- }
549
-
550
- $category_id_list = substr($category_id_list, 0, -1);
551
- $category_name_list = substr($category_name_list, 0, -1);
552
- $category_url_list = substr($category_url_list, 0, -1);
553
- $category_sort_list = substr($category_sort_list, 0, -1);
554
-
555
-
556
- echo ",\"" . $category_id_list . "\"";
557
- echo ",\"" . $category_name_list . "\"";
558
- echo ",\"" . $category_url_list . "\"";
559
- echo ",\"" . $category_sort_list . "\"";
560
- }
561
- echo "\n";
562
- }
563
- if ($_GET['debug'] == '1')
564
- { //Show performance data
565
- echo "\n\n\n" . Varien_Profiler::getSqlProfiler($conn);
566
- }
567
- }
568
- catch (Exception $ex)
569
- {
570
- var_dump($settings);
571
- var_dump($ex);
572
- }
573
- }
574
-
575
- public function cartAction()
576
- {
577
-
578
- //Configuration values
579
- $next_url = '/checkout/'; //After the product are added, redirect to this url.
580
- $require_https = false; //SSL-encrypted requests cannot be read by anyone else, and will not be stored in history etc.
581
- $require_signed_request = false; //If enabled, will require the request to be signed, we can verify that the URL has not been tampered with.
582
- $signed_request_secret = ''; //Get this configuration value from Poq Studio
583
- $limit_referer = false; //Enable this to require the request to come from our trusted source. Also makes it difficult to URL hack and investigate
584
- $safe_referer_list = array("poqstudio.com", "cloudapp.net"); //add mobile website domains here, leave cloudapp.net and poqstudio.com.
585
- $tracking_code = "utm_source=mobile&utm_campaign=poq"; //If set, will be added to the checkout page URL.
586
- //End of configuration values
587
-
588
- header("Pragma: no-cache");
589
- header("Expires: 0");
590
- $session = Mage::getSingleton('core/session', array('name' => 'frontend'));
591
-
592
- //Security check #1 - make sure reference id is set and has a decent format
593
- $reference_id = $_GET['reference_id'];
594
- if (empty($reference_id))
595
- {
596
- die("Invalid request. Error 1001.");
597
- }
598
- else if (!strpos($reference_id, '-'))
599
- {
600
- die("Invalid request. Error 1002.");
601
- }
602
- $session->setPoqReferenceId($reference_id); //Save reference ID in session, for cross-tracking
603
- //Security Check #2 - is the request SSL-encrypted?
604
- if ($require_https)
605
- {
606
- $is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443);
607
- if (!$is_https)
608
- {
609
- die("Invalid request. Error 2001.");
610
- }
611
- }
612
-
613
- //Security Check #3 - is the referer from poqstudio.com?
614
- if ($limit_referer)
615
- {
616
- $http_referer = $_SERVER['HTTP_REFERER'];
617
- $is_from_safe_referer = false;
618
- foreach ($safe_referer_list as $referer)
619
- {
620
- if (strpos($http_referer, $referer) > -1)
621
- {
622
- $is_from_safe_referer = true;
623
- }
624
- }
625
- if (!$is_from_safe_referer)
626
- {
627
- if ($_GET['debug'] == '1')
628
- {
629
- echo "Invalid Referer:" . $http_referer;
630
- }
631
- die("Invalid request. Error 3001.");
632
- }
633
- }
634
-
635
-
636
- //Security Check #4 - is the request SSL-encrypted?
637
- if ($require_signed_request)
638
- {
639
- $hv = $reference_id = $_GET['hv'];
640
- $qs = $_SERVER['QUERY_STRING'];
641
- $toBeHashed = substr($qs, strrpos($qs, 'reference_id='));
642
- $toBeHashed = substr($toBeHashed, 0, strrpos($toBeHashed, '&hv='));
643
- $hash = md5($signed_request_secret . $toBeHashed . $signed_request_secret);
644
- if ($hash != $hv)
645
- {
646
- if ($_GET['debug'] == '1')
647
- {
648
- echo "<br>Preparing: " . $toBeHashed;
649
- echo "<br>Computed: " . $hash;
650
- echo "<br>HV: " . $hv;
651
- }
652
- die("Invalid request. Error 4001.");
653
- }
654
- }
655
-
656
- //Get access to the cart
657
- $cart = Mage::helper('checkout/cart')->getCart();
658
-
659
- //Empty out cart first, in case the user clicked back and then tried again.
660
- $items = $cart->getItems();
661
- foreach ($items as $item)
662
- {
663
- $cart->removeItem($item->getId());
664
- }
665
-
666
- //Loop through the querystring, find items and add them to bag.
667
- for ($i = 1; $i <= 99; $i++)
668
- {
669
- $item_quantity = $_GET['item_quantity_' . $i];
670
- $item_sku = $_GET['item_sku_' . $i];
671
-
672
- if (!empty($item_sku) && !empty($item_quantity))
673
- {
674
- $product_id = Mage::getModel('catalog/product')->getIdBySku($item_sku);
675
- $product = Mage::getModel('catalog/product')->load($product_id);
676
- if (!$product)
677
- {
678
- die("Invalid product added. Error 6002.");
679
- }
680
- else if (!$product->isSalable())
681
- {
682
- //The product has sold out since the customer added it to cart on mobile, show friendly error message.
683
- echo "<html><body style='font-family:Tahoma;color:#444444;text-align:center;padding-top:1em;'><h1>Out of stock</h1>";
684
- echo $product->getName() . "<br/>";
685
- echo $product->getSku() . "<br/><br/>";
686
- echo "Please go back and try again.";
687
- echo "</body></html>";
688
- die();
689
- }
690
- else
691
- {
692
- //Seems legit, let's try and add it to the cart. Note that stock level control might stop it here, products often sell out.
693
- try
694
- {
695
- $visibility = $product->getVisibility();
696
- if ($visibility != 4)
697
- {
698
- //If the product is not individually visible, add its parent with the selected SKU as the configured attribute.
699
- $parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($product_id);
700
- $parent_product_id = $parentIds[0];
701
- $parent_product = Mage::getModel('catalog/product')->load($parent_product_id);
702
- $confAttributes = $parent_product->getTypeInstance(true)->getConfigurableAttributesAsArray($parent_product); //var_dump($confAttributes);
703
- //Get the required attributes, and set them on the cart.
704
- if (sizeof($confAttributes) > 0)
705
- {
706
- $configurable_attribute_id = $confAttributes[0]["attribute_id"];
707
- $configurable_attribute_code = $confAttributes[0]["attribute_code"];
708
- $attribute_id = $product->getData($configurable_attribute_code);
709
-
710
- //Construct attributes so the correct size will be selected in the cart.
711
- $params = array(
712
- 'product' => $parent_product_id,
713
- 'super_attribute' => array(
714
- $configurable_attribute_id => $attribute_id,
715
- ),
716
- 'qty' => $item_quantity,
717
- );
718
-
719
-
720
- $cart->addProduct($parent_product, $params);
721
- $session->setLastAddedProductId($parent_product->getId());
722
- }
723
- else
724
- {
725
- //if the parent product has no configurable attributes, just add the simple product.
726
- $cart->addProduct($product, $item_quantity);
727
- $session->setLastAddedProductId($product->getId());
728
- }
729
- }
730
- else
731
- {
732
- //If the simple product is visible directly, simpley add it to the bag.
733
- $cart->addProduct($product, $item_quantity);
734
- $session->setLastAddedProductId($product->getId());
735
- }
736
- }
737
- catch (Exception $e)
738
- {
739
- //An error occurred when adding the product to the cart, such as ordering 2 of a product when only 1 is left in stock.
740
- echo "<html><body style='font-family:Tahoma;color:#444444;text-align:center;padding-top:1em;'><h1>Out of stock</h1>";
741
- echo "Please go back and try again.<br><br><em>";
742
- echo $product->getName() . "<br/>";
743
- echo $product->getSku() . "</em><br/><br/>";
744
- echo $e->getMessage() . "<br/>";
745
- echo "</body></html>";
746
- die();
747
- }
748
- }
749
- }
750
- }
751
-
752
- //Save changes
753
- $session->setCartWasUpdated(true);
754
- $cart->save();
755
-
756
- if ($tracking_code != "")
757
- {
758
- $tracking_code .= "&utm_medium=" . $_GET['channel'];
759
- $tracking_code .= "&reference_id=" . $reference_id; //Add unique id to tracking code, so it's stored in analytics
760
- if (strpos($next_url, "?") > -1)
761
- {
762
- $next_url .= "&" . $tracking_code;
763
- }
764
- else
765
- {
766
- $next_url .= "?" . $tracking_code;
767
- }
768
- }
769
-
770
- //Redirect to checkout page.
771
- header("Location: " . $next_url);
772
- die(); //stop execution of further scripts.
773
- }
774
-
775
- }
776
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Poq Integration model
5
+ *
6
+ * @author Poq Studio
7
+ */
8
+ class Poq_Integration_IndexController extends Mage_Core_Controller_Front_Action
9
+ {
10
+
11
+ /**
12
+ * Info page for checking extension status
13
+ */
14
+ public function indexAction()
15
+ {
16
+
17
+ // Get layout
18
+ $this->loadLayout();
19
+
20
+ // Create static block dynmacially
21
+ $block = $this->getLayout()->createBlock('Mage_Core_Block_Template', 'Integration Settings', array('template' => 'poqintegration/index.phtml'));
22
+
23
+ // Push block to layout
24
+ $this->getLayout()->getBlock('content')->append($block);
25
+
26
+ // Show settings
27
+ //Set CSV content type
28
+ if ($_GET['debug'] == '1')
29
+ {
30
+ // Get extension settings
31
+ $settings = Mage::helper('poq_integration')->getSettings();
32
+ var_dump($settings);
33
+ }
34
+
35
+ // Render page
36
+ $this->renderLayout();
37
+ }
38
+
39
+ /**
40
+ * Gets all categories indexed by id
41
+ * @return array
42
+ */
43
+ private function getCategories()
44
+ {
45
+ // Init category name and url arrays indexed by id
46
+ $activeCategorNamesById = array();
47
+ $activeCategoryUrlsById = array();
48
+
49
+ // Composite category array
50
+ $categories = array();
51
+
52
+ // Load all categories (flat)
53
+ $activeCategoryCollection = Mage::getModel('catalog/category')
54
+ ->getCollection()
55
+ ->addAttributeToSelect('*');
56
+
57
+
58
+ // Load all categories (tree)
59
+ $categoriesArray = Mage::getModel('catalog/category')
60
+ ->getCollection()
61
+ ->addAttributeToSelect('name')
62
+ ->addAttributeToSort('path', 'asc')
63
+ ->load()
64
+ ->toArray();
65
+
66
+ // Expose category name and urls and index by id
67
+ foreach ($activeCategoryCollection as $activeCategory)
68
+ {
69
+ $activeCategorNamesById[$activeCategory->getId()] = $activeCategory->getName();
70
+ $activeCategoryUrlsById[$activeCategory->getId()] = $activeCategory->getUrl();
71
+ }
72
+
73
+
74
+ // Find root category
75
+ $rootCategory = array();
76
+
77
+
78
+ if (isset($categoriesArray['items'])) {
79
+ foreach ($categoriesArray['items'] as $category)
80
+ {
81
+ if ($category['level'] == 1)
82
+ {
83
+ $rootCategory = $category;
84
+ break;
85
+ }
86
+ }
87
+
88
+ foreach ($categoriesArray['items'] as $category)
89
+ {
90
+ // Check if category is not at root category level
91
+ if (isset($category['name']) && isset($category['level']) && $category['level'] > $rootCategory['level'])
92
+ {
93
+
94
+ // Remove root category path from category
95
+ $path = str_replace($rootCategory['path'] . '/', '', $category['path']);
96
+
97
+ // Explode parent categories
98
+ $parents = explode('/', $path);
99
+ $name = '';
100
+ $url = '';
101
+
102
+ // Get category name and urls for each parent
103
+ foreach ($parents as $parent)
104
+ {
105
+ $name .= $activeCategorNamesById[$parent] . '>';
106
+ $url .= $activeCategoryUrlsById[$parent] . '>';
107
+ }
108
+
109
+ // Get products in category with their positions
110
+ $currentCategory = Mage::getModel('catalog/category')->load($categoryId);
111
+ $collection = $currentCategory->getProductCollection()->addAttributeToSort('position');
112
+ Mage::getModel('catalog/layer')->prepareProductCollection($collection);
113
+
114
+ // Index category data
115
+ $categories[$category['entity_id']] = array(
116
+ 'name' => substr($name, 0, -1),
117
+ 'level' => $category['level'],
118
+ 'ids' => str_replace('/', '>', $path),
119
+ 'url' => substr($url, 0, -1),
120
+ 'id' => $category['entity_id'],
121
+ 'products' => $currentCategory->getProductsPosition()
122
+ );
123
+ }
124
+ }
125
+ }
126
+ else{
127
+
128
+ foreach ($categoriesArray as $category)
129
+ {
130
+ if ($category['level'] == 1)
131
+ {
132
+ $rootCategory = $category;
133
+ break;
134
+ }
135
+ }
136
+ // Expose composite category data
137
+ foreach ($categoriesArray as $categoryId => $category)
138
+ {
139
+ // Check if category is not at root category level
140
+ if (isset($category['name']) && isset($category['level']) && $category['level'] > $rootCategory['level'])
141
+ {
142
+
143
+ // Remove root category path from category
144
+ $path = str_replace($rootCategory['path'] . '/', '', $category['path']);
145
+
146
+ // Explode parent categories
147
+ $parents = explode('/', $path);
148
+ $name = '';
149
+ $url = '';
150
+
151
+ // Get category name and urls for each parent
152
+ foreach ($parents as $parent)
153
+ {
154
+ $name .= $activeCategorNamesById[$parent] . '>';
155
+ $url .= $activeCategoryUrlsById[$parent] . '>';
156
+ }
157
+
158
+ // Get products in category with their positions
159
+ $currentCategory = Mage::getModel('catalog/category')->load($categoryId);
160
+ $collection = $currentCategory->getProductCollection()->addAttributeToSort('position');
161
+ Mage::getModel('catalog/layer')->prepareProductCollection($collection);
162
+
163
+ // Index category data
164
+ $categories[$categoryId] = array(
165
+ 'name' => substr($name, 0, -1),
166
+ 'level' => $category['level'],
167
+ 'ids' => str_replace('/', '>', $path),
168
+ 'url' => substr($url, 0, -1),
169
+ 'id' => $categoryId,
170
+ 'products' => $currentCategory->getProductsPosition()
171
+ );
172
+ }
173
+ }
174
+ }
175
+ return $categories;
176
+ }
177
+
178
+ public function showcategoriesAction()
179
+ {
180
+ var_dump($this->getCategories());
181
+ }
182
+
183
+ /**
184
+ * Create csv feed file with respecto extension settings
185
+ */
186
+ public function feedAction()
187
+ {
188
+
189
+ // Get extension settings
190
+ $settings = Mage::helper('poq_integration')->getSettings();
191
+
192
+ //Configuration values
193
+ $store_id = $settings->store_id;
194
+ $image_base_url = $settings->image_base_url;
195
+ $image_ignore_strings = $settings->image_ignore_string;
196
+ $tax_rates_enabled = $settings->tax_enabled;
197
+ $description_fields = $settings->description_fields;
198
+ $description_values = $settings->description_values;
199
+ $barcode_field = $settings->barcode_field;
200
+
201
+ //Trying to get default values
202
+ if ($store_id == 0)
203
+ {
204
+ $store_id = Mage::app()->getStore()->getStoreId();
205
+ }
206
+
207
+ //Set CSV content type
208
+ if ($_GET['debug'] == '1')
209
+ {
210
+ header("Content-type: text/plain");
211
+ }
212
+ else
213
+ {
214
+ header("Content-type: text/csv");
215
+ header("Content-Disposition: attachment; filename=feed.csv");
216
+ }
217
+ header("Pragma: no-cache");
218
+ header("Expires: 0");
219
+
220
+
221
+ // Init product attribute arrays
222
+ $productSizeDescriptions = array();
223
+ $parentProductIds = array();
224
+ $productColors = array();
225
+
226
+
227
+ // Attribute label configurations
228
+ // These can be moved to integration settings
229
+ // They always be lowercase for code convention
230
+ $colorAttributeLabel = "color";
231
+ $sizeAttributeLabel = "size";
232
+
233
+ $conn = Mage::getSingleton('core/resource')->getConnection('core_setup');
234
+ $collection = Mage::getModel('catalog/product')->getCollection()
235
+ ->joinField(
236
+ 'qty', 'cataloginventory/stock_item', 'qty', 'product_id=entity_id', '{{table}}.stock_id=1', 'left'
237
+ )
238
+ ->addAttributeToFilter('status', 1) // enabled
239
+ ->addUrlRewrite()
240
+ ->addPriceData()
241
+ ->addStoreFilter($store_id)
242
+ ->addAttributeToSelect('*');
243
+ Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($collection);
244
+ Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
245
+ $collection->setOrder('sku', 'desc');
246
+
247
+ if ($_GET['debug'] == '1')
248
+ {
249
+ //only get the first hundred rows, useful for faster testing. Also enable profiler, so we can see performance data.
250
+ $collection->setPageSize(200)->setCurPage(1);
251
+ $conn->getProfiler()->setEnabled(true);
252
+ echo $collection->getSelect()->__toString() . "\n\n";
253
+ }
254
+
255
+ //Read the dataset into memory
256
+ $collection->load();
257
+
258
+ //Preload the media_gallery image data into memory
259
+ //For use with Option #1 below
260
+ $_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
261
+ $_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
262
+ $_mediaGalleryData = $_read->fetchAll('SELECT
263
+ main.entity_id, `main`.`value_id`, `main`.`value` AS `file`,
264
+ `value`.`label`, `value`.`position`, `value`.`disabled`, `default_value`.`label` AS `label_default`,
265
+ `default_value`.`position` AS `position_default`,
266
+ `default_value`.`disabled` AS `disabled_default`
267
+ FROM `catalog_product_entity_media_gallery` AS `main`
268
+ LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
269
+ ON main.value_id=value.value_id AND value.store_id=' . $store_id . '
270
+ LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
271
+ ON main.value_id=default_value.value_id AND default_value.store_id=0
272
+ WHERE (
273
+ main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
274
+ AND (main.entity_id IN (' . $_read->quote($collection->getAllIds()) . '))
275
+ ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC
276
+ ');
277
+ $_mediaGalleryByProductId = array();
278
+ foreach ($_mediaGalleryData as $_galleryImage)
279
+ {
280
+ $k = $_galleryImage['entity_id'];
281
+ unset($_galleryImage['entity_id']);
282
+ if (!isset($_mediaGalleryByProductId[$k]))
283
+ {
284
+ $_mediaGalleryByProductId[$k] = array();
285
+ }
286
+ $_mediaGalleryByProductId[$k][] = $_galleryImage;
287
+ }
288
+ unset($_mediaGalleryData);
289
+ foreach ($collection as &$_product)
290
+ {
291
+ $_productId = $_product->getData('entity_id');
292
+ if (isset($_mediaGalleryByProductId[$_productId]))
293
+ {
294
+ $_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
295
+ }
296
+ }
297
+ unset($_mediaGalleryByProductId);
298
+
299
+ $isDumped=false;
300
+ // End of media_gallery queries for Option #1
301
+ //Go through configurable products, and preload data into $parentProductIds and $productSizeDescriptions
302
+
303
+ foreach ($collection as $product)
304
+ {
305
+ // Showing all product data to see all the configuration
306
+ if ($_GET['debug'] == '1' && $isDumped == false)
307
+ {
308
+ $isDumped = true;
309
+ $allProductData = Mage::getModel('catalog/product')->load($product->getId());
310
+ var_dump($allProductData);
311
+ }
312
+ if ($product->getTypeId() == "configurable")
313
+ {
314
+
315
+ //Get list of related sub-products
316
+ $productids = $product->getTypeInstance()->getUsedProductIds();
317
+ foreach ($productids as $productid)
318
+ {
319
+ $parentProductIds[$productid] = $product->getId(); //Add to array of related products, so we can look up when we loop through the main products later.
320
+ }
321
+
322
+ // Collect options applicable to the configurable product
323
+ $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($product);
324
+
325
+ // Get all attributes of the super products
326
+ $productAttributeOptions = $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
327
+
328
+ // Group attributes of children products
329
+ foreach ($productAttributeOptions as $productAttribute)
330
+ {
331
+
332
+ $code = $productAttribute["attribute_code"];
333
+
334
+ // Find attribute contains "color"
335
+ if (strpos($code, $colorAttributeLabel) !== false)
336
+ {
337
+ // Get children products used attribute code
338
+ $col = $conf->getUsedProductCollection()->addAttributeToSelect($code)->addFilterByRequiredOptions();
339
+ foreach ($col as $simple_product)
340
+ {
341
+ $productColors[$simple_product->getId()] = $simple_product->getAttributeText($code);
342
+ }
343
+ }
344
+
345
+
346
+ // Find attribute contains "size"
347
+ if (strpos($code, $sizeAttributeLabel) !== false)
348
+ {
349
+ // Get children products used attribute code
350
+ $col = $conf->getUsedProductCollection()->addAttributeToSelect($code)->addFilterByRequiredOptions();
351
+ foreach ($col as $simple_product)
352
+ {
353
+ $productSizeDescriptions[$simple_product->getId()] = $simple_product->getAttributeText($code);
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+
360
+ // Get all active categories
361
+ $categories = $this->getCategories();
362
+
363
+
364
+
365
+ //Add one line of headers above the actual content.
366
+ echo "\"id\"";
367
+ echo ",\"name\"";
368
+ echo ",\"price\"";
369
+ echo ",\"specialprice\"";
370
+ echo ",\"parentproductid\"";
371
+ echo ",\"sku\"";
372
+ echo ",\"isinstock\"";
373
+ echo ",\"quantity\"";
374
+ echo ",\"size\"";
375
+ echo ",\"color\"";
376
+ echo ",\"colorGroupId\"";
377
+ echo ",\"productURL\"";
378
+ echo ",\"pictureurls\"";
379
+ echo ",\"categoryid\"";
380
+ echo ",\"categoryname\"";
381
+ echo ",\"categoryurl\"";
382
+ echo ",\"categorysortindex\"";
383
+ echo ",\"description\"";
384
+ echo ",\"ean\"";
385
+ echo "\n";
386
+
387
+ // Get tax rates if enabled
388
+ $tax_classes;
389
+
390
+ if ($tax_rates_enabled)
391
+ {
392
+
393
+ // Get all tax classes with their values
394
+ $tax_classes = Mage::helper('tax')->getAllRatesByProductClass();
395
+ }
396
+
397
+ //Loop through the products, get the values and write them in CSV format
398
+ foreach ($collection as $product)
399
+ {
400
+ echo "\"" . $product->getId() . "\"";
401
+ echo ",\"" . addslashes($product->getName()) . "\"";
402
+
403
+ // Original price might have been tax rates applied on live site
404
+ // Fix by macromania
405
+ //echo ",\"" . $product->getPrice() . "\""; )
406
+ try
407
+ {
408
+
409
+ // Original price without tax
410
+ $product_price = $product->getPrice();
411
+ $special_price = $product->getFinalPrice();
412
+
413
+ if ($tax_rates_enabled)
414
+ {
415
+
416
+ // Get product tax class id
417
+ $tax_class_id = $_product->getData('tax_class_id');
418
+
419
+ // $tax_classes is returned as string. So parsing is needed to get the value
420
+ // an example $tax_classes could be like {"value_2":20,"value_4":20,"value_5":20,"value_6":0,"value_7":5}
421
+ $tax_classes = str_replace('{', '', $tax_classes);
422
+ $tax_classes = str_replace('}', '', $tax_classes);
423
+ $tax_class_value_array = explode(',', $tax_classes);
424
+
425
+ // Tax value
426
+ $product_tax_value = 0;
427
+
428
+ foreach ($tax_class_value_array as $tax_class)
429
+ {
430
+
431
+ $values = explode(':', $tax_class);
432
+ if ($values[0] == '"value_' . $tax_class_id . '"')
433
+ {
434
+ // Get the rate
435
+ $product_tax_value = $values[1];
436
+ }
437
+ }
438
+
439
+ // Apply tax rate
440
+ if ($product_tax_value > 0)
441
+ {
442
+ $product_price += $product_price * $product_tax_value / 100;
443
+ $special_price += $special_price * $product_tax_value / 100;
444
+ }
445
+
446
+ echo ",\"" . ceil($product_price) . "\"";
447
+ echo ",\"" . ceil($special_price) . "\"";
448
+ }
449
+ else
450
+ {
451
+ echo ",\"" . $product_price . "\"";
452
+ echo ",\"" . $special_price . "\"";
453
+ }
454
+
455
+
456
+
457
+ //echo '<p style="color:red">------<br/>Caught exception: ', ceil($product_price),'----',$product->getPrice(), '<br/>-----</p>';
458
+ }
459
+ catch (Exception $eproductprice)
460
+ {
461
+ echo '<p style="color:red">------<br/>Caught exception: ', $e2->getMessage(), '<br/>-----</p>';
462
+ }
463
+
464
+
465
+ // Parent product id
466
+ $parentProductIdCombined = $parentProductIds[$product->getId()];
467
+ if ($productColors[$product->getId()])
468
+ {
469
+ if (!empty($productColors[$product->getId()]))
470
+ {
471
+ $parentProductIdCombined .= "-" . $productColors[$product->getId()];
472
+ }
473
+ }
474
+
475
+
476
+ echo ",\"" . $parentProductIdCombined . "\"";
477
+
478
+ // SKU
479
+ echo ",\"" . $product->getSku() . "\"";
480
+
481
+ // Stock
482
+ echo ",\"" . $product->getStockItem()->getIsInStock() . "\"";
483
+
484
+ // Stock Quantity
485
+ echo ",\"" . $product->getQty() . "\"";
486
+
487
+ // Size
488
+ echo ",\"" . $productSizeDescriptions[$product->getId()] . "\"";
489
+
490
+ // Color name
491
+ echo ",\"" . $productColors[$product->getId()] . "\"";
492
+
493
+ // Color group id
494
+ echo ",\"" . $parentProductIds[$product->getId()] . "\"";
495
+
496
+ // Color
497
+ /*
498
+ $productColor = "test";
499
+ echo ",\"" . $productColor . "\"";
500
+ *
501
+ */
502
+
503
+ if ($product->getVisibility() == 4)
504
+ { //Only products that are individually visible need URLs, pictures, categories.
505
+ //Get product URL
506
+ echo ",\"" . $product->getProductUrl() . "\"";
507
+
508
+ //Get main image
509
+ $imageString = $product->getMediaConfig()->getMediaUrl($product->getData('image'));
510
+
511
+ //attempt to audo-detect base image url, if necessary
512
+ if ($image_base_url == '')
513
+ {
514
+ $image_base_url = substr($imageString, 0, strrpos($imageString, 'media/catalog/product')) . 'media/catalog/product';
515
+ }
516
+
517
+ //Option #1 - Fast way to get all media gallery images from preloaded array
518
+ $_images = $product->getData('media_gallery');
519
+ foreach ($_images as $imagegallery)
520
+ {
521
+ foreach ($imagegallery as $add_image)
522
+ {
523
+
524
+ //Check if image should be filtered.
525
+ $image_should_be_added = true;
526
+ if ($image_ignore_strings != '')
527
+ {
528
+ //echo "\n image_ignore_strings: " . $image_ignore_strings;
529
+ $image_ignore_string_array = explode(",", $image_ignore_strings);
530
+ foreach ($image_ignore_string_array as $image_ignore_string)
531
+ {
532
+ //echo "\n image_ignore_string: " . $image_ignore_string;
533
+ if (strpos($add_image['file'], $image_ignore_string) !== false)
534
+ {
535
+ //echo "\n IGNORING: " . $add_image['file'];
536
+ $image_should_be_added = false;
537
+ }
538
+ }
539
+ }
540
+ if ($image_should_be_added)
541
+ {
542
+ $imageString .= ',' . $image_base_url . $add_image['file'];
543
+ }
544
+ }
545
+ }
546
+
547
+ //Option #2 - Slower, but more reliable way to get all images. Try this is option #1 does not run
548
+ // $_images = Mage::getModel('catalog/product')->load($product->getId())->getMediaGalleryImages();
549
+ // foreach ($_images as $imagegallery) {
550
+ // $imageString .= ';' . $imagegallery['url'];
551
+ // }
552
+ echo ",\"" . $imageString . "\"";
553
+
554
+ //List the categories this product should be listed in
555
+ $cats = $product->getCategoryIds();
556
+ $category_id_list = "";
557
+ $category_name_list = "";
558
+ $category_url_list = "";
559
+ $category_sort_list = "";
560
+
561
+ foreach ($cats as $category_id)
562
+ {
563
+ $category_id_list .= $categories[$category_id]['ids'] . ';';
564
+ $category_name_list .= $categories[$category_id]['name'] . ';';
565
+ $category_url_list .= $categories[$category_id]['url'] . ';';
566
+
567
+ // Check if this category has products
568
+ if(count($categories[$category_id]['products']) > 0)
569
+ {
570
+ $category_sort_list .= $categories[$category_id]['products'][$product->getId()] . ';';
571
+ }
572
+
573
+ }
574
+
575
+ $category_id_list = substr($category_id_list, 0, -1);
576
+ $category_name_list = substr($category_name_list, 0, -1);
577
+ $category_url_list = substr($category_url_list, 0, -1);
578
+ $category_sort_list = substr($category_sort_list, 0, -1);
579
+
580
+ echo ",\"" . $category_id_list . "\"";
581
+ echo ",\"" . $category_name_list . "\"";
582
+ echo ",\"" . $category_url_list . "\"";
583
+ echo ",\"" . $category_sort_list . "\"";
584
+ }
585
+
586
+ if (!isset($description_fields)) {
587
+ $description = $product->getDescription(); //Remove HTML tags from the description
588
+ }
589
+ else {
590
+ $product = Mage::getModel('catalog/product')->load($product->getId());
591
+ $descFields = explode(",",$description_fields);
592
+ $descValues = explode(",",$description_values);
593
+ $i=0;
594
+ $description = "";
595
+
596
+
597
+ foreach ($descFields as $descField) {
598
+ //$attr = $product->getResource()->getAttribute($descField);
599
+ $val=$product->getData($descField);//$attr->getFrontend()->getValue($product);
600
+ if (isset($descValues) && count($descValues) == count($descFields)) {
601
+
602
+ if (isset($val)) {
603
+ $description=$description.'<b>'.$descValues[$i].'</b><br/>';
604
+ $description=$description.$val.'<br/><br/>';//$product->getValue($descField).'\n\n';
605
+ }
606
+ $i++;
607
+ }
608
+ else {
609
+ if (isset($val)) {
610
+ $description=$description.$val.'<br/>';
611
+ }
612
+ }
613
+ }
614
+ }
615
+ $description = addslashes($description); //Escape quotes etc from the text
616
+ $description = preg_replace('#\s{2,}#', '\\n', $description); //Remove line breaks, "\\n" will be put back in as line breaks when importing.
617
+ //$description = preg_replace('/(?<!,)"(?!,)/', '""', $description); //double up any double quote that is not immediately preceded or followed by a comma
618
+ $description = preg_replace('/\"/', '""', $description); //double up any double quote
619
+ echo ",\"" . $description . "\"";
620
+ // get barcode of product and expose it as ean
621
+ if (isset($barcode_field)) {
622
+ $barcode = $product->getData($barcode_field);
623
+ if (!isset($barcode)) {
624
+ $product = Mage::getModel('catalog/product')->load($product->getId());
625
+ $barcode = $product->getData($barcode_field);
626
+ }
627
+ }
628
+ else {
629
+ $barcode = $product->getData('barcode');
630
+ }
631
+
632
+ echo ",\"" . $barcode . "\"";
633
+
634
+ echo "\n";
635
+ }
636
+ if ($_GET['debug'] == '1')
637
+ { //Show performance data
638
+ echo "\n\n\n" . Varien_Profiler::getSqlProfiler($conn);
639
+ }
640
+ }
641
+
642
+ public function cartAction()
643
+ {
644
+
645
+ //Configuration values
646
+ $next_url = '/checkout/'; //After the product are added, redirect to this url.
647
+ $require_https = false; //SSL-encrypted requests cannot be read by anyone else, and will not be stored in history etc.
648
+ $require_signed_request = false; //If enabled, will require the request to be signed, we can verify that the URL has not been tampered with.
649
+ $signed_request_secret = ''; //Get this configuration value from Poq Studio
650
+ $limit_referer = false; //Enable this to require the request to come from our trusted source. Also makes it difficult to URL hack and investigate
651
+ $safe_referer_list = array("poqstudio.com", "cloudapp.net"); //add mobile website domains here, leave cloudapp.net and poqstudio.com.
652
+ $tracking_code = "utm_source=mobile&utm_campaign=poq"; //If set, will be added to the checkout page URL.
653
+ //End of configuration values
654
+
655
+ header("Pragma: no-cache");
656
+ header("Expires: 0");
657
+ $session = Mage::getSingleton('core/session', array('name' => 'frontend'));
658
+
659
+ //Security check #1 - make sure reference id is set and has a decent format
660
+ $reference_id = $_GET['reference_id'];
661
+ if (empty($reference_id))
662
+ {
663
+ die("Invalid request. Error 1001.");
664
+ }
665
+ else if (!strpos($reference_id, '-'))
666
+ {
667
+ die("Invalid request. Error 1002.");
668
+ }
669
+ $session->setPoqReferenceId($reference_id); //Save reference ID in session, for cross-tracking
670
+ //Security Check #2 - is the request SSL-encrypted?
671
+ if ($require_https)
672
+ {
673
+ $is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443);
674
+ if (!$is_https)
675
+ {
676
+ die("Invalid request. Error 2001.");
677
+ }
678
+ }
679
+
680
+ //Security Check #3 - is the referer from poqstudio.com?
681
+ if ($limit_referer)
682
+ {
683
+ $http_referer = $_SERVER['HTTP_REFERER'];
684
+ $is_from_safe_referer = false;
685
+ foreach ($safe_referer_list as $referer)
686
+ {
687
+ if (strpos($http_referer, $referer) > -1)
688
+ {
689
+ $is_from_safe_referer = true;
690
+ }
691
+ }
692
+ if (!$is_from_safe_referer)
693
+ {
694
+ if ($_GET['debug'] == '1')
695
+ {
696
+ echo "Invalid Referer:" . $http_referer;
697
+ }
698
+ die("Invalid request. Error 3001.");
699
+ }
700
+ }
701
+
702
+
703
+ //Security Check #4 - is the request SSL-encrypted?
704
+ if ($require_signed_request)
705
+ {
706
+ $hv = $reference_id = $_GET['hv'];
707
+ $qs = $_SERVER['QUERY_STRING'];
708
+ $toBeHashed = substr($qs, strrpos($qs, 'reference_id='));
709
+ $toBeHashed = substr($toBeHashed, 0, strrpos($toBeHashed, '&hv='));
710
+ $hash = md5($signed_request_secret . $toBeHashed . $signed_request_secret);
711
+ if ($hash != $hv)
712
+ {
713
+ if ($_GET['debug'] == '1')
714
+ {
715
+ echo "<br>Preparing: " . $toBeHashed;
716
+ echo "<br>Computed: " . $hash;
717
+ echo "<br>HV: " . $hv;
718
+ }
719
+ die("Invalid request. Error 4001.");
720
+ }
721
+ }
722
+
723
+ //Get access to the cart
724
+ $cart = Mage::helper('checkout/cart')->getCart();
725
+
726
+ //Empty out cart first, in case the user clicked back and then tried again.
727
+ $items = $cart->getItems();
728
+ foreach ($items as $item)
729
+ {
730
+ $cart->removeItem($item->getId());
731
+ }
732
+
733
+ //Loop through the querystring, find items and add them to bag.
734
+ for ($i = 1; $i <= 99; $i++)
735
+ {
736
+ $item_quantity = $_GET['item_quantity_' . $i];
737
+ $item_sku = $_GET['item_sku_' . $i];
738
+
739
+ if (!empty($item_sku) && !empty($item_quantity))
740
+ {
741
+ $product_id = Mage::getModel('catalog/product')->getIdBySku($item_sku);
742
+ $product = Mage::getModel('catalog/product')->load($product_id);
743
+ if (!$product)
744
+ {
745
+ die("Invalid product added. Error 6002.");
746
+ }
747
+ else if (!$product->isSalable())
748
+ {
749
+ //The product has sold out since the customer added it to cart on mobile, show friendly error message.
750
+ echo "<html><body style='font-family:Tahoma;color:#444444;text-align:center;padding-top:1em;'><h1>Out of stock</h1>";
751
+ echo $product->getName() . "<br/>";
752
+ echo $product->getSku() . "<br/><br/>";
753
+ echo "Please go back and try again.";
754
+ echo "</body></html>";
755
+ die();
756
+ }
757
+ else
758
+ {
759
+ //Seems legit, let's try and add it to the cart. Note that stock level control might stop it here, products often sell out.
760
+ try
761
+ {
762
+ $visibility = $product->getVisibility();
763
+ if ($visibility != 4)
764
+ {
765
+ //If the product is not individually visible, add its parent with the selected SKU as the configured attribute.
766
+ $parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($product_id);
767
+ $parent_product_id = $parentIds[0];
768
+ $parent_product = Mage::getModel('catalog/product')->load($parent_product_id);
769
+ $confAttributes = $parent_product->getTypeInstance(true)->getConfigurableAttributesAsArray($parent_product); //var_dump($confAttributes);
770
+ //Get the required attributes, and set them on the cart.
771
+ if (sizeof($confAttributes) > 0)
772
+ {
773
+ $configurable_attribute_id = $confAttributes[0]["attribute_id"];
774
+ $configurable_attribute_code = $confAttributes[0]["attribute_code"];
775
+ $attribute_id = $product->getData($configurable_attribute_code);
776
+
777
+ //Construct attributes so the correct size will be selected in the cart.
778
+ $params = array(
779
+ 'product' => $parent_product_id,
780
+ 'super_attribute' => array(
781
+ $configurable_attribute_id => $attribute_id,
782
+ ),
783
+ 'qty' => $item_quantity,
784
+ );
785
+
786
+
787
+ $cart->addProduct($parent_product, $params);
788
+ $session->setLastAddedProductId($parent_product->getId());
789
+ }
790
+ else
791
+ {
792
+ //if the parent product has no configurable attributes, just add the simple product.
793
+ $cart->addProduct($product, $item_quantity);
794
+ $session->setLastAddedProductId($product->getId());
795
+ }
796
+ }
797
+ else
798
+ {
799
+ //If the simple product is visible directly, simpley add it to the bag.
800
+ $cart->addProduct($product, $item_quantity);
801
+ $session->setLastAddedProductId($product->getId());
802
+ }
803
+ }
804
+ catch (Exception $e)
805
+ {
806
+ //An error occurred when adding the product to the cart, such as ordering 2 of a product when only 1 is left in stock.
807
+ echo "<html><body style='font-family:Tahoma;color:#444444;text-align:center;padding-top:1em;'><h1>Out of stock</h1>";
808
+ echo "Please go back and try again.<br><br><em>";
809
+ echo $product->getName() . "<br/>";
810
+ echo $product->getSku() . "</em><br/><br/>";
811
+ echo $e->getMessage() . "<br/>";
812
+ echo "</body></html>";
813
+ die();
814
+ }
815
+ }
816
+ }
817
+ }
818
+
819
+ //Save changes
820
+ $session->setCartWasUpdated(true);
821
+ $cart->save();
822
+
823
+ if ($tracking_code != "")
824
+ {
825
+ $tracking_code .= "&utm_medium=" . $_GET['channel'];
826
+ $tracking_code .= "&reference_id=" . $reference_id; //Add unique id to tracking code, so it's stored in analytics
827
+ if (strpos($next_url, "?") > -1)
828
+ {
829
+ $next_url .= "&" . $tracking_code;
830
+ }
831
+ else
832
+ {
833
+ $next_url .= "?" . $tracking_code;
834
+ }
835
+ }
836
+
837
+ //Redirect to checkout page.
838
+ header("Location: " . $next_url);
839
+ die(); //stop execution of further scripts.
840
+ }
841
+
842
+ }
843
+
app/code/community/Poq/Integration/controllers/OrderController.php CHANGED
@@ -1,522 +1,546 @@
1
- <?php
2
-
3
- /**
4
- * Poq Integration Order Management
5
- *
6
- * @author Poq Studio
7
- */
8
- class Poq_Integration_OrderController extends Mage_Core_Controller_Front_Action
9
- {
10
- /*
11
- * Creates an order as completed
12
- */
13
-
14
- public function createAction()
15
- {
16
- try
17
- {
18
-
19
- // Get extension settings
20
- $settings = Mage::helper('poq_integration')->getSettings();
21
-
22
- // Get store id
23
- $storeId = $settings->store_id;
24
-
25
- // Check if extension configured with signed request string
26
- if (empty($settings -> signed_request_string))
27
- {
28
- die("A security protocol error occured.\n Please try again later.");
29
- }
30
-
31
- // Check if the store id is valid
32
- if (is_null($storeId))
33
- {
34
- // Set store id as default store id
35
- $storeId = Mage::app()->getWebsite()
36
- ->getDefaultGroup()
37
- ->getDefaultStoreId();
38
- }
39
- else
40
- if (!is_numeric($storeId))
41
- {
42
- // Set store id as default store id
43
- $storeId = Mage::app()->getWebsite()
44
- ->getDefaultGroup()
45
- ->getDefaultStoreId();
46
- }
47
-
48
- // Get HTTP-POST data
49
- $post_data = Mage::app()->getRequest()->getPost();
50
-
51
- // Check if data is sent
52
- if (count($post_data) == 0)
53
- {
54
- Mage::throwException(Mage::helper('core')->__('Please send data via HTTP POST.'));
55
- }
56
-
57
- // Check if security phrase is sent
58
- if (empty($post_data['integration_key']))
59
- {
60
- die("Integration security settings couldn't be received.\nPlease try again later.");
61
- }
62
-
63
- if($post_data['integration_key'] != $settings -> signed_request_string)
64
- {
65
- die("Integration security settings couldn't be veried.\nPlease try again later.");
66
- }
67
-
68
- // Check if customer details is sent
69
- if (empty($post_data['email']) || empty($post_data['firstname']) || empty($post_data['lastname']) || empty($post_data['phone']))
70
- {
71
- Mage::throwException(Mage::helper('core')->__('Please set customer details: e-mail, firstname, lastname, phone'));
72
- }
73
-
74
- // Get customer details
75
- $customer = array(
76
- 'email' => $post_data['email'],
77
- 'firstname' => $post_data['firstname'],
78
- 'lastname' => $post_data['lastname'],
79
- 'phone' => $post_data['phone']
80
- );
81
-
82
- // Check if billing details is sent
83
- if (empty($post_data['address']) || empty($post_data['city']) || empty($post_data['country']) || empty($post_data['state']) ||
84
- empty($post_data['postcode']))
85
- {
86
- Mage::throwException(Mage::helper('core')->__('Please set billing details: address, city, country, state, postcode'));
87
- }
88
-
89
- // Get billing address details
90
- $billing = array(
91
- 'firstname' => $customer['firstname'],
92
- 'lastname' => $customer['lastname'],
93
- 'phone' => $customer['phone'],
94
- 'street' => $post_data['address'] . ' ' . $post_data['address2'],
95
- 'city' => $post_data['city'],
96
- 'country' => $post_data['country'],
97
- 'region' => $post_data['state'],
98
- 'postcode' => $post_data['postcode']
99
- );
100
-
101
- // Check if shipping details is sent
102
- if (empty($post_data['deliveryfirstname']) || empty($post_data['deliverylastname']) || empty($post_data['deliveryaddress']) ||
103
- empty($post_data['deliverycity']) || empty($post_data['deliverystate']) || empty($post_data['deliverypostcode']) ||
104
- empty($post_data['deliverycountry']))
105
- {
106
- Mage::throwException(
107
- Mage::helper('core')->__(
108
- 'Please set shipping details: deliveryfirstname, deliverylastname, deliveryaddress, deliverycity, deliverypostcode, deliverystate, deliverycountry'));
109
- }
110
-
111
- // Get shipping address details
112
- $shipping = array(
113
- 'firstname' => $post_data['deliveryfirstname'],
114
- 'lastname' => $post_data['deliverylastname'],
115
- 'street' => $post_data['deliveryaddress'] . ' ' . $post_data['deliveryaddress2'],
116
- 'city' => $post_data['deliverycity'],
117
- 'country' => $post_data['deliverycountry'],
118
- 'region' => $post_data['deliverystate'],
119
- 'postcode' => $post_data['deliverypostcode']
120
- );
121
-
122
- // Create transaction
123
- $transaction = Mage::getModel('core/resource_transaction');
124
-
125
- // Reserve the order increment id
126
- $reservedOrderId = Mage::getSingleton('eav/config')->getEntityType('order')->fetchNewIncrementId($storeId);
127
-
128
- // Check if currenct is set
129
- if (empty($post_data['currency']))
130
- {
131
- Mage::throwException(Mage::helper('core')->__('Please set currency details: currency'));
132
- }
133
-
134
- // Create order
135
- $order = Mage::getModel('sales/order')->setIncrementId($reservedOrderId)
136
- ->setStoreId($storeId)
137
- ->setQuoteId(0)
138
- ->setGlobal_currency_code($post_data['currency'])
139
- ->setBase_currency_code($post_data['currency'])
140
- ->setStore_currency_code($post_data['currency'])
141
- ->setOrder_currency_code($post_data['currency']);
142
-
143
- // Set Customer data
144
- $order->setCustomer_email($customer['email'])
145
- ->setCustomerFirstname($customer['firstname'])
146
- ->setCustomerLastname($customer['lastname'])
147
- ->setCustomer_is_guest(1);
148
-
149
- // Set Billing detaials
150
- $billingAddress = Mage::getModel('sales/order_address')->setStoreId($storeId)
151
- ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING)
152
- ->setFirstname($billing['firstname'])
153
- ->setLastname($billing['lastname'])
154
- ->setStreet($billing['street'])
155
- ->setCity($billing['city'])
156
- ->setCountry($billing['country'])
157
- ->setRegion($billing['state'])
158
- ->setPostcode($billing['postcode'])
159
- ->setTelephone($billing['phone']);
160
- $order->setBillingAddress($billingAddress);
161
-
162
- // Set Shippong details
163
- $shippingAddress = Mage::getModel('sales/order_address')->setStoreId($storeId)
164
- ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
165
- ->setFirstname($shipping['firstname'])
166
- ->setLastname($shipping['lastname'])
167
- ->setStreet($shipping['street'])
168
- ->setCity($shipping['city'])
169
- ->setCountry($shipping['country'])
170
- ->setRegion($shipping['state'])
171
- ->setPostcode($shipping['postcode'])
172
- ->setTelephone($shipping['phone']);
173
- $order->setShippingAddress($shippingAddress);
174
-
175
- // Set order payment type
176
- $orderPayment = Mage::getModel('sales/order_payment')->setStoreId($storeId)->setMethod('purchaseorder');
177
- $order->setPayment($orderPayment);
178
-
179
- // Get shipping price
180
- $shipping_price = $post_data['deliverycost'];
181
-
182
- // Set shipping description
183
- $order->setShippingDescription($post_data['deliveryoptiontitle']);
184
-
185
- // Subtotal
186
- $subTotal = 0;
187
-
188
- // Get products
189
- $items = $post_data['items'];
190
-
191
- // Set order products
192
- foreach ($items as $item)
193
- {
194
-
195
- // Get product details by id
196
- $product = Mage::getModel('catalog/product')->load($item['id']);
197
-
198
- if (!is_null($product->getId()))
199
- {
200
-
201
- // Get total price per product by quantity
202
- $rowTotal = $product->getPrice() * $item['quantity'];
203
-
204
- // Set order item
205
- $orderItem = Mage::getModel('sales/order_item')->setStoreId($storeId)
206
- ->setQuoteItemId(0)
207
- ->setQuoteParentItemId(NULL)
208
- ->setProductId($item['id'])
209
- ->setProductType($product->getTypeId())
210
- ->setQtyBackordered(NULL)
211
- ->setQtyOrdered($item['quantity'])
212
- ->setName($product->getName())
213
- ->setSku($product->getSku())
214
- ->setPrice($product->getPrice())
215
- ->setBasePrice($product->getPrice())
216
- ->setOriginalPrice($product->getPrice())
217
- ->setRowTotal($rowTotal)
218
- ->setBaseRowTotal($rowTotal);
219
-
220
- // Add order item total to subtotal
221
- $subTotal += $rowTotal;
222
-
223
- // Add order item to order
224
- $order->addItem($orderItem);
225
- }
226
- else
227
- {
228
-
229
- // Product not found
230
- Mage::throwException(Mage::helper('core')->__('Cannot add product ' . $item['id'] . ' to order. Please check product id.'));
231
- }
232
- }
233
-
234
- // Get voucer details
235
- $voucher = array(
236
- 'code' => $post_data['vouchercode'],
237
- 'amount' => $post_data['voucheramount']
238
- );
239
-
240
- // Check voucher
241
- if ($voucher['amount'] > 0)
242
- {
243
-
244
- // Apply discount
245
- $order->setDiscountAmount($voucher['amount']);
246
- $subTotal -= $voucher['amount'];
247
-
248
- // Add coupon code
249
- $order->addStatusHistoryComment('Voucher coupon ' . $voucher['code'] . ' applied.', Mage_Sales_Model_Order::STATE_COMPLETE);
250
- }
251
-
252
- // Add Poq order data
253
- $order->addStatusHistoryComment('Poq Data: Payment Transaction ID:' . $post_data['payment_transaction_id'] . ' Ref ID:' . $post_data['reference_id'], Mage_Sales_Model_Order::STATE_COMPLETE);
254
-
255
- // Add Poq channel data
256
- $order->addStatusHistoryComment('Poq Data: Channel:' . $post_data['channel'] . ' Platform:' . $post_data['platform'], Mage_Sales_Model_Order::STATE_COMPLETE);
257
-
258
- // Set order total
259
- $order->setSubtotal($subTotal)
260
- ->setBaseSubtotal($subTotal)
261
- ->setGrandTotal($subTotal + $shipping_price)
262
- ->setBaseGrandTotal($subTotal + $shipping_price)
263
- ->setShippingAmount($shipping_price)
264
- ->setBaseShippingAmount($shipping_price);
265
-
266
- // Add order to transaction
267
- $transaction->addObject($order);
268
- $transaction->addCommitCallback(array(
269
- $order,
270
- 'place'
271
- ));
272
- $transaction->addCommitCallback(array(
273
- $order,
274
- 'save'
275
- ));
276
- $transaction->save();
277
-
278
-
279
- if ($order->getTotalPaid() == 0)
280
- {
281
-
282
- // Generate invoice
283
- // Check if order invoicable
284
- if (!$order->canInvoice())
285
- {
286
- Mage::throwException(Mage::helper('core')->__('Cannot create an invoice for this order.'));
287
- }
288
-
289
- // Prepare invoice
290
- $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
291
-
292
- // Check if order has products
293
- if (!$invoice->getTotalQty())
294
- {
295
- Mage::throwException(
296
- Mage::helper('core')->__('Cannot create an invoice without products. Check product ids before creating the order.'));
297
- }
298
-
299
- // Update invoice as captured online
300
- $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
301
- $invoice->register();
302
-
303
- // Add update history comment
304
- $order->addStatusHistoryComment('Order paid via native payment with transaction id ' . $post_data['payment_transaction_id'], Mage_Sales_Model_Order::STATE_COMPLETE);
305
-
306
- // Update order status
307
- $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
308
-
309
- // Save transcation and update order
310
- $transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
311
- $transactionSave->save();
312
-
313
- try
314
- {
315
- // Send order e-mail notification to customer
316
- if($settings->send_order_emails){
317
-
318
- $order->sendNewOrderEmail();
319
- }
320
-
321
- }
322
- catch (Exception $ex)
323
- {
324
-
325
- }
326
-
327
- echo "Success";
328
- }
329
- }
330
- catch (Mage_Core_Exception $e)
331
- {
332
-
333
- // Output error message
334
- echo $e->getMessage();
335
- }
336
- }
337
-
338
- /*
339
- * Updates order status and payment info
340
- */
341
-
342
- public function saveAction()
343
- {
344
- try
345
- {
346
-
347
- // Get HTTP-POST data
348
- $post_data = Mage::app()->getRequest()->getPost();
349
-
350
- if (count($post_data) == 0)
351
- {
352
- Mage::throwException(Mage::helper('core')->__('Please send data via HTTP POST.'));
353
- }
354
-
355
- // Get order id
356
- $orderId = $post_data['orderId'];
357
-
358
- // Check order id
359
- if (is_null($orderId))
360
- {
361
- Mage::throwException(Mage::helper('core')->__('Order id is required to complete this order.'));
362
- }
363
-
364
- // Get transaction id
365
- $transactionId = $post_data['transactionId'];
366
-
367
- // Check transaction id
368
- if (is_null($transactionId))
369
- {
370
- Mage::throwException(Mage::helper('core')->__('Transaction id is required to complete this order.'));
371
- }
372
-
373
- // Get order
374
- $order = Mage::getModel('sales/order')->load($orderId);
375
-
376
- if (!is_null($order->getId()))
377
- {
378
-
379
- if ($order->getTotalPaid() == 0)
380
- {
381
-
382
- // Generate invoice
383
- // Check if order invoicable
384
- if (!$order->canInvoice())
385
- {
386
- Mage::throwException(Mage::helper('core')->__('Cannot create an invoice for this order.'));
387
- }
388
-
389
- // Prepare invoice
390
- $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
391
-
392
- // Check if order has products
393
- if (!$invoice->getTotalQty())
394
- {
395
- Mage::throwException(
396
- Mage::helper('core')->__('Cannot create an invoice without products. Check product ids before creating the order.'));
397
- }
398
-
399
- // Update invoice as captured online
400
- $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
401
- $invoice->register();
402
-
403
- // Add update history comment
404
- $order->addStatusHistoryComment('Order paid via native payment with transaction id ' . $transactionId, Mage_Sales_Model_Order::STATE_COMPLETE);
405
-
406
- // Update order status
407
- $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
408
-
409
- // Save transcation and update order
410
- $transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
411
- $transactionSave->save();
412
-
413
-
414
-
415
- echo "Success";
416
- }
417
- else
418
- {
419
- Mage::throwException(Mage::helper('core')->__('Order has been already updated.'));
420
- }
421
- }
422
- else
423
- {
424
- Mage::throwException(Mage::helper('core')->__('Order id ' . $orderId . ' is not valid. Please check order id.'));
425
- }
426
- }
427
- catch (Mage_Core_Exception $e)
428
- {
429
-
430
- // Output error message
431
- echo $e->getMessage();
432
- }
433
- }
434
-
435
- /*
436
- * Checks product's stock status
437
- */
438
-
439
- public function checkAction()
440
- {
441
- try
442
- {
443
- // Get HTTP-POST data
444
- $post_data = Mage::app()->getRequest()->getPost();
445
-
446
- // Check if data is sent
447
- if (count($post_data) == 0)
448
- {
449
- die('Please send data via HTTP POST.');
450
- }
451
-
452
- // Get products
453
- $items = $post_data['items'];
454
-
455
- // Out of stock product names for error message
456
- $outOfStockItems = array();
457
-
458
-
459
- // Set order products
460
- foreach ($items as $item)
461
- {
462
- if (!empty($item['sku']))
463
- {
464
- // Get product id by sku
465
- $productId = Mage::getModel('catalog/product')->getIdBySku($item['sku']);
466
-
467
- if (!empty($productId))
468
- {
469
- // Get product details by id
470
- $product = Mage::getModel('catalog/product')->load($productId);
471
-
472
- // Die if the product is not found
473
- if (!$product)
474
- {
475
- die("Products in your shopping cart are out of stock:\n".$item['productTitle']);
476
- }
477
-
478
- // The product has sold out
479
- if (!$product->isSalable())
480
- {
481
- array_push($outOfStockItems, $product->getName());
482
- }
483
- }
484
- else
485
- {
486
- die("Products in your shopping cart are out of stock:\n".$item['productTitle']);
487
- }
488
- }
489
- else
490
- {
491
- die("SKU field is empty for item index :" . array_search($item, $items));
492
- }
493
- }
494
-
495
-
496
-
497
- // Return out of stock items if any
498
- if (count($outOfStockItems) > 0)
499
- {
500
- $errorMessage = "The following products in your cart are out of stock:\n";
501
-
502
- foreach ($outOfStockItems as $outOfStockItem)
503
- {
504
- $errorMessage .= $outOfStockItem . "\n";
505
- }
506
-
507
- echo $errorMessage;
508
- }
509
- else
510
- {
511
- echo "Success";
512
- }
513
- }
514
- catch (Exception $e)
515
- {
516
- // Output error message
517
- echo $e->getMessage(), "\n";
518
- }
519
- }
520
-
521
- }
522
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Poq Integration Order Management
5
+ *
6
+ * @author Poq Studio
7
+ */
8
+ class Poq_Integration_OrderController extends Mage_Core_Controller_Front_Action
9
+ {
10
+ /*
11
+ * Creates an order as completed
12
+ */
13
+
14
+ public function createAction()
15
+ {
16
+ try
17
+ {
18
+
19
+ // Get extension settings
20
+ $settings = Mage::helper('poq_integration')->getSettings();
21
+
22
+ // Get store id
23
+ $storeId = $settings->store_id;
24
+
25
+ // Check if extension configured with signed request string
26
+ if (empty($settings -> signed_request_string))
27
+ {
28
+ die("A security protocol error occured.\n Please try again later.");
29
+ }
30
+
31
+ // Check if the store id is valid
32
+ if (is_null($storeId))
33
+ {
34
+ // Set store id as default store id
35
+ $storeId = Mage::app()->getWebsite()
36
+ ->getDefaultGroup()
37
+ ->getDefaultStoreId();
38
+ }
39
+ else
40
+ if (!is_numeric($storeId))
41
+ {
42
+ // Set store id as default store id
43
+ $storeId = Mage::app()->getWebsite()
44
+ ->getDefaultGroup()
45
+ ->getDefaultStoreId();
46
+ }
47
+
48
+ // Get HTTP-POST data
49
+ $post_data = Mage::app()->getRequest()->getPost();
50
+
51
+ // Check if data is sent
52
+ if (count($post_data) == 0)
53
+ {
54
+ Mage::throwException(Mage::helper('core')->__('Please send data via HTTP POST.'));
55
+ }
56
+
57
+ // Check if security phrase is sent
58
+ if (empty($post_data['integration_key']))
59
+ {
60
+ die("Integration security settings couldn't be received.\nPlease try again later.");
61
+ }
62
+
63
+ if($post_data['integration_key'] != $settings -> signed_request_string)
64
+ {
65
+ die("Integration security settings couldn't be veried.\nPlease try again later.");
66
+ }
67
+
68
+ // Check if customer details is sent
69
+ if (empty($post_data['email']) || empty($post_data['firstname']) || empty($post_data['lastname']) || empty($post_data['phone']))
70
+ {
71
+ Mage::throwException(Mage::helper('core')->__('Please set customer details: e-mail, firstname, lastname, phone'));
72
+ }
73
+
74
+ // Get customer details
75
+ $customer = array(
76
+ 'email' => $post_data['email'],
77
+ 'firstname' => $post_data['firstname'],
78
+ 'lastname' => $post_data['lastname'],
79
+ 'phone' => $post_data['phone']
80
+ );
81
+
82
+ // Check if billing details is sent
83
+ if (empty($post_data['address']) || empty($post_data['city']) || empty($post_data['country']) || empty($post_data['state']) ||
84
+ empty($post_data['postcode']))
85
+ {
86
+ Mage::throwException(Mage::helper('core')->__('Please set billing details: address, city, country, state, postcode'));
87
+ }
88
+
89
+ // Get billing address details
90
+ $billing = array(
91
+ 'firstname' => $customer['firstname'],
92
+ 'lastname' => $customer['lastname'],
93
+ 'phone' => $customer['phone'],
94
+ 'street' => $post_data['address'] . ' ' . $post_data['address2'],
95
+ 'city' => $post_data['city'],
96
+ 'country' => $post_data['country'],
97
+ 'region' => $post_data['state'],
98
+ 'postcode' => $post_data['postcode']
99
+ );
100
+
101
+ // Check if shipping details is sent
102
+ if (empty($post_data['deliveryfirstname']) || empty($post_data['deliverylastname']) || empty($post_data['deliveryaddress']) ||
103
+ empty($post_data['deliverycity']) || empty($post_data['deliverystate']) || empty($post_data['deliverypostcode']) ||
104
+ empty($post_data['deliverycountry']))
105
+ {
106
+ Mage::throwException(
107
+ Mage::helper('core')->__(
108
+ 'Please set shipping details: deliveryfirstname, deliverylastname, deliveryaddress, deliverycity, deliverypostcode, deliverystate, deliverycountry'));
109
+ }
110
+
111
+ // Get shipping address details
112
+ $shipping = array(
113
+ 'firstname' => $post_data['deliveryfirstname'],
114
+ 'lastname' => $post_data['deliverylastname'],
115
+ 'street' => $post_data['deliveryaddress'] . ' ' . $post_data['deliveryaddress2'],
116
+ 'city' => $post_data['deliverycity'],
117
+ 'country' => $post_data['deliverycountry'],
118
+ 'region' => $post_data['deliverystate'],
119
+ 'postcode' => $post_data['deliverypostcode']
120
+ );
121
+
122
+ // Create transaction
123
+ $transaction = Mage::getModel('core/resource_transaction');
124
+
125
+ // Reserve the order increment id
126
+ $reservedOrderId = Mage::getSingleton('eav/config')->getEntityType('order')->fetchNewIncrementId($storeId);
127
+
128
+ // Check if currenct is set
129
+ if (empty($post_data['currency']))
130
+ {
131
+ Mage::throwException(Mage::helper('core')->__('Please set currency details: currency'));
132
+ }
133
+
134
+ // Create order
135
+ $order = Mage::getModel('sales/order')->setIncrementId($reservedOrderId)
136
+ ->setStoreId($storeId)
137
+ ->setQuoteId(0)
138
+ ->setGlobal_currency_code($post_data['currency'])
139
+ ->setBase_currency_code($post_data['currency'])
140
+ ->setStore_currency_code($post_data['currency'])
141
+ ->setOrder_currency_code($post_data['currency']);
142
+
143
+ // Set Customer data
144
+ $order->setCustomer_email($customer['email'])
145
+ ->setCustomerFirstname($customer['firstname'])
146
+ ->setCustomerLastname($customer['lastname'])
147
+ ->setCustomer_is_guest(1);
148
+
149
+ // Set Billing detaials
150
+ $billingAddress = Mage::getModel('sales/order_address')->setStoreId($storeId)
151
+ ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_BILLING)
152
+ ->setFirstname($billing['firstname'])
153
+ ->setLastname($billing['lastname'])
154
+ ->setStreet($billing['street'])
155
+ ->setCity($billing['city'])
156
+ ->setCountry($billing['country'])
157
+ ->setRegion($billing['state'])
158
+ ->setPostcode($billing['postcode'])
159
+ ->setTelephone($billing['phone']);
160
+ $order->setBillingAddress($billingAddress);
161
+
162
+ // Set Shippong details
163
+ $shippingAddress = Mage::getModel('sales/order_address')->setStoreId($storeId)
164
+ ->setAddressType(Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)
165
+ ->setFirstname($shipping['firstname'])
166
+ ->setLastname($shipping['lastname'])
167
+ ->setStreet($shipping['street'])
168
+ ->setCity($shipping['city'])
169
+ ->setCountry($shipping['country'])
170
+ ->setRegion($shipping['state'])
171
+ ->setPostcode($shipping['postcode'])
172
+ ->setTelephone($shipping['phone']);
173
+ $order->setShippingAddress($shippingAddress);
174
+
175
+ // Set order payment type
176
+ $orderPayment = Mage::getModel('sales/order_payment')->setStoreId($storeId)->setMethod('purchaseorder');
177
+ $order->setPayment($orderPayment);
178
+
179
+ // Get shipping price
180
+ $shipping_price = $post_data['deliverycost'];
181
+
182
+ // Set shipping description
183
+ $order->setShippingDescription($post_data['deliveryoptiontitle']);
184
+
185
+ // Subtotal
186
+ $subTotal = 0;
187
+
188
+ // Get products
189
+ $items = $post_data['items'];
190
+
191
+ // Set order products
192
+ foreach ($items as $item)
193
+ {
194
+
195
+ // Get product details by id
196
+ $product = Mage::getModel('catalog/product')->load($item['id']);
197
+
198
+ $parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')
199
+ ->getParentIdsByChild($item['id']);
200
+ $parentProduct = Mage::getModel('catalog/product')->load($parentIds[0]);
201
+
202
+ if (!is_null($product->getId()))
203
+ {
204
+
205
+ if (!is_null($parentProduct->getId())) {
206
+
207
+ $rowTotal = $parentProduct->getFinalPrice() * $item['quantity'];
208
+
209
+ // Set order item
210
+ $orderItem = Mage::getModel('sales/order_item')->setStoreId($storeId)
211
+ ->setQuoteItemId(0)
212
+ ->setQuoteParentItemId(NULL)
213
+ ->setProductId($item['id'])
214
+ ->setProductType($product->getTypeId())
215
+ ->setQtyBackordered(NULL)
216
+ ->setQtyOrdered($item['quantity'])
217
+ ->setName($product->getName())
218
+ ->setSku($product->getSku())
219
+ ->setPrice($parentProduct->getPrice())
220
+ ->setBasePrice($parentProduct->getPrice())
221
+ ->setOriginalPrice($parentProduct->getPrice())
222
+ ->setRowTotal($rowTotal)
223
+ ->setBaseRowTotal($rowTotal);
224
+ }
225
+ else {
226
+ // Get total price per product by quantity
227
+ $rowTotal = $product->getPrice() * $item['quantity'];
228
+
229
+ // Set order item
230
+ $orderItem = Mage::getModel('sales/order_item')->setStoreId($storeId)
231
+ ->setQuoteItemId(0)
232
+ ->setQuoteParentItemId(NULL)
233
+ ->setProductId($item['id'])
234
+ ->setProductType($product->getTypeId())
235
+ ->setQtyBackordered(NULL)
236
+ ->setQtyOrdered($item['quantity'])
237
+ ->setName($product->getName())
238
+ ->setSku($product->getSku())
239
+ ->setPrice($product->getPrice())
240
+ ->setBasePrice($product->getPrice())
241
+ ->setOriginalPrice($product->getPrice())
242
+ ->setRowTotal($rowTotal)
243
+ ->setBaseRowTotal($rowTotal);
244
+ }
245
+
246
+ // Add order item total to subtotal
247
+ $subTotal += $rowTotal;
248
+
249
+ // Add order item to order
250
+ $order->addItem($orderItem);
251
+ }
252
+ else
253
+ {
254
+
255
+ // Product not found
256
+ Mage::throwException(Mage::helper('core')->__('Cannot add product ' . $item['id'] . ' to order. Please check product id.'));
257
+ }
258
+ }
259
+
260
+ // Get voucer details
261
+ $voucher = array(
262
+ 'code' => $post_data['vouchercode'],
263
+ 'amount' => $post_data['voucheramount']
264
+ );
265
+
266
+ // Check voucher
267
+ if ($voucher['amount'] > 0)
268
+ {
269
+
270
+ // Apply discount
271
+ $order->setDiscountAmount($voucher['amount']);
272
+ $subTotal -= $voucher['amount'];
273
+
274
+ // Add coupon code
275
+ $order->addStatusHistoryComment('Voucher coupon ' . $voucher['code'] . ' applied.', Mage_Sales_Model_Order::STATE_COMPLETE);
276
+ }
277
+
278
+ // Add Poq order data
279
+ $order->addStatusHistoryComment('Poq Data: Payment Transaction ID:' . $post_data['payment_transaction_id'] . ' Ref ID:' . $post_data['reference_id'], Mage_Sales_Model_Order::STATE_COMPLETE);
280
+
281
+ // Add Poq channel data
282
+ $order->addStatusHistoryComment('Poq Data: Channel:' . $post_data['channel'] . ' Platform:' . $post_data['platform'], Mage_Sales_Model_Order::STATE_COMPLETE);
283
+
284
+ // Set order total
285
+ $order->setSubtotal($subTotal)
286
+ ->setBaseSubtotal($subTotal)
287
+ ->setGrandTotal($subTotal + $shipping_price)
288
+ ->setBaseGrandTotal($subTotal + $shipping_price)
289
+ ->setShippingAmount($shipping_price)
290
+ ->setBaseShippingAmount($shipping_price);
291
+
292
+ // Add order to transaction
293
+ $transaction->addObject($order);
294
+ $transaction->addCommitCallback(array(
295
+ $order,
296
+ 'place'
297
+ ));
298
+ $transaction->addCommitCallback(array(
299
+ $order,
300
+ 'save'
301
+ ));
302
+ $transaction->save();
303
+
304
+
305
+ if ($order->getTotalPaid() == 0)
306
+ {
307
+
308
+ // Generate invoice
309
+ // Check if order invoicable
310
+ if (!$order->canInvoice())
311
+ {
312
+ Mage::throwException(Mage::helper('core')->__('Cannot create an invoice for this order.'));
313
+ }
314
+
315
+ // Prepare invoice
316
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
317
+
318
+ // Check if order has products
319
+ if (!$invoice->getTotalQty())
320
+ {
321
+ Mage::throwException(
322
+ Mage::helper('core')->__('Cannot create an invoice without products. Check product ids before creating the order.'));
323
+ }
324
+
325
+ // Update invoice as captured online
326
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
327
+ $invoice->register();
328
+
329
+ // Add update history comment
330
+ $order->addStatusHistoryComment('Order paid via native payment with transaction id ' . $post_data['payment_transaction_id'], Mage_Sales_Model_Order::STATE_COMPLETE);
331
+
332
+ // Update order status
333
+ $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
334
+
335
+ // Save transcation and update order
336
+ $transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
337
+ $transactionSave->save();
338
+
339
+ try
340
+ {
341
+
342
+ if($settings->send_order_emails){
343
+
344
+ $order->sendNewOrderEmail();
345
+ }
346
+
347
+ }
348
+ catch (Exception $ex)
349
+ {
350
+
351
+ }
352
+
353
+ echo "Success";
354
+ }
355
+ }
356
+ catch (Mage_Core_Exception $e)
357
+ {
358
+
359
+ // Output error message
360
+ echo $e->getMessage();
361
+ }
362
+ }
363
+
364
+ /*
365
+ * Updates order status and payment info
366
+ */
367
+
368
+ public function saveAction()
369
+ {
370
+ try
371
+ {
372
+
373
+ // Get HTTP-POST data
374
+ $post_data = Mage::app()->getRequest()->getPost();
375
+
376
+ if (count($post_data) == 0)
377
+ {
378
+ Mage::throwException(Mage::helper('core')->__('Please send data via HTTP POST.'));
379
+ }
380
+
381
+ // Get order id
382
+ $orderId = $post_data['orderId'];
383
+
384
+ // Check order id
385
+ if (is_null($orderId))
386
+ {
387
+ Mage::throwException(Mage::helper('core')->__('Order id is required to complete this order.'));
388
+ }
389
+
390
+ // Get transaction id
391
+ $transactionId = $post_data['transactionId'];
392
+
393
+ // Check transaction id
394
+ if (is_null($transactionId))
395
+ {
396
+ Mage::throwException(Mage::helper('core')->__('Transaction id is required to complete this order.'));
397
+ }
398
+
399
+ // Get order
400
+ $order = Mage::getModel('sales/order')->load($orderId);
401
+
402
+ if (!is_null($order->getId()))
403
+ {
404
+
405
+ if ($order->getTotalPaid() == 0)
406
+ {
407
+
408
+ // Generate invoice
409
+ // Check if order invoicable
410
+ if (!$order->canInvoice())
411
+ {
412
+ Mage::throwException(Mage::helper('core')->__('Cannot create an invoice for this order.'));
413
+ }
414
+
415
+ // Prepare invoice
416
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
417
+
418
+ // Check if order has products
419
+ if (!$invoice->getTotalQty())
420
+ {
421
+ Mage::throwException(
422
+ Mage::helper('core')->__('Cannot create an invoice without products. Check product ids before creating the order.'));
423
+ }
424
+
425
+ // Update invoice as captured online
426
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
427
+ $invoice->register();
428
+
429
+ // Add update history comment
430
+ $order->addStatusHistoryComment('Order paid via native payment with transaction id ' . $transactionId, Mage_Sales_Model_Order::STATE_COMPLETE);
431
+
432
+ // Update order status
433
+ $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
434
+
435
+ // Save transcation and update order
436
+ $transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
437
+ $transactionSave->save();
438
+
439
+
440
+
441
+ echo "Success";
442
+ }
443
+ else
444
+ {
445
+ Mage::throwException(Mage::helper('core')->__('Order has been already updated.'));
446
+ }
447
+ }
448
+ else
449
+ {
450
+ Mage::throwException(Mage::helper('core')->__('Order id ' . $orderId . ' is not valid. Please check order id.'));
451
+ }
452
+ }
453
+ catch (Mage_Core_Exception $e)
454
+ {
455
+
456
+ // Output error message
457
+ echo $e->getMessage();
458
+ }
459
+ }
460
+
461
+ /*
462
+ * Checks product's stock status
463
+ */
464
+
465
+ public function checkAction()
466
+ {
467
+ try
468
+ {
469
+ // Get HTTP-POST data
470
+ $post_data = Mage::app()->getRequest()->getPost();
471
+
472
+ // Check if data is sent
473
+ if (count($post_data) == 0)
474
+ {
475
+ die('Please send data via HTTP POST.');
476
+ }
477
+
478
+ // Get products
479
+ $items = $post_data['items'];
480
+ // Out of stock product names for error message
481
+ $outOfStockItems = array();
482
+
483
+ // Set order products
484
+ foreach ($items as $item)
485
+ {
486
+ if (!empty($item['sku']))
487
+ {
488
+ // Get product id by sku
489
+ $productId = Mage::getModel('catalog/product')->getIdBySku($item['sku']);
490
+
491
+ if (!empty($productId))
492
+ {
493
+ // Get product details by id
494
+ $product = Mage::getModel('catalog/product')->load($productId);
495
+
496
+ // Die if the product is not found
497
+ if (!$product)
498
+ {
499
+ die("Products in your shopping cart are out of stock:\n".$item['productTitle']."\n".$item['sku']);
500
+ }
501
+
502
+ // The product has sold out
503
+ if (!$product->isSalable())
504
+ {
505
+ array_push($outOfStockItems, $product->getName());
506
+ }
507
+ }
508
+ else
509
+ {
510
+ die("Products in your shopping cart are out of stock:\n".$item['productTitle']."\n".$item['sku']);
511
+ }
512
+ }
513
+ else
514
+ {
515
+ die("SKU field is empty for item index :" . array_search($item, $items));
516
+ }
517
+ }
518
+
519
+
520
+
521
+ // Return out of stock items if any
522
+ if (count($outOfStockItems) > 0)
523
+ {
524
+ $errorMessage = "The following products in your cart are out of stock:\n";
525
+
526
+ foreach ($outOfStockItems as $outOfStockItem)
527
+ {
528
+ $errorMessage .= $outOfStockItem . "\n";
529
+ }
530
+
531
+ echo $errorMessage;
532
+ }
533
+ else
534
+ {
535
+ echo "Success";
536
+ }
537
+ }
538
+ catch (Exception $e)
539
+ {
540
+ // Output error message
541
+ echo $e->getMessage(), "\n";
542
+ }
543
+ }
544
+
545
+ }
546
+
app/code/community/Poq/Integration/etc/config.xml CHANGED
@@ -1,49 +1,49 @@
1
- <?xml version="1.0"?>
2
- <!--
3
- /**
4
- * Module configuration
5
- *
6
- * @author Poq Studio
7
- */
8
- -->
9
- <config>
10
- <modules>
11
- <Poq_Integration>
12
- <version>2.1.0.0.0</version>
13
- </Poq_Integration>
14
- </modules>
15
- <global>
16
- <helpers>
17
- <poq_integration>
18
- <class>Poq_Integration_Helper</class>
19
- </poq_integration>
20
- </helpers>
21
- </global>
22
- <frontend>
23
- <routers>
24
- <poq_integration>
25
- <use>standard</use>
26
- <args>
27
- <module>Poq_Integration</module>
28
- <frontName>poq</frontName>
29
- </args>
30
- </poq_integration>
31
- </routers>
32
- </frontend>
33
- <default>
34
- <integration>
35
- <integration_feed_group>
36
- <integration_feed_taxrates_select>1</integration_feed_taxrates_select>
37
- </integration_feed_group>
38
- <integration_checkout_group>
39
- <integration_checkout_checkout_input><![CDATA[/checkout/]]></integration_checkout_checkout_input>
40
- <integration_checkout_requirehttps_select>0</integration_checkout_requirehttps_select>
41
- <integration_checkout_requiresignedrequest_select>0</integration_checkout_requiresignedrequest_select>
42
- <integration_checkout_limitreferrrer_select>0</integration_checkout_limitreferrrer_select>
43
- <integration_checkout_safereferrerlist_input></integration_checkout_safereferrerlist_input>
44
- <integration_checkout_trackingcode_input><![CDATA[tm_source=mobile&utm_campaign=poq]]></integration_checkout_trackingcode_input>
45
- <integration_checkout_sendorderemail_input>0</integration_checkout_sendorderemail_input>
46
- </integration_checkout_group>
47
- </integration>
48
- </default>
49
  </config>
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Module configuration
5
+ *
6
+ * @author Poq Studio
7
+ */
8
+ -->
9
+ <config>
10
+ <modules>
11
+ <Poq_Integration>
12
+ <version>2.0.0.2.4</version>
13
+ </Poq_Integration>
14
+ </modules>
15
+ <global>
16
+ <helpers>
17
+ <poq_integration>
18
+ <class>Poq_Integration_Helper</class>
19
+ </poq_integration>
20
+ </helpers>
21
+ </global>
22
+ <frontend>
23
+ <routers>
24
+ <poq_integration>
25
+ <use>standard</use>
26
+ <args>
27
+ <module>Poq_Integration</module>
28
+ <frontName>poq</frontName>
29
+ </args>
30
+ </poq_integration>
31
+ </routers>
32
+ </frontend>
33
+ <default>
34
+ <integration>
35
+ <integration_feed_group>
36
+ <integration_feed_taxrates_select>1</integration_feed_taxrates_select>
37
+ </integration_feed_group>
38
+ <integration_checkout_group>
39
+ <integration_checkout_checkout_input><![CDATA[/checkout/]]></integration_checkout_checkout_input>
40
+ <integration_checkout_requirehttps_select>0</integration_checkout_requirehttps_select>
41
+ <integration_checkout_requiresignedrequest_select>0</integration_checkout_requiresignedrequest_select>
42
+ <integration_checkout_limitreferrrer_select>0</integration_checkout_limitreferrrer_select>
43
+ <integration_checkout_safereferrerlist_input></integration_checkout_safereferrerlist_input>
44
+ <integration_checkout_trackingcode_input><![CDATA[tm_source=mobile&utm_campaign=poq]]></integration_checkout_trackingcode_input>
45
+ <integration_checkout_sendorderemail_input>0</integration_checkout_sendorderemail_input>
46
+ </integration_checkout_group>
47
+ </integration>
48
+ </default>
49
  </config>
app/code/community/Poq/Integration/etc/system.xml CHANGED
@@ -1,165 +1,192 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <config>
3
- <tabs>
4
- <integrationconfig translate="label" module="poq_integration">
5
- <label>POQ Studio</label>
6
- <sort_order>99999</sort_order>
7
- </integrationconfig>
8
- </tabs>
9
- <sections>
10
- <integration translate="label" module="poq_integration">
11
- <label>Integration Settings</label>
12
- <tab>integrationconfig</tab>
13
- <frontend_type>text</frontend_type>
14
- <sort_order>1000</sort_order>
15
- <show_in_default>1</show_in_default>
16
- <show_in_website>1</show_in_website>
17
- <show_in_store>1</show_in_store>
18
- <groups>
19
- <integration_feed_group translate="label" module="poq_integration">
20
- <label>Feed Settings</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
- <fields>
27
- <integration_feed_store_input translate="label">
28
- <label>Store Id: </label>
29
- <comment>Set store id if you prefer a specific store for feed integration. Otherwise, leave blank and let the default store will be used.</comment>
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
- </integration_feed_store_input>
36
- <integration_feed_image_url_input translate="label">
37
- <label>Image URL: </label>
38
- <comment>Set to override images location. Will try to auto-detect this value if not set.</comment>
39
- <frontend_type>text</frontend_type>
40
- <sort_order>21</sort_order>
41
- <show_in_default>1</show_in_default>
42
- <show_in_website>1</show_in_website>
43
- <show_in_store>1</show_in_store>
44
- </integration_feed_image_url_input>
45
- <integration_feed_image_ignore_input translate="label">
46
- <label>Ignore Images: </label>
47
- <comment>Comma-separated strings to filter out unwanted pictures.</comment>
48
- <frontend_type>text</frontend_type>
49
- <sort_order>22</sort_order>
50
- <show_in_default>1</show_in_default>
51
- <show_in_website>1</show_in_website>
52
- <show_in_store>1</show_in_store>
53
- </integration_feed_image_ignore_input>
54
- <integration_feed_taxrates_select translate="label">
55
- <label>Enable Tax Rate per Product</label>
56
- <comment>Set to apply custom tax rates to product prices.</comment>
57
- <frontend_type>select</frontend_type>
58
- <sort_order>23</sort_order>
59
- <show_in_default>1</show_in_default>
60
- <show_in_website>1</show_in_website>
61
- <show_in_store>1</show_in_store>
62
- <source_model>adminhtml/system_config_source_yesno</source_model>
63
- </integration_feed_taxrates_select>
64
- </fields>
65
- </integration_feed_group>
66
- <integration_checkout_group translate="label" module="poq_integration">
67
- <label>Checkout Settings</label>
68
- <frontend_type>text</frontend_type>
69
- <sort_order>1001</sort_order>
70
- <show_in_default>1</show_in_default>
71
- <show_in_website>1</show_in_website>
72
- <show_in_store>1</show_in_store>
73
- <fields>
74
- <integration_checkout_checkout_input translate="label">
75
- <label>Checkout URL </label>
76
- <comment>After the products are added to bag, user is redirect to this url for checkout.</comment>
77
- <frontend_type>text</frontend_type>
78
- <sort_order>20</sort_order>
79
- <show_in_default>1</show_in_default>
80
- <show_in_website>1</show_in_website>
81
- <show_in_store>1</show_in_store>
82
- </integration_checkout_checkout_input>
83
- <integration_checkout_trackingcode_input translate="label">
84
- <label>Tracking Code</label>
85
- <comment>If set, will be added to the checkout page URL.</comment>
86
- <frontend_type>text</frontend_type>
87
- <sort_order>26</sort_order>
88
- <show_in_default>1</show_in_default>
89
- <show_in_website>1</show_in_website>
90
- <show_in_store>1</show_in_store>
91
- </integration_checkout_trackingcode_input>
92
- <integration_checkout_sendorderemail_input translate="label">
93
- <label>Send Order E-mails</label>
94
- <comment>If set, will be sending order confirmation e-mails to the customers after the payment completed via mobile app.</comment>
95
- <frontend_type>select</frontend_type>
96
- <sort_order>27</sort_order>
97
- <show_in_default>1</show_in_default>
98
- <show_in_website>1</show_in_website>
99
- <show_in_store>1</show_in_store>
100
- <source_model>adminhtml/system_config_source_yesno</source_model>
101
- </integration_checkout_sendorderemail_input>
102
- </fields>
103
- </integration_checkout_group>
104
- <integration_checkoutsecurity_group translate="label" module="poq_integration">
105
- <label>Checkout Security Settings</label>
106
- <frontend_type>text</frontend_type>
107
- <sort_order>1002</sort_order>
108
- <show_in_default>1</show_in_default>
109
- <show_in_website>1</show_in_website>
110
- <show_in_store>1</show_in_store>
111
- <fields>
112
- <integration_checkout_requirehttps_select translate="label">
113
- <label>Require HTTPS</label>
114
- <comment>SSL-encrypted requests cannot be read by anyone else, and will not be stored in history.</comment>
115
- <frontend_type>select</frontend_type>
116
- <sort_order>21</sort_order>
117
- <show_in_default>1</show_in_default>
118
- <show_in_website>1</show_in_website>
119
- <show_in_store>1</show_in_store>
120
- <source_model>adminhtml/system_config_source_yesno</source_model>
121
- </integration_checkout_requirehttps_select>
122
- <integration_checkout_requiresignedrequest_select translate="label">
123
- <label>Require Signed Request</label>
124
- <comment>If enabled, will require the request to be signed for additional security.</comment>
125
- <frontend_type>select</frontend_type>
126
- <sort_order>22</sort_order>
127
- <show_in_default>1</show_in_default>
128
- <show_in_website>1</show_in_website>
129
- <show_in_store>1</show_in_store>
130
- <source_model>adminhtml/system_config_source_yesno</source_model>
131
- </integration_checkout_requiresignedrequest_select>
132
- <integration_checkout_signedrequeststring_input translate="label">
133
- <label>Signed Request Phrase</label>
134
- <comment>Please ask for this configuration value from Poq Studio</comment>
135
- <frontend_type>text</frontend_type>
136
- <sort_order>23</sort_order>
137
- <show_in_default>1</show_in_default>
138
- <show_in_website>1</show_in_website>
139
- <show_in_store>1</show_in_store>
140
- </integration_checkout_signedrequeststring_input>
141
- <integration_checkout_limitreferrrer_select translate="label">
142
- <label>Limit Referer</label>
143
- <comment>Enable this to require the request to come from a trusted source. </comment>
144
- <frontend_type>select</frontend_type>
145
- <sort_order>24</sort_order>
146
- <show_in_default>1</show_in_default>
147
- <show_in_website>1</show_in_website>
148
- <show_in_store>1</show_in_store>
149
- <source_model>adminhtml/system_config_source_yesno</source_model>
150
- </integration_checkout_limitreferrrer_select>
151
- <integration_checkout_safereferrerlist_input translate="label">
152
- <label>Safe Referer List</label>
153
- <comment>Add comma-seperated mobile website domains here. Only use this if you enable Limit Referer option.</comment>
154
- <frontend_type>text</frontend_type>
155
- <sort_order>25</sort_order>
156
- <show_in_default>1</show_in_default>
157
- <show_in_website>1</show_in_website>
158
- <show_in_store>1</show_in_store>
159
- </integration_checkout_safereferrerlist_input>
160
- </fields>
161
- </integration_checkoutsecurity_group>
162
- </groups>
163
- </integration>
164
- </sections>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  </config>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <integrationconfig translate="label" module="poq_integration">
5
+ <label>POQ Studio</label>
6
+ <sort_order>99999</sort_order>
7
+ </integrationconfig>
8
+ </tabs>
9
+ <sections>
10
+ <integration translate="label" module="poq_integration">
11
+ <label>Integration Settings</label>
12
+ <tab>integrationconfig</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>1000</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <integration_feed_group translate="label" module="poq_integration">
20
+ <label>Feed Settings</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
+ <fields>
27
+ <integration_feed_store_input translate="label">
28
+ <label>Store Id: </label>
29
+ <comment>Set store id if you prefer a specific store for feed integration. Otherwise, leave blank and let the default store will be used.</comment>
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
+ </integration_feed_store_input>
36
+ <integration_feed_image_url_input translate="label">
37
+ <label>Image URL: </label>
38
+ <comment>Set to override images location. Will try to auto-detect this value if not set.</comment>
39
+ <frontend_type>text</frontend_type>
40
+ <sort_order>21</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ </integration_feed_image_url_input>
45
+ <integration_feed_image_ignore_input translate="label">
46
+ <label>Ignore Images: </label>
47
+ <comment>Comma-separated strings to filter out unwanted pictures.</comment>
48
+ <frontend_type>text</frontend_type>
49
+ <sort_order>22</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>1</show_in_website>
52
+ <show_in_store>1</show_in_store>
53
+ </integration_feed_image_ignore_input>
54
+ <integration_feed_taxrates_select translate="label">
55
+ <label>Enable Tax Rate per Product</label>
56
+ <comment>Set to apply custom tax rates to product prices.</comment>
57
+ <frontend_type>select</frontend_type>
58
+ <sort_order>23</sort_order>
59
+ <show_in_default>1</show_in_default>
60
+ <show_in_website>1</show_in_website>
61
+ <show_in_store>1</show_in_store>
62
+ <source_model>adminhtml/system_config_source_yesno</source_model>
63
+ </integration_feed_taxrates_select>
64
+ <integration_feed_description_fields translate="label">
65
+ <label>Description Fields</label>
66
+ <comment>Comma-seperated strings to specify where description value for the products should pulled through. Leave blank for default.</comment>
67
+ <frontend_type>text</frontend_type>
68
+ <sort_order>24</sort_order>
69
+ <show_in_default>1</show_in_default>
70
+ <show_in_website>1</show_in_website>
71
+ <show_in_store>1</show_in_store>
72
+ </integration_feed_description_fields>
73
+ <integration_feed_description_values translate="label">
74
+ <label>Description Values</label>
75
+ <comment>Comma-seperated strings to specify description title in the feed. Number of values should match with number of description fields above, in order to show them in the feed.</comment>
76
+ <frontend_type>text</frontend_type>
77
+ <sort_order>25</sort_order>
78
+ <show_in_default>1</show_in_default>
79
+ <show_in_website>1</show_in_website>
80
+ <show_in_store>1</show_in_store>
81
+ </integration_feed_description_values>
82
+ <integration_feed_barcode_field translate="label">
83
+ <label>Barcode Field</label>
84
+ <comment>Set to add barcode into product feed.</comment>
85
+ <frontend_type>text</frontend_type>
86
+ <sort_order>26</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>1</show_in_store>
90
+ </integration_feed_barcode_field>
91
+ </fields>
92
+ </integration_feed_group>
93
+ <integration_checkout_group translate="label" module="poq_integration">
94
+ <label>Checkout Settings</label>
95
+ <frontend_type>text</frontend_type>
96
+ <sort_order>1001</sort_order>
97
+ <show_in_default>1</show_in_default>
98
+ <show_in_website>1</show_in_website>
99
+ <show_in_store>1</show_in_store>
100
+ <fields>
101
+ <integration_checkout_checkout_input translate="label">
102
+ <label>Checkout URL </label>
103
+ <comment>After the products are added to bag, user is redirect to this url for checkout.</comment>
104
+ <frontend_type>text</frontend_type>
105
+ <sort_order>20</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ </integration_checkout_checkout_input>
110
+ <integration_checkout_trackingcode_input translate="label">
111
+ <label>Tracking Code</label>
112
+ <comment>If set, will be added to the checkout page URL.</comment>
113
+ <frontend_type>text</frontend_type>
114
+ <sort_order>26</sort_order>
115
+ <show_in_default>1</show_in_default>
116
+ <show_in_website>1</show_in_website>
117
+ <show_in_store>1</show_in_store>
118
+ </integration_checkout_trackingcode_input>
119
+ <integration_checkout_sendorderemail_input translate="label">
120
+ <label>Send Order E-mails</label>
121
+ <comment>If set, will be sending order confirmation e-mails to the customers after the payment completed via mobile app.</comment>
122
+ <frontend_type>select</frontend_type>
123
+ <sort_order>27</sort_order>
124
+ <show_in_default>1</show_in_default>
125
+ <show_in_website>1</show_in_website>
126
+ <show_in_store>1</show_in_store>
127
+ <source_model>adminhtml/system_config_source_yesno</source_model>
128
+ </integration_checkout_sendorderemail_input>
129
+ </fields>
130
+ </integration_checkout_group>
131
+ <integration_checkoutsecurity_group translate="label" module="poq_integration">
132
+ <label>Checkout Security Settings</label>
133
+ <frontend_type>text</frontend_type>
134
+ <sort_order>1002</sort_order>
135
+ <show_in_default>1</show_in_default>
136
+ <show_in_website>1</show_in_website>
137
+ <show_in_store>1</show_in_store>
138
+ <fields>
139
+ <integration_checkout_requirehttps_select translate="label">
140
+ <label>Require HTTPS</label>
141
+ <comment>SSL-encrypted requests cannot be read by anyone else, and will not be stored in history.</comment>
142
+ <frontend_type>select</frontend_type>
143
+ <sort_order>21</sort_order>
144
+ <show_in_default>1</show_in_default>
145
+ <show_in_website>1</show_in_website>
146
+ <show_in_store>1</show_in_store>
147
+ <source_model>adminhtml/system_config_source_yesno</source_model>
148
+ </integration_checkout_requirehttps_select>
149
+ <integration_checkout_requiresignedrequest_select translate="label">
150
+ <label>Require Signed Request</label>
151
+ <comment>If enabled, will require the request to be signed for additional security.</comment>
152
+ <frontend_type>select</frontend_type>
153
+ <sort_order>22</sort_order>
154
+ <show_in_default>1</show_in_default>
155
+ <show_in_website>1</show_in_website>
156
+ <show_in_store>1</show_in_store>
157
+ <source_model>adminhtml/system_config_source_yesno</source_model>
158
+ </integration_checkout_requiresignedrequest_select>
159
+ <integration_checkout_signedrequeststring_input translate="label">
160
+ <label>Signed Request Phrase</label>
161
+ <comment>Please ask for this configuration value from Poq Studio</comment>
162
+ <frontend_type>text</frontend_type>
163
+ <sort_order>23</sort_order>
164
+ <show_in_default>1</show_in_default>
165
+ <show_in_website>1</show_in_website>
166
+ <show_in_store>1</show_in_store>
167
+ </integration_checkout_signedrequeststring_input>
168
+ <integration_checkout_limitreferrrer_select translate="label">
169
+ <label>Limit Referer</label>
170
+ <comment>Enable this to require the request to come from a trusted source. </comment>
171
+ <frontend_type>select</frontend_type>
172
+ <sort_order>24</sort_order>
173
+ <show_in_default>1</show_in_default>
174
+ <show_in_website>1</show_in_website>
175
+ <show_in_store>1</show_in_store>
176
+ <source_model>adminhtml/system_config_source_yesno</source_model>
177
+ </integration_checkout_limitreferrrer_select>
178
+ <integration_checkout_safereferrerlist_input translate="label">
179
+ <label>Safe Referer List</label>
180
+ <comment>Add comma-seperated mobile website domains here. Only use this if you enable Limit Referer option.</comment>
181
+ <frontend_type>text</frontend_type>
182
+ <sort_order>25</sort_order>
183
+ <show_in_default>1</show_in_default>
184
+ <show_in_website>1</show_in_website>
185
+ <show_in_store>1</show_in_store>
186
+ </integration_checkout_safereferrerlist_input>
187
+ </fields>
188
+ </integration_checkoutsecurity_group>
189
+ </groups>
190
+ </integration>
191
+ </sections>
192
  </config>
app/etc/modules/{Poq_Integration.xml → Poq_integration.xml} RENAMED
File without changes
package.xml CHANGED
@@ -1,18 +1,19 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Poq_Integration</name>
4
- <version>2.0.0.2.3</version>
5
  <stability>stable</stability>
6
  <license>ASL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>This integration forms a connection between the Magento and Poq Studio platforms.</summary>
10
  <description>The extension has two main features: Exposing your catalogue information in the Poq Feed Format and Accepting a shopping cart transfer from the Poq Studio platform.</description>
11
- <notes>Barcode data for products is now exported as EAN</notes>
 
12
  <authors><author><name>Oyvind Henriksen</name><user>poqmagento</user><email>info@poqstudio.com</email></author></authors>
13
- <date>2014-09-01</date>
14
- <time>12:42:51</time>
15
- <contents><target name="magecommunity"><dir name="Poq"><dir name="Integration"><dir name="Helper"><file name="Data.php" hash="c008f517ee4299385ac8887c9b7852dc"/></dir><dir name="controllers"><file name="IndexController.php" hash="945406d76a1857809db993bb47bda114"/><file name="OrderController.php" hash="e41bc679854fe870fb74fec4ec25de26"/></dir><dir name="etc"><file name="adminhtml.xml" hash="545b50fa7d354adb75a6bc27ff2ef41e"/><file name="config.xml" hash="f49058ef8c5cc6326367837c205e4029"/><file name="system.xml" hash="d4e53e147e5c76e6e9977382b31e005b"/></dir><file name=".DS_Store" hash="edbbdc9cbdcde369d585980e7a279eac"/></dir><file name=".DS_Store" hash="16eb133391c4355b50681fccd76eee48"/></dir></target><target name="mageetc"><dir name="modules"><file name="Poq_Integration.xml" hash="f735b9c01c16c559a05ba50185ef8a61"/></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Poq_Integration</name>
4
+ <version>2.0.0.2.4</version>
5
  <stability>stable</stability>
6
  <license>ASL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>This integration forms a connection between the Magento and Poq Studio platforms.</summary>
10
  <description>The extension has two main features: Exposing your catalogue information in the Poq Feed Format and Accepting a shopping cart transfer from the Poq Studio platform.</description>
11
+ <notes>- Minor bug fixes.&#xD;
12
+ - Product description and barcode fields configuration added.</notes>
13
  <authors><author><name>Oyvind Henriksen</name><user>poqmagento</user><email>info@poqstudio.com</email></author></authors>
14
+ <date>2014-10-30</date>
15
+ <time>11:40:13</time>
16
+ <contents><target name="magecommunity"><dir name="Poq"><dir name="Integration"><dir name="Helper"><file name="Data.php" hash="12410f17762f6ae40294252a0c383d87"/></dir><dir name="controllers"><file name="IndexController.php" hash="c7433ce5cf0b847f1f2fdb2b9b57e7d5"/><file name="OrderController.php" hash="2fe18c8f02b05440412f84df1bb6bc13"/></dir><dir name="etc"><file name="adminhtml.xml" hash="545b50fa7d354adb75a6bc27ff2ef41e"/><file name="config.xml" hash="8a63e106ffc41fd0d65e56e160d40026"/><file name="system.xml" hash="4c572e04c7adf4e6feb37385376134e2"/></dir><file name=".DS_Store" hash="edbbdc9cbdcde369d585980e7a279eac"/></dir><file name=".DS_Store" hash="16eb133391c4355b50681fccd76eee48"/></dir></target><target name="mageetc"><dir name="modules"><file name="Poq_integration.xml" hash="f735b9c01c16c559a05ba50185ef8a61"/></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
19
  </package>