/** * full cancel of the order at shopgate * $data["order"] should set with an object of Mage_Sales_Model_Order * called on event "order_cancel_after" * called from Mage_Sales_Model_Order::cancel() * Uses the cancle_order action in ShopgateMerchantApi * * @see http://wiki.shopgate.com/Merchant_API_cancel_order * @param Varien_Event_Observer $observer * @return bool */ public function cancelOrder(Varien_Event_Observer $observer) { /* @var $order Mage_Sales_Model_Order */ $order = $observer->getEvent()->getOrder(); /* @var $shopgateOrder Shopgate_Framework_Model_Shopgate_Order */ $shopgateOrder = Mage::getModel("shopgate/shopgate_order")->load($order->getId(), "order_id"); if (!$shopgateOrder->getId()) { return true; } if ($order instanceof Mage_Sales_Model_Order) { try { $orderNumber = $shopgateOrder->getShopgateOrderNumber(); $this->_initMerchantApi($order->getStoreId()); // Do nothing if plugin is not active for this store if (!Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_ACTIVE, $this->_config->getStoreViewId())) { return true; } if (!$this->_config->isValidConfig()) { return true; } $cancellationItems = array(); $qtyCancelled = 0; $rd = $shopgateOrder->getShopgateOrderObject(); $orderItems = $order->getItemsCollection(); $rdItem = false; foreach ($orderItems as $orderItem) { /** @var $orderItem Mage_Sales_Model_Order_Item */ if ($rd instanceof ShopgateOrder) { $rdItem = $this->_findItemByProductId($rd->getItems(), $orderItem->getData('product_id')); } if ($orderItem->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE && $orderItem->getQtyCanceled() + $orderItem->getQtyRefunded() > 0 && !$orderItem->getIsVirtual() && $rdItem) { $cancellationItems[] = array("item_number" => $rdItem->getItemNumber(), "quantity" => intval($orderItem->getQtyCanceled()) + intval($orderItem->getQtyRefunded())); $qtyCancelled += intval($orderItem->getQtyCanceled()) + intval($orderItem->getQtyRefunded()); } } if (count($orderItems) > 0 && empty($cancellationItems)) { $order->addStatusHistoryComment('[SHOPGATE] Notice: Credit memo was not sent to Shopgate because no product quantity was affected.'); $order->save(); return true; } $fullCancellation = empty($cancellationItems); $fullCancellation = $fullCancellation || $qtyCancelled == $order->getTotalQtyOrdered(); $cancelShippingCosts = !$shopgateOrder->hasShippedItems($order); /** @var Mage_Sales_Model_Order_Creditmemo $creditMemo */ $creditMemo = $observer->getEvent()->getCreditMemo(); if ($creditMemo) { if ($creditMemo->getShippingAmount() == $order->getShippingAmount()) { $cancelShippingCosts = true; } else { $cancelShippingCosts = false; } } $this->_merchantApi->cancelOrder($shopgateOrder->getShopgateOrderNumber(), $fullCancellation, $cancellationItems, $cancelShippingCosts, "Order was cancelled in Shopsystem!"); Mage::getSingleton('core/session')->addSuccess(Mage::helper("shopgate")->__("[SHOPGATE] Order successfully cancelled at Shopgate.")); $shopgateOrder->setIsCancellationSentToShopgate(true); $shopgateOrder->save(); if (!$shopgateOrder->getIsSentToShopgate() && !$this->_completeShipping($shopgateOrder, $order)) { $this->_logShopgateError("! (#{$orderNumber}) not sent to shopgate and shipping not complete", ShopgateLogger::LOGTYPE_ERROR); } } catch (ShopgateMerchantApiException $e) { if ($e->getCode() == "222") { // order already canceled in shopgate $shopgateOrder->setIsCancellationSentToShopgate(true); $shopgateOrder->save(); } else { // Received error from shopgate server Mage::getSingleton('core/session')->addError(Mage::helper("shopgate")->__("[SHOPGATE] An error occured while trying to cancel the order at Shopgate.<br />Please contact Shopgate support.")); Mage::getSingleton('core/session')->addError("Error: {$e->getCode()} - {$e->getMessage()}"); $this->_logShopgateError("! (#{$orderNumber}) SMA-Error on cancel order! Message: {$e->getCode()} -\n {$e->getMessage()}", ShopgateLogger::LOGTYPE_ERROR); $this->_logShopgateError("! (#{$orderNumber}) SMA-Error on cancel order! Message: {$e->getCode()} -\n {$e->getMessage()}", ShopgateLogger::LOGTYPE_DEBUG); } } catch (Exception $e) { Mage::getSingleton('core/session')->addError(Mage::helper("shopgate")->__("[SHOPGATE] An unknown error occured!<br />Please contact Shopgate support.")); $this->_logShopgateError("! (#{$orderNumber}) SMA-Error on cancel order! Message: {$e->getCode()} -\n {$e->getMessage()}", ShopgateLogger::LOGTYPE_ERROR); $this->_logShopgateError("! (#{$orderNumber}) SMA-Error on cancel order! Message: {$e->getCode()} -\n {$e->getMessage()}", ShopgateLogger::LOGTYPE_DEBUG); } } }
/** * @param ShopgateConfigInterface $config */ public function setup(ShopgateConfigInterface $config) { // needs to check if an old config is present without any access token if ($config->getCustomerNumber() && $config->getShopNumber() && $config->getApiKey() && !$config->getOauthAccessToken()) { // needs to load the non-oauth-url since the new access token needs to be generated using the classic shopgate merchant api authentication $apiUrls = $config->getApiUrls(); $apiUrl = $config->getServer() == 'custom' ? str_replace('/api/merchant2', '/api/merchant', $config->getApiUrl()) : $apiUrls[$config->getServer()][ShopgateConfigInterface::SHOPGATE_AUTH_SERVICE_CLASS_NAME_SHOPGATE]; $smaAuthServiceShopgate = new ShopgateAuthenticationServiceShopgate($config->getCustomerNumber(), $config->getApiKey()); $smaAuthServiceShopgate->setup($config); $classicSma = new ShopgateMerchantApi($smaAuthServiceShopgate, $config->getShopNumber(), $apiUrl); // the "get_shop_info" returns an oauth access token $shopInfo = $classicSma->getShopInfo()->getData(); // set newly generated access token $this->accessToken = $shopInfo['oauth_access_token']; // create a new settings array $shopgateSettingsNew = array($field = 'oauth_access_token' => $shopInfo[$field], $field = 'customer_number' => $shopInfo[$field], $field = 'shop_number' => $shopInfo[$field], $field = 'apikey' => $shopInfo[$field], $field = 'alias' => $shopInfo[$field], $field = 'cname' => $shopInfo[$field]); // save all shop config data to plugin-config using the configs save method $config->load($shopgateSettingsNew); $config->save(array_keys($shopgateSettingsNew), true); } elseif (!$this->accessToken && $config->getOauthAccessToken()) { // this would mean the data was somehow not in sync (should no be happening by default) $this->accessToken = $config->getOauthAccessToken(); } else { // skip this since the connection is fully functional or there has not been made any connection at all, yet // -> missing data (except the oauth access token) is treated as "no valid connection available" // -> in either case there is nothing to do here } }