ShipHero - Version 1.0.0.14

Version Notes

- Fixed typo in customerEmailComment, that was filling up the log

Download this release

Release Info

Developer Fareed Hosein
Extension ShipHero
Version 1.0.0.14
Comparing to
See all releases


Version 1.0.0.14

Files changed (24) hide show
  1. app/code/community/ShipHero/.DS_Store +0 -0
  2. app/code/community/ShipHero/CatalogExtApi/Model/Api2/Product/Rest/.DS_Store +0 -0
  3. app/code/community/ShipHero/CatalogExtApi/Model/Api2/Product/Rest/Admin/V1.php +187 -0
  4. app/code/community/ShipHero/CatalogExtApi/etc/api2.xml +53 -0
  5. app/code/community/ShipHero/CatalogExtApi/etc/config.xml +15 -0
  6. app/code/community/ShipHero/PaymentExtApi/Model/Api2/Payment.php +6 -0
  7. app/code/community/ShipHero/PaymentExtApi/Model/Api2/Payment/Rest/Admin/V1.php +151 -0
  8. app/code/community/ShipHero/PaymentExtApi/etc/api2.xml +30 -0
  9. app/code/community/ShipHero/PaymentExtApi/etc/config.xml +15 -0
  10. app/code/community/ShipHero/SalesExtApi/Model/Api2/Order/Rest/Admin/V1.php +76 -0
  11. app/code/community/ShipHero/SalesExtApi/etc/api2.xml +299 -0
  12. app/code/community/ShipHero/SalesExtApi/etc/config.xml +15 -0
  13. app/code/community/ShipHero/ShipmentExtApi/Model/Api2/Shipment.php +6 -0
  14. app/code/community/ShipHero/ShipmentExtApi/Model/Api2/Shipment/Rest/Admin/V1.php +192 -0
  15. app/code/community/ShipHero/ShipmentExtApi/etc/api2.xml +34 -0
  16. app/code/community/ShipHero/ShipmentExtApi/etc/config.xml +15 -0
  17. app/code/community/ShipHero/WebHooks/Model/OrderObserver.php +216 -0
  18. app/code/community/ShipHero/WebHooks/Model/ProductObserver.php +215 -0
  19. app/code/community/ShipHero/WebHooks/Model/Resource/Setup.php +4 -0
  20. app/code/community/ShipHero/WebHooks/etc/config.xml +87 -0
  21. app/code/community/ShipHero/WebHooks/etc/webapi/acl.xml +35 -0
  22. app/code/community/ShipHero/WebHooks/sql/shiphero_setup/install-0.1.0.php +112 -0
  23. app/etc/modules/ShipHero.xml +25 -0
  24. package.xml +50 -0
app/code/community/ShipHero/.DS_Store ADDED
Binary file
app/code/community/ShipHero/CatalogExtApi/Model/Api2/Product/Rest/.DS_Store ADDED
Binary file
app/code/community/ShipHero/CatalogExtApi/Model/Api2/Product/Rest/Admin/V1.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_CatalogExtApi_Model_Api2_Product_Rest_Admin_V1 extends Mage_Catalog_Model_Api2_Product_Rest_Admin_V1
4
+ {
5
+
6
+ /**
7
+ * Retrieve product count
8
+ *
9
+ * @return array
10
+ */
11
+ protected function _retrieve()
12
+ {
13
+ /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
14
+ $collection = Mage::getResourceModel('catalog/product_collection');
15
+ $store = $this->_getStore();
16
+ $collection->setStoreId($store->getId());
17
+ $collection->addAttributeToSelect(array_keys(
18
+ $this->getAvailableAttributes($this->getUserType(), Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ)
19
+ ));
20
+ $this->_applyCategoryFilter($collection);
21
+ $this->_applyCollectionModifiers($collection);
22
+ $products = $collection->load()->toArray();
23
+
24
+ // Get all attribute sets
25
+ $attributeSets = array();
26
+ // $attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection')->load();
27
+ $entityType = Mage::getModel('catalog/product')->getResource()->getTypeId();
28
+ $attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection')->setEntityTypeFilter($entityType);
29
+ foreach ($attributeSetCollection as $attributeSet) {
30
+ $id = $attributeSet->getAttributeSetId();
31
+ $name = $attributeSet->getAttributeSetName();
32
+ $attributeSets[] = array('id' => $id, 'name' => $name);
33
+ }
34
+
35
+ $productInfo = array('catalog_size' => $collection->getSize(), 'attribute_sets' => $attributeSets);
36
+
37
+ return $productInfo;
38
+ }
39
+
40
+ /**
41
+ * Retrieve list of products
42
+ *
43
+ * @return array
44
+ */
45
+ protected function _retrieveCollection()
46
+ {
47
+ /** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
48
+ $collection = Mage::getResourceModel('catalog/product_collection');
49
+ $store = $this->_getStore();
50
+ $collection->setStoreId($store->getId());
51
+ $collection->addAttributeToSelect(array_keys(
52
+ $this->getAvailableAttributes($this->getUserType(), Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ)
53
+ ));
54
+ $this->_applyCategoryFilter($collection);
55
+ $this->_applyCollectionModifiers($collection);
56
+ $products = $collection->load()->toArray();
57
+ $total_products = $collection->getSize();
58
+
59
+ // Get all frontend attributes
60
+ $allFrontendAttributeCodes = array();
61
+ $allAttributeCodes = array();
62
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')->getItems();
63
+
64
+ foreach ($attributes as $attribute){
65
+ $_attribute = $attribute->getData();
66
+ if($_attribute['is_visible_on_front'])
67
+ {
68
+ $allFrontendAttributeCodes[] = $attribute->getAttributeCode();
69
+ }
70
+
71
+ $allAttributeCodes[] = $attribute->getAttributeCode();
72
+
73
+ }
74
+
75
+ foreach($products as $k => $p)
76
+ {
77
+ $images = array();
78
+ $product = Mage::getModel('catalog/product')->load($p['entity_id']);
79
+ $product_attributes = array();
80
+
81
+ $p_name = $p['name'];
82
+ foreach($allFrontendAttributeCodes as $a)
83
+ {
84
+ if(array_key_exists($a, $p) && ($a == 'color' || $a == 'size'))
85
+ {
86
+ $attribute_value = $product->getAttributeText($a);
87
+
88
+ if(!empty($attribute_value))
89
+ $p_name .= ' / ' . $attribute_value;
90
+ }
91
+ }
92
+
93
+
94
+ foreach($allAttributeCodes as $b)
95
+ {
96
+ if(array_key_exists($b, $p))
97
+ {
98
+ $attribute_value = $product->getAttributeText($b);
99
+ if($attribute_value == false)
100
+ {
101
+ $attr = $product->getResource()->getAttribute('design_number');
102
+ if(!empty($attr))
103
+ $attribute_value = $attr->getFrontend()->getValue($product);
104
+ }
105
+ $product_attributes[] = array($b => $attribute_value);
106
+ }
107
+ }
108
+
109
+ $stock = $product['stock_item']->getData();
110
+
111
+ foreach ($product->getMediaGalleryImages() as $image) {
112
+ $images[] = array('url' => $image->getUrl(), 'position' => $image->getPosition());
113
+ }
114
+
115
+ if(empty($images))
116
+ {
117
+ $parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($p['entity_id']);
118
+ if(!empty($parentIds))
119
+ {
120
+ $productParent = Mage::getModel('catalog/product')->load($parentIds[0]);
121
+ foreach($productParent->getMediaGalleryImages() as $image)
122
+ {
123
+ $images[] = array('url' => $image->getUrl(), 'position' => $image->getPosition());
124
+ }
125
+ }
126
+ }
127
+
128
+ $products[$k]['adjusted_name'] = $p_name;
129
+ $products[$k]['images'] = $images;
130
+ $products[$k]['stock'] = $stock;
131
+ $products[$k]['attributes'] = $product_attributes;
132
+ $products[$k]['catalog_size'] = $total_products;
133
+ }
134
+
135
+ return $products;
136
+ }
137
+
138
+ /**
139
+ * Update product by its ID
140
+ *
141
+ * @param array $data
142
+ * TODO: Finish update product endpoint
143
+ */
144
+ // protected function _update(array $data)
145
+ // {
146
+ // error_log('in update');
147
+ // error_log(print_r($data,1));
148
+ // $product = $this->_getProduct();
149
+ // if(empty($product))
150
+ // {
151
+ // $this->_critical('Invalid product id: ' . $this->getRequest()->getParam('id'), Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
152
+ // }
153
+ //
154
+ // $colors = array();
155
+ // $attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 'color');
156
+ // foreach ($attribute->getSource()->getAllOptions(true, true) as $instance)
157
+ // {
158
+ // $colors[$instance['value']] = $instance['label'];
159
+ // }
160
+ //
161
+ // // Make sure that the product has the default attribute set id
162
+ // $defaultAttributeSetId = Mage::getModel('catalog/product')->getDefaultAttributeSetId();
163
+ // $productData = $product->getData();
164
+ //// $product->setData('color', 20);
165
+ //// $attributes = Mage::getModel('catalog/product_attribute_api')->items($data['attribute_set_id']);
166
+ //// error_log(print_r($attributes,1));
167
+ //// if($product->getAttributeSetId() == $defaultAttributeSetId)
168
+ //// {
169
+ //// $attributes = Mage::getModel('catalog/product_attribute_set_api')->items($data['attribute_set_id']);
170
+ //// $product->setAttributeSetId($data['attribute_set_id']);
171
+ //// }
172
+ //// if (isset($data['sku'])) {
173
+ //// $product->setSku($data['sku']);
174
+ //// }
175
+ //
176
+ // try {
177
+ // $product->save();
178
+ // } catch (Mage_Eav_Model_Entity_Attribute_Exception $e) {
179
+ // $this->_critical(sprintf('Invalid attribute "%s": %s', $e->getAttributeCode(), $e->getMessage()),
180
+ // Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
181
+ // } catch (Mage_Core_Exception $e) {
182
+ // $this->_critical($e->getMessage(), Mage_Api2_Model_Server::HTTP_INTERNAL_ERROR);
183
+ // } catch (Exception $e) {
184
+ // $this->_critical(self::RESOURCE_UNKNOWN_ERROR);
185
+ // }
186
+ // }
187
+ }
app/code/community/ShipHero/CatalogExtApi/etc/api2.xml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api2>
4
+ <resource_groups>
5
+ <catalogextapi translate="title" module="ShipHero_CatalogEXtApi">
6
+ <title>ShipHero</title>
7
+ <sort_order>10</sort_order>
8
+ </catalogextapi>
9
+ </resource_groups>
10
+ <resources>
11
+ <catalogextapi translate="title" module="ShipHero_CatalogEXtApi">
12
+ <group>catalogextapi</group>
13
+ <title>Product</title>
14
+ <sort_order>10</sort_order>
15
+ <model>catalogextapi/api2_product</model>
16
+ <privileges>
17
+ <admin>
18
+ <create>1</create>
19
+ <retrieve>1</retrieve>
20
+ <update>1</update>
21
+ <delete>1</delete>
22
+ </admin>
23
+ </privileges>
24
+ <attributes>
25
+ <adjusted_name>Adjusted Name</adjusted_name>
26
+ <images>Images</images>
27
+ <stock>Inventory</stock>
28
+ <attributes>Attributes</attributes>
29
+ <catalog_size>Catalog Size</catalog_size>
30
+ <attribute_sets>Attribute Sets</attribute_sets>
31
+ <components>Components</components>
32
+ <attribute_set_id>Attribute Set Id</attribute_set_id>
33
+ <entity_id>Entity Id</entity_id>
34
+ </attributes>
35
+ <routes>
36
+ <route_entity>
37
+ <route>/shiphero/products/count</route>
38
+ <action_type>entity</action_type>
39
+ </route_entity>
40
+ <route_entity>
41
+ <route>/shiphero/products/:id</route>
42
+ <action_type>entity</action_type>
43
+ </route_entity>
44
+ <route_collection>
45
+ <route>/shiphero/products</route>
46
+ <action_type>collection</action_type>
47
+ </route_collection>
48
+ </routes>
49
+ <versions>1</versions>
50
+ </catalogextapi>
51
+ </resources>
52
+ </api2>
53
+ </config>
app/code/community/ShipHero/CatalogExtApi/etc/config.xml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_CatalogExtApi>
5
+ <version>0.1.0</version>
6
+ </ShipHero_CatalogExtApi>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <catalogextapi>
11
+ <class>ShipHero_CatalogExtApi_Model</class>
12
+ </catalogextapi>
13
+ </models>
14
+ </global>
15
+ </config>
app/code/community/ShipHero/PaymentExtApi/Model/Api2/Payment.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_PaymentExtApi_Model_Api2_Payment extends Mage_Api2_Model_Resource
4
+ {
5
+
6
+ }
app/code/community/ShipHero/PaymentExtApi/Model/Api2/Payment/Rest/Admin/V1.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* ShipHero Shipment REST API
3
+ *
4
+ * @category ShipHero
5
+ * @package ShipHero_Shipment
6
+ * @author Chuck Hudson (used with permission). For more recipes, see Chuck's book http://shop.oreilly.com/product/0636920023968.do
7
+ */
8
+
9
+ class ShipHero_PaymentExtApi_Model_Api2_Payment_Rest_Admin_V1 extends ShipHero_PaymentExtApi_Model_Api2_Payment
10
+ {
11
+
12
+ /**
13
+ * Retrieve
14
+ *
15
+ * @return array
16
+ */
17
+ protected function _retrieve()
18
+ {
19
+ // Not implemented for Beta release
20
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
21
+ }
22
+
23
+ /**
24
+ * Retrieve Collection
25
+ *
26
+ * @return array
27
+ */
28
+ protected function _retrieveCollection()
29
+ {
30
+ // Not implemented for Beta release
31
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
32
+ }
33
+
34
+ /**
35
+ * Create
36
+ *
37
+ * @return string|void
38
+ */
39
+ protected function _create(array $data)
40
+ {
41
+ if(empty($data['order_id']))
42
+ {
43
+ $this->_critical(self::RESOURCE_REQUEST_DATA_INVALID);
44
+ }
45
+
46
+ $orderId = $data['order_id'];
47
+ $order = Mage::getModel('sales/order')->load($orderId);
48
+
49
+ if($order['status'] == 'complete') $this->_error("The order is already complete.", Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
50
+
51
+ if($order->canInvoice()) {
52
+ try {
53
+ // Generate invoice for this shipment
54
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($this->_getItemQtys($order));
55
+ $this->_saveInvoice($invoice, $order);
56
+
57
+ // Finally, Save the Order
58
+ $this->_saveOrder($order, $customerEmailComments);
59
+
60
+ } catch (Exception $e){
61
+ $this->_error($e->getMessage(), Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
62
+ }
63
+ }
64
+
65
+ }
66
+
67
+ /**
68
+ * Update
69
+ *
70
+ * @return void
71
+ */
72
+ protected function _update(array $data)
73
+ {
74
+ // Not Implemented for beta release
75
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
76
+ }
77
+
78
+ /**
79
+ * HELPER FUNCTIONS
80
+ */
81
+
82
+ /**
83
+ * Get the Quantities shipped for the Order, based on an item-level
84
+ * This method can also be modified, to have the Partial Shipment functionality in place
85
+ *
86
+ * @param $order Mage_Sales_Model_Order
87
+ * @return array
88
+ */
89
+ protected function _getItemQtys(Mage_Sales_Model_Order $order)
90
+ {
91
+ $qty = array();
92
+
93
+ foreach ($order->getAllItems() as $_eachItem) {
94
+ if ($_eachItem->getParentItemId()) {
95
+ $qty[$_eachItem->getParentItemId()] = (int)$_eachItem->getQtyOrdered();
96
+ } else {
97
+ $qty[$_eachItem->getId()] = (int)$_eachItem->getQtyOrdered();
98
+ }
99
+ }
100
+
101
+ return $qty;
102
+ }
103
+
104
+ /**
105
+ * Saves the Invoice in the Order
106
+ *
107
+ * @param $invoice Mage_Sales_Model_Order_Invoice
108
+ * @param $order Mage_Sales_Model_Order
109
+ */
110
+ protected function _saveInvoice(Mage_Sales_Model_Order_Invoice $invoice, Mage_Sales_Model_Order $order)
111
+ {
112
+ $amount = $invoice->getGrandTotal();
113
+ $invoice->register()->pay();
114
+ $invoice->getOrder()->setIsInProcess(true);
115
+
116
+ $history = $invoice->getOrder()->addStatusHistoryComment(
117
+ 'Amount of $' . $amount . ' captured automatically.', false
118
+ );
119
+ $history->setIsCustomerNotified(true);
120
+
121
+ Mage::getModel('core/resource_transaction')
122
+ ->addObject($invoice)
123
+ ->addObject($invoice->getOrder())
124
+ ->save();
125
+ $invoice->capture()->save();
126
+ $invoice->sendEmail(true, ''); //set this to false to not send the invoice via email
127
+
128
+ return $this;
129
+ }
130
+
131
+ /**
132
+ * Saves the Order, to complete the full life-cycle of the Order
133
+ * Order status will now show as Complete
134
+ *
135
+ * @param $order Mage_Sales_Model_Order
136
+ */
137
+ protected function _saveOrder(Mage_Sales_Model_Order $order, $customerEmailComments = '')
138
+ {
139
+ if(!empty($customerEmailComments))
140
+ {
141
+ $order->addStatusHistoryComment($customerEmailComments, false);
142
+ }
143
+ // $order->setData('state', Mage_Sales_Model_Order::STATE_PROCESSING);
144
+ // $order->setData('status', Mage_Sales_Model_Order::STATE_PROCESSING);
145
+
146
+ $order->save();
147
+
148
+ return $this;
149
+ }
150
+
151
+ }
app/code/community/ShipHero/PaymentExtApi/etc/api2.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api2>
4
+ <resources>
5
+ <paymentextapi translate="title" module="ShipHero_PaymentExtApi">
6
+ <group>catalogextapi</group>
7
+ <title>Payment</title>
8
+ <model>paymentextapi/api2_payment</model>
9
+ <sort_order>10</sort_order>
10
+ <privileges>
11
+ <admin>
12
+ <create>1</create>
13
+ </admin>
14
+ </privileges>
15
+ <attributes>
16
+ <order_id>Order Id</order_id>
17
+ <line_items>Line Items</line_items>
18
+ <status>Status</status>
19
+ </attributes>
20
+ <routes>
21
+ <route_collection>
22
+ <route>/shiphero/payment</route>
23
+ <action_type>collection</action_type>
24
+ </route_collection>
25
+ </routes>
26
+ <versions>1</versions>
27
+ </paymentextapi>
28
+ </resources>
29
+ </api2>
30
+ </config>
app/code/community/ShipHero/PaymentExtApi/etc/config.xml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_PaymentExtApi>
5
+ <version>0.1.0</version>
6
+ </ShipHero_PaymentExtApi>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <paymentextapi>
11
+ <class>ShipHero_PaymentExtApi_Model</class>
12
+ </paymentextapi>
13
+ </models>
14
+ </global>
15
+ </config>
app/code/community/ShipHero/SalesExtApi/Model/Api2/Order/Rest/Admin/V1.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_SalesExtApi_Model_Api2_Order_Rest_Admin_V1 extends Mage_Sales_Model_Api2_Order_Rest_Admin_V1
4
+ {
5
+
6
+ /**
7
+ * Get orders list
8
+ *
9
+ * @return array
10
+ */
11
+ protected function _retrieveCollection()
12
+ {
13
+ $collection = $this->_getCollectionForRetrieve();
14
+ $total_orders = $collection->getSize();
15
+
16
+ // Get all frontend attributes
17
+ $allAttributeCodes = array();
18
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')->getItems();
19
+
20
+ foreach ($attributes as $attribute){
21
+ $_attribute = $attribute->getData();
22
+ if($_attribute['is_visible_on_front'])
23
+ {
24
+ $allAttributeCodes[] = $attribute->getAttributeCode();
25
+ }
26
+ }
27
+
28
+ if ($this->_isPaymentMethodAllowed()) {
29
+ $this->_addPaymentMethodInfo($collection);
30
+ }
31
+ if ($this->_isGiftMessageAllowed()) {
32
+ $this->_addGiftMessageInfo($collection);
33
+ }
34
+ $this->_addTaxInfo($collection);
35
+
36
+ $ordersData = array();
37
+
38
+ foreach ($collection->getItems() as $order) {
39
+ $ordersData[$order->getId()] = $order->toArray();
40
+ $ordersData[$order->getId()]['total_orders'] = $total_orders;
41
+ }
42
+ if ($ordersData) {
43
+ foreach ($this->_getAddresses(array_keys($ordersData)) as $orderId => $addresses) {
44
+ $ordersData[$orderId]['addresses'] = $addresses;
45
+ }
46
+ foreach ($this->_getItems(array_keys($ordersData)) as $orderId => $items) {
47
+ foreach($items as $key => $item)
48
+ {
49
+ $product_id = Mage::getModel("catalog/product")->getIdBySku($item['sku']);
50
+ $product = Mage::getModel('catalog/product')->load($product_id);
51
+ $p = $product->getData();
52
+ $p_name = $item['name'];
53
+ // error_log(print_r($p,1));
54
+ foreach($allAttributeCodes as $a)
55
+ {
56
+ if(array_key_exists($a, $p) && ($a == 'color' || $a == 'size'))
57
+ {
58
+ $attribute_value = $product->getAttributeText($a);
59
+ if(!empty($attribute_value))
60
+ $p_name .= ' / ' . $attribute_value;
61
+ }
62
+ }
63
+ $items[$key]['adjusted_name'] = $p_name;
64
+ $items[$key]['type_id'] = $p['type_id'];
65
+ }
66
+ $ordersData[$orderId]['order_items'] = $items;
67
+ }
68
+ foreach ($this->_getComments(array_keys($ordersData)) as $orderId => $comments) {
69
+ $ordersData[$orderId]['order_comments'] = $comments;
70
+ }
71
+ }
72
+
73
+ return $ordersData;
74
+ }
75
+
76
+ }
app/code/community/ShipHero/SalesExtApi/etc/api2.xml ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Academic Free License (AFL 3.0)
9
+ * that is bundled with this package in the file LICENSE_AFL.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/afl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magentocommerce.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Sales
24
+ * @copyright Copyright (c) 2014 Magento Inc. (http://www.magentocommerce.com)
25
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
26
+ */
27
+ -->
28
+ <config>
29
+ <api2>
30
+ <resources>
31
+ <salesextapi_order translate="title" module="ShipHero_SalesExtApi">
32
+ <group>catalogextapi</group>
33
+ <sort_order>20</sort_order>
34
+ <model>salesextapi/api2_order</model>
35
+ <title>Orders</title>
36
+ <privileges>
37
+ <admin>
38
+ <retrieve>1</retrieve>
39
+ </admin>
40
+ <customer>
41
+ <retrieve>1</retrieve>
42
+ </customer>
43
+ </privileges>
44
+ <routes>
45
+ <route_entity>
46
+ <route>/shiphero/orders/:id</route>
47
+ <action_type>entity</action_type>
48
+ </route_entity>
49
+ <route_collection>
50
+ <route>/shiphero/orders</route>
51
+ <action_type>collection</action_type>
52
+ </route_collection>
53
+ </routes>
54
+ <attributes translate="entity_id increment_id created_at status shipping_description _payment_method base_currency_code store_currency_code store_name remote_ip store_to_order_rate subtotal subtotal_incl_tax discount_amount base_grand_total grand_total shipping_amount shipping_tax_amount shipping_incl_tax tax_amount _tax_name _tax_rate coupon_code base_discount_amount base_subtotal base_shipping_amount base_shipping_tax_amount base_tax_amount total_paid base_total_paid total_refunded base_total_refunded base_subtotal_incl_tax base_total_due total_due shipping_discount_amount base_shipping_discount_amount discount_description customer_balance_amount base_customer_balance_amount base_customer_balance_amount _gift_message _order_comments customer_id" module="ShipHero_SalesExtApi">
55
+ <entity_id>Order ID (internal)</entity_id>
56
+ <increment_id>Order ID</increment_id>
57
+ <created_at>Order Date</created_at>
58
+ <status>Order Status</status>
59
+ <shipping_description>Shipping Method</shipping_description>
60
+ <_payment_method>Payment Method</_payment_method>
61
+ <base_currency_code>Base Currency</base_currency_code>
62
+ <store_currency_code>Order Currency</store_currency_code>
63
+ <store_name>Store Name</store_name>
64
+ <remote_ip>Placed from IP</remote_ip>
65
+ <store_to_order_rate>Store Currency to Order Currency Rate</store_to_order_rate>
66
+ <subtotal>Subtotal</subtotal>
67
+ <subtotal_incl_tax>Subtotal Including Tax</subtotal_incl_tax>
68
+ <discount_amount>Discount</discount_amount>
69
+ <base_grand_total>Grand Total to Be Charged</base_grand_total>
70
+ <grand_total>Grand Total</grand_total>
71
+ <shipping_amount>Shipping Amount</shipping_amount>
72
+ <shipping_tax_amount>Shipping Including Tax</shipping_tax_amount>
73
+ <shipping_incl_tax>Shipping Tax</shipping_incl_tax>
74
+ <tax_amount>Tax Amount</tax_amount>
75
+ <_tax_name>Tax Name</_tax_name>
76
+ <_tax_rate>Tax Rate</_tax_rate>
77
+ <coupon_code>Coupon Code</coupon_code>
78
+ <base_discount_amount>Base Discount</base_discount_amount>
79
+ <base_subtotal>Base Subtotal</base_subtotal>
80
+ <base_shipping_amount>Base Shipping</base_shipping_amount>
81
+ <base_shipping_tax_amount>Base Shipping Tax</base_shipping_tax_amount>
82
+ <base_tax_amount>Base Tax Amount</base_tax_amount>
83
+ <total_paid>Total Paid</total_paid>
84
+ <base_total_paid>Base Total Paid</base_total_paid>
85
+ <total_refunded>Total Refunded</total_refunded>
86
+ <base_total_refunded>Base Total Refunded</base_total_refunded>
87
+ <base_subtotal_incl_tax>Base Subtotal Including Tax</base_subtotal_incl_tax>
88
+ <base_total_due>Base Total Due</base_total_due>
89
+ <total_due>Total Due</total_due>
90
+ <shipping_discount_amount>Shipping Discount</shipping_discount_amount>
91
+ <base_shipping_discount_amount>Base Shipping Discount</base_shipping_discount_amount>
92
+ <discount_description>Discount Description</discount_description>
93
+ <customer_balance_amount>Customer Balance</customer_balance_amount>
94
+ <base_customer_balance_amount>Base Customer Balance</base_customer_balance_amount>
95
+ <_gift_message>Gift Message</_gift_message>
96
+ <_order_comments>Order Comments</_order_comments>
97
+ <customer_id>Customer ID</customer_id>
98
+ <total_orders>Total Orders</total_orders>
99
+ </attributes>
100
+ <include_attributes>
101
+ <customer>
102
+ <read>
103
+ <entity_id>1</entity_id>
104
+ <increment_id>1</increment_id>
105
+ <created_at>1</created_at>
106
+ <status>1</status>
107
+ <shipping_description>1</shipping_description>
108
+ <_payment_method>1</_payment_method>
109
+ <base_currency_code>1</base_currency_code>
110
+ <store_currency_code>1</store_currency_code>
111
+ <subtotal>1</subtotal>
112
+ <subtotal_incl_tax>1</subtotal_incl_tax>
113
+ <discount_amount>1</discount_amount>
114
+ <base_grand_total>1</base_grand_total>
115
+ <grand_total>1</grand_total>
116
+ <shipping_amount>1</shipping_amount>
117
+ <shipping_tax_amount>1</shipping_tax_amount>
118
+ <shipping_incl_tax>1</shipping_incl_tax>
119
+ <tax_amount>1</tax_amount>
120
+ <_tax_name>1</_tax_name>
121
+ <_tax_rate>1</_tax_rate>
122
+ <_gift_message>1</_gift_message>
123
+ <_order_comments>1</_order_comments>
124
+ </read>
125
+ </customer>
126
+ </include_attributes>
127
+ <force_attributes>
128
+ <customer>
129
+ <payment_method>1</payment_method>
130
+ <addresses>1</addresses>
131
+ <order_items>1</order_items>
132
+ <gift_message_from>1</gift_message_from>
133
+ <gift_message_to>1</gift_message_to>
134
+ <gift_message_body>1</gift_message_body>
135
+ <order_comments>1</order_comments>
136
+ <tax_name>1</tax_name>
137
+ <tax_rate>1</tax_rate>
138
+ </customer>
139
+ <admin>
140
+ <payment_method>1</payment_method>
141
+ <addresses>1</addresses>
142
+ <order_items>1</order_items>
143
+ <gift_message_from>1</gift_message_from>
144
+ <gift_message_to>1</gift_message_to>
145
+ <gift_message_body>1</gift_message_body>
146
+ <order_comments>1</order_comments>
147
+ <tax_name>1</tax_name>
148
+ <tax_rate>1</tax_rate>
149
+ </admin>
150
+ </force_attributes>
151
+ <versions>1</versions>
152
+ </salesextapi_order>
153
+ <salesextapi_order_item translate="title" module="ShipHero_SalesExtApi">
154
+ <group>catalogextapi</group>
155
+ <sort_order>30</sort_order>
156
+ <model>salesextapi/api2_order_item</model>
157
+ <working_model>salesextapi/order_item</working_model>
158
+ <title>Order Items</title>
159
+ <privileges>
160
+ <admin>
161
+ <retrieve>1</retrieve>
162
+ </admin>
163
+ <customer>
164
+ <retrieve>1</retrieve>
165
+ </customer>
166
+ </privileges>
167
+ <attributes translate="item_id name parent_item_id sku price price_incl_tax qty_ordered qty_invoiced qty_shipped qty_canceled qty_refunded row_total row_total_incl_tax base_price original_price base_original_price base_price_incl_tax tax_percent tax_amount base_tax_amount discount_amount base_discount_amount base_row_total base_row_total_incl_tax" module="ShipHero_SalesExtApi">
168
+ <item_id>Order Item ID</item_id>
169
+ <name>Product and Custom Options Name</name>
170
+ <parent_item_id>Parent Order Item ID</parent_item_id>
171
+ <sku>SKU</sku>
172
+ <price>Price</price>
173
+ <price_incl_tax>Price Including Tax</price_incl_tax>
174
+ <qty_ordered>Ordered Qty</qty_ordered>
175
+ <qty_invoiced>Invoiced Qty</qty_invoiced>
176
+ <qty_shipped>Shipped Qty</qty_shipped>
177
+ <qty_canceled>Canceled Qty</qty_canceled>
178
+ <qty_refunded>Refunded Qty</qty_refunded>
179
+ <row_total>Item Subtotal</row_total>
180
+ <row_total_incl_tax>Item Subtotal Including Tax</row_total_incl_tax>
181
+ <base_price>Base Price</base_price>
182
+ <original_price>Original Price</original_price>
183
+ <base_original_price>Base Original Price</base_original_price>
184
+ <base_price_incl_tax>Base Price Including Tax</base_price_incl_tax>
185
+ <tax_percent>Tax Percent</tax_percent>
186
+ <tax_amount>Tax Amount</tax_amount>
187
+ <base_tax_amount>Base Tax Amount</base_tax_amount>
188
+ <discount_amount>Discount Amount</discount_amount>
189
+ <base_discount_amount>Base Discount Amount</base_discount_amount>
190
+ <base_row_total>Base Item Subtotal</base_row_total>
191
+ <base_row_total_incl_tax>Base Item Subtotal Including Tax</base_row_total_incl_tax>
192
+ </attributes>
193
+ <include_attributes>
194
+ <customer>
195
+ <read>
196
+ <item_id>1</item_id>
197
+ <name>1</name>
198
+ <parent_item_id>1</parent_item_id>
199
+ <sku>1</sku>
200
+ <price>1</price>
201
+ <price_incl_tax>1</price_incl_tax>
202
+ <qty_ordered>1</qty_ordered>
203
+ <qty_invoiced>1</qty_invoiced>
204
+ <qty_shipped>1</qty_shipped>
205
+ <qty_canceled>1</qty_canceled>
206
+ <qty_refunded>1</qty_refunded>
207
+ <row_total>1</row_total>
208
+ <row_total_incl_tax>1</row_total_incl_tax>
209
+ </read>
210
+ </customer>
211
+ </include_attributes>
212
+ <routes>
213
+ <route_collection>
214
+ <route>/shiphero/orders/:id/items</route>
215
+ <action_type>collection</action_type>
216
+ </route_collection>
217
+ </routes>
218
+ <versions>1</versions>
219
+ </salesextapi_order_item>
220
+ <salesextapi_order_address translate="title" module="ShipHero_SalesExtApi">
221
+ <group>catalogextapi</group>
222
+ <sort_order>40</sort_order>
223
+ <model>salesextapi/api2_order_address</model>
224
+ <working_model>salesextapi/order_address</working_model>
225
+ <title>Order Addresses</title>
226
+ <privileges>
227
+ <admin>
228
+ <retrieve>1</retrieve>
229
+ </admin>
230
+ <customer>
231
+ <retrieve>1</retrieve>
232
+ </customer>
233
+ </privileges>
234
+ <routes>
235
+ <route_entity>
236
+ <route>/shiphero/orders/:order_id/addresses/:address_type</route>
237
+ <action_type>entity</action_type>
238
+ </route_entity>
239
+ <route_collection>
240
+ <route>/shiphero/orders/:order_id/addresses</route>
241
+ <action_type>collection</action_type>
242
+ </route_collection>
243
+ </routes>
244
+ <versions>1</versions>
245
+ <attributes translate="lastname firstname middlename prefix suffix company street city region postcode country_id telephone address_type email" module="ShipHero_SalesExtApi">
246
+ <lastname>Customer Last Name</lastname>
247
+ <firstname>Customer First Name</firstname>
248
+ <middlename>Customer Middle Name</middlename>
249
+ <prefix>Customer Prefix</prefix>
250
+ <suffix>Customer Suffix</suffix>
251
+ <company>Company</company>
252
+ <street>Street</street>
253
+ <city>City</city>
254
+ <region>State</region>
255
+ <postcode>ZIP/Postal Code</postcode>
256
+ <country_id>Country</country_id>
257
+ <telephone>Phone Number</telephone>
258
+ <address_type>Address Type</address_type>
259
+ <email>Email</email>
260
+ </attributes>
261
+ </salesextapi_order_address>
262
+ <salesextapi_order_comment translate="title" module="ShipHero_SalesExtApi">
263
+ <group>catalogextapi</group>
264
+ <sort_order>60</sort_order>
265
+ <model>salesextapi/api2_order_comment</model>
266
+ <working_model>salesextapi/order_status_history</working_model>
267
+ <title>Order Comments</title>
268
+ <privileges>
269
+ <admin>
270
+ <retrieve>1</retrieve>
271
+ </admin>
272
+ <customer>
273
+ <retrieve>1</retrieve>
274
+ </customer>
275
+ </privileges>
276
+ <force_attributes>
277
+ <admin>
278
+ <created_at>1</created_at>
279
+ <comment>1</comment>
280
+ <is_customer_notified>1</is_customer_notified>
281
+ <is_visible_on_front>1</is_visible_on_front>
282
+ <status>1</status>
283
+ </admin>
284
+ <customer>
285
+ <created_at>1</created_at>
286
+ <comment>1</comment>
287
+ </customer>
288
+ </force_attributes>
289
+ <routes>
290
+ <route_collection>
291
+ <route>/shiphero/orders/:id/comments</route>
292
+ <action_type>collection</action_type>
293
+ </route_collection>
294
+ </routes>
295
+ <versions>1</versions>
296
+ </salesextapi_order_comment>
297
+ </resources>
298
+ </api2>
299
+ </config>
app/code/community/ShipHero/SalesExtApi/etc/config.xml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_SalesExtApi>
5
+ <version>0.1.0</version>
6
+ </ShipHero_SalesExtApi>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <salesextapi>
11
+ <class>ShipHero_SalesExtApi_Model</class>
12
+ </salesextapi>
13
+ </models>
14
+ </global>
15
+ </config>
app/code/community/ShipHero/ShipmentExtApi/Model/Api2/Shipment.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_ShipmentExtApi_Model_Api2_Shipment extends Mage_Api2_Model_Resource
4
+ {
5
+
6
+ }
app/code/community/ShipHero/ShipmentExtApi/Model/Api2/Shipment/Rest/Admin/V1.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* ShipHero Shipment REST API
3
+ *
4
+ * @category ShipHero
5
+ * @package ShipHero_Shipment
6
+ * @author Chuck Hudson (used with permission). For more recipes, see Chuck's book http://shop.oreilly.com/product/0636920023968.do
7
+ */
8
+
9
+ class ShipHero_ShipmentExtApi_Model_Api2_Shipment_Rest_Admin_V1 extends ShipHero_ShipmentExtApi_Model_Api2_Shipment
10
+ {
11
+
12
+ /**
13
+ * Retrieve
14
+ *
15
+ * @return array
16
+ */
17
+ protected function _retrieve()
18
+ {
19
+ // Not implemented for Beta release
20
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
21
+ }
22
+
23
+ /**
24
+ * Retrieve Collection
25
+ *
26
+ * @return array
27
+ */
28
+ protected function _retrieveCollection()
29
+ {
30
+ // Not implemented for Beta release
31
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
32
+ }
33
+
34
+ /**
35
+ * Create
36
+ *
37
+ * @return string|void
38
+ */
39
+ protected function _create(array $data)
40
+ {
41
+ if(empty($data['order_id']))
42
+ {
43
+ $this->_critical(self::RESOURCE_REQUEST_DATA_INVALID);
44
+ }
45
+
46
+ $orderId = $data['order_id'];
47
+ $order = Mage::getModel('sales/order')->load($orderId);
48
+
49
+ if($order['status'] == 'complete') $this->_error("The order is already complete.", Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
50
+
51
+ /**
52
+ * Provide the Shipment Tracking Number,
53
+ * which will be sent out by any warehouse to Magento
54
+ */
55
+ $shipmentTrackingNumber = $data['tracking_number'];
56
+
57
+ /**
58
+ * This can be blank also.
59
+ */
60
+ $customerEmailComments = 'Shipment Submitted by ShipHero App.';
61
+ if ($order->canShip()) {
62
+ try {
63
+ // $shipment = Mage::getModel('sales/service_order', $order)
64
+ // ->prepareShipment($this->_getItemQtys($order, $data['line_items']));
65
+ $shipment = Mage::getModel('sales/service_order', $order)
66
+ ->prepareShipment($this->_getItemQtys($order, $data['line_items']));
67
+
68
+ /**
69
+ * Carrier Codes can be like "ups" / "fedex" / "custom",
70
+ * but they need to be active from the System Configuration area.
71
+ * These variables can be provided custom-value, but it is always
72
+ * suggested to use Order values
73
+ */
74
+ $shipmentCarrierCode = $data['shipping_carrier'];
75
+ $shipmentCarrierTitle = NULL; // $data['shipping_method'];
76
+
77
+ $arrTracking = array(
78
+ 'carrier_code' => isset($shipmentCarrierCode) ? $shipmentCarrierCode : $order->getShippingCarrier()->getCarrierCode(),
79
+ 'title' => isset($shipmentCarrierTitle) ? $shipmentCarrierTitle : $order->getShippingCarrier()->getConfigData('title'),
80
+ 'number' => $shipmentTrackingNumber,
81
+ );
82
+
83
+ $track = Mage::getModel('sales/order_shipment_track')->addData($arrTracking);
84
+ $shipment->addTrack($track);
85
+
86
+ // Register Shipment
87
+ $shipment->register();
88
+
89
+ // Save the Shipment
90
+ $this->_saveShipment($shipment, $order, $customerEmailComments);
91
+
92
+ // Finally, Save the Order
93
+ $this->_saveOrder($order, $customerEmailComments);
94
+
95
+ } catch (Exception $e) {
96
+ // throw $e;
97
+ $this->_error($e->getMessage(), Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
98
+ }
99
+ }
100
+
101
+ }
102
+
103
+ /**
104
+ * Update
105
+ *
106
+ * @return void
107
+ */
108
+ protected function _update(array $data)
109
+ {
110
+ // Not Implemented for beta release
111
+ $this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
112
+ }
113
+
114
+ /**
115
+ * HELPER FUNCTIONS
116
+ */
117
+
118
+ /**
119
+ * Get the Quantities shipped for the Order, based on an item-level
120
+ * This method can also be modified, to have the Partial Shipment functionality in place
121
+ *
122
+ * @param $order Mage_Sales_Model_Order
123
+ * @return array
124
+ */
125
+ protected function _getItemQtys(Mage_Sales_Model_Order $order, $lineItems)
126
+ {
127
+ $qty = array();
128
+
129
+ foreach ($order->getAllItems() as $_eachItem) {
130
+ $orderQty = (int)$_eachItem->getQtyOrdered();
131
+ $shippedQty = (int)$_eachItem->getQtyShipped();
132
+ $remainingQty = $orderQty - $shippedQty;
133
+
134
+ if ($_eachItem->getParentItemId()) {
135
+ $lineItemQty = (int)$lineItems[$_eachItem->getParentItemId()];
136
+ $actualQty = ($lineItemQty > $remainingQty) ? $remainingQty : $lineItemQty;
137
+ $qty[$_eachItem->getParentItemId()] = $actualQty;
138
+ } else {
139
+ $lineItemQty = (int)$lineItems[$_eachItem->getId()];
140
+ $actualQty = ($lineItemQty > $remainingQty) ? $remainingQty : $lineItemQty;
141
+ $qty[$_eachItem->getId()] = $actualQty;
142
+ }
143
+ }
144
+
145
+ return $qty;
146
+ }
147
+
148
+ /**
149
+ * Saves the Shipment changes in the Order
150
+ *
151
+ * @param $shipment Mage_Sales_Model_Order_Shipment
152
+ * @param $order Mage_Sales_Model_Order
153
+ * @param $customerEmailComments string
154
+ */
155
+ protected function _saveShipment(Mage_Sales_Model_Order_Shipment $shipment, Mage_Sales_Model_Order $order, $customerEmailComments = '')
156
+ {
157
+ $shipment->getOrder()->setIsInProcess(true);
158
+ $transactionSave = Mage::getModel('core/resource_transaction')
159
+ ->addObject($shipment)
160
+ ->addObject($order)
161
+ ->save();
162
+
163
+ $emailSentStatus = $shipment->getData('email_sent');
164
+ if (!is_null($customerEmailComments) && !$emailSentStatus) {
165
+ $shipment->sendEmail(true, $customerEmailComments);
166
+ $shipment->setEmailSent(true);
167
+ }
168
+
169
+ return $this;
170
+ }
171
+
172
+ /**
173
+ * Saves the Order, to complete the full life-cycle of the Order
174
+ * Order status will now show as Complete
175
+ *
176
+ * @param $order Mage_Sales_Model_Order
177
+ */
178
+ protected function _saveOrder(Mage_Sales_Model_Order $order, $customerEmailComments = '')
179
+ {
180
+ if(!empty($customerEmailComments))
181
+ {
182
+ $order->addStatusHistoryComment($customerEmailComments, false);
183
+ }
184
+ // $order->setData('state', Mage_Sales_Model_Order::STATE_PROCESSING);
185
+ // $order->setData('status', Mage_Sales_Model_Order::STATE_PROCESSING);
186
+
187
+ $order->save();
188
+
189
+ return $this;
190
+ }
191
+
192
+ }
app/code/community/ShipHero/ShipmentExtApi/etc/api2.xml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api2>
4
+ <resources>
5
+ <shipmentextapi translate="title" module="ShipHero_ShipmentExtApi">
6
+ <group>catalogextapi</group>
7
+ <title>Shipment</title>
8
+ <model>shipmentextapi/api2_shipment</model>
9
+ <sort_order>10</sort_order>
10
+ <privileges>
11
+ <admin>
12
+ <create>1</create>
13
+ </admin>
14
+ </privileges>
15
+ <attributes>
16
+ <order_id>Order Id</order_id>
17
+ <tracking_number>Tracking Number</tracking_number>
18
+ <line_items>Line Items</line_items>
19
+ <notify_customer>Notify Customer</notify_customer>
20
+ <shipping_method>Shipping Method</shipping_method>
21
+ <shipping_carrier>Shipping Carrier</shipping_carrier>
22
+ <status>Status</status>
23
+ </attributes>
24
+ <routes>
25
+ <route_collection>
26
+ <route>/shiphero/shipment</route>
27
+ <action_type>collection</action_type>
28
+ </route_collection>
29
+ </routes>
30
+ <versions>1</versions>
31
+ </shipmentextapi>
32
+ </resources>
33
+ </api2>
34
+ </config>
app/code/community/ShipHero/ShipmentExtApi/etc/config.xml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_ShipmentExtApi>
5
+ <version>0.1.0</version>
6
+ </ShipHero_ShipmentExtApi>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <shipmentextapi>
11
+ <class>ShipHero_ShipmentExtApi_Model</class>
12
+ </shipmentextapi>
13
+ </models>
14
+ </global>
15
+ </config>
app/code/community/ShipHero/WebHooks/Model/OrderObserver.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_WebHooks_Model_OrderObserver
4
+ {
5
+ protected $url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
6
+
7
+ /**
8
+ * Constructor
9
+ * Determine our endpoint url
10
+ */
11
+ public function __construct()
12
+ {
13
+ switch($_SERVER['HTTP_HOST'])
14
+ {
15
+ case 'dev.magento.shiphero.com':
16
+ $this->url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
17
+ break;
18
+
19
+ case 'magento.dev':
20
+ $this->url = 'http://api.v1.shiphero.dev/api2/magento/webhooks/';
21
+ break;
22
+
23
+ default:
24
+ $this->url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
25
+ break;
26
+ }
27
+ }
28
+
29
+ public function orderSaveBefore(Varien_Event_Observer $observer)
30
+ {
31
+ // error_log('in order save before');
32
+ }
33
+
34
+ /**
35
+ * Magento passes a Varien_Event_Observer object as
36
+ * the first parameter of dispatched events.
37
+ */
38
+ public function orderSaveAfter(Varien_Event_Observer $observer)
39
+ {
40
+ error_log('in order save after');
41
+ $sale = $observer->getEvent()->getOrder();
42
+ $status = $sale['status'];
43
+ $state = (isset($sale['state'])) ? $sale['state'] : NULL;
44
+ error_log(print_r($sale,1));
45
+ // Determine how to process the order event
46
+ if(($status == 'canceled' && $state == 'canceled') || ($status == 'closed' && $state == 'closed')) $this->_orderCanceled($sale);
47
+ if(($status == 'pending' && $state == 'new') || ($status == 'processing' && $state == 'processing') || ($status == 'complete' && $state == 'complete')) $this->_orderCreatedUpdated($sale);
48
+ }
49
+
50
+ private function _orderCreatedUpdated($sale)
51
+ {
52
+ // error_log('in order created');
53
+ $origData = $sale->getOrigData();
54
+ $origDataUpdated = (!empty($origData)) ? $origData['updated_at'] : $sale['updated_at'];
55
+ $incrementId = $sale['increment_id'];
56
+ $updating = 'no';
57
+ if($sale['updated_at'] != $origDataUpdated)
58
+ {
59
+ $updating = 'yes';
60
+ }
61
+ $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);
62
+ $billingAddress = $order->getBillingAddress()->getData();
63
+ $shippingAddress = $order->getShippingAddress()->getData();
64
+ $items = $order->getAllVisibleItems();
65
+ $payment = $order->getPayment()->getMethodInstance()->getCode();
66
+ $remoteIp = (!empty($order['remote_ip'])) ? $order['remote_ip'] : NULL;
67
+ $giftMessage = Mage::getModel('giftmessage/message');
68
+ $giftMessageArr = array();
69
+ if(!is_null($order['gift_message_id'])) {
70
+ $message = $giftMessage->load((int)$order['gift_message_id']);
71
+ $giftMessageArr = array(
72
+ 'from' => $message->getData('sender'),
73
+ 'to' => $message->getData('recipient'),
74
+ 'message' => $message->getData('message')
75
+ );
76
+ }
77
+
78
+ $orderItems = array();
79
+ foreach($items as $item)
80
+ {
81
+ $product = Mage::getModel('catalog/product')->load($item['product_id']);
82
+ $p_name = $this->_getProductName($product);
83
+ $orderItems[] = array(
84
+ 'item_id' => $item['item_id'],
85
+ 'sku' => $item['sku'],
86
+ 'qty_ordered' => $item['qty_ordered'],
87
+ 'price' => $item['price'],
88
+ 'adjusted_name' => $p_name,
89
+ 'qty_shipped' => $item['qty_shipped'],
90
+ 'type_id' => $product->getTypeID()
91
+ );
92
+ }
93
+
94
+ // Get Creds
95
+ $creds = $this->_getCredentials();
96
+ $fields = array(
97
+ 'order_id' => $order['entity_id'],
98
+ 'increment_id' => $order['increment_id'],
99
+ 'store_name' => $order['store_name'],
100
+ 'subtotal' => $order['subtotal'],
101
+ 'discount' => $order['discount_amount'],
102
+ 'total_tax' => $order['tax_amount'],
103
+ 'total_price' => $order['grand_total'],
104
+ 'shipping_amount' => $order['shipping_amount'],
105
+ 'shipping_tax_amount' => $order['shipping_tax_amount'],
106
+ 'addresses' => array($billingAddress, $shippingAddress),
107
+ 'payment_method' => $payment,
108
+ 'shipping_description' => $order['shipping_description'],
109
+ 'comment' => $order['customer_note'],
110
+ 'gift_message' => $giftMessageArr,
111
+ 'order_items' => $orderItems,
112
+ 'remote_ip' => $remoteIp,
113
+ 'status' => $sale['status'],
114
+ 'consumer_key' => $creds['key'],
115
+ 'consumer_secret' => $creds['secret'],
116
+ 'created_at' => $order['created_at'],
117
+ 'is_update' => $updating
118
+ );
119
+
120
+ $url = $this->url . 'ordercreation/';
121
+ $request = $this->_sendData($url, $fields);
122
+ }
123
+
124
+ private function _orderCanceled($sale)
125
+ {
126
+ // error_log('in order cancel');
127
+ // Get Creds
128
+ $creds = $this->_getCredentials();
129
+ $fields = array(
130
+ 'order_id' => $sale['increment_id'],
131
+ 'consumer_key' => $creds['key'],
132
+ 'consumer_secret' => $creds['secret']
133
+ );
134
+
135
+ $url = $this->url . 'ordercancellation/';
136
+ $request = $this->_sendData($url, $fields);
137
+ }
138
+
139
+ /**
140
+ * Helper Functions
141
+ */
142
+ // Get Credentials for ShipHero Authentication
143
+ private function _getCredentials()
144
+ {
145
+ //database read adapter
146
+ $read = Mage::getSingleton('core/resource')->getConnection('core_read');
147
+ $result = $read->fetchRow("
148
+ SELECT oc.key, oc.secret
149
+ FROM oauth_consumer AS oc
150
+ WHERE name = 'ShipHero'
151
+ ");
152
+
153
+ return $result;
154
+ }
155
+
156
+ // Send Data
157
+ private function _sendData($url, $fields = array())
158
+ {
159
+ $content = json_encode($fields);
160
+
161
+ $curl = curl_init($url);
162
+ curl_setopt($curl, CURLOPT_HEADER, false);
163
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
164
+ curl_setopt($curl, CURLOPT_HTTPHEADER,
165
+ array("Content-type: application/json")
166
+ );
167
+ curl_setopt($curl, CURLOPT_POST, true);
168
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
169
+
170
+ $json_response = curl_exec($curl);
171
+
172
+ $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
173
+ if ($status != 200)
174
+ {
175
+ // Write a new line to var/log/shiphero-webhook-observers.log
176
+ $error_msg = "Call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", culr_errno " . curl_errno($curl);
177
+ Mage::log(
178
+ "OrderObserverError: " . $error_msg,
179
+ null,
180
+ 'shiphero-webhook-observers.log'
181
+ );
182
+ }
183
+
184
+ curl_close($curl);
185
+
186
+ $response = json_decode($json_response, true);
187
+ return $response;
188
+ }
189
+
190
+ // Get all frontend attributes
191
+ private function _getProductName($product)
192
+ {
193
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')->getItems();
194
+ $allAttributecodes = array();
195
+ $p_name = $product['name'];
196
+ foreach ($attributes as $attribute){
197
+ $_attribute = $attribute->getData();
198
+ if($_attribute['is_visible_on_front'])
199
+ {
200
+ $allAttributecodes[] = $attribute->getAttributeCode();
201
+ }
202
+ }
203
+
204
+ $p = $product->debug();
205
+ foreach($p as $key => $val)
206
+ {
207
+ if(in_array($key, $allAttributecodes) && ($key == 'color' || $key == 'size'))
208
+ {
209
+ $attribute_value = $product->getAttributeText($key);
210
+ if(!empty($attribute_value))
211
+ $p_name .= ' / ' . $attribute_value;
212
+ }
213
+ }
214
+ return $p_name;
215
+ }
216
+ }
app/code/community/ShipHero/WebHooks/Model/ProductObserver.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_WebHooks_Model_ProductObserver
4
+ {
5
+ protected $url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
6
+ protected $attributes = array();
7
+
8
+ /**
9
+ * Constructor
10
+ * Determine our endpoint url
11
+ */
12
+ public function __construct()
13
+ {
14
+ switch($_SERVER['HTTP_HOST'])
15
+ {
16
+ case 'dev.magento.shiphero.com':
17
+ $this->url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
18
+ break;
19
+
20
+ case 'magento.dev':
21
+ $this->url = 'http://api.v1.shiphero.dev/api2/magento/webhooks/';
22
+ break;
23
+
24
+ default:
25
+ $this->url = 'http://api.shiphe.ro/api/api2/magento/webhooks/';
26
+ break;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Magento passes a Varien_Event_Observer object as
32
+ * the first parameter of dispatched events.
33
+ */
34
+ public function productSaveAfter(Varien_Event_Observer $observer)
35
+ {
36
+ // error_log('in product save after');
37
+ $product = $observer->getEvent()->getProduct();
38
+
39
+ // A sku must always be present
40
+ // On product duplicate theire is no sku initially so we don't want' to
41
+ // fire the webhook
42
+ if(empty($product['sku'])) return true;
43
+
44
+ $this->_productCreatedUpdated($product);
45
+ }
46
+
47
+ public function productDelete(Varien_Event_Observer $observer)
48
+ {
49
+ // error_log('in product delete');
50
+ $product = $observer->getEvent()->getProduct();
51
+ $images = array();
52
+ foreach($product->getMediaGalleryImages() as $image)
53
+ {
54
+ $images[] = array('url' => $image->getUrl(), 'position' => $image->getPosition());
55
+ }
56
+
57
+ // Get Creds
58
+ $creds = $this->_getCredentials();
59
+ $url = $this->url . 'product-deletion/';
60
+ $fields = array(
61
+ "product_id" => $product["entity_id"],
62
+ "sku" => $product["sku"],
63
+ "consumer_key" => $creds['key'],
64
+ "consumer_secret" => $creds['secret']
65
+ );
66
+
67
+ $response = $this->_sendData($url, $fields);
68
+ }
69
+
70
+ private function _productCreatedUpdated($product)
71
+ {
72
+ // error_log('in product create update');
73
+ // Retrieve the product being updated from the event observer
74
+ $stock = $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product["entity_id"])->getData();
75
+
76
+ $images = array();
77
+ foreach($product->getMediaGalleryImages() as $image)
78
+ {
79
+ $images[] = array('url' => $image->getUrl(), 'position' => $image->getPosition());
80
+ }
81
+
82
+ if(empty($images))
83
+ {
84
+ $parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($product['entity_id']);
85
+ if(!empty($parentIds))
86
+ {
87
+ $productParent = Mage::getModel('catalog/product')->load($parentIds[0]);
88
+ foreach($productParent->getMediaGalleryImages() as $image)
89
+ {
90
+ $images[] = array('url' => $image->getUrl(), 'position' => $image->getPosition());
91
+ }
92
+ }
93
+ }
94
+
95
+ $name = $this->_getProductName($product);
96
+ $stock_item_id = $stock['item_id'];
97
+ $store_id = (isset($stock['store_id'])) ? $stock['store_id'] : $product['store_id'];
98
+
99
+ // Get Creds
100
+ $creds = $this->_getCredentials();
101
+ $url = $this->url . 'product-update/';
102
+ $fields = array(
103
+ "product_id" => $product["entity_id"],
104
+ "name" => $name,
105
+ "sku" => $product["sku"],
106
+ "price" => $product["price"],
107
+ "status" => $product["status"],
108
+ "quantity" => $stock['qty'],
109
+ "stock_item_id" => $stock_item_id,
110
+ "store_id" => $store_id,
111
+ "images" => $images,
112
+ "attributes" => $this->attributes,
113
+ "consumer_key" => $creds['key'],
114
+ "consumer_secret" => $creds['secret']
115
+ );
116
+
117
+ $response = $this->_sendData($url, $fields);
118
+ }
119
+
120
+
121
+ /**
122
+ * Helper Functions
123
+ */
124
+ // Get Credentials for ShipHero Authentication
125
+ private function _getCredentials()
126
+ {
127
+ //database read adapter
128
+ $read = Mage::getSingleton('core/resource')->getConnection('core_read');
129
+ $result = $read->fetchRow("
130
+ SELECT oc.key, oc.secret
131
+ FROM oauth_consumer AS oc
132
+ WHERE name = 'ShipHero'
133
+ ");
134
+
135
+ return $result;
136
+ }
137
+
138
+ // Send Data
139
+ private function _sendData($url, $fields)
140
+ {
141
+ $content = json_encode($fields);
142
+
143
+ $curl = curl_init($url);
144
+ curl_setopt($curl, CURLOPT_HEADER, false);
145
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
146
+ curl_setopt($curl, CURLOPT_HTTPHEADER,
147
+ array("Content-type: application/json")
148
+ );
149
+ curl_setopt($curl, CURLOPT_POST, true);
150
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
151
+
152
+ $json_response = curl_exec($curl);
153
+
154
+ $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
155
+ if ($status != 200)
156
+ {
157
+ // Write a new line to var/log/shiphero-webhook-observers.log
158
+ $error_msg = "Call to URL $url failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", culr_errno " . curl_errno($curl);
159
+ Mage::log(
160
+ "ProductObserverError: " . $error_msg,
161
+ null,
162
+ 'shiphero-webhook-observers.log'
163
+ );
164
+ }
165
+
166
+ curl_close($curl);
167
+
168
+ $response = json_decode($json_response, true);
169
+ return $response;
170
+ }
171
+
172
+ // Get all frontend attributes
173
+ private function _getProductName($product)
174
+ {
175
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')->getItems();
176
+ $allAttributecodes = array();
177
+ $allFrontendAttributecodes = array();
178
+ $p_name = $product['name'];
179
+ foreach ($attributes as $attribute){
180
+ $_attribute = $attribute->getData();
181
+ if($_attribute['is_visible_on_front'])
182
+ {
183
+ $allFrontendAttributecodes[] = $attribute->getAttributeCode();
184
+ }
185
+
186
+ $allAttributecodes[] = $attribute->getAttributeCode();
187
+ }
188
+
189
+ $p = $product->debug();
190
+ foreach($p as $key => $val)
191
+ {
192
+ if(in_array($key, $allFrontendAttributecodes) && ($key == 'color' || $key == 'size'))
193
+ {
194
+ $attribute_value = $product->getAttributeText($key);
195
+
196
+ if(!empty($attribute_value))
197
+ $p_name .= ' / ' . $attribute_value;
198
+ }
199
+
200
+ if(in_array($key, $allAttributecodes))
201
+ {
202
+ $attribute_value = $product->getAttributeText($key);
203
+ if($attribute_value == false)
204
+ {
205
+ $attr = $product->getResource()->getAttribute('design_number');
206
+ if(!empty($attr))
207
+ $attribute_value = $attr->getFrontend()->getValue($product);
208
+ }
209
+ $this->attributes[] = array($key => $attribute_value);
210
+ }
211
+ }
212
+
213
+ return $p_name;
214
+ }
215
+ }
app/code/community/ShipHero/WebHooks/Model/Resource/Setup.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+
3
+ class ShipHero_WebHooks_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup {
4
+ }
app/code/community/ShipHero/WebHooks/etc/config.xml ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_WebHooks>
5
+ <version>0.1.0</version>
6
+ </ShipHero_WebHooks>
7
+ </modules>
8
+ <global>
9
+ <resources>
10
+ <shiphero_setup>
11
+ <setup>
12
+ <module>ShipHero_WebHooks</module>
13
+ <class>ShipHero_WebHooks_Model_Resource_Setup</class>
14
+ </setup>
15
+ </shiphero_setup>
16
+ </resources>
17
+ <models>
18
+ <shiphero_webhooks>
19
+ <class>ShipHero_WebHooks_Model</class>
20
+ </shiphero_webhooks>
21
+ </models>
22
+ <events>
23
+ <sales_order_save_before>
24
+ <observers>
25
+ <shiphero_order_before_webhook>
26
+ <class>shiphero_webhooks/OrderObserver</class>
27
+ <method>orderSaveBefore</method>
28
+ <type>singleton</type>
29
+ </shiphero_order_before_webhook>
30
+ </observers>
31
+ </sales_order_save_before>
32
+ <sales_order_save_after>
33
+ <observers>
34
+ <shiphero_order_after_webhook>
35
+ <class>shiphero_webhooks/OrderObserver</class>
36
+ <method>orderSaveAfter</method>
37
+ <type>singleton</type>
38
+ </shiphero_order_after_webhook>
39
+ </observers>
40
+ </sales_order_save_after>
41
+ <catalog_product_save_after>
42
+ <observers>
43
+ <shiphero_product_webhook>
44
+ <class>shiphero_webhooks/ProductObserver</class>
45
+ <method>productSaveAfter</method>
46
+ <type>singleton</type>
47
+ </shiphero_product_webhook>
48
+ </observers>
49
+ </catalog_product_save_after>
50
+ <catalog_product_delete_after>
51
+ <observers>
52
+ <shiphero_product_delete_webhook>
53
+ <class>shiphero_webhooks/ProductObserver</class>
54
+ <method>productDelete</method>
55
+ <type>singleton</type>
56
+ </shiphero_product_delete_webhook>
57
+ </observers>
58
+ </catalog_product_delete_after>
59
+ </events>
60
+ <webhook>
61
+ <webhooks>
62
+ <product>
63
+ <created>
64
+ <label>Product Created</label>
65
+ </created>
66
+ <updated>
67
+ <label>Product Updated</label>
68
+ </updated>
69
+ <deleted>
70
+ <label>Product Deleted</label>
71
+ </deleted>
72
+ </product>
73
+ <order>
74
+ <created>
75
+ <label>Order Created</label>
76
+ </created>
77
+ <updated>
78
+ <label>Order Updated</label>
79
+ </updated>
80
+ <deleted>
81
+ <label>Order Deleted</label>
82
+ </deleted>
83
+ </order>
84
+ </webhooks>
85
+ </webhook>
86
+ </global>
87
+ </config>
app/code/community/ShipHero/WebHooks/etc/webapi/acl.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <acl>
3
+ <resources>
4
+ <resource id="Magento_Webapi">
5
+ <resource id="product" title="Manage Products" module="Magento_Product">
6
+ <resource id="product/create" title="Create" sortOrder="10" />
7
+ <resource id="product/get" title="Retrieve" sortOrder="20" />
8
+ <resource id="product/update" title="Update" sortOrder="30" />
9
+ <resource id="product/delete" title="Delete" sortOrder="40" />
10
+ </resource>
11
+ <resource id="order" title="Manage Orders" module="Magento_Order">
12
+ <resource id="order/create" title="Create" sortOrder="10" />
13
+ <resource id="order/get" title="Retrieve" sortOrder="20" />
14
+ <resource id="order/update" title="Update" sortOrder="30" />
15
+ <resource id="order/delete" title="Delete" sortOrder="40" />
16
+ </resource>
17
+ </resource>
18
+ </resources>
19
+ </acl>
20
+ <mapping>
21
+ <!-- Products -->
22
+ <resource id="product/list" parent="product/get" />
23
+ <!-- webhooks -->
24
+ <resource id="product/updated" parent="product/get"/>
25
+ <resource id="product/created" parent="product/get"/>
26
+ <resource id="product/deleted" parent="product/get"/>
27
+
28
+ <!-- Orders -->
29
+ <resource id="order/list" parent="order/get" />
30
+ <!-- webhooks -->
31
+ <resource id="order/updated" parent="order/get"/>
32
+ <resource id="order/created" parent="order/get"/>
33
+ <resource id="order/deleted" parent="order/get"/>
34
+ </mapping>
35
+ </config>
app/code/community/ShipHero/WebHooks/sql/shiphero_setup/install-0.1.0.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // Hold error message
7
+ $errors = array();
8
+
9
+ // Check for duplicate Consumer
10
+ $consumerName = 'ShipHero';
11
+ $callbackUrl = 'http://app.shiphero.com/magento/callback';
12
+
13
+ // Database Read Adapter
14
+ $coreResource = Mage::getSingleton('core/resource');
15
+ $read = $coreResource->getConnection('core_read');
16
+ $query = "SELECT entity_id FROM oauth_consumer WHERE name = ? AND callback_url = ?";
17
+ $result = $read->fetchRow($query, array($consumerName, $callbackUrl));
18
+
19
+ // If we don't have an existing consumer create one
20
+ if(empty($result)){
21
+ // Create Consumer
22
+ $consumer = Mage::getModel('oauth/consumer');
23
+
24
+ /** @var $helper Mage_Oauth_Helper_Data */
25
+ $helper = Mage::helper('oauth');
26
+
27
+ $data = array(
28
+ 'name' => $consumerName,
29
+ 'key' => $helper->generateConsumerKey(),
30
+ 'secret' => $helper->generateConsumerSecret(),
31
+ 'callback_url' => 'http://app.shiphero.com/magento/callback'
32
+ );
33
+
34
+ $consumer->addData($data);
35
+ try {
36
+ $consumer->save();
37
+ }catch(Exception $e){
38
+ array_push($errors, $e->getMessage());
39
+ }
40
+ }else{
41
+ array_push($errors, 'Consumer already exists.');
42
+ }
43
+
44
+ // Get Admin User
45
+ $query = "SELECT user_id FROM admin_user WHERE is_active = ? ORDER BY user_id ASC LIMIT 1";
46
+ $admin = $read->fetchRow($query, array(1));
47
+
48
+ // Get Admin User To API User Association
49
+ $query = "SELECT admin_id, role_id FROM api2_acl_user WHERE admin_id = ?";
50
+ $role = $read->fetchRow($query, $admin['user_id']);
51
+
52
+ // Check for existing Admin Role
53
+ $query = "SELECT entity_id FROM api2_acl_role WHERE role_name = ?";
54
+ $result = $read->fetchRow($query, array($consumerName));
55
+
56
+ if(empty($result)){
57
+ // Create Admin API Role
58
+ $transaction = $coreResource->getConnection('core_write');
59
+ $now = date('Y-m-d H:i:s',time());
60
+ try {
61
+ $transaction->beginTransaction();
62
+
63
+ // Add API Admin User Role
64
+ $query = "INSERT INTO api2_acl_role (created_at, role_name) VALUES (?, ?)";
65
+ $transaction->query($query, array($now, $consumerName));
66
+ $lastInsertId = $transaction->lastInsertId();
67
+
68
+ // Add API Privileges For User Role
69
+ $query = "INSERT INTO api2_acl_rule (role_id, resource_id) VALUES (?, ?)";
70
+ $transaction->query($query, array($lastInsertId, 'all'));
71
+
72
+ // Add ACL Attribute Privileges For Admin Role
73
+ $query = "INSERT IGNORE INTO api2_acl_attribute (user_type, resource_id) VALUES (?, ?)";
74
+ $transaction->query($query, array('admin', 'all'));
75
+
76
+ // Associate Admin User To API User
77
+ $query = "INSERT INTO api2_acl_user (admin_id, role_id) VALUES (?, ?) ON DUPLICATE KEY UPDATE role_id = ?";
78
+ $transaction->query($query, array($admin['user_id'], $lastInsertId, $lastInsertId));
79
+
80
+ $transaction->commit();
81
+ } catch (Exception $e) {
82
+ array_push($errors, $e->getMessage());
83
+ $transaction->rollback();
84
+ }
85
+ }else{
86
+ array_push($errors, 'Admin role already exists.');
87
+ }
88
+
89
+ //Send an email if there is an error
90
+ $currentStore = $_SERVER['HTTP_HOST'];
91
+ $fromEmail = "noreply@shiphero.com";
92
+ $fromName = $currentStore;
93
+ $toEmail = "roger@shiphero.com";
94
+ $toName = "Roger Hosein";
95
+ $subject = "Magento Installation: " . $currentStore;
96
+ $msgErrors = (!empty($errors)) ? "Errors: " . implode(".\n", $errors) : '';
97
+ $msg = "New installation from " . $currentStore . "\n\n" . $msgErrors;
98
+ $body = $msg;
99
+
100
+ try{
101
+ $mail = new Zend_Mail();
102
+ $mail->setFrom($fromEmail, $fromName);
103
+ $mail->addTo($toEmail, $toName);
104
+ $mail->setSubject($subject);
105
+ $mail->setBodyHtml($body); // here u also use setBodyText options.
106
+
107
+ $mail->send();
108
+ }catch(Exception $e){
109
+ error_log($e->getMessage());
110
+ }
111
+
112
+ $installer->endSetup();
app/etc/modules/ShipHero.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <ShipHero_CatalogExtApi>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </ShipHero_CatalogExtApi>
8
+ <ShipHero_SalesExtApi>
9
+ <active>true</active>
10
+ <codePool>community</codePool>
11
+ </ShipHero_SalesExtApi>
12
+ <ShipHero_ShipmentExtApi>
13
+ <active>true</active>
14
+ <codePool>community</codePool>
15
+ </ShipHero_ShipmentExtApi>
16
+ <ShipHero_PaymentExtApi>
17
+ <active>true</active>
18
+ <codePool>community</codePool>
19
+ </ShipHero_PaymentExtApi>
20
+ <ShipHero_WebHooks>
21
+ <active>true</active>
22
+ <codePool>community</codePool>
23
+ </ShipHero_WebHooks>
24
+ </modules>
25
+ </config>
package.xml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>ShipHero</name>
4
+ <version>1.0.0.14</version>
5
+ <stability>beta</stability>
6
+ <license>GNU General Public License (GPL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Beautiful and powerful warehouse management system using iPads and iPods to ship orders and manage inventory.</summary>
10
+ <description>&lt;img src="http://shiphero.wpengine.com/wp-content/uploads/2014/01/packer-in-action2.jpg" /&gt;&#xD;
11
+ &lt;h2&gt;Maintain 100% Accurate Inventory&lt;/h2&gt;&#xD;
12
+ &lt;p&gt;ShipHero accurately maintains your inventory at all time. You will know in real time what&#x2019;s on your shelves and allowing you to count or cycle count your warehouse, without stopping shipping.&lt;/p&gt;&#xD;
13
+ &#xD;
14
+ &lt;h2&gt;Know Where Every Order Is At All Times&lt;/h2&gt;&#xD;
15
+ You can see the status of the order in real time and the history of the order in detail including who picked the order and if any items were missed from the order.&#xD;
16
+ &#xD;
17
+ &lt;h2&gt;Ship Effortlessly&lt;/h2&gt;&#xD;
18
+ &lt;p&gt;ShipHero is the easiest way to ship orders, there are no more paper pick tickets. You see a list of orders, with the pictures of the items and you ship what you see on the screen. Ship via UPS, USPS via Endicia, FedEx and/or DHL &lt;/p&gt;&#xD;
19
+ &#xD;
20
+ &lt;h2&gt;Use the Cheapest Carrier&lt;/h2&gt;&#xD;
21
+ &lt;p&gt;For every shipping method in your store, you can choose a specific shipping method, say UPS Ground or you can choose a delivery target, say 2 Day Delivery. If you choose a target like 2 Day Delivery, we will seamlessly compare all the available shipping methods that you have enabled including USPS flat and regional rate boxes if you have them and we will generate and print the cheapest label that will get there in time, all seamlessly.. &#xD;
22
+ &lt;/p&gt;&#xD;
23
+ &#xD;
24
+ &#xD;
25
+ &lt;h2&gt;FAQ&lt;/h2&gt;&#xD;
26
+ &lt;h2&gt;What do I need to use ShipHero&lt;/h2&gt;&#xD;
27
+ &lt;p&gt;The courage to try something new! Oh, you mean hardware?&lt;li&gt;One iPod Touch or iPhone per packer.&lt;/li&gt;&lt;li&gt;The ShipHero app, which is free. &lt;a href="https://itunes.apple.com/us/app/id726640178?mt=8"&gt;Download from iTunes.&lt;/a&gt; or search for &lt;b&gt;ShipHero&lt;/b&gt; in iTunes.&lt;/li&gt;&#xD;
28
+ &lt;li&gt;A label printer and invoice printer. You can use just one standard printer for both labels and invoices if you want.&lt;/li&gt;&#xD;
29
+ &lt;h2&gt;How long does set up take?&lt;/h2&gt;&#xD;
30
+ &lt;p /&gt;To set up ShipHero and start shipping your first order takes about 20 minutes. Unless you don't have an iPhone or iPod touch, then it depends on the location of the nearest Apple store.&lt;/p&gt;&#xD;
31
+ &lt;h2&gt;Can I also include my non-Magento orders?&lt;/h2&gt;&#xD;
32
+ &lt;p&gt;ShipHero works with Shopify, eBay and Amazon as well, managing your inventory across channels and handling the shipping for all your stores in one place.&#xD;
33
+ &lt;h2&gt;How much does ShipHero cost?&lt;/h2&gt;&#xD;
34
+ &lt;p /&gt;$99 per month per user. For the first 14 days ShipHero is totally free, you don't even have to enter your credit card&lt;/p&gt;&#xD;
35
+ &lt;h2&gt;I have a physical store or multiple locations, can you help me?&lt;/h2&gt;&#xD;
36
+ &lt;p&gt;Yes, omni-channel and multiple location is a big part of what we do.&lt;/p&gt;&#xD;
37
+ &lt;h2&gt;Do I need windows?&lt;/h2&gt;&#xD;
38
+ &lt;p&gt;Nope, we work with Windows and Macs, OSX&lt;/p&gt;&#xD;
39
+ &lt;h2&gt;Can I ask you some questions about my specific needs?&lt;/h2&gt;&#xD;
40
+ &lt;p&gt;Please do! Contact us at 1-(877) 671-6011 or &lt;a href="mailto:hello@shiphero.com"&gt;hello@shiphero.com&lt;/a&gt;&lt;/p&gt;&#xD;
41
+ &#xD;
42
+ &lt;p /&gt;Want to know more about ShipHero? &lt;a href="http://www.ShipHero.com"&gt;Watch video of ShipHero in action, and learn about the full set of features.&lt;/a&gt;</description>
43
+ <notes>- Fixed typo in customerEmailComment, that was filling up the log</notes>
44
+ <authors><author><name>Fareed Hosein</name><user>shipherollc</user><email>roger@shiphero.com</email></author></authors>
45
+ <date>2014-12-01</date>
46
+ <time>22:46:44</time>
47
+ <contents><target name="magecommunity"><dir name="ShipHero"><dir name="CatalogExtApi"><dir name="Model"><dir name="Api2"><dir name="Product"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="fa124c3cf7655d6c9efc8172ecfdb8b4"/></dir><file name=".DS_Store" hash="82133767cb30f899e06a57a6c0215a3d"/></dir></dir></dir></dir><dir name="etc"><file name="api2.xml" hash="4bfa96037c915b8da87b87cd48f8c51b"/><file name="config.xml" hash="75fca57d73d1909bfb92a0b4116c3b24"/></dir></dir><dir name="PaymentExtApi"><dir name="Model"><dir name="Api2"><dir name="Payment"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="76eab99916d836c5910b744b2d81fdd7"/></dir></dir></dir><file name="Payment.php" hash="dd379bf5c286b0924111db0a8fadd658"/></dir></dir><dir name="etc"><file name="api2.xml" hash="792e6b7c9f17b551cb327267427ac128"/><file name="config.xml" hash="3a0e38693d058eb48521a4325b761b2e"/></dir></dir><dir name="SalesExtApi"><dir name="Model"><dir name="Api2"><dir name="Order"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="e153e3b2e377e83e86798d332e83b9b9"/></dir></dir></dir></dir></dir><dir name="etc"><file name="api2.xml" hash="7fd3830df03511ab3fd8923e9bf490dc"/><file name="config.xml" hash="a0817be74340d9f9e12861993e5ee2c9"/></dir></dir><dir name="ShipmentExtApi"><dir name="Model"><dir name="Api2"><dir name="Shipment"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="c87d1a796f1734cc6c65f68bcf3b7c55"/></dir></dir></dir><file name="Shipment.php" hash="8a804aecde89f00f4d013253e8526cfb"/></dir></dir><dir name="etc"><file name="api2.xml" hash="84d7bb1a150b5b94f0797403ef656f45"/><file name="config.xml" hash="6bcba4e8b893bb78eadfb6038fa01927"/></dir></dir><dir name="WebHooks"><dir name="Model"><file name="OrderObserver.php" hash="03b9ca983e4605b5fca5bf08d9b7f192"/><file name="ProductObserver.php" hash="df1790c6df7b976d4973f05a2e8c0088"/><dir name="Resource"><file name="Setup.php" hash="428887c1ea6151a293d3d4b633963bce"/></dir></dir><dir name="etc"><file name="config.xml" hash="e5e8d6595e85311f3617f63b813e8e35"/><dir name="webapi"><file name="acl.xml" hash="444730c8892d9a14c169b6cd96da1cdd"/></dir></dir><dir name="sql"><dir name="shiphero_setup"><file name="install-0.1.0.php" hash="9bc5e69f5d1a726dc36c95d7e6dae982"/></dir></dir></dir><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir></target><target name="mageetc"><dir name="modules"><file name="ShipHero.xml" hash="9ab0798e75362629478abe9a1db7bb6f"/></dir></target></contents>
48
+ <compatible/>
49
+ <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.7.0</min><max>2.0.0</max></package></required></dependencies>
50
+ </package>