Version Notes
Official release.
Capable of creating invoices and capturing payments when instructed to by ShipStation.
Download this release
Release Info
| Developer | Clockworkgeek |
| Extension | Auctane_ShipStation |
| Version | 1.3.6 |
| Comparing to | |
| See all releases | |
Code changes from version 1.3.4 to 1.3.6
- app/code/community/Auctane/Api/Helper/Data.php +11 -0
- app/code/community/Auctane/Api/Model/Action/Export.php +269 -0
- app/code/community/Auctane/Api/Model/Action/Shipnotify.php +151 -0
- app/code/community/Auctane/Api/Model/Server/Adapter.php +5 -343
- app/code/community/Auctane/Api/etc/config.xml +2 -1
- app/code/community/Auctane/ShipStation/etc/config.xml +1 -1
- package.xml +5 -5
app/code/community/Auctane/Api/Helper/Data.php
CHANGED
|
@@ -79,4 +79,15 @@ class Auctane_Api_Helper_Data extends Mage_Core_Helper_Data
|
|
| 79 |
return isset($types[$type]);
|
| 80 |
}
|
| 81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
}
|
| 79 |
return isset($types[$type]);
|
| 80 |
}
|
| 81 |
|
| 82 |
+
/**
|
| 83 |
+
* A simple list of module names for debugging.
|
| 84 |
+
*
|
| 85 |
+
* @return string
|
| 86 |
+
*/
|
| 87 |
+
public function getModuleList()
|
| 88 |
+
{
|
| 89 |
+
$modules = array_keys((array)Mage::getConfig()->getNode('modules')->children());
|
| 90 |
+
return implode(',', $modules);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
}
|
app/code/community/Auctane/Api/Model/Action/Export.php
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Auctane_Api_Model_Action_Export {
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* Perform an export according to the given request.
|
| 7 |
+
*
|
| 8 |
+
* @param Mage_Core_Controller_Request_Http $request
|
| 9 |
+
* @param Mage_Core_Controller_Response_Http $response
|
| 10 |
+
* @throws Exception
|
| 11 |
+
*/
|
| 12 |
+
public function process(Mage_Core_Controller_Request_Http $request,
|
| 13 |
+
Mage_Core_Controller_Response_Http $response)
|
| 14 |
+
{
|
| 15 |
+
// In case store is part of URL path use it to choose config.
|
| 16 |
+
$store = $request->get('store');
|
| 17 |
+
if ($store) $store = Mage::app()->getStore($store);
|
| 18 |
+
|
| 19 |
+
$apiConfigCharset = Mage::getStoreConfig("api/config/charset", $store);
|
| 20 |
+
|
| 21 |
+
$start_date = strtotime($request->getParam('start_date'));
|
| 22 |
+
$end_date = strtotime($request->getParam('end_date'));
|
| 23 |
+
if (!$start_date || !$end_date) throw new Exception('Start and end dates are required', 400);
|
| 24 |
+
|
| 25 |
+
$page = (int) $request->getParam('page');
|
| 26 |
+
|
| 27 |
+
/* @var $orders Mage_Sales_Model_Mysql4_Order_Collection */
|
| 28 |
+
$orders = Mage::getResourceModel('sales/order_collection');
|
| 29 |
+
// might use 'created_at' attribute instead
|
| 30 |
+
$orders->addAttributeToFilter('updated_at',
|
| 31 |
+
array(
|
| 32 |
+
'from' => date('Y-m-d H:i:s', $start_date),
|
| 33 |
+
'to' => date('Y-m-d H:i:s', $end_date)
|
| 34 |
+
));
|
| 35 |
+
if ($store) $orders->addAttributeToFilter('store_id', $store->getId());
|
| 36 |
+
if ($page > 0) $orders->setPage($page, $this->_getExportPageSize());
|
| 37 |
+
|
| 38 |
+
$xml = new XMLWriter;
|
| 39 |
+
$xml->openMemory();
|
| 40 |
+
$xml->startDocument('1.0', $apiConfigCharset);
|
| 41 |
+
$this->_writeOrders($orders, $xml, $store ? $store->getId() : 0);
|
| 42 |
+
$xml->endDocument();
|
| 43 |
+
|
| 44 |
+
$response->clearHeaders()
|
| 45 |
+
->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
|
| 46 |
+
->setBody($xml->outputMemory(true));
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
protected function _getExportPageSize()
|
| 50 |
+
{
|
| 51 |
+
return (int) Mage::getStoreConfig('auctaneapi/config/exportPageSize');
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
protected function _writeOrders(Varien_Data_Collection $orders, XMLWriter $xml, $storeId = null)
|
| 55 |
+
{
|
| 56 |
+
$xml->startElement('Orders');
|
| 57 |
+
$xml->writeAttribute('pages', $orders->getLastPageNumber());
|
| 58 |
+
foreach ($orders as $order) {
|
| 59 |
+
$this->_writeOrder($order, $xml, $storeId);
|
| 60 |
+
}
|
| 61 |
+
$xml->startElement('Query');
|
| 62 |
+
$xml->writeCdata($orders->getSelectSql());
|
| 63 |
+
$xml->endElement(); // Query
|
| 64 |
+
|
| 65 |
+
$xml->startElement('Version');
|
| 66 |
+
$xml->writeCdata('Magento ' . Mage::getVersion());
|
| 67 |
+
$xml->endElement(); // Version
|
| 68 |
+
|
| 69 |
+
$xml->startElement('Extensions');
|
| 70 |
+
$xml->writeCdata(Mage::helper('auctaneapi')->getModuleList());
|
| 71 |
+
$xml->endElement(); // Extensions
|
| 72 |
+
|
| 73 |
+
$xml->endElement(); // Orders
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
protected function _writeOrder(Mage_Sales_Model_Order $order, XMLWriter $xml, $storeId = null)
|
| 77 |
+
{
|
| 78 |
+
$history = '';
|
| 79 |
+
/* @var $status Mage_Sales_Model_Order_Status */
|
| 80 |
+
foreach ($order->getStatusHistoryCollection() as $status) {
|
| 81 |
+
if ($status->getComment()) {
|
| 82 |
+
$history .= $status->getCreatedAt() . PHP_EOL;
|
| 83 |
+
$history .= $status->getComment() . PHP_EOL . PHP_EOL;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
$history = trim($history);
|
| 87 |
+
if ($history) {
|
| 88 |
+
$order->setStatusHistoryText($history);
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
/* @var $gift Mage_GiftMessage_Model_Message */
|
| 92 |
+
$gift = Mage::helper('giftmessage/message')->getGiftMessage($order->getGiftMessageId());
|
| 93 |
+
$order->setGift($gift->isObjectNew() ? 'false' : 'true');
|
| 94 |
+
if (!$gift->isObjectNew()) {
|
| 95 |
+
$order->setGiftMessage(sprintf("From: %s\nTo: %s\nMessage: %s",
|
| 96 |
+
$gift->getSender(), $gift->getRecipient(), $gift->getMessage()));
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
$helper = Mage::helper('auctaneapi');
|
| 100 |
+
|
| 101 |
+
$xml->startElement('Order');
|
| 102 |
+
$helper->fieldsetToXml('sales_order', $order, $xml);
|
| 103 |
+
|
| 104 |
+
$xml->startElement('Customer');
|
| 105 |
+
$xml->startElement('CustomerCode');
|
| 106 |
+
$xml->writeCdata($order->getCustomerEmail());
|
| 107 |
+
$xml->endElement(); // CustomerCode
|
| 108 |
+
|
| 109 |
+
$xml->startElement('BillTo');
|
| 110 |
+
$helper->fieldsetToXml('sales_order_billing_address',
|
| 111 |
+
$order->getBillingAddress(), $xml);
|
| 112 |
+
$xml->endElement(); // BillTo
|
| 113 |
+
|
| 114 |
+
$xml->startElement('ShipTo');
|
| 115 |
+
$helper->fieldsetToXml('sales_order_shipping_address',
|
| 116 |
+
$order->getShippingAddress(), $xml);
|
| 117 |
+
$xml->endElement(); // ShipTo
|
| 118 |
+
|
| 119 |
+
$xml->endElement(); // Customer
|
| 120 |
+
|
| 121 |
+
$xml->startElement('Items');
|
| 122 |
+
/* @var $item Mage_Sales_Model_Order_Item */
|
| 123 |
+
foreach ($order->getItemsCollection($helper->getIncludedProductTypes()) as $item) {
|
| 124 |
+
$this->_writeOrderItem($item, $xml, $storeId);
|
| 125 |
+
}
|
| 126 |
+
$xml->endElement(); // Items
|
| 127 |
+
|
| 128 |
+
$xml->endElement(); // Order
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
protected function _writeOrderItem(Mage_Sales_Model_Order_Item $item, XMLWriter $xml, $storeId = null)
|
| 132 |
+
{
|
| 133 |
+
// inherit some attributes from parent order item
|
| 134 |
+
if ($item->getParentItemId() && !$item->getParentItem()) {
|
| 135 |
+
$item->setParentItem(Mage::getModel('sales/order_item')->load($item->getParentItemId()));
|
| 136 |
+
}
|
| 137 |
+
// only inherit if parent has been hidden
|
| 138 |
+
if ($item->getParentItem() && ($item->getPrice() == 0.000)
|
| 139 |
+
&& (Mage::helper('auctaneapi')->isExcludedProductType($item->getParentItem()->getProductType())))
|
| 140 |
+
{
|
| 141 |
+
$item->setPrice($item->getParentItem()->getPrice());
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
/* @var $gift Mage_GiftMessage_Model_Message */
|
| 145 |
+
$gift = Mage::helper('giftmessage/message')->getGiftMessage(
|
| 146 |
+
!$item->getGiftMessageId() && $item->getParentItem()
|
| 147 |
+
? $item->getParentItem()->getGiftMessageId()
|
| 148 |
+
: $item->getGiftMessageId());
|
| 149 |
+
$item->setGift($gift->isObjectNew() ? 'false' : 'true');
|
| 150 |
+
if (!$gift->isObjectNew()) {
|
| 151 |
+
$item->setGiftMessage(sprintf("From: %s\nTo: %s\nMessage: %s",
|
| 152 |
+
$gift->getSender(), $gift->getRecipient(), $gift->getMessage()));
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
/* @var $product Mage_Catalog_Model_Product */
|
| 156 |
+
$product = Mage::getModel('catalog/product')
|
| 157 |
+
->setStoreId($storeId)
|
| 158 |
+
->load($item->getProductId());
|
| 159 |
+
// inherit some attributes from parent product item
|
| 160 |
+
if (($parentProduct = $this->_getOrderItemParentProduct($item, $storeId))) {
|
| 161 |
+
if (!$product->getImage() || ($product->getImage() == 'no_selection'))
|
| 162 |
+
$product->setImage($parentProduct->getImage());
|
| 163 |
+
if (!$product->getSmallImage() || ($product->getSmallImage() == 'no_selection'))
|
| 164 |
+
$product->setSmallImage($parentProduct->getSmallImage());
|
| 165 |
+
if (!$product->getThumbnail() || ($product->getThumbnail() == 'no_selection'))
|
| 166 |
+
$product->setThumbnail($parentProduct->getThumbnail());
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
$xml->startElement('Item');
|
| 170 |
+
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item', $item, $xml);
|
| 171 |
+
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item_product',
|
| 172 |
+
$product, $xml);
|
| 173 |
+
|
| 174 |
+
$xml->startElement('Options');
|
| 175 |
+
$this->_writeOrderProductAttribute($product, $xml, $storeId);
|
| 176 |
+
// items may have several custom options chosen by customer
|
| 177 |
+
foreach ((array) $item->getProductOptionByCode('options') as $option) {
|
| 178 |
+
$this->_writeOrderItemOption($option, $xml, $storeId);
|
| 179 |
+
}
|
| 180 |
+
$buyRequest = $item->getProductOptionByCode('info_buyRequest');
|
| 181 |
+
if ($buyRequest && @$buyRequest['super_attribute']) {
|
| 182 |
+
// super_attribute is non-null and non-empty, there must be a Configurable involved
|
| 183 |
+
$parentItem = $this->_getOrderItemParent($item);
|
| 184 |
+
foreach ((array) $parentItem->getProductOptionByCode('attributes_info') as $option) {
|
| 185 |
+
$this->_writeOrderItemOption($option, $xml, $storeId);
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
$xml->endElement(); // Options
|
| 189 |
+
|
| 190 |
+
$xml->endElement(); // Item
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
protected function _writeOrderProductAttribute(Mage_Catalog_Model_Product $product, XMLWriter $xml, $storeId = null)
|
| 194 |
+
{
|
| 195 |
+
// custom attributes are specified in Admin > Configuration > Sales > Auctane Shipstation API
|
| 196 |
+
// static because attributes can be cached, they do not change during a request
|
| 197 |
+
static $attrs = null;
|
| 198 |
+
if (is_null($attrs)) {
|
| 199 |
+
$attrs = Mage::getResourceModel('eav/entity_attribute_collection');
|
| 200 |
+
$attrIds = explode(',', Mage::getStoreConfig('sales/auctaneapi/customattributes', $storeId));
|
| 201 |
+
$attrs->addFieldToFilter('attribute_id', $attrIds);
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
/* @var $attr Mage_Eav_Model_Entity_Attribute */
|
| 205 |
+
foreach ($attrs as $attr) {
|
| 206 |
+
if ($product->hasData($attr->getName())) {
|
| 207 |
+
// if an attribute has options/labels
|
| 208 |
+
if (in_array($attr->getFrontendInput(), array('select', 'multiselect'))) {
|
| 209 |
+
$value = $product->getAttributeText($attr->getName());
|
| 210 |
+
if (is_array($value)) $value = implode(',', $value);
|
| 211 |
+
}
|
| 212 |
+
// else is a static value
|
| 213 |
+
else {
|
| 214 |
+
$value = $product->getDataUsingMethod($attr->getName());
|
| 215 |
+
}
|
| 216 |
+
// fake an item option
|
| 217 |
+
$option = array(
|
| 218 |
+
'value' => $value,
|
| 219 |
+
'label' => $attr->getFrontendLabel()
|
| 220 |
+
);
|
| 221 |
+
$this->_writeOrderItemOption($option, $xml, $storeId);
|
| 222 |
+
}
|
| 223 |
+
}
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
protected function _writeOrderItemOption($option, XMLWriter $xml)
|
| 227 |
+
{
|
| 228 |
+
$xml->startElement('Option');
|
| 229 |
+
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item_option', $option, $xml);
|
| 230 |
+
$xml->endElement(); // Option
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
/**
|
| 234 |
+
* Safe way to lookup parent order items.
|
| 235 |
+
*
|
| 236 |
+
* @param Mage_Sales_Model_Order_Item $item
|
| 237 |
+
* @return Mage_Sales_Model_Order_Item
|
| 238 |
+
*/
|
| 239 |
+
protected function _getOrderItemParent(Mage_Sales_Model_Order_Item $item)
|
| 240 |
+
{
|
| 241 |
+
if ($item->getParentItem()) {
|
| 242 |
+
return $item->getParentItem();
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
$parentItem = Mage::getModel('sales/order_item')
|
| 246 |
+
->load($item->getParentItemId());
|
| 247 |
+
$item->setParentItem($parentItem);
|
| 248 |
+
return $parentItem;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
/**
|
| 252 |
+
* @param Mage_Sales_Model_Order_Item $item
|
| 253 |
+
* @param mixed $storeId
|
| 254 |
+
* @return Mage_Catalog_Model_Product
|
| 255 |
+
*/
|
| 256 |
+
protected function _getOrderItemParentProduct(Mage_Sales_Model_Order_Item $item, $storeId = null)
|
| 257 |
+
{
|
| 258 |
+
if ($item->getParentItemId()) {
|
| 259 |
+
// cannot use getParentItem() because we stripped parents from the order
|
| 260 |
+
$parentItem = $this->_getOrderItemParent($item);
|
| 261 |
+
// initialise with store so that images are correct
|
| 262 |
+
return Mage::getModel('catalog/product')
|
| 263 |
+
->setStoreId($storeId)
|
| 264 |
+
->load($parentItem->getProductId());
|
| 265 |
+
}
|
| 266 |
+
return null;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
}
|
app/code/community/Auctane/Api/Model/Action/Shipnotify.php
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<?php
|
| 2 |
+
|
| 3 |
+
class Auctane_Api_Model_Action_Shipnotify {
|
| 4 |
+
|
| 5 |
+
/**
|
| 6 |
+
* Perform a notify using POSTed data.
|
| 7 |
+
*
|
| 8 |
+
* See Auctane API specification.
|
| 9 |
+
*
|
| 10 |
+
* @param Mage_Core_Controller_Request_Http $request
|
| 11 |
+
* @throws Exception
|
| 12 |
+
*/
|
| 13 |
+
public function process(Mage_Core_Controller_Request_Http $request)
|
| 14 |
+
{
|
| 15 |
+
// Raw XML is POSTed to this stream
|
| 16 |
+
$xml = simplexml_load_file('php://input');
|
| 17 |
+
|
| 18 |
+
// load some objects
|
| 19 |
+
$order = $this->_getOrder($xml->OrderNumber);
|
| 20 |
+
$carrier = $this->_getCarrier(@$xml->Carrier);
|
| 21 |
+
$qtys = $this->_getOrderItemQtys(@$xml->Items, $order);
|
| 22 |
+
$shipment = $this->_getOrderShipment($order, $qtys);
|
| 23 |
+
|
| 24 |
+
// this is where tracking is actually added
|
| 25 |
+
$track = Mage::getModel('sales/order_shipment_track')
|
| 26 |
+
->setNumber($xml->TrackingNumber)
|
| 27 |
+
->setCarrierCode($xml->Carrier)
|
| 28 |
+
->setTitle($xml->Service);
|
| 29 |
+
$shipment->addTrack($track);
|
| 30 |
+
|
| 31 |
+
// 'NotifyCustomer' must be "true" or "yes" to trigger an email
|
| 32 |
+
$notify = filter_var(@$xml->NotifyCustomer, FILTER_VALIDATE_BOOLEAN);
|
| 33 |
+
|
| 34 |
+
$capture = filter_var($request->getParam('capture'), FILTER_VALIDATE_BOOLEAN);
|
| 35 |
+
if ($capture && $order->canInvoice()) {
|
| 36 |
+
$invoice = $order->prepareInvoice($qtys);
|
| 37 |
+
$invoice->register(); // captures & updates order totals
|
| 38 |
+
$invoice->addComment($this->_getInvoiceComment(), $notify)
|
| 39 |
+
->sendEmail($notify); // always send to store manager, and optionally notify customer too
|
| 40 |
+
$order->setIsInProcess(true); // updates status on save
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// Internal notes are only visible to admin
|
| 44 |
+
if (@$xml->InternalNotes) {
|
| 45 |
+
$shipment->addComment($xml->InternalNotes);
|
| 46 |
+
}
|
| 47 |
+
// Customer notes have 'Visible On Frontend' set
|
| 48 |
+
if (@$xml->NotesToCustomer) {
|
| 49 |
+
if ($notify) {
|
| 50 |
+
$shipment
|
| 51 |
+
->sendEmail(true, $xml->NotesToCustomer)
|
| 52 |
+
->setEmailSent(true);
|
| 53 |
+
}
|
| 54 |
+
$shipment->addComment($xml->NotesToCustomer, $notify, true);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
$transaction = Mage::getModel('core/resource_transaction');
|
| 58 |
+
$transaction->addObject($shipment)
|
| 59 |
+
->addObject($track);
|
| 60 |
+
if (isset($invoice)) {
|
| 61 |
+
// order has been captured, therefore has been modified
|
| 62 |
+
$transaction->addObject($invoice)
|
| 63 |
+
->addObject($order);
|
| 64 |
+
}
|
| 65 |
+
$transaction->save();
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
/**
|
| 69 |
+
* Configurable comment, in case language needs to be changed.
|
| 70 |
+
*
|
| 71 |
+
* @return string
|
| 72 |
+
*/
|
| 73 |
+
protected function _getInvoiceComment()
|
| 74 |
+
{
|
| 75 |
+
return Mage::getStoreConfig('auctaneapi/config/invoiceComment');
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
/**
|
| 79 |
+
* @param string $carrierCode
|
| 80 |
+
* @return Mage_Shipping_Model_Carrier_Interface
|
| 81 |
+
*/
|
| 82 |
+
protected function _getCarrier($carrierCode)
|
| 83 |
+
{
|
| 84 |
+
$carrierCode = strtolower($carrierCode);
|
| 85 |
+
$carrierModel = Mage::getStoreConfig("carriers/{$carrierCode}/model");
|
| 86 |
+
if (!$carrierModel) throw new Exception('Invalid carrier specified.', 400);
|
| 87 |
+
/* @var $carrier Mage_Shipping_Model_Carrier_Interface */
|
| 88 |
+
$carrier = Mage::getModel($carrierModel);
|
| 89 |
+
if (!$carrier) throw new Exception('Invalid carrier specified.', 400);
|
| 90 |
+
if (!$carrier->isTrackingAvailable()) throw new Exception('Carrier does not supported tracking.', 400);
|
| 91 |
+
return $carrier;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
/**
|
| 95 |
+
* @param string $orderIncrementId
|
| 96 |
+
* @return Mage_Sales_Model_Order
|
| 97 |
+
*/
|
| 98 |
+
protected function _getOrder($orderIncrementId)
|
| 99 |
+
{
|
| 100 |
+
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
|
| 101 |
+
if ($order->isObjectNew()) throw new Exception("Order '{$orderIncrementId}' does not exist", 400);
|
| 102 |
+
return $order;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
protected function _getOrderItemQtys(SimpleXMLElement $xmlItems, Mage_Sales_Model_Order $order)
|
| 106 |
+
{
|
| 107 |
+
/* @var $items Mage_Sales_Model_Mysql4_Order_Item_Collection */
|
| 108 |
+
$items = $order->getItemsCollection();
|
| 109 |
+
$qtys = array();
|
| 110 |
+
/* @var $item Mage_Sales_Model_Order_Item */
|
| 111 |
+
foreach ($items as $item) {
|
| 112 |
+
// search for item by SKU
|
| 113 |
+
@list($xmlItem) = $xmlItems->xpath(sprintf('//Item/SKU[text()="%s"]/..',
|
| 114 |
+
addslashes($item->getSku())));
|
| 115 |
+
if ($xmlItem) {
|
| 116 |
+
// store quantity by order item ID, not by SKU
|
| 117 |
+
$qtys[$item->getId()] = (float) $xmlItem->Quantity;
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
return $qtys;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
/**
|
| 124 |
+
* @param Mage_Sales_ModelOrder $order
|
| 125 |
+
* @param array $qtys
|
| 126 |
+
* @return Mage_Sales_Model_Order_Shipment
|
| 127 |
+
*/
|
| 128 |
+
protected function _getOrderShipment(Mage_Sales_Model_Order $order, $qtys)
|
| 129 |
+
{
|
| 130 |
+
/* @var $shipments Mage_Sales_Model_Mysql4_Order_Shipment_Collection */
|
| 131 |
+
$shipments = $order->getShipmentsCollection();
|
| 132 |
+
/* @var $shipment Mage_Sales_Model_Order_Shipment */
|
| 133 |
+
if (($shipments === false) || ($shipments->count() === 0)) {
|
| 134 |
+
// order has no shipments yet, create one
|
| 135 |
+
$shipment = $order->prepareShipment($qtys);
|
| 136 |
+
$shipment->register();
|
| 137 |
+
$order->setIsInProgress(true);
|
| 138 |
+
// shipment must have an ID before proceeding
|
| 139 |
+
Mage::getModel('core/resource_transaction')
|
| 140 |
+
->addObject($shipment)
|
| 141 |
+
->addObject($order)
|
| 142 |
+
->save();
|
| 143 |
+
}
|
| 144 |
+
else {
|
| 145 |
+
// probably only one shipment for all items, assume the last is most recent
|
| 146 |
+
$shipment = $shipments->getLastItem();
|
| 147 |
+
}
|
| 148 |
+
return $shipment;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
}
|
app/code/community/Auctane/Api/Model/Server/Adapter.php
CHANGED
|
@@ -66,17 +66,6 @@ class Auctane_Api_Model_Server_Adapter
|
|
| 66 |
return $this->getData('controller');
|
| 67 |
}
|
| 68 |
|
| 69 |
-
protected function _getExportPageSize()
|
| 70 |
-
{
|
| 71 |
-
return (int) Mage::getStoreConfig('auctaneapi/config/exportPageSize');
|
| 72 |
-
}
|
| 73 |
-
|
| 74 |
-
protected function _getModuleList()
|
| 75 |
-
{
|
| 76 |
-
$modules = array_keys((array)Mage::getConfig()->getNode('modules')->children());
|
| 77 |
-
return implode(',', $modules);
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
/**
|
| 81 |
* Run webservice
|
| 82 |
*
|
|
@@ -95,79 +84,15 @@ class Auctane_Api_Model_Server_Adapter
|
|
| 95 |
$this->fault(401, 'Unauthorized');
|
| 96 |
}
|
| 97 |
|
| 98 |
-
// In case store is part of URL path use it to choose config.
|
| 99 |
-
$store = $this->getController()->getRequest()->get('store');
|
| 100 |
-
if ($store) $store = Mage::app()->getStore($store);
|
| 101 |
-
|
| 102 |
-
$apiConfigCharset = Mage::getStoreConfig("api/config/charset", $store);
|
| 103 |
-
|
| 104 |
try { switch ($this->getController()->getRequest()->getParam('action', 'export')) {
|
| 105 |
case 'export':
|
| 106 |
-
$
|
| 107 |
-
$
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
$page = (int) $this->getController()->getRequest()->getParam('page');
|
| 111 |
-
|
| 112 |
-
/* @var $orders Mage_Sales_Model_Mysql4_Order_Collection */
|
| 113 |
-
$orders = Mage::getResourceModel('sales/order_collection');
|
| 114 |
-
// might use 'created_at' attribute instead
|
| 115 |
-
$orders->addAttributeToFilter('updated_at',
|
| 116 |
-
array(
|
| 117 |
-
'from' => date('Y-m-d H:i:s', $start_date),
|
| 118 |
-
'to' => date('Y-m-d H:i:s', $end_date)
|
| 119 |
-
));
|
| 120 |
-
if ($store) $orders->addAttributeToFilter('store_id', $store->getId());
|
| 121 |
-
if ($page > 0) $orders->setPage($page, $this->_getExportPageSize());
|
| 122 |
-
|
| 123 |
-
$xml = new XMLWriter;
|
| 124 |
-
$xml->openMemory();
|
| 125 |
-
$xml->startDocument('1.0', $apiConfigCharset);
|
| 126 |
-
$this->_writeOrders($orders, $xml, $store ? $store->getId() : 0);
|
| 127 |
-
$xml->endDocument();
|
| 128 |
-
|
| 129 |
-
$this->getController()->getResponse()
|
| 130 |
-
->clearHeaders()
|
| 131 |
-
->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
|
| 132 |
-
->setBody($xml->outputMemory(true));
|
| 133 |
break;
|
| 134 |
case 'shipnotify':
|
| 135 |
-
|
| 136 |
-
$
|
| 137 |
-
|
| 138 |
-
// load some objects
|
| 139 |
-
$order = $this->_getOrder($xml->OrderNumber);
|
| 140 |
-
$carrier = $this->_getCarrier(@$xml->Carrier);
|
| 141 |
-
$qtys = $this->_getOrderItemQtys(@$xml->Items, $order);
|
| 142 |
-
$shipment = $this->_getOrderShipment($order, $qtys);
|
| 143 |
-
|
| 144 |
-
// this is where tracking is actually added
|
| 145 |
-
$track = Mage::getModel('sales/order_shipment_track')
|
| 146 |
-
->setNumber($xml->TrackingNumber)
|
| 147 |
-
->setCarrierCode($xml->Carrier)
|
| 148 |
-
->setTitle($xml->Service);
|
| 149 |
-
$shipment->addTrack($track);
|
| 150 |
-
|
| 151 |
-
// Internal notes are only visible to admin
|
| 152 |
-
if (@$xml->InternalNotes) {
|
| 153 |
-
$shipment->addComment($xml->InternalNotes);
|
| 154 |
-
}
|
| 155 |
-
// Customer notes have 'Visible On Frontend' set
|
| 156 |
-
// 'NotifyCustomer' must be "true" or "yes" to trigger an email
|
| 157 |
-
if (@$xml->NotesToCustomer) {
|
| 158 |
-
$notify = filter_var(@$xml->NotifyCustomer, FILTER_VALIDATE_BOOLEAN);
|
| 159 |
-
if ($notify) {
|
| 160 |
-
$shipment
|
| 161 |
-
->sendEmail(true, $xml->NotesToCustomer)
|
| 162 |
-
->setEmailSent(true);
|
| 163 |
-
}
|
| 164 |
-
$shipment->addComment($xml->NotesToCustomer, $notify, true);
|
| 165 |
-
}
|
| 166 |
-
|
| 167 |
-
Mage::getModel('core/resource_transaction')
|
| 168 |
-
->addObject($shipment)
|
| 169 |
-
->addObject($track)
|
| 170 |
-
->save();
|
| 171 |
// if there hasn't been an error yet the work is done and a "200 OK" is given
|
| 172 |
break;
|
| 173 |
}}
|
|
@@ -198,267 +123,4 @@ class Auctane_Api_Model_Server_Adapter
|
|
| 198 |
');
|
| 199 |
}
|
| 200 |
|
| 201 |
-
protected function _writeOrders(Varien_Data_Collection $orders, XMLWriter $xml, $storeId = null)
|
| 202 |
-
{
|
| 203 |
-
$xml->startElement('Orders');
|
| 204 |
-
$xml->writeAttribute('pages', $orders->getLastPageNumber());
|
| 205 |
-
foreach ($orders as $order) {
|
| 206 |
-
$this->_writeOrder($order, $xml, $storeId);
|
| 207 |
-
}
|
| 208 |
-
$xml->startElement('Query');
|
| 209 |
-
$xml->writeCdata($orders->getSelectSql());
|
| 210 |
-
$xml->endElement(); // Query
|
| 211 |
-
|
| 212 |
-
$xml->startElement('Version');
|
| 213 |
-
$xml->writeCdata('Magento ' . Mage::getVersion());
|
| 214 |
-
$xml->endElement(); // Version
|
| 215 |
-
|
| 216 |
-
$xml->startElement('Extensions');
|
| 217 |
-
$xml->writeCdata($this->_getModuleList());
|
| 218 |
-
$xml->endElement(); // Extensions
|
| 219 |
-
|
| 220 |
-
$xml->endElement(); // Orders
|
| 221 |
-
}
|
| 222 |
-
|
| 223 |
-
protected function _writeOrder(Mage_Sales_Model_Order $order, XMLWriter $xml, $storeId = null)
|
| 224 |
-
{
|
| 225 |
-
$history = '';
|
| 226 |
-
/* @var $status Mage_Sales_Model_Order_Status */
|
| 227 |
-
foreach ($order->getStatusHistoryCollection() as $status) {
|
| 228 |
-
if ($status->getComment()) {
|
| 229 |
-
$history .= $status->getCreatedAt() . PHP_EOL;
|
| 230 |
-
$history .= $status->getComment() . PHP_EOL . PHP_EOL;
|
| 231 |
-
}
|
| 232 |
-
}
|
| 233 |
-
$history = trim($history);
|
| 234 |
-
if ($history) {
|
| 235 |
-
$order->setStatusHistoryText($history);
|
| 236 |
-
}
|
| 237 |
-
|
| 238 |
-
/* @var $gift Mage_GiftMessage_Model_Message */
|
| 239 |
-
$gift = Mage::helper('giftmessage/message')->getGiftMessage($order->getGiftMessageId());
|
| 240 |
-
$order->setGift($gift->isObjectNew() ? 'false' : 'true');
|
| 241 |
-
if (!$gift->isObjectNew()) {
|
| 242 |
-
$order->setGiftMessage(sprintf("From: %s\nTo: %s\nMessage: %s",
|
| 243 |
-
$gift->getSender(), $gift->getRecipient(), $gift->getMessage()));
|
| 244 |
-
}
|
| 245 |
-
|
| 246 |
-
$helper = Mage::helper('auctaneapi');
|
| 247 |
-
|
| 248 |
-
$xml->startElement('Order');
|
| 249 |
-
$helper->fieldsetToXml('sales_order', $order, $xml);
|
| 250 |
-
|
| 251 |
-
$xml->startElement('Customer');
|
| 252 |
-
$xml->startElement('CustomerCode');
|
| 253 |
-
$xml->writeCdata($order->getCustomerEmail());
|
| 254 |
-
$xml->endElement(); // CustomerCode
|
| 255 |
-
|
| 256 |
-
$xml->startElement('BillTo');
|
| 257 |
-
$helper->fieldsetToXml('sales_order_billing_address',
|
| 258 |
-
$order->getBillingAddress(), $xml);
|
| 259 |
-
$xml->endElement(); // BillTo
|
| 260 |
-
|
| 261 |
-
$xml->startElement('ShipTo');
|
| 262 |
-
$helper->fieldsetToXml('sales_order_shipping_address',
|
| 263 |
-
$order->getShippingAddress(), $xml);
|
| 264 |
-
$xml->endElement(); // ShipTo
|
| 265 |
-
|
| 266 |
-
$xml->endElement(); // Customer
|
| 267 |
-
|
| 268 |
-
$xml->startElement('Items');
|
| 269 |
-
/* @var $item Mage_Sales_Model_Order_Item */
|
| 270 |
-
foreach ($order->getItemsCollection($helper->getIncludedProductTypes()) as $item) {
|
| 271 |
-
$this->_writeOrderItem($item, $xml, $storeId);
|
| 272 |
-
}
|
| 273 |
-
$xml->endElement(); // Items
|
| 274 |
-
|
| 275 |
-
$xml->endElement(); // Order
|
| 276 |
-
}
|
| 277 |
-
|
| 278 |
-
protected function _writeOrderItem(Mage_Sales_Model_Order_Item $item, XMLWriter $xml, $storeId = null)
|
| 279 |
-
{
|
| 280 |
-
// inherit some attributes from parent order item
|
| 281 |
-
if ($item->getParentItemId() && !$item->getParentItem()) {
|
| 282 |
-
$item->setParentItem(Mage::getModel('sales/order_item')->load($item->getParentItemId()));
|
| 283 |
-
}
|
| 284 |
-
// only inherit if parent has been hidden
|
| 285 |
-
if ($item->getParentItem() && ($item->getPrice() == 0.000)
|
| 286 |
-
&& (Mage::helper('auctaneapi')->isExcludedProductType($item->getParentItem()->getProductType())))
|
| 287 |
-
{
|
| 288 |
-
$item->setPrice($item->getParentItem()->getPrice());
|
| 289 |
-
}
|
| 290 |
-
|
| 291 |
-
/* @var $gift Mage_GiftMessage_Model_Message */
|
| 292 |
-
$gift = Mage::helper('giftmessage/message')->getGiftMessage(
|
| 293 |
-
!$item->getGiftMessageId() && $item->getParentItem()
|
| 294 |
-
? $item->getParentItem()->getGiftMessageId()
|
| 295 |
-
: $item->getGiftMessageId());
|
| 296 |
-
$item->setGift($gift->isObjectNew() ? 'false' : 'true');
|
| 297 |
-
if (!$gift->isObjectNew()) {
|
| 298 |
-
$item->setGiftMessage(sprintf("From: %s\nTo: %s\nMessage: %s",
|
| 299 |
-
$gift->getSender(), $gift->getRecipient(), $gift->getMessage()));
|
| 300 |
-
}
|
| 301 |
-
|
| 302 |
-
/* @var $product Mage_Catalog_Model_Product */
|
| 303 |
-
$product = Mage::getModel('catalog/product')
|
| 304 |
-
->setStoreId($storeId)
|
| 305 |
-
->load($item->getProductId());
|
| 306 |
-
// inherit some attributes from parent product item
|
| 307 |
-
if (($parentProduct = $this->_getOrderItemParentProduct($item, $storeId))) {
|
| 308 |
-
if (!$product->getImage() || ($product->getImage() == 'no_selection'))
|
| 309 |
-
$product->setImage($parentProduct->getImage());
|
| 310 |
-
if (!$product->getSmallImage() || ($product->getSmallImage() == 'no_selection'))
|
| 311 |
-
$product->setSmallImage($parentProduct->getSmallImage());
|
| 312 |
-
if (!$product->getThumbnail() || ($product->getThumbnail() == 'no_selection'))
|
| 313 |
-
$product->setThumbnail($parentProduct->getThumbnail());
|
| 314 |
-
}
|
| 315 |
-
|
| 316 |
-
$xml->startElement('Item');
|
| 317 |
-
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item', $item, $xml);
|
| 318 |
-
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item_product',
|
| 319 |
-
$product, $xml);
|
| 320 |
-
|
| 321 |
-
$xml->startElement('Options');
|
| 322 |
-
$this->_writeOrderProductAttribute($product, $xml, $storeId);
|
| 323 |
-
// items may have several custom options chosen by customer
|
| 324 |
-
foreach ((array) $item->getProductOptionByCode('options') as $option) {
|
| 325 |
-
$this->_writeOrderItemOption($option, $xml, $storeId);
|
| 326 |
-
}
|
| 327 |
-
$xml->endElement(); // Options
|
| 328 |
-
|
| 329 |
-
$xml->endElement(); // Item
|
| 330 |
-
}
|
| 331 |
-
|
| 332 |
-
protected function _writeOrderProductAttribute(Mage_Catalog_Model_Product $product, XMLWriter $xml, $storeId = null)
|
| 333 |
-
{
|
| 334 |
-
// custom attributes are specified in Admin > Configuration > Sales > Auctane Shipstation API
|
| 335 |
-
// static because attributes can be cached, they do not change during a request
|
| 336 |
-
static $attrs = null;
|
| 337 |
-
if (is_null($attrs)) {
|
| 338 |
-
$attrs = Mage::getResourceModel('eav/entity_attribute_collection');
|
| 339 |
-
$attrIds = explode(',', Mage::getStoreConfig('sales/auctaneapi/customattributes', $storeId));
|
| 340 |
-
$attrs->addFieldToFilter('attribute_id', $attrIds);
|
| 341 |
-
}
|
| 342 |
-
|
| 343 |
-
/* @var $attr Mage_Eav_Model_Entity_Attribute */
|
| 344 |
-
foreach ($attrs as $attr) {
|
| 345 |
-
if ($product->hasData($attr->getName())) {
|
| 346 |
-
// if an attribute has options/labels
|
| 347 |
-
if (in_array($attr->getFrontendInput(), array('select', 'multiselect'))) {
|
| 348 |
-
$value = $product->getAttributeText($attr->getName());
|
| 349 |
-
if (is_array($value)) $value = implode(',', $value);
|
| 350 |
-
}
|
| 351 |
-
// else is a static value
|
| 352 |
-
else {
|
| 353 |
-
$value = $product->getDataUsingMethod($attr->getName());
|
| 354 |
-
}
|
| 355 |
-
// fake an item option
|
| 356 |
-
$option = array(
|
| 357 |
-
'value' => $value,
|
| 358 |
-
'label' => $attr->getFrontendLabel()
|
| 359 |
-
);
|
| 360 |
-
$this->_writeOrderItemOption($option, $xml, $storeId);
|
| 361 |
-
}
|
| 362 |
-
}
|
| 363 |
-
}
|
| 364 |
-
|
| 365 |
-
protected function _writeOrderItemOption($option, XMLWriter $xml)
|
| 366 |
-
{
|
| 367 |
-
$xml->startElement('Option');
|
| 368 |
-
Mage::helper('auctaneapi')->fieldsetToXml('sales_order_item_option', $option, $xml);
|
| 369 |
-
$xml->endElement(); // Option
|
| 370 |
-
}
|
| 371 |
-
|
| 372 |
-
/**
|
| 373 |
-
* @param string $carrierCode
|
| 374 |
-
* @return Mage_Shipping_Model_Carrier_Interface
|
| 375 |
-
*/
|
| 376 |
-
protected function _getCarrier($carrierCode)
|
| 377 |
-
{
|
| 378 |
-
$carrierCode = strtolower($carrierCode);
|
| 379 |
-
$carrierModel = Mage::getStoreConfig("carriers/{$carrierCode}/model");
|
| 380 |
-
if (!$carrierModel) throw new Exception('Invalid carrier specified.', 400);
|
| 381 |
-
/* @var $carrier Mage_Shipping_Model_Carrier_Interface */
|
| 382 |
-
$carrier = Mage::getModel($carrierModel);
|
| 383 |
-
if (!$carrier) throw new Exception('Invalid carrier specified.', 400);
|
| 384 |
-
if (!$carrier->isTrackingAvailable()) throw new Exception('Carrier does not supported tracking.', 400);
|
| 385 |
-
return $carrier;
|
| 386 |
-
}
|
| 387 |
-
|
| 388 |
-
/**
|
| 389 |
-
* @param string $orderIncrementId
|
| 390 |
-
* @return Mage_Sales_Model_Order
|
| 391 |
-
*/
|
| 392 |
-
protected function _getOrder($orderIncrementId)
|
| 393 |
-
{
|
| 394 |
-
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
|
| 395 |
-
if ($order->isObjectNew()) throw new Exception("Order '{$orderIncrementId}' does not exist", 400);
|
| 396 |
-
return $order;
|
| 397 |
-
}
|
| 398 |
-
|
| 399 |
-
protected function _getOrderItemQtys(SimpleXMLElement $xmlItems, Mage_Sales_Model_Order $order)
|
| 400 |
-
{
|
| 401 |
-
/* @var $items Mage_Sales_Model_Mysql4_Order_Item_Collection */
|
| 402 |
-
$items = $order->getItemsCollection();
|
| 403 |
-
$qtys = array();
|
| 404 |
-
/* @var $item Mage_Sales_Model_Order_Item */
|
| 405 |
-
foreach ($items as $item) {
|
| 406 |
-
// search for item by SKU
|
| 407 |
-
@list($xmlItem) = $xmlItems->xpath(sprintf('//Item/SKU[text()="%s"]/..',
|
| 408 |
-
addslashes($item->getSku())));
|
| 409 |
-
if ($xmlItem) {
|
| 410 |
-
// store quantity by order item ID, not by SKU
|
| 411 |
-
$qtys[$item->getId()] = (float) $xmlItem->Quantity;
|
| 412 |
-
}
|
| 413 |
-
}
|
| 414 |
-
return $qtys;
|
| 415 |
-
}
|
| 416 |
-
|
| 417 |
-
/**
|
| 418 |
-
* @param Mage_Sales_Model_Order_Item $item
|
| 419 |
-
* @param mixed $storeId
|
| 420 |
-
* @return Mage_Catalog_Model_Product
|
| 421 |
-
*/
|
| 422 |
-
protected function _getOrderItemParentProduct(Mage_Sales_Model_Order_Item $item, $storeId = null)
|
| 423 |
-
{
|
| 424 |
-
if ($item->getParentItemId()) {
|
| 425 |
-
// cannot use getParentItem() because we stripped parents from the order
|
| 426 |
-
$parentItem = Mage::getModel('sales/order_item')
|
| 427 |
-
->load($item->getParentItemId());
|
| 428 |
-
// initialise with store so that images are correct
|
| 429 |
-
return Mage::getModel('catalog/product')
|
| 430 |
-
->setStoreId($storeId)
|
| 431 |
-
->load($parentItem->getProductId());
|
| 432 |
-
}
|
| 433 |
-
return null;
|
| 434 |
-
}
|
| 435 |
-
|
| 436 |
-
/**
|
| 437 |
-
* @param Mage_Sales_ModelOrder $order
|
| 438 |
-
* @param array $qtys
|
| 439 |
-
* @return Mage_Sales_Model_Order_Shipment
|
| 440 |
-
*/
|
| 441 |
-
protected function _getOrderShipment(Mage_Sales_Model_Order $order, $qtys)
|
| 442 |
-
{
|
| 443 |
-
/* @var $shipments Mage_Sales_Model_Mysql4_Order_Shipment_Collection */
|
| 444 |
-
$shipments = $order->getShipmentsCollection();
|
| 445 |
-
/* @var $shipment Mage_Sales_Model_Order_Shipment */
|
| 446 |
-
if (($shipments === false) || ($shipments->count() === 0)) {
|
| 447 |
-
// order has no shipments yet, create one
|
| 448 |
-
$shipment = $order->prepareShipment($qtys);
|
| 449 |
-
$shipment->register();
|
| 450 |
-
$order->setIsInProgress(true);
|
| 451 |
-
// shipment must have an ID before proceeding
|
| 452 |
-
Mage::getModel('core/resource_transaction')
|
| 453 |
-
->addObject($shipment)
|
| 454 |
-
->addObject($order)
|
| 455 |
-
->save();
|
| 456 |
-
}
|
| 457 |
-
else {
|
| 458 |
-
// probably only one shipment for all items, assume the last is most recent
|
| 459 |
-
$shipment = $shipments->getLastItem();
|
| 460 |
-
}
|
| 461 |
-
return $shipment;
|
| 462 |
-
}
|
| 463 |
-
|
| 464 |
}
|
| 66 |
return $this->getData('controller');
|
| 67 |
}
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
/**
|
| 70 |
* Run webservice
|
| 71 |
*
|
| 84 |
$this->fault(401, 'Unauthorized');
|
| 85 |
}
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
try { switch ($this->getController()->getRequest()->getParam('action', 'export')) {
|
| 88 |
case 'export':
|
| 89 |
+
$action = Mage::getModel('auctaneapi/action_export');
|
| 90 |
+
$action->process($this->getController()->getRequest(),
|
| 91 |
+
$this->getController()->getResponse());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
break;
|
| 93 |
case 'shipnotify':
|
| 94 |
+
$action = Mage::getModel('auctaneapi/action_shipnotify');
|
| 95 |
+
$action->process($this->getController()->getRequest());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
// if there hasn't been an error yet the work is done and a "200 OK" is given
|
| 97 |
break;
|
| 98 |
}}
|
| 123 |
');
|
| 124 |
}
|
| 125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
}
|
app/code/community/Auctane/Api/etc/config.xml
CHANGED
|
@@ -19,7 +19,7 @@
|
|
| 19 |
<config>
|
| 20 |
<modules>
|
| 21 |
<Auctane_Api>
|
| 22 |
-
<version>0.
|
| 23 |
</Auctane_Api>
|
| 24 |
</modules>
|
| 25 |
|
|
@@ -154,6 +154,7 @@
|
|
| 154 |
<config>
|
| 155 |
<realm>Auctane ShipStation</realm>
|
| 156 |
<exportPageSize>100</exportPageSize>
|
|
|
|
| 157 |
</config>
|
| 158 |
</auctaneapi>
|
| 159 |
</default>
|
| 19 |
<config>
|
| 20 |
<modules>
|
| 21 |
<Auctane_Api>
|
| 22 |
+
<version>0.6.0</version>
|
| 23 |
</Auctane_Api>
|
| 24 |
</modules>
|
| 25 |
|
| 154 |
<config>
|
| 155 |
<realm>Auctane ShipStation</realm>
|
| 156 |
<exportPageSize>100</exportPageSize>
|
| 157 |
+
<invoiceComment>Issued by Auctane ShipStation.</invoiceComment>
|
| 158 |
</config>
|
| 159 |
</auctaneapi>
|
| 160 |
</default>
|
app/code/community/Auctane/ShipStation/etc/config.xml
CHANGED
|
@@ -19,7 +19,7 @@
|
|
| 19 |
<config>
|
| 20 |
<modules>
|
| 21 |
<Auctane_ShipStation>
|
| 22 |
-
<version>1.3.
|
| 23 |
</Auctane_ShipStation>
|
| 24 |
</modules>
|
| 25 |
|
| 19 |
<config>
|
| 20 |
<modules>
|
| 21 |
<Auctane_ShipStation>
|
| 22 |
+
<version>1.3.6</version>
|
| 23 |
</Auctane_ShipStation>
|
| 24 |
</modules>
|
| 25 |
|
package.xml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Auctane_ShipStation</name>
|
| 4 |
-
<version>1.3.
|
| 5 |
<stability>stable</stability>
|
| 6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
| 7 |
<channel>community</channel>
|
|
@@ -9,11 +9,11 @@
|
|
| 9 |
<summary>ShipStation is a web-based shipping solution that is integrated with the Magento API for retrieving order information and updating shipping details.</summary>
|
| 10 |
<description>ShipStation is a web-based shipping solution that is integrated with the Magento API for retrieving order information and updating shipping details.</description>
|
| 11 |
<notes>Official release.
|
| 12 |
-
|
| 13 |
<authors><author><name>clockworkgeek</name><user>nonproffessional</user><email>nonproffessional@clockworkgeek.com</email></author></authors>
|
| 14 |
-
<date>2013-
|
| 15 |
-
<time>
|
| 16 |
-
<contents><target name="magecommunity"><dir name="Auctane"><dir name="ShipStation"><dir name="Block"><dir name="Adminhtml"><dir name="Linkup"><file name="Form.php" hash="68b7c7bc627e89c304cf630c24aa5164"/></dir><file name="Linkup.php" hash="f280d1f6a26e74244898ea16cdf29c9b"/><file name="Pending.php" hash="6bc7a07b5d0b5192db32fefc55b94b08"/></dir></dir><dir name="Helper"><file name="Data.php" hash="cf2bd6a04dd7b88cae8096c2dd548214"/></dir><file name="LICENSE.html" hash="caf0a79ffb5e4719f9f4de286f253a61"/><file name="LICENSE.txt" hash="59563e7be45096d0833dade102989042"/><file name="LICENSE_AFL.txt" hash="45a399f2095030865fb962263ccd7506"/><dir name="Model"><dir name="Mysql4"><dir name="User"><file name="Collection.php" hash="eee6af3b0c7ecf4f4a42eb0b50605d29"/></dir><file name="User.php" hash="296427f3d22c7cc18c0ece7c1afbc278"/></dir><file name="Observer.php" hash="ffb797d5cfc2f0724d20a44140661bed"/><file name="User.php" hash="9e3fad822b8adcd79dd5438d995fc61a"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ShipstationController.php" hash="c7cd0029ed2a0a46d7b16821b1e6a683"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="3021b17f108f3f50230194ff63975481"/><file name="api.xml" hash="3021b17f108f3f50230194ff63975481"/><file name="config.xml" hash="
|
| 17 |
<compatible/>
|
| 18 |
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
| 19 |
</package>
|
| 1 |
<?xml version="1.0"?>
|
| 2 |
<package>
|
| 3 |
<name>Auctane_ShipStation</name>
|
| 4 |
+
<version>1.3.6</version>
|
| 5 |
<stability>stable</stability>
|
| 6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
|
| 7 |
<channel>community</channel>
|
| 9 |
<summary>ShipStation is a web-based shipping solution that is integrated with the Magento API for retrieving order information and updating shipping details.</summary>
|
| 10 |
<description>ShipStation is a web-based shipping solution that is integrated with the Magento API for retrieving order information and updating shipping details.</description>
|
| 11 |
<notes>Official release.
|
| 12 |
+
Capable of creating invoices and capturing payments when instructed to by ShipStation.</notes>
|
| 13 |
<authors><author><name>clockworkgeek</name><user>nonproffessional</user><email>nonproffessional@clockworkgeek.com</email></author></authors>
|
| 14 |
+
<date>2013-05-07</date>
|
| 15 |
+
<time>14:03:40</time>
|
| 16 |
+
<contents><target name="magecommunity"><dir name="Auctane"><dir name="ShipStation"><dir name="Block"><dir name="Adminhtml"><dir name="Linkup"><file name="Form.php" hash="68b7c7bc627e89c304cf630c24aa5164"/></dir><file name="Linkup.php" hash="f280d1f6a26e74244898ea16cdf29c9b"/><file name="Pending.php" hash="6bc7a07b5d0b5192db32fefc55b94b08"/></dir></dir><dir name="Helper"><file name="Data.php" hash="cf2bd6a04dd7b88cae8096c2dd548214"/></dir><file name="LICENSE.html" hash="caf0a79ffb5e4719f9f4de286f253a61"/><file name="LICENSE.txt" hash="59563e7be45096d0833dade102989042"/><file name="LICENSE_AFL.txt" hash="45a399f2095030865fb962263ccd7506"/><dir name="Model"><dir name="Mysql4"><dir name="User"><file name="Collection.php" hash="eee6af3b0c7ecf4f4a42eb0b50605d29"/></dir><file name="User.php" hash="296427f3d22c7cc18c0ece7c1afbc278"/></dir><file name="Observer.php" hash="ffb797d5cfc2f0724d20a44140661bed"/><file name="User.php" hash="9e3fad822b8adcd79dd5438d995fc61a"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ShipstationController.php" hash="c7cd0029ed2a0a46d7b16821b1e6a683"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="3021b17f108f3f50230194ff63975481"/><file name="api.xml" hash="3021b17f108f3f50230194ff63975481"/><file name="config.xml" hash="8cf015e0374daa0959c959d6a4eabb09"/></dir><dir name="sql"><dir name="auctaneshipstation_setup"><file name="mysql4-install-1.0.0.php" hash="ab307db58a6d8ec97b5efc8d4eedb349"/></dir></dir></dir><dir name="Api"><dir name="Helper"><file name="Data.php" hash="0f99ca3811ec41b3b6672117d449305e"/></dir><file name="LICENSE.html" hash="caf0a79ffb5e4719f9f4de286f253a61"/><file name="LICENSE.txt" hash="59563e7be45096d0833dade102989042"/><file name="LICENSE_AFL.txt" hash="45a399f2095030865fb962263ccd7506"/><dir name="Model"><dir name="Action"><file name="Export.php" hash="a1b0531a6f8002386b4fa07b92573646"/><file name="Shipnotify.php" hash="c831fec09a6d5d0f4dd57b3aeb664ef8"/></dir><dir name="Server"><file name="Adapter.php" hash="c42a5c0968cf9bca320f6823212618b1"/></dir><dir name="System"><dir name="Source"><dir name="Config"><file name="Customattributes.php" hash="a10dff7d323044151803ce2e30313615"/></dir></dir></dir></dir><dir name="controllers"><file name="AuctaneController.php" hash="b7100ac35e0b3a5d737cde7ef96e19c0"/></dir><dir name="etc"><file name="api.xml" hash="3b6279da3c6a4e5fc71c72f1caf94ae1"/><file name="config.xml" hash="d3aa363a20a1cf1b72e5433ae4f3e043"/><file name="system.xml" hash="37d6921d13f1410dbb98f53925fba200"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="auctaneshipstation.xml" hash="d89f79f6de41bb4b23866356f16f48a1"/></dir><dir name="template"><dir name="auctane"><dir name="shipstation"><file name="container.phtml" hash="fb3df40a0baa33a21f6a51d52a90066c"/><file name="launch.phtml" hash="c3fbbc817cbf307fbd500defb2ab9f8e"/><file name="launchform.phtml" hash="b77583e98de80857b185d19a8ce03987"/><file name="linkup.phtml" hash="282a2114ca36efb68f1e681a29739a87"/><file name="pending.phtml" hash="100ec728f3b5ce479e09361bb22960bb"/></dir></dir></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Auctane_ShipStation.csv" hash="0f9582a3124a762cd6d9531f714d2f82"/></dir></target><target name="mageetc"><dir name="modules"><file name="Auctane_ShipStation.xml" hash="bacef7ff4049dece52644ec7be714ee6"/><file name="Auctane_Api.xml" hash="a27b534a3ad08732488959f8bdb72a03"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><file name="shipstation.png" hash="e19a42099ef020edaf7c10d9a068c1c0"/></dir></dir></dir></dir></target></contents>
|
| 17 |
<compatible/>
|
| 18 |
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
| 19 |
</package>
|
