Version Notes
* Fix for duplicate attribute options.
* Limited retry on image remote copy failure.
* Fix to update image attributes even if image itself already exists.
* Fix for inability to update or add more than one image to a sku.
* Fix for case insensitivity on attribute sets.
* Locate existing shipment before creating a new shipment.
* Don't add tracking if shipment already has tracking number.
* Fix for erroneous invoice captures.
* Added retailops_hold status.
Download this release
Release Info
Developer | Daniel Norman |
Extension | RetailOps_Api |
Version | 1.0.3 |
Comparing to | |
See all releases |
Version 1.0.3
- app/code/community/RetailOps/Api/Block/Adminhtml/Sales/Order/View/Tab/Retailops.php +111 -0
- app/code/community/RetailOps/Api/Exception.php +30 -0
- app/code/community/RetailOps/Api/Helper/Data.php +139 -0
- app/code/community/RetailOps/Api/Model/Api.php +107 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Abstract.php +151 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Attribute.php +504 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Bundle.php +176 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Category.php +224 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Configurable.php +248 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Default.php +168 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Downloadable.php +160 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Link.php +164 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Media.php +399 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Option.php +266 -0
- app/code/community/RetailOps/Api/Model/Catalog/Adapter/Tag.php +72 -0
- app/code/community/RetailOps/Api/Model/Catalog/Api.php +91 -0
- app/code/community/RetailOps/Api/Model/Catalog/Exception.php +65 -0
- app/code/community/RetailOps/Api/Model/Catalog/Media/Item.php +50 -0
- app/code/community/RetailOps/Api/Model/Catalog/Pull/Api.php +98 -0
- app/code/community/RetailOps/Api/Model/Catalog/Push/Api.php +267 -0
- app/code/community/RetailOps/Api/Model/Catalog/Push/Downloadable/Validator.php +36 -0
- app/code/community/RetailOps/Api/Model/Inventory/Api.php +163 -0
- app/code/community/RetailOps/Api/Model/Observer.php +47 -0
- app/code/community/RetailOps/Api/Model/Observer2.php~ +47 -0
- app/code/community/RetailOps/Api/Model/Order/Api.php +216 -0
- app/code/community/RetailOps/Api/Model/Order/Status/History.php +122 -0
- app/code/community/RetailOps/Api/Model/Resource/Api.php +123 -0
- app/code/community/RetailOps/Api/Model/Resource/Catalog/Media/Item.php +39 -0
- app/code/community/RetailOps/Api/Model/Resource/Catalog/Media/Item/Collection.php +40 -0
- app/code/community/RetailOps/Api/Model/Resource/Order/Status/History.php +49 -0
- app/code/community/RetailOps/Api/Model/Resource/Order/Status/History/Collection.php +57 -0
- app/code/community/RetailOps/Api/Model/Return/Api.php +193 -0
- app/code/community/RetailOps/Api/Model/Shipment/Api.php +469 -0
- app/code/community/RetailOps/Api/Model/Shipment/Api.php.~80d30a79e43e602a0b5b5da0b2b1a8007dc0ada9~ +355 -0
- app/code/community/RetailOps/Api/Model/Shipment/Api.php.~84b644444a1b813b9b5956dbc9eeabb8577db950~ +355 -0
- app/code/community/RetailOps/Api/Model/System/Config/Source/Catalog/AttributeSet.php +41 -0
- app/code/community/RetailOps/Api/controllers/Adminhtml/Sales/OrderController.php +68 -0
- app/code/community/RetailOps/Api/etc/adminhtml.xml +45 -0
- app/code/community/RetailOps/Api/etc/api.xml +108 -0
- app/code/community/RetailOps/Api/etc/config.xml +117 -0
- app/code/community/RetailOps/Api/etc/config.xml~ +117 -0
- app/code/community/RetailOps/Api/etc/system.xml +74 -0
- app/code/community/RetailOps/Api/sql/retailops_api_setup/install-1.0.0.php +78 -0
- app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.0-1.0.1.php +44 -0
- app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.1-1.0.2.php +53 -0
- app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.2-1.0.3.php +42 -0
- app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.2-1.0.3.php~ +53 -0
- app/code/community/RetailOps/Model/Observer.php +18 -0
- app/code/community/RetailOps/Model/Observer.php~ +17 -0
- app/design/adminhtml/default/default/layout/retailops.xml +39 -0
- app/design/adminhtml/default/default/template/retailops/order/view/tab/retailops.phtml +60 -0
- app/etc/modules/RetailOps_Api.xml +35 -0
- package.xml +33 -0
app/code/community/RetailOps/Api/Block/Adminhtml/Sales/Order/View/Tab/Retailops.php
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Block_Adminhtml_Sales_Order_View_Tab_Retailops
|
27 |
+
extends Mage_Adminhtml_Block_Sales_Order_Abstract
|
28 |
+
implements Mage_Adminhtml_Block_Widget_Tab_Interface
|
29 |
+
{
|
30 |
+
protected function _construct()
|
31 |
+
{
|
32 |
+
parent::_construct();
|
33 |
+
$this->setTemplate('retailops/order/view/tab/retailops.phtml');
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function _prepareLayout()
|
37 |
+
{
|
38 |
+
$onclick = "submitAndReloadArea($('retops-info').parentNode, '" . $this->getSubmitUrl() . "')";
|
39 |
+
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
|
40 |
+
->setData(array(
|
41 |
+
'label' => Mage::helper('sales')->__('Submit'),
|
42 |
+
'class' => 'save',
|
43 |
+
'onclick' => $onclick
|
44 |
+
));
|
45 |
+
$this->setChild('submit_button', $button);
|
46 |
+
return parent::_prepareLayout();
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Gets submit url for retail ops order status
|
51 |
+
*
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function getSubmitUrl()
|
55 |
+
{
|
56 |
+
return $this->getUrl('*/*/saveRetailOpsInfo', array('order_id' => $this->getOrder()->getId()));
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Gets Retail Ops order statuses
|
61 |
+
*
|
62 |
+
* @return mixed
|
63 |
+
*/
|
64 |
+
public function getStatuses()
|
65 |
+
{
|
66 |
+
return Mage::helper('retailops_api')->getRetOpsStatuses();
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Gets Current Order
|
71 |
+
*
|
72 |
+
* @return Mage_Sales_Model_Order|mixed
|
73 |
+
*/
|
74 |
+
public function getOrder()
|
75 |
+
{
|
76 |
+
return Mage::registry('current_order');
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Gets Retail Ops Order Status History
|
81 |
+
*
|
82 |
+
* @return mixed
|
83 |
+
*/
|
84 |
+
public function getRetailOpsStatusHistory()
|
85 |
+
{
|
86 |
+
return Mage::getModel('retailops_api/order_status_history')->getRetailOpsStatusHistory($this->getOrder());
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* ######################## TAB settings #################################
|
91 |
+
*/
|
92 |
+
public function getTabLabel()
|
93 |
+
{
|
94 |
+
return Mage::helper('retailops_api')->__('RetailOps');
|
95 |
+
}
|
96 |
+
|
97 |
+
public function getTabTitle()
|
98 |
+
{
|
99 |
+
return Mage::helper('retailops_api')->__('RetailOps');
|
100 |
+
}
|
101 |
+
|
102 |
+
public function canShowTab()
|
103 |
+
{
|
104 |
+
return true;
|
105 |
+
}
|
106 |
+
|
107 |
+
public function isHidden()
|
108 |
+
{
|
109 |
+
return false;
|
110 |
+
}
|
111 |
+
}
|
app/code/community/RetailOps/Api/Exception.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Exception
|
27 |
+
extends Mage_Core_Exception
|
28 |
+
{
|
29 |
+
|
30 |
+
}
|
app/code/community/RetailOps/Api/Helper/Data.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Helper_Data extends Mage_Api_Helper_Data
|
27 |
+
{
|
28 |
+
const API_STATUS_SUCCESS = 'success';
|
29 |
+
const API_STATUS_FAIL = 'fail';
|
30 |
+
|
31 |
+
const RETAILOPS_ORDER_PROCESSING = 'retailops_processing';
|
32 |
+
const RETAILOPS_ORDER_COMPLETE = 'retailops_complete';
|
33 |
+
const RETAILOPS_ORDER_READY = 'retailops_ready';
|
34 |
+
const RETAILOPS_ORDER_HOLD = 'retailops_hold';
|
35 |
+
|
36 |
+
const DEFAULT_LIMIT = 10;
|
37 |
+
|
38 |
+
const XML_CONFIG_DEFAULT_GROUP = 'catalog';
|
39 |
+
|
40 |
+
public function getRetOpsStatuses()
|
41 |
+
{
|
42 |
+
return array(
|
43 |
+
self::RETAILOPS_ORDER_PROCESSING => 'Processing',
|
44 |
+
self::RETAILOPS_ORDER_COMPLETE => 'Complete',
|
45 |
+
self::RETAILOPS_ORDER_READY => 'Ready',
|
46 |
+
self::RETAILOPS_ORDER_HOLD => 'Hold'
|
47 |
+
);
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Apply pager to collection
|
52 |
+
*
|
53 |
+
* @param $collection
|
54 |
+
* @param $filters
|
55 |
+
* @return array
|
56 |
+
*/
|
57 |
+
public function applyPager($collection, $filters)
|
58 |
+
{
|
59 |
+
$start = 0;
|
60 |
+
if (isset($filters['start'])) {
|
61 |
+
$start = $filters['start'];
|
62 |
+
unset($filters['start']);
|
63 |
+
}
|
64 |
+
$limit = self::DEFAULT_LIMIT;
|
65 |
+
if (isset($filters['limit'])) {
|
66 |
+
$limit = $filters['limit'];
|
67 |
+
unset($filters['limit']);
|
68 |
+
}
|
69 |
+
|
70 |
+
$collection->getSelect()->limit($limit, $start);
|
71 |
+
|
72 |
+
return $filters;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param array $array
|
77 |
+
* @param $keyField
|
78 |
+
* @param $valueField
|
79 |
+
* @return array
|
80 |
+
*/
|
81 |
+
public function arrayToOptionHash(array $array, $keyField, $valueField)
|
82 |
+
{
|
83 |
+
$result = array();
|
84 |
+
foreach ($array as $item) {
|
85 |
+
/** @var $item Varien_Object */
|
86 |
+
$result[$item[$keyField]] = $item[$valueField];
|
87 |
+
}
|
88 |
+
|
89 |
+
return $result;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Get config value
|
94 |
+
*
|
95 |
+
* @param $path
|
96 |
+
* @return mixed
|
97 |
+
*/
|
98 |
+
public function getConfig($path)
|
99 |
+
{
|
100 |
+
if (strpos($path, '/') === false) {
|
101 |
+
$path = self::XML_CONFIG_DEFAULT_GROUP . '/' . $path;
|
102 |
+
}
|
103 |
+
|
104 |
+
return Mage::getStoreConfig('retailops_settings/' . $path);
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Reindex stock and price data for products
|
109 |
+
*
|
110 |
+
* @param $idsToReindex
|
111 |
+
* @param null $type
|
112 |
+
*/
|
113 |
+
public function reindexProducts($idsToReindex, $type = null)
|
114 |
+
{
|
115 |
+
$indexerStock = Mage::getModel('cataloginventory/stock_status');
|
116 |
+
foreach ($idsToReindex as $id) {
|
117 |
+
$indexerStock->updateStatus($id, $type);
|
118 |
+
}
|
119 |
+
$indexerPrice = Mage::getResourceModel('catalog/product_indexer_price');
|
120 |
+
$indexerPrice->reindexProductIds($idsToReindex);
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Remove objects from result array
|
125 |
+
*
|
126 |
+
* @param $data
|
127 |
+
* @return array
|
128 |
+
*/
|
129 |
+
public function removeObjectsFromResult($data)
|
130 |
+
{
|
131 |
+
foreach ($data as $key => $value) {
|
132 |
+
if (is_object($value)) {
|
133 |
+
unset($data[$key]);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return $data;
|
138 |
+
}
|
139 |
+
}
|
app/code/community/RetailOps/Api/Model/Api.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Api extends Mage_Api_Model_Resource_Abstract
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Get Products
|
30 |
+
*
|
31 |
+
* @param mixed $filters
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function catalogPull($filters = null){
|
35 |
+
return Mage::getModel('retailops_api/catalog_pull_api')->catalogPull($filters);
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Create/update Products
|
40 |
+
*
|
41 |
+
* @param mixed $productsData
|
42 |
+
* @return array
|
43 |
+
*/
|
44 |
+
public function catalogPush($productsData){
|
45 |
+
return Mage::getModel('retailops_api/catalog_push_api')->catalogPush($productsData);
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Product Inventory Update
|
50 |
+
*
|
51 |
+
* @param array $itemData
|
52 |
+
* @return array
|
53 |
+
*/
|
54 |
+
public function inventoryPush($itemData){
|
55 |
+
return Mage::getModel('retailops_api/inventory_api')->inventoryPush($itemData);
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* create Credit Memo
|
60 |
+
*
|
61 |
+
* @param mixed $returns
|
62 |
+
* @return array
|
63 |
+
*/
|
64 |
+
public function returnPush($returns){
|
65 |
+
return Mage::getModel('retailops_api/return_api')->returnPush($returns);
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Get orders
|
70 |
+
*
|
71 |
+
* @param mixed $filters
|
72 |
+
* @return array
|
73 |
+
*/
|
74 |
+
public function orderPull($filters = null){
|
75 |
+
return Mage::getModel('retailops_api/order_api')->orderPull($filters);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Update retailops order status
|
80 |
+
*
|
81 |
+
* @param $ordersData
|
82 |
+
* @return mixed
|
83 |
+
*/
|
84 |
+
public function orderStatusUpdate($ordersData){
|
85 |
+
return Mage::getModel('retailops_api/order_api')->orderStatusUpdate($ordersData);
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Create shipments
|
90 |
+
*
|
91 |
+
* @param mixed $shipments
|
92 |
+
* @return array
|
93 |
+
*/
|
94 |
+
public function shipmentPush($shipments){
|
95 |
+
return Mage::getModel('retailops_api/shipment_api')->shipmentPush($shipments);
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Close order
|
100 |
+
*
|
101 |
+
* @param $ordersData
|
102 |
+
* @return mixed
|
103 |
+
*/
|
104 |
+
public function orderClose($ordersData){
|
105 |
+
return Mage::getModel('retailops_api/shipment_api')->orderClose($ordersData);
|
106 |
+
}
|
107 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Abstract.php
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
abstract class RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'general';
|
29 |
+
protected $_errorCodes = array();
|
30 |
+
/** @var RetailOps_Api_Model_Catalog_Api */
|
31 |
+
protected $_api;
|
32 |
+
|
33 |
+
public function __construct($api = null)
|
34 |
+
{
|
35 |
+
$this->_api = $api;
|
36 |
+
$this->_construct();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return RetailOps_Api_Model_Resource_Api
|
41 |
+
*/
|
42 |
+
protected function _getResource()
|
43 |
+
{
|
44 |
+
return Mage::getResourceModel('retailops_api/api');
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @return RetailOps_Api_Helper_Data
|
49 |
+
*/
|
50 |
+
public function getHelper()
|
51 |
+
{
|
52 |
+
return Mage::helper('retailops_api');
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @return $this
|
57 |
+
*/
|
58 |
+
protected function _construct()
|
59 |
+
{
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param $message
|
65 |
+
* @param string $code
|
66 |
+
* @param null $sku
|
67 |
+
* @throws RetailOps_Api_Model_Catalog_Exception
|
68 |
+
*/
|
69 |
+
protected function _throwException($message, $code, $sku = null)
|
70 |
+
{
|
71 |
+
if (isset($this->_errorCodes[$code])) {
|
72 |
+
$code = $this->_errorCodes[$code];
|
73 |
+
}
|
74 |
+
throw new RetailOps_Api_Model_Catalog_Exception($message, $code, $sku, $this->_section);
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Will be called before preparing
|
79 |
+
*
|
80 |
+
* @return $this
|
81 |
+
*/
|
82 |
+
public function beforeDataPrepare()
|
83 |
+
{
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param array $data
|
89 |
+
* @return $this
|
90 |
+
*/
|
91 |
+
public function prepareData(array &$data)
|
92 |
+
{
|
93 |
+
return $this;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Will be called when all rows prepared
|
98 |
+
*
|
99 |
+
* @return $this
|
100 |
+
*/
|
101 |
+
public function afterDataPrepare()
|
102 |
+
{
|
103 |
+
return $this;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @return $this
|
108 |
+
*/
|
109 |
+
public function beforeDataProcess()
|
110 |
+
{
|
111 |
+
return $this;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @param array $productData
|
116 |
+
* @param $product
|
117 |
+
* @return mixed
|
118 |
+
*/
|
119 |
+
abstract public function processData(array &$productData, $product);
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @param array $skuToIdMap
|
123 |
+
* @return $this
|
124 |
+
*/
|
125 |
+
public function afterDataProcess(array &$skuToIdMap)
|
126 |
+
{
|
127 |
+
return $this;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Prepare data for pull api
|
132 |
+
*
|
133 |
+
* @param $productCollection
|
134 |
+
* @return $this
|
135 |
+
*/
|
136 |
+
public function prepareOutputData($productCollection)
|
137 |
+
{
|
138 |
+
return $this;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Output data for pull api
|
143 |
+
*
|
144 |
+
* @param Mage_Catalog_Model_Product $product
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
public function outputData($product)
|
148 |
+
{
|
149 |
+
return array();
|
150 |
+
}
|
151 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Attribute.php
ADDED
@@ -0,0 +1,504 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Attribute extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'attribute';
|
29 |
+
|
30 |
+
protected $_attributeSets;
|
31 |
+
protected $_attributeSetGroups;
|
32 |
+
protected $_attributes;
|
33 |
+
protected $_simpleAttributes;
|
34 |
+
protected $_sourceAttributes;
|
35 |
+
protected $_multiSelectAttributes = array();
|
36 |
+
protected $_attributeOptionCache;
|
37 |
+
protected $_entityTypeId;
|
38 |
+
protected $_newOptions = array();
|
39 |
+
/**
|
40 |
+
* Array of already processed attribute codes to avoid double save
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
protected $_wereProcessed = array();
|
44 |
+
|
45 |
+
|
46 |
+
/*
|
47 |
+
* Attributes to skip while unsetting missing attributes
|
48 |
+
*/
|
49 |
+
protected $_systemAttributes = array('has_options', 'required_options', 'media_gallery');
|
50 |
+
|
51 |
+
protected function _construct()
|
52 |
+
{
|
53 |
+
$this->_entityTypeId = Mage::getModel('eav/entity')->setType(Mage_Catalog_Model_Product::ENTITY)->getTypeId();
|
54 |
+
$this->_attributeSets = $this->_getAttributeSets();
|
55 |
+
$this->_attributeSetGroups = $this->_getAttributeSetGroups();
|
56 |
+
$this->_initAttributes();
|
57 |
+
$this->_errorCodes = array(
|
58 |
+
'cant_create_attribute_set' => 101,
|
59 |
+
'missing_attribute_set' => 102,
|
60 |
+
'default_attribute_set_not_set' => 103,
|
61 |
+
'error_processing_attribute' => 104,
|
62 |
+
'error_adding_attribute_options' => 105
|
63 |
+
);
|
64 |
+
|
65 |
+
parent::_construct();
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @param array $data
|
70 |
+
* @return $this
|
71 |
+
*/
|
72 |
+
public function prepareData(array &$data)
|
73 |
+
{
|
74 |
+
$this->_prepareAttributeSet($data);
|
75 |
+
$this->_prepareAttributes($data);
|
76 |
+
$this->_processAttributes($data, true);
|
77 |
+
|
78 |
+
return $this;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return $this
|
83 |
+
*/
|
84 |
+
public function afterDataPrepare()
|
85 |
+
{
|
86 |
+
$this->_addAttributeOptions($this->_newOptions);
|
87 |
+
|
88 |
+
return $this;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param array $productData
|
93 |
+
* @param Mage_Catalog_Model_Product $product
|
94 |
+
* @return mixed|void
|
95 |
+
*/
|
96 |
+
public function processData(array &$productData, $product)
|
97 |
+
{
|
98 |
+
$productData['attribute_set_id'] = $this->_getAttributeSetIdByName($productData['attribute_set']);
|
99 |
+
$this->_processStaticAttributes($productData);
|
100 |
+
$this->_processAttributes($productData);
|
101 |
+
if ($product->getId() &&
|
102 |
+
(!isset($productData['unset_other_attribute']) || $productData['unset_other_attribute'])) {
|
103 |
+
$this->_unsetOldData($productData, $product);
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* @return mixed
|
109 |
+
*/
|
110 |
+
public function getSourceAttributes()
|
111 |
+
{
|
112 |
+
return $this->_sourceAttributes;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @return mixed
|
117 |
+
*/
|
118 |
+
public function getAttributeOptions()
|
119 |
+
{
|
120 |
+
return $this->_attributeOptionCache;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param Mage_Catalog_Model_Product $product
|
125 |
+
* @return array
|
126 |
+
*/
|
127 |
+
public function outputData($product)
|
128 |
+
{
|
129 |
+
$data = array();
|
130 |
+
$data['attribute_set'] = $this->_attributeSets[$product->getDefaultAttributeSetId()];
|
131 |
+
foreach ($this->_simpleAttributes as $code) {
|
132 |
+
$data[$code] = $product->getData($code);
|
133 |
+
}
|
134 |
+
|
135 |
+
foreach ($this->_sourceAttributes as $code) {
|
136 |
+
$values = $product->getData($code);
|
137 |
+
if (array_search($code, $this->_multiSelectAttributes) !== false) {
|
138 |
+
$values = explode(',', $values);
|
139 |
+
}
|
140 |
+
$values = (array) $values;
|
141 |
+
$data[$code] = array();
|
142 |
+
/**
|
143 |
+
* Return array for multiselect options and string for select options
|
144 |
+
*/
|
145 |
+
foreach ($values as $value) {
|
146 |
+
$optionLabel = array_search($value, $this->_attributeOptionCache[$code]);
|
147 |
+
if ($optionLabel) {
|
148 |
+
$data[$code][] = $optionLabel;
|
149 |
+
} else {
|
150 |
+
$data[$code][] = $value;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
if (count($data[$code]) == 1) {
|
154 |
+
$data[$code] = $data[$code][0];
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
return $data;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @return Mage_Catalog_Model_Product_Attribute_Api
|
163 |
+
*/
|
164 |
+
protected function _getProductAttributeApi()
|
165 |
+
{
|
166 |
+
return Mage::getModel('catalog/product_attribute_api');
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* @return Mage_Catalog_Model_Product_Attribute_Set_Api
|
171 |
+
*/
|
172 |
+
protected function _getProductAttributeSetApi()
|
173 |
+
{
|
174 |
+
return Mage::getModel('catalog/product_attribute_set_api');
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* @return array
|
179 |
+
*/
|
180 |
+
protected function _getAttributeSets()
|
181 |
+
{
|
182 |
+
/** @var $attributeSetCollection Mage_Eav_Model_Resource_Entity_Attribute_Set_Collection */
|
183 |
+
$attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection');
|
184 |
+
$attributeSetCollection->setEntityTypeFilter($this->_entityTypeId);
|
185 |
+
|
186 |
+
return $attributeSetCollection->toOptionHash();
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @return array
|
191 |
+
*/
|
192 |
+
protected function _getAttributeSetGroups()
|
193 |
+
{
|
194 |
+
/** @var $attributeSetCollection Mage_Eav_Model_Resource_Entity_Attribute_Group_Collection */
|
195 |
+
$groupsCollection = Mage::getResourceModel('eav/entity_attribute_group_collection');
|
196 |
+
$groups = array();
|
197 |
+
foreach ($groupsCollection as $group) {
|
198 |
+
if (!isset($groups[$group->getAttributeSetId()])) {
|
199 |
+
$groups[$group->getAttributeSetId()] = array();
|
200 |
+
}
|
201 |
+
$groups[$group->getAttributeSetId()][$group->getAttributeGroupName()] = $group->getId();
|
202 |
+
}
|
203 |
+
|
204 |
+
return $groups;
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Init product attributes and attirubtes options
|
209 |
+
*/
|
210 |
+
protected function _initAttributes()
|
211 |
+
{
|
212 |
+
/** @var $attributeCollection Mage_Catalog_Model_Resource_Product_Attribute_Collection */
|
213 |
+
$attributeCollection = Mage::getResourceModel('catalog/product_attribute_collection');
|
214 |
+
$attributeCollection->setItemObjectClass('catalog/resource_eav_attribute');
|
215 |
+
$attributeCollection->addFieldToSelect('*');
|
216 |
+
|
217 |
+
$this->_sourceAttributes = array();
|
218 |
+
$this->_simpleAttributes = array();
|
219 |
+
$this->_multiSelectAttributes = array();
|
220 |
+
foreach ($attributeCollection as $attribute) {
|
221 |
+
$attributeCode = $attribute->getAttributeCode();
|
222 |
+
if ($this->_usesSource($attribute)) {
|
223 |
+
/** @var Mage_Eav_Model_Entity_Attribute $attribute */
|
224 |
+
$this->_attributeOptionCache[$attributeCode] =
|
225 |
+
$this->getHelper()->arrayToOptionHash(
|
226 |
+
$attribute->getSource()->getAllOptions(),
|
227 |
+
'label',
|
228 |
+
'value',
|
229 |
+
false
|
230 |
+
);
|
231 |
+
$this->_sourceAttributes[$attribute->getId()] = $attributeCode;
|
232 |
+
if ($attribute->getFrontendInput() === 'multiselect') {
|
233 |
+
$this->_multiSelectAttributes[] = $attribute->getAttributeCode();
|
234 |
+
}
|
235 |
+
} else {
|
236 |
+
$this->_simpleAttributes[$attribute->getId()] = $attributeCode;
|
237 |
+
}
|
238 |
+
}
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Check if attribute uses source
|
243 |
+
*
|
244 |
+
* @param $attribute
|
245 |
+
* @return bool
|
246 |
+
*/
|
247 |
+
protected function _usesSource($attribute)
|
248 |
+
{
|
249 |
+
return $attribute->getFrontendInput() === 'select' || $attribute->getFrontendInput() === 'multiselect'
|
250 |
+
|| $attribute->getData('source_model') != '';
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @param $data
|
255 |
+
* @return mixed
|
256 |
+
*/
|
257 |
+
protected function _prepareAttributeSet(array &$data)
|
258 |
+
{
|
259 |
+
if (!empty($data['attribute_set'])) {
|
260 |
+
$attributeSet = $data['attribute_set'];
|
261 |
+
$attributeSetId = $this->_getAttributeSetIdByName($attributeSet);
|
262 |
+
if ($attributeSetId === false) {
|
263 |
+
try {
|
264 |
+
$attributeSetId = $this->_createAttributeSet($attributeSet, $data['sku']);
|
265 |
+
} catch (Mage_Api_Exception $e) {
|
266 |
+
$this->_throwException($e->getCustomMessage(), 'cant_create_attribute_set', $data['sku']);
|
267 |
+
}
|
268 |
+
$this->_attributeSets[$attributeSetId] = $attributeSet;
|
269 |
+
}
|
270 |
+
} else {
|
271 |
+
$this->_throwException('Attribute set not provided', 'missing_attribute_set', $data['sku']);
|
272 |
+
}
|
273 |
+
|
274 |
+
$data['attribute_set_id'] = $attributeSetId;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* @param $name
|
279 |
+
* @return mixed
|
280 |
+
*/
|
281 |
+
protected function _createAttributeSet($name, $sku)
|
282 |
+
{
|
283 |
+
$defaultAttributeSetId = $this->getHelper()->getConfig('catalog/default_attribute_set');
|
284 |
+
if (!$defaultAttributeSetId) {
|
285 |
+
$this->_throwException('Default attribute set is not set', 'default_attribute_set_not_set', $sku);
|
286 |
+
}
|
287 |
+
|
288 |
+
$attributeSetId = $this->_getProductAttributeSetApi()->create($name, $defaultAttributeSetId);
|
289 |
+
|
290 |
+
return $attributeSetId;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @param $set
|
295 |
+
* @return mixed
|
296 |
+
*/
|
297 |
+
protected function _getAttributeSetIdByName($set)
|
298 |
+
{
|
299 |
+
$tolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
|
300 |
+
|
301 |
+
return array_search($tolower($set), array_map($tolower, $this->_attributeSets));
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Create/update attributes. Assign them to the attribute set
|
306 |
+
*
|
307 |
+
* @param $data
|
308 |
+
*/
|
309 |
+
protected function _prepareAttributes(array &$data)
|
310 |
+
{
|
311 |
+
$attributeSetId = $data['attribute_set_id'];
|
312 |
+
$attributeApi = $this->_getProductAttributeApi();
|
313 |
+
$attributeSetApi = $this->_getProductAttributeSetApi();
|
314 |
+
if (isset($data['attributes'])) {
|
315 |
+
foreach ($data['attributes'] as $attributeData) {
|
316 |
+
try {
|
317 |
+
$attribute = new Varien_Object($attributeData);
|
318 |
+
$attributeId = $this->findAttribute($attributeData['attribute_code']);
|
319 |
+
if (!in_array($attributeData['attribute_code'], $this->_wereProcessed)) {
|
320 |
+
if ($attributeId !== false) {
|
321 |
+
if (!$attributeData['no_update_if_exists']) {
|
322 |
+
Mage::dispatchEvent('retailops_catalog_attribute_update_before',
|
323 |
+
array('attribute_data' => $attribute));
|
324 |
+
$attributeApi->update($attributeData['attribute_code'], $attribute->getData());
|
325 |
+
Mage::dispatchEvent('retailops_catalog_attribute_update_after',
|
326 |
+
array('attribute_data' => $attribute));
|
327 |
+
}
|
328 |
+
} else {
|
329 |
+
Mage::dispatchEvent('retailops_catalog_attribute_create_before',
|
330 |
+
array('attribute_data' => $attribute));
|
331 |
+
$attributeId = $attributeApi->create($attribute->getData());
|
332 |
+
Mage::dispatchEvent('retailops_catalog_attribute_create_after',
|
333 |
+
array('attribute_id' => $attributeId, 'attribute_data' => $attribute));
|
334 |
+
if ($this->_usesSource($attribute)) {
|
335 |
+
$this->_sourceAttributes[$attributeId] = $attribute->getData('attribute_code');
|
336 |
+
} else {
|
337 |
+
$this->_simpleAttributes[$attributeId] = $attribute->getData('attribute_code');
|
338 |
+
}
|
339 |
+
}
|
340 |
+
$this->_wereProcessed[] = $attributeData['attribute_code'];
|
341 |
+
}
|
342 |
+
$attributeGroup = $attributeData['group_name'];
|
343 |
+
$attributeGroupId = null;
|
344 |
+
if (isset($this->_attributeSetGroups[$attributeSetId][$attributeGroup])) {
|
345 |
+
$attributeGroupId = $this->_attributeSetGroups[$attributeSetId][$attributeGroup];
|
346 |
+
}
|
347 |
+
/**
|
348 |
+
* Try to add attribute set group, use the default group if failed
|
349 |
+
*/
|
350 |
+
try {
|
351 |
+
$attributeGroupId = $attributeSetApi->groupAdd($attributeSetId, $attributeGroup);
|
352 |
+
} catch (Mage_Api_Exception $e) { }
|
353 |
+
$sortOrder = isset($attributeData['sort_order']) ? $attributeData['sort_order'] : 0;
|
354 |
+
try {
|
355 |
+
$this->_getProductAttributeSetApi()
|
356 |
+
->attributeAdd($attributeId, $attributeSetId, $attributeGroupId, $sortOrder);
|
357 |
+
} catch (Mage_Api_Exception $e) {
|
358 |
+
if ($e->getMessage() !== 'attribute_is_already_in_set') {
|
359 |
+
throw new Mage_Api_Exception($e->getMessage(), $e->getCustomMessage());
|
360 |
+
}
|
361 |
+
}
|
362 |
+
} catch (Mage_Api_Exception $e) {
|
363 |
+
$this->_throwException(
|
364 |
+
sprintf('Error while saving attribute %s, error message: %s', $attributeData['attribute_code'], $e->getMessage()),
|
365 |
+
'error_processing_attribute', $data['sku']);
|
366 |
+
}
|
367 |
+
}
|
368 |
+
}
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* @param $attributeCode
|
373 |
+
* @return bool
|
374 |
+
*/
|
375 |
+
public function findAttribute($attributeCode)
|
376 |
+
{
|
377 |
+
return array_search($attributeCode, $this->_getAttributes());
|
378 |
+
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* @return mixed
|
382 |
+
*/
|
383 |
+
protected function _getAttributes()
|
384 |
+
{
|
385 |
+
return $this->_simpleAttributes + $this->_sourceAttributes;
|
386 |
+
}
|
387 |
+
|
388 |
+
/**
|
389 |
+
* @param $productData
|
390 |
+
* @param bool $collectOptions
|
391 |
+
*/
|
392 |
+
protected function _processAttributes(&$productData, $collectOptions = false)
|
393 |
+
{
|
394 |
+
if (isset($productData['attributes'])) {
|
395 |
+
foreach ($productData['attributes'] as $attributeData) {
|
396 |
+
$code = $attributeData['attribute_code'];
|
397 |
+
$attributeId = array_search($code, $this->_sourceAttributes);
|
398 |
+
if ($attributeId !== false && isset($attributeData['value'])) {
|
399 |
+
$values = (array) $attributeData['value'];
|
400 |
+
if ($collectOptions) {
|
401 |
+
/**
|
402 |
+
* Collect missing options to add
|
403 |
+
*/
|
404 |
+
foreach ($values as $value) {
|
405 |
+
if (!isset($this->_attributeOptionCache[$code][$value])) {
|
406 |
+
$this->_newOptions[$attributeId][] = $value;
|
407 |
+
$this->_attributeOptionCache[$code][$value] = true;
|
408 |
+
}
|
409 |
+
}
|
410 |
+
} else {
|
411 |
+
/**
|
412 |
+
* Collect attribute values
|
413 |
+
*/
|
414 |
+
$valuesIds = array();
|
415 |
+
foreach ($values as $value) {
|
416 |
+
if (isset($this->_attributeOptionCache[$code][$value])) {
|
417 |
+
$valuesIds[] = $this->_attributeOptionCache[$code][$value];
|
418 |
+
}
|
419 |
+
}
|
420 |
+
if (count($valuesIds) == 1) {
|
421 |
+
$valuesIds = current($valuesIds);
|
422 |
+
}
|
423 |
+
$productData[$code] = $valuesIds;
|
424 |
+
}
|
425 |
+
} elseif (isset($attributeData['value'])) {
|
426 |
+
$productData[$code] = $attributeData['value'];
|
427 |
+
}
|
428 |
+
}
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* @param $productData
|
434 |
+
*/
|
435 |
+
protected function _processStaticAttributes(&$productData)
|
436 |
+
{
|
437 |
+
foreach ($productData as $code => $value) {
|
438 |
+
$attributeId = array_search($code, $this->_sourceAttributes);
|
439 |
+
if ($attributeId !== false) {
|
440 |
+
if (isset($this->_attributeOptionCache[$code][$value])) {
|
441 |
+
$realValue = $this->_attributeOptionCache[$code][$value];
|
442 |
+
$productData[$code] = $realValue;
|
443 |
+
}
|
444 |
+
}
|
445 |
+
}
|
446 |
+
}
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Add missing attribute options
|
450 |
+
*
|
451 |
+
* @param $newOptions
|
452 |
+
*/
|
453 |
+
protected function _addAttributeOptions($newOptions)
|
454 |
+
{
|
455 |
+
foreach ($newOptions as $attributeId => $options) {
|
456 |
+
$attribute = Mage::getResourceModel('catalog/eav_attribute')
|
457 |
+
->setEntityTypeId($this->_entityTypeId);
|
458 |
+
$attribute->load($attributeId);
|
459 |
+
$optionsData = array();
|
460 |
+
foreach ($options as $key => $option) {
|
461 |
+
$optionsData['value']['option_' . $key][0] = $option;
|
462 |
+
$optionsData['order']['option_' . $key] = 0;
|
463 |
+
}
|
464 |
+
$attribute->setData('option', $optionsData);
|
465 |
+
try {
|
466 |
+
$attribute->save();
|
467 |
+
$this->_attributeOptionCache[$attribute->getAttributeCode()] =
|
468 |
+
$this->getHelper()->arrayToOptionHash(
|
469 |
+
$attribute->getSource()->getAllOptions(),
|
470 |
+
'label',
|
471 |
+
'value',
|
472 |
+
false
|
473 |
+
);
|
474 |
+
} catch (Exception $e) {
|
475 |
+
$this->_throwException(sprintf('Error saving attribute "%s" options, %s', $attribute->getAttributeCode(),
|
476 |
+
$e->getMessage()), 'error_adding_attribute_options');
|
477 |
+
}
|
478 |
+
}
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Unset attributes which are not passed in the API call
|
483 |
+
*
|
484 |
+
* @param array $productData
|
485 |
+
* @param Mage_Catalog_Model_Product $product
|
486 |
+
*/
|
487 |
+
protected function _unsetOldData(array &$productData, $product)
|
488 |
+
{
|
489 |
+
$usedAttributes = array();
|
490 |
+
if (isset($data['attributes'])) {
|
491 |
+
foreach ($data['attributes'] as $attributeData) {
|
492 |
+
$usedAttributes[] = $attributeData['attribute_code'];
|
493 |
+
}
|
494 |
+
}
|
495 |
+
$usedAttributes = array_merge(array_keys($productData), $usedAttributes);
|
496 |
+
$origDataKeys = array_keys($product->getOrigData());
|
497 |
+
$origDataAttributeKeys = array_intersect($origDataKeys, $this->_getAttributes());
|
498 |
+
$keysToUnset = array_diff($origDataAttributeKeys, $usedAttributes, $this->_systemAttributes);
|
499 |
+
|
500 |
+
foreach ($keysToUnset as $key) {
|
501 |
+
$product->setData($key, null);
|
502 |
+
}
|
503 |
+
}
|
504 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Bundle.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Bundle extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'bundle';
|
29 |
+
|
30 |
+
protected $_bundleOptions = array();
|
31 |
+
|
32 |
+
protected function _construct()
|
33 |
+
{
|
34 |
+
$this->_errorCodes = array(
|
35 |
+
'cant_save_bundle_data' => '801'
|
36 |
+
);
|
37 |
+
parent::_construct();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @param array $productData
|
42 |
+
* @param Mage_Catalog_Model_Product $product
|
43 |
+
* @return mixed|void
|
44 |
+
*/
|
45 |
+
public function processData(array &$productData, $product)
|
46 |
+
{
|
47 |
+
$sku = $productData['sku'];
|
48 |
+
|
49 |
+
if (isset($productData['bundle_options'])) {
|
50 |
+
$this->_bundleOptions[$sku] = $productData['bundle_options'];
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param array $skuToIdMap
|
56 |
+
* @return $this|void
|
57 |
+
*/
|
58 |
+
public function afterDataProcess(array &$skuToIdMap)
|
59 |
+
{
|
60 |
+
$failedSkus = array();
|
61 |
+
$idsToReindex = array();
|
62 |
+
if (isset($this->_bundleOptions)) {
|
63 |
+
|
64 |
+
foreach ($this->_bundleOptions as $sku => $bundleOptions) {
|
65 |
+
try {
|
66 |
+
$productId = $skuToIdMap[$sku];
|
67 |
+
/** @var Mage_Catalog_Model_Product $bundle */
|
68 |
+
$bundle = Mage::getModel('catalog/product')->load($productId);
|
69 |
+
$options = array();
|
70 |
+
$selections = array();
|
71 |
+
foreach ($bundleOptions as $optionKey => $bundleOption) {
|
72 |
+
$option = array(
|
73 |
+
'type' => $bundleOption['type'],
|
74 |
+
'title' => $bundleOption['title'],
|
75 |
+
'required' => isset($bundleOption['required']) ? $bundleOption['required'] : 0,
|
76 |
+
'position' => isset($bundleOption['position']) ? $bundleOption['position'] : 0,
|
77 |
+
'delete' => 0,
|
78 |
+
);
|
79 |
+
$options[] = $option;
|
80 |
+
if (!empty($bundleOption['bundle_selections'])) {
|
81 |
+
$selections[$optionKey] = array();
|
82 |
+
foreach ($bundleOption['bundle_selections'] as $selectionData) {
|
83 |
+
if (isset($skuToIdMap[$selectionData['sku']])) {
|
84 |
+
$productId = $skuToIdMap[$selectionData['sku']];
|
85 |
+
$priceType = 0;
|
86 |
+
$price = isset($selectionData['price']) ? $selectionData['price'] : 0;
|
87 |
+
if (false !== strpos($price, '%')) {
|
88 |
+
$priceType = 1;
|
89 |
+
}
|
90 |
+
$selection = array(
|
91 |
+
'product_id' => $productId,
|
92 |
+
'delete' => 0,
|
93 |
+
'selection_price_value' => $price,
|
94 |
+
'selection_price_type' => $priceType,
|
95 |
+
'selection_qty' => isset($selectionData['default_qty']) ? $selectionData['default_qty'] : 1,
|
96 |
+
'selection_can_change_qty' => isset($selectionData['can_change_qty']) ? $selectionData['can_change_qty'] : 1,
|
97 |
+
'is_default' => isset($selectionData['is_default']) ? $selectionData['is_default'] : 0,
|
98 |
+
'position' => isset($selectionData['position']) ? $selectionData['position'] : 0,
|
99 |
+
);
|
100 |
+
$selections[$optionKey][] = $selection;
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
105 |
+
}
|
106 |
+
Mage::register('product', $bundle); //required by selection object
|
107 |
+
$currentOptions = $bundle->getTypeInstance()->getOptionsCollection();
|
108 |
+
foreach ($currentOptions as $option) {
|
109 |
+
$option->delete();
|
110 |
+
}
|
111 |
+
$bundle->setBundleOptionsData($options);
|
112 |
+
$bundle->setBundleSelectionsData($selections);
|
113 |
+
$bundle->setCanSaveCustomOptions(true);
|
114 |
+
$bundle->setCanSaveBundleSelections(true);
|
115 |
+
$bundle->save();
|
116 |
+
$idsToReindex[] = $bundle->getId();
|
117 |
+
$bundle->clearInstance();
|
118 |
+
Mage::unregister('product');
|
119 |
+
} catch (Exception $e) {
|
120 |
+
$failedSkus[] = $sku;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
if ($idsToReindex) {
|
125 |
+
$this->getHelper()->reindexProducts(array_unique($idsToReindex), 'bundle');
|
126 |
+
}
|
127 |
+
if ($failedSkus) {
|
128 |
+
$this->_throwException('Bundle data is not saved for ' . implode(',', array_unique($failedSkus)),
|
129 |
+
'cant_save_bundle_data');
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @param Mage_Catalog_Model_Product $product
|
135 |
+
* @return array
|
136 |
+
*/
|
137 |
+
public function outputData($product)
|
138 |
+
{
|
139 |
+
$data = array();
|
140 |
+
|
141 |
+
if ($product->getTypeId() !== 'bundle') {
|
142 |
+
return array();
|
143 |
+
}
|
144 |
+
$options = $product->getTypeInstance()->getOptionsCollection();
|
145 |
+
$selectionsCollection = $product->getTypeInstance()->getSelectionsCollection($options->getAllIds());
|
146 |
+
$options->appendSelections($selectionsCollection, false, true);
|
147 |
+
$optionsData = array();
|
148 |
+
/** @var $option Mage_Bundle_Model_Option */
|
149 |
+
foreach ($options as $option) {
|
150 |
+
$selectionsData = array();
|
151 |
+
$optionSelections = $option->getSelections();
|
152 |
+
/** @var $selection Mage_Bundle_Model_Selection */
|
153 |
+
foreach ($optionSelections as $selection) {
|
154 |
+
$selectionsData[] = array(
|
155 |
+
'sku' => $selection->getSku(),
|
156 |
+
'price' => $selection->getSelectionPriceValue() . ($selection->getSelectionPriceType() ? '%' : ''),
|
157 |
+
'default_qty' => $selection->getSelectionQty(),
|
158 |
+
'selection_can_change_qty' => $selection->getSelectionCanChangeQty(),
|
159 |
+
'is_default' => $selection->getIsDefault(),
|
160 |
+
'position' => $selection->getPosition(),
|
161 |
+
);
|
162 |
+
}
|
163 |
+
$optionsData[] = array(
|
164 |
+
'type' => $option->getType(),
|
165 |
+
'title' => $option->getDefaultTitle(),
|
166 |
+
'required' => $option->getRequired(),
|
167 |
+
'position' => $option->getPosition(),
|
168 |
+
'bundle_selections' => $selectionsData
|
169 |
+
);
|
170 |
+
}
|
171 |
+
|
172 |
+
$data['bundle_options'] = $optionsData;
|
173 |
+
|
174 |
+
return $data;
|
175 |
+
}
|
176 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Category.php
ADDED
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Category extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_categories;
|
29 |
+
/**
|
30 |
+
* Array of already processed category indexes to avoid double save
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
protected $_wereProcessed = array();
|
34 |
+
|
35 |
+
protected $_section = 'category';
|
36 |
+
|
37 |
+
protected function _construct()
|
38 |
+
{
|
39 |
+
$this->_initCategories();
|
40 |
+
$this->_errorCodes = array(
|
41 |
+
'cant_save_category' => 201,
|
42 |
+
);
|
43 |
+
parent::_construct();
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param array $productData
|
48 |
+
* @param Mage_Catalog_Model_Product $product
|
49 |
+
* @return mixed|void
|
50 |
+
*/
|
51 |
+
public function processData(array &$productData, $product)
|
52 |
+
{
|
53 |
+
$assignedCategories = array();
|
54 |
+
$categoryApi = $this->_getCategoryApi();
|
55 |
+
if (isset($productData['categories'])) {
|
56 |
+
foreach ($productData['categories'] as $categoriesData) {
|
57 |
+
$categoryPath = array();
|
58 |
+
foreach ($categoriesData as $categoryData) {
|
59 |
+
try {
|
60 |
+
$data = new Varien_Object($categoryData);
|
61 |
+
$parentCategoryPath = $categoryPath;
|
62 |
+
$categoryPath[] = $categoryData['name'];
|
63 |
+
$index = $this->_getCategoryPathIndex($categoryPath);
|
64 |
+
if (!in_array($index, $this->_wereProcessed)) {
|
65 |
+
if (!isset($this->_categories[$index])) {
|
66 |
+
$parentIndex = $this->_getCategoryPathIndex($parentCategoryPath);
|
67 |
+
$parentId = isset($this->_categories[$parentIndex]) ? $this->_categories[$parentIndex] : 1;
|
68 |
+
|
69 |
+
Mage::dispatchEvent('retailops_catalog_category_create_before',
|
70 |
+
array('category_data' => $data));
|
71 |
+
|
72 |
+
$categoryId = $categoryApi->create($parentId, $data->getData());
|
73 |
+
$this->_categories[$index] = $categoryId;
|
74 |
+
|
75 |
+
Mage::dispatchEvent('retailops_catalog_category_create_after',
|
76 |
+
array('category_id' => $categoryId, 'category_data' => $data));
|
77 |
+
|
78 |
+
} else {
|
79 |
+
$categoryId = $this->_categories[$index];
|
80 |
+
|
81 |
+
Mage::dispatchEvent('retailops_catalog_category_update_before',
|
82 |
+
array('category_id' => $categoryId, 'category_data' => $data));
|
83 |
+
|
84 |
+
$categoryApi->update($categoryId, $data->getData());
|
85 |
+
|
86 |
+
Mage::dispatchEvent('retailops_catalog_category_update_after',
|
87 |
+
array('category_id' => $categoryId, 'category_data' => $data));
|
88 |
+
}
|
89 |
+
$this->_wereProcessed[] = $index;
|
90 |
+
}
|
91 |
+
if (!empty($categoryData['link'])) {
|
92 |
+
$categoryId = $this->_categories[$index];
|
93 |
+
$assignedCategories[] = $categoryId;
|
94 |
+
}
|
95 |
+
} catch (Mage_Api_Exception $e) {
|
96 |
+
$this->_throwException(
|
97 |
+
sprintf('Error while saving category %s, message: %s', $categoryData['name'], $e->getCustomMessage()),
|
98 |
+
'cant_save_category'
|
99 |
+
);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
if (empty($productData['unset_other_categories']) || !$productData['unset_other_categories']) {
|
104 |
+
$assignedCategories = array_merge($assignedCategories, $product->getCategoryIds());
|
105 |
+
}
|
106 |
+
$productData['category_ids'] = $assignedCategories;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* @param Mage_Catalog_Model_Resource_Product_Collection $productCollection
|
112 |
+
* @return $this
|
113 |
+
*/
|
114 |
+
public function prepareOutputData($productCollection)
|
115 |
+
{
|
116 |
+
$usedCategoryIds = array();
|
117 |
+
/** @var $product Mage_Catalog_Model_Product */
|
118 |
+
foreach ($productCollection as $product) {
|
119 |
+
$usedCategoryIds = array_merge($usedCategoryIds, $product->getCategoryIds());
|
120 |
+
}
|
121 |
+
$usedCategoryIds = array_unique($usedCategoryIds);
|
122 |
+
/** @var $collection Mage_Catalog_Model_Resource_Category_Collection */
|
123 |
+
$collection = Mage::getModel('catalog/category')->getCollection();
|
124 |
+
$collection->addAttributeToSelect('path');
|
125 |
+
$collection->addIdFilter($usedCategoryIds);
|
126 |
+
$categoryToLoad = array();
|
127 |
+
/** @var $category Mage_Catalog_Model_Category */
|
128 |
+
foreach ($collection as $category) {
|
129 |
+
$categoryToLoad = array_merge($categoryToLoad, $category->getPathIds());
|
130 |
+
}
|
131 |
+
$categoryToLoad = array_unique($categoryToLoad);
|
132 |
+
/** @var $fullCollection Mage_Catalog_Model_Resource_Category_Collection */
|
133 |
+
$fullCollection = Mage::getModel('catalog/category')->getCollection();
|
134 |
+
$fullCollection->addAttributeToSelect('*');
|
135 |
+
$fullCollection->addIdFilter($categoryToLoad);
|
136 |
+
foreach ($fullCollection as $category) {
|
137 |
+
$this->_categories[$category->getId()] = $category;
|
138 |
+
}
|
139 |
+
|
140 |
+
return $this;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @param Mage_Catalog_Model_Product $product
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
public function outputData($product)
|
148 |
+
{
|
149 |
+
$data = array();
|
150 |
+
$categoryIds = $product->getCategoryIds();
|
151 |
+
$categoryPaths = array();
|
152 |
+
foreach ($categoryIds as $categoryId) {
|
153 |
+
$categoryPath = $this->_getCategoryData($categoryId);
|
154 |
+
$categoryPaths[]['path'] = $categoryPath;
|
155 |
+
}
|
156 |
+
|
157 |
+
$data['categories'] = $categoryPaths;
|
158 |
+
|
159 |
+
return $data;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Get category data
|
164 |
+
*
|
165 |
+
* @param $categoryId
|
166 |
+
* @return array
|
167 |
+
*/
|
168 |
+
protected function _getCategoryData($categoryId)
|
169 |
+
{
|
170 |
+
$data = array();
|
171 |
+
if (isset($this->_categories[$categoryId])) {
|
172 |
+
$category = $this->_categories[$categoryId];
|
173 |
+
$path = array_slice($category->getPathIds(), 1);
|
174 |
+
foreach ($path as $catId) {
|
175 |
+
if (isset($this->_categories[$catId])) {
|
176 |
+
$parentCategory = $this->_categories[$catId];
|
177 |
+
$data[] = $parentCategory->getData();
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
return $data;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @return $this
|
187 |
+
*/
|
188 |
+
protected function _initCategories()
|
189 |
+
{
|
190 |
+
$collection = Mage::getResourceModel('catalog/category_collection')->addNameToResult();
|
191 |
+
/* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
|
192 |
+
foreach ($collection as $category) {
|
193 |
+
$structure = explode('/', $category->getPath());
|
194 |
+
$pathSize = count($structure);
|
195 |
+
if ($pathSize > 1) {
|
196 |
+
$path = array();
|
197 |
+
for ($i = 1; $i < $pathSize; $i++) {
|
198 |
+
$path[] = $collection->getItemById($structure[$i])->getName();
|
199 |
+
}
|
200 |
+
$index = $this->_getCategoryPathIndex($path);
|
201 |
+
$this->_categories[$index] = $category->getId();
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
return $this;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* @return Mage_Catalog_Model_Category_Api
|
210 |
+
*/
|
211 |
+
protected function _getCategoryApi()
|
212 |
+
{
|
213 |
+
return Mage::getModel('catalog/category_api');
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* @param $path
|
218 |
+
* @return string
|
219 |
+
*/
|
220 |
+
protected function _getCategoryPathIndex($path)
|
221 |
+
{
|
222 |
+
return implode('/', $path);
|
223 |
+
}
|
224 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Configurable.php
ADDED
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Configurable extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'configurable';
|
29 |
+
|
30 |
+
protected $_associations = array();
|
31 |
+
protected $_configurableOptions = array();
|
32 |
+
|
33 |
+
protected function _construct()
|
34 |
+
{
|
35 |
+
$this->_errorCodes = array(
|
36 |
+
'cant_save_configurable_data' => 301,
|
37 |
+
);
|
38 |
+
parent::_construct();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param array $productData
|
43 |
+
* @param Mage_Catalog_Model_Product $product
|
44 |
+
* @return mixed|void
|
45 |
+
*/
|
46 |
+
public function processData(array &$productData, $product)
|
47 |
+
{
|
48 |
+
$sku = $productData['sku'];
|
49 |
+
if (isset($productData['configurable_sku'])) {
|
50 |
+
$this->_associations[$sku] = $productData['configurable_sku'];
|
51 |
+
}
|
52 |
+
|
53 |
+
if (isset($productData['price_changes'])) {
|
54 |
+
$this->_configurableOptions[$sku] = $productData['price_changes'];
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @param array $skuToIdMap
|
60 |
+
* @return $this|void
|
61 |
+
*/
|
62 |
+
public function afterDataProcess(array &$skuToIdMap)
|
63 |
+
{
|
64 |
+
$failedSkus = array();
|
65 |
+
$idsToReindex = array();
|
66 |
+
if (!empty($this->_associations)) {
|
67 |
+
$parentChildIds = array();
|
68 |
+
$disassociateIds = array();
|
69 |
+
foreach ((array) $this->_associations as $sku => $parentSkus) {
|
70 |
+
$childProductId = $skuToIdMap[$sku];
|
71 |
+
if ($parentSkus) {
|
72 |
+
foreach ($parentSkus as $parentSku) {
|
73 |
+
if (isset($skuToIdMap[$parentSku])) {
|
74 |
+
$parentProductId = $skuToIdMap[$parentSku];
|
75 |
+
if (!isset($parentChildIds[$parentProductId])) {
|
76 |
+
$parentChildIds[$parentProductId]['add'] = array();
|
77 |
+
}
|
78 |
+
$parentChildIds[$parentProductId]['add'][] = $childProductId;
|
79 |
+
} else {
|
80 |
+
$failedSkus[$sku] = sprintf('Parent product "%s" not found', $parentSku);
|
81 |
+
}
|
82 |
+
}
|
83 |
+
} else {
|
84 |
+
$disassociateIds[] = $childProductId;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
foreach ($disassociateIds as $disassociateId) {
|
88 |
+
$parents = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($disassociateId);
|
89 |
+
foreach ($parents as $parentId) {
|
90 |
+
if (!isset($parentChildIds[$parentId])) {
|
91 |
+
$parentChildIds[$parentId]['remove'] = array();
|
92 |
+
}
|
93 |
+
$parentChildIds[$parentId]['remove'][] = $disassociateId;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
foreach ($parentChildIds as $parentId => $childIds) {
|
97 |
+
try {
|
98 |
+
/** @var Mage_Catalog_Model_Product $configurable */
|
99 |
+
$configurable = Mage::getModel('catalog/product')->load($parentId);
|
100 |
+
if ($configurable->getTypeId() !== Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE) {
|
101 |
+
Mage::throwException('Product is not configurable');
|
102 |
+
}
|
103 |
+
$assignedProducts = $configurable->getTypeInstance()->getUsedProductIds($configurable);
|
104 |
+
if (!empty($childIds['add'])) {
|
105 |
+
$assignedProducts = array_merge($assignedProducts, $childIds['add']);
|
106 |
+
}
|
107 |
+
if (!empty($childIds['remove'])) {
|
108 |
+
$assignedProducts = array_diff($assignedProducts, $childIds['remove']);
|
109 |
+
}
|
110 |
+
Mage::getResourceModel('catalog/product_type_configurable')
|
111 |
+
->saveProducts($configurable, $assignedProducts);
|
112 |
+
$idsToReindex[] = $parentId;
|
113 |
+
} catch (Exception $e) {
|
114 |
+
$failedSkus[$configurable->getSku()] = $e->getMessage();
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
if (isset($this->_configurableOptions)) {
|
119 |
+
/** @var RetailOps_Api_Model_Catalog_Adapter_Attribute $attributesAdapter */
|
120 |
+
$attributesAdapter = $this->_api->getAdapter('attributes');
|
121 |
+
$allOptions = $attributesAdapter->getAttributeOptions();
|
122 |
+
foreach ($this->_configurableOptions as $sku => $configurableAttributes) {
|
123 |
+
try {
|
124 |
+
$productId = $skuToIdMap[$sku];
|
125 |
+
$configurable = Mage::getModel('catalog/product')->load($productId);
|
126 |
+
if ($configurable->getTypeId() !== Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE) {
|
127 |
+
Mage::throwException('Product is not configurable');
|
128 |
+
}
|
129 |
+
$productType = $configurable->getTypeInstance();
|
130 |
+
$productType->setProduct($configurable);
|
131 |
+
$usedAttributes = array();
|
132 |
+
foreach ($configurableAttributes as $attributeCode => $attribute) {
|
133 |
+
$attributeId = $attributesAdapter->findAttribute($attributeCode);
|
134 |
+
if ($attributeId === false) {
|
135 |
+
Mage::throwException(sprintf('Attribute "%s" not found', $attributeCode));
|
136 |
+
}
|
137 |
+
/** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
|
138 |
+
$attribute = Mage::getResourceModel('catalog/eav_attribute')->load($attributeId);
|
139 |
+
$isInSet = Mage::getResourceModel('eav/entity_attribute_set')->getSetInfo(array($attributeId),
|
140 |
+
$configurable->getAttributeSetId());
|
141 |
+
if (!$isInSet[$attributeId]
|
142 |
+
|| !$productType->canUseAttribute($attribute)) {
|
143 |
+
Mage::throwException(sprintf('Attribute "%s" is not assigned to attribute set or cannot be used for configurable products', $attributeCode));
|
144 |
+
}
|
145 |
+
$usedAttributes[] = $attributeId;
|
146 |
+
}
|
147 |
+
$configurableAttributesData = $productType->getConfigurableAttributesAsArray();
|
148 |
+
if (!$configurableAttributesData) {
|
149 |
+
$productType->setUsedProductAttributeIds($usedAttributes);
|
150 |
+
$configurableAttributesData = $productType->getConfigurableAttributesAsArray();
|
151 |
+
} else {
|
152 |
+
foreach ($configurableAttributesData as $key => $attributeData) {
|
153 |
+
if (!in_array($attributeData['attribute_id'], $usedAttributes)) {
|
154 |
+
unset($configurableAttributesData[$key]);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
foreach ($configurableAttributesData as &$attributeData) {
|
159 |
+
if (isset($configurableAttributes[$attributeData['attribute_code']])) {
|
160 |
+
$attribute = $configurableAttributes[$attributeData['attribute_code']];
|
161 |
+
} else {
|
162 |
+
$attribute = array();
|
163 |
+
}
|
164 |
+
$attributeData['label'] = isset($attribute['label']) ? $attribute['label'] : $attributeData['frontend_label'];
|
165 |
+
$attributeData['position'] = isset($attribute['position']) ? $attribute['position'] : 0;
|
166 |
+
if (isset($attribute['options'])) {
|
167 |
+
foreach ($attribute['options'] as $option => $priceChange) {
|
168 |
+
if (isset($allOptions[$attributeCode][$option])) {
|
169 |
+
$optionId = $allOptions[$attributeCode][$option];
|
170 |
+
$isPercent = 0;
|
171 |
+
if (false !== strpos($priceChange, '%')) {
|
172 |
+
$isPercent = 1;
|
173 |
+
}
|
174 |
+
$priceChange = preg_replace('/[^0-9\.,-]/', '', $priceChange);
|
175 |
+
$priceChange = (float) str_replace(',', '.', $priceChange);
|
176 |
+
$attributeData['values'][$optionId] = array(
|
177 |
+
'value_index' => $optionId,
|
178 |
+
'is_percent' => $isPercent,
|
179 |
+
'pricing_value' => $priceChange,
|
180 |
+
);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
}
|
184 |
+
}
|
185 |
+
$configurable->setConfigurableAttributesData($configurableAttributesData);
|
186 |
+
$configurable->save();
|
187 |
+
$idsToReindex[] = $configurable->getId();
|
188 |
+
$configurable->clearInstance();
|
189 |
+
} catch (Exception $e) {
|
190 |
+
$failedSkus[$configurable->getSku()] = $e->getMessage();
|
191 |
+
}
|
192 |
+
}
|
193 |
+
}
|
194 |
+
if ($idsToReindex) {
|
195 |
+
$this->getHelper()->reindexProducts(array_unique($idsToReindex),
|
196 |
+
Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE);
|
197 |
+
}
|
198 |
+
if ($failedSkus) {
|
199 |
+
$finalMessage = array();
|
200 |
+
foreach ($failedSkus as $sku => $message) {
|
201 |
+
$finalMessage[] = sprintf('sku: "%s", error: "%s"', $sku, $message);
|
202 |
+
}
|
203 |
+
$finalMessage = implode('; ', $finalMessage);
|
204 |
+
$this->_throwException('Configurable data is not saved for: ' . $finalMessage,
|
205 |
+
'cant_save_configurable_data');
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @param Mage_Catalog_Model_Product $product
|
211 |
+
* @return array
|
212 |
+
*/
|
213 |
+
public function outputData($product)
|
214 |
+
{
|
215 |
+
$data = array();
|
216 |
+
|
217 |
+
if ($product->getTypeId() !== Mage_Catalog_Model_Product_Type_Configurable::TYPE_CODE) {
|
218 |
+
return array();
|
219 |
+
}
|
220 |
+
$productType = $product->getTypeInstance(true);
|
221 |
+
$productType->setProduct($product);
|
222 |
+
$children = $productType->getChildrenIds($product->getId());
|
223 |
+
if ($children) {
|
224 |
+
$children = $children[0];
|
225 |
+
}
|
226 |
+
$associations = $this->_getResource()->getSkuByProductIds($children);
|
227 |
+
|
228 |
+
$data['associations'] = $associations;
|
229 |
+
|
230 |
+
$attributesData = $productType->getConfigurableAttributesAsArray();
|
231 |
+
$priceChanges = array();
|
232 |
+
foreach ($attributesData as $attributeData) {
|
233 |
+
$options = array();
|
234 |
+
foreach ($attributeData['values'] as $value) {
|
235 |
+
$options[$value['label']] = floatval($value['pricing_value']) . ($value['is_percent'] ? '%' : '');
|
236 |
+
}
|
237 |
+
$priceChanges[$attributeData['attribute_code']] = array(
|
238 |
+
'label' => $attributeData['label'],
|
239 |
+
'position' => $attributeData['position'],
|
240 |
+
'options' => $options
|
241 |
+
);
|
242 |
+
}
|
243 |
+
|
244 |
+
$data['price_changes'] = $priceChanges;
|
245 |
+
|
246 |
+
return $data;
|
247 |
+
}
|
248 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Default.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Default extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'general';
|
29 |
+
|
30 |
+
/** @var array */
|
31 |
+
protected $_productTypes;
|
32 |
+
|
33 |
+
protected function _construct()
|
34 |
+
{
|
35 |
+
$this->_productTypes = array_keys(Mage::getModel('catalog/product_type')->getOptionArray());
|
36 |
+
$this->_errorCodes = array(
|
37 |
+
'product_type_not_passed' => 401,
|
38 |
+
'invalid_product_data' => 402,
|
39 |
+
'error_saving_product' => 403,
|
40 |
+
'product_type_not_exists' => 404
|
41 |
+
);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @param array $productData
|
46 |
+
* @param Mage_Catalog_Model_Product $product
|
47 |
+
* @return mixed
|
48 |
+
*/
|
49 |
+
public function processData(array &$productData, $product)
|
50 |
+
{
|
51 |
+
$attributeSetId = $productData['attribute_set_id'];
|
52 |
+
$sku = $productData['sku'];
|
53 |
+
|
54 |
+
$product->setAttributeSetId($attributeSetId);
|
55 |
+
|
56 |
+
if (!$product->getId()) {
|
57 |
+
if (empty($productData['type_id'])) {
|
58 |
+
$this->_throwException('Product type is not specified', 'product_type_not_passed');
|
59 |
+
}
|
60 |
+
$type = $productData['type_id'];
|
61 |
+
$this->_checkProductTypeExists($type);
|
62 |
+
$product->setTypeId($type)->setSku($sku);
|
63 |
+
if (!isset($productData['stock_data']) || !is_array($productData['stock_data'])) {
|
64 |
+
//Set default stock_data if not exist in product data
|
65 |
+
$product->setStockData(array('use_config_manage_stock' => 0));
|
66 |
+
}
|
67 |
+
}
|
68 |
+
$this->_prepareDataForSave($product, $productData);
|
69 |
+
|
70 |
+
try {
|
71 |
+
if (is_array($errors = $product->validate())) {
|
72 |
+
$strErrors = array();
|
73 |
+
foreach($errors as $code => $error) {
|
74 |
+
if ($error === true) {
|
75 |
+
$error = Mage::helper('catalog')->__('Attribute "%s" is invalid.', $code);
|
76 |
+
}
|
77 |
+
$strErrors[] = $error;
|
78 |
+
}
|
79 |
+
$this->_throwException(implode("\n", $strErrors), 'invalid_product_data');
|
80 |
+
}
|
81 |
+
|
82 |
+
$product->save();
|
83 |
+
} catch (Mage_Core_Exception $e) {
|
84 |
+
$this->_throwException($e->getMessage(), 'error_saving_product');
|
85 |
+
}
|
86 |
+
|
87 |
+
$productData['product_id'] = $product->getId();
|
88 |
+
|
89 |
+
return $product->getId();
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @param Mage_Catalog_Model_Product $product
|
94 |
+
* @return array
|
95 |
+
*/
|
96 |
+
public function outputData($product)
|
97 |
+
{
|
98 |
+
$data = array();
|
99 |
+
|
100 |
+
$data['parents'] = array();
|
101 |
+
|
102 |
+
if ($product->isComposite()) {
|
103 |
+
return $data;
|
104 |
+
}
|
105 |
+
$parents = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
106 |
+
$parents = array_merge($parents, Mage::getModel('bundle/product_type')->getParentIdsByChild($product->getId()));
|
107 |
+
$parents = $this->_getResource()->getSkuByProductIds($parents);
|
108 |
+
|
109 |
+
$data['parents'] = $parents;
|
110 |
+
|
111 |
+
return $data;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Set additional data before product saved
|
116 |
+
*
|
117 |
+
* @param Mage_Catalog_Model_Product $product
|
118 |
+
* @param array $productData
|
119 |
+
* @return object
|
120 |
+
*/
|
121 |
+
protected function _prepareDataForSave($product, $productData)
|
122 |
+
{
|
123 |
+
$product->addData($productData);
|
124 |
+
|
125 |
+
if (isset($productData['website_ids']) && is_array($productData['website_ids'])) {
|
126 |
+
$product->setWebsiteIds($productData['website_ids']);
|
127 |
+
}
|
128 |
+
|
129 |
+
if (isset($productData['websites']) && is_array($productData['websites'])) {
|
130 |
+
foreach ($productData['websites'] as &$website) {
|
131 |
+
if (is_string($website)) {
|
132 |
+
try {
|
133 |
+
$website = Mage::app()->getWebsite($website)->getId();
|
134 |
+
} catch (Exception $e) { }
|
135 |
+
}
|
136 |
+
}
|
137 |
+
$product->setWebsiteIds($productData['websites']);
|
138 |
+
}
|
139 |
+
|
140 |
+
if (Mage::app()->isSingleStoreMode()) {
|
141 |
+
$product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId()));
|
142 |
+
}
|
143 |
+
|
144 |
+
if (isset($productData['stock_data']) && is_array($productData['stock_data'])) {
|
145 |
+
$product->setStockData($productData['stock_data']);
|
146 |
+
}
|
147 |
+
|
148 |
+
if (isset($productData['tier_price']) && is_array($productData['tier_price'])) {
|
149 |
+
$tierPrices = Mage::getModel('catalog/product_attribute_tierprice_api')
|
150 |
+
->prepareTierPrices($product, $productData['tier_price']);
|
151 |
+
$product->setData(Mage_Catalog_Model_Product_Attribute_Tierprice_Api::ATTRIBUTE_CODE, $tierPrices);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Check if product type exists
|
157 |
+
*
|
158 |
+
* @param $productType
|
159 |
+
* @throw Mage_Api_Exception
|
160 |
+
* @return void
|
161 |
+
*/
|
162 |
+
protected function _checkProductTypeExists($productType)
|
163 |
+
{
|
164 |
+
if (!in_array($productType, $this->_productTypes)) {
|
165 |
+
$this->_throwException('Product type not exists', 'product_type_not_exists');
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Downloadable.php
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Downloadable extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'downloadable';
|
29 |
+
|
30 |
+
protected $_downloadableData = array();
|
31 |
+
|
32 |
+
protected function _construct()
|
33 |
+
{
|
34 |
+
$this->_errorCodes = array(
|
35 |
+
'cant_save_downloadable_data' => '901'
|
36 |
+
);
|
37 |
+
parent::_construct();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @param array $productData
|
42 |
+
* @param Mage_Catalog_Model_Product $product
|
43 |
+
* @return mixed|void
|
44 |
+
*/
|
45 |
+
public function processData(array &$productData, $product)
|
46 |
+
{
|
47 |
+
$sku = $productData['sku'];
|
48 |
+
|
49 |
+
if (isset($productData['downloadable_links'])) {
|
50 |
+
$this->_downloadableData[$sku] = $productData['downloadable_links'];
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param array $skuToIdMap
|
56 |
+
* @return $this|void
|
57 |
+
*/
|
58 |
+
public function afterDataProcess(array &$skuToIdMap)
|
59 |
+
{
|
60 |
+
$failedSkus = array();
|
61 |
+
$idsToReindex = array();
|
62 |
+
if (isset($this->_downloadableData)) {
|
63 |
+
|
64 |
+
foreach ($this->_downloadableData as $sku => $downloadableData) {
|
65 |
+
try {
|
66 |
+
$productId = $skuToIdMap[$sku];
|
67 |
+
/** @var Mage_Catalog_Model_Product $downloadable */
|
68 |
+
$downloadable = Mage::getModel('catalog/product')->load($productId);
|
69 |
+
$data = array();
|
70 |
+
foreach ($downloadableData as $resource) {
|
71 |
+
$resourceType = $resource['link_type'];
|
72 |
+
if (!isset($data[$resourceType])) {
|
73 |
+
$data[$resourceType] = array();
|
74 |
+
}
|
75 |
+
$this->_getValidator()->validateType($resourceType);
|
76 |
+
$this->_getValidator()->validateAttributes($resource, $resourceType);
|
77 |
+
$resource['is_delete'] = 0;
|
78 |
+
if ($resourceType == 'link') {
|
79 |
+
$resource['link_id'] = 0;
|
80 |
+
} elseif ($resourceType == 'sample') {
|
81 |
+
$resource['sample_id'] = 0;
|
82 |
+
}
|
83 |
+
|
84 |
+
if ($resource['type'] == 'file') {
|
85 |
+
if (isset($resource['file'])) {
|
86 |
+
$resource['file'] = $this->_uploadFile($resource['file'], $resourceType);
|
87 |
+
}
|
88 |
+
} elseif ($resource['type'] == 'url') {
|
89 |
+
unset($resource['file']);
|
90 |
+
}
|
91 |
+
|
92 |
+
if ($resourceType == 'link' && $resource['sample']['type'] == 'file') {
|
93 |
+
if (isset($resource['sample']['file'])) {
|
94 |
+
$resource['sample']['file'] = $this->_uploadFile($resource['sample']['file'], 'link_samples');
|
95 |
+
}
|
96 |
+
unset($resource['sample']['url']);
|
97 |
+
} elseif ($resourceType == 'link' && $resource['sample']['type'] == 'url') {
|
98 |
+
$resource['sample']['file'] = null;
|
99 |
+
}
|
100 |
+
$data[$resourceType][] = $resource;
|
101 |
+
}
|
102 |
+
$downloadable->setDownloadableData($data);
|
103 |
+
$downloadable->save();
|
104 |
+
$downloadable->clearInstance();
|
105 |
+
} catch (Exception $e) {
|
106 |
+
echo $e->getMessage();
|
107 |
+
$failedSkus[] = $sku;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
}
|
111 |
+
if ($failedSkus) {
|
112 |
+
$this->_throwException('Downloadable data is not saved for ' . implode(',', array_unique($failedSkus)),
|
113 |
+
'cant_save_downloadable_data');
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Return validator instance
|
119 |
+
*
|
120 |
+
* @return RetailOps_Api_Model_Catalog_Push_Downloadable_Validator
|
121 |
+
*/
|
122 |
+
protected function _getValidator()
|
123 |
+
{
|
124 |
+
return Mage::getSingleton('retailops_api/catalog_push_downloadable_validator');
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Decode file from base64 and upload it to donwloadable 'tmp' folder
|
129 |
+
*
|
130 |
+
* @param array $fileInfo
|
131 |
+
* @param string $type
|
132 |
+
* @return string
|
133 |
+
*/
|
134 |
+
protected function _uploadFile($fileInfo, $type)
|
135 |
+
{
|
136 |
+
$tmpPath = '';
|
137 |
+
if ($type == 'sample') {
|
138 |
+
$tmpPath = Mage_Downloadable_Model_Sample::getBaseTmpPath();
|
139 |
+
} elseif ($type == 'link') {
|
140 |
+
$tmpPath = Mage_Downloadable_Model_Link::getBaseTmpPath();
|
141 |
+
} elseif ($type == 'link_samples') {
|
142 |
+
$tmpPath = Mage_Downloadable_Model_Link::getBaseSampleTmpPath();
|
143 |
+
}
|
144 |
+
|
145 |
+
$result = array();
|
146 |
+
$url = $fileInfo['url'];
|
147 |
+
$remoteFileName = $fileInfo['name'];
|
148 |
+
$ioAdapter = new Varien_Io_File();
|
149 |
+
$ioAdapter->checkAndCreateFolder($tmpPath);
|
150 |
+
$ioAdapter->open(array('path' => $tmpPath));
|
151 |
+
$fileName = $tmpPath . DS . Varien_File_Uploader::getCorrectFileName($remoteFileName);
|
152 |
+
if ($ioAdapter->cp($url, $fileName)) {
|
153 |
+
Mage::helper('core/file_storage_database')->saveFile($fileName);
|
154 |
+
}
|
155 |
+
$result['file'] = $remoteFileName;
|
156 |
+
$result['status'] = 'new';
|
157 |
+
$result['name'] = $remoteFileName;
|
158 |
+
return Mage::helper('core')->jsonEncode(array($result));
|
159 |
+
}
|
160 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Link.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Link extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'links';
|
29 |
+
|
30 |
+
protected $_linksData = array();
|
31 |
+
protected $_linkTypes = array();
|
32 |
+
|
33 |
+
protected function _construct()
|
34 |
+
{
|
35 |
+
$this->_linkTypes = $this->_getResource()->getLinkTypes();
|
36 |
+
$this->_errorCodes = array(
|
37 |
+
'cant_save_links_data' => 501,
|
38 |
+
);
|
39 |
+
parent::_construct();
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param array $productData
|
44 |
+
* @param Mage_Catalog_Model_Product $product
|
45 |
+
* @return mixed|void
|
46 |
+
*/
|
47 |
+
public function processData(array &$productData, $product)
|
48 |
+
{
|
49 |
+
if (isset($productData['links'])) {
|
50 |
+
foreach ($this->_linkTypes as $linkTypeId => $linkTypeCode) {
|
51 |
+
if (isset($productData['links'][$linkTypeCode])) {
|
52 |
+
$this->_linksData[$linkTypeId][$productData['sku']] = $productData['links'][$linkTypeCode];
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @param array $skuToIdMap
|
60 |
+
* @return $this|void
|
61 |
+
*/
|
62 |
+
public function afterDataProcess(array &$skuToIdMap)
|
63 |
+
{
|
64 |
+
$failedSkus = array();
|
65 |
+
if (!empty($this->_linksData)) {
|
66 |
+
foreach ($this->_linksData as $typeId => $linksData) {
|
67 |
+
foreach ($linksData as $sku => $productLinksData) {
|
68 |
+
$productId = $skuToIdMap[$sku];
|
69 |
+
/** @var Mage_Catalog_Model_Product $product */
|
70 |
+
$product = Mage::getModel('catalog/product')->setId($productId);
|
71 |
+
$link = $product->getLinkInstance()->setLinkTypeId($typeId);
|
72 |
+
$links = array();
|
73 |
+
foreach ($productLinksData as $productLinkData) {
|
74 |
+
if (!isset($skuToIdMap[$productLinkData['sku']])) {
|
75 |
+
continue;
|
76 |
+
}
|
77 |
+
$linkedProductId = $skuToIdMap[$productLinkData['sku']];
|
78 |
+
$links[$linkedProductId] = array();
|
79 |
+
foreach ($link->getAttributes() as $attribute) {
|
80 |
+
if (isset($productLinkData[$attribute['code']])) {
|
81 |
+
$links[$linkedProductId][$attribute['code']] = $productLinkData[$attribute['code']];
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
try {
|
86 |
+
if ($typeId == Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED) {
|
87 |
+
$link->getResource()->saveGroupedLinks($product, $links, $typeId);
|
88 |
+
$this->getHelper()->reindexProducts(array($product->getId()),
|
89 |
+
Mage_Catalog_Model_Product_Type_Grouped::TYPE_CODE);
|
90 |
+
} else {
|
91 |
+
$link->getResource()->saveProductLinks($product, $links, $typeId);
|
92 |
+
}
|
93 |
+
} catch (Exception $e) {
|
94 |
+
$failedSkus[] = $sku;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
if ($failedSkus) {
|
100 |
+
$this->_throwException('Links data is not saved for ' . implode(',', array_unique($failedSkus)),
|
101 |
+
'cant_save_links_data');
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* @param Mage_Catalog_Model_Product $product
|
107 |
+
* @return array
|
108 |
+
*/
|
109 |
+
public function outputData($product)
|
110 |
+
{
|
111 |
+
$data = array();
|
112 |
+
$data['links'] = $this->_getLinksData($product);
|
113 |
+
|
114 |
+
return $data;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Collect product links data
|
119 |
+
*
|
120 |
+
* @param Mage_Catalog_Model_Product $product
|
121 |
+
* @return array
|
122 |
+
*/
|
123 |
+
protected function _getLinksData(Mage_Catalog_Model_Product $product)
|
124 |
+
{
|
125 |
+
$linksData = array();
|
126 |
+
$link = $product->getLinkInstance();
|
127 |
+
foreach ($this->_linkTypes as $linkTypeId => $linkType) {
|
128 |
+
$link->setLinkTypeId($linkTypeId);
|
129 |
+
$linkedProducts = $this->_initLinksCollection($link, $product);
|
130 |
+
foreach ($linkedProducts as $linkedProduct) {
|
131 |
+
$row = array(
|
132 |
+
'product_id' => $linkedProduct->getId(),
|
133 |
+
'type' => $linkedProduct->getTypeId(),
|
134 |
+
'sku' => $linkedProduct->getSku()
|
135 |
+
);
|
136 |
+
|
137 |
+
foreach ($link->getAttributes() as $attribute) {
|
138 |
+
$row[$attribute['code']] = $linkedProduct->getData($attribute['code']);
|
139 |
+
}
|
140 |
+
|
141 |
+
$linksData[$linkType][] = $row;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
return $linksData;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Initialize and return linked products collection
|
150 |
+
*
|
151 |
+
* @param Mage_Catalog_Model_Product_Link $link
|
152 |
+
* @param Mage_Catalog_Model_Product $product
|
153 |
+
* @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collection
|
154 |
+
*/
|
155 |
+
protected function _initLinksCollection($link, $product)
|
156 |
+
{
|
157 |
+
$collection = $link
|
158 |
+
->getProductCollection()
|
159 |
+
->setIsStrongMode()
|
160 |
+
->setProduct($product);
|
161 |
+
|
162 |
+
return $collection;
|
163 |
+
}
|
164 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Media.php
ADDED
@@ -0,0 +1,399 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Media extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Attribute code for media gallery
|
30 |
+
*/
|
31 |
+
const ATTRIBUTE_CODE = 'media_gallery';
|
32 |
+
|
33 |
+
const CRON_DOWNLOAD_LIMIT = 10;
|
34 |
+
|
35 |
+
protected $_section = 'media';
|
36 |
+
|
37 |
+
protected $_mediaDataToSave = array();
|
38 |
+
protected $_straightMediaProcessing = false;
|
39 |
+
|
40 |
+
protected function _construct()
|
41 |
+
{
|
42 |
+
$this->_errorCodes = array(
|
43 |
+
'no_media_attribute' => 801,
|
44 |
+
);
|
45 |
+
parent::_construct();
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @param array $productData
|
50 |
+
* @param Mage_Catalog_Model_Product $product
|
51 |
+
* @return mixed|void
|
52 |
+
*/
|
53 |
+
public function processData(array &$productData, $product)
|
54 |
+
{
|
55 |
+
if ($product->getId() && (!isset($productData['unset_other_media']) || $productData['unset_other_media'])) {
|
56 |
+
$this->clearProductGallery($product);
|
57 |
+
}
|
58 |
+
|
59 |
+
if (isset($productData['media'])) {
|
60 |
+
$allMediaData = array();
|
61 |
+
foreach ($productData['media'] as $mediaData) {
|
62 |
+
$mediaData = new Varien_Object($mediaData);
|
63 |
+
|
64 |
+
Mage::dispatchEvent('retailops_catalog_media_process_before',
|
65 |
+
array('media_data' => $mediaData));
|
66 |
+
|
67 |
+
$allMediaData[] = $mediaData->getData();
|
68 |
+
}
|
69 |
+
$this->_mediaDataToSave[$productData['sku']] = json_encode($allMediaData);
|
70 |
+
}
|
71 |
+
if (isset($productData['straight_media_process']) && $productData['straight_media_process']) {
|
72 |
+
$this->_straightMediaProcessing = true;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param array $skuToIdMap
|
78 |
+
* @return $this|void
|
79 |
+
*/
|
80 |
+
public function afterDataProcess(array &$skuToIdMap)
|
81 |
+
{
|
82 |
+
if ($this->_mediaDataToSave) {
|
83 |
+
foreach ($this->_mediaDataToSave as $sku => $data) {
|
84 |
+
$productId = $skuToIdMap[$sku];
|
85 |
+
$dataToSave['media_data'] = $data;
|
86 |
+
$dataToSave['product_id'] = $productId;
|
87 |
+
$item = Mage::getModel('retailops_api/catalog_media_item')->setData($dataToSave);
|
88 |
+
if (!$this->_straightMediaProcessing) {
|
89 |
+
$item->save();
|
90 |
+
} else {
|
91 |
+
$this->downloadProductImages($item);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Unset product image gallery
|
99 |
+
*
|
100 |
+
* @param $product
|
101 |
+
*/
|
102 |
+
public function clearProductGallery($product)
|
103 |
+
{
|
104 |
+
$galleryData = $this->_prepareGallery($product);
|
105 |
+
|
106 |
+
if (isset($galleryData['images']) && is_array($galleryData['images'])) {
|
107 |
+
foreach ($galleryData['images'] as &$image) {
|
108 |
+
$image['removed'] = 1;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
$product->setData(self::ATTRIBUTE_CODE, $galleryData);
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Download products media
|
117 |
+
*
|
118 |
+
* @param Varien_Object|null $item
|
119 |
+
* @return array
|
120 |
+
*/
|
121 |
+
public function downloadProductImages($item = null)
|
122 |
+
{
|
123 |
+
$ioAdapter = new Varien_Io_File();
|
124 |
+
$tmpDirectory = Mage::getBaseDir('var') . DS . 'api' . DS . uniqid();
|
125 |
+
$ioAdapter->checkAndCreateFolder($tmpDirectory);
|
126 |
+
$ioAdapter->open(array('path' => $tmpDirectory));
|
127 |
+
$remoteCopyRetryLimit = 3;
|
128 |
+
$errorLogPath = '/tmp/retailops_magento_image_error.log';
|
129 |
+
if (!$item) {
|
130 |
+
$items = Mage::getModel('retailops_api/catalog_media_item')->getCollection();
|
131 |
+
$limit = $this->getHelper()->getConfig('media_processing_products_limit');
|
132 |
+
if (!is_numeric($limit)) {
|
133 |
+
$limit = self::CRON_DOWNLOAD_LIMIT;
|
134 |
+
}
|
135 |
+
$items->getSelect()->limit($limit);
|
136 |
+
} else {
|
137 |
+
$items = array($item);
|
138 |
+
}
|
139 |
+
$result = array();
|
140 |
+
/** @var $item RetailOps_Api_Model_Catalog_Media_Item */
|
141 |
+
foreach ($items as $item) {
|
142 |
+
$productId = $item->getProductId();
|
143 |
+
$product = Mage::getModel('catalog/product')->load($productId);
|
144 |
+
$product->setStoreId(0); //using default store for images import
|
145 |
+
$gallery = $this->_getGalleryAttribute($product);
|
146 |
+
$data = json_decode($item->getMediaData(), true);
|
147 |
+
$allImages = $this->_getResource()->getProductMedia($productId);
|
148 |
+
$existingImageMap = array();
|
149 |
+
foreach ($allImages as $image) {
|
150 |
+
$existingImageMap[$image['value_id']]
|
151 |
+
= array( 'mediakey' => $image['retailops_mediakey'], 'filename' => $image['value'] );
|
152 |
+
}
|
153 |
+
$sku = $product->getSku();
|
154 |
+
$result[$sku] = array();
|
155 |
+
try {
|
156 |
+
$imageResult = array();
|
157 |
+
$newImages = array();
|
158 |
+
foreach ($data as $newImage) {
|
159 |
+
try {
|
160 |
+
$file = $this->_existingImage($existingImageMap, $newImage);
|
161 |
+
|
162 |
+
if (!$file) {
|
163 |
+
$url = $newImage['download_url'];
|
164 |
+
if (!$this->_httpFileExists($url)) {
|
165 |
+
Mage::throwException('Image does not exist.');
|
166 |
+
}
|
167 |
+
$fileName = $this->_getFileName($url, $newImage['mediakey']);
|
168 |
+
$fileName = $tmpDirectory . DS . $fileName;
|
169 |
+
$ioAdapter->cp($url, $fileName);
|
170 |
+
|
171 |
+
$retry = 0;
|
172 |
+
$remoteCopySuccess = false;
|
173 |
+
while ($retry++ < $remoteCopyRetryLimit && !$remoteCopySuccess) {
|
174 |
+
$remoteCopySuccess = $ioAdapter->cp($url, $fileName);
|
175 |
+
}
|
176 |
+
|
177 |
+
if (!$remoteCopySuccess) {
|
178 |
+
$remoteCopyError = error_get_last();
|
179 |
+
|
180 |
+
throw new Exception($remoteCopyError['message']);
|
181 |
+
}
|
182 |
+
|
183 |
+
// Adding image to gallery
|
184 |
+
$file = $gallery->getBackend()->addImage(
|
185 |
+
$product,
|
186 |
+
$fileName,
|
187 |
+
null,
|
188 |
+
true
|
189 |
+
);
|
190 |
+
|
191 |
+
$newImages[$file] = $newImage['mediakey'];
|
192 |
+
}
|
193 |
+
|
194 |
+
$gallery->getBackend()->updateImage($product, $file, $newImage);
|
195 |
+
if (isset($newImage['types'])) {
|
196 |
+
$gallery->getBackend()->setMediaAttribute($product, $newImage['types'], $file);
|
197 |
+
}
|
198 |
+
} catch (Exception $e) {
|
199 |
+
$message = sprintf("Could not process image %s, error message: %s", $newImage['download_url'], $e->getMessage());
|
200 |
+
$imageResult[] = $message;
|
201 |
+
file_put_contents($errorLogPath, "$message\n", FILE_APPEND);
|
202 |
+
}
|
203 |
+
}
|
204 |
+
if ($imageResult) {
|
205 |
+
$result[$sku]['images'] = $imageResult;
|
206 |
+
}
|
207 |
+
$product->save();
|
208 |
+
$this->_updateMediaKeys($product->getId(), $newImages);
|
209 |
+
if ($item->getId()) {
|
210 |
+
$item->delete();
|
211 |
+
}
|
212 |
+
$product->clearInstance();
|
213 |
+
} catch (Exception $e) {
|
214 |
+
$result[$sku]['general'] = $e->getMessage();
|
215 |
+
file_put_contents($errorLogPath, "{$e->getMessage()}\n", FILE_APPEND);
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
// Remove temporary directory
|
220 |
+
$ioAdapter->rmdir($tmpDirectory, true);
|
221 |
+
|
222 |
+
return $result;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* @param Mage_Catalog_Model_Product $product
|
227 |
+
* @return array
|
228 |
+
*/
|
229 |
+
public function outputData($product)
|
230 |
+
{
|
231 |
+
$galleryData = $this->_prepareGallery($product);
|
232 |
+
$data = array();
|
233 |
+
$data['media'] = array();
|
234 |
+
|
235 |
+
if (!isset($galleryData['images']) || !is_array($galleryData['images'])) {
|
236 |
+
return $data;
|
237 |
+
}
|
238 |
+
|
239 |
+
$result = array();
|
240 |
+
$mediaWithMediaKey = $this->_getResource()->getProductMedia($product->getId());
|
241 |
+
$valueIdToMediaKey = array();
|
242 |
+
foreach ($mediaWithMediaKey as $media) {
|
243 |
+
$valueIdToMediaKey[$media['value_id']] = $media['retailops_mediakey'];
|
244 |
+
}
|
245 |
+
foreach ($galleryData['images'] as &$image) {
|
246 |
+
if (!empty($valueIdToMediaKey[$image['value_id']])) {
|
247 |
+
$image['mediakey'] = $valueIdToMediaKey[$image['value_id']];
|
248 |
+
}
|
249 |
+
$result[] = $this->_imageToArray($image, $product);
|
250 |
+
}
|
251 |
+
|
252 |
+
$data['media'] = $result;
|
253 |
+
|
254 |
+
return $data;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Converts image to api array data
|
259 |
+
*
|
260 |
+
* @param array $image
|
261 |
+
* @param Mage_Catalog_Model_Product $product
|
262 |
+
* @return array
|
263 |
+
*/
|
264 |
+
protected function _imageToArray(&$image, $product)
|
265 |
+
{
|
266 |
+
$result = array(
|
267 |
+
'file' => $image['file'],
|
268 |
+
'label' => $image['label'],
|
269 |
+
'position' => $image['position'],
|
270 |
+
'exclude' => $image['disabled'],
|
271 |
+
'mediakey' => $image['mediakey'],
|
272 |
+
'url' => $this->_getMediaConfig()->getMediaUrl($image['file']),
|
273 |
+
'types' => array()
|
274 |
+
);
|
275 |
+
|
276 |
+
|
277 |
+
foreach ($product->getMediaAttributes() as $attribute) {
|
278 |
+
if ($product->getData($attribute->getAttributeCode()) == $image['file']) {
|
279 |
+
$result['types'][] = $attribute->getAttributeCode();
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
return $result;
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Retrieve media config
|
288 |
+
*
|
289 |
+
* @return Mage_Catalog_Model_Product_Media_Config
|
290 |
+
*/
|
291 |
+
protected function _getMediaConfig()
|
292 |
+
{
|
293 |
+
return Mage::getSingleton('catalog/product_media_config');
|
294 |
+
}
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Prepare product's gallery data
|
298 |
+
*
|
299 |
+
* @param $product
|
300 |
+
* @return mixed
|
301 |
+
*/
|
302 |
+
protected function _prepareGallery($product)
|
303 |
+
{
|
304 |
+
$gallery = $this->_getGalleryAttribute($product);
|
305 |
+
$gallery->getBackend()->afterLoad($product);
|
306 |
+
$galleryData = $product->getData(self::ATTRIBUTE_CODE);
|
307 |
+
|
308 |
+
return $galleryData;
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* Check if image download url is valid
|
313 |
+
*
|
314 |
+
* @param $url
|
315 |
+
* @return bool
|
316 |
+
*/
|
317 |
+
protected function _httpFileExists($url)
|
318 |
+
{
|
319 |
+
$headers = @get_headers($url);
|
320 |
+
|
321 |
+
return !(strpos($headers[0], '200') === false);
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Get existing image filename, if any, based on mediakey and filename
|
326 |
+
*
|
327 |
+
* @param $existingImageMap
|
328 |
+
* @param $imageData
|
329 |
+
* @return mixed
|
330 |
+
*/
|
331 |
+
protected function _existingImage($existingImageMap, $imageData)
|
332 |
+
{
|
333 |
+
// Prioritize mediakeys. Search all existing images for mediakey before considering filename_match.
|
334 |
+
foreach ($existingImageMap as $existingImageData) {
|
335 |
+
if ($imageData['mediakey'] == $existingImageData['mediakey']) {
|
336 |
+
return $existingImageData['filename'];
|
337 |
+
}
|
338 |
+
}
|
339 |
+
|
340 |
+
foreach ($existingImageMap as $existingImageData) {
|
341 |
+
$fileNameMatch = preg_quote($data['filename_match'], '~');
|
342 |
+
|
343 |
+
if (strlen($fileNameMatch) && preg_grep('~' . $fileNameMatch . '~', $existingImageData['filename'])) {
|
344 |
+
return $existingImageData['filename'];
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
return false;
|
349 |
+
}
|
350 |
+
|
351 |
+
protected function _getFileName($url, $mediakey)
|
352 |
+
{
|
353 |
+
$fileName = Varien_File_Uploader::getCorrectFileName(basename($url));
|
354 |
+
$fileName = trim($fileName, '_');
|
355 |
+
|
356 |
+
return $fileName;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Update product's gallery with mediakeys
|
361 |
+
*
|
362 |
+
* @param $productId
|
363 |
+
* @param $newImages
|
364 |
+
*/
|
365 |
+
protected function _updateMediaKeys($productId, $newImages)
|
366 |
+
{
|
367 |
+
$allImages = Mage::getResourceModel('retailops_api/api')->getProductMedia($productId);
|
368 |
+
$dataToUpdate = array();
|
369 |
+
foreach ($allImages as $image) {
|
370 |
+
if (isset($newImages[$image['value']])) {
|
371 |
+
$dataToUpdate[] = array(
|
372 |
+
'value_id' => $image['value_id'],
|
373 |
+
'retailops_mediakey' => $newImages[$image['value']]
|
374 |
+
);
|
375 |
+
}
|
376 |
+
}
|
377 |
+
if ($dataToUpdate) {
|
378 |
+
Mage::getResourceModel('retailops_api/api')->updateMediaKeys($dataToUpdate);
|
379 |
+
}
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Retrieve gallery attribute from product
|
384 |
+
*
|
385 |
+
* @param Mage_Catalog_Model_Product $product
|
386 |
+
* @param Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute|boolean
|
387 |
+
*/
|
388 |
+
protected function _getGalleryAttribute($product)
|
389 |
+
{
|
390 |
+
$attributes = $product->getTypeInstance(true)
|
391 |
+
->getSetAttributes($product);
|
392 |
+
|
393 |
+
if (!isset($attributes[self::ATTRIBUTE_CODE])) {
|
394 |
+
$this->_throwException('Product has no media attribute', 'no_media_attribute');
|
395 |
+
}
|
396 |
+
|
397 |
+
return $attributes[self::ATTRIBUTE_CODE];
|
398 |
+
}
|
399 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Option.php
ADDED
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Option extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'custom_options';
|
29 |
+
protected $_optionTypes = array();
|
30 |
+
|
31 |
+
protected function _construct()
|
32 |
+
{
|
33 |
+
$this->_optionTypes = $this->_getOptionTypes();
|
34 |
+
$this->_errorCodes = array(
|
35 |
+
'invalid_options_data' => 701,
|
36 |
+
'invalid_options_type' => 702,
|
37 |
+
);
|
38 |
+
parent::_construct();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param array $productData
|
43 |
+
* @param Mage_Catalog_Model_Product $product
|
44 |
+
* @return mixed|void
|
45 |
+
*/
|
46 |
+
public function processData(array &$productData, $product)
|
47 |
+
{
|
48 |
+
if (isset($productData['custom_options'])) {
|
49 |
+
if ($product->getId()) {
|
50 |
+
$currentOptions = $product->getOptions();
|
51 |
+
foreach ($currentOptions as $option) {
|
52 |
+
$option->delete();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
$optionsData = $productData['custom_options'];
|
56 |
+
if (!empty($optionsData)) {
|
57 |
+
foreach ($optionsData as $optionData) {
|
58 |
+
$this->_addOption($product, $optionData);
|
59 |
+
}
|
60 |
+
$product->setHasOptions(true);
|
61 |
+
} else {
|
62 |
+
$product->setHasOptions(false);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param Mage_Catalog_Model_Product $product
|
69 |
+
* @return array
|
70 |
+
*/
|
71 |
+
public function outputData($product)
|
72 |
+
{
|
73 |
+
$data = array();
|
74 |
+
$data['custom_options'] = $this->_getCustomOptions($product);
|
75 |
+
|
76 |
+
return $data;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Get product custom options data
|
81 |
+
*
|
82 |
+
* @param Mage_Catalog_Model_Product $product
|
83 |
+
* @return array
|
84 |
+
*/
|
85 |
+
protected function _getCustomOptions($product)
|
86 |
+
{
|
87 |
+
$data = array();
|
88 |
+
foreach ($product->getProductOptionsCollection() as $option) {
|
89 |
+
$result = array(
|
90 |
+
'title' => $option->getTitle(),
|
91 |
+
'type' => $option->getType(),
|
92 |
+
'is_require' => $option->getIsRequire(),
|
93 |
+
'sort_order' => $option->getSortOrder(),
|
94 |
+
// additional_fields should be two-dimensional array for all option types
|
95 |
+
'additional_fields' => array(
|
96 |
+
array(
|
97 |
+
'price' => $option->getPrice(),
|
98 |
+
'price_type' => $option->getPriceType(),
|
99 |
+
'sku' => $option->getSku()
|
100 |
+
)
|
101 |
+
)
|
102 |
+
);
|
103 |
+
// Set additional fields to each type group
|
104 |
+
switch ($option->getGroupByType()) {
|
105 |
+
case Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT:
|
106 |
+
$result['additional_fields'][0]['max_characters'] = $option->getMaxCharacters();
|
107 |
+
break;
|
108 |
+
case Mage_Catalog_Model_Product_Option::OPTION_GROUP_FILE:
|
109 |
+
$result['additional_fields'][0]['file_extension'] = $option->getFileExtension();
|
110 |
+
$result['additional_fields'][0]['image_size_x'] = $option->getImageSizeX();
|
111 |
+
$result['additional_fields'][0]['image_size_y'] = $option->getImageSizeY();
|
112 |
+
break;
|
113 |
+
case Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT:
|
114 |
+
$result['additional_fields'] = array();
|
115 |
+
foreach ($option->getValuesCollection() as $value) {
|
116 |
+
$result['additional_fields'][] = array(
|
117 |
+
'value_id' => $value->getId(),
|
118 |
+
'title' => $value->getTitle(),
|
119 |
+
'price' => $value->getPrice(),
|
120 |
+
'price_type' => $value->getPriceType(),
|
121 |
+
'sku' => $value->getSku(),
|
122 |
+
'sort_order' => $value->getSortOrder()
|
123 |
+
);
|
124 |
+
}
|
125 |
+
break;
|
126 |
+
default:
|
127 |
+
break;
|
128 |
+
}
|
129 |
+
|
130 |
+
$data[] = $result;
|
131 |
+
}
|
132 |
+
|
133 |
+
return $data;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Add custom option to product
|
138 |
+
*
|
139 |
+
* @param Mage_Catalog_Model_Product $product
|
140 |
+
* @param array $data
|
141 |
+
* @param int|string|null $store
|
142 |
+
* @return bool $isAdded
|
143 |
+
*/
|
144 |
+
protected function _addOption($product, $data, $store = null)
|
145 |
+
{
|
146 |
+
if (!(is_array($data['additional_fields']) and count($data['additional_fields']))) {
|
147 |
+
$this->_throwException('Invalid custom options data', 'invalid_options_data');
|
148 |
+
}
|
149 |
+
if (!$this->_isTypeAllowed($data['type'])) {
|
150 |
+
$this->_throwException('Invalid custom options type', 'invalid_options_type');
|
151 |
+
}
|
152 |
+
$this->_prepareAdditionalFields(
|
153 |
+
$data,
|
154 |
+
$product->getOptionInstance()->getGroupByType($data['type'])
|
155 |
+
);
|
156 |
+
$this->_addProductCustomOption($product, $data);
|
157 |
+
|
158 |
+
return true;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @return Mage_Catalog_Model_Product_Option_Api
|
163 |
+
*/
|
164 |
+
protected function _getOptionApi()
|
165 |
+
{
|
166 |
+
return Mage::getModel('catalog/product_option_api');
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Add product custom option data.
|
171 |
+
*
|
172 |
+
* @param Mage_Catalog_Model_Product $product
|
173 |
+
* @param array $data
|
174 |
+
* @return void
|
175 |
+
*/
|
176 |
+
protected function _addProductCustomOption($product, $data)
|
177 |
+
{
|
178 |
+
foreach ($data as $key => $value) {
|
179 |
+
if (is_string($value)) {
|
180 |
+
$data[$key] = Mage::helper('catalog')->stripTags($value);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
if (!$product->getOptionsReadonly()) {
|
185 |
+
$product
|
186 |
+
->getOptionInstance()
|
187 |
+
->addOption($data);
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Prepare custom option data for saving by model.
|
193 |
+
*
|
194 |
+
* @param array $data
|
195 |
+
* @param string $groupType
|
196 |
+
* @return void
|
197 |
+
*/
|
198 |
+
protected function _prepareAdditionalFields(&$data, $groupType)
|
199 |
+
{
|
200 |
+
if (is_array($data['additional_fields'])) {
|
201 |
+
if ($groupType != Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
|
202 |
+
// reset can be used as there should be the only
|
203 |
+
// element in 'additional_fields' for options of all types except those from Select group
|
204 |
+
$field = reset($data['additional_fields']);
|
205 |
+
if (!(is_array($field) and count($field))) {
|
206 |
+
$this->_throwException('Invalid custom options data', 'invalid_options_data');
|
207 |
+
} else {
|
208 |
+
foreach ($field as $key => $value) {
|
209 |
+
$data[$key] = $value;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
} else {
|
213 |
+
// convert Select rows array to appropriate format for saving in the model
|
214 |
+
foreach ($data['additional_fields'] as $row) {
|
215 |
+
if (!(is_array($row) and count($row))) {
|
216 |
+
$this->_throwException('Invalid custom options data', 'invalid_options_data');
|
217 |
+
} else {
|
218 |
+
foreach ($row as $key => $value) {
|
219 |
+
$row[$key] = Mage::helper('catalog')->stripTags($value);
|
220 |
+
}
|
221 |
+
if (!empty($row['value_id'])) {
|
222 |
+
// map 'value_id' to 'option_type_id'
|
223 |
+
$row['option_type_id'] = $row['value_id'];
|
224 |
+
unset($row['value_id']);
|
225 |
+
$data['values'][$row['option_type_id']] = $row;
|
226 |
+
} else {
|
227 |
+
$data['values'][] = $row;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
231 |
+
}
|
232 |
+
}
|
233 |
+
unset($data['additional_fields']);
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Get allowed option types
|
238 |
+
*
|
239 |
+
* @return array
|
240 |
+
*/
|
241 |
+
protected function _getOptionTypes()
|
242 |
+
{
|
243 |
+
$types = $this->_getOptionApi()->types();
|
244 |
+
$allowedTypes = array();
|
245 |
+
foreach($types as $optionType){
|
246 |
+
$allowedTypes[] = $optionType['value'];
|
247 |
+
}
|
248 |
+
|
249 |
+
return $allowedTypes;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Check is type in allowed set
|
254 |
+
*
|
255 |
+
* @param string $type
|
256 |
+
* @return bool
|
257 |
+
*/
|
258 |
+
protected function _isTypeAllowed($type)
|
259 |
+
{
|
260 |
+
if (!in_array($type, $this->_optionTypes)) {
|
261 |
+
return false;
|
262 |
+
}
|
263 |
+
|
264 |
+
return true;
|
265 |
+
}
|
266 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Adapter/Tag.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Adapter_Tag extends RetailOps_Api_Model_Catalog_Adapter_Abstract
|
27 |
+
{
|
28 |
+
protected $_section = 'tags';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @param array $productData
|
32 |
+
* @param Mage_Catalog_Model_Product $product
|
33 |
+
* @return mixed|void
|
34 |
+
*/
|
35 |
+
public function processData(array &$productData, $product)
|
36 |
+
{
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param Mage_Catalog_Model_Product $product
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
public function outputData($product)
|
44 |
+
{
|
45 |
+
$data = array();
|
46 |
+
$data['tags'] = $this->_getTagsData($product->getId());
|
47 |
+
|
48 |
+
return $data;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get products tags data
|
53 |
+
*
|
54 |
+
* @param $productId
|
55 |
+
* @return array
|
56 |
+
*/
|
57 |
+
protected function _getTagsData($productId)
|
58 |
+
{
|
59 |
+
$data = array();
|
60 |
+
$tags = Mage::getModel('tag/tag')->getCollection()->addProductFilter($productId)->addPopularity();
|
61 |
+
/** @var $tag Mage_Tag_Model_Tag */
|
62 |
+
foreach ($tags as $tag) {
|
63 |
+
$result = array();
|
64 |
+
$result['status'] = $tag->getStatus();
|
65 |
+
$result['name'] = $tag->getName();
|
66 |
+
$result['base_popularity'] = (is_numeric($tag->getBasePopularity())) ? $tag->getBasePopularity() : 0;
|
67 |
+
$data[] = $result;
|
68 |
+
}
|
69 |
+
|
70 |
+
return $data;
|
71 |
+
}
|
72 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Api.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Api extends Mage_Catalog_Model_Product_Api
|
27 |
+
{
|
28 |
+
/** @var array */
|
29 |
+
protected $_dataAdapters;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Constructor. Initializes default values.
|
33 |
+
*/
|
34 |
+
public function __construct()
|
35 |
+
{
|
36 |
+
$this->_dataAdapters = array(
|
37 |
+
'attributes' => new RetailOps_Api_Model_Catalog_Adapter_Attribute($this),
|
38 |
+
'category' => new RetailOps_Api_Model_Catalog_Adapter_Category($this),
|
39 |
+
'media' => new RetailOps_Api_Model_Catalog_Adapter_Media($this),
|
40 |
+
'option' => new RetailOps_Api_Model_Catalog_Adapter_Option($this),
|
41 |
+
'configurable' => new RetailOps_Api_Model_Catalog_Adapter_Configurable($this),
|
42 |
+
'bundle' => new RetailOps_Api_Model_Catalog_Adapter_Bundle($this),
|
43 |
+
'downloadable' => new RetailOps_Api_Model_Catalog_Adapter_Downloadable($this),
|
44 |
+
'tag' => new RetailOps_Api_Model_Catalog_Adapter_Tag($this),
|
45 |
+
'default' => new RetailOps_Api_Model_Catalog_Adapter_Default($this),
|
46 |
+
'link' => new RetailOps_Api_Model_Catalog_Adapter_Link($this),
|
47 |
+
);
|
48 |
+
Mage::dispatchEvent('retailops_catalog_adapter_init_after', array('api' => $this));
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param $code
|
53 |
+
* @return bool
|
54 |
+
*/
|
55 |
+
public function getAdapter($code)
|
56 |
+
{
|
57 |
+
if (isset($this->_dataAdapters[$code])) {
|
58 |
+
return $this->_dataAdapters[$code];
|
59 |
+
}
|
60 |
+
|
61 |
+
return false;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @param $code
|
66 |
+
* @param $adapter
|
67 |
+
*/
|
68 |
+
public function addAdapter($code, $adapter)
|
69 |
+
{
|
70 |
+
if (!($adapter instanceof RetailOps_Api_Model_Catalog_Adapter_Abstract)) {
|
71 |
+
$this->_fault('wrong_data_adapter', 'Wrong data adapter class');
|
72 |
+
}
|
73 |
+
$this->_dataAdapters[$code] = $adapter;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @return RetailOps_Api_Helper_Data
|
78 |
+
*/
|
79 |
+
public function getHelper()
|
80 |
+
{
|
81 |
+
return Mage::helper('retailops_api');
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @return RetailOps_Api_Model_Resource_Api
|
86 |
+
*/
|
87 |
+
protected function _getResource()
|
88 |
+
{
|
89 |
+
return Mage::getResourceModel('retailops_api/api');
|
90 |
+
}
|
91 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Exception.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Exception
|
27 |
+
extends RetailOps_Api_Exception
|
28 |
+
{
|
29 |
+
/**
|
30 |
+
* API section with exception
|
31 |
+
*/
|
32 |
+
protected $_section = null;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* sku of product caused the excpetion
|
36 |
+
*/
|
37 |
+
protected $_sku = null;
|
38 |
+
|
39 |
+
public function __construct($message, $code = 0, $sku = null, $section = null)
|
40 |
+
{
|
41 |
+
parent::__construct($message, $code);
|
42 |
+
$this->_section = $section;
|
43 |
+
$this->_sku = $sku;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Area of code with exception
|
48 |
+
*
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
public function getSku()
|
52 |
+
{
|
53 |
+
return $this->_sku;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Area of code with exception
|
58 |
+
*
|
59 |
+
* @return string
|
60 |
+
*/
|
61 |
+
public function getSection()
|
62 |
+
{
|
63 |
+
return $this->_section;
|
64 |
+
}
|
65 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Media/Item.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* RetailOps media update item
|
28 |
+
*
|
29 |
+
* @method RetailOps_Api_Model_Resource_Catalog_Media_Item _getResource()
|
30 |
+
* @method RetailOps_Api_Model_Resource_Catalog_Media_Item getResource()
|
31 |
+
* @method int getProductId()
|
32 |
+
* @method RetailOps_Api_Model_Catalog_Media_Item setProductId()
|
33 |
+
* @method int getUnsetOtherMedia()
|
34 |
+
* @method RetailOps_Api_Model_Catalog_Media_Item setUnsetOtherMedia()
|
35 |
+
* @method string getMediaData()
|
36 |
+
* @method RetailOps_Api_Model_Catalog_Media_Item setMediaData()
|
37 |
+
*
|
38 |
+
* @category RetailOps
|
39 |
+
* @package RetailOps_Api
|
40 |
+
*/
|
41 |
+
class RetailOps_Api_Model_Catalog_Media_Item extends Mage_Core_Model_Abstract
|
42 |
+
{
|
43 |
+
/**
|
44 |
+
* Initialize resource model
|
45 |
+
*/
|
46 |
+
protected function _construct()
|
47 |
+
{
|
48 |
+
$this->_init('retailops_api/catalog_media_item');
|
49 |
+
}
|
50 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Pull/Api.php
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Pull_Api extends RetailOps_Api_Model_Catalog_Api
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Get Products
|
30 |
+
*
|
31 |
+
* @param mixed $filters
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function catalogPull($filters = null)
|
35 |
+
{
|
36 |
+
/** @var $collection Mage_Catalog_Model_Resource_Product_Collection */
|
37 |
+
$collection = Mage::getModel('catalog/product')->getCollection()
|
38 |
+
->addStoreFilter($this->_getStoreId())
|
39 |
+
->addAttributeToSelect('*');
|
40 |
+
|
41 |
+
$apiHelper = $this->getHelper();
|
42 |
+
$filters = $apiHelper->applyPager($collection, $filters);
|
43 |
+
$filters = $apiHelper->parseFilters($filters, $this->_filtersMap);
|
44 |
+
try {
|
45 |
+
foreach ($filters as $field => $value) {
|
46 |
+
$collection->addFieldToFilter($field, $value);
|
47 |
+
}
|
48 |
+
} catch (Mage_Core_Exception $e) {
|
49 |
+
$this->_fault('filters_invalid', $e->getMessage());
|
50 |
+
}
|
51 |
+
|
52 |
+
$result = array();
|
53 |
+
try {
|
54 |
+
|
55 |
+
Mage::dispatchEvent(
|
56 |
+
'retailops_catalog_pull_collection_prepare',
|
57 |
+
array('collection' => $collection)
|
58 |
+
);
|
59 |
+
|
60 |
+
$result['totalCount'] = $collection->getSize();
|
61 |
+
|
62 |
+
foreach ($this->_dataAdapters as $adapter) {
|
63 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
64 |
+
$adapter->prepareOutputData($collection);
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
$result['count'] = count($collection);
|
69 |
+
$records = array();
|
70 |
+
/** @var $product Mage_Catalog_Model_Product */
|
71 |
+
foreach ($collection as $product) {
|
72 |
+
$record = array(
|
73 |
+
'product_id' => $product->getId(),
|
74 |
+
'type' => $product->getTypeId(),
|
75 |
+
);
|
76 |
+
foreach ($this->_dataAdapters as $adapter) {
|
77 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
78 |
+
$record = array_merge($record, $adapter->outputData($product));
|
79 |
+
}
|
80 |
+
|
81 |
+
$recordObj = new Varien_Object($record);
|
82 |
+
|
83 |
+
Mage::dispatchEvent(
|
84 |
+
'retailops_catalog_pull_record',
|
85 |
+
array('record' => $recordObj)
|
86 |
+
);
|
87 |
+
|
88 |
+
$records[] = $recordObj->getData();
|
89 |
+
}
|
90 |
+
|
91 |
+
$result['records'] = $records;
|
92 |
+
} catch (Mage_Core_Exception $e) {
|
93 |
+
$this->_fault('catalog_pull_error', $e->getMessage());
|
94 |
+
}
|
95 |
+
|
96 |
+
return $result;
|
97 |
+
}
|
98 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Push/Api.php
ADDED
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Push_Api extends RetailOps_Api_Model_Catalog_Api
|
27 |
+
{
|
28 |
+
/** @var array */
|
29 |
+
protected $_skuToIdMap;
|
30 |
+
|
31 |
+
/** @var Mage_Index_Model_Resource_Process_Collection */
|
32 |
+
protected $_indexers;
|
33 |
+
|
34 |
+
protected $_errors = array();
|
35 |
+
|
36 |
+
public function __construct()
|
37 |
+
{
|
38 |
+
//$this->_indexers = Mage::getSingleton('index/indexer')->getProcessesCollection();
|
39 |
+
parent::__construct();
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return $this
|
44 |
+
*/
|
45 |
+
public function beforeDataPrepare()
|
46 |
+
{
|
47 |
+
try {
|
48 |
+
foreach ($this->_dataAdapters as $adapter) {
|
49 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
50 |
+
$adapter->beforeDataPrepare();
|
51 |
+
}
|
52 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
53 |
+
$this->_addError($e);
|
54 |
+
}
|
55 |
+
|
56 |
+
return $this;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param array $data
|
61 |
+
* @return $this
|
62 |
+
*/
|
63 |
+
public function prepareData(array &$data)
|
64 |
+
{
|
65 |
+
$this->_validateData($data);
|
66 |
+
foreach ($this->_dataAdapters as $adapter) {
|
67 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
68 |
+
$adapter->prepareData($data);
|
69 |
+
}
|
70 |
+
|
71 |
+
return $this;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return $this
|
76 |
+
*/
|
77 |
+
public function afterDataPrepare()
|
78 |
+
{
|
79 |
+
try {
|
80 |
+
foreach ($this->_dataAdapters as $adapter) {
|
81 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
82 |
+
$adapter->afterDataPrepare();
|
83 |
+
}
|
84 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
85 |
+
$this->_addError($e);
|
86 |
+
}
|
87 |
+
|
88 |
+
return $this;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @return $this
|
93 |
+
*/
|
94 |
+
public function beforeDataProcess()
|
95 |
+
{
|
96 |
+
try {
|
97 |
+
foreach ($this->_dataAdapters as $adapter) {
|
98 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
99 |
+
$adapter->beforeDataProcess();
|
100 |
+
}
|
101 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
102 |
+
$this->_addError($e);
|
103 |
+
}
|
104 |
+
$this->_skuToIdMap = $this->_getResource()->getIdsByProductSkus();
|
105 |
+
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @param array $data
|
111 |
+
* @return bool
|
112 |
+
* @throws Exception
|
113 |
+
*/
|
114 |
+
public function processData(array &$data)
|
115 |
+
{
|
116 |
+
/** @var Mage_Catalog_Model_Product $product */
|
117 |
+
$product = Mage::getModel('catalog/product');
|
118 |
+
if (isset($this->_skuToIdMap[$data['sku']])) {
|
119 |
+
$data['product_id'] = $this->_skuToIdMap[$data['sku']];
|
120 |
+
$product->load($data['product_id']);
|
121 |
+
}
|
122 |
+
|
123 |
+
foreach ($this->_dataAdapters as $adapter) {
|
124 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
125 |
+
$adapter->processData($data, $product);
|
126 |
+
}
|
127 |
+
|
128 |
+
$this->_skuToIdMap[$data['sku']] = $product->getId();
|
129 |
+
if ($product->getHasOptions()) {
|
130 |
+
/**
|
131 |
+
* Clear custom options singleton
|
132 |
+
*/
|
133 |
+
$product->getOptionInstance()->unsetOptions();
|
134 |
+
}
|
135 |
+
$product->clearInstance();
|
136 |
+
|
137 |
+
return true;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @return $this
|
142 |
+
*/
|
143 |
+
public function afterDataProcess()
|
144 |
+
{
|
145 |
+
foreach ($this->_dataAdapters as $adapter) {
|
146 |
+
try {
|
147 |
+
/** @var $adapter RetailOps_Api_Model_Catalog_Adapter_Abstract */
|
148 |
+
$adapter->afterDataProcess($this->_skuToIdMap);
|
149 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
150 |
+
$this->_addError($e);
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
return $this;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Create products
|
159 |
+
*
|
160 |
+
* @param $productsData
|
161 |
+
* @return array
|
162 |
+
*/
|
163 |
+
public function catalogPush($productsData)
|
164 |
+
{
|
165 |
+
file_put_contents('/tmp/magento_debug', 'catalogPush data ' . var_export($productsData, true) . "\n", FILE_APPEND);
|
166 |
+
if (isset($productsData['records'])) {
|
167 |
+
$productsData = $productsData['records'];
|
168 |
+
}
|
169 |
+
$result = array();
|
170 |
+
$result['records'] = array();
|
171 |
+
$processedSkus = array();
|
172 |
+
try {
|
173 |
+
//$this->_stopReindex();
|
174 |
+
$this->beforeDataPrepare();
|
175 |
+
foreach ($productsData as $key => $data) {
|
176 |
+
try {
|
177 |
+
$dataObj = new Varien_Object($data);
|
178 |
+
Mage::dispatchEvent('retailops_catalog_push_data_prepare_before', array('data' => $dataObj));
|
179 |
+
$data = $dataObj->getData();
|
180 |
+
$processedSkus[] = $data['sku'];
|
181 |
+
$this->prepareData($data);
|
182 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
183 |
+
unset($productsData[$key]);
|
184 |
+
$this->_addError($e);
|
185 |
+
}
|
186 |
+
}
|
187 |
+
$this->afterDataPrepare();
|
188 |
+
|
189 |
+
$this->beforeDataProcess();
|
190 |
+
foreach ($productsData as $data) {
|
191 |
+
try {
|
192 |
+
$dataObj = new Varien_Object($data);
|
193 |
+
Mage::dispatchEvent('retailops_catalog_push_data_process_before', array('data' => $dataObj));
|
194 |
+
$data = $dataObj->getData();
|
195 |
+
$this->processData($data);
|
196 |
+
} catch (RetailOps_Api_Model_Catalog_Exception $e) {
|
197 |
+
$this->_addError($e);
|
198 |
+
}
|
199 |
+
}
|
200 |
+
$this->afterDataProcess();
|
201 |
+
//$this->_startReindex();
|
202 |
+
} catch (Exception $e) {
|
203 |
+
$this->_addError(new RetailOps_Api_Model_Catalog_Exception($e->getMessage()));
|
204 |
+
}
|
205 |
+
foreach ($processedSkus as $sku) {
|
206 |
+
$r = array();
|
207 |
+
$r['sku'] = $sku;
|
208 |
+
$r['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
209 |
+
if (!empty($this->_errors[$sku])) {
|
210 |
+
$r['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
211 |
+
$r['errors'] = $this->_errors[$sku];
|
212 |
+
}
|
213 |
+
$result['records'][] = $r;
|
214 |
+
}
|
215 |
+
if (isset($this->_errors['global'])) {
|
216 |
+
$result['global_errors'] = $this->_errors['global'];
|
217 |
+
}
|
218 |
+
|
219 |
+
return $result;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* @param array $data
|
224 |
+
* @throws RetailOps_Api_Model_Catalog_Exception
|
225 |
+
*/
|
226 |
+
protected function _validateData(array &$data)
|
227 |
+
{
|
228 |
+
if (empty($data['sku'])) {
|
229 |
+
throw new RetailOps_Api_Model_Catalog_Exception('Sku is missing', 100, null, 'general');
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Add error message for api results
|
235 |
+
*
|
236 |
+
* @param RetailOps_Api_Model_Catalog_Exception $e
|
237 |
+
*/
|
238 |
+
protected function _addError(RetailOps_Api_Model_Catalog_Exception $e)
|
239 |
+
{
|
240 |
+
if ($e->getSku()) {
|
241 |
+
$errorKey = $e->getSku();
|
242 |
+
} else {
|
243 |
+
$errorKey = 'global';
|
244 |
+
}
|
245 |
+
if (!isset($this->_errors[$errorKey])) {
|
246 |
+
$this->_errors[$errorKey] = array();
|
247 |
+
}
|
248 |
+
$this->_errors[$errorKey][] = array(
|
249 |
+
'message' => $e->getMessage(),
|
250 |
+
'code' => $e->getCode(),
|
251 |
+
'section' => $e->getSection(),
|
252 |
+
);
|
253 |
+
}
|
254 |
+
|
255 |
+
// protected function _stopReindex()
|
256 |
+
// {
|
257 |
+
// $this->_indexers->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
|
258 |
+
// $this->_indexers->walk('save');
|
259 |
+
// }
|
260 |
+
//
|
261 |
+
// protected function _startReindex()
|
262 |
+
// {
|
263 |
+
// $this->_indexers->walk('reindexAll');
|
264 |
+
// $this->_indexers->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
|
265 |
+
// $this->_indexers->walk('save');
|
266 |
+
// }
|
267 |
+
}
|
app/code/community/RetailOps/Api/Model/Catalog/Push/Downloadable/Validator.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Catalog_Push_Downloadable_Validator extends Mage_Downloadable_Model_Link_Api_Validator
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Remove base64 file contents validation
|
30 |
+
*
|
31 |
+
* @param mixed $var
|
32 |
+
*/
|
33 |
+
public function validateFileDetails(&$var)
|
34 |
+
{
|
35 |
+
}
|
36 |
+
}
|
app/code/community/RetailOps/Api/Model/Inventory/Api.php
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Inventory_Api extends Mage_CatalogInventory_Model_Stock_Item_Api
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Update stock data of multiple products at once
|
30 |
+
*
|
31 |
+
* @param array $itemData
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function inventoryPush($itemData)
|
35 |
+
{
|
36 |
+
if (isset($itemData['records'])) {
|
37 |
+
$itemData = $itemData['records'];
|
38 |
+
}
|
39 |
+
$response = array();
|
40 |
+
$response['records'] = array();
|
41 |
+
$orderItemsCollection = Mage::getResourceModel('retailops_api/api')->getRetailopsNonretrievedOrderItems();
|
42 |
+
$orderItems = $this->filterOrderItems($orderItemsCollection);
|
43 |
+
$productIds = $this->getProductIds($itemData);
|
44 |
+
|
45 |
+
foreach ($itemData as $item) {
|
46 |
+
try {
|
47 |
+
$itemObj = new Varien_Object($item);
|
48 |
+
|
49 |
+
Mage::dispatchEvent(
|
50 |
+
'retailops_inventory_push_record',
|
51 |
+
array('record' => $itemObj)
|
52 |
+
);
|
53 |
+
|
54 |
+
$result = array();
|
55 |
+
$result['sku'] = $itemObj->getSku();
|
56 |
+
|
57 |
+
$itemObj->setQty($itemObj->getQuantity()); // api update accepts qty not quantity parameter
|
58 |
+
|
59 |
+
$qty = $itemObj->getQty();
|
60 |
+
if (isset($orderItems[$itemObj->getSku()])) {
|
61 |
+
$qty = $itemObj->getQty() - $orderItems[$itemObj->getSku()];
|
62 |
+
}
|
63 |
+
$itemObj->setQty($qty);
|
64 |
+
|
65 |
+
Mage::dispatchEvent(
|
66 |
+
'retailops_inventory_push_record_qty_processed',
|
67 |
+
array('record' => $itemObj)
|
68 |
+
);
|
69 |
+
|
70 |
+
$this->update($productIds[$itemObj->getSku()], $itemObj->getData());
|
71 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
72 |
+
} catch (Mage_Core_Exception $e) {
|
73 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
74 |
+
$result['error'] = array(
|
75 |
+
'code' => $e->getCode(),
|
76 |
+
'message' => $e->getMessage()
|
77 |
+
);
|
78 |
+
}
|
79 |
+
$response['records'][] = $result;
|
80 |
+
}
|
81 |
+
|
82 |
+
return $response;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Removes parent order items from collection
|
87 |
+
*
|
88 |
+
* @param $collection Mage_Sales_Model_Resource_Order_Item_Collection
|
89 |
+
* @return array
|
90 |
+
*/
|
91 |
+
public function filterOrderItems(Mage_Sales_Model_Resource_Order_Item_Collection $collection)
|
92 |
+
{
|
93 |
+
$result = array();
|
94 |
+
|
95 |
+
/* remove parent items */
|
96 |
+
foreach ($collection as $item) {
|
97 |
+
$collection->removeItemByKey($item->getParentItemId());
|
98 |
+
}
|
99 |
+
|
100 |
+
/* calculate total ordered quantity per item */
|
101 |
+
foreach ($collection as $item) {
|
102 |
+
if (isset($result[$item->getSku()])){
|
103 |
+
$result[$item->getSku()] += $item->getQtyOrdered();
|
104 |
+
} else {
|
105 |
+
$result[$item->getSku()] = $item->getQtyOrdered();
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
return $result;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Update product stock data
|
114 |
+
*
|
115 |
+
* @param int $productId
|
116 |
+
* @param array $data
|
117 |
+
* @return bool
|
118 |
+
*/
|
119 |
+
public function update($productId, $data)
|
120 |
+
{
|
121 |
+
/** @var $product Mage_Catalog_Model_Product */
|
122 |
+
$product = Mage::getModel('catalog/product');
|
123 |
+
|
124 |
+
$product->setStoreId($this->_getStoreId())
|
125 |
+
->load($productId);
|
126 |
+
|
127 |
+
if (!$product->getId()) {
|
128 |
+
$this->_fault('not_exists');
|
129 |
+
}
|
130 |
+
|
131 |
+
/** @var $stockItem Mage_CatalogInventory_Model_Stock_Item */
|
132 |
+
$stockItem = $product->getStockItem();
|
133 |
+
$stockData = array_replace($stockItem->getData(), (array)$data);
|
134 |
+
$stockItem->setData($stockData);
|
135 |
+
|
136 |
+
try {
|
137 |
+
$stockItem->save();
|
138 |
+
} catch (Mage_Core_Exception $e) {
|
139 |
+
$this->_fault('not_updated', $e->getMessage());
|
140 |
+
}
|
141 |
+
|
142 |
+
return true;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
*
|
147 |
+
*
|
148 |
+
* @param $data array
|
149 |
+
* @return array
|
150 |
+
*/
|
151 |
+
public function getProductIds($data)
|
152 |
+
{
|
153 |
+
$skus = array();
|
154 |
+
|
155 |
+
foreach ($data as $item) {
|
156 |
+
$skus[] = $item['sku'];
|
157 |
+
}
|
158 |
+
|
159 |
+
$result = Mage::getResourceModel('retailops_api/api')->getIdsByProductSkus($skus);
|
160 |
+
|
161 |
+
return $result;
|
162 |
+
}
|
163 |
+
}
|
app/code/community/RetailOps/Api/Model/Observer.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Observer
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Update retailops order status when payment is made
|
30 |
+
*
|
31 |
+
* @param $observer
|
32 |
+
*/
|
33 |
+
public function updateRetailopsStatus($observer)
|
34 |
+
{
|
35 |
+
$order = $observer->getEvent()->getPayment()->getOrder();
|
36 |
+
$order->setRetailopsStatus(RetailOps_Api_Helper_Data::RETAILOPS_ORDER_READY);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Download product images
|
41 |
+
*/
|
42 |
+
public function downloadProductImages()
|
43 |
+
{
|
44 |
+
$mediaAdapter = new RetailOps_Api_Model_Catalog_Adapter_Media();
|
45 |
+
$mediaAdapter->downloadProductImages();
|
46 |
+
}
|
47 |
+
}
|
app/code/community/RetailOps/Api/Model/Observer2.php~
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Observer
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Update retailops order status when payment is made
|
30 |
+
*
|
31 |
+
* @param $observer
|
32 |
+
*/
|
33 |
+
public function updateRetailopsStatus($observer)
|
34 |
+
{
|
35 |
+
$order = $observer->getEvent()->getPayment()->getOrder();
|
36 |
+
$order->setRetailopsStatus(RetailOps_Api_Helper_Data::RETAILOPS_ORDER_READY);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Download product images
|
41 |
+
*/
|
42 |
+
public function downloadProductImages()
|
43 |
+
{
|
44 |
+
$mediaAdapter = new RetailOps_Api_Model_Catalog_Adapter_Media();
|
45 |
+
$mediaAdapter->downloadProductImages();
|
46 |
+
}
|
47 |
+
}
|
app/code/community/RetailOps/Api/Model/Order/Api.php
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Order_Api extends Mage_Sales_Model_Order_Api
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Initialize attributes map
|
30 |
+
*/
|
31 |
+
public function __construct()
|
32 |
+
{
|
33 |
+
$this->_attributesMap = array(
|
34 |
+
'order' => array(
|
35 |
+
'order_id' => 'entity_id',
|
36 |
+
'order_increment_id' => 'increment_id'
|
37 |
+
),
|
38 |
+
'order_address' => array('address_id' => 'entity_id'),
|
39 |
+
'order_payment' => array('payment_id' => 'entity_id')
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Retrieve list of orders. Filtration could be applied
|
45 |
+
*
|
46 |
+
* @param null|object|array $filters
|
47 |
+
* @return array
|
48 |
+
*/
|
49 |
+
public function orderPull($filters = null)
|
50 |
+
{
|
51 |
+
$result = array();
|
52 |
+
//TODO: add full name logic
|
53 |
+
$billingAliasName = 'billing_o_a';
|
54 |
+
$shippingAliasName = 'shipping_o_a';
|
55 |
+
|
56 |
+
/** @var $orderCollection Mage_Sales_Model_Mysql4_Order_Collection */
|
57 |
+
$orderCollection = Mage::getModel("sales/order")->getCollection();
|
58 |
+
$billingFirstnameField = "$billingAliasName.firstname";
|
59 |
+
$billingLastnameField = "$billingAliasName.lastname";
|
60 |
+
$shippingFirstnameField = "$shippingAliasName.firstname";
|
61 |
+
$shippingLastnameField = "$shippingAliasName.lastname";
|
62 |
+
$orderCollection->addAttributeToSelect('*')
|
63 |
+
->addAddressFields()
|
64 |
+
->addExpressionFieldToSelect('billing_firstname', "{{billing_firstname}}",
|
65 |
+
array('billing_firstname' => $billingFirstnameField))
|
66 |
+
->addExpressionFieldToSelect('billing_lastname', "{{billing_lastname}}",
|
67 |
+
array('billing_lastname' => $billingLastnameField))
|
68 |
+
->addExpressionFieldToSelect('shipping_firstname', "{{shipping_firstname}}",
|
69 |
+
array('shipping_firstname' => $shippingFirstnameField))
|
70 |
+
->addExpressionFieldToSelect('shipping_lastname', "{{shipping_lastname}}",
|
71 |
+
array('shipping_lastname' => $shippingLastnameField))
|
72 |
+
->addExpressionFieldToSelect('billing_name', "CONCAT({{billing_firstname}}, ' ', {{billing_lastname}})",
|
73 |
+
array('billing_firstname' => $billingFirstnameField, 'billing_lastname' => $billingLastnameField))
|
74 |
+
->addExpressionFieldToSelect('shipping_name', 'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
|
75 |
+
array('shipping_firstname' => $shippingFirstnameField, 'shipping_lastname' => $shippingLastnameField)
|
76 |
+
);
|
77 |
+
|
78 |
+
Mage::dispatchEvent(
|
79 |
+
'retailops_order_collection_prepare',
|
80 |
+
array('collection' => $orderCollection)
|
81 |
+
);
|
82 |
+
|
83 |
+
|
84 |
+
|
85 |
+
/** @var $apiHelper Retailops_Api_Helper_Data */
|
86 |
+
$apiHelper = Mage::helper('retailops_api');
|
87 |
+
$filters = $apiHelper->applyPager($orderCollection, $filters);
|
88 |
+
$filters = $apiHelper->parseFilters($filters, $this->_attributesMap['order']);
|
89 |
+
|
90 |
+
try {
|
91 |
+
foreach ($filters as $field => $value) {
|
92 |
+
$orderCollection->addFieldToFilter($field, $value);
|
93 |
+
}
|
94 |
+
} catch (Mage_Core_Exception $e) {
|
95 |
+
$this->_fault('filters_invalid', $e->getMessage());
|
96 |
+
}
|
97 |
+
|
98 |
+
$result['totalCount'] = $orderCollection->getSize();
|
99 |
+
$result['count'] = count($orderCollection);
|
100 |
+
|
101 |
+
try {
|
102 |
+
foreach ($orderCollection as $order) {
|
103 |
+
$record = $this->orderInfo($order);
|
104 |
+
$recordObj = new Varien_Object($record);
|
105 |
+
|
106 |
+
Mage::dispatchEvent(
|
107 |
+
'retailops_order_pull_record',
|
108 |
+
array('record' => $recordObj)
|
109 |
+
);
|
110 |
+
|
111 |
+
$orders[] = $recordObj->getData();
|
112 |
+
}
|
113 |
+
|
114 |
+
$result['records'] = $orders;
|
115 |
+
} catch (Mage_Core_Exception $e) {
|
116 |
+
$this->_fault('order_pull_error', $e->getMessage());
|
117 |
+
}
|
118 |
+
|
119 |
+
return $result;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Retrieve full order information
|
124 |
+
*
|
125 |
+
* @param Mage_Core_Model_Abstract $order
|
126 |
+
* @return array
|
127 |
+
*/
|
128 |
+
public function orderInfo($order)
|
129 |
+
{
|
130 |
+
if ($order->getGiftMessageId() > 0) {
|
131 |
+
$order->setGiftMessage(
|
132 |
+
Mage::getSingleton('giftmessage/message')->load($order->getGiftMessageId())->getMessage()
|
133 |
+
);
|
134 |
+
} else {
|
135 |
+
$order->setGiftMessage(null);
|
136 |
+
}
|
137 |
+
|
138 |
+
$result['order_info'] = $this->_getAttributes($order, 'order');
|
139 |
+
|
140 |
+
$result['shipping_address'] = $this->_getAttributes($order->getShippingAddress(), 'order_address');
|
141 |
+
$result['billing_address'] = $this->_getAttributes($order->getBillingAddress(), 'order_address');
|
142 |
+
$result['items'] = array();
|
143 |
+
|
144 |
+
foreach ($order->getAllItems() as $item) {
|
145 |
+
if ($item->getGiftMessageId() > 0) {
|
146 |
+
$item->setGiftMessage(
|
147 |
+
Mage::getSingleton('giftmessage/message')->load($item->getGiftMessageId())->getMessage()
|
148 |
+
);
|
149 |
+
}
|
150 |
+
|
151 |
+
$result['items'][] = $this->_getAttributes($item, 'order_item');
|
152 |
+
}
|
153 |
+
|
154 |
+
$result['payment'] = $this->_getAttributes($order->getPayment(), 'order_payment');
|
155 |
+
|
156 |
+
$result['status_history'] = array();
|
157 |
+
|
158 |
+
foreach ($order->getAllStatusHistory() as $history) {
|
159 |
+
$result['status_history'][] = $this->_getAttributes($history, 'order_status_history');
|
160 |
+
}
|
161 |
+
|
162 |
+
$retailops_status_history = Mage::getModel('retailops_api/order_status_history')->getRetailOpsStatusHistory($order);
|
163 |
+
$result['retailops_status_history'] = array();
|
164 |
+
|
165 |
+
foreach ($retailops_status_history as $history) {
|
166 |
+
$result['retailops_status_history'][] = $this->_getAttributes($history, 'retailops_order_status_history');
|
167 |
+
}
|
168 |
+
|
169 |
+
return $result;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @param array $ordersData
|
174 |
+
* @return array
|
175 |
+
*/
|
176 |
+
public function orderStatusUpdate($ordersData)
|
177 |
+
{
|
178 |
+
if (isset($ordersData['records'])) {
|
179 |
+
$ordersData = $ordersData['records'];
|
180 |
+
}
|
181 |
+
$fullResult = array();
|
182 |
+
$fullResult['records'] = array();
|
183 |
+
foreach ($ordersData as $orderData) {
|
184 |
+
if (isset($orderData['order_increment_id'])) {
|
185 |
+
try {
|
186 |
+
$result = array(
|
187 |
+
'order_increment_id' => $orderData['order_increment_id']
|
188 |
+
);
|
189 |
+
/** @var Mage_Sales_Model_Order $order */
|
190 |
+
$order = Mage::getModel('sales/order');
|
191 |
+
$order->loadByIncrementId($orderData['order_increment_id']);
|
192 |
+
if (!$order->getId()) {
|
193 |
+
throw new Exception('Order is not found');
|
194 |
+
}
|
195 |
+
$order->setRetailopsStatus($orderData['retailops_status']);
|
196 |
+
$order->save();
|
197 |
+
/** @var RetailOps_Api_Model_Order_Status_History $history */
|
198 |
+
$history = Mage::getModel('retailops_api/order_status_history');
|
199 |
+
$history->setOrder($order);
|
200 |
+
$history->setStatus($orderData['retailops_status']);
|
201 |
+
if (isset($orderData['comment'])) {
|
202 |
+
$history->setComment($orderData['comment']);
|
203 |
+
}
|
204 |
+
$history->save();
|
205 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
206 |
+
} catch (Exception $e) {
|
207 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
208 |
+
$result['message'] = $e->getMessage();
|
209 |
+
}
|
210 |
+
$fullResult['records'][] = $result;
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
return $fullResult;
|
215 |
+
}
|
216 |
+
}
|
app/code/community/RetailOps/Api/Model/Order/Status/History.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Order status history comments
|
28 |
+
*
|
29 |
+
* @method RetailOps_Api_Model_Resource_Order_Status_History _getResource()
|
30 |
+
* @method RetailOps_Api_Model_Resource_Order_Status_History getResource()
|
31 |
+
* @method int getParentId()
|
32 |
+
* @method RetailOps_Api_Model_Order_Status_History setParentId(int $value)
|
33 |
+
* @method string getComment()
|
34 |
+
* @method RetailOps_Api_Model_Order_Status_History setComment(string $value)
|
35 |
+
* @method string getStatus()
|
36 |
+
* @method RetailOps_Api_Model_Order_Status_History setStatus(string $value)
|
37 |
+
* @method string getCreatedAt()
|
38 |
+
* @method RetailOps_Api_Model_Order_Status_History setCreatedAt(string $value)
|
39 |
+
*
|
40 |
+
* @category RetailOps
|
41 |
+
* @package RetailOps_Api
|
42 |
+
*/
|
43 |
+
class RetailOps_Api_Model_Order_Status_History extends Mage_Core_Model_Abstract
|
44 |
+
{
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Order instance
|
48 |
+
*
|
49 |
+
* @var Mage_Sales_Model_Order
|
50 |
+
*/
|
51 |
+
protected $_order;
|
52 |
+
|
53 |
+
protected $_eventPrefix = 'retailops_order_status_history';
|
54 |
+
protected $_eventObject = 'retailops_status_history';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Initialize resource model
|
58 |
+
*/
|
59 |
+
protected function _construct()
|
60 |
+
{
|
61 |
+
$this->_init('retailops_api/order_status_history');
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Set order object and grab some metadata from it
|
66 |
+
*
|
67 |
+
* @param Mage_Sales_Model_Order $order
|
68 |
+
* @return RetailOps_Api_Model_Order_Status_History
|
69 |
+
*/
|
70 |
+
public function setOrder(Mage_Sales_Model_Order $order)
|
71 |
+
{
|
72 |
+
$this->_order = $order;
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Retrieve order instance
|
78 |
+
*
|
79 |
+
* @return Mage_Sales_Model_Order
|
80 |
+
*/
|
81 |
+
public function getOrder()
|
82 |
+
{
|
83 |
+
return $this->_order;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Set order again if required
|
88 |
+
*
|
89 |
+
* @return RetailOps_Api_Model_Order_Status_History
|
90 |
+
*/
|
91 |
+
protected function _beforeSave()
|
92 |
+
{
|
93 |
+
parent::_beforeSave();
|
94 |
+
if (!$this->getParentId() && $this->getOrder()) {
|
95 |
+
$this->setParentId($this->getOrder()->getId());
|
96 |
+
$this->setStatus($this->getOrder()->getRetailopsStatus());
|
97 |
+
}
|
98 |
+
|
99 |
+
return $this;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @param Mage_Sales_Model_Order $order
|
104 |
+
*
|
105 |
+
* @return RetailOps_Api_Model_Resource_Order_Status_History_Collection
|
106 |
+
*/
|
107 |
+
public function getRetailOpsStatusHistory(Mage_Sales_Model_Order $order)
|
108 |
+
{
|
109 |
+
$statusHistory = Mage::getResourceModel('retailops_api/order_status_history_collection')
|
110 |
+
->setOrderFilter($order)
|
111 |
+
->setOrder('created_at', 'desc')
|
112 |
+
->setOrder('entity_id', 'desc');
|
113 |
+
|
114 |
+
if ($order->getId()) {
|
115 |
+
foreach ($statusHistory as $status) {
|
116 |
+
$status->setOrder($order);
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
return $statusHistory;
|
121 |
+
}
|
122 |
+
}
|
app/code/community/RetailOps/Api/Model/Resource/Api.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Resource_Api extends Mage_Core_Model_Resource_Db_Abstract
|
27 |
+
{
|
28 |
+
protected function _construct()
|
29 |
+
{
|
30 |
+
$this->_setResource('catalog');
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get product link types
|
35 |
+
*
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public function getLinkTypes()
|
39 |
+
{
|
40 |
+
$select = $this->_getReadAdapter()->select()->from($this->getTable('catalog/product_link_type'));
|
41 |
+
|
42 |
+
return $this->_getReadAdapter()->fetchPairs($select);
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Get products skus
|
47 |
+
*
|
48 |
+
* @param array $produtIds
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function getSkuByProductIds($produtIds)
|
52 |
+
{
|
53 |
+
if (!$produtIds) {
|
54 |
+
return array();
|
55 |
+
}
|
56 |
+
$select = $this->_getReadAdapter()->select()->from($this->getTable('catalog/product'), array('sku'));
|
57 |
+
$where = sprintf('entity_id IN (%s)', implode(',', $produtIds));
|
58 |
+
$select->where($where);
|
59 |
+
|
60 |
+
return $this->_getReadAdapter()->fetchCol($select);
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get products ids
|
65 |
+
*
|
66 |
+
* @param array $productSkus
|
67 |
+
* @return array
|
68 |
+
*/
|
69 |
+
public function getIdsByProductSkus($productSkus = null)
|
70 |
+
{
|
71 |
+
$select = $this->_getReadAdapter()->select()->from($this->getTable('catalog/product'), array('sku', 'entity_id'));
|
72 |
+
if ($productSkus) {
|
73 |
+
$select->where("sku IN (?)", $productSkus);
|
74 |
+
}
|
75 |
+
|
76 |
+
return $this->_getReadAdapter()->fetchPairs($select);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Gets Order Items For Orders with retailops_ready status
|
81 |
+
*
|
82 |
+
* @return Mage_Sales_Order_Item_Collection
|
83 |
+
*/
|
84 |
+
public function getRetailopsNonretrievedOrderItems()
|
85 |
+
{
|
86 |
+
$collection = Mage::getModel('sales/order_item')->getCollection();
|
87 |
+
|
88 |
+
$collection->getSelect()
|
89 |
+
->join(
|
90 |
+
array('orders' => $this->getTable('sales/order')),
|
91 |
+
'orders.entity_id = main_table.order_id',
|
92 |
+
array('orders.retailops_status')
|
93 |
+
)
|
94 |
+
->where('orders.retailops_status IN (?)', array( RetailOps_Api_Helper_Data::RETAILOPS_ORDER_HOLD, RetailOps_Api_Helper_Data::RETAILOPS_ORDER_READY ));
|
95 |
+
|
96 |
+
return $collection;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Get product's media gallery records
|
101 |
+
*
|
102 |
+
* @param $productId
|
103 |
+
* @return array
|
104 |
+
*/
|
105 |
+
public function getProductMedia($productId)
|
106 |
+
{
|
107 |
+
$select = $this->_getReadAdapter()->select()->from($this->getTable('catalog/product_attribute_media_gallery'))
|
108 |
+
->where('entity_id = ?', $productId);
|
109 |
+
|
110 |
+
return $this->_getReadAdapter()->fetchAll($select);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Update gallery table with media keys
|
115 |
+
*
|
116 |
+
* @param $data
|
117 |
+
*/
|
118 |
+
public function updateMediaKeys($data)
|
119 |
+
{
|
120 |
+
$adapter = $this->_getWriteAdapter();
|
121 |
+
$adapter->insertOnDuplicate($this->getTable('catalog/product_attribute_media_gallery'), $data);
|
122 |
+
}
|
123 |
+
}
|
app/code/community/RetailOps/Api/Model/Resource/Catalog/Media/Item.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @category RetailOps
|
28 |
+
* @package RetailOps_Api
|
29 |
+
*/
|
30 |
+
class RetailOps_Api_Model_Resource_Catalog_Media_Item extends Mage_Core_Model_Resource_Db_Abstract
|
31 |
+
{
|
32 |
+
/**
|
33 |
+
* Model initialization
|
34 |
+
*/
|
35 |
+
protected function _construct()
|
36 |
+
{
|
37 |
+
$this->_init('retailops_api/media_import', 'entity_id');
|
38 |
+
}
|
39 |
+
}
|
app/code/community/RetailOps/Api/Model/Resource/Catalog/Media/Item/Collection.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @category RetailOps
|
28 |
+
* @package RetailOps_Api
|
29 |
+
*/
|
30 |
+
class RetailOps_Api_Model_Resource_Catalog_Media_Item_Collection
|
31 |
+
extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
32 |
+
{
|
33 |
+
/**
|
34 |
+
* Model initialization
|
35 |
+
*/
|
36 |
+
protected function _construct()
|
37 |
+
{
|
38 |
+
$this->_init('retailops_api/catalog_media_item');
|
39 |
+
}
|
40 |
+
}
|
app/code/community/RetailOps/Api/Model/Resource/Order/Status/History.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Flat RetailOps_Api order status history resource
|
28 |
+
*
|
29 |
+
* @category RetailOps
|
30 |
+
* @package RetailOps_Api
|
31 |
+
*/
|
32 |
+
class RetailOps_Api_Model_Resource_Order_Status_History extends Mage_Sales_Model_Resource_Order_Abstract
|
33 |
+
{
|
34 |
+
/**
|
35 |
+
* Event prefix
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
protected $_eventPrefix = 'retailops_api_order_status_history_resource';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Model initialization
|
43 |
+
*
|
44 |
+
*/
|
45 |
+
protected function _construct()
|
46 |
+
{
|
47 |
+
$this->_init('retailops_api/order_status_history', 'entity_id');
|
48 |
+
}
|
49 |
+
}
|
app/code/community/RetailOps/Api/Model/Resource/Order/Status/History/Collection.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Flat retailops order status history collection
|
28 |
+
*
|
29 |
+
* @category RetailOps
|
30 |
+
* @package RetailOps_Api
|
31 |
+
*/
|
32 |
+
class RetailOps_Api_Model_Resource_Order_Status_History_Collection
|
33 |
+
extends Mage_Sales_Model_Resource_Order_Collection_Abstract
|
34 |
+
{
|
35 |
+
/**
|
36 |
+
* Event prefix
|
37 |
+
*
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
protected $_eventPrefix = 'retailops_order_status_history_collection';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Event object
|
44 |
+
*
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
protected $_eventObject = 'order_retailops_status_history_collection';
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Model initialization
|
51 |
+
*
|
52 |
+
*/
|
53 |
+
protected function _construct()
|
54 |
+
{
|
55 |
+
$this->_init('retailops_api/order_status_history');
|
56 |
+
}
|
57 |
+
}
|
app/code/community/RetailOps/Api/Model/Return/Api.php
ADDED
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Return_Api extends Mage_Sales_Model_Order_Creditmemo_Api
|
27 |
+
{
|
28 |
+
protected $_requestParams;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Initialize attributes mapping
|
32 |
+
*/
|
33 |
+
public function __construct()
|
34 |
+
{
|
35 |
+
parent::__construct();
|
36 |
+
$this->_ignoredAttributeCodes['creditmemo'] = array('invoice');
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Creates Credit Memo
|
41 |
+
*
|
42 |
+
* @param mixed $returns
|
43 |
+
* @return array
|
44 |
+
*/
|
45 |
+
public function returnPush($returns)
|
46 |
+
{
|
47 |
+
$this->_requestParams = $returns;
|
48 |
+
|
49 |
+
if (isset($returns['records'])) {
|
50 |
+
$returns = $returns['records'];
|
51 |
+
}
|
52 |
+
$fullResult = array();
|
53 |
+
$fullResult['records'] = array();
|
54 |
+
foreach ($returns as $return) {
|
55 |
+
try {
|
56 |
+
$result = array();
|
57 |
+
$returnObj = new Varien_Object($return);
|
58 |
+
Mage::dispatchEvent(
|
59 |
+
'retailops_return_push_record',
|
60 |
+
array('record' => $returnObj)
|
61 |
+
);
|
62 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId($returnObj->getOrderIncrementId());
|
63 |
+
$result = $this->create($order, $returnObj->getCreditmemoData(),
|
64 |
+
$returnObj->getComment(), $returnObj->getNotifyCustomer(), $returnObj->getIncludeComment(),
|
65 |
+
$returnObj->getRefundToStoreCredit());
|
66 |
+
} catch (Exception $e) {
|
67 |
+
$result['message'] = $e->getMessage();
|
68 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
69 |
+
$result['stack_trace'] = $e->getTraceAsString();
|
70 |
+
$result['request_params'] = $this->_requestParams;
|
71 |
+
}
|
72 |
+
$fullResult['records'][] = $result;
|
73 |
+
}
|
74 |
+
|
75 |
+
return $fullResult;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Create new credit memo for order
|
80 |
+
*
|
81 |
+
* @param Mage_Sales_Model_Order $order
|
82 |
+
* @param array $creditmemoData array('qtys' => array('itemId1' => qty1, ... , 'itemIdN' => qtyN),
|
83 |
+
* 'shipping_amount' => value, 'adjustment_positive' => value, 'adjustment_negative' => value)
|
84 |
+
* @param string|null $comment
|
85 |
+
* @param bool $notifyCustomer
|
86 |
+
* @param bool $includeComment
|
87 |
+
* @param string $refundToStoreCreditAmount
|
88 |
+
* @return string $creditmemoIncrementId
|
89 |
+
*/
|
90 |
+
public function create($order, $creditmemoData = null, $comment = null, $notifyCustomer = false,
|
91 |
+
$includeComment = false, $refundToStoreCreditAmount = null)
|
92 |
+
{
|
93 |
+
/** @var $helper RetailOps_Api_Helper_Data */
|
94 |
+
$helper = Mage::helper('retailops_api');
|
95 |
+
try {
|
96 |
+
$result = array();
|
97 |
+
if (!$order->getId()) {
|
98 |
+
$this->_fault('order_not_exists');
|
99 |
+
}
|
100 |
+
if (!$order->canCreditmemo()) {
|
101 |
+
$this->_fault('cannot_create_creditmemo');
|
102 |
+
}
|
103 |
+
$creditmemoData['order'] = $order;
|
104 |
+
$creditmemoData = $this->_prepareCreateData($creditmemoData);
|
105 |
+
|
106 |
+
/** @var $service Mage_Sales_Model_Service_Order */
|
107 |
+
$service = Mage::getModel('sales/service_order', $order);
|
108 |
+
/** @var $creditmemo Mage_Sales_Model_Order_Creditmemo */
|
109 |
+
$creditmemo = $service->prepareCreditmemo($creditmemoData, $order);
|
110 |
+
$invoice = $order->getInvoiceCollection()->getFirstItem();
|
111 |
+
if ($invoice) {
|
112 |
+
$creditmemo->setInvoice($invoice);
|
113 |
+
}
|
114 |
+
// refund to Store Credit
|
115 |
+
if ($refundToStoreCreditAmount) {
|
116 |
+
// check if refund to Store Credit is available
|
117 |
+
if ($order->getCustomerIsGuest()) {
|
118 |
+
$this->_fault('cannot_refund_to_storecredit');
|
119 |
+
}
|
120 |
+
$refundToStoreCreditAmount = max(
|
121 |
+
0,
|
122 |
+
min($creditmemo->getBaseCustomerBalanceReturnMax(), $refundToStoreCreditAmount)
|
123 |
+
);
|
124 |
+
if ($refundToStoreCreditAmount) {
|
125 |
+
$refundToStoreCreditAmount = $creditmemo->getStore()->roundPrice($refundToStoreCreditAmount);
|
126 |
+
$creditmemo->setBaseCustomerBalanceTotalRefunded($refundToStoreCreditAmount);
|
127 |
+
$refundToStoreCreditAmount = $creditmemo->getStore()->roundPrice(
|
128 |
+
$refundToStoreCreditAmount*$order->getStoreToOrderRate()
|
129 |
+
);
|
130 |
+
// this field can be used by customer balance observer
|
131 |
+
$creditmemo->setBsCustomerBalTotalRefunded($refundToStoreCreditAmount);
|
132 |
+
// setting flag to make actual refund to customer balance after credit memo save
|
133 |
+
$creditmemo->setCustomerBalanceRefundFlag(true);
|
134 |
+
}
|
135 |
+
$creditmemo->setPaymentRefundDisallowed(true);
|
136 |
+
}
|
137 |
+
$creditmemo->register();
|
138 |
+
// add comment to creditmemo
|
139 |
+
if (!empty($comment)) {
|
140 |
+
$creditmemo->addComment($comment, $notifyCustomer);
|
141 |
+
}
|
142 |
+
|
143 |
+
Mage::getModel('core/resource_transaction')
|
144 |
+
->addObject($creditmemo)
|
145 |
+
->addObject($order)
|
146 |
+
->save();
|
147 |
+
// send email notification
|
148 |
+
$creditmemo->sendEmail($notifyCustomer, ($includeComment ? $comment : ''));
|
149 |
+
$result['credit_memo'] = $helper->removeObjectsFromResult($this->_getAttributes($creditmemo, 'creditmemo'));
|
150 |
+
$result['items'] = array();
|
151 |
+
foreach ($creditmemo->getAllItems() as $item) {
|
152 |
+
$result['items'][] = $helper->removeObjectsFromResult($this->_getAttributes($item, 'creditmemo_item'));
|
153 |
+
}
|
154 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
155 |
+
} catch (Mage_Core_Exception $e) {
|
156 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
157 |
+
$result['message'] = $e->getMessage();
|
158 |
+
$result['code'] = $e->getCode();
|
159 |
+
$result['stack_trace'] = $e->getTraceAsString();
|
160 |
+
$result['request_params'] = $this->_requestParams;
|
161 |
+
}
|
162 |
+
|
163 |
+
return $result;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Set shipping amount to refund to 0 in case it's not passed
|
168 |
+
* Set qtys to refund to 0 by default if they are not passed
|
169 |
+
*
|
170 |
+
* @param array $data
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
protected function _prepareCreateData($data)
|
174 |
+
{
|
175 |
+
$data = parent::_prepareCreateData($data);
|
176 |
+
$qtys = array();
|
177 |
+
if (isset($data['qtys'])) {
|
178 |
+
$qtys = $data['qtys'];
|
179 |
+
}
|
180 |
+
$order = $data['order'];
|
181 |
+
$qtysArray = array();
|
182 |
+
foreach ($order->getAllItems() as $orderItem) {
|
183 |
+
$qtysArray[$orderItem->getId()] = isset($qtys[$orderItem->getId()]) ? $qtys[$orderItem->getId()] : 0;
|
184 |
+
}
|
185 |
+
$data['qtys'] = $qtysArray;
|
186 |
+
|
187 |
+
if (empty($data['shipping_amount'])) {
|
188 |
+
$data['shipping_amount'] = 0;
|
189 |
+
}
|
190 |
+
|
191 |
+
return $data;
|
192 |
+
}
|
193 |
+
}
|
app/code/community/RetailOps/Api/Model/Shipment/Api.php
ADDED
@@ -0,0 +1,469 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Shipment_Api extends Mage_Sales_Model_Order_Shipment_Api
|
27 |
+
{
|
28 |
+
protected $_requestParams;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Create new shipment for order
|
32 |
+
*
|
33 |
+
* @param string $orderIncrementId
|
34 |
+
* @param array $itemsQty
|
35 |
+
* @param string $comment
|
36 |
+
* @param booleam $email
|
37 |
+
* @param boolean $includeComment
|
38 |
+
* @param int $retailopsShipmentId
|
39 |
+
* @return string
|
40 |
+
*/
|
41 |
+
public function create($orderIncrementId, $itemsQty = array(), $comment = null, $email = false,
|
42 |
+
$includeComment = false, $retailopsShipmentId = null
|
43 |
+
) {
|
44 |
+
$shipmentIncrementId = parent::create($orderIncrementId, $itemsQty, $comment, $email, $includeComment);
|
45 |
+
|
46 |
+
if ($retailopsShipmentId && $shipmentIncrementId) {
|
47 |
+
$shipment = Mage::getModel('sales/order_shipment')->loadByIncrementId($shipmentIncrementId);
|
48 |
+
|
49 |
+
if (!$shipment->getId()) {
|
50 |
+
$this->_fault('shipment_not_exists');
|
51 |
+
}
|
52 |
+
|
53 |
+
$shipment->setRetailopsShipmentId($retailopsShipmentId);
|
54 |
+
$shipment->save();
|
55 |
+
}
|
56 |
+
|
57 |
+
return $shipmentIncrementId;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Creates shipment, adds track numbers, creates new invoices
|
62 |
+
*
|
63 |
+
* @param $shipments array
|
64 |
+
* @return array
|
65 |
+
*/
|
66 |
+
public function shipmentPush($shipments)
|
67 |
+
{
|
68 |
+
$this->_requestParams = $shipments;
|
69 |
+
|
70 |
+
$fullResult = array();
|
71 |
+
$fullResult['records'] = array();
|
72 |
+
if (isset($shipments['records'])) {
|
73 |
+
$shipments = $shipments['records'];
|
74 |
+
}
|
75 |
+
foreach ($shipments as $shipmentData) {
|
76 |
+
$result = array();
|
77 |
+
try{
|
78 |
+
$shipment = new Varien_Object($shipmentData);
|
79 |
+
|
80 |
+
Mage::dispatchEvent(
|
81 |
+
'retailops_shipment_process_before',
|
82 |
+
array('record' => $shipment)
|
83 |
+
);
|
84 |
+
|
85 |
+
$result['order_increment_id'] = $shipment->getOrderIncrementId();
|
86 |
+
|
87 |
+
$orderIncrementId = $shipment->getOrderIncrementId();
|
88 |
+
$shipmentInfo = $shipment->getShipment();
|
89 |
+
$trackInfo = isset($shipmentInfo['track']) ? $shipmentInfo['track'] : array();
|
90 |
+
$invoiceInfo = isset($shipmentInfo['invoice']) ? $shipmentInfo['invoice'] : array();
|
91 |
+
$shipmentResult = array();
|
92 |
+
$shipmentIncrementId = null;
|
93 |
+
|
94 |
+
/** @var Mage_Sales_Model_Order $order */
|
95 |
+
$order = Mage::getModel('sales/order');
|
96 |
+
$order->loadByIncrementId($orderIncrementId);
|
97 |
+
if (!$order->getId()) {
|
98 |
+
throw new Exception('Order is not found');
|
99 |
+
}
|
100 |
+
|
101 |
+
// create shipment
|
102 |
+
try {
|
103 |
+
// Try to locate existing shipment
|
104 |
+
$orderShipments = $order->getShipmentsCollection();
|
105 |
+
if (count($orderShipments)) {
|
106 |
+
foreach ($orderShipments as $orderShipment) {
|
107 |
+
$retailopsShipmentId = $orderShipment->getRetailopsShipmentId();
|
108 |
+
if ($retailopsShipmentId && $shipmentInfo['retailops_shipment_id']
|
109 |
+
&& $retailopsShipmentId == $shipmentInfo['retailops_shipment_id']) {
|
110 |
+
$shipmentIncrementId = $orderShipment->getIncrementId();
|
111 |
+
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
|
115 |
+
$shipmentComments = $orderShipment->getCommentsCollection();
|
116 |
+
foreach ($shipmentComments as $shipmentComment) {
|
117 |
+
if ($shipmentComment->getComment() == $shipmentInfo['comment']) {
|
118 |
+
$shipmentIncrementId = $orderShipment->getIncrementId();
|
119 |
+
|
120 |
+
break;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
if ($shipmentIncrementId) {
|
125 |
+
break;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
// Create a new shipment if we didn't find an existing one
|
131 |
+
// Only adding shipment to result if it was created
|
132 |
+
if (!$shipmentIncrementId && $order->canShip()) {
|
133 |
+
$shipmentIncrementId = $this->create($orderIncrementId,
|
134 |
+
$shipmentInfo['qtys'],
|
135 |
+
$shipmentInfo['comment'],
|
136 |
+
$shipmentInfo['email'],
|
137 |
+
$shipmentInfo['include_comment'],
|
138 |
+
$shipmentInfo['retailops_shipment_id']
|
139 |
+
);
|
140 |
+
|
141 |
+
if ($shipmentIncrementId) {
|
142 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
143 |
+
$shipmentResult['shipment_increment_id'] = $shipmentIncrementId;
|
144 |
+
} else {
|
145 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
146 |
+
$shipmentResult['message'] = Mage::helper('retailops_api')->__('Can not create shipment');
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
// We should have found or created a shipment by now
|
151 |
+
if (!$shipmentIncrementId) {
|
152 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
153 |
+
$shipmentResult['message'] = Mage::helper('retailops_api')->__('Shipment not found');
|
154 |
+
}
|
155 |
+
} catch (Mage_Core_Exception $e) {
|
156 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
157 |
+
$shipmentResult['message'] = $e->getCustomMessage() ? $e->getCustomMessage() : $e->getMessage();
|
158 |
+
$shipmentResult['stack_trace'] = $e->getTraceAsString();
|
159 |
+
$shipmentResult['request_params'] = $this->_requestParams;
|
160 |
+
}
|
161 |
+
$result['shipment_result'] = $shipmentResult ? array($shipmentResult) : array();
|
162 |
+
|
163 |
+
if ($shipmentIncrementId) {
|
164 |
+
if ($trackInfo) {
|
165 |
+
$existingShipmentInfo = Mage::getModel('sales/order_shipment_api')->info($shipmentIncrementId);
|
166 |
+
|
167 |
+
$result['track_result'] = array();
|
168 |
+
foreach ($trackInfo as $track) {
|
169 |
+
// add shipment track
|
170 |
+
try {
|
171 |
+
$trackResult = array();
|
172 |
+
$track = new Varien_Object($track);
|
173 |
+
|
174 |
+
$trackId = null;
|
175 |
+
foreach ($existingShipmentInfo['tracks'] as $existingTrack) {
|
176 |
+
if ($existingTrack['track_number'] == $track->getData('track_number')) {
|
177 |
+
$trackId = $existingTrack['track_id'];
|
178 |
+
|
179 |
+
break;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
if ($trackId) {
|
184 |
+
continue;
|
185 |
+
}
|
186 |
+
|
187 |
+
Mage::dispatchEvent(
|
188 |
+
'retailops_shipment_add_track_before',
|
189 |
+
array('record' => $track)
|
190 |
+
);
|
191 |
+
$trackResult['track_number'] = $track->getData('track_number');
|
192 |
+
|
193 |
+
$trackId = $this->addTrack($shipmentIncrementId,
|
194 |
+
$track->getData('carrier'),
|
195 |
+
$track->getData('title'),
|
196 |
+
$track->getData('track_number')
|
197 |
+
);
|
198 |
+
|
199 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
200 |
+
$trackResult['track_id'] = $trackId;
|
201 |
+
} catch (Mage_Core_Exception $e) {
|
202 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
203 |
+
$trackResult['message'] = $e->getMessage();
|
204 |
+
$trackResult['stack_trace'] = $e->getTraceAsString();
|
205 |
+
$trackResult['request_params'] = $this->_requestParams;
|
206 |
+
}
|
207 |
+
$result['track_result'][] = $trackResult;
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
// create invoice
|
212 |
+
/** @var Mage_Sales_Model_Order $order */
|
213 |
+
// Note that this does need to be loaded again. The item data may be stale if a shipment
|
214 |
+
// was submitted above.
|
215 |
+
$order = Mage::getModel('sales/order');
|
216 |
+
$order->loadByIncrementId($orderIncrementId);
|
217 |
+
$isFullyShipped = $this->_checkAllItemsShipped($order);
|
218 |
+
$invoices = $order->getInvoiceCollection();
|
219 |
+
$invoiceResult = array();
|
220 |
+
if ($order->canInvoice()) {
|
221 |
+
$itemsToInvoice = array();
|
222 |
+
if ($order->getPayment()->canCapturePartial()) {
|
223 |
+
/**
|
224 |
+
* If payment allows partial capture, trying to create invoice with shipped items only and capture it
|
225 |
+
*/
|
226 |
+
$itemsToInvoice = $shipmentInfo['qtys'];
|
227 |
+
}
|
228 |
+
if (($itemsToInvoice || $isFullyShipped) && $invoiceInfo) {
|
229 |
+
|
230 |
+
$invoice = new Varien_Object($invoiceInfo);
|
231 |
+
$invoice->setData('items_to_invoice', $itemsToInvoice);
|
232 |
+
|
233 |
+
Mage::dispatchEvent(
|
234 |
+
'retailops_shipment_invoice_before',
|
235 |
+
array('record' => $invoice)
|
236 |
+
);
|
237 |
+
|
238 |
+
$invoiceResult = $this->_createInvoiceAndCapture(
|
239 |
+
$order,
|
240 |
+
$invoice->getItemsToInvoice(),
|
241 |
+
$invoice->getComment(),
|
242 |
+
$invoice->getEmail(),
|
243 |
+
$invoice->getIncludeComment()
|
244 |
+
);
|
245 |
+
|
246 |
+
$invoiceResult = array($invoiceResult);
|
247 |
+
}
|
248 |
+
} else {
|
249 |
+
if ($isFullyShipped) {
|
250 |
+
/**
|
251 |
+
* Capturing all available invoices if all order items are shipped
|
252 |
+
*/
|
253 |
+
$invoiceResult = $this->_captureInvoices($invoices);
|
254 |
+
}
|
255 |
+
}
|
256 |
+
$result['invoice_result'] = $invoiceResult;
|
257 |
+
}
|
258 |
+
} catch (Exception $e) {
|
259 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
260 |
+
$result['message'] = $e->getMessage();
|
261 |
+
$result['stack_trace'] = $e->getTraceAsString();
|
262 |
+
$result['request_params'] = $this->_requestParams;
|
263 |
+
}
|
264 |
+
$fullResult['records'][] = $result;
|
265 |
+
}
|
266 |
+
|
267 |
+
return $fullResult;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @param array $ordersData
|
272 |
+
* @return array
|
273 |
+
*/
|
274 |
+
public function orderClose($ordersData)
|
275 |
+
{
|
276 |
+
$this->_requestParams = $ordersData;
|
277 |
+
|
278 |
+
$fullResult = array();
|
279 |
+
$fullResult['records'] = array();
|
280 |
+
if (isset($ordersData['records'])) {
|
281 |
+
$ordersData = $ordersData['records'];
|
282 |
+
}
|
283 |
+
foreach ($ordersData as $orderData) {
|
284 |
+
try {
|
285 |
+
if (!empty($orderData['order_increment_id'])) {
|
286 |
+
$result = array(
|
287 |
+
'order_increment_id' => $orderData['order_increment_id']
|
288 |
+
);
|
289 |
+
/** @var Mage_Sales_Model_Order $order */
|
290 |
+
$order = Mage::getModel('sales/order');
|
291 |
+
$order->loadByIncrementId($orderData['order_increment_id']);
|
292 |
+
if (!$order->getId()) {
|
293 |
+
throw new Exception('Order is not found');
|
294 |
+
}
|
295 |
+
Mage::dispatchEvent(
|
296 |
+
'retailops_order_close_before',
|
297 |
+
array('order' => $order)
|
298 |
+
);
|
299 |
+
$items = $order->getAllItems();
|
300 |
+
$itemsToReturn = array();
|
301 |
+
$itemsToCancel = array();
|
302 |
+
$itemsToCapture = array();
|
303 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
304 |
+
foreach ($items as $item) {
|
305 |
+
$qtyToShip = $item->getQtyToShip();
|
306 |
+
$qtyToInvoice = $item->getQtyToInvoice();
|
307 |
+
if ($qtyToShip + $qtyToInvoice > 0) {
|
308 |
+
if ($qtyToShip < $qtyToInvoice) {
|
309 |
+
/**
|
310 |
+
* If we have shipped more items than invoiced, capture the difference
|
311 |
+
*/
|
312 |
+
$itemsToCapture[$item->getId()] = $qtyToInvoice - $qtyToShip;
|
313 |
+
} elseif ($qtyToShip > $qtyToInvoice) {
|
314 |
+
/**
|
315 |
+
* If we have invoiced more items than shipped, return the difference
|
316 |
+
*/
|
317 |
+
$itemsToReturn[$item->getId()] = $qtyToShip - $qtyToInvoice;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
if ($itemsToCapture) {
|
322 |
+
$result['invoice_result'] = $this->_createInvoiceAndCapture($order, $itemsToCapture);
|
323 |
+
}
|
324 |
+
if ($itemsToReturn) {
|
325 |
+
$result['creditmemo_result'] = $this->_getCreditMemoApi()->create($order, array('qtys' => $itemsToReturn));
|
326 |
+
}
|
327 |
+
/**
|
328 |
+
* Cancel the rest items if any
|
329 |
+
*/
|
330 |
+
$order->registerCancellation(Mage::helper('retailops_api')->__('No more items will be shipped'));
|
331 |
+
if (isset($orderData['retailops_status'])) {
|
332 |
+
$order->setRetailopsStatus($orderData['retailops_status']);
|
333 |
+
}
|
334 |
+
$order->save();
|
335 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
336 |
+
}
|
337 |
+
} catch (Exception $e) {
|
338 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
339 |
+
$result['message'] = $e->getMessage();
|
340 |
+
$result['stack_trace'] = $e->getTraceAsString();
|
341 |
+
$result['request_params'] = $this->_requestParams;
|
342 |
+
}
|
343 |
+
$fullResult['records'][] = $result;
|
344 |
+
}
|
345 |
+
|
346 |
+
return $fullResult;
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* @return RetailOps_Api_Model_Return_Api
|
351 |
+
*/
|
352 |
+
protected function _getCreditMemoApi()
|
353 |
+
{
|
354 |
+
return Mage::getModel('retailops_api/return_api');
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* @param Mage_Sales_Model_Order $order
|
359 |
+
* @param array $itemsQty
|
360 |
+
* @param string $comment
|
361 |
+
* @param bool $email
|
362 |
+
* @param bool $includeComment
|
363 |
+
* @return string
|
364 |
+
*/
|
365 |
+
protected function _createInvoiceAndCapture($order, $itemsQty, $comment = null, $email = false, $includeComment = false)
|
366 |
+
{
|
367 |
+
/** @var $helper RetailOps_Api_Helper_Data */
|
368 |
+
$helper = Mage::helper('retailops_api');
|
369 |
+
try {
|
370 |
+
$itemsQtyFomratted = array();
|
371 |
+
if ($itemsQty) {
|
372 |
+
foreach ($order->getAllItems() as $item) {
|
373 |
+
$itemsQtyFomratted[$item->getId()] = isset($itemsQty[$item->getId()]) ? $itemsQty[$item->getId()] : 0;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
$invoice = $order->prepareInvoice($itemsQtyFomratted);
|
377 |
+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
|
378 |
+
$invoice->register();
|
379 |
+
|
380 |
+
if ($comment !== null) {
|
381 |
+
$invoice->addComment($comment, $email);
|
382 |
+
}
|
383 |
+
|
384 |
+
if ($email) {
|
385 |
+
$invoice->setEmailSent(true);
|
386 |
+
}
|
387 |
+
|
388 |
+
$invoice->getOrder()->setIsInProcess(true);
|
389 |
+
|
390 |
+
|
391 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
392 |
+
->addObject($invoice)
|
393 |
+
->addObject($invoice->getOrder())
|
394 |
+
->save();
|
395 |
+
|
396 |
+
$invoice->sendEmail($email, ($includeComment ? $comment : ''));
|
397 |
+
|
398 |
+
$result['invoice'] = $helper->removeObjectsFromResult($this->_getAttributes($invoice, 'invoice'));
|
399 |
+
$result['items'] = array();
|
400 |
+
foreach ($invoice->getAllItems() as $item) {
|
401 |
+
$result['items'][] = $helper->removeObjectsFromResult($this->_getAttributes($item, 'invoice_item'));
|
402 |
+
}
|
403 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
404 |
+
} catch (Exception $e) {
|
405 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
406 |
+
$result['message'] = $e->getMessage();
|
407 |
+
$result['stack_trace'] = $e->getTraceAsString();
|
408 |
+
$result['request_params'] = $this->_requestParams;
|
409 |
+
}
|
410 |
+
|
411 |
+
return $result;
|
412 |
+
}
|
413 |
+
|
414 |
+
/**
|
415 |
+
* Check that there are no items left for shipping
|
416 |
+
*
|
417 |
+
* @param Mage_Sales_Model_Order $order $order
|
418 |
+
* @return bool
|
419 |
+
*/
|
420 |
+
protected function _checkAllItemsShipped($order)
|
421 |
+
{
|
422 |
+
$items = $order->getAllItems();
|
423 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
424 |
+
foreach ($items as $item) {
|
425 |
+
if ($item->getQtyToShip()) {
|
426 |
+
return false;
|
427 |
+
}
|
428 |
+
}
|
429 |
+
|
430 |
+
return true;
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* @param Mage_Sales_Model_Resource_Order_Invoice_Collection $invoices
|
435 |
+
* @return array
|
436 |
+
*/
|
437 |
+
protected function _captureInvoices($invoices)
|
438 |
+
{
|
439 |
+
$result = array();
|
440 |
+
/** @var $invoice Mage_Sales_Model_Order_Invoice */
|
441 |
+
foreach ($invoices as $invoice) {
|
442 |
+
try {
|
443 |
+
if ($invoice->getState() == Mage_Sales_Model_Order_Invoice::STATE_PAID) {
|
444 |
+
continue;
|
445 |
+
}
|
446 |
+
$invoiceResult = array();
|
447 |
+
$invoiceResult['invoice_increment_id'] = $invoice->getIncrementId();
|
448 |
+
if (!$invoice->canCapture()) {
|
449 |
+
throw new Exception('Invoice cannot be captured.');
|
450 |
+
}
|
451 |
+
$invoice->capture();
|
452 |
+
$invoice->getOrder()->setIsInProcess(true);
|
453 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
454 |
+
->addObject($invoice)
|
455 |
+
->addObject($invoice->getOrder())
|
456 |
+
->save();
|
457 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
458 |
+
} catch (Exception $e) {
|
459 |
+
$invoiceResult['message'] = $e->getMessage();
|
460 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
461 |
+
$invoiceResult['stack_trace'] = $e->getTraceAsString();
|
462 |
+
$invoiceResult['request_params'] = $this->_requestParams;
|
463 |
+
}
|
464 |
+
$result[] = $invoiceResult;
|
465 |
+
}
|
466 |
+
|
467 |
+
return $result;
|
468 |
+
}
|
469 |
+
}
|
app/code/community/RetailOps/Api/Model/Shipment/Api.php.~80d30a79e43e602a0b5b5da0b2b1a8007dc0ada9~
ADDED
@@ -0,0 +1,355 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Shipment_Api extends Mage_Sales_Model_Order_Shipment_Api
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Creates shipment, adds track numbers, creates new invoices
|
30 |
+
*
|
31 |
+
* @param $shipments array
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function shipmentPush($shipments)
|
35 |
+
{
|
36 |
+
$fullResult = array();
|
37 |
+
$fullResult['records'] = array();
|
38 |
+
if (isset($shipments['records'])) {
|
39 |
+
$shipments = $shipments['records'];
|
40 |
+
}
|
41 |
+
foreach ($shipments as $shipmentData) {
|
42 |
+
$result = array();
|
43 |
+
try{
|
44 |
+
$shipment = new Varien_Object($shipmentData);
|
45 |
+
|
46 |
+
Mage::dispatchEvent(
|
47 |
+
'retailops_shipment_process_before',
|
48 |
+
array('record' => $shipment)
|
49 |
+
);
|
50 |
+
|
51 |
+
$result['order_increment_id'] = $shipment->getOrderIncrementId();
|
52 |
+
|
53 |
+
$orderIncrementId = $shipment->getOrderIncrementId();
|
54 |
+
$shipmentInfo = $shipment->getShipment();
|
55 |
+
$trackInfo = isset($shipmentInfo['track']) ? $shipmentInfo['track'] : array();
|
56 |
+
$invoiceInfo = isset($shipmentInfo['invoice']) ? $shipmentInfo['invoice'] : array();
|
57 |
+
$shipmentIncrementId = null;
|
58 |
+
// create shipment
|
59 |
+
try {
|
60 |
+
$shipmentResult = array();
|
61 |
+
$shipmentIncrementId = $this->create($orderIncrementId,
|
62 |
+
$shipmentInfo['qtys'],
|
63 |
+
$shipmentInfo['comment'],
|
64 |
+
$shipmentInfo['email'],
|
65 |
+
$shipmentInfo['include_comment']
|
66 |
+
);
|
67 |
+
|
68 |
+
if ($shipmentIncrementId) {
|
69 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
70 |
+
$shipmentResult['shipment_increment_id'] = $shipmentIncrementId;
|
71 |
+
} else {
|
72 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
73 |
+
$shipmentResult['message'] = Mage::helper('retailops_api')->__('Can not create shipment');
|
74 |
+
}
|
75 |
+
} catch (Mage_Core_Exception $e) {
|
76 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
77 |
+
$shipmentResult['message'] = $e->getCustomMessage() ? $e->getCustomMessage() : $e->getMessage();
|
78 |
+
}
|
79 |
+
|
80 |
+
$result['shipment_result'] = $shipmentResult;
|
81 |
+
if ($shipmentIncrementId) {
|
82 |
+
if ($trackInfo) {
|
83 |
+
$result['track_result'] = array();
|
84 |
+
foreach ($trackInfo as $track) {
|
85 |
+
// add shipment track
|
86 |
+
try {
|
87 |
+
$trackResult = array();
|
88 |
+
$track = new Varien_Object($track);
|
89 |
+
|
90 |
+
Mage::dispatchEvent(
|
91 |
+
'retailops_shipment_add_track_before',
|
92 |
+
array('record' => $track)
|
93 |
+
);
|
94 |
+
$trackResult['track_number'] = $track->getData('track_number');
|
95 |
+
|
96 |
+
$trackId = $this->addTrack($shipmentIncrementId,
|
97 |
+
$track->getData('carrier'),
|
98 |
+
$track->getData('title'),
|
99 |
+
$track->getData('track_number')
|
100 |
+
);
|
101 |
+
|
102 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
103 |
+
$trackResult['track_id'] = $trackId;
|
104 |
+
} catch (Mage_Core_Exception $e) {
|
105 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
106 |
+
$trackResult['message'] = $e->getMessage();
|
107 |
+
}
|
108 |
+
$result['track_result'][] = $trackResult;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
// create invoice
|
113 |
+
/** @var Mage_Sales_Model_Order $order */
|
114 |
+
$order = Mage::getModel('sales/order');
|
115 |
+
$order->loadByIncrementId($orderIncrementId);
|
116 |
+
$isFullyShipped = $this->_checkAllItemsShipped($order);
|
117 |
+
$invoices = $order->getInvoiceCollection();
|
118 |
+
$invoiceResult = array();
|
119 |
+
if ($order->canInvoice()) {
|
120 |
+
$itemsToInvoice = array();
|
121 |
+
if ($order->getPayment()->canCapturePartial()) {
|
122 |
+
/**
|
123 |
+
* If payment allows partial capture, trying to create invoice with shipped items only and capture it
|
124 |
+
*/
|
125 |
+
$itemsToInvoice = $shipmentInfo['qtys'];
|
126 |
+
}
|
127 |
+
if (($itemsToInvoice || $isFullyShipped) && $invoiceInfo) {
|
128 |
+
|
129 |
+
$invoice = new Varien_Object($invoiceInfo);
|
130 |
+
$invoice->setData('items_to_invoice', $itemsToInvoice);
|
131 |
+
|
132 |
+
Mage::dispatchEvent(
|
133 |
+
'retailops_shipment_invoice_before',
|
134 |
+
array('record' => $invoice)
|
135 |
+
);
|
136 |
+
|
137 |
+
$invoiceResult = $this->_createInvoiceAndCapture(
|
138 |
+
$order,
|
139 |
+
$invoice->getItemsToInvoice(),
|
140 |
+
$invoice->getComment(),
|
141 |
+
$invoice->getEmail(),
|
142 |
+
$invoice->getIncludeComment()
|
143 |
+
);
|
144 |
+
|
145 |
+
$invoiceResult = array($invoiceResult);
|
146 |
+
}
|
147 |
+
} else {
|
148 |
+
if ($isFullyShipped) {
|
149 |
+
/**
|
150 |
+
* Capturing all available invoices if all order items are shipped
|
151 |
+
*/
|
152 |
+
$invoiceResult = $this->_captureInvoices($invoices);
|
153 |
+
}
|
154 |
+
}
|
155 |
+
$result['invoice_result'] = $invoiceResult;
|
156 |
+
}
|
157 |
+
} catch (Exception $e) {
|
158 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
159 |
+
$result['message'] = $e->getMessage();
|
160 |
+
}
|
161 |
+
$fullResult['records'][] = $result;
|
162 |
+
}
|
163 |
+
|
164 |
+
return $fullResult;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param array $ordersData
|
169 |
+
* @return array
|
170 |
+
*/
|
171 |
+
public function orderClose($ordersData)
|
172 |
+
{
|
173 |
+
$fullResult = array();
|
174 |
+
$fullResult['records'] = array();
|
175 |
+
if (isset($ordersData['records'])) {
|
176 |
+
$ordersData = $ordersData['records'];
|
177 |
+
}
|
178 |
+
foreach ($ordersData as $orderData) {
|
179 |
+
try {
|
180 |
+
if (!empty($orderData['order_increment_id'])) {
|
181 |
+
$result = array(
|
182 |
+
'order_increment_id' => $orderData['order_increment_id']
|
183 |
+
);
|
184 |
+
/** @var Mage_Sales_Model_Order $order */
|
185 |
+
$order = Mage::getModel('sales/order');
|
186 |
+
$order->loadByIncrementId($orderData['order_increment_id']);
|
187 |
+
if (!$order->getId()) {
|
188 |
+
throw new Exception('Order is not found');
|
189 |
+
}
|
190 |
+
Mage::dispatchEvent(
|
191 |
+
'retailops_order_close_before',
|
192 |
+
array('order' => $order)
|
193 |
+
);
|
194 |
+
$items = $order->getAllItems();
|
195 |
+
$itemsToReturn = array();
|
196 |
+
$itemsToCancel = array();
|
197 |
+
$itemsToCapture = array();
|
198 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
199 |
+
foreach ($items as $item) {
|
200 |
+
$qtyToShip = $item->getQtyToShip();
|
201 |
+
$qtyToInvoice = $item->getQtyToInvoice();
|
202 |
+
if ($qtyToShip + $qtyToInvoice > 0) {
|
203 |
+
if ($qtyToShip < $qtyToInvoice) {
|
204 |
+
/**
|
205 |
+
* If we have shipped more items than invoiced, capture the difference
|
206 |
+
*/
|
207 |
+
$itemsToCapture[$item->getId()] = $qtyToInvoice - $qtyToShip;
|
208 |
+
} elseif ($qtyToShip > $qtyToInvoice) {
|
209 |
+
/**
|
210 |
+
* If we have invoiced more items than shipped, return the difference
|
211 |
+
*/
|
212 |
+
$itemsToReturn[$item->getId()] = $qtyToShip - $qtyToInvoice;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
if ($itemsToCapture) {
|
217 |
+
$result['invoice_result'] = $this->_createInvoiceAndCapture($order, $itemsToCapture);
|
218 |
+
}
|
219 |
+
if ($itemsToReturn) {
|
220 |
+
$result['creditmemo_result'] = $this->_getCreditMemoApi()->create($order, array('qtys' => $itemsToReturn));
|
221 |
+
}
|
222 |
+
/**
|
223 |
+
* Cancel the rest items if any
|
224 |
+
*/
|
225 |
+
$order->registerCancellation(Mage::helper('retailops_api')->__('No more items will be shipped'));
|
226 |
+
if (isset($orderData['retailops_status'])) {
|
227 |
+
$order->setRetailopsStatus($orderData['retailops_status']);
|
228 |
+
}
|
229 |
+
$order->save();
|
230 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
231 |
+
}
|
232 |
+
} catch (Exception $e) {
|
233 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
234 |
+
$result['message'] = $e->getMessage();
|
235 |
+
}
|
236 |
+
$fullResult['records'][] = $result;
|
237 |
+
}
|
238 |
+
|
239 |
+
return $fullResult;
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* @return RetailOps_Api_Model_Return_Api
|
244 |
+
*/
|
245 |
+
protected function _getCreditMemoApi()
|
246 |
+
{
|
247 |
+
return Mage::getModel('retailops_api/return_api');
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* @param Mage_Sales_Model_Order $order
|
252 |
+
* @param array $itemsQty
|
253 |
+
* @param string $comment
|
254 |
+
* @param bool $email
|
255 |
+
* @param bool $includeComment
|
256 |
+
* @return string
|
257 |
+
*/
|
258 |
+
protected function _createInvoiceAndCapture($order, $itemsQty, $comment = null, $email = false, $includeComment = false)
|
259 |
+
{
|
260 |
+
/** @var $helper RetailOps_Api_Helper_Data */
|
261 |
+
$helper = Mage::helper('retailops_api');
|
262 |
+
try {
|
263 |
+
$itemsQtyFomratted = array();
|
264 |
+
if ($itemsQty) {
|
265 |
+
foreach ($order->getAllItems() as $item) {
|
266 |
+
$itemsQtyFomratted[$item->getId()] = isset($itemsQty[$item->getId()]) ? $itemsQty[$item->getId()] : 0;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
$invoice = $order->prepareInvoice($itemsQtyFomratted);
|
270 |
+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
|
271 |
+
$invoice->register();
|
272 |
+
|
273 |
+
if ($comment !== null) {
|
274 |
+
$invoice->addComment($comment, $email);
|
275 |
+
}
|
276 |
+
|
277 |
+
if ($email) {
|
278 |
+
$invoice->setEmailSent(true);
|
279 |
+
}
|
280 |
+
|
281 |
+
$invoice->getOrder()->setIsInProcess(true);
|
282 |
+
|
283 |
+
|
284 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
285 |
+
->addObject($invoice)
|
286 |
+
->addObject($invoice->getOrder())
|
287 |
+
->save();
|
288 |
+
|
289 |
+
$invoice->sendEmail($email, ($includeComment ? $comment : ''));
|
290 |
+
|
291 |
+
$result['invoice'] = $helper->removeObjectsFromResult($this->_getAttributes($invoice, 'invoice'));
|
292 |
+
$result['items'] = array();
|
293 |
+
foreach ($invoice->getAllItems() as $item) {
|
294 |
+
$result['items'][] = $helper->removeObjectsFromResult($this->_getAttributes($item, 'invoice_item'));
|
295 |
+
}
|
296 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
297 |
+
} catch (Exception $e) {
|
298 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
299 |
+
$result['message'] = $e->getMessage();
|
300 |
+
}
|
301 |
+
|
302 |
+
return $result;
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Check that there are no items left for shipping
|
307 |
+
*
|
308 |
+
* @param Mage_Sales_Model_Order $order $order
|
309 |
+
* @return bool
|
310 |
+
*/
|
311 |
+
protected function _checkAllItemsShipped($order)
|
312 |
+
{
|
313 |
+
$items = $order->getAllItems();
|
314 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
315 |
+
foreach ($items as $item) {
|
316 |
+
if ($item->getQtyToShip()) {
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
return true;
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* @param Mage_Sales_Model_Resource_Order_Invoice_Collection $invoices
|
326 |
+
* @return array
|
327 |
+
*/
|
328 |
+
protected function _captureInvoices($invoices)
|
329 |
+
{
|
330 |
+
$result = array();
|
331 |
+
/** @var $invoice Mage_Sales_Model_Order_Invoice */
|
332 |
+
foreach ($invoices as $invoice) {
|
333 |
+
try {
|
334 |
+
$invoiceResult = array();
|
335 |
+
$invoiceResult['invoice_increment_id'] = $invoice->getIncrementId();
|
336 |
+
if (!$invoice->canCapture()) {
|
337 |
+
throw new Exception('Invoice cannot be captured.');
|
338 |
+
}
|
339 |
+
$invoice->capture();
|
340 |
+
$invoice->getOrder()->setIsInProcess(true);
|
341 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
342 |
+
->addObject($invoice)
|
343 |
+
->addObject($invoice->getOrder())
|
344 |
+
->save();
|
345 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
346 |
+
} catch (Exception $e) {
|
347 |
+
$invoiceResult['message'] = $e->getMessage();
|
348 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
349 |
+
}
|
350 |
+
$result[] = $invoiceResult;
|
351 |
+
}
|
352 |
+
|
353 |
+
return $result;
|
354 |
+
}
|
355 |
+
}
|
app/code/community/RetailOps/Api/Model/Shipment/Api.php.~84b644444a1b813b9b5956dbc9eeabb8577db950~
ADDED
@@ -0,0 +1,355 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_Shipment_Api extends Mage_Sales_Model_Order_Shipment_Api
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Creates shipment, adds track numbers, creates new invoices
|
30 |
+
*
|
31 |
+
* @param $shipments array
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function shipmentPush($shipments)
|
35 |
+
{
|
36 |
+
$fullResult = array();
|
37 |
+
$fullResult['records'] = array();
|
38 |
+
if (isset($shipments['records'])) {
|
39 |
+
$shipments = $shipments['records'];
|
40 |
+
}
|
41 |
+
foreach ($shipments as $shipmentData) {
|
42 |
+
$result = array();
|
43 |
+
try{
|
44 |
+
$shipment = new Varien_Object($shipmentData);
|
45 |
+
|
46 |
+
Mage::dispatchEvent(
|
47 |
+
'retailops_shipment_process_before',
|
48 |
+
array('record' => $shipment)
|
49 |
+
);
|
50 |
+
|
51 |
+
$result['order_increment_id'] = $shipment->getOrderIncrementId();
|
52 |
+
|
53 |
+
$orderIncrementId = $shipment->getOrderIncrementId();
|
54 |
+
$shipmentInfo = $shipment->getShipment();
|
55 |
+
$trackInfo = isset($shipmentInfo['track']) ? $shipmentInfo['track'] : array();
|
56 |
+
$invoiceInfo = isset($shipmentInfo['invoice']) ? $shipmentInfo['invoice'] : array();
|
57 |
+
$shipmentIncrementId = null;
|
58 |
+
// create shipment
|
59 |
+
try {
|
60 |
+
$shipmentResult = array();
|
61 |
+
$shipmentIncrementId = $this->create($orderIncrementId,
|
62 |
+
$shipmentInfo['qtys'],
|
63 |
+
$shipmentInfo['comment'],
|
64 |
+
$shipmentInfo['email'],
|
65 |
+
$shipmentInfo['include_comment']
|
66 |
+
);
|
67 |
+
|
68 |
+
if ($shipmentIncrementId) {
|
69 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
70 |
+
$shipmentResult['shipment_increment_id'] = $shipmentIncrementId;
|
71 |
+
} else {
|
72 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
73 |
+
$shipmentResult['message'] = Mage::helper('retailops_api')->__('Can not create shipment');
|
74 |
+
}
|
75 |
+
} catch (Mage_Core_Exception $e) {
|
76 |
+
$shipmentResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
77 |
+
$shipmentResult['message'] = $e->getCustomMessage() ? $e->getCustomMessage() : $e->getMessage();
|
78 |
+
}
|
79 |
+
|
80 |
+
$result['shipment_result'] = $shipmentResult;
|
81 |
+
if ($shipmentIncrementId) {
|
82 |
+
if ($trackInfo) {
|
83 |
+
$result['track_result'] = array();
|
84 |
+
foreach ($trackInfo as $track) {
|
85 |
+
// add shipment track
|
86 |
+
try {
|
87 |
+
$trackResult = array();
|
88 |
+
$track = new Varien_Object($track);
|
89 |
+
|
90 |
+
Mage::dispatchEvent(
|
91 |
+
'retailops_shipment_add_track_before',
|
92 |
+
array('record' => $track)
|
93 |
+
);
|
94 |
+
$trackResult['track_number'] = $track->getData('track_number');
|
95 |
+
|
96 |
+
$trackId = $this->addTrack($shipmentIncrementId,
|
97 |
+
$track->getData('carrier'),
|
98 |
+
$track->getData('title'),
|
99 |
+
$track->getData('track_number')
|
100 |
+
);
|
101 |
+
|
102 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
103 |
+
$trackResult['track_id'] = $trackId;
|
104 |
+
} catch (Mage_Core_Exception $e) {
|
105 |
+
$trackResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
106 |
+
$trackResult['message'] = $e->getMessage();
|
107 |
+
}
|
108 |
+
$result['track_result'][] = $trackResult;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
// create invoice
|
113 |
+
/** @var Mage_Sales_Model_Order $order */
|
114 |
+
$order = Mage::getModel('sales/order');
|
115 |
+
$order->loadByIncrementId($orderIncrementId);
|
116 |
+
$isFullyShipped = $this->_checkAllItemsShipped($order);
|
117 |
+
$invoices = $order->getInvoiceCollection();
|
118 |
+
$invoiceResult = array();
|
119 |
+
if ($order->canInvoice()) {
|
120 |
+
$itemsToInvoice = array();
|
121 |
+
if ($order->getPayment()->canCapturePartial()) {
|
122 |
+
/**
|
123 |
+
* If payment allows partial capture, trying to create invoice with shipped items only and capture it
|
124 |
+
*/
|
125 |
+
$itemsToInvoice = $shipmentInfo['qtys'];
|
126 |
+
}
|
127 |
+
if (($itemsToInvoice || $isFullyShipped) && $invoiceInfo) {
|
128 |
+
|
129 |
+
$invoice = new Varien_Object($invoiceInfo);
|
130 |
+
$invoice->setData('items_to_invoice', $itemsToInvoice);
|
131 |
+
|
132 |
+
Mage::dispatchEvent(
|
133 |
+
'retailops_shipment_invoice_before',
|
134 |
+
array('record' => $invoice)
|
135 |
+
);
|
136 |
+
|
137 |
+
$invoiceResult = $this->_createInvoiceAndCapture(
|
138 |
+
$order,
|
139 |
+
$invoice->getItemsToInvoice(),
|
140 |
+
$invoice->getComment(),
|
141 |
+
$invoice->getEmail(),
|
142 |
+
$invoice->getIncludeComment()
|
143 |
+
);
|
144 |
+
|
145 |
+
$invoiceResult = array($invoiceResult);
|
146 |
+
}
|
147 |
+
} else {
|
148 |
+
if ($isFullyShipped) {
|
149 |
+
/**
|
150 |
+
* Capturing all available invoices if all order items are shipped
|
151 |
+
*/
|
152 |
+
$invoiceResult = $this->_captureInvoices($invoices);
|
153 |
+
}
|
154 |
+
}
|
155 |
+
$result['invoice_result'] = $invoiceResult;
|
156 |
+
}
|
157 |
+
} catch (Exception $e) {
|
158 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
159 |
+
$result['message'] = $e->getMessage();
|
160 |
+
}
|
161 |
+
$fullResult['records'][] = $result;
|
162 |
+
}
|
163 |
+
|
164 |
+
return $fullResult;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param array $ordersData
|
169 |
+
* @return array
|
170 |
+
*/
|
171 |
+
public function orderClose($ordersData)
|
172 |
+
{
|
173 |
+
$fullResult = array();
|
174 |
+
$fullResult['records'] = array();
|
175 |
+
if (isset($ordersData['records'])) {
|
176 |
+
$ordersData = $ordersData['records'];
|
177 |
+
}
|
178 |
+
foreach ($ordersData as $orderData) {
|
179 |
+
try {
|
180 |
+
if (!empty($orderData['order_increment_id'])) {
|
181 |
+
$result = array(
|
182 |
+
'order_increment_id' => $orderData['order_increment_id']
|
183 |
+
);
|
184 |
+
/** @var Mage_Sales_Model_Order $order */
|
185 |
+
$order = Mage::getModel('sales/order');
|
186 |
+
$order->loadByIncrementId($orderData['order_increment_id']);
|
187 |
+
if (!$order->getId()) {
|
188 |
+
throw new Exception('Order is not found');
|
189 |
+
}
|
190 |
+
Mage::dispatchEvent(
|
191 |
+
'retailops_order_close_before',
|
192 |
+
array('order' => $order)
|
193 |
+
);
|
194 |
+
$items = $order->getAllItems();
|
195 |
+
$itemsToReturn = array();
|
196 |
+
$itemsToCancel = array();
|
197 |
+
$itemsToCapture = array();
|
198 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
199 |
+
foreach ($items as $item) {
|
200 |
+
$qtyToShip = $item->getQtyToShip();
|
201 |
+
$qtyToInvoice = $item->getQtyToInvoice();
|
202 |
+
if ($qtyToShip + $qtyToInvoice > 0) {
|
203 |
+
if ($qtyToShip < $qtyToInvoice) {
|
204 |
+
/**
|
205 |
+
* If we have shipped more items than invoiced, capture the difference
|
206 |
+
*/
|
207 |
+
$itemsToCapture[$item->getId()] = $qtyToInvoice - $qtyToShip;
|
208 |
+
} elseif ($qtyToShip > $qtyToInvoice) {
|
209 |
+
/**
|
210 |
+
* If we have invoiced more items than shipped, return the difference
|
211 |
+
*/
|
212 |
+
$itemsToReturn[$item->getId()] = $qtyToShip - $qtyToInvoice;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
if ($itemsToCapture) {
|
217 |
+
$result['invoice_result'] = $this->_createInvoiceAndCapture($order, $itemsToCapture);
|
218 |
+
}
|
219 |
+
if ($itemsToReturn) {
|
220 |
+
$result['creditmemo_result'] = $this->_getCreditMemoApi()->create($order, array('qtys' => $itemsToReturn));
|
221 |
+
}
|
222 |
+
/**
|
223 |
+
* Cancel the rest items if any
|
224 |
+
*/
|
225 |
+
$order->registerCancellation(Mage::helper('retailops_api')->__('No more items will be shipped'));
|
226 |
+
if (isset($orderData['retailops_status'])) {
|
227 |
+
$order->setRetailopsStatus($orderData['retailops_status']);
|
228 |
+
}
|
229 |
+
$order->save();
|
230 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
231 |
+
}
|
232 |
+
} catch (Exception $e) {
|
233 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
234 |
+
$result['message'] = $e->getMessage();
|
235 |
+
}
|
236 |
+
$fullResult['records'][] = $result;
|
237 |
+
}
|
238 |
+
|
239 |
+
return $fullResult;
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* @return RetailOps_Api_Model_Return_Api
|
244 |
+
*/
|
245 |
+
protected function _getCreditMemoApi()
|
246 |
+
{
|
247 |
+
return Mage::getModel('retailops_api/return_api');
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* @param Mage_Sales_Model_Order $order
|
252 |
+
* @param array $itemsQty
|
253 |
+
* @param string $comment
|
254 |
+
* @param bool $email
|
255 |
+
* @param bool $includeComment
|
256 |
+
* @return string
|
257 |
+
*/
|
258 |
+
protected function _createInvoiceAndCapture($order, $itemsQty, $comment = null, $email = false, $includeComment = false)
|
259 |
+
{
|
260 |
+
/** @var $helper RetailOps_Api_Helper_Data */
|
261 |
+
$helper = Mage::helper('retailops_api');
|
262 |
+
try {
|
263 |
+
$itemsQtyFomratted = array();
|
264 |
+
if ($itemsQty) {
|
265 |
+
foreach ($order->getAllItems() as $item) {
|
266 |
+
$itemsQtyFomratted[$item->getId()] = isset($itemsQty[$item->getId()]) ? $itemsQty[$item->getId()] : 0;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
$invoice = $order->prepareInvoice($itemsQtyFomratted);
|
270 |
+
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
|
271 |
+
$invoice->register();
|
272 |
+
|
273 |
+
if ($comment !== null) {
|
274 |
+
$invoice->addComment($comment, $email);
|
275 |
+
}
|
276 |
+
|
277 |
+
if ($email) {
|
278 |
+
$invoice->setEmailSent(true);
|
279 |
+
}
|
280 |
+
|
281 |
+
$invoice->getOrder()->setIsInProcess(true);
|
282 |
+
|
283 |
+
|
284 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
285 |
+
->addObject($invoice)
|
286 |
+
->addObject($invoice->getOrder())
|
287 |
+
->save();
|
288 |
+
|
289 |
+
$invoice->sendEmail($email, ($includeComment ? $comment : ''));
|
290 |
+
|
291 |
+
$result['invoice'] = $helper->removeObjectsFromResult($this->_getAttributes($invoice, 'invoice'));
|
292 |
+
$result['items'] = array();
|
293 |
+
foreach ($invoice->getAllItems() as $item) {
|
294 |
+
$result['items'][] = $helper->removeObjectsFromResult($this->_getAttributes($item, 'invoice_item'));
|
295 |
+
}
|
296 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
297 |
+
} catch (Exception $e) {
|
298 |
+
$result['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
299 |
+
$result['message'] = $e->getMessage();
|
300 |
+
}
|
301 |
+
|
302 |
+
return $result;
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Check that there are no items left for shipping
|
307 |
+
*
|
308 |
+
* @param Mage_Sales_Model_Order $order $order
|
309 |
+
* @return bool
|
310 |
+
*/
|
311 |
+
protected function _checkAllItemsShipped($order)
|
312 |
+
{
|
313 |
+
$items = $order->getAllItems();
|
314 |
+
/** @var $item Mage_Sales_Model_Order_Item */
|
315 |
+
foreach ($items as $item) {
|
316 |
+
if ($item->getQtyToShip()) {
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
return true;
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* @param Mage_Sales_Model_Resource_Order_Invoice_Collection $invoices
|
326 |
+
* @return array
|
327 |
+
*/
|
328 |
+
protected function _captureInvoices($invoices)
|
329 |
+
{
|
330 |
+
$result = array();
|
331 |
+
/** @var $invoice Mage_Sales_Model_Order_Invoice */
|
332 |
+
foreach ($invoices as $invoice) {
|
333 |
+
try {
|
334 |
+
$invoiceResult = array();
|
335 |
+
$invoiceResult['invoice_increment_id'] = $invoice->getIncrementId();
|
336 |
+
if ($invoice->canCapture()) {
|
337 |
+
throw new Exception('Invoice cannot be captured.');
|
338 |
+
}
|
339 |
+
$invoice->capture();
|
340 |
+
$invoice->getOrder()->setIsInProcess(true);
|
341 |
+
$transactionSave = Mage::getModel('core/resource_transaction')
|
342 |
+
->addObject($invoice)
|
343 |
+
->addObject($invoice->getOrder())
|
344 |
+
->save();
|
345 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_SUCCESS;
|
346 |
+
} catch (Exception $e) {
|
347 |
+
$invoiceResult['message'] = $e->getMessage();
|
348 |
+
$invoiceResult['status'] = RetailOps_Api_Helper_Data::API_STATUS_FAIL;
|
349 |
+
}
|
350 |
+
$result[] = $invoiceResult;
|
351 |
+
}
|
352 |
+
|
353 |
+
return $result;
|
354 |
+
}
|
355 |
+
}
|
app/code/community/RetailOps/Api/Model/System/Config/Source/Catalog/AttributeSet.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Model_System_Config_Source_Catalog_AttributeSet
|
27 |
+
{
|
28 |
+
protected $_options;
|
29 |
+
|
30 |
+
public function toOptionArray()
|
31 |
+
{
|
32 |
+
if (!$this->_options) {
|
33 |
+
$entityType = Mage::getModel('eav/entity')->setType(Mage_Catalog_Model_Product::ENTITY)->getTypeId();
|
34 |
+
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
|
35 |
+
->setEntityTypeFilter($entityType);
|
36 |
+
$this->_options = $collection->load()->toOptionArray();
|
37 |
+
}
|
38 |
+
|
39 |
+
return $this->_options;
|
40 |
+
}
|
41 |
+
}
|
app/code/community/RetailOps/Api/controllers/Adminhtml/Sales/OrderController.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
class RetailOps_Api_Adminhtml_Sales_OrderController extends Mage_Adminhtml_Sales_OrderController
|
27 |
+
{
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Add order comment action
|
31 |
+
*/
|
32 |
+
public function saveRetailOpsInfoAction()
|
33 |
+
{
|
34 |
+
if ($order = $this->_initOrder()) {
|
35 |
+
try {
|
36 |
+
$response = false;
|
37 |
+
$data = $this->getRequest()->getPost('retops');
|
38 |
+
|
39 |
+
$order->setRetailopsStatus($data['status']);
|
40 |
+
$order->save();
|
41 |
+
|
42 |
+
$history = Mage::getModel('retailops_api/order_status_history')
|
43 |
+
->setOrder($order)
|
44 |
+
->setComment($data['comment'])
|
45 |
+
->save();
|
46 |
+
|
47 |
+
$this->loadLayout('empty');
|
48 |
+
$this->renderLayout();
|
49 |
+
}
|
50 |
+
catch (Mage_Core_Exception $e) {
|
51 |
+
$response = array(
|
52 |
+
'error' => true,
|
53 |
+
'message' => $e->getMessage(),
|
54 |
+
);
|
55 |
+
}
|
56 |
+
catch (Exception $e) {
|
57 |
+
$response = array(
|
58 |
+
'error' => true,
|
59 |
+
'message' => $this->__('Cannot add order history.')
|
60 |
+
);
|
61 |
+
}
|
62 |
+
if (is_array($response)) {
|
63 |
+
$response = Mage::helper('core')->jsonEncode($response);
|
64 |
+
$this->getResponse()->setBody($response);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
app/code/community/RetailOps/Api/etc/adminhtml.xml
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<acl>
|
27 |
+
<resources>
|
28 |
+
<admin>
|
29 |
+
<children>
|
30 |
+
<system>
|
31 |
+
<children>
|
32 |
+
<config>
|
33 |
+
<children>
|
34 |
+
<retailops_settings translate="title" module="retailops_api">
|
35 |
+
<title>RetailOps Api Settings</title>
|
36 |
+
</retailops_settings>
|
37 |
+
</children>
|
38 |
+
</config>
|
39 |
+
</children>
|
40 |
+
</system>
|
41 |
+
</children>
|
42 |
+
</admin>
|
43 |
+
</resources>
|
44 |
+
</acl>
|
45 |
+
</config>
|
app/code/community/RetailOps/Api/etc/api.xml
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<api>
|
27 |
+
<resources>
|
28 |
+
<retailops translate="title" module="retailops_api">
|
29 |
+
<title>RetailOps API</title>
|
30 |
+
<model>retailops_api/api</model>
|
31 |
+
<acl>retailops</acl><!-- acl resource alias -->
|
32 |
+
<methods><!-- definne the methods -->
|
33 |
+
<catalog_pull translate="title" module="retailops_api">
|
34 |
+
<title>Retrieve list of products</title>
|
35 |
+
<method>catalogPull</method>
|
36 |
+
<acl>retailops/catalog_pull</acl>
|
37 |
+
</catalog_pull>
|
38 |
+
<catalog_push translate="title" module="retailops_api">
|
39 |
+
<title>Create/update products</title>
|
40 |
+
<method>catalogPush</method>
|
41 |
+
<acl>retailops/catalog_push</acl>
|
42 |
+
</catalog_push>
|
43 |
+
<return_push translate="title" module="retailops_api">
|
44 |
+
<title>Create Credit Memo</title>
|
45 |
+
<method>returnPush</method>
|
46 |
+
<acl>retailops/return_push</acl>
|
47 |
+
</return_push>
|
48 |
+
<order_pull translate="title" module="retailops_api">
|
49 |
+
<title>Retrieve list of orders</title>
|
50 |
+
<method>orderPull</method>
|
51 |
+
<acl>retailops/order_pull</acl>
|
52 |
+
</order_pull>
|
53 |
+
<inventory_push translate="title" module="retailops_api">
|
54 |
+
<title>Update product inventory</title>
|
55 |
+
<method>inventoryPush</method>
|
56 |
+
<acl>retailops/inventory_push</acl>
|
57 |
+
</inventory_push>
|
58 |
+
<shipment_push translate="title" module="retailops_api">
|
59 |
+
<title>Create Shipments</title>
|
60 |
+
<method>shipmentPush</method>
|
61 |
+
<acl>retailops/shipment_push</acl>
|
62 |
+
</shipment_push>
|
63 |
+
<order_close translate="title" module="retailops_api">
|
64 |
+
<title>Order Close</title>
|
65 |
+
<method>orderClose</method>
|
66 |
+
<acl>retailops/shipment_push</acl>
|
67 |
+
</order_close>
|
68 |
+
<order_status_update translate="title" module="retailops_api">
|
69 |
+
<title>Order Status Update</title>
|
70 |
+
<method>orderStatusUpdate</method>
|
71 |
+
<acl>retailops/order_pull</acl>
|
72 |
+
</order_status_update>
|
73 |
+
</methods>
|
74 |
+
<faults module="retailops_api"><!-- errors that might appear-->
|
75 |
+
</faults>
|
76 |
+
</retailops>
|
77 |
+
</resources>
|
78 |
+
<acl><!-- acl definition -->
|
79 |
+
<resources>
|
80 |
+
<retailops translate="title" module="retailops_api">
|
81 |
+
<title>Retailops</title>
|
82 |
+
<sort_order>120</sort_order>
|
83 |
+
<catalog_pull translate="title" module="retailops_api">
|
84 |
+
<title>Catalog Pull</title>
|
85 |
+
</catalog_pull>
|
86 |
+
<catalog_push translate="title" module="retailops_api">
|
87 |
+
<title>Catalog Push</title>
|
88 |
+
</catalog_push>
|
89 |
+
<inventory_push translate="title" module="retailops_api">
|
90 |
+
<title>Inventory Push</title>
|
91 |
+
</inventory_push>
|
92 |
+
<order_pull translate="title" module="retailops_api">
|
93 |
+
<title>Order Pull</title>
|
94 |
+
</order_pull>
|
95 |
+
<order_update translate="title" module="retailops_api">
|
96 |
+
<title>Order Update</title>
|
97 |
+
</order_update>
|
98 |
+
<return_push translate="title" module="retailops_api">
|
99 |
+
<title>Return Push</title>
|
100 |
+
</return_push>
|
101 |
+
<shipment_push translate="title" module="retailops_api">
|
102 |
+
<title>Shipment Push</title>
|
103 |
+
</shipment_push>
|
104 |
+
</retailops>
|
105 |
+
</resources>
|
106 |
+
</acl>
|
107 |
+
</api>
|
108 |
+
</config>
|
app/code/community/RetailOps/Api/etc/config.xml
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<modules>
|
27 |
+
<RetailOps_Api>
|
28 |
+
<version>1.0.3</version>
|
29 |
+
</RetailOps_Api>
|
30 |
+
</modules>
|
31 |
+
<global>
|
32 |
+
<helpers>
|
33 |
+
<retailops_api>
|
34 |
+
<class>RetailOps_Api_Helper</class>
|
35 |
+
</retailops_api>
|
36 |
+
</helpers>
|
37 |
+
<models>
|
38 |
+
<retailops_api>
|
39 |
+
<class>RetailOps_Api_Model</class>
|
40 |
+
<resourceModel>retailops_api_resource</resourceModel>
|
41 |
+
</retailops_api>
|
42 |
+
<retailops_api_resource>
|
43 |
+
<class>RetailOps_Api_Model_Resource</class>
|
44 |
+
<entities>
|
45 |
+
<order_status_history>
|
46 |
+
<table>retailops_order_status_history</table>
|
47 |
+
</order_status_history>
|
48 |
+
<media_import>
|
49 |
+
<table>retailops_media_import</table>
|
50 |
+
</media_import>
|
51 |
+
</entities>
|
52 |
+
</retailops_api_resource>
|
53 |
+
</models>
|
54 |
+
<blocks>
|
55 |
+
<retailops_api>
|
56 |
+
<class>RetailOps_Api_Block</class>
|
57 |
+
</retailops_api>
|
58 |
+
</blocks>
|
59 |
+
<resources>
|
60 |
+
<retailops_api_setup>
|
61 |
+
<setup>
|
62 |
+
<module>RetailOps_Api</module>
|
63 |
+
<class>Mage_Core_Model_Resource_Setup</class>
|
64 |
+
</setup>
|
65 |
+
</retailops_api_setup>
|
66 |
+
</resources>
|
67 |
+
<events>
|
68 |
+
<sales_order_payment_place_end>
|
69 |
+
<observers>
|
70 |
+
<update_retailops_status>
|
71 |
+
<class>retailops_api/observer</class>
|
72 |
+
<method>updateRetailopsStatus</method>
|
73 |
+
</update_retailops_status>
|
74 |
+
</observers>
|
75 |
+
</sales_order_payment_place_end>
|
76 |
+
</events>
|
77 |
+
</global>
|
78 |
+
<admin>
|
79 |
+
<routers>
|
80 |
+
<adminhtml>
|
81 |
+
<args>
|
82 |
+
<modules>
|
83 |
+
<RetailOps_Api after="Mage_Adminhtml">RetailOps_Api_Adminhtml</RetailOps_Api>
|
84 |
+
</modules>
|
85 |
+
</args>
|
86 |
+
</adminhtml>
|
87 |
+
</routers>
|
88 |
+
</admin>
|
89 |
+
<adminhtml>
|
90 |
+
<layout>
|
91 |
+
<updates>
|
92 |
+
<retailops_api>
|
93 |
+
<file>retailops.xml</file>
|
94 |
+
</retailops_api>
|
95 |
+
</updates>
|
96 |
+
</layout>
|
97 |
+
</adminhtml>
|
98 |
+
<frontend>
|
99 |
+
</frontend>
|
100 |
+
<crontab>
|
101 |
+
<jobs>
|
102 |
+
<retailops_media_download>
|
103 |
+
<schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
|
104 |
+
<run>
|
105 |
+
<model>retailops_api/observer::downloadProductImages</model>
|
106 |
+
</run>
|
107 |
+
</retailops_media_download>
|
108 |
+
</jobs>
|
109 |
+
</crontab>
|
110 |
+
<default>
|
111 |
+
<retailops_settings>
|
112 |
+
<catalog>
|
113 |
+
<media_processing_products_limit>10</media_processing_products_limit>
|
114 |
+
</catalog>
|
115 |
+
</retailops_settings>
|
116 |
+
</default>
|
117 |
+
</config>
|
app/code/community/RetailOps/Api/etc/config.xml~
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<modules>
|
27 |
+
<RetailOps_Api>
|
28 |
+
<version>1.0.3</version>
|
29 |
+
</RetailOps_Api>
|
30 |
+
</modules>
|
31 |
+
<global>
|
32 |
+
<helpers>
|
33 |
+
<retailops_api>
|
34 |
+
<class>RetailOps_Api_Helper</class>
|
35 |
+
</retailops_api>
|
36 |
+
</helpers>
|
37 |
+
<models>
|
38 |
+
<retailops_api>
|
39 |
+
<class>RetailOps_Api_Model</class>
|
40 |
+
<resourceModel>retailops_api_resource</resourceModel>
|
41 |
+
</retailops_api>
|
42 |
+
<retailops_api_resource>
|
43 |
+
<class>RetailOps_Api_Model_Resource</class>
|
44 |
+
<entities>
|
45 |
+
<order_status_history>
|
46 |
+
<table>retailops_order_status_history</table>
|
47 |
+
</order_status_history>
|
48 |
+
<media_import>
|
49 |
+
<table>retailops_media_import</table>
|
50 |
+
</media_import>
|
51 |
+
</entities>
|
52 |
+
</retailops_api_resource>
|
53 |
+
</models>
|
54 |
+
<blocks>
|
55 |
+
<retailops_api>
|
56 |
+
<class>RetailOps_Api_Block</class>
|
57 |
+
</retailops_api>
|
58 |
+
</blocks>
|
59 |
+
<resources>
|
60 |
+
<retailops_api_setup>
|
61 |
+
<setup>
|
62 |
+
<module>RetailOps_Api</module>
|
63 |
+
<class>Mage_Core_Model_Resource_Setup</class>
|
64 |
+
</setup>
|
65 |
+
</retailops_api_setup>
|
66 |
+
</resources>
|
67 |
+
<events>
|
68 |
+
<sales_order_payment_place_end>
|
69 |
+
<observers>
|
70 |
+
<update_retailops_status>
|
71 |
+
<class>retailops_api/observer</class>
|
72 |
+
<method>updateRetailopsStatus</method>
|
73 |
+
</update_retailops_status>
|
74 |
+
</observers>
|
75 |
+
</sales_order_payment_place_end>
|
76 |
+
</events>
|
77 |
+
</global>
|
78 |
+
<admin>
|
79 |
+
<routers>
|
80 |
+
<adminhtml>
|
81 |
+
<args>
|
82 |
+
<modules>
|
83 |
+
<RetailOps_Api after="Mage_Adminhtml">RetailOps_Api_Adminhtml</RetailOps_Api>
|
84 |
+
</modules>
|
85 |
+
</args>
|
86 |
+
</adminhtml>
|
87 |
+
</routers>
|
88 |
+
</admin>
|
89 |
+
<adminhtml>
|
90 |
+
<layout>
|
91 |
+
<updates>
|
92 |
+
<retailops_api>
|
93 |
+
<file>retailops.xml</file>
|
94 |
+
</retailops_api>
|
95 |
+
</updates>
|
96 |
+
</layout>
|
97 |
+
</adminhtml>
|
98 |
+
<frontend>
|
99 |
+
</frontend>
|
100 |
+
<crontab>
|
101 |
+
<jobs>
|
102 |
+
<retailops_media_download>
|
103 |
+
<schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
|
104 |
+
<run>
|
105 |
+
<model>retailops_api/observer::downloadProductImages</model>
|
106 |
+
</run>
|
107 |
+
</retailops_media_download>
|
108 |
+
</jobs>
|
109 |
+
</crontab>
|
110 |
+
<default>
|
111 |
+
<retailops_settings>
|
112 |
+
<catalog>
|
113 |
+
<media_processing_products_limit>10</media_processing_products_limit>
|
114 |
+
</catalog>
|
115 |
+
</retailops_settings>
|
116 |
+
</default>
|
117 |
+
</config>
|
app/code/community/RetailOps/Api/etc/system.xml
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<tabs>
|
27 |
+
<retailops translate="label" module="retailops_api">
|
28 |
+
<label>RetailOps</label>
|
29 |
+
<sort_order>250</sort_order>
|
30 |
+
</retailops>
|
31 |
+
</tabs>
|
32 |
+
<sections>
|
33 |
+
<retailops_settings translate="label" module="retailops_api">
|
34 |
+
<class>separator-top</class>
|
35 |
+
<label>Settings</label>
|
36 |
+
<tab>retailops</tab>
|
37 |
+
<frontend_type>text</frontend_type>
|
38 |
+
<sort_order>40</sort_order>
|
39 |
+
<show_in_default>1</show_in_default>
|
40 |
+
<show_in_website>1</show_in_website>
|
41 |
+
<show_in_store>1</show_in_store>
|
42 |
+
<groups>
|
43 |
+
<catalog translate="label">
|
44 |
+
<label>Catalog</label>
|
45 |
+
<frontend_type>text</frontend_type>
|
46 |
+
<sort_order>100</sort_order>
|
47 |
+
<show_in_default>1</show_in_default>
|
48 |
+
<show_in_website>0</show_in_website>
|
49 |
+
<show_in_store>0</show_in_store>
|
50 |
+
<fields>
|
51 |
+
<default_attribute_set translate="label">
|
52 |
+
<label>Default Attribute Set To Extend</label>
|
53 |
+
<frontend_type>select</frontend_type>
|
54 |
+
<source_model>retailops_api/system_config_source_catalog_attributeSet</source_model>
|
55 |
+
<sort_order>1</sort_order>
|
56 |
+
<show_in_default>1</show_in_default>
|
57 |
+
<show_in_website>0</show_in_website>
|
58 |
+
<show_in_store>0</show_in_store>
|
59 |
+
</default_attribute_set>
|
60 |
+
<media_processing_products_limit>
|
61 |
+
<label>Limit to process media data for products by a cron job</label>
|
62 |
+
<frontend_type>text</frontend_type>
|
63 |
+
<sort_order>1</sort_order>
|
64 |
+
<show_in_default>1</show_in_default>
|
65 |
+
<show_in_website>0</show_in_website>
|
66 |
+
<show_in_store>0</show_in_store>
|
67 |
+
</media_processing_products_limit>
|
68 |
+
</fields>
|
69 |
+
</catalog>
|
70 |
+
</groups>
|
71 |
+
</retailops_settings>
|
72 |
+
</sections>
|
73 |
+
</config>
|
74 |
+
|
app/code/community/RetailOps/Api/sql/retailops_api_setup/install-1.0.0.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
$installer = $this;
|
27 |
+
|
28 |
+
$installer->startSetup();
|
29 |
+
|
30 |
+
$installer->getConnection()
|
31 |
+
->addColumn($installer->getTable('sales/order'),
|
32 |
+
'retailops_status',
|
33 |
+
array(
|
34 |
+
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
|
35 |
+
'length' => 255,
|
36 |
+
'comment' => 'RetailOps Order Status'
|
37 |
+
));
|
38 |
+
$installer->getConnection()
|
39 |
+
->addIndex($installer->getTable('sales/order'),
|
40 |
+
$installer->getIdxName('sales/order', array('retailops_status')),
|
41 |
+
array('retailops_status')
|
42 |
+
);
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Create table 'retail_ops/order_status_history'
|
46 |
+
*/
|
47 |
+
$table = $installer->getConnection()
|
48 |
+
->newTable($installer->getTable('retailops_api/order_status_history'))
|
49 |
+
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
50 |
+
'identity' => true,
|
51 |
+
'unsigned' => true,
|
52 |
+
'nullable' => false,
|
53 |
+
'primary' => true,
|
54 |
+
), 'Entity Id')
|
55 |
+
->addColumn('parent_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
56 |
+
'unsigned' => true,
|
57 |
+
'nullable' => false,
|
58 |
+
), 'Parent Id')
|
59 |
+
->addColumn('comment', Varien_Db_Ddl_Table::TYPE_TEXT, '64k', array(
|
60 |
+
), 'Comment')
|
61 |
+
->addColumn('status', Varien_Db_Ddl_Table::TYPE_TEXT, 32, array(
|
62 |
+
), 'Status')
|
63 |
+
->addColumn('created_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
|
64 |
+
), 'Created At')
|
65 |
+
->addIndex($installer->getIdxName('retailops_api/order_status_history', array('parent_id')),
|
66 |
+
array('parent_id'))
|
67 |
+
->addIndex($installer->getIdxName('retailops_api/order_status_history', array('created_at')),
|
68 |
+
array('created_at'))
|
69 |
+
->addIndex($installer->getIdxName('retailops_api/order_status_history', array('status')),
|
70 |
+
array('status'))
|
71 |
+
->addForeignKey($installer->getFkName('retailops_api/order_status_history', 'parent_id', 'sales/order', 'entity_id'),
|
72 |
+
'parent_id', $installer->getTable('sales/order'), 'entity_id',
|
73 |
+
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
74 |
+
->setComment('Sales Flat Order Status History');
|
75 |
+
|
76 |
+
$installer->getConnection()->createTable($table);
|
77 |
+
|
78 |
+
$installer->endSetup();
|
app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.0-1.0.1.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
$installer = $this;
|
27 |
+
|
28 |
+
$installer->startSetup();
|
29 |
+
|
30 |
+
$installer->getConnection()
|
31 |
+
->addColumn($installer->getTable('catalog/product_attribute_media_gallery'),
|
32 |
+
'retailops_mediakey',
|
33 |
+
array(
|
34 |
+
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
|
35 |
+
'length' => 255,
|
36 |
+
'comment' => 'RetailOps Mediakey'
|
37 |
+
));
|
38 |
+
$installer->getConnection()
|
39 |
+
->addIndex($installer->getTable('catalog/product_attribute_media_gallery'),
|
40 |
+
$installer->getIdxName('catalog/product_attribute_media_gallery', array('retailops_mediakey')),
|
41 |
+
array('retailops_mediakey')
|
42 |
+
);
|
43 |
+
|
44 |
+
$installer->endSetup();
|
app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.1-1.0.2.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
$installer = $this;
|
27 |
+
|
28 |
+
$installer->startSetup();
|
29 |
+
|
30 |
+
$table = $installer->getConnection()
|
31 |
+
->newTable($installer->getTable('retailops_api/media_import'))
|
32 |
+
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
33 |
+
'identity' => true,
|
34 |
+
'unsigned' => true,
|
35 |
+
'nullable' => false,
|
36 |
+
'primary' => true,
|
37 |
+
), 'Entity Id')
|
38 |
+
->addColumn('product_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
39 |
+
'unsigned' => true,
|
40 |
+
'nullable' => false,
|
41 |
+
), 'Product Id')
|
42 |
+
->addColumn('unset_other_media', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
|
43 |
+
), 'Unset other media flag')
|
44 |
+
->addColumn('media_data', Varien_Db_Ddl_Table::TYPE_TEXT, '64k', array(
|
45 |
+
), 'Full Media Data')
|
46 |
+
->addForeignKey($installer->getFkName('retailops_api/media_import', 'product_id', 'catalog/product', 'entity_id'),
|
47 |
+
'product_id', $installer->getTable('catalog/product'), 'entity_id',
|
48 |
+
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
49 |
+
->setComment('RetailOps Media Update Table');
|
50 |
+
|
51 |
+
$installer->getConnection()->createTable($table);
|
52 |
+
|
53 |
+
$installer->endSetup();
|
app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.2-1.0.3.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
$installer = $this;
|
27 |
+
|
28 |
+
$installer->startSetup();
|
29 |
+
|
30 |
+
$installer->getConnection()
|
31 |
+
->addColumn($installer->getTable('sales/shipment'),
|
32 |
+
'retailops_shipment_id',
|
33 |
+
array(
|
34 |
+
'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
|
35 |
+
'length' => 10,
|
36 |
+
'unsigned' => true,
|
37 |
+
'comment' => 'RetailOps Shipment ID',
|
38 |
+
'nullable' => true,
|
39 |
+
));
|
40 |
+
|
41 |
+
$installer->endSetup();
|
42 |
+
|
app/code/community/RetailOps/Api/sql/retailops_api_setup/upgrade-1.0.2-1.0.3.php~
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
*/
|
25 |
+
|
26 |
+
$installer = $this;
|
27 |
+
|
28 |
+
$installer->startSetup();
|
29 |
+
|
30 |
+
$table = $installer->getConnection()
|
31 |
+
->newTable($installer->getTable('retailops_api/media_import'))
|
32 |
+
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
33 |
+
'identity' => true,
|
34 |
+
'unsigned' => true,
|
35 |
+
'nullable' => false,
|
36 |
+
'primary' => true,
|
37 |
+
), 'Entity Id')
|
38 |
+
->addColumn('product_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
39 |
+
'unsigned' => true,
|
40 |
+
'nullable' => false,
|
41 |
+
), 'Product Id')
|
42 |
+
->addColumn('unset_other_media', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
|
43 |
+
), 'Unset other media flag')
|
44 |
+
->addColumn('media_data', Varien_Db_Ddl_Table::TYPE_TEXT, '64k', array(
|
45 |
+
), 'Full Media Data')
|
46 |
+
->addForeignKey($installer->getFkName('retailops_api/media_import', 'product_id', 'catalog/product', 'entity_id'),
|
47 |
+
'product_id', $installer->getTable('catalog/product'), 'entity_id',
|
48 |
+
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
49 |
+
->setComment('RetailOps Media Update Table');
|
50 |
+
|
51 |
+
$installer->getConnection()->createTable($table);
|
52 |
+
|
53 |
+
$installer->endSetup();
|
app/code/community/RetailOps/Model/Observer.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class RetailOps_Model_Observer
|
4 |
+
{
|
5 |
+
/*
|
6 |
+
* Transfer MyGiftCardPlugin amount to 'gift_cards_amount' for RetailOps Orders
|
7 |
+
*/
|
8 |
+
public function transferMyGiftCardValue(Varien_Event_Observer $observer) {
|
9 |
+
file_put_contents('/tmp/magento_gift_card_test', "transferMyGiftCardValue observer " . var_export($observer, TRUE) . "\n", FILE_APPEND);
|
10 |
+
$record = $observer->getEvent()->getRecord();
|
11 |
+
$orderInfo = $record->getOrderInfo();
|
12 |
+
// $orderInfo->setGiftCardsAmount($orderInfo->getMyGiftCardAmount());
|
13 |
+
$orderInfo->setGiftCardsAmount('100');
|
14 |
+
$record->setOrderInfo($orderInfo);
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
?>
|
app/code/community/RetailOps/Model/Observer.php~
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Acme_Model_Observer
|
4 |
+
{
|
5 |
+
/*
|
6 |
+
* Transfer MyGiftCardPlugin amount to 'gift_cards_amount' for RetailOps Orders
|
7 |
+
*/
|
8 |
+
public function transferMyGiftCardValue(Varien_Event_Observer $observer) {
|
9 |
+
$record = $observer->getEvent()->getRecord();
|
10 |
+
$orderInfo = $record->getOrderInfo();
|
11 |
+
// $orderInfo->setGiftCardsAmount($orderInfo->getMyGiftCardAmount());
|
12 |
+
$orderInfo->setGiftCardsAmount('100');
|
13 |
+
$record->setOrderInfo($orderInfo);
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
?>
|
app/design/adminhtml/default/default/layout/retailops.xml
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<layout>
|
26 |
+
<adminhtml_sales_order_view>
|
27 |
+
<reference name="sales_order_tabs">
|
28 |
+
<action method="addTab"><name>retailops_info</name><block>retailops_api/adminhtml_sales_order_view_tab_retailops</block></action>
|
29 |
+
</reference>
|
30 |
+
</adminhtml_sales_order_view>
|
31 |
+
|
32 |
+
<adminhtml_sales_order_saveretailopsinfo>
|
33 |
+
<block type="retailops_api/adminhtml_sales_order_view_tab_retailops"
|
34 |
+
name="retailops_info"
|
35 |
+
template="retailops/order/view/tab/retailops.phtml"
|
36 |
+
output="toHtml"
|
37 |
+
/>
|
38 |
+
</adminhtml_sales_order_saveretailopsinfo>
|
39 |
+
</layout>
|
app/design/adminhtml/default/default/template/retailops/order/view/tab/retailops.phtml
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!--
|
2 |
+
The MIT License (MIT)
|
3 |
+
|
4 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
5 |
+
|
6 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
+
of this software and associated documentation files (the "Software"), to deal
|
8 |
+
in the Software without restriction, including without limitation the rights
|
9 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 |
+
copies of the Software, and to permit persons to whom the Software is
|
11 |
+
furnished to do so, subject to the following conditions:
|
12 |
+
|
13 |
+
The above copyright notice and this permission notice shall be included in
|
14 |
+
all copies or substantial portions of the Software.
|
15 |
+
|
16 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
+
THE SOFTWARE.
|
23 |
+
-->
|
24 |
+
<div class="entry-edit" id="retops-info">
|
25 |
+
<div class="entry-edit-head">
|
26 |
+
<h4><?php echo $this->__('RetailOps'); ?></h4>
|
27 |
+
</div>
|
28 |
+
<div class="fieldset fieldset-wide">
|
29 |
+
<div id="status_form" class="order-history-form">
|
30 |
+
<span class="field-row">
|
31 |
+
<label class="normal" for="history_status"><?php echo Mage::helper('sales')->__('Status') ?></label><br/>
|
32 |
+
<select name="retops[status]" class="select" id="retops_status">
|
33 |
+
<?php foreach ($this->getStatuses() as $_code=>$_label): ?>
|
34 |
+
<option value="<?php echo $_code ?>"<?php if($_code==$this->getOrder()->getRetailopsStatus()): ?> selected="selected"<?php endif; ?>><?php echo $_label ?></option>
|
35 |
+
<?php endforeach; ?>
|
36 |
+
</select>
|
37 |
+
</span>
|
38 |
+
<span class="field-row">
|
39 |
+
<label class="normal" for="status_comment"><?php echo Mage::helper('sales')->__('Comment') ?></label>
|
40 |
+
<textarea name="retops[comment]" rows="3" cols="5" style="height:6em; width:99%;" id="retops_comment"><?php echo $this->getOrder()->getRetailopsStatusComment() ?></textarea>
|
41 |
+
</span>
|
42 |
+
<div class="f-right">
|
43 |
+
<?php echo $this->getChildHtml('submit_button') ?>
|
44 |
+
</div>
|
45 |
+
<div class="clear"></div>
|
46 |
+
</div>
|
47 |
+
</div>
|
48 |
+
<div class="divider"></div>
|
49 |
+
<ul class="note-list">
|
50 |
+
<?php foreach ($this->getRetailOpsStatusHistory() as $_item): ?>
|
51 |
+
<li>
|
52 |
+
<strong><?php echo $this->helper('core')->formatDate($_item->getCreatedAt(), 'medium') ?></strong>
|
53 |
+
<?php echo $this->helper('core')->formatTime($_item->getCreatedAt(), 'medium') ?><span class="separator">|</span><strong><?php echo $_item->getStatus() ?></strong>
|
54 |
+
<?php if ($_item->getComment()): ?>
|
55 |
+
<br/><?php echo $this->escapeHtml($_item->getComment(), array('b', 'br', 'strong', 'i', 'u', 'a')) ?>
|
56 |
+
<?php endif; ?>
|
57 |
+
</li>
|
58 |
+
<?php endforeach; ?>
|
59 |
+
</ul>
|
60 |
+
</div>
|
app/etc/modules/RetailOps_Api.xml
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
The MIT License (MIT)
|
4 |
+
|
5 |
+
Copyright (c) 2015 Gud Technologies Incorporated (RetailOps by GüdTech)
|
6 |
+
|
7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8 |
+
of this software and associated documentation files (the "Software"), to deal
|
9 |
+
in the Software without restriction, including without limitation the rights
|
10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
copies of the Software, and to permit persons to whom the Software is
|
12 |
+
furnished to do so, subject to the following conditions:
|
13 |
+
|
14 |
+
The above copyright notice and this permission notice shall be included in
|
15 |
+
all copies or substantial portions of the Software.
|
16 |
+
|
17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23 |
+
THE SOFTWARE.
|
24 |
+
-->
|
25 |
+
<config>
|
26 |
+
<modules>
|
27 |
+
<RetailOps_Api>
|
28 |
+
<active>true</active>
|
29 |
+
<codePool>community</codePool>
|
30 |
+
<depends>
|
31 |
+
<Mage_Core/>
|
32 |
+
</depends>
|
33 |
+
</RetailOps_Api>
|
34 |
+
</modules>
|
35 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>RetailOps_Api</name>
|
4 |
+
<version>1.0.3</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="https://opensource.org/licenses/MIT">MIT</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Seamless integration with the RetailOps distributed order management platform</summary>
|
10 |
+
<description>RetailOps Magento Extension - The Ultimate Tools for Retail
|
11 |
+

|
12 |
+
When it comes to modern retail, best-of-breed is broken. Retailers today are forced to string together disjointed, legacy software to run their businesses because nothing better exists. RetailOps’ cloud-based platform addresses the unique challenges facing eCommerce and Omni-Channel retailers today. Our philosophy is simple; create software that doesn't get in the way and makes the modern retailer's life easier and more profitable.
|
13 |
+

|
14 |
+
The RetailOps Magento extension allows for a seamless integration with RetailOps, offering unparalleled performance and flexibility.
|
15 |
+

|
16 |
+
For more details or to sign up for a demo, visit: http://www.retailops.com</description>
|
17 |
+
<notes>* Fix for duplicate attribute options.
|
18 |
+
* Limited retry on image remote copy failure.
|
19 |
+
* Fix to update image attributes even if image itself already exists.
|
20 |
+
* Fix for inability to update or add more than one image to a sku.
|
21 |
+
* Fix for case insensitivity on attribute sets.
|
22 |
+
* Locate existing shipment before creating a new shipment.
|
23 |
+
* Don't add tracking if shipment already has tracking number.
|
24 |
+
* Fix for erroneous invoice captures.
|
25 |
+
* Added retailops_hold status.
|
26 |
+
</notes>
|
27 |
+
<authors><author><name>RetailOps</name><user>RetailOps</user><email>daniel@retailops.com</email></author></authors>
|
28 |
+
<date>2015-09-14</date>
|
29 |
+
<time>23:48:56</time>
|
30 |
+
<contents><target name="mageetc"><dir name="modules"><file name="RetailOps_Api.xml" hash="4efaf09b352f1f122f0af83342bdef07"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="retailops"><dir name="order"><dir name="view"><dir name="tab"><file name="retailops.phtml" hash="51d17085f74fb4ad1e09b987d7a0e733"/></dir></dir></dir></dir></dir><dir name="layout"><file name="retailops.xml" hash="8879a617964a66e0e02731e262234637"/></dir></dir></dir></dir></target><target name="magecommunity"><dir name="RetailOps"><dir name="Api"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="View"><dir name="Tab"><file name="Retailops.php" hash="27e0a91fcf5c0aaac5a545c16574465e"/></dir></dir></dir></dir></dir></dir><file name="Exception.php" hash="921703ce05b3e8d630fc8a36baa25d12"/><dir name="Helper"><file name="Data.php" hash="cb10d1f57ba9b7f96bd77b106c950a83"/></dir><dir name="Model"><file name="Api.php" hash="65e9e16cb8ee9c75c746d689f7f9e03e"/><dir name="Catalog"><dir name="Adapter"><file name="Abstract.php" hash="61a561a95bb40071d4bb7c2e02e63c46"/><file name="Attribute.php" hash="6fa97e2e8af011979c3600c877e81dea"/><file name="Bundle.php" hash="6777aa2ba12fdec543713cae97d50fe3"/><file name="Category.php" hash="4bf0053cd77d2f0a4a0094b67414169c"/><file name="Configurable.php" hash="91a5984f2e59a062f39f118aaa8a3bd5"/><file name="Default.php" hash="fcb2b32e6e4d008292d84caee9bdf240"/><file name="Downloadable.php" hash="dd2d4cf7650268861175c5cecf6ed1f2"/><file name="Link.php" hash="887104e69a274352867286c194172a8f"/><file name="Media.php" hash="4ba7f7e4f18cd055d86b73120c2b96a5"/><file name="Option.php" hash="d33d2a018f3ba2aa9460ec208df7fb95"/><file name="Tag.php" hash="615eff9ad88ab0c33122cb423f51fa67"/></dir><file name="Api.php" hash="b0b25c3897d67bc3bb6967d569a9ebb6"/><file name="Exception.php" hash="9a1ea92e48522ddaaa24e42dde94d0ef"/><dir name="Media"><file name="Item.php" hash="cf68048a5a9284fa2e3a50749b41235d"/></dir><dir name="Pull"><file name="Api.php" hash="b183269002499dfa29ad692904f41949"/></dir><dir name="Push"><file name="Api.php" hash="cc71f946efdd5d8e96cb68980e011262"/><dir name="Downloadable"><file name="Validator.php" hash="a2b4eb49b62e212eae06a0f55dfa393e"/></dir></dir></dir><dir name="Inventory"><file name="Api.php" hash="176ab5a377d1ca993791ca1f48af5f90"/></dir><file name="Observer.php" hash="7ef2c195010ae4c81b676d3c177e23e5"/><file name="Observer2.php~" hash="7ef2c195010ae4c81b676d3c177e23e5"/><dir name="Order"><file name="Api.php" hash="69beaf68afc724619a7dffbf923f0d08"/><dir name="Status"><file name="History.php" hash="39aae107a2029de67ecb01477508f271"/></dir></dir><dir name="Resource"><file name="Api.php" hash="168233c0b41251b67a20d0c8a32396ea"/><dir name="Catalog"><dir name="Media"><dir name="Item"><file name="Collection.php" hash="5938f25540bd59e75538eda614637179"/></dir><file name="Item.php" hash="eb3292a63811de285d2f44a6cb0dd630"/></dir></dir><dir name="Order"><dir name="Status"><dir name="History"><file name="Collection.php" hash="7427e972c92a5a435b772779a5548d29"/></dir><file name="History.php" hash="eab86f946bd58e5ab86d1cca21eee435"/></dir></dir></dir><dir name="Return"><file name="Api.php" hash="30ca168255518611669ac2e79067af5c"/></dir><dir name="Shipment"><file name="Api.php" hash="c0e471e66f14d29757b91479cdb6dc60"/><file name="Api.php.~80d30a79e43e602a0b5b5da0b2b1a8007dc0ada9~" hash="e1475ba8ce8216e0da57d45ae167246f"/><file name="Api.php.~84b644444a1b813b9b5956dbc9eeabb8577db950~" hash="8704e365691335f82eac3d3636539d35"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Catalog"><file name="AttributeSet.php" hash="a158e6ee2971b6464a184f6f07d2a5dd"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Sales"><file name="OrderController.php" hash="9b620414e2f98a6764f803bdaa7d01d3"/></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="60053ceed8f5e0d8d175331fb239c7f5"/><file name="api.xml" hash="32f6e0212a770054748aefd338bb2c85"/><file name="config.xml" hash="1336116e03068593f3d971fb49d619d4"/><file name="config.xml~" hash="1336116e03068593f3d971fb49d619d4"/><file name="system.xml" hash="5840692fb14c6d5d7848753bce79aa53"/></dir><dir name="sql"><dir name="retailops_api_setup"><file name="install-1.0.0.php" hash="3edc90b95f4219c9508be3de6a86dda1"/><file name="upgrade-1.0.0-1.0.1.php" hash="63724e6209e0ef59696ffdd6a14dc738"/><file name="upgrade-1.0.1-1.0.2.php" hash="a5c7795cd35f9af984c729bd3d3cd18a"/><file name="upgrade-1.0.2-1.0.3.php" hash="3987d4fda58f7545469700df599b050a"/><file name="upgrade-1.0.2-1.0.3.php~" hash="a5c7795cd35f9af984c729bd3d3cd18a"/></dir></dir></dir><dir name="Model"><file name="Observer.php" hash="5d53ef3a3901d287ea7368606ce081f4"/><file name="Observer.php~" hash="ac545a977d4b202444e5af526188f9b3"/></dir></dir></target></contents>
|
31 |
+
<compatible/>
|
32 |
+
<dependencies><required><php><min>5.4.0</min><max>5.6.13</max></php></required></dependencies>
|
33 |
+
</package>
|