yd521cdsf5re1serkcjbf4r50rew54cxc12 - Version 0.0.1

Version Notes

- This is first Notes

Download this release

Release Info

Developer Whiplash
Extension yd521cdsf5re1serkcjbf4r50rew54cxc12
Version 0.0.1
Comparing to
See all releases


Version 0.0.1

app/code/community/Whiplash/Fulfillment/Helper/Data.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class Whiplash_Fulfillment_Helper_Data extends Mage_Core_Helper_Abstract
35
+ {
36
+
37
+ }
app/code/community/Whiplash/Fulfillment/Model/Adminhtml/System/Config/Source/Apiversion.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Used in creating options for Yes|No config value selection
29
+ *
30
+ */
31
+ class Whiplash_Fulfillment_Model_Adminhtml_System_Config_Source_Apiversion
32
+ {
33
+
34
+ /**
35
+ * Options getter
36
+ *
37
+ * @return array
38
+ */
39
+ public function toOptionArray()
40
+ {
41
+ return array(
42
+ array('value' => '', 'label'=>Mage::helper('adminhtml')->__('Latest Available')),
43
+ array('value' => 1.0, 'label'=>Mage::helper('adminhtml')->__('Whatever You Want. Edit Whiplash_FulFillment_Model_System_Config_Source_Apiversion')),
44
+ );
45
+ }
46
+
47
+ }
app/code/community/Whiplash/Fulfillment/Model/Observer.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class Whiplash_Fulfillment_Model_Observer extends Varien_Object
35
+ {
36
+
37
+ protected function getStoreId()
38
+ {
39
+ $storeId = Mage::app()->getStore()->getId();
40
+
41
+ if($storeId == 0) // If the store id is 0 then we are in the admin area
42
+ {
43
+ // We want to make sure that whiplash is enabled for the requested store, if there is a requested store
44
+ $storeId = Mage::app()->getRequest()->getParam('store', Mage::getStoreConfig('whiplash/api/default_store_to_update')); //storeId will contain either a store id, or the "Default Store [id] to Update" if no specific store was requested
45
+ }
46
+
47
+ return $storeId;
48
+ }
49
+
50
+ protected function isEnabledForStoreId($storeId)
51
+ {
52
+ return Mage::getStoreConfig('whiplash/api/enabled',$storeId);
53
+ }
54
+
55
+ protected function init_whiplash()
56
+ {
57
+ // Set the API credentials
58
+ $api_key = Mage::getStoreConfig('whiplash/api/key'); // Whiplash Sandbox on Testing Server
59
+ $api_version = Mage::getStoreConfig('whiplash/api/version'); // OPTIONAL: Leave this blank to use the most recent API
60
+ $storeId = $this->getStoreId();
61
+ $test = Mage::getStoreConfig('whiplash/api/test_mode'); // OPTIONAL: If test is true, this will use your sandbox account
62
+
63
+ // Include the Whiplash lib and initialize
64
+ $ExternalLibPath=Mage::getBaseDir('code') . DS . 'community' . DS . 'Whiplash' . DS . 'Fulfillment'. DS . 'lib' . DS .'WhiplashApi.php';
65
+ require_once ($ExternalLibPath);
66
+ $api = new WhiplashApi($api_key, $api_version, $storeId, $test);
67
+ return $api;
68
+ }
69
+
70
+ public function update_or_create_item($observer)
71
+ // Creates or updates an item in Whiplash
72
+ {
73
+ if($this->isEnabledForStoreId($this->getStoreId()))
74
+ {
75
+ $api = $this->init_whiplash();
76
+ $_product = $observer->getProduct();
77
+ if($_product->getTypeID() == 'simple'){
78
+
79
+ $parentProduct = Mage::getResourceSingleton('catalog/product_type_configurable')
80
+ ->getParentIdsByChild($_product->getId());
81
+
82
+ if(is_array($parentProduct) && !empty($parentProduct))
83
+ {
84
+ $parentProduct = Mage::getModel('catalog/product')->load(array_pop($parentProduct));
85
+ if($parentProduct && $parentProduct->getId())
86
+ {
87
+ $image = $parentProduct->getMediaConfig()->getMediaUrl($parentProduct->getData('image'));
88
+ }
89
+ }
90
+
91
+ // Get the expected quantity
92
+ $quantity = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
93
+
94
+ $item = array(
95
+ 'sku' => $_product->getSku(),
96
+ 'title' => $_product->getName(),
97
+ 'exp_quantity' => $quantity,
98
+ 'image_originator_url' => $image?$image:$_product->getMediaConfig()->getMediaUrl($_product->getData('image')),
99
+ 'price' => $_product->getPrice(),
100
+ 'wholesale_cost' => $_product->getCost(),
101
+ 'originator_id' => $_product->getId()
102
+ );
103
+
104
+ // Check if the item exists in Whiplash
105
+ $whiplash_item = $api->get_item_by_originator($_product->getId());
106
+ if (!$whiplash_item){
107
+ // We didn't get an item back, create it
108
+ $api->create_item($item); }
109
+ // Item exists in Whiplash, so update it
110
+ else {
111
+ $api->update_item($whiplash_item->id,$item);
112
+ }
113
+ } // Failed type == simple test, ignore item
114
+ }
115
+ }
116
+
117
+
118
+ public function create_order($observer)
119
+ // Creates an order and order_items in Whiplash
120
+ {
121
+ $api = $this->init_whiplash();
122
+ $_order = $observer->getEvent()->getInvoice()->getOrder();
123
+ if($this->isEnabledForStoreId($_order->getStoreId()))
124
+ {
125
+ $_shippingAddress = $_order->getShippingAddress();
126
+ $_shippingMethod = $_shippingAddress->getAddressShippingMethod();
127
+
128
+ // Translate magento fields for whiplash
129
+ $_shipping_name = $_shippingAddress->getFirstname() . " " . $_shippingAddress->getLastname();
130
+ $order_attributes = array(
131
+ 'shipping_name' => $_shipping_name,
132
+ 'shipping_company' => $_shippingAddress->getCompany(),
133
+ 'shipping_address_1' => $_shippingAddress->getStreetFull(), // All address lines gets truncated into 1
134
+ 'shipping_city' => $_shippingAddress->getCity(),
135
+ 'shipping_state' => $_shippingAddress->getRegion(),
136
+ 'shipping_zip' => $_shippingAddress->getPostcode(),
137
+ 'shipping_country' => $_shippingAddress->getCountry_id(),
138
+ 'shipping_phone' => $_shippingAddress->getTelephone(),
139
+ 'email' => $_order->getCustomerEmail(),
140
+ 'originator_id' => $_order->getRealOrderId(),
141
+ 'order_orig' => $_order->getRealOrderId(),
142
+ 'req_ship_method_text' => $_order->getShippingMethod(),
143
+ 'req_ship_method_price' => $_order->getShippingAmount(),
144
+ 'order_items_attributes' => array()
145
+ );
146
+
147
+ // Add the order_items
148
+ $items = $_order->getAllVisibleItems();
149
+ $i = 0;
150
+ foreach ($items as $itemId => $item)
151
+ {
152
+ if ($item->getQtyOrdered() > 0){
153
+ // There are master items on the invoice, we only want the 'real' items
154
+ $whiplash_item = $api->get_items_by_sku($item->getSku()); // This is an array; we want to the first result
155
+ // Find the id of the whiplash item
156
+ if ( is_array($whiplash_item) ) {
157
+ $whiplash_item = $whiplash_item[0];
158
+ $order_attributes['order_items'][$i] = array('quantity' => $item->getQtyOrdered(), 'item_id' => $whiplash_item->id, 'originator_id' => $item->getId(), 'price' => $item->getRowTotalInclTax()/$item->getQtyOrdered());
159
+ $i += 1;
160
+ }
161
+ }
162
+ }
163
+ // Post to Whiplash
164
+ $order = $api->create_order($order_attributes);
165
+ }
166
+ }
167
+
168
+ // public function update_order($observer){
169
+ // Not currently supported. This could overwrite intentional changes in Whiplash. Possibly see which side is newer to allow it through?
170
+
171
+ // // Updates the address and shipping method in Whiplash
172
+
173
+ // // Translate magento fields for whiplash
174
+ // $api = $this->init_whiplash();
175
+ // $_order = $observer->getOrder();
176
+ // $_shippingAddress = $_order->getShippingAddress();
177
+ // $_shippingMethod = $_shippingAddress->getAddressShippingMethod();
178
+ // $_shipping_name = $_shippingAddress->getFirstname() . " " . $_shippingAddress->getLastname();
179
+ // $order_attributes = array(
180
+ // 'shipping_name' => $_shipping_name,
181
+ // 'shipping_company' => $_shippingAddress->getCompany(),
182
+ // 'shipping_address_1' => $_shippingAddress->getStreetFull(), // All address lines gets truncated into 1
183
+ // 'shipping_city' => $_shippingAddress->getCity(),
184
+ // 'shipping_state' => $_shippingAddress->getRegion(),
185
+ // 'shipping_zip' => $_shippingAddress->getPostcode(),
186
+ // 'shipping_country' => $_shippingAddress->getCountry_id(),
187
+ // 'email' => $_order->getCustomerEmail(),
188
+ // 'originator_id' => $_order->getEntity_id(),
189
+ // 'order_orig' => $_order->getRealOrderId(),
190
+ // 'req_ship_method_text' => $_order->getShipping_method(),
191
+ // 'req_ship_method_price' => $_order->getShipping_amount()
192
+ // );
193
+
194
+ // // Find the Whiplash order
195
+ // $whiplash_order = $api->get_order_by_originator($_order->getEntity_id());
196
+
197
+ // // Post to Whiplash
198
+ // $order = $api->update_order($whiplash_order->id, $order_attributes);
199
+
200
+
201
+ // }
202
+
203
+ }
app/code/community/Whiplash/Fulfillment/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <all>Allow Everything</all>
6
+ <admin>
7
+ <children>
8
+ <system>
9
+ <children>
10
+ <config>
11
+ <children>
12
+ <whiplash>
13
+ <title>Whiplash Configuration</title>
14
+ </whiplash>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/community/Whiplash/Fulfillment/etc/config.xml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Whiplash_Fulfillment>
6
+ <version>0.0.1</version>
7
+ </Whiplash_Fulfillment>
8
+ </modules>
9
+ <global>
10
+ <models>
11
+ <fulfillment>
12
+ <class>Whiplash_Fulfillment_Model</class>
13
+ </fulfillment>
14
+ </models>
15
+ <helpers>
16
+ <fulfillment>
17
+ <class>Whiplash_Fulfillment_Helper</class>
18
+ </fulfillment>
19
+ </helpers>
20
+ <events>
21
+ <catalog_product_save_after>
22
+ <observers>
23
+ <whiplash_fulfillment_product_observer>
24
+ <class>Whiplash_Fulfillment_Model_Observer</class>
25
+ <method>update_or_create_item</method>
26
+ </whiplash_fulfillment_product_observer>
27
+ </observers>
28
+ </catalog_product_save_after>
29
+ <sales_order_invoice_pay>
30
+ <observers>
31
+ <whiplash_fulfillment_order_observer>
32
+ <class>Whiplash_Fulfillment_Model_Observer</class>
33
+ <method>create_order</method>
34
+ </whiplash_fulfillment_order_observer>
35
+ </observers>
36
+ </sales_order_invoice_pay>
37
+ </events>
38
+ </global>
39
+ <default>
40
+ <whiplash>
41
+ <api>
42
+ <enabled>0</enabled>
43
+ <key></key> <!-- No key by default-->
44
+ <version></version> <!-- Latest Version (i.e. no value) by default-->
45
+ <test_mode>1</test_mode> <!-- Test mode by default-->
46
+ </api>
47
+ </whiplash>
48
+ </default>
49
+ </config>
app/code/community/Whiplash/Fulfillment/etc/system.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <whiplash>
5
+ <label>Whiplash</label>
6
+ <tab>catalog</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>305</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <api>
14
+ <label>API Configuration</label>
15
+ <sort_order>1</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <fields>
20
+ <enabled>
21
+ <label>Enable Whiplash</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>10</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </enabled>
29
+ <key translate="label">
30
+ <label>API Key</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>10</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ </key>
37
+ <version translate="label">
38
+ <label>API Version</label>
39
+ <frontend_type>select</frontend_type>
40
+ <source_model>fulfillment/adminhtml_system_config_source_apiversion</source_model>
41
+ <sort_order>20</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ </version>
46
+ <default_store_to_update translate="label">
47
+ <label>Default Store to Update</label>
48
+ <frontend_type>select</frontend_type>
49
+ <source_model>adminhtml/system_config_source_store</source_model>
50
+ <comment>Select the store that will get updated by default when no specific store view is selected when saving a product</comment>
51
+ <sort_order>30</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ </default_store_to_update>
55
+ <test_mode translate="label">
56
+ <label>Test Mode</label>
57
+ <frontend_type>select</frontend_type>
58
+ <source_model>adminhtml/system_config_source_yesno</source_model>
59
+ <sort_order>30</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ </test_mode>
64
+ </fields>
65
+ </api>
66
+ </groups>
67
+ </whiplash>
68
+ </sections>
69
+ </config>
app/code/community/Whiplash/Fulfillment/lib/WhiplashApi.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class WhiplashApi extends Varien_Object
35
+ {
36
+ // property declaration
37
+ public $base_url;
38
+ public $connection;
39
+
40
+ // Constructor
41
+ public function WhiplashApi($api_key, $api_version='', $storeId, $test=false) {
42
+ if ($test == true) {
43
+ $this->base_url = 'http://testing.whiplashmerch.com/api/';
44
+ } else {
45
+ $this->base_url = 'https://www.whiplashmerch.com/api/';
46
+ }
47
+
48
+ $ch = curl_init();
49
+ // Set headers
50
+ $headers = array(
51
+ 'Content-type: application/json',
52
+ 'Accept: application/json',
53
+ "X-API-KEY: $api_key",
54
+ 'Provider: magento',
55
+ "Shop-ID: $storeId"
56
+ );
57
+
58
+ if ($api_version != '') {
59
+ array_push($headers, "X-API-VERSION: $api_version");
60
+ }
61
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
62
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
63
+ $this->connection = $ch;
64
+ }
65
+
66
+ // Basic REST functions
67
+ public function get($path, $params=array()) {
68
+ $json_url = $this->base_url . $path;
69
+ $json_url .= '?' . http_build_query($params);
70
+ $ch = $this->connection;
71
+ curl_setopt($ch, CURLOPT_URL, $json_url);
72
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
73
+ $result = curl_exec($ch); // Getting jSON result string
74
+ $out = json_decode($result); // Decode the result
75
+ return $out;
76
+ }
77
+
78
+ public function post($path, $params=array()) {
79
+ $json_url = $this->base_url . $path;
80
+ $ch = $this->connection;
81
+ curl_setopt($ch, CURLOPT_URL, $json_url);
82
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
83
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
84
+ $result = curl_exec($ch); // Getting jSON result string
85
+ $out = json_decode($result); // Decode the result
86
+ return $out;
87
+ }
88
+
89
+ public function put($path, $params=array()) {
90
+ $json_url = $this->base_url . $path;
91
+ $ch = $this->connection;
92
+ curl_setopt($ch, CURLOPT_URL, $json_url);
93
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
94
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
95
+ $result = curl_exec($ch); // Getting jSON result string
96
+ $out = json_decode($result); // Decode the result
97
+ return $out;
98
+ }
99
+
100
+ public function delete($path, $params=array()) {
101
+ $json_url = $this->base_url . $path;
102
+ $ch = $this->connection;
103
+ curl_setopt($ch, CURLOPT_URL, $json_url);
104
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
105
+ $result = curl_exec($ch); // Getting jSON result string
106
+ $out = json_decode($result); // Decode the result
107
+ return $out;
108
+ }
109
+
110
+ /** Item functions **/
111
+ public function get_items($params=array()) {
112
+ return $this->get('items', $params);
113
+ }
114
+
115
+ public function get_item($id) {
116
+ return $this->get('items/'.$id);
117
+ }
118
+
119
+ public function get_items_by_sku($sku, $params=array()) {
120
+ return $this->get('items/sku/'.$sku, $params);
121
+ }
122
+
123
+ public function get_item_by_originator($id) {
124
+ return $this->get('items/originator/'.$id);
125
+ }
126
+
127
+ // This requires a valid ID
128
+ public function create_item($params=array()) {
129
+ $p = array();
130
+ if (!array_key_exists('item', $params)) {
131
+ $p['item'] = $params;
132
+ } else {
133
+ $p = $params;
134
+ }
135
+ return $this->post('items', $p);
136
+ }
137
+
138
+ // This requires a valid ID
139
+ public function update_item($id, $params=array()) {
140
+ $p = array();
141
+ if (!array_key_exists('item', $params)) {
142
+ $p['item'] = $params;
143
+ } else {
144
+ $p = $params;
145
+ }
146
+ return $this->put('items/'.$id, $p);
147
+ }
148
+
149
+ // This requires a valid ID
150
+ public function delete_item($id) {
151
+ return $this->delete('items/'.$id);
152
+ }
153
+
154
+
155
+ /** Order functions **/
156
+ public function get_orders($params=array()) {
157
+ return $this->get('orders', $params);
158
+ }
159
+
160
+ public function get_order($id) {
161
+ return $this->get('orders/'.$id);
162
+ }
163
+
164
+ public function get_order_by_originator($id) {
165
+ return $this->get('orders/originator/'.$id);
166
+ }
167
+
168
+ public function get_order_by_status($status) {
169
+ return $this->get('orders/status/'.$status);
170
+ }
171
+
172
+ // This requires a valid ID
173
+ public function create_order($params=array()) {
174
+ $p = array();
175
+ if ( !array_key_exists('order', $params)){
176
+ $p['order'] = $params;
177
+ } else {
178
+ $p = $params;
179
+ }
180
+ if ( array_key_exists('order', $p) ){
181
+ if (array_key_exists('order_items', $p['order'])) {
182
+ $p['order']['order_items_attributes'] = $p['order']['order_items'];
183
+ unset($p['order']['order_items']);
184
+ }
185
+ }
186
+ return $this->post('orders', $p);
187
+ }
188
+
189
+ // This requires a valid ID
190
+ public function update_order($id, $params=array()) {
191
+ $p = array();
192
+ if ( !array_key_exists('order', $params) ){
193
+ $p['order'] = $params;
194
+ } else {
195
+ $p = $params;
196
+ }
197
+ return $this->put('orders/'.$id, $p);
198
+ }
199
+
200
+ // This requires a valid ID
201
+ public function delete_order($id) {
202
+ return $this->delete('orders/'.$id);
203
+ }
204
+
205
+
206
+ /** OrderItem functions **/
207
+ public function get_order_item($id) {
208
+ return $this->get('order_items/'.$id);
209
+ }
210
+
211
+ public function get_order_item_by_originator($id) {
212
+ return $this->get('order_items/originator/'.$id);
213
+ }
214
+
215
+ // This requires a valid ID
216
+ public function create_order_item($params=array()) {
217
+ $p = array();
218
+ if (!array_key_exists('order_item', $params)) {
219
+ $p['order_item'] = $params;
220
+ } else {
221
+ $p = $params;
222
+ }
223
+ return $this->post('order_items', $p);
224
+ }
225
+
226
+ // This requires a valid ID
227
+ public function update_order_item($id, $params=array()) {
228
+ $p = array();
229
+ if (!array_key_exists('order_item', $params)) {
230
+ $p['order_item'] = $params;
231
+ } else {
232
+ $p = $params;
233
+ }
234
+ return $this->put('order_items/'.$id, $p);
235
+ }
236
+
237
+ // This requires a valid ID
238
+ public function delete_order_item($id) {
239
+ return $this->delete('order_items/'.$id);
240
+ }
241
+ }
242
+ ?>
app/code/community/Whiplash/Helper/Data.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class Whiplash_Fulfillment_Helper_Data extends Mage_Core_Helper_Abstract
35
+ {
36
+
37
+ }
app/code/community/Whiplash/Model/Adminhtml/System/Config/Source/Apiversion.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Adminhtml
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Used in creating options for Yes|No config value selection
29
+ *
30
+ */
31
+ class Whiplash_Fulfillment_Model_Adminhtml_System_Config_Source_Apiversion
32
+ {
33
+
34
+ /**
35
+ * Options getter
36
+ *
37
+ * @return array
38
+ */
39
+ public function toOptionArray()
40
+ {
41
+ return array(
42
+ array('value' => '', 'label'=>Mage::helper('adminhtml')->__('Latest Available')),
43
+ array('value' => 1.0, 'label'=>Mage::helper('adminhtml')->__('Whatever You Want. Edit Whiplash_FulFillment_Model_System_Config_Source_Apiversion')),
44
+ );
45
+ }
46
+
47
+ }
app/code/community/Whiplash/Model/Observer.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class Whiplash_Fulfillment_Model_Observer extends Varien_Object
35
+ {
36
+
37
+ protected function getStoreId()
38
+ {
39
+ $storeId = Mage::app()->getStore()->getId();
40
+
41
+ if($storeId == 0) // If the store id is 0 then we are in the admin area
42
+ {
43
+ // We want to make sure that whiplash is enabled for the requested store, if there is a requested store
44
+ $storeId = Mage::app()->getRequest()->getParam('store', Mage::getStoreConfig('whiplash/api/default_store_to_update')); //storeId will contain either a store id, or the "Default Store [id] to Update" if no specific store was requested
45
+ }
46
+
47
+ return $storeId;
48
+ }
49
+
50
+ protected function isEnabledForStoreId($storeId)
51
+ {
52
+ return Mage::getStoreConfig('whiplash/api/enabled',$storeId);
53
+ }
54
+
55
+ protected function init_whiplash()
56
+ {
57
+ // Set the API credentials
58
+ $api_key = Mage::getStoreConfig('whiplash/api/key'); // Whiplash Sandbox on Testing Server
59
+ $api_version = Mage::getStoreConfig('whiplash/api/version'); // OPTIONAL: Leave this blank to use the most recent API
60
+ $storeId = $this->getStoreId();
61
+ $test = Mage::getStoreConfig('whiplash/api/test_mode'); // OPTIONAL: If test is true, this will use your sandbox account
62
+
63
+ // Include the Whiplash lib and initialize
64
+ $ExternalLibPath=Mage::getBaseDir('code') . DS . 'community' . DS . 'Whiplash' . DS . 'Fulfillment'. DS . 'lib' . DS .'WhiplashApi.php';
65
+ require_once ($ExternalLibPath);
66
+ $api = new WhiplashApi($api_key, $api_version, $storeId, $test);
67
+ return $api;
68
+ }
69
+
70
+ public function update_or_create_item($observer)
71
+ // Creates or updates an item in Whiplash
72
+ {
73
+ if($this->isEnabledForStoreId($this->getStoreId()))
74
+ {
75
+ $api = $this->init_whiplash();
76
+ $_product = $observer->getProduct();
77
+ if($_product->getTypeID() == 'simple'){
78
+
79
+ $parentProduct = Mage::getResourceSingleton('catalog/product_type_configurable')
80
+ ->getParentIdsByChild($_product->getId());
81
+
82
+ if(is_array($parentProduct) && !empty($parentProduct))
83
+ {
84
+ $parentProduct = Mage::getModel('catalog/product')->load(array_pop($parentProduct));
85
+ if($parentProduct && $parentProduct->getId())
86
+ {
87
+ $image = $parentProduct->getMediaConfig()->getMediaUrl($parentProduct->getData('image'));
88
+ }
89
+ }
90
+
91
+ // Get the expected quantity
92
+ $quantity = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
93
+
94
+ $item = array(
95
+ 'sku' => $_product->getSku(),
96
+ 'title' => $_product->getName(),
97
+ 'exp_quantity' => $quantity,
98
+ 'image_originator_url' => $image?$image:$_product->getMediaConfig()->getMediaUrl($_product->getData('image')),
99
+ 'price' => $_product->getPrice(),
100
+ 'wholesale_cost' => $_product->getCost(),
101
+ 'originator_id' => $_product->getId()
102
+ );
103
+
104
+ // Check if the item exists in Whiplash
105
+ $whiplash_item = $api->get_item_by_originator($_product->getId());
106
+ if (!$whiplash_item){
107
+ // We didn't get an item back, create it
108
+ $api->create_item($item); }
109
+ // Item exists in Whiplash, so update it
110
+ else {
111
+ $api->update_item($whiplash_item->id,$item);
112
+ }
113
+ } // Failed type == simple test, ignore item
114
+ }
115
+ }
116
+
117
+
118
+ public function create_order($observer)
119
+ // Creates an order and order_items in Whiplash
120
+ {
121
+ $api = $this->init_whiplash();
122
+ $_order = $observer->getEvent()->getInvoice()->getOrder();
123
+ if($this->isEnabledForStoreId($_order->getStoreId()))
124
+ {
125
+ $_shippingAddress = $_order->getShippingAddress();
126
+ $_shippingMethod = $_shippingAddress->getAddressShippingMethod();
127
+
128
+ // Translate magento fields for whiplash
129
+ $_shipping_name = $_shippingAddress->getFirstname() . " " . $_shippingAddress->getLastname();
130
+ $order_attributes = array(
131
+ 'shipping_name' => $_shipping_name,
132
+ 'shipping_company' => $_shippingAddress->getCompany(),
133
+ 'shipping_address_1' => $_shippingAddress->getStreetFull(), // All address lines gets truncated into 1
134
+ 'shipping_city' => $_shippingAddress->getCity(),
135
+ 'shipping_state' => $_shippingAddress->getRegion(),
136
+ 'shipping_zip' => $_shippingAddress->getPostcode(),
137
+ 'shipping_country' => $_shippingAddress->getCountry_id(),
138
+ 'shipping_phone' => $_shippingAddress->getTelephone(),
139
+ 'email' => $_order->getCustomerEmail(),
140
+ 'originator_id' => $_order->getRealOrderId(),
141
+ 'order_orig' => $_order->getRealOrderId(),
142
+ 'req_ship_method_text' => $_order->getShippingMethod(),
143
+ 'req_ship_method_price' => $_order->getShippingAmount(),
144
+ 'order_items_attributes' => array()
145
+ );
146
+
147
+ // Add the order_items
148
+ $items = $_order->getAllVisibleItems();
149
+ $i = 0;
150
+ foreach ($items as $itemId => $item)
151
+ {
152
+ if ($item->getQtyOrdered() > 0){
153
+ // There are master items on the invoice, we only want the 'real' items
154
+ $whiplash_item = $api->get_items_by_sku($item->getSku()); // This is an array; we want to the first result
155
+ // Find the id of the whiplash item
156
+ if ( is_array($whiplash_item) ) {
157
+ $whiplash_item = $whiplash_item[0];
158
+ $order_attributes['order_items'][$i] = array('quantity' => $item->getQtyOrdered(), 'item_id' => $whiplash_item->id, 'originator_id' => $item->getId(), 'price' => $item->getRowTotalInclTax()/$item->getQtyOrdered());
159
+ $i += 1;
160
+ }
161
+ }
162
+ }
163
+ // Post to Whiplash
164
+ $order = $api->create_order($order_attributes);
165
+ }
166
+ }
167
+
168
+ // public function update_order($observer){
169
+ // Not currently supported. This could overwrite intentional changes in Whiplash. Possibly see which side is newer to allow it through?
170
+
171
+ // // Updates the address and shipping method in Whiplash
172
+
173
+ // // Translate magento fields for whiplash
174
+ // $api = $this->init_whiplash();
175
+ // $_order = $observer->getOrder();
176
+ // $_shippingAddress = $_order->getShippingAddress();
177
+ // $_shippingMethod = $_shippingAddress->getAddressShippingMethod();
178
+ // $_shipping_name = $_shippingAddress->getFirstname() . " " . $_shippingAddress->getLastname();
179
+ // $order_attributes = array(
180
+ // 'shipping_name' => $_shipping_name,
181
+ // 'shipping_company' => $_shippingAddress->getCompany(),
182
+ // 'shipping_address_1' => $_shippingAddress->getStreetFull(), // All address lines gets truncated into 1
183
+ // 'shipping_city' => $_shippingAddress->getCity(),
184
+ // 'shipping_state' => $_shippingAddress->getRegion(),
185
+ // 'shipping_zip' => $_shippingAddress->getPostcode(),
186
+ // 'shipping_country' => $_shippingAddress->getCountry_id(),
187
+ // 'email' => $_order->getCustomerEmail(),
188
+ // 'originator_id' => $_order->getEntity_id(),
189
+ // 'order_orig' => $_order->getRealOrderId(),
190
+ // 'req_ship_method_text' => $_order->getShipping_method(),
191
+ // 'req_ship_method_price' => $_order->getShipping_amount()
192
+ // );
193
+
194
+ // // Find the Whiplash order
195
+ // $whiplash_order = $api->get_order_by_originator($_order->getEntity_id());
196
+
197
+ // // Post to Whiplash
198
+ // $order = $api->update_order($whiplash_order->id, $order_attributes);
199
+
200
+
201
+ // }
202
+
203
+ }
app/code/community/Whiplash/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <all>Allow Everything</all>
6
+ <admin>
7
+ <children>
8
+ <system>
9
+ <children>
10
+ <config>
11
+ <children>
12
+ <whiplash>
13
+ <title>Whiplash Configuration</title>
14
+ </whiplash>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/community/Whiplash/etc/config.xml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Whiplash_Fulfillment>
6
+ <version>0.0.1</version>
7
+ </Whiplash_Fulfillment>
8
+ </modules>
9
+ <global>
10
+ <models>
11
+ <fulfillment>
12
+ <class>Whiplash_Fulfillment_Model</class>
13
+ </fulfillment>
14
+ </models>
15
+ <helpers>
16
+ <fulfillment>
17
+ <class>Whiplash_Fulfillment_Helper</class>
18
+ </fulfillment>
19
+ </helpers>
20
+ <events>
21
+ <catalog_product_save_after>
22
+ <observers>
23
+ <whiplash_fulfillment_product_observer>
24
+ <class>Whiplash_Fulfillment_Model_Observer</class>
25
+ <method>update_or_create_item</method>
26
+ </whiplash_fulfillment_product_observer>
27
+ </observers>
28
+ </catalog_product_save_after>
29
+ <sales_order_invoice_pay>
30
+ <observers>
31
+ <whiplash_fulfillment_order_observer>
32
+ <class>Whiplash_Fulfillment_Model_Observer</class>
33
+ <method>create_order</method>
34
+ </whiplash_fulfillment_order_observer>
35
+ </observers>
36
+ </sales_order_invoice_pay>
37
+ </events>
38
+ </global>
39
+ <default>
40
+ <whiplash>
41
+ <api>
42
+ <enabled>0</enabled>
43
+ <key></key> <!-- No key by default-->
44
+ <version></version> <!-- Latest Version (i.e. no value) by default-->
45
+ <test_mode>1</test_mode> <!-- Test mode by default-->
46
+ </api>
47
+ </whiplash>
48
+ </default>
49
+ </config>
app/code/community/Whiplash/etc/system.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <whiplash>
5
+ <label>Whiplash</label>
6
+ <tab>catalog</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>305</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <api>
14
+ <label>API Configuration</label>
15
+ <sort_order>1</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <fields>
20
+ <enabled>
21
+ <label>Enable Whiplash</label>
22
+ <frontend_type>select</frontend_type>
23
+ <source_model>adminhtml/system_config_source_yesno</source_model>
24
+ <sort_order>10</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </enabled>
29
+ <key translate="label">
30
+ <label>API Key</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>10</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ </key>
37
+ <version translate="label">
38
+ <label>API Version</label>
39
+ <frontend_type>select</frontend_type>
40
+ <source_model>fulfillment/adminhtml_system_config_source_apiversion</source_model>
41
+ <sort_order>20</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ </version>
46
+ <default_store_to_update translate="label">
47
+ <label>Default Store to Update</label>
48
+ <frontend_type>select</frontend_type>
49
+ <source_model>adminhtml/system_config_source_store</source_model>
50
+ <comment>Select the store that will get updated by default when no specific store view is selected when saving a product</comment>
51
+ <sort_order>30</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ <show_in_website>1</show_in_website>
54
+ </default_store_to_update>
55
+ <test_mode translate="label">
56
+ <label>Test Mode</label>
57
+ <frontend_type>select</frontend_type>
58
+ <source_model>adminhtml/system_config_source_yesno</source_model>
59
+ <sort_order>30</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ </test_mode>
64
+ </fields>
65
+ </api>
66
+ </groups>
67
+ </whiplash>
68
+ </sections>
69
+ </config>
app/code/community/Whiplash/lib/WhiplashApi.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Whiplash
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Please do not edit or add to this file if you wish to upgrade
18
+ * Magento or this extension to newer versions in the future.
19
+ * Whiplash developers (Whiplasher's) give their best to conform to
20
+ * "non-obtrusive, best Magento practices" style of coding.
21
+ * However, Whiplash does not guarantee functional accuracy of
22
+ * specific extension behavior. Additionally we take no responsibility
23
+ * for any possible issue(s) resulting from extension usage.
24
+ * We reserve the full right not to provide any kind of support for our free extensions.
25
+ * Thank you for your understanding.
26
+ *
27
+ * @category Whiplash
28
+ * @package Fulfillment
29
+ * @author James Marks <james@whiplashmerch.com> based on the work of Marko Martinović <marko.martinovic@inchoo.net>
30
+ * @copyright Copyright (c) Whiplash Merch (http://whiplashmerch.com/)
31
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
+ */
33
+
34
+ class WhiplashApi extends Varien_Object
35
+ {
36
+ // property declaration
37
+ public $base_url;
38
+ public $connection;
39
+
40
+ // Constructor
41
+ public function WhiplashApi($api_key, $api_version='', $storeId, $test=false) {
42
+ if ($test == true) {
43
+ $this->base_url = 'http://testing.whiplashmerch.com/api/';
44
+ } else {
45
+ $this->base_url = 'https://www.whiplashmerch.com/api/';
46
+ }
47
+
48
+ $ch = curl_init();
49
+ // Set headers
50
+ $headers = array(
51
+ 'Content-type: application/json',
52
+ 'Accept: application/json',
53
+ "X-API-KEY: $api_key",
54
+ 'Provider: magento',
55
+ "Shop-ID: $storeId"
56
+ );
57
+
58
+ if ($api_version != '') {
59
+ array_push($headers, "X-API-VERSION: $api_version");
60
+ }
61
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
62
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
63
+ $this->connection = $ch;
64
+ }
65
+
66
+ // Basic REST functions
67
+ public function get($path, $params=array()) {
68
+ $json_url = $this->base_url . $path;
69
+ $json_url .= '?' . http_build_query($params);
70
+ $ch = $this->connection;
71
+ curl_setopt($ch, CURLOPT_URL, $json_url);
72
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
73
+ $result = curl_exec($ch); // Getting jSON result string
74
+ $out = json_decode($result); // Decode the result
75
+ return $out;
76
+ }
77
+
78
+ public function post($path, $params=array()) {
79
+ $json_url = $this->base_url . $path;
80
+ $ch = $this->connection;
81
+ curl_setopt($ch, CURLOPT_URL, $json_url);
82
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
83
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
84
+ $result = curl_exec($ch); // Getting jSON result string
85
+ $out = json_decode($result); // Decode the result
86
+ return $out;
87
+ }
88
+
89
+ public function put($path, $params=array()) {
90
+ $json_url = $this->base_url . $path;
91
+ $ch = $this->connection;
92
+ curl_setopt($ch, CURLOPT_URL, $json_url);
93
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
94
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
95
+ $result = curl_exec($ch); // Getting jSON result string
96
+ $out = json_decode($result); // Decode the result
97
+ return $out;
98
+ }
99
+
100
+ public function delete($path, $params=array()) {
101
+ $json_url = $this->base_url . $path;
102
+ $ch = $this->connection;
103
+ curl_setopt($ch, CURLOPT_URL, $json_url);
104
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
105
+ $result = curl_exec($ch); // Getting jSON result string
106
+ $out = json_decode($result); // Decode the result
107
+ return $out;
108
+ }
109
+
110
+ /** Item functions **/
111
+ public function get_items($params=array()) {
112
+ return $this->get('items', $params);
113
+ }
114
+
115
+ public function get_item($id) {
116
+ return $this->get('items/'.$id);
117
+ }
118
+
119
+ public function get_items_by_sku($sku, $params=array()) {
120
+ return $this->get('items/sku/'.$sku, $params);
121
+ }
122
+
123
+ public function get_item_by_originator($id) {
124
+ return $this->get('items/originator/'.$id);
125
+ }
126
+
127
+ // This requires a valid ID
128
+ public function create_item($params=array()) {
129
+ $p = array();
130
+ if (!array_key_exists('item', $params)) {
131
+ $p['item'] = $params;
132
+ } else {
133
+ $p = $params;
134
+ }
135
+ return $this->post('items', $p);
136
+ }
137
+
138
+ // This requires a valid ID
139
+ public function update_item($id, $params=array()) {
140
+ $p = array();
141
+ if (!array_key_exists('item', $params)) {
142
+ $p['item'] = $params;
143
+ } else {
144
+ $p = $params;
145
+ }
146
+ return $this->put('items/'.$id, $p);
147
+ }
148
+
149
+ // This requires a valid ID
150
+ public function delete_item($id) {
151
+ return $this->delete('items/'.$id);
152
+ }
153
+
154
+
155
+ /** Order functions **/
156
+ public function get_orders($params=array()) {
157
+ return $this->get('orders', $params);
158
+ }
159
+
160
+ public function get_order($id) {
161
+ return $this->get('orders/'.$id);
162
+ }
163
+
164
+ public function get_order_by_originator($id) {
165
+ return $this->get('orders/originator/'.$id);
166
+ }
167
+
168
+ public function get_order_by_status($status) {
169
+ return $this->get('orders/status/'.$status);
170
+ }
171
+
172
+ // This requires a valid ID
173
+ public function create_order($params=array()) {
174
+ $p = array();
175
+ if ( !array_key_exists('order', $params)){
176
+ $p['order'] = $params;
177
+ } else {
178
+ $p = $params;
179
+ }
180
+ if ( array_key_exists('order', $p) ){
181
+ if (array_key_exists('order_items', $p['order'])) {
182
+ $p['order']['order_items_attributes'] = $p['order']['order_items'];
183
+ unset($p['order']['order_items']);
184
+ }
185
+ }
186
+ return $this->post('orders', $p);
187
+ }
188
+
189
+ // This requires a valid ID
190
+ public function update_order($id, $params=array()) {
191
+ $p = array();
192
+ if ( !array_key_exists('order', $params) ){
193
+ $p['order'] = $params;
194
+ } else {
195
+ $p = $params;
196
+ }
197
+ return $this->put('orders/'.$id, $p);
198
+ }
199
+
200
+ // This requires a valid ID
201
+ public function delete_order($id) {
202
+ return $this->delete('orders/'.$id);
203
+ }
204
+
205
+
206
+ /** OrderItem functions **/
207
+ public function get_order_item($id) {
208
+ return $this->get('order_items/'.$id);
209
+ }
210
+
211
+ public function get_order_item_by_originator($id) {
212
+ return $this->get('order_items/originator/'.$id);
213
+ }
214
+
215
+ // This requires a valid ID
216
+ public function create_order_item($params=array()) {
217
+ $p = array();
218
+ if (!array_key_exists('order_item', $params)) {
219
+ $p['order_item'] = $params;
220
+ } else {
221
+ $p = $params;
222
+ }
223
+ return $this->post('order_items', $p);
224
+ }
225
+
226
+ // This requires a valid ID
227
+ public function update_order_item($id, $params=array()) {
228
+ $p = array();
229
+ if (!array_key_exists('order_item', $params)) {
230
+ $p['order_item'] = $params;
231
+ } else {
232
+ $p = $params;
233
+ }
234
+ return $this->put('order_items/'.$id, $p);
235
+ }
236
+
237
+ // This requires a valid ID
238
+ public function delete_order_item($id) {
239
+ return $this->delete('order_items/'.$id);
240
+ }
241
+ }
242
+ ?>
app/etc/modules/Whiplash_Fulfillment.xml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <modules>
5
+ <Whiplash_Fulfillment>
6
+ <active>true</active>
7
+ <codePool>community</codePool>
8
+ </Whiplash_Fulfillment>
9
+ </modules>
10
+ </config>
package.xml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Whiplash_Fulfillment</name>
4
+ <version>0.0.1</version>
5
+ <stability>devel</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">yd521cdsf5re1serkcjbf4r50rew54cxc12</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>The Whiplash extension enables you to seamlessly connect your Magento store with Whiplash Fulfillment.</summary>
10
+ <description>&lt;h3&gt;Packing orders is fun at first&lt;/h3&gt;&#xD;
11
+ &#xD;
12
+ But as your business grows, you need to hand the task off to the professionals. A proper warehouse can free your time up to work ON your business instead of IN your business, lower your shipping costs, and make your customers happier.&#xD;
13
+ &#xD;
14
+ But let's face it, do you really want your orders to look like they came from some factory that doesn't have a clue what's in the box? Of course not.&#xD;
15
+ &#xD;
16
+ Customers feel Connected&amp;lt;/h3&amp;gt;&#xD;
17
+ &#xD;
18
+ And that's where Whiplash steps in. Once you send your products to us for storage, you've got the power of a modern warehouse at your fingertips, without compromising the look and feel of your brand.&#xD;
19
+ &#xD;
20
+ &lt;h3&gt;Life gets easier&lt;/h3&gt;&#xD;
21
+ &#xD;
22
+ As orders come in, they ship automatically. Did you get an email that a customer needs to change their address? No problem-- you can change an address up until the moment the package goes out the door. Need to swap small out for a medium? Easy as pie.&#xD;
23
+ &#xD;
24
+ When orders ship, we update your Magento store with the tracking number and close the order auto-magically.&#xD;
25
+ &#xD;
26
+ &lt;h3&gt;Inventory stays Organized&lt;/h3&gt;&#xD;
27
+ &#xD;
28
+ There's something you should know about us- we're neat freaks, maybe even a little OCD. The upside is your inventory is clean, organized, and best yet -- Whiplash updates your Magento store automatically with exactly what's in stock.&#xD;
29
+ &#xD;
30
+ &lt;h3&gt;Pricing&lt;/h3&gt;&#xD;
31
+ &#xD;
32
+ &amp;lt;ul&amp;gt;&#xD;
33
+ &lt;li&gt;$2.95 per order, which includes the 1st item&#xD;
34
+ &lt;li /&gt;Items 2-6: $.85 each&lt;/li&gt;&#xD;
35
+ &lt;li&gt;Items 7+: $.25 each&lt;/li&gt;&#xD;
36
+ &#xD;
37
+ Lastly you pay the actual cost of mailing materials, carrier fees (we use USPS &amp;amp; UPS), and a warehousing fee as low as $.45/cubic foot with a $25/month minimum.</description>
38
+ <notes>- This is first Notes</notes>
39
+ <authors><author><name>Peter Imai</name><user>Whiplash</user><email>james@whiplashmerch.com</email></author></authors>
40
+ <date>2016-02-08</date>
41
+ <time>12:10:03</time>
42
+ <contents><target name="magecommunity"><dir name="Whiplash"><dir name="Fulfillment"><dir name="Helper"><file name="Data.php" hash="b7f252699701bd3eee38b208c1be9689"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Source"><file name="Apiversion.php" hash="7ec9961a0fe148fd4e30802da3d8c354"/></dir></dir></dir></dir><file name="Observer.php" hash="97b84f00820f346d2af8e86d8092d84f"/></dir><dir name="etc"><file name="adminhtml.xml" hash="997969b7b8dee067918cf652d804607d"/><file name="config.xml" hash="f0cfaa405dd89cbd8701a16b4a9e33b0"/><file name="system.xml" hash="563858f86eaa4459e16917d0fd8e6043"/></dir><dir name="lib"><file name="WhiplashApi.php" hash="66d952fb5735e1ca5e74c8803fcc7597"/></dir></dir><dir name="Helper"><file name="Data.php" hash="b7f252699701bd3eee38b208c1be9689"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Source"><file name="Apiversion.php" hash="7ec9961a0fe148fd4e30802da3d8c354"/></dir></dir></dir></dir><file name="Observer.php" hash="97b84f00820f346d2af8e86d8092d84f"/></dir><dir name="etc"><file name="adminhtml.xml" hash="997969b7b8dee067918cf652d804607d"/><file name="config.xml" hash="f0cfaa405dd89cbd8701a16b4a9e33b0"/><file name="system.xml" hash="563858f86eaa4459e16917d0fd8e6043"/></dir><dir name="lib"><file name="WhiplashApi.php" hash="66d952fb5735e1ca5e74c8803fcc7597"/></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Whiplash_Fulfillment.xml" hash="3b195f95342271be87bbf2f5fdc2265b"/></dir></target></contents>
43
+ <compatible/>
44
+ <dependencies><required><php><min>5.0.0</min><max>5.6.17</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.2.0</min><max>1.9.2</max></package></required></dependencies>
45
+ </package>