Tritac_ChannelEngine - Version 3.0.0

Version Notes

* New tracking script

Download this release

Release Info

Developer Christiaan de Ridder
Extension Tritac_ChannelEngine
Version 3.0.0
Comparing to
See all releases


Code changes from version 2.7.1 to 3.0.0

Files changed (56) hide show
  1. app/code/community/Tritac/ChannelEngine/Block/Adminhtml/System/Config/Feed.php +53 -53
  2. app/code/community/Tritac/ChannelEngine/Block/Head.php +15 -10
  3. app/code/community/Tritac/ChannelEngine/Block/Sales/Order/Grid.php +0 -204
  4. app/code/community/Tritac/ChannelEngine/Helper/Data.php +105 -93
  5. app/code/community/Tritac/ChannelEngine/Model/Carrier/Channelengine.php +67 -67
  6. app/code/community/Tritac/ChannelEngine/Model/Observer.php +905 -905
  7. app/code/community/Tritac/ChannelEngine/Model/Order.php +31 -31
  8. app/code/community/Tritac/ChannelEngine/Model/Payment/Method/Channelengine.php +21 -21
  9. app/code/community/Tritac/ChannelEngine/Model/Resource/Order.php +59 -59
  10. app/code/community/Tritac/ChannelEngine/Model/Resource/Order/Collection.php +6 -6
  11. app/code/community/Tritac/ChannelEngine/Model/Resource/Setup.php +3 -3
  12. app/code/community/Tritac/ChannelEngine/Model/Resource/Shipment.php +33 -33
  13. app/code/community/Tritac/ChannelEngine/Model/Resource/Shipment/Collection.php +6 -6
  14. app/code/community/Tritac/ChannelEngine/Model/Shipment.php +19 -19
  15. app/code/community/Tritac/ChannelEngine/Model/System/Config/Source/Gtin.php +31 -31
  16. app/code/community/Tritac/ChannelEngine/Model/System/Config/Source/Shipping.php +39 -39
  17. app/code/community/Tritac/ChannelEngine/controllers/Adminhtml/GenerateController.php +11 -11
  18. app/code/community/Tritac/ChannelEngine/controllers/TestController.php +0 -372
  19. app/code/community/Tritac/ChannelEngine/etc/adminhtml.xml +24 -24
  20. app/code/community/Tritac/ChannelEngine/etc/config.xml +194 -194
  21. app/code/community/Tritac/ChannelEngine/etc/system.xml +144 -144
  22. app/code/community/Tritac/ChannelEngine/sql/channelengine_setup/mysql4-install-1.0.0.php +55 -55
  23. app/code/community/Tritac/ChannelEngine/sql/channelengine_setup/mysql4-upgrade-2.6.0-2.7.0.php +24 -24
  24. app/design/adminhtml/default/default/template/channelengine/system/config/feed/generate_button.phtml +40 -40
  25. app/design/frontend/base/default/layout/channelengine.xml +17 -17
  26. app/design/frontend/base/default/template/channelengine/checkout/success.phtml +42 -30
  27. app/design/frontend/base/default/template/channelengine/head.phtml +13 -2
  28. app/etc/modules/Tritac_ChannelEngine.xml +9 -9
  29. lib/Tritac/ChannelEngineApiClient/Client.php +281 -281
  30. lib/Tritac/ChannelEngineApiClient/Enums/CancellationLineStatus.php +8 -8
  31. lib/Tritac/ChannelEngineApiClient/Enums/CancellationStatus.php +8 -8
  32. lib/Tritac/ChannelEngineApiClient/Enums/Gender.php +7 -7
  33. lib/Tritac/ChannelEngineApiClient/Enums/MancoReason.php +7 -7
  34. lib/Tritac/ChannelEngineApiClient/Enums/OrderStatus.php +12 -12
  35. lib/Tritac/ChannelEngineApiClient/Enums/ReturnAcceptStatus.php +5 -5
  36. lib/Tritac/ChannelEngineApiClient/Enums/ReturnReason.php +9 -9
  37. lib/Tritac/ChannelEngineApiClient/Enums/ReturnStatus.php +5 -5
  38. lib/Tritac/ChannelEngineApiClient/Enums/ShipmentLineStatus.php +7 -7
  39. lib/Tritac/ChannelEngineApiClient/Enums/ShipmentStatus.php +4 -4
  40. lib/Tritac/ChannelEngineApiClient/Helpers/Collection.php +48 -48
  41. lib/Tritac/ChannelEngineApiClient/Helpers/HttpMethod.php +8 -8
  42. lib/Tritac/ChannelEngineApiClient/Helpers/JsonMapper.php +90 -90
  43. lib/Tritac/ChannelEngineApiClient/Models/Address.php +96 -96
  44. lib/Tritac/ChannelEngineApiClient/Models/BaseModel.php +23 -23
  45. lib/Tritac/ChannelEngineApiClient/Models/Cancellation.php +39 -39
  46. lib/Tritac/ChannelEngineApiClient/Models/CancellationLine.php +33 -33
  47. lib/Tritac/ChannelEngineApiClient/Models/Message.php +11 -11
  48. lib/Tritac/ChannelEngineApiClient/Models/Order.php +153 -153
  49. lib/Tritac/ChannelEngineApiClient/Models/OrderExtraDataItem.php +18 -18
  50. lib/Tritac/ChannelEngineApiClient/Models/OrderLine.php +145 -145
  51. lib/Tritac/ChannelEngineApiClient/Models/ReturnLine.php +46 -46
  52. lib/Tritac/ChannelEngineApiClient/Models/ReturnObject.php +64 -64
  53. lib/Tritac/ChannelEngineApiClient/Models/Shipment.php +73 -73
  54. lib/Tritac/ChannelEngineApiClient/Models/ShipmentLine.php +47 -47
  55. lib/Tritac/ChannelEngineApiClient/loader.php +13 -13
  56. package.xml +5 -5
app/code/community/Tritac/ChannelEngine/Block/Adminhtml/System/Config/Feed.php CHANGED
@@ -1,53 +1,53 @@
1
- <?php
2
- /**
3
- * Adminhtml system "generate feed" button
4
- *
5
- * @category Tritac
6
- * @package Tritac_ChannelEngine
7
- */
8
- class Tritac_ChannelEngine_Block_Adminhtml_System_Config_Feed extends Mage_Adminhtml_Block_System_Config_Form_Field
9
- {
10
- /**
11
- * Set template block template
12
- *
13
- * @return Tritac_ChannelEngine_Block_Adminhtml_System_Config_Feed
14
- */
15
- protected function _prepareLayout()
16
- {
17
- parent::_prepareLayout();
18
- if (!$this->getTemplate()) {
19
- $this->setTemplate('channelengine/system/config/feed/generate_button.phtml');
20
- }
21
- return $this;
22
- }
23
-
24
- /**
25
- * Disable website scope
26
- *
27
- * @param Varien_Data_Form_Element_Abstract $element
28
- * @return string
29
- */
30
- public function render(Varien_Data_Form_Element_Abstract $element)
31
- {
32
- $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
33
- return parent::render($element);
34
- }
35
-
36
- /**
37
- * Get the button and scripts contents
38
- *
39
- * @param Varien_Data_Form_Element_Abstract $element
40
- * @return string
41
- */
42
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
43
- {
44
- $originalData = $element->getOriginalData();
45
- $this->addData(array(
46
- 'button_label' => Mage::helper('channelengine')->__($originalData['button_label']),
47
- 'html_id' => $element->getHtmlId(),
48
- 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('channelengine/adminhtml_generate/ajax')
49
- ));
50
-
51
- return $this->_toHtml();
52
- }
53
- }
1
+ <?php
2
+ /**
3
+ * Adminhtml system "generate feed" button
4
+ *
5
+ * @category Tritac
6
+ * @package Tritac_ChannelEngine
7
+ */
8
+ class Tritac_ChannelEngine_Block_Adminhtml_System_Config_Feed extends Mage_Adminhtml_Block_System_Config_Form_Field
9
+ {
10
+ /**
11
+ * Set template block template
12
+ *
13
+ * @return Tritac_ChannelEngine_Block_Adminhtml_System_Config_Feed
14
+ */
15
+ protected function _prepareLayout()
16
+ {
17
+ parent::_prepareLayout();
18
+ if (!$this->getTemplate()) {
19
+ $this->setTemplate('channelengine/system/config/feed/generate_button.phtml');
20
+ }
21
+ return $this;
22
+ }
23
+
24
+ /**
25
+ * Disable website scope
26
+ *
27
+ * @param Varien_Data_Form_Element_Abstract $element
28
+ * @return string
29
+ */
30
+ public function render(Varien_Data_Form_Element_Abstract $element)
31
+ {
32
+ $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
33
+ return parent::render($element);
34
+ }
35
+
36
+ /**
37
+ * Get the button and scripts contents
38
+ *
39
+ * @param Varien_Data_Form_Element_Abstract $element
40
+ * @return string
41
+ */
42
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
43
+ {
44
+ $originalData = $element->getOriginalData();
45
+ $this->addData(array(
46
+ 'button_label' => Mage::helper('channelengine')->__($originalData['button_label']),
47
+ 'html_id' => $element->getHtmlId(),
48
+ 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('channelengine/adminhtml_generate/ajax')
49
+ ));
50
+
51
+ return $this->_toHtml();
52
+ }
53
+ }
app/code/community/Tritac/ChannelEngine/Block/Head.php CHANGED
@@ -1,11 +1,16 @@
1
- <?php
2
- class Tritac_ChannelEngine_Block_Head extends Mage_Core_Block_Template
3
- {
4
- public function getAccountName() {
5
-
6
- $storeId = Mage::app()->getStore()->getId();
7
- $config = Mage::helper('channelengine')->getGeneralConfig();
8
-
9
- return $config[$storeId]['tenant'];
10
- }
 
 
 
 
 
11
  }
1
+ <?php
2
+ class Tritac_ChannelEngine_Block_Head extends Mage_Core_Block_Template
3
+ {
4
+ public function getAccountName() {
5
+
6
+ $storeId = Mage::app()->getStore()->getId();
7
+ $config = Mage::helper('channelengine')->getGeneralConfig();
8
+
9
+ return $config[$storeId]['tenant'];
10
+ }
11
+
12
+ public function getEnvironment()
13
+ {
14
+ return Mage::helper('channelengine')->isDevelopment() ? 'development' : 'production';
15
+ }
16
  }
app/code/community/Tritac/ChannelEngine/Block/Sales/Order/Grid.php DELETED
@@ -1,204 +0,0 @@
1
- <?php
2
- class Tritac_ChannelEngine_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid {
3
-
4
- public function __construct()
5
- {
6
- parent::__construct();
7
- $this->setId('sales_order_grid');
8
- $this->setUseAjax(true);
9
- $this->setDefaultSort('created_at');
10
- $this->setDefaultDir('DESC');
11
- $this->setSaveParametersInSession(true);
12
- }
13
-
14
- /**
15
- * Retrieve collection class
16
- *
17
- * @return string
18
- */
19
- protected function _getCollectionClass()
20
- {
21
- return 'sales/order_grid_collection';
22
- }
23
-
24
- protected function _prepareCollection()
25
- {
26
- $collection = Mage::getResourceModel($this->_getCollectionClass());
27
- $joinTableName = Mage::getSingleton('core/resource')->getTableName('channelengine/order');
28
- $collection->getSelect()->joinLeft(
29
- array('channel_order_table' => $joinTableName),
30
- 'channel_order_table.order_id=main_table.entity_id',
31
- array('channel_name', 'channel_order_id')
32
- );
33
- $this->setCollection($collection);
34
- return parent::_prepareCollection();
35
- }
36
-
37
- protected function _prepareColumns()
38
- {
39
- $this->addColumn('real_order_id', array(
40
- 'header'=> Mage::helper('sales')->__('Order #'),
41
- 'width' => '80px',
42
- 'type' => 'text',
43
- 'index' => 'increment_id',
44
- ));
45
-
46
- $this->addColumn('channel_order_id', array(
47
- 'header'=> Mage::helper('sales')->__('ChannelEngine Order ID'),
48
- 'width' => '80px',
49
- 'type' => 'text',
50
- 'index' => 'channel_order_id',
51
- ));
52
-
53
- $this->addColumn('channel_name', array(
54
- 'header'=> Mage::helper('sales')->__('Channel Name'),
55
- 'width' => '80px',
56
- 'type' => 'text',
57
- 'index' => 'channel_name',
58
- ));
59
-
60
- if (!Mage::app()->isSingleStoreMode()) {
61
- $this->addColumn('store_id', array(
62
- 'header' => Mage::helper('sales')->__('Purchased From (Store)'),
63
- 'index' => 'store_id',
64
- 'type' => 'store',
65
- 'store_view'=> true,
66
- 'display_deleted' => true,
67
- ));
68
- }
69
-
70
- $this->addColumn('created_at', array(
71
- 'header' => Mage::helper('sales')->__('Purchased On'),
72
- 'index' => 'created_at',
73
- 'type' => 'datetime',
74
- 'width' => '100px',
75
- ));
76
-
77
- $this->addColumn('billing_name', array(
78
- 'header' => Mage::helper('sales')->__('Bill to Name'),
79
- 'index' => 'billing_name',
80
- ));
81
-
82
- $this->addColumn('shipping_name', array(
83
- 'header' => Mage::helper('sales')->__('Ship to Name'),
84
- 'index' => 'shipping_name',
85
- ));
86
-
87
- $this->addColumn('base_grand_total', array(
88
- 'header' => Mage::helper('sales')->__('G.T. (Base)'),
89
- 'index' => 'base_grand_total',
90
- 'type' => 'currency',
91
- 'currency' => 'base_currency_code',
92
- ));
93
-
94
- $this->addColumn('grand_total', array(
95
- 'header' => Mage::helper('sales')->__('G.T. (Purchased)'),
96
- 'index' => 'grand_total',
97
- 'type' => 'currency',
98
- 'currency' => 'order_currency_code',
99
- ));
100
-
101
- $this->addColumn('status', array(
102
- 'header' => Mage::helper('sales')->__('Status'),
103
- 'index' => 'status',
104
- 'type' => 'options',
105
- 'width' => '70px',
106
- 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
107
- ));
108
-
109
- if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
110
- $this->addColumn('action',
111
- array(
112
- 'header' => Mage::helper('sales')->__('Action'),
113
- 'width' => '50px',
114
- 'type' => 'action',
115
- 'getter' => 'getId',
116
- 'actions' => array(
117
- array(
118
- 'caption' => Mage::helper('sales')->__('View'),
119
- 'url' => array('base'=>'*/sales_order/view'),
120
- 'field' => 'order_id'
121
- )
122
- ),
123
- 'filter' => false,
124
- 'sortable' => false,
125
- 'index' => 'stores',
126
- 'is_system' => true,
127
- ));
128
- }
129
- $this->addRssList('rss/order/new', Mage::helper('sales')->__('New Order RSS'));
130
-
131
- $this->addExportType('*/*/exportCsv', Mage::helper('sales')->__('CSV'));
132
- $this->addExportType('*/*/exportExcel', Mage::helper('sales')->__('Excel XML'));
133
-
134
- return parent::_prepareColumns();
135
- }
136
-
137
- protected function _prepareMassaction()
138
- {
139
- $this->setMassactionIdField('entity_id');
140
- $this->getMassactionBlock()->setFormFieldName('order_ids');
141
- $this->getMassactionBlock()->setUseSelectAll(false);
142
-
143
- if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/cancel')) {
144
- $this->getMassactionBlock()->addItem('cancel_order', array(
145
- 'label'=> Mage::helper('sales')->__('Cancel'),
146
- 'url' => $this->getUrl('*/sales_order/massCancel'),
147
- ));
148
- }
149
-
150
- if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/hold')) {
151
- $this->getMassactionBlock()->addItem('hold_order', array(
152
- 'label'=> Mage::helper('sales')->__('Hold'),
153
- 'url' => $this->getUrl('*/sales_order/massHold'),
154
- ));
155
- }
156
-
157
- if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/unhold')) {
158
- $this->getMassactionBlock()->addItem('unhold_order', array(
159
- 'label'=> Mage::helper('sales')->__('Unhold'),
160
- 'url' => $this->getUrl('*/sales_order/massUnhold'),
161
- ));
162
- }
163
-
164
- $this->getMassactionBlock()->addItem('pdfinvoices_order', array(
165
- 'label'=> Mage::helper('sales')->__('Print Invoices'),
166
- 'url' => $this->getUrl('*/sales_order/pdfinvoices'),
167
- ));
168
-
169
- $this->getMassactionBlock()->addItem('pdfshipments_order', array(
170
- 'label'=> Mage::helper('sales')->__('Print Packingslips'),
171
- 'url' => $this->getUrl('*/sales_order/pdfshipments'),
172
- ));
173
-
174
- $this->getMassactionBlock()->addItem('pdfcreditmemos_order', array(
175
- 'label'=> Mage::helper('sales')->__('Print Credit Memos'),
176
- 'url' => $this->getUrl('*/sales_order/pdfcreditmemos'),
177
- ));
178
-
179
- $this->getMassactionBlock()->addItem('pdfdocs_order', array(
180
- 'label'=> Mage::helper('sales')->__('Print All'),
181
- 'url' => $this->getUrl('*/sales_order/pdfdocs'),
182
- ));
183
-
184
- $this->getMassactionBlock()->addItem('print_shipping_label', array(
185
- 'label'=> Mage::helper('sales')->__('Print Shipping Labels'),
186
- 'url' => $this->getUrl('*/sales_order_shipment/massPrintShippingLabel'),
187
- ));
188
-
189
- return $this;
190
- }
191
-
192
- public function getRowUrl($row)
193
- {
194
- if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
195
- return $this->getUrl('*/sales_order/view', array('order_id' => $row->getId()));
196
- }
197
- return false;
198
- }
199
-
200
- public function getGridUrl()
201
- {
202
- return $this->getUrl('*/*/grid', array('_current'=>true));
203
- }
204
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Tritac/ChannelEngine/Helper/Data.php CHANGED
@@ -1,94 +1,106 @@
1
- <?php
2
- class Tritac_ChannelEngine_Helper_Data extends Mage_Core_Helper_Abstract {
3
-
4
- protected $_config = null;
5
-
6
- /**
7
- * Default expected shipment time (in weekdays)
8
- *
9
- * @var int
10
- */
11
- protected $_defaultTimeToShip = 5;
12
-
13
- /**
14
- * Get extension general config
15
- *
16
- * @param null $storeId
17
- * @return array
18
- */
19
- public function getConfig($storeId = null)
20
- {
21
- if(empty($this->_config)) {
22
- foreach(Mage::app()->getStores() as $_store) {
23
- $this->_config[$_store->getId()] = Mage::getStoreConfig('channelengine', $_store->getId());
24
- }
25
- }
26
-
27
- if($storeId) {
28
- if(!isset($this->_config[$storeId])) {
29
- return false;
30
- }else{
31
- return $this->_config[$storeId];
32
- }
33
- }
34
-
35
- return $this->_config;
36
- }
37
-
38
- /**
39
- * Get extension general config
40
- *
41
- * @return array
42
- */
43
- public function getGeneralConfig()
44
- {
45
- $result = array();
46
-
47
- foreach($this->getConfig() as $storeId => $storeConfig) {
48
- $result[$storeId] = $storeConfig['general'];
49
- }
50
-
51
- return $result;
52
- }
53
-
54
- /**
55
- * Check required general config data
56
- *
57
- * @param null $storeId
58
- * @return bool
59
- */
60
- public function checkGeneralConfig($storeId = null)
61
- {
62
- $config = Mage::getStoreConfig('channelengine/general', $storeId);
63
-
64
- if(empty($config['api_key']) || empty($config['api_secret']) || empty($config['tenant'])) {
65
- $storeMsg = ($storeId) ? 'for store '.$storeId : '';
66
- Mage::log(
67
- "Couldn't connect to ChannelEngine.
68
- Please specify account keys {$storeMsg}
69
- (System/Configuration/Tritac ChannelEngine/Settings/General)"
70
- );
71
- return false;
72
- }
73
-
74
- return true;
75
- }
76
-
77
- /**
78
- * Get store expected shipment text
79
- *
80
- * @param $store_id
81
- * @return DateTime
82
- */
83
- public function getExpectedShipmentDate($store_id)
84
- {
85
- $config = $this->getConfig($store_id);
86
-
87
- $weekdays = (int) $config['shipping']['expected_date'];
88
- if($weekdays <= 0)
89
- $weekdays = $this->_defaultTimeToShip;
90
-
91
- $expectedDate = date("Y-m-d", strtotime("{$weekdays} weekdays"));
92
- return new DateTime($expectedDate);
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
1
+ <?php
2
+ class Tritac_ChannelEngine_Helper_Data extends Mage_Core_Helper_Abstract {
3
+
4
+ protected $_config = null;
5
+
6
+ /**
7
+ * Default expected shipment time (in weekdays)
8
+ *
9
+ * @var int
10
+ */
11
+ protected $_defaultTimeToShip = 5;
12
+
13
+ /**
14
+ * Get extension general config
15
+ *
16
+ * @param null $storeId
17
+ * @return array
18
+ */
19
+ public function getConfig($storeId = null)
20
+ {
21
+ if(empty($this->_config)) {
22
+ foreach(Mage::app()->getStores() as $_store) {
23
+ $this->_config[$_store->getId()] = Mage::getStoreConfig('channelengine', $_store->getId());
24
+ }
25
+ }
26
+
27
+ if($storeId) {
28
+ if(!isset($this->_config[$storeId])) {
29
+ return false;
30
+ }else{
31
+ return $this->_config[$storeId];
32
+ }
33
+ }
34
+
35
+ return $this->_config;
36
+ }
37
+
38
+ /**
39
+ * Get extension general config
40
+ *
41
+ * @return bool
42
+ */
43
+ public function isDevelopment()
44
+ {
45
+ $machines = array('tritac-ssd16');
46
+ $machine = gethostname();
47
+ return in_array($machine, $machines);
48
+ }
49
+
50
+ /**
51
+ * Get extension general config
52
+ *
53
+ * @return array
54
+ */
55
+ public function getGeneralConfig()
56
+ {
57
+ $result = array();
58
+
59
+ foreach($this->getConfig() as $storeId => $storeConfig) {
60
+ $result[$storeId] = $storeConfig['general'];
61
+ }
62
+
63
+ return $result;
64
+ }
65
+
66
+ /**
67
+ * Check required general config data
68
+ *
69
+ * @param null $storeId
70
+ * @return bool
71
+ */
72
+ public function checkGeneralConfig($storeId = null)
73
+ {
74
+ $config = Mage::getStoreConfig('channelengine/general', $storeId);
75
+
76
+ if(empty($config['api_key']) || empty($config['api_secret']) || empty($config['tenant'])) {
77
+ $storeMsg = ($storeId) ? 'for store '.$storeId : '';
78
+ Mage::log(
79
+ "Couldn't connect to ChannelEngine.
80
+ Please specify account keys {$storeMsg}
81
+ (System/Configuration/Tritac ChannelEngine/Settings/General)"
82
+ );
83
+ return false;
84
+ }
85
+
86
+ return true;
87
+ }
88
+
89
+ /**
90
+ * Get store expected shipment text
91
+ *
92
+ * @param $store_id
93
+ * @return DateTime
94
+ */
95
+ public function getExpectedShipmentDate($store_id)
96
+ {
97
+ $config = $this->getConfig($store_id);
98
+
99
+ $weekdays = (int) $config['shipping']['expected_date'];
100
+ if($weekdays <= 0)
101
+ $weekdays = $this->_defaultTimeToShip;
102
+
103
+ $expectedDate = date("Y-m-d", strtotime("{$weekdays} weekdays"));
104
+ return new DateTime($expectedDate);
105
+ }
106
  }
app/code/community/Tritac/ChannelEngine/Model/Carrier/Channelengine.php CHANGED
@@ -1,67 +1,67 @@
1
- <?php
2
- class Tritac_ChannelEngine_Model_Carrier_Channelengine
3
- extends Mage_Shipping_Model_Carrier_Abstract
4
- implements Mage_Shipping_Model_Carrier_Interface
5
- {
6
-
7
- /** @var string Shipping method system code*/
8
- protected $_code = 'channelengine';
9
-
10
- protected $_isFixed = true;
11
-
12
- /**
13
- * Collect and get shipping rates
14
- *
15
- * @param Mage_Shipping_Model_Rate_Request $request
16
- * @return bool|false|Mage_Core_Model_Abstract|Mage_Shipping_Model_Rate_Result|null
17
- */
18
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
19
- {
20
- if (!$this->getConfigFlag('active')) {
21
- return false;
22
- }
23
-
24
- // Check if the rates were requested by ChannelEngine and not by the frontend
25
- if(!Mage::registry('channelengine_shipping')){
26
- return false;
27
- }
28
- Mage::unregister('channelengine_shipping');
29
-
30
- $result = Mage::getModel('shipping/rate_result');
31
-
32
- $shippingPrice = 0;
33
-
34
- if(Mage::registry('channelengine_shipping_amount')) {
35
- $shippingPrice = Mage::registry('channelengine_shipping_amount');
36
- }
37
- Mage::unregister('channelengine_shipping_amount');
38
-
39
-
40
- $method = Mage::getModel('shipping/rate_result_method');
41
-
42
- $method->setCarrier($this->_code);
43
- $method->setCarrierTitle($this->getConfigData('title'));
44
-
45
- $method->setMethod($this->_code);
46
- $method->setMethodTitle($this->getConfigData('name'));
47
-
48
- $method->setPrice($shippingPrice);
49
- $method->setCost($shippingPrice);
50
-
51
- $result->append($method);
52
-
53
-
54
- return $result;
55
- }
56
-
57
- public function isActive()
58
- {
59
-
60
- }
61
-
62
- public function getAllowedMethods()
63
- {
64
- return array('channelengine'=>'ChannelEngine');
65
- }
66
-
67
- }
1
+ <?php
2
+ class Tritac_ChannelEngine_Model_Carrier_Channelengine
3
+ extends Mage_Shipping_Model_Carrier_Abstract
4
+ implements Mage_Shipping_Model_Carrier_Interface
5
+ {
6
+
7
+ /** @var string Shipping method system code*/
8
+ protected $_code = 'channelengine';
9
+
10
+ protected $_isFixed = true;
11
+
12
+ /**
13
+ * Collect and get shipping rates
14
+ *
15
+ * @param Mage_Shipping_Model_Rate_Request $request
16
+ * @return bool|false|Mage_Core_Model_Abstract|Mage_Shipping_Model_Rate_Result|null
17
+ */
18
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request)
19
+ {
20
+ if (!$this->getConfigFlag('active')) {
21
+ return false;
22
+ }
23
+
24
+ // Check if the rates were requested by ChannelEngine and not by the frontend
25
+ if(!Mage::registry('channelengine_shipping')){
26
+ return false;
27
+ }
28
+ Mage::unregister('channelengine_shipping');
29
+
30
+ $result = Mage::getModel('shipping/rate_result');
31
+
32
+ $shippingPrice = 0;
33
+
34
+ if(Mage::registry('channelengine_shipping_amount')) {
35
+ $shippingPrice = Mage::registry('channelengine_shipping_amount');
36
+ }
37
+ Mage::unregister('channelengine_shipping_amount');
38
+
39
+
40
+ $method = Mage::getModel('shipping/rate_result_method');
41
+
42
+ $method->setCarrier($this->_code);
43
+ $method->setCarrierTitle($this->getConfigData('title'));
44
+
45
+ $method->setMethod($this->_code);
46
+ $method->setMethodTitle($this->getConfigData('name'));
47
+
48
+ $method->setPrice($shippingPrice);
49
+ $method->setCost($shippingPrice);
50
+
51
+ $result->append($method);
52
+
53
+
54
+ return $result;
55
+ }
56
+
57
+ public function isActive()
58
+ {
59
+
60
+ }
61
+
62
+ public function getAllowedMethods()
63
+ {
64
+ return array('channelengine'=>'ChannelEngine');
65
+ }
66
+
67
+ }
app/code/community/Tritac/ChannelEngine/Model/Observer.php CHANGED
@@ -1,905 +1,905 @@
1
- <?php
2
- /**
3
- * Observer model
4
- */
5
- class Tritac_ChannelEngine_Model_Observer
6
- {
7
- /**
8
- * API client
9
- *
10
- * @var Tritac_ChannelEngineApiClient_Client
11
- */
12
- protected $_client = null;
13
-
14
- /**
15
- * API config. API key, API secret, API tenant
16
- *
17
- * @var array
18
- */
19
- protected $_config = null;
20
-
21
- /**
22
- * ChannelEngine helper
23
- *
24
- * @var Tritac_ChannelEngine_Helper_Data
25
- */
26
- protected $_helper = null;
27
-
28
- const ATTRIBUTES_LIMIT = 30;
29
-
30
- /**
31
- * Retrieve and validate API config
32
- * Initialize API client
33
- */
34
- public function __construct()
35
- {
36
- $this->_helper = Mage::helper('channelengine');
37
- $this->_config = $this->_helper->getConfig();
38
- /**
39
- * Check required config parameters. Initialize API client.
40
- */
41
- foreach($this->_config as $storeId => $storeConfig) {
42
- if($this->_helper->checkGeneralConfig($storeId)) {
43
- $this->_client[$storeId] = new Tritac_ChannelEngineApiClient_Client(
44
- $storeConfig['general']['api_key'],
45
- $storeConfig['general']['api_secret'],
46
- $storeConfig['general']['tenant']
47
- );
48
- }
49
- }
50
- }
51
-
52
- /**
53
- * Fetch new orders from ChannelEngine.
54
- * Ran by cron. The cronjob is set in extension config file.
55
- *
56
- * @return bool
57
- */
58
- public function fetchNewOrders()
59
- {
60
- /**
61
- * Check if client is initialized
62
- */
63
- if(is_null($this->_client))
64
- return false;
65
-
66
- foreach($this->_client as $storeId => $_client) {
67
- /**
68
- * Retrieve new orders
69
- */
70
- $orders = $_client->getOrders(array(
71
- Tritac_ChannelEngineApiClient_Enums_OrderStatus::NEW_ORDER
72
- ));
73
-
74
- /**
75
- * Check new orders existing
76
- */
77
- if(is_null($orders) || $orders->count() == 0)
78
- continue;
79
-
80
- Mage::log("Received {$orders->count()} orders from ChannelEngine.");
81
-
82
- foreach($orders as $order) {
83
-
84
- $billingAddress = $order->getBillingAddress();
85
- $shippingAddress = $order->getShippingAddress();
86
- if(empty($billingAddress)) continue;
87
-
88
- $lines = $order->getLines();
89
-
90
- if(!empty($lines)) {
91
-
92
- // Initialize new quote
93
- $quote = Mage::getModel('sales/quote')->setStoreId($storeId);
94
-
95
- foreach($lines as $item) {
96
-
97
- $productNo = $item->getMerchantProductNo();
98
- $ids = explode('_', $productNo);
99
- $productId = $ids[0];
100
- // Load magento product
101
- $_product = Mage::getModel('catalog/product')
102
- ->setStoreId($storeId);
103
- $productOptions = array();
104
- $_product->load($productId);
105
- if(count($ids) == 3) {
106
- $productOptions = array($ids[1] => intval($ids[2]));
107
- }
108
-
109
- // Prepare product parameters for quote
110
- $params = new Varien_Object();
111
- $params->setQty($item->getQuantity());
112
- $params->setOptions($productOptions);
113
-
114
- // Add product to quote
115
- try {
116
- $_quoteItem = $quote->addProduct($_product, $params);
117
-
118
- if(is_string($_quoteItem)) {
119
- // Magento sometimes returns a string when the method fails. -_-"
120
- Mage::throwException('Failed to create quote item: ' . $_quoteItem);
121
- }
122
-
123
- $_quoteItem->setChannelengineOrderLineId($item->getId());
124
-
125
- } catch (Exception $e) {
126
-
127
- Mage::getModel('adminnotification/inbox')->addCritical(
128
- "An order (#{$order->getId()}) could not be imported",
129
- "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
130
- );
131
- Mage::logException($e);
132
- continue 2;
133
- }
134
- }
135
- }
136
-
137
- $phone = $order->getPhone();
138
- if(empty($phone))
139
- $phone = '-';
140
- // Prepare billing and shipping addresses
141
- $billingData = array(
142
- 'firstname' => $billingAddress->getFirstName(),
143
- 'lastname' => $billingAddress->getLastName(),
144
- 'email' => $order->getEmail(),
145
- 'telephone' => $phone,
146
- 'country_id' => $billingAddress->getCountryIso(),
147
- 'postcode' => $billingAddress->getZipCode(),
148
- 'city' => $billingAddress->getCity(),
149
- 'street' =>
150
- $billingAddress->getStreetName().' '.
151
- $billingAddress->getHouseNr().
152
- $billingAddress->getHouseNrAddition()
153
- );
154
- $shippingData = array(
155
- 'firstname' => $shippingAddress->getFirstName(),
156
- 'lastname' => $shippingAddress->getLastName(),
157
- 'email' => $order->getEmail(),
158
- 'telephone' => $phone,
159
- 'country_id' => $shippingAddress->getCountryIso(),
160
- 'postcode' => $shippingAddress->getZipCode(),
161
- 'city' => $shippingAddress->getCity(),
162
- 'street' =>
163
- $shippingAddress->getStreetName().' '.
164
- $shippingAddress->getHouseNr().
165
- $shippingAddress->getHouseNrAddition()
166
- );
167
-
168
- // Register shipping cost. See Tritac_ChannelEngine_Model_Carrier_Channelengine::collectrates();
169
- Mage::register('channelengine_shipping_amount', floatval($order->getShippingCostsInclVat()));
170
- // Set this value to make sure ChannelEngine requested the rates and not the frontend
171
- // because the shipping method has a fallback on 0,- and this will make it show up on the frontend
172
- Mage::register('channelengine_shipping', true);
173
-
174
- $quote->getBillingAddress()
175
- ->addData($billingData);
176
- $quote->getShippingAddress()
177
- ->addData($shippingData)
178
- ->setSaveInAddressBook(0)
179
- ->setCollectShippingRates(true)
180
- ->setShippingMethod('channelengine_channelengine');
181
-
182
- $quote->collectTotals();
183
-
184
- // Set guest customer
185
- $quote->setCustomerId(null)
186
- ->setCustomerEmail($quote->getBillingAddress()->getEmail())
187
- ->setCustomerIsGuest(true)
188
- ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
189
-
190
- // Set custom payment method
191
- $quote->setIsSystem(true);
192
- $quote->getPayment()->importData(array('method' => 'channelengine'));
193
-
194
- // Save quote and convert it to new order
195
- try {
196
-
197
- $quote->save();
198
-
199
- $service = Mage::getModel('sales/service_quote', $quote);
200
-
201
- $service->submitAll();
202
-
203
- } catch (Exception $e) {
204
- Mage::getModel('adminnotification/inbox')->addCritical(
205
- "An order (#{$order->getId()}) could not be imported",
206
- "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
207
- );
208
- Mage::logException($e);
209
- continue;
210
- }
211
-
212
- $_order = $service->getOrder();
213
-
214
-
215
- if($_order->getIncrementId()) {
216
-
217
- /**
218
- * Create new invoice and save channel order
219
- */
220
- try {
221
- // Initialize new invoice model
222
- $invoice = Mage::getModel('sales/service_order', $_order)->prepareInvoice();
223
- // Add comment to invoice
224
- $invoice->addComment(
225
- "Order paid on the marketplace.",
226
- false,
227
- true
228
- );
229
-
230
- // Register invoice. Register invoice items. Collect invoice totals.
231
- $invoice->register();
232
- $invoice->getOrder()->setIsInProcess(true);
233
-
234
- // Initialize new channel order
235
- $_channelOrder = Mage::getModel('channelengine/order');
236
- $_channelOrder->setOrderId($_order->getId())
237
- ->setChannelOrderId($order->getId())
238
- ->setChannelName($order->getChannelName())
239
- ->setDoSendMails($order->getDoSendMails())
240
- ->setCanShipPartial($order->getCanShipPartialOrderLines());
241
-
242
- $invoice->getOrder()
243
- ->setCanShipPartiallyItem($order->getCanShipPartialOrderLines())
244
- ->setCanShipPartially($order->getCanShipPartialOrderLines());
245
-
246
- // Start new transaction
247
- $transactionSave = Mage::getModel('core/resource_transaction')
248
- ->addObject($invoice)
249
- ->addObject($invoice->getOrder())
250
- ->addObject($_channelOrder);
251
- $transactionSave->save();
252
-
253
- } catch (Exception $e) {
254
- Mage::getModel('adminnotification/inbox')->addCritical(
255
- "An invoice could not be created (order #{$_order->getIncrementId()}, channel order #{$order->getId()})",
256
- "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
257
- );
258
- Mage::logException($e);
259
- continue;
260
- }
261
- Mage::log("Order #{$_order->getIncrementId()} was imported successfully.");
262
- } else {
263
- Mage::log("An order (#{$order->getId()}) could not be imported");
264
- }
265
- }
266
- }
267
-
268
- return true;
269
- }
270
-
271
- /**
272
- * Post new shipment to ChannelEngine. This function is set in extension config file.
273
- *
274
- * @param Varien_Event_Observer $observer
275
- * @return bool
276
- * @throws Exception
277
- */
278
- public function saveShipment(Varien_Event_Observer $observer)
279
- {
280
- Mage::log('--------------------------------------');
281
- $event = $observer->getEvent();
282
- /** @var $_shipment Mage_Sales_Model_Order_Shipment */
283
- $_shipment = $event->getShipment();
284
-
285
- /** @var $_order Mage_Sales_Model_Order */
286
- $_order = $_shipment->getOrder();
287
-
288
- $storeId = $_order->getStoreId();
289
-
290
- $ceOrder = Mage::getModel('channelengine/order')->loadByOrderId($_order->getId());
291
- $ceOrderId = $ceOrder->getChannelOrderId();
292
-
293
- if(!$ceOrderId) return false;
294
-
295
- // Check if the API client was initialized for this order
296
- if(!isset($this->_client[$storeId])) return false;
297
-
298
- // Initialize new ChannelEngine shipment object
299
- $ceShipment = new Tritac_ChannelEngineApiClient_Models_Shipment();
300
- $ceShipment->setOrderId($ceOrderId);
301
- $ceShipment->setMerchantShipmentNo($_shipment->getId());
302
-
303
- // Set tracking info if available
304
- $trackingCode = null;
305
- $trackingCodes = $_shipment->getAllTracks();
306
- if(count($trackingCodes) > 0) {
307
-
308
- $trackingCode = $trackingCodes[0];
309
- $ceShipment->setTrackTraceNo($trackingCode->getNumber());
310
- $ceShipment->setMethod($trackingCode->getTitle());
311
- }
312
-
313
- // If the shipment is already known to ChannelEngine we will just update it
314
- $_channelShipment = Mage::getModel('channelengine/shipment')->loadByShipmentId($_shipment->getId());
315
-
316
- if($_channelShipment->getId() != null) {
317
-
318
- if($trackingCode != null) {
319
- Mage::Log("TrackTrace: {$trackingCode->getNumber()}");
320
- }
321
-
322
- Mage::log("CE Shipment Id: #{$_channelShipment->getChannelengineShipmentId()}");
323
- $ceShipment->setId($_channelShipment->getChannelengineShipmentId());
324
- $this->_client[$storeId]->putShipment($ceShipment);
325
- return true;
326
- }
327
-
328
- Mage::log('New shipment, continue');
329
-
330
- // Add the shipment lines
331
- $ceShipmentLines = new Tritac_ChannelEngineApiClient_Helpers_Collection('Tritac_ChannelEngineApiClient_Models_ShipmentLine');
332
- foreach($_shipment->getAllItems() as $_shipmentItem) {
333
-
334
- // Get the quantity for this shipment
335
- $shippedQty = (int)$_shipmentItem->getQty();
336
- if($shippedQty == 0) continue;
337
-
338
- // Get the original order item
339
- $_orderItem = Mage::getModel('sales/order_item')->load($_shipmentItem->getOrderItemId());
340
- if($_orderItem == null) continue;
341
-
342
- $ceShipmentLine = new Tritac_ChannelEngineApiClient_Models_ShipmentLine();
343
- $ceShipmentLine->setOrderLineId($_orderItem->getChannelengineOrderLineId());
344
- $ceShipmentLine->setQuantity($shippedQty);
345
- $ceShipmentLine->setStatus(Tritac_ChannelEngineApiClient_Enums_ShipmentLineStatus::SHIPPED);
346
-
347
- $ceShipmentLines->append($ceShipmentLine);
348
- }
349
-
350
- // Check if there are any shipment lines
351
- if(count($ceShipmentLines) == 0) return false;
352
-
353
- $ceShipment->setLines($ceShipmentLines);
354
-
355
- // Post shipment to ChannelEngine
356
- try{
357
-
358
- $result = $this->_client[$storeId]->postShipment($ceShipment);
359
- if($result == null) return false;
360
-
361
- $_channelShipment = Mage::getModel('channelengine/shipment')
362
- ->setShipmentId($_shipment->getId())
363
- ->setChannelengineShipmentId($result->getId());
364
- $_channelShipment->save();
365
-
366
- Mage::log("Shipment #{$_shipment->getId()} (CE #{$result->getId()}) was placed successfully.");
367
-
368
-
369
-
370
- } catch(Exception $e) {
371
-
372
- Mage::getModel('adminnotification/inbox')->addCritical(
373
- "A shipment (#{$_shipment->getId()}) could not be exported",
374
- "Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
375
- );
376
-
377
- Mage::logException($e);
378
-
379
- }
380
-
381
-
382
- return true;
383
- }
384
-
385
- /**
386
- * Fetch new returns from channelengine
387
- *
388
- * @return bool
389
- */
390
- public function fetchReturns()
391
- {
392
- /**
393
- * Check if client is initialized
394
- */
395
- if(is_null($this->_client))
396
- return false;
397
-
398
- foreach($this->_client as $storeId => $_client) {
399
- /**
400
- * Retrieve returns
401
- */
402
- $returns = $_client->getReturns(array(
403
- Tritac_ChannelEngineApiClient_Enums_ReturnStatus::DECLARED
404
- ));
405
-
406
- /**
407
- * Check declared returns
408
- */
409
- if(is_null($returns) || $returns->count() == 0)
410
- return false;
411
-
412
- foreach($returns as $return) {
413
- $_channelOrder = Mage::getModel('channelengine/order')->loadByChannelOrderId($return->getOrderId());
414
- $_order = Mage::getModel('sales/order')->load($_channelOrder->getOrderId());
415
-
416
- if(!$_order->getIncrementId()) {
417
- continue;
418
- }
419
-
420
-
421
- $link = "https://". $this->_config[$storeId]['general']['tenant'] .".channelengine.net/orders/view/". $return->getOrderId();
422
- $status = $return->getStatus(); // Get return status
423
- $reason = $return->getReason(); // Get return reason
424
- $title = "A new return was declared in ChannelEngine (ChannelEngine Order #{$return->getOrderId()})";
425
- $message = "Magento Order #: <a href='".
426
- Mage::helper('adminhtml')->getUrl('adminhtml/sales_order/view', array('order_id'=>$_order->getOrderId())).
427
- "'>".
428
- $_order->getIncrementId().
429
- "</a><br />";
430
- $message .= "Status: {$status}<br />";
431
- $message .= "Reason: {$reason}<br />";
432
- $message .= "For more details visit ChannelEngine your <a href='".$link."' target='_blank'>account</a>";
433
-
434
- // Check if notification is already exist
435
- $_resource = Mage::getSingleton('core/resource');
436
- $_connectionRead = $_resource->getConnection('core_read');
437
- $select = $_connectionRead->select()
438
- ->from($_resource->getTableName('adminnotification/inbox'))
439
- ->where('title = ?', $title)
440
- ->where('is_remove != 1')
441
- ->limit(1);
442
- $data = $_connectionRead->fetchRow($select);
443
-
444
- if ($data) {
445
- continue;
446
- }
447
-
448
- // Add new notification
449
- Mage::getModel('adminnotification/inbox')->addCritical(
450
- $title,
451
- $message,
452
- $link
453
- );
454
- }
455
- }
456
- }
457
-
458
- /**
459
- * Generate products feed for ChannelEngine
460
- */
461
- public function generateFeed()
462
- {
463
- $start_memory = memory_get_usage();
464
-
465
- /**
466
- * Prepare categories array
467
- */
468
- $categoryArray = array();
469
- $parent = Mage::app()->getWebsite(true)->getDefaultStore()->getRootCategoryId();
470
- $category = Mage::getModel('catalog/category');
471
- if ($category->checkId($parent)) {
472
- $storeCategories = $category->getCategories($parent, 0, true, true, true);
473
- foreach($storeCategories as $_category) {
474
- $categoryArray[$_category->getId()] = $_category->getData();
475
- }
476
- }
477
-
478
- /**
479
- * Prepare products relation
480
- */
481
- // $productsRelation = array();
482
- // $_resource = Mage::getSingleton('core/resource');
483
- // $_connection = $_resource->getConnection('core_read');
484
- // $relations = $_connection->fetchAll("SELECT * FROM " . $_resource->getTableName('catalog/product_relation'));
485
- // foreach($relations as $relation) {
486
- // $productsRelation[$relation['child_id']] = $relation['parent_id'];
487
- // }
488
-
489
- /**
490
- * Export products from each store.
491
- * Note: products with undefined website id will not be export.
492
- */
493
- foreach(Mage::app()->getStores() as $_store) {
494
- Mage::app()->setCurrentStore($_store);
495
- $path = Mage::getBaseDir('media') . DS . 'channelengine' . DS;
496
- $storeConfig = $this->_helper->getConfig($_store->getId());
497
- $name = $storeConfig['general']['tenant'].'_products.xml';
498
- $file = $path . DS . $name;
499
-
500
- $io = new Varien_Io_File();
501
- $io->setAllowCreateFolders(true);
502
- $io->open(array('path' => $path));
503
- $io->streamOpen($file, 'w+');
504
- $io->streamLock(true);
505
- $io->streamWrite('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
506
- $io->streamWrite('<Products xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n");
507
-
508
- /**
509
- * Prepare custom options array
510
- */
511
- $storeId = $_store->getId();
512
- $optionsArray = array();
513
- $_options = Mage::getModel('catalog/product_option')
514
- ->getCollection()
515
- ->addTitleToResult($storeId)
516
- ->addPriceToResult($storeId)
517
- ->addValuesToResult($storeId)
518
- ->setOrder('sort_order', 'asc');
519
- foreach($_options as $_option) {
520
- $productId = $_option->getProductId();
521
- $optionId = $_option->getOptionId();
522
- $optionsArray[$productId][$optionId] = $_option->getData();
523
- if($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {
524
- $optionsArray[$productId][$optionId]['values'] = $_option->getValues();
525
- }
526
- }
527
-
528
- /**
529
- * Retrieve product collection with all visible attributes
530
- */
531
- if(Mage::helper('catalog/product_flat')->isEnabled($storeId)) {
532
- Mage::getResourceSingleton('catalog/product_flat')->setStoreId($storeId);
533
- }
534
- $collection = Mage::getModel('catalog/product')->getCollection();
535
-
536
- if(Mage::helper('catalog/product_flat')->isEnabled($storeId)) {
537
- $collection->getEntity()->setStoreId($storeId);
538
- }
539
-
540
- $systemAttributes = $attributesToSelect = array(
541
- 'name',
542
- 'description',
543
- 'image',
544
- 'url_key',
545
- 'price',
546
- 'cost',
547
- 'special_price',
548
- 'special_from_date',
549
- 'special_to_date',
550
- 'visibility',
551
- 'msrp'
552
- );
553
-
554
- $visibleAttributes = array();
555
- $attributes = Mage::getSingleton('eav/config')
556
- ->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getAttributeCollection();
557
-
558
- foreach($attributes as $attribute) {
559
- if( ($attribute->getIsVisible() && $attribute->getIsVisibleOnFront())
560
- || in_array($attribute->getAttributeCode(), $systemAttributes))
561
- {
562
- $code = $attribute->getAttributeCode();
563
- $visibleAttributes[$code]['label'] = $attribute->getFrontendLabel();
564
-
565
- foreach( $attribute->getSource()->getAllOptions(false) as $option ) {
566
- $visibleAttributes[$code]['values'][$option['value']] = $option['label'];
567
- }
568
- if(!in_array($code, $attributesToSelect)) {
569
- $attributesToSelect[] = $code;
570
- }
571
- }
572
- }
573
-
574
- if(!empty($this->_config[$storeId]['feed']['gtin'])) {
575
- $attributesToSelect[] = $this->_config[$storeId]['feed']['gtin'];
576
- }
577
-
578
- if( (count($attributesToSelect) > self::ATTRIBUTES_LIMIT) && !$collection->isEnabledFlat()) {
579
- $error = $this->_helper->__('Too many visible attributes. Please enable catalog product flat mode.');
580
- Mage::getSingleton('adminhtml/session')->addError($error);
581
- echo 'redirect';
582
- return false;
583
- }
584
-
585
- $collection->addAttributeToSelect($attributesToSelect, 'left')
586
- ->addFieldToFilter('type_id', array('in' => array('simple')))
587
- ->addStoreFilter($_store)
588
- ->addAttributeToFilter('status', 1)
589
- ->addAttributeToFilter('visibility', array('in' => array('2', '3', '4')))
590
- ->addAttributeToSort('entity_id', 'DESC');
591
-
592
- // Add qty and category fields to select
593
- $collection->getSelect()
594
- ->joinLeft(
595
- array('csi' => Mage::getSingleton('core/resource')->getTableName('cataloginventory/stock_item')),
596
- '`e`.`entity_id` = `csi`.`product_id`',
597
- array('qty' => 'COALESCE(`qty`, 0)')
598
- )
599
- ->joinLeft(
600
- array('ccp' => Mage::getSingleton('core/resource')->getTableName('catalog/category_product')),
601
- '`e`.`entity_id` = `ccp`.`product_id`',
602
- array('category_id' => 'MAX(`ccp`.`category_id`)')
603
- )
604
- ->group('e.entity_id');
605
-
606
- Mage::getSingleton('core/resource_iterator')->walk(
607
- $collection->getSelect(),
608
- array(array($this, 'callbackGenerateFeed')),
609
- array(
610
- 'io' => $io,
611
- 'categories' => $categoryArray,
612
- 'attributes' => $visibleAttributes,
613
- 'systemAttributes' => $systemAttributes,
614
- 'options' => $optionsArray,
615
- 'store' => $_store,
616
- 'startMemory' => $start_memory,
617
- )
618
- );
619
-
620
- $collection->clear()->getSelect()->reset('where');
621
- $collection->addFieldToFilter('type_id', array('in' => array('configurable')))
622
- ->addStoreFilter($_store)
623
- ->addAttributeToFilter('status', 1)
624
- ->addAttributeToSort('entity_id', 'DESC');
625
-
626
- foreach($collection as $_product) {
627
- $productAttributeOptions = $_product->getTypeInstance(true)->getConfigurableAttributesAsArray($_product);
628
- $superAttributes = array();
629
-
630
- foreach($productAttributeOptions as $superAttribute) {
631
- foreach($superAttribute['values'] as $value) {
632
- $superAttributes[$superAttribute['attribute_code']][$value['value_index']] = $value;
633
- }
634
- }
635
-
636
- $parentData = $_product->getData();
637
- $parentData['id'] = $parentData['entity_id'];
638
-
639
- $productModel = Mage::getModel('catalog/product');
640
- $productModel->setData('entity_id', $parentData['entity_id']);
641
- $productModel->setData('url_key', $parentData['url_key']);
642
- $productModel->setData('store_id', $parentData['store_id']);
643
- $parentData['url'] = $productModel->getProductUrl();
644
-
645
- $specialPrice = $parentData['special_price'];
646
- $specialFrom = $parentData['special_from_date'];
647
- $specialTo = $parentData['special_to_date'];
648
- $parentData['price'] = Mage::getModel('catalog/product_type_price')
649
- ->calculateSpecialPrice($parentData['price'], $specialPrice, $specialFrom, $specialTo, $storeId);
650
-
651
- $xml = $this->_getProductXml($parentData, $categoryArray, array('systemAttributes' => $systemAttributes, 'attributes' => $visibleAttributes));
652
- $_childProducts = Mage::getModel('catalog/product_type_configurable')
653
- ->getUsedProducts(null, $_product);
654
-
655
- foreach($_childProducts as $_child) {
656
- $childData = $_child->getData();
657
- $childData['id'] = $childData['entity_id'];
658
- $childData['parent_id'] = $parentData['id'];
659
- $childData['price'] = $parentData['price'];
660
- $childData['url'] = $parentData['url'];
661
- $childData['description'] = $parentData['description'];
662
-
663
- if(!isset($childData['image']) || $childData['image'] == 'no_slection') {
664
- $childData['image'] = $parentData['image'];
665
- }
666
-
667
- foreach($superAttributes as $code => $superAttribute) {
668
- if(isset($childData[$code])) {
669
- $priceValue = $superAttribute[$childData[$code]]['pricing_value'];
670
- if($superAttribute[$childData[$code]]['is_percent']) {
671
- $newPrice = $childData['price'] + $childData['price'] * $priceValue / 100;
672
- } else {
673
- $newPrice = $childData['price'] + $priceValue;
674
- }
675
- $childData['price'] = $newPrice;
676
- }
677
- }
678
- $xml .= $this->_getProductXml($childData, $categoryArray, array('systemAttributes' => $systemAttributes, 'attributes' => $visibleAttributes));
679
- }
680
- $io->streamWrite($xml);
681
- }
682
-
683
-
684
- $io->streamWrite('</Products>');
685
- $io->streamUnlock();
686
- $io->streamClose();
687
-
688
- Mage::log("Product feed {$name} was generated successfully");
689
- }
690
-
691
- return true;
692
- }
693
-
694
- public function callbackGenerateFeed($args)
695
- {
696
- $io = $args['io'];
697
- $product = $args['row'];
698
- $attributes = $args['attributes'];
699
- $systemAttributes = $args['systemAttributes'];
700
- $categories = $args['categories'];
701
- $options = $args['options'];
702
- $_store = $args['store'];
703
- $storeId = $_store->getId();
704
-
705
- $xml = '';
706
-
707
- $product['store_id'] = $storeId;
708
- if(!empty($this->_config[$storeId]['feed']['gtin'])) {
709
- $product['gtin'] = $product[$this->_config[$storeId]['feed']['gtin']];
710
- }
711
-
712
- $specialPrice = $product['special_price'];
713
- $specialFrom = $product['special_from_date'];
714
- $specialTo = $product['special_to_date'];
715
- $product['price'] = Mage::getModel('catalog/product_type_price')
716
- ->calculateSpecialPrice($product['price'], $specialPrice, $specialFrom, $specialTo, $storeId);
717
-
718
- $productModel = Mage::getModel('catalog/product');
719
- $productModel->setData('entity_id', $product['entity_id']);
720
- $productModel->setData('url_key', $product['url_key']);
721
- $productModel->setData('store_id', $product['store_id']);
722
- $product['url'] = $productModel->getProductUrl();
723
-
724
- /**
725
- * Add product custom options to feed.
726
- * Each option value will generate new product row
727
- */
728
- $additional['systemAttributes'] = $systemAttributes;
729
- $additional['attributes'] = $attributes;
730
- if(isset($options[$product['entity_id']])) {
731
- $product['group_code'] = $product['entity_id'];
732
- foreach($options[$product['entity_id']] as $option) {
733
- if(isset($option['values'])) {
734
- foreach($option['values'] as $_value) {
735
- $product['id'] = $product['entity_id'].'_'.$option['option_id'].'_'.$_value->getId();
736
- $additional['title'] = str_replace(' ', '_', $option['default_title']);
737
- $additional['value'] = $_value->getDefaultTitle();
738
- $xml .= $this->_getProductXml($product, $categories, $additional);
739
- }
740
- } else {
741
- $product['id'] = $product['entity_id'].'_'.$option['option_id'];
742
- $additional['title'] = str_replace(' ', '_', $option['default_title']);
743
- $additional['value'] = '';
744
- $xml .= $this->_getProductXml($product, $categories, $additional);
745
- }
746
- }
747
- }else {
748
- $product['id'] = $product['entity_id'];
749
- $xml .= $this->_getProductXml($product, $categories, $additional);
750
- }
751
-
752
- $io->streamWrite($xml);
753
- }
754
-
755
- protected function _getProductXml($product, $categories, $additional = null)
756
- {
757
- $xml = "<Product>";
758
- $xml .= "<Id>".$product['id']."</Id>";
759
-
760
- // Add group code with product id if product have custom options
761
- if(isset($product['group_code'])) {
762
- $xml .= "<GroupCode><![CDATA[".$product['group_code']."]]></GroupCode>";
763
- }
764
- if(isset($product['parent_id'])) {
765
- $xml .= "<ParentId><![CDATA[".$product['parent_id']."]]></ParentId>";
766
- }
767
- $xml .= "<Type><![CDATA[".$product['type_id']."]]></Type>";
768
- $xml .= "<Name><![CDATA[".$product['name']."]]></Name>";
769
- $xml .= "<Description><![CDATA[".$product['description']."]]></Description>";
770
- $xml .= "<Price><![CDATA[".$product['price']."]]></Price>";
771
- $xml .= "<ListPrice><![CDATA[".$product['msrp']."]]></ListPrice>";
772
- $xml .= "<PurchasePrice><![CDATA[".$product['cost']."]]></PurchasePrice>";
773
-
774
- // Add product stock qty
775
- $xml .= "<Stock><![CDATA[".$product['qty']."]]></Stock>";
776
- // Add product SKU and GTIN
777
- $xml .= "<SKU><![CDATA[".$product['sku']."]]></SKU>";
778
- if(!empty($product['gtin'])) {
779
- $xml .= "<GTIN><![CDATA[".$product['gtin']."]]></GTIN>";
780
- }
781
-
782
- // VAT and Shipping Time are pre configured in extension settings
783
- if(!empty($this->_config[$product['store_id']]['feed']['vat_rate'])) {
784
- $vat = $this->_config[$product['store_id']]['feed']['vat_rate'];
785
- $xml .= "<VAT><![CDATA[".$vat."]]></VAT>";
786
- }
787
-
788
- $shippingTime = ($product['qty'] > 0) ? $this->_config[$product['store_id']]['feed']['shipping_time'] : $this->_config[$product['store_id']]['feed']['shipping_time_oos'];
789
-
790
- if($shippingTime) {
791
- $xml .= "<ShippingTime><![CDATA[".$shippingTime."]]></ShippingTime>";
792
- }
793
-
794
- $xml .= "<Url><![CDATA[".$product['url']."]]></Url>";
795
-
796
- if(isset($product['image']) && $product['image'] != 'no_selection') {
797
- $imgUrl = Mage::getSingleton('catalog/product_media_config')->getMediaUrl($product['image']);
798
- $xml .= "<ImageUrl><![CDATA[".$imgUrl."]]></ImageUrl>";
799
- }
800
-
801
- // Prepare category path
802
- if(!empty($product['category_id']) && !empty($categories)) {
803
- $categoryId = $product['category_id'];
804
- $categoryPathIds = explode('/', $categories[$categoryId]['path']);
805
- $categoryPath = null;
806
- foreach($categoryPathIds as $id) {
807
- if($id > 2) {
808
- $categoryPath .= ($categoryPath) ? ' > ':'';
809
- $categoryPath .= $categories[$id]['name'];
810
- }
811
- }
812
- if($categoryPath) {
813
- $xml .= "<Category><![CDATA[".$categoryPath."]]></Category>";
814
- }
815
- }
816
-
817
- if(isset($additional['title']) && isset($additional['value'])) {
818
- $title = preg_replace("/[^a-zA-Z0-9]/", "", $additional['title']);
819
- $xml .= sprintf("<%1\$s><![CDATA[%2\$s]]></%1\$s>",
820
- $title,
821
- $additional['value']
822
- );
823
- }
824
-
825
- /*
826
- * Prepare product visible attributes
827
- */
828
- if(isset($additional['attributes'])) {
829
- $xml .= '<Attributes>';
830
- foreach($additional['attributes'] as $code => $attribute) {
831
- if(isset($product[$code]) && !in_array($code, $additional['systemAttributes'])) {
832
- $xml .= "<".$code.">";
833
- /*$xml .= "<label><![CDATA[".$attribute['label']."]]></label>";
834
- if(!empty($attribute['values'])) {
835
- $xml .= "<value><![CDATA[".$attribute['values'][$product[$code]]."]]></value>";
836
- } else {
837
- $xml .= "<value><![CDATA[".$product[$code]."]]></value>";
838
- }*/
839
- if(!empty($attribute['values'])) {
840
- $xml .= "<![CDATA[".$attribute['values'][$product[$code]]."]]>";
841
- } else {
842
- $xml .= "<![CDATA[".$product[$code]."]]>";
843
- }
844
- $xml .= "</".$code.">";
845
- }
846
- }
847
- $xml .= '</Attributes>';
848
- }
849
-
850
- $xml .= "</Product>\n";
851
-
852
- return $xml;
853
- }
854
-
855
- public function addConfigurableProducts($collection)
856
- {
857
-
858
- }
859
-
860
- /**
861
- * Join channelengine order fields to adminhtml order grid
862
- *
863
- * @param $observer
864
- */
865
- /*public function prepareOrderGridCollection($observer)
866
- {
867
- $collection = $observer->getOrderGridCollection();
868
- $joinTableName = Mage::getSingleton('core/resource')->getTableName('channelengine/order');
869
- $collection->getSelect()->joinLeft(
870
- array('channel_order_table' => $joinTableName),
871
- 'channel_order_table.order_id=main_table.entity_id',
872
- array('channel_name', 'channel_order_id')
873
- );
874
- }*/
875
-
876
- /**
877
- * Add channelengine order fields to adminhtml order grid
878
- *
879
- * @param $observer
880
- * @return $this
881
- */
882
- /*public function appendCustomColumnToOrderGrid($observer)
883
- {
884
- $block = $observer->getBlock();
885
- if (!isset($block)) {
886
- return $this;
887
- }
888
-
889
- if ($block->getType() == 'adminhtml/sales_order_grid') {
890
- $block->addColumnAfter('channel_order_id', array(
891
- 'header'=> Mage::helper('sales')->__('ChannelEngine Order ID'),
892
- 'width' => '80px',
893
- 'type' => 'text',
894
- 'index' => 'channel_order_id',
895
- ), 'real_order_id');
896
-
897
- $block->addColumnAfter('channel_name', array(
898
- 'header'=> Mage::helper('sales')->__('Channel Name'),
899
- 'width' => '80px',
900
- 'type' => 'text',
901
- 'index' => 'channel_name',
902
- ), 'real_order_id');
903
- }
904
- }*/
905
- }
1
+ <?php
2
+ /**
3
+ * Observer model
4
+ */
5
+ class Tritac_ChannelEngine_Model_Observer
6
+ {
7
+ /**
8
+ * API client
9
+ *
10
+ * @var Tritac_ChannelEngineApiClient_Client
11
+ */
12
+ protected $_client = null;
13
+
14
+ /**
15
+ * API config. API key, API secret, API tenant
16
+ *
17
+ * @var array
18
+ */
19
+ protected $_config = null;
20
+
21
+ /**
22
+ * ChannelEngine helper
23
+ *
24
+ * @var Tritac_ChannelEngine_Helper_Data
25
+ */
26
+ protected $_helper = null;
27
+
28
+ const ATTRIBUTES_LIMIT = 30;
29
+
30
+ /**
31
+ * Retrieve and validate API config
32
+ * Initialize API client
33
+ */
34
+ public function __construct()
35
+ {
36
+ $this->_helper = Mage::helper('channelengine');
37
+ $this->_config = $this->_helper->getConfig();
38
+ /**
39
+ * Check required config parameters. Initialize API client.
40
+ */
41
+ foreach($this->_config as $storeId => $storeConfig) {
42
+ if($this->_helper->checkGeneralConfig($storeId)) {
43
+ $this->_client[$storeId] = new Tritac_ChannelEngineApiClient_Client(
44
+ $storeConfig['general']['api_key'],
45
+ $storeConfig['general']['api_secret'],
46
+ $storeConfig['general']['tenant']
47
+ );
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Fetch new orders from ChannelEngine.
54
+ * Ran by cron. The cronjob is set in extension config file.
55
+ *
56
+ * @return bool
57
+ */
58
+ public function fetchNewOrders()
59
+ {
60
+ /**
61
+ * Check if client is initialized
62
+ */
63
+ if(is_null($this->_client))
64
+ return false;
65
+
66
+ foreach($this->_client as $storeId => $_client) {
67
+ /**
68
+ * Retrieve new orders
69
+ */
70
+ $orders = $_client->getOrders(array(
71
+ Tritac_ChannelEngineApiClient_Enums_OrderStatus::NEW_ORDER
72
+ ));
73
+
74
+ /**
75
+ * Check new orders existing
76
+ */
77
+ if(is_null($orders) || $orders->count() == 0)
78
+ continue;
79
+
80
+ Mage::log("Received {$orders->count()} orders from ChannelEngine.");
81
+
82
+ foreach($orders as $order) {
83
+
84
+ $billingAddress = $order->getBillingAddress();
85
+ $shippingAddress = $order->getShippingAddress();
86
+ if(empty($billingAddress)) continue;
87
+
88
+ $lines = $order->getLines();
89
+
90
+ if(!empty($lines)) {
91
+
92
+ // Initialize new quote
93
+ $quote = Mage::getModel('sales/quote')->setStoreId($storeId);
94
+
95
+ foreach($lines as $item) {
96
+
97
+ $productNo = $item->getMerchantProductNo();
98
+ $ids = explode('_', $productNo);
99
+ $productId = $ids[0];
100
+ // Load magento product
101
+ $_product = Mage::getModel('catalog/product')
102
+ ->setStoreId($storeId);
103
+ $productOptions = array();
104
+ $_product->load($productId);
105
+ if(count($ids) == 3) {
106
+ $productOptions = array($ids[1] => intval($ids[2]));
107
+ }
108
+
109
+ // Prepare product parameters for quote
110
+ $params = new Varien_Object();
111
+ $params->setQty($item->getQuantity());
112
+ $params->setOptions($productOptions);
113
+
114
+ // Add product to quote
115
+ try {
116
+ $_quoteItem = $quote->addProduct($_product, $params);
117
+
118
+ if(is_string($_quoteItem)) {
119
+ // Magento sometimes returns a string when the method fails. -_-"
120
+ Mage::throwException('Failed to create quote item: ' . $_quoteItem);
121
+ }
122
+
123
+ $_quoteItem->setChannelengineOrderLineId($item->getId());
124
+
125
+ } catch (Exception $e) {
126
+
127
+ Mage::getModel('adminnotification/inbox')->addCritical(
128
+ "An order (#{$order->getId()}) could not be imported",
129
+ "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
130
+ );
131
+ Mage::logException($e);
132
+ continue 2;
133
+ }
134
+ }
135
+ }
136
+
137
+ $phone = $order->getPhone();
138
+ if(empty($phone))
139
+ $phone = '-';
140
+ // Prepare billing and shipping addresses
141
+ $billingData = array(
142
+ 'firstname' => $billingAddress->getFirstName(),
143
+ 'lastname' => $billingAddress->getLastName(),
144
+ 'email' => $order->getEmail(),
145
+ 'telephone' => $phone,
146
+ 'country_id' => $billingAddress->getCountryIso(),
147
+ 'postcode' => $billingAddress->getZipCode(),
148
+ 'city' => $billingAddress->getCity(),
149
+ 'street' =>
150
+ $billingAddress->getStreetName().' '.
151
+ $billingAddress->getHouseNr().
152
+ $billingAddress->getHouseNrAddition()
153
+ );
154
+ $shippingData = array(
155
+ 'firstname' => $shippingAddress->getFirstName(),
156
+ 'lastname' => $shippingAddress->getLastName(),
157
+ 'email' => $order->getEmail(),
158
+ 'telephone' => $phone,
159
+ 'country_id' => $shippingAddress->getCountryIso(),
160
+ 'postcode' => $shippingAddress->getZipCode(),
161
+ 'city' => $shippingAddress->getCity(),
162
+ 'street' =>
163
+ $shippingAddress->getStreetName().' '.
164
+ $shippingAddress->getHouseNr().
165
+ $shippingAddress->getHouseNrAddition()
166
+ );
167
+
168
+ // Register shipping cost. See Tritac_ChannelEngine_Model_Carrier_Channelengine::collectrates();
169
+ Mage::register('channelengine_shipping_amount', floatval($order->getShippingCostsInclVat()));
170
+ // Set this value to make sure ChannelEngine requested the rates and not the frontend
171
+ // because the shipping method has a fallback on 0,- and this will make it show up on the frontend
172
+ Mage::register('channelengine_shipping', true);
173
+
174
+ $quote->getBillingAddress()
175
+ ->addData($billingData);
176
+ $quote->getShippingAddress()
177
+ ->addData($shippingData)
178
+ ->setSaveInAddressBook(0)
179
+ ->setCollectShippingRates(true)
180
+ ->setShippingMethod('channelengine_channelengine');
181
+
182
+ $quote->collectTotals();
183
+
184
+ // Set guest customer
185
+ $quote->setCustomerId(null)
186
+ ->setCustomerEmail($quote->getBillingAddress()->getEmail())
187
+ ->setCustomerIsGuest(true)
188
+ ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
189
+
190
+ // Set custom payment method
191
+ $quote->setIsSystem(true);
192
+ $quote->getPayment()->importData(array('method' => 'channelengine'));
193
+
194
+ // Save quote and convert it to new order
195
+ try {
196
+
197
+ $quote->save();
198
+
199
+ $service = Mage::getModel('sales/service_quote', $quote);
200
+
201
+ $service->submitAll();
202
+
203
+ } catch (Exception $e) {
204
+ Mage::getModel('adminnotification/inbox')->addCritical(
205
+ "An order (#{$order->getId()}) could not be imported",
206
+ "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
207
+ );
208
+ Mage::logException($e);
209
+ continue;
210
+ }
211
+
212
+ $_order = $service->getOrder();
213
+
214
+
215
+ if($_order->getIncrementId()) {
216
+
217
+ /**
218
+ * Create new invoice and save channel order
219
+ */
220
+ try {
221
+ // Initialize new invoice model
222
+ $invoice = Mage::getModel('sales/service_order', $_order)->prepareInvoice();
223
+ // Add comment to invoice
224
+ $invoice->addComment(
225
+ "Order paid on the marketplace.",
226
+ false,
227
+ true
228
+ );
229
+
230
+ // Register invoice. Register invoice items. Collect invoice totals.
231
+ $invoice->register();
232
+ $invoice->getOrder()->setIsInProcess(true);
233
+
234
+ // Initialize new channel order
235
+ $_channelOrder = Mage::getModel('channelengine/order');
236
+ $_channelOrder->setOrderId($_order->getId())
237
+ ->setChannelOrderId($order->getId())
238
+ ->setChannelName($order->getChannelName())
239
+ ->setDoSendMails($order->getDoSendMails())
240
+ ->setCanShipPartial($order->getCanShipPartialOrderLines());
241
+
242
+ $invoice->getOrder()
243
+ ->setCanShipPartiallyItem($order->getCanShipPartialOrderLines())
244
+ ->setCanShipPartially($order->getCanShipPartialOrderLines());
245
+
246
+ // Start new transaction
247
+ $transactionSave = Mage::getModel('core/resource_transaction')
248
+ ->addObject($invoice)
249
+ ->addObject($invoice->getOrder())
250
+ ->addObject($_channelOrder);
251
+ $transactionSave->save();
252
+
253
+ } catch (Exception $e) {
254
+ Mage::getModel('adminnotification/inbox')->addCritical(
255
+ "An invoice could not be created (order #{$_order->getIncrementId()}, channel order #{$order->getId()})",
256
+ "Reason: {$e->getMessage()} Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
257
+ );
258
+ Mage::logException($e);
259
+ continue;
260
+ }
261
+ Mage::log("Order #{$_order->getIncrementId()} was imported successfully.");
262
+ } else {
263
+ Mage::log("An order (#{$order->getId()}) could not be imported");
264
+ }
265
+ }
266
+ }
267
+
268
+ return true;
269
+ }
270
+
271
+ /**
272
+ * Post new shipment to ChannelEngine. This function is set in extension config file.
273
+ *
274
+ * @param Varien_Event_Observer $observer
275
+ * @return bool
276
+ * @throws Exception
277
+ */
278
+ public function saveShipment(Varien_Event_Observer $observer)
279
+ {
280
+ Mage::log('--------------------------------------');
281
+ $event = $observer->getEvent();
282
+ /** @var $_shipment Mage_Sales_Model_Order_Shipment */
283
+ $_shipment = $event->getShipment();
284
+
285
+ /** @var $_order Mage_Sales_Model_Order */
286
+ $_order = $_shipment->getOrder();
287
+
288
+ $storeId = $_order->getStoreId();
289
+
290
+ $ceOrder = Mage::getModel('channelengine/order')->loadByOrderId($_order->getId());
291
+ $ceOrderId = $ceOrder->getChannelOrderId();
292
+
293
+ if(!$ceOrderId) return false;
294
+
295
+ // Check if the API client was initialized for this order
296
+ if(!isset($this->_client[$storeId])) return false;
297
+
298
+ // Initialize new ChannelEngine shipment object
299
+ $ceShipment = new Tritac_ChannelEngineApiClient_Models_Shipment();
300
+ $ceShipment->setOrderId($ceOrderId);
301
+ $ceShipment->setMerchantShipmentNo($_shipment->getId());
302
+
303
+ // Set tracking info if available
304
+ $trackingCode = null;
305
+ $trackingCodes = $_shipment->getAllTracks();
306
+ if(count($trackingCodes) > 0) {
307
+
308
+ $trackingCode = $trackingCodes[0];
309
+ $ceShipment->setTrackTraceNo($trackingCode->getNumber());
310
+ $ceShipment->setMethod($trackingCode->getTitle());
311
+ }
312
+
313
+ // If the shipment is already known to ChannelEngine we will just update it
314
+ $_channelShipment = Mage::getModel('channelengine/shipment')->loadByShipmentId($_shipment->getId());
315
+
316
+ if($_channelShipment->getId() != null) {
317
+
318
+ if($trackingCode != null) {
319
+ Mage::Log("TrackTrace: {$trackingCode->getNumber()}");
320
+ }
321
+
322
+ Mage::log("CE Shipment Id: #{$_channelShipment->getChannelengineShipmentId()}");
323
+ $ceShipment->setId($_channelShipment->getChannelengineShipmentId());
324
+ $this->_client[$storeId]->putShipment($ceShipment);
325
+ return true;
326
+ }
327
+
328
+ Mage::log('New shipment, continue');
329
+
330
+ // Add the shipment lines
331
+ $ceShipmentLines = new Tritac_ChannelEngineApiClient_Helpers_Collection('Tritac_ChannelEngineApiClient_Models_ShipmentLine');
332
+ foreach($_shipment->getAllItems() as $_shipmentItem) {
333
+
334
+ // Get the quantity for this shipment
335
+ $shippedQty = (int)$_shipmentItem->getQty();
336
+ if($shippedQty == 0) continue;
337
+
338
+ // Get the original order item
339
+ $_orderItem = Mage::getModel('sales/order_item')->load($_shipmentItem->getOrderItemId());
340
+ if($_orderItem == null) continue;
341
+
342
+ $ceShipmentLine = new Tritac_ChannelEngineApiClient_Models_ShipmentLine();
343
+ $ceShipmentLine->setOrderLineId($_orderItem->getChannelengineOrderLineId());
344
+ $ceShipmentLine->setQuantity($shippedQty);
345
+ $ceShipmentLine->setStatus(Tritac_ChannelEngineApiClient_Enums_ShipmentLineStatus::SHIPPED);
346
+
347
+ $ceShipmentLines->append($ceShipmentLine);
348
+ }
349
+
350
+ // Check if there are any shipment lines
351
+ if(count($ceShipmentLines) == 0) return false;
352
+
353
+ $ceShipment->setLines($ceShipmentLines);
354
+
355
+ // Post shipment to ChannelEngine
356
+ try{
357
+
358
+ $result = $this->_client[$storeId]->postShipment($ceShipment);
359
+ if($result == null) return false;
360
+
361
+ $_channelShipment = Mage::getModel('channelengine/shipment')
362
+ ->setShipmentId($_shipment->getId())
363
+ ->setChannelengineShipmentId($result->getId());
364
+ $_channelShipment->save();
365
+
366
+ Mage::log("Shipment #{$_shipment->getId()} (CE #{$result->getId()}) was placed successfully.");
367
+
368
+
369
+
370
+ } catch(Exception $e) {
371
+
372
+ Mage::getModel('adminnotification/inbox')->addCritical(
373
+ "A shipment (#{$_shipment->getId()}) could not be exported",
374
+ "Please contact ChannelEngine support at <a href='mailto:support@channelengine.com'>support@channelengine.com</a> or +31(0)71-5288792"
375
+ );
376
+
377
+ Mage::logException($e);
378
+
379
+ }
380
+
381
+
382
+ return true;
383
+ }
384
+
385
+ /**
386
+ * Fetch new returns from channelengine
387
+ *
388
+ * @return bool
389
+ */
390
+ public function fetchReturns()
391
+ {
392
+ /**
393
+ * Check if client is initialized
394
+ */
395
+ if(is_null($this->_client))
396
+ return false;
397
+
398
+ foreach($this->_client as $storeId => $_client) {
399
+ /**
400
+ * Retrieve returns
401
+ */
402
+ $returns = $_client->getReturns(array(
403
+ Tritac_ChannelEngineApiClient_Enums_ReturnStatus::DECLARED
404
+ ));
405
+
406
+ /**
407
+ * Check declared returns
408
+ */
409
+ if(is_null($returns) || $returns->count() == 0)
410
+ return false;
411
+
412
+ foreach($returns as $return) {
413
+ $_channelOrder = Mage::getModel('channelengine/order')->loadByChannelOrderId($return->getOrderId());
414
+ $_order = Mage::getModel('sales/order')->load($_channelOrder->getOrderId());
415
+
416
+ if(!$_order->getIncrementId()) {
417
+ continue;
418
+ }
419
+
420
+
421
+ $link = "https://". $this->_config[$storeId]['general']['tenant'] .".channelengine.net/orders/view/". $return->getOrderId();
422
+ $status = $return->getStatus(); // Get return status
423
+ $reason = $return->getReason(); // Get return reason
424
+ $title = "A new return was declared in ChannelEngine (ChannelEngine Order #{$return->getOrderId()})";
425
+ $message = "Magento Order #: <a href='".
426
+ Mage::helper('adminhtml')->getUrl('adminhtml/sales_order/view', array('order_id'=>$_order->getOrderId())).
427
+ "'>".
428
+ $_order->getIncrementId().
429
+ "</a><br />";
430
+ $message .= "Status: {$status}<br />";
431
+ $message .= "Reason: {$reason}<br />";
432
+ $message .= "For more details visit ChannelEngine your <a href='".$link."' target='_blank'>account</a>";
433
+
434
+ // Check if notification is already exist
435
+ $_resource = Mage::getSingleton('core/resource');
436
+ $_connectionRead = $_resource->getConnection('core_read');
437
+ $select = $_connectionRead->select()
438
+ ->from($_resource->getTableName('adminnotification/inbox'))
439
+ ->where('title = ?', $title)
440
+ ->where('is_remove != 1')
441
+ ->limit(1);
442
+ $data = $_connectionRead->fetchRow($select);
443
+
444
+ if ($data) {
445
+ continue;
446
+ }
447
+
448
+ // Add new notification
449
+ Mage::getModel('adminnotification/inbox')->addCritical(
450
+ $title,
451
+ $message,
452
+ $link
453
+ );
454
+ }
455
+ }
456
+ }
457
+
458
+ /**
459
+ * Generate products feed for ChannelEngine
460
+ */
461
+ public function generateFeed()
462
+ {
463
+ $start_memory = memory_get_usage();
464
+
465
+ /**
466
+ * Prepare categories array
467
+ */
468
+ $categoryArray = array();
469
+ $parent = Mage::app()->getWebsite(true)->getDefaultStore()->getRootCategoryId();
470
+ $category = Mage::getModel('catalog/category');
471
+ if ($category->checkId($parent)) {
472
+ $storeCategories = $category->getCategories($parent, 0, true, true, true);
473
+ foreach($storeCategories as $_category) {
474
+ $categoryArray[$_category->getId()] = $_category->getData();
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Prepare products relation
480
+ */
481
+ // $productsRelation = array();
482
+ // $_resource = Mage::getSingleton('core/resource');
483
+ // $_connection = $_resource->getConnection('core_read');
484
+ // $relations = $_connection->fetchAll("SELECT * FROM " . $_resource->getTableName('catalog/product_relation'));
485
+ // foreach($relations as $relation) {
486
+ // $productsRelation[$relation['child_id']] = $relation['parent_id'];
487
+ // }
488
+
489
+ /**
490
+ * Export products from each store.
491
+ * Note: products with undefined website id will not be export.
492
+ */
493
+ foreach(Mage::app()->getStores() as $_store) {
494
+ Mage::app()->setCurrentStore($_store);
495
+ $path = Mage::getBaseDir('media') . DS . 'channelengine' . DS;
496
+ $storeConfig = $this->_helper->getConfig($_store->getId());
497
+ $name = $storeConfig['general']['tenant'].'_products.xml';
498
+ $file = $path . DS . $name;
499
+
500
+ $io = new Varien_Io_File();
501
+ $io->setAllowCreateFolders(true);
502
+ $io->open(array('path' => $path));
503
+ $io->streamOpen($file, 'w+');
504
+ $io->streamLock(true);
505
+ $io->streamWrite('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
506
+ $io->streamWrite('<Products xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n");
507
+
508
+ /**
509
+ * Prepare custom options array
510
+ */
511
+ $storeId = $_store->getId();
512
+ $optionsArray = array();
513
+ $_options = Mage::getModel('catalog/product_option')
514
+ ->getCollection()
515
+ ->addTitleToResult($storeId)
516
+ ->addPriceToResult($storeId)
517
+ ->addValuesToResult($storeId)
518
+ ->setOrder('sort_order', 'asc');
519
+ foreach($_options as $_option) {
520
+ $productId = $_option->getProductId();
521
+ $optionId = $_option->getOptionId();
522
+ $optionsArray[$productId][$optionId] = $_option->getData();
523
+ if($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN) {
524
+ $optionsArray[$productId][$optionId]['values'] = $_option->getValues();
525
+ }
526
+ }
527
+
528
+ /**
529
+ * Retrieve product collection with all visible attributes
530
+ */
531
+ if(Mage::helper('catalog/product_flat')->isEnabled($storeId)) {
532
+ Mage::getResourceSingleton('catalog/product_flat')->setStoreId($storeId);
533
+ }
534
+ $collection = Mage::getModel('catalog/product')->getCollection();
535
+
536
+ if(Mage::helper('catalog/product_flat')->isEnabled($storeId)) {
537
+ $collection->getEntity()->setStoreId($storeId);
538
+ }
539
+
540
+ $systemAttributes = $attributesToSelect = array(
541
+ 'name',
542
+ 'description',
543
+ 'image',
544
+ 'url_key',
545
+ 'price',
546
+ 'cost',
547
+ 'special_price',
548
+ 'special_from_date',
549
+ 'special_to_date',
550
+ 'visibility',
551
+ 'msrp'
552
+ );
553
+
554
+ $visibleAttributes = array();
555
+ $attributes = Mage::getSingleton('eav/config')
556
+ ->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getAttributeCollection();
557
+
558
+ foreach($attributes as $attribute) {
559
+ if( ($attribute->getIsVisible() && $attribute->getIsVisibleOnFront())
560
+ || in_array($attribute->getAttributeCode(), $systemAttributes))
561
+ {
562
+ $code = $attribute->getAttributeCode();
563
+ $visibleAttributes[$code]['label'] = $attribute->getFrontendLabel();
564
+
565
+ foreach( $attribute->getSource()->getAllOptions(false) as $option ) {
566
+ $visibleAttributes[$code]['values'][$option['value']] = $option['label'];
567
+ }
568
+ if(!in_array($code, $attributesToSelect)) {
569
+ $attributesToSelect[] = $code;
570
+ }
571
+ }
572
+ }
573
+
574
+ if(!empty($this->_config[$storeId]['feed']['gtin'])) {
575
+ $attributesToSelect[] = $this->_config[$storeId]['feed']['gtin'];
576
+ }
577
+
578
+ if( (count($attributesToSelect) > self::ATTRIBUTES_LIMIT) && !$collection->isEnabledFlat()) {
579
+ $error = $this->_helper->__('Too many visible attributes. Please enable catalog product flat mode.');
580
+ Mage::getSingleton('adminhtml/session')->addError($error);
581
+ echo 'redirect';
582
+ return false;
583
+ }
584
+
585
+ $collection->addAttributeToSelect($attributesToSelect, 'left')
586
+ ->addFieldToFilter('type_id', array('in' => array('simple')))
587
+ ->addStoreFilter($_store)
588
+ ->addAttributeToFilter('status', 1)
589
+ ->addAttributeToFilter('visibility', array('in' => array('2', '3', '4')))
590
+ ->addAttributeToSort('entity_id', 'DESC');
591
+
592
+ // Add qty and category fields to select
593
+ $collection->getSelect()
594
+ ->joinLeft(
595
+ array('csi' => Mage::getSingleton('core/resource')->getTableName('cataloginventory/stock_item')),
596
+ '`e`.`entity_id` = `csi`.`product_id`',
597
+ array('qty' => 'COALESCE(`qty`, 0)')
598
+ )
599
+ ->joinLeft(
600
+ array('ccp' => Mage::getSingleton('core/resource')->getTableName('catalog/category_product')),
601
+ '`e`.`entity_id` = `ccp`.`product_id`',
602
+ array('category_id' => 'MAX(`ccp`.`category_id`)')
603
+ )
604
+ ->group('e.entity_id');
605
+
606
+ Mage::getSingleton('core/resource_iterator')->walk(
607
+ $collection->getSelect(),
608
+ array(array($this, 'callbackGenerateFeed')),
609
+ array(
610
+ 'io' => $io,
611
+ 'categories' => $categoryArray,
612
+ 'attributes' => $visibleAttributes,
613
+ 'systemAttributes' => $systemAttributes,
614
+ 'options' => $optionsArray,
615
+ 'store' => $_store,
616
+ 'startMemory' => $start_memory,
617
+ )
618
+ );
619
+
620
+ $collection->clear()->getSelect()->reset('where');
621
+ $collection->addFieldToFilter('type_id', array('in' => array('configurable')))
622
+ ->addStoreFilter($_store)
623
+ ->addAttributeToFilter('status', 1)
624
+ ->addAttributeToSort('entity_id', 'DESC');
625
+
626
+ foreach($collection as $_product) {
627
+ $productAttributeOptions = $_product->getTypeInstance(true)->getConfigurableAttributesAsArray($_product);
628
+ $superAttributes = array();
629
+
630
+ foreach($productAttributeOptions as $superAttribute) {
631
+ foreach($superAttribute['values'] as $value) {
632
+ $superAttributes[$superAttribute['attribute_code']][$value['value_index']] = $value;
633
+ }
634
+ }
635
+
636
+ $parentData = $_product->getData();
637
+ $parentData['id'] = $parentData['entity_id'];
638
+
639
+ $productModel = Mage::getModel('catalog/product');
640
+ $productModel->setData('entity_id', $parentData['entity_id']);
641
+ $productModel->setData('url_key', $parentData['url_key']);
642
+ $productModel->setData('store_id', $parentData['store_id']);
643
+ $parentData['url'] = $productModel->getProductUrl();
644
+
645
+ $specialPrice = $parentData['special_price'];
646
+ $specialFrom = $parentData['special_from_date'];
647
+ $specialTo = $parentData['special_to_date'];
648
+ $parentData['price'] = Mage::getModel('catalog/product_type_price')
649
+ ->calculateSpecialPrice($parentData['price'], $specialPrice, $specialFrom, $specialTo, $storeId);
650
+
651
+ $xml = $this->_getProductXml($parentData, $categoryArray, array('systemAttributes' => $systemAttributes, 'attributes' => $visibleAttributes));
652
+ $_childProducts = Mage::getModel('catalog/product_type_configurable')
653
+ ->getUsedProducts(null, $_product);
654
+
655
+ foreach($_childProducts as $_child) {
656
+ $childData = $_child->getData();
657
+ $childData['id'] = $childData['entity_id'];
658
+ $childData['parent_id'] = $parentData['id'];
659
+ $childData['price'] = $parentData['price'];
660
+ $childData['url'] = $parentData['url'];
661
+ $childData['description'] = $parentData['description'];
662
+
663
+ if(!isset($childData['image']) || $childData['image'] == 'no_slection') {
664
+ $childData['image'] = $parentData['image'];
665
+ }
666
+
667
+ foreach($superAttributes as $code => $superAttribute) {
668
+ if(isset($childData[$code])) {
669
+ $priceValue = $superAttribute[$childData[$code]]['pricing_value'];
670
+ if($superAttribute[$childData[$code]]['is_percent']) {
671
+ $newPrice = $childData['price'] + $childData['price'] * $priceValue / 100;
672
+ } else {
673
+ $newPrice = $childData['price'] + $priceValue;
674
+ }
675
+ $childData['price'] = $newPrice;
676
+ }
677
+ }
678
+ $xml .= $this->_getProductXml($childData, $categoryArray, array('systemAttributes' => $systemAttributes, 'attributes' => $visibleAttributes));
679
+ }
680
+ $io->streamWrite($xml);
681
+ }
682
+
683
+
684
+ $io->streamWrite('</Products>');
685
+ $io->streamUnlock();
686
+ $io->streamClose();
687
+
688
+ Mage::log("Product feed {$name} was generated successfully");
689
+ }
690
+
691
+ return true;
692
+ }
693
+
694
+ public function callbackGenerateFeed($args)
695
+ {
696
+ $io = $args['io'];
697
+ $product = $args['row'];
698
+ $attributes = $args['attributes'];
699
+ $systemAttributes = $args['systemAttributes'];
700
+ $categories = $args['categories'];
701
+ $options = $args['options'];
702
+ $_store = $args['store'];
703
+ $storeId = $_store->getId();
704
+
705
+ $xml = '';
706
+
707
+ $product['store_id'] = $storeId;
708
+ if(!empty($this->_config[$storeId]['feed']['gtin'])) {
709
+ $product['gtin'] = $product[$this->_config[$storeId]['feed']['gtin']];
710
+ }
711
+
712
+ $specialPrice = $product['special_price'];
713
+ $specialFrom = $product['special_from_date'];
714
+ $specialTo = $product['special_to_date'];
715
+ $product['price'] = Mage::getModel('catalog/product_type_price')
716
+ ->calculateSpecialPrice($product['price'], $specialPrice, $specialFrom, $specialTo, $storeId);
717
+
718
+ $productModel = Mage::getModel('catalog/product');
719
+ $productModel->setData('entity_id', $product['entity_id']);
720
+ $productModel->setData('url_key', $product['url_key']);
721
+ $productModel->setData('store_id', $product['store_id']);
722
+ $product['url'] = $productModel->getProductUrl();
723
+
724
+ /**
725
+ * Add product custom options to feed.
726
+ * Each option value will generate new product row
727
+ */
728
+ $additional['systemAttributes'] = $systemAttributes;
729
+ $additional['attributes'] = $attributes;
730
+ if(isset($options[$product['entity_id']])) {
731
+ $product['group_code'] = $product['entity_id'];
732
+ foreach($options[$product['entity_id']] as $option) {
733
+ if(isset($option['values'])) {
734
+ foreach($option['values'] as $_value) {
735
+ $product['id'] = $product['entity_id'].'_'.$option['option_id'].'_'.$_value->getId();
736
+ $additional['title'] = str_replace(' ', '_', $option['default_title']);
737
+ $additional['value'] = $_value->getDefaultTitle();
738
+ $xml .= $this->_getProductXml($product, $categories, $additional);
739
+ }
740
+ } else {
741
+ $product['id'] = $product['entity_id'].'_'.$option['option_id'];
742
+ $additional['title'] = str_replace(' ', '_', $option['default_title']);
743
+ $additional['value'] = '';
744
+ $xml .= $this->_getProductXml($product, $categories, $additional);
745
+ }
746
+ }
747
+ }else {
748
+ $product['id'] = $product['entity_id'];
749
+ $xml .= $this->_getProductXml($product, $categories, $additional);
750
+ }
751
+
752
+ $io->streamWrite($xml);
753
+ }
754
+
755
+ protected function _getProductXml($product, $categories, $additional = null)
756
+ {
757
+ $xml = "<Product>";
758
+ $xml .= "<Id>".$product['id']."</Id>";
759
+
760
+ // Add group code with product id if product have custom options
761
+ if(isset($product['group_code'])) {
762
+ $xml .= "<GroupCode><![CDATA[".$product['group_code']."]]></GroupCode>";
763
+ }
764
+ if(isset($product['parent_id'])) {
765
+ $xml .= "<ParentId><![CDATA[".$product['parent_id']."]]></ParentId>";
766
+ }
767
+ $xml .= "<Type><![CDATA[".$product['type_id']."]]></Type>";
768
+ $xml .= "<Name><![CDATA[".$product['name']."]]></Name>";
769
+ $xml .= "<Description><![CDATA[".$product['description']."]]></Description>";
770
+ $xml .= "<Price><![CDATA[".$product['price']."]]></Price>";
771
+ $xml .= "<ListPrice><![CDATA[".$product['msrp']."]]></ListPrice>";
772
+ $xml .= "<PurchasePrice><![CDATA[".$product['cost']."]]></PurchasePrice>";
773
+
774
+ // Add product stock qty
775
+ $xml .= "<Stock><![CDATA[".$product['qty']."]]></Stock>";
776
+ // Add product SKU and GTIN
777
+ $xml .= "<SKU><![CDATA[".$product['sku']."]]></SKU>";
778
+ if(!empty($product['gtin'])) {
779
+ $xml .= "<GTIN><![CDATA[".$product['gtin']."]]></GTIN>";
780
+ }
781
+
782
+ // VAT and Shipping Time are pre configured in extension settings
783
+ if(!empty($this->_config[$product['store_id']]['feed']['vat_rate'])) {
784
+ $vat = $this->_config[$product['store_id']]['feed']['vat_rate'];
785
+ $xml .= "<VAT><![CDATA[".$vat."]]></VAT>";
786
+ }
787
+
788
+ $shippingTime = ($product['qty'] > 0) ? $this->_config[$product['store_id']]['feed']['shipping_time'] : $this->_config[$product['store_id']]['feed']['shipping_time_oos'];
789
+
790
+ if($shippingTime) {
791
+ $xml .= "<ShippingTime><![CDATA[".$shippingTime."]]></ShippingTime>";
792
+ }
793
+
794
+ $xml .= "<Url><![CDATA[".$product['url']."]]></Url>";
795
+
796
+ if(isset($product['image']) && $product['image'] != 'no_selection') {
797
+ $imgUrl = Mage::getSingleton('catalog/product_media_config')->getMediaUrl($product['image']);
798
+ $xml .= "<ImageUrl><![CDATA[".$imgUrl."]]></ImageUrl>";
799
+ }
800
+
801
+ // Prepare category path
802
+ if(!empty($product['category_id']) && !empty($categories)) {
803
+ $categoryId = $product['category_id'];
804
+ $categoryPathIds = explode('/', $categories[$categoryId]['path']);
805
+ $categoryPath = null;
806
+ foreach($categoryPathIds as $id) {
807
+ if($id > 2) {
808
+ $categoryPath .= ($categoryPath) ? ' > ':'';
809
+ $categoryPath .= $categories[$id]['name'];
810
+ }
811
+ }
812
+ if($categoryPath) {
813
+ $xml .= "<Category><![CDATA[".$categoryPath."]]></Category>";
814
+ }
815
+ }
816
+
817
+ if(isset($additional['title']) && isset($additional['value'])) {
818
+ $title = preg_replace("/[^a-zA-Z0-9]/", "", $additional['title']);
819
+ $xml .= sprintf("<%1\$s><![CDATA[%2\$s]]></%1\$s>",
820
+ $title,
821
+ $additional['value']
822
+ );
823
+ }
824
+
825
+ /*
826
+ * Prepare product visible attributes
827
+ */
828
+ if(isset($additional['attributes'])) {
829
+ $xml .= '<Attributes>';
830
+ foreach($additional['attributes'] as $code => $attribute) {
831
+ if(isset($product[$code]) && !in_array($code, $additional['systemAttributes'])) {
832
+ $xml .= "<".$code.">";
833
+ /*$xml .= "<label><![CDATA[".$attribute['label']."]]></label>";
834
+ if(!empty($attribute['values'])) {
835
+ $xml .= "<value><![CDATA[".$attribute['values'][$product[$code]]."]]></value>";
836
+ } else {
837
+ $xml .= "<value><![CDATA[".$product[$code]."]]></value>";
838
+ }*/
839
+ if(!empty($attribute['values'])) {
840
+ $xml .= "<![CDATA[".$attribute['values'][$product[$code]]."]]>";
841
+ } else {
842
+ $xml .= "<![CDATA[".$product[$code]."]]>";
843
+ }
844
+ $xml .= "</".$code.">";
845
+ }
846
+ }
847
+ $xml .= '</Attributes>';
848
+ }
849
+
850
+ $xml .= "</Product>\n";
851
+
852
+ return $xml;
853
+ }
854
+
855
+ public function addConfigurableProducts($collection)
856
+ {
857
+
858
+ }
859
+
860
+ /**
861
+ * Join channelengine order fields to adminhtml order grid
862
+ *
863
+ * @param $observer
864
+ */
865
+ /*public function prepareOrderGridCollection($observer)
866
+ {
867
+ $collection = $observer->getOrderGridCollection();
868
+ $joinTableName = Mage::getSingleton('core/resource')->getTableName('channelengine/order');
869
+ $collection->getSelect()->joinLeft(
870
+ array('channel_order_table' => $joinTableName),
871
+ 'channel_order_table.order_id=main_table.entity_id',
872
+ array('channel_name', 'channel_order_id')
873
+ );
874
+ }*/
875
+
876
+ /**
877
+ * Add channelengine order fields to adminhtml order grid
878
+ *
879
+ * @param $observer
880
+ * @return $this
881
+ */
882
+ /*public function appendCustomColumnToOrderGrid($observer)
883
+ {
884
+ $block = $observer->getBlock();
885
+ if (!isset($block)) {
886
+ return $this;
887
+ }
888
+
889
+ if ($block->getType() == 'adminhtml/sales_order_grid') {
890
+ $block->addColumnAfter('channel_order_id', array(
891
+ 'header'=> Mage::helper('sales')->__('ChannelEngine Order ID'),
892
+ 'width' => '80px',
893
+ 'type' => 'text',
894
+ 'index' => 'channel_order_id',
895
+ ), 'real_order_id');
896
+
897
+ $block->addColumnAfter('channel_name', array(
898
+ 'header'=> Mage::helper('sales')->__('Channel Name'),
899
+ 'width' => '80px',
900
+ 'type' => 'text',
901
+ 'index' => 'channel_name',
902
+ ), 'real_order_id');
903
+ }
904
+ }*/
905
+ }
app/code/community/Tritac/ChannelEngine/Model/Order.php CHANGED
@@ -1,32 +1,32 @@
1
- <?php
2
- class Tritac_ChannelEngine_Model_Order extends Mage_Core_Model_Abstract {
3
-
4
- protected function _construct()
5
- {
6
- $this->_init('channelengine/order');
7
- }
8
-
9
- /**
10
- * Load channel order by magento order ID
11
- *
12
- * @param $orderId
13
- * @return Tritac_ChannelEngine_Model_Order
14
- */
15
- public function loadByOrderId($orderId)
16
- {
17
- $this->_getResource()->loadByOrderId($this, $orderId);
18
- return $this;
19
- }
20
-
21
- /**
22
- * Load channel order by channel order ID
23
- *
24
- * @param $orderId
25
- * @return Tritac_ChannelEngine_Model_Order
26
- */
27
- public function loadByChannelOrderId($orderId)
28
- {
29
- $this->_getResource()->loadByChannelOrderId($this, $orderId);
30
- return $this;
31
- }
32
  }
1
+ <?php
2
+ class Tritac_ChannelEngine_Model_Order extends Mage_Core_Model_Abstract {
3
+
4
+ protected function _construct()
5
+ {
6
+ $this->_init('channelengine/order');
7
+ }
8
+
9
+ /**
10
+ * Load channel order by magento order ID
11
+ *
12
+ * @param $orderId
13
+ * @return Tritac_ChannelEngine_Model_Order
14
+ */
15
+ public function loadByOrderId($orderId)
16
+ {
17
+ $this->_getResource()->loadByOrderId($this, $orderId);
18
+ return $this;
19
+ }
20
+
21
+ /**
22
+ * Load channel order by channel order ID
23
+ *
24
+ * @param $orderId
25
+ * @return Tritac_ChannelEngine_Model_Order
26
+ */
27
+ public function loadByChannelOrderId($orderId)
28
+ {
29
+ $this->_getResource()->loadByChannelOrderId($this, $orderId);
30
+ return $this;
31
+ }
32
  }
app/code/community/Tritac/ChannelEngine/Model/Payment/Method/Channelengine.php CHANGED
@@ -1,22 +1,22 @@
1
- <?php
2
- /**
3
- * ChannelEngine Payment Method
4
- */
5
- class Tritac_ChannelEngine_Model_Payment_Method_Channelengine extends Mage_Payment_Model_Method_Abstract {
6
-
7
- /**
8
- * System payment method code
9
- *
10
- * @var string
11
- */
12
- protected $_code = 'channelengine';
13
-
14
- public function isAvailable($quote = null)
15
- {
16
- if($quote->getIsSystem() && $quote->getPayment()->getMethod() == $this->_code) {
17
- return true;
18
- }
19
-
20
- return false;
21
- }
22
  }
1
+ <?php
2
+ /**
3
+ * ChannelEngine Payment Method
4
+ */
5
+ class Tritac_ChannelEngine_Model_Payment_Method_Channelengine extends Mage_Payment_Model_Method_Abstract {
6
+
7
+ /**
8
+ * System payment method code
9
+ *
10
+ * @var string
11
+ */
12
+ protected $_code = 'channelengine';
13
+
14
+ public function isAvailable($quote = null)
15
+ {
16
+ if($quote->getIsSystem() && $quote->getPayment()->getMethod() == $this->_code) {
17