diff --git a/.travis.yml b/.travis.yml index 2da862d3..badb8653 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,6 @@ env: global: - MAGENTO_DB_ALLOWSAME=1 - SKIP_CLEANUP=1 - - TEST_BASEDIR=.modman/oyst-magento/app/code/community/Oyst/Oyst/Test matrix: - MAGENTO_VERSION="magento-mirror-1.6.2.0" - MAGENTO_VERSION="magento-mirror-1.7.0.2" @@ -67,7 +66,7 @@ install: script: - mkdir -p build/logs - - curl --retry 2 --retry-delay 5 -H "Authorization":"token $GITHUB_TOKEN" -f -sSL https://raw.githubusercontent.com/mehdichaouch/MageTestStand/master/setup.sh | bash + - curl --retry 2 --retry-delay 5 -H "Authorization":"token $GITHUB_TOKEN" -f -sSL https://raw.githubusercontent.com/AOEpeople/MageTestStand//master/setup.sh | bash ## PHP CodeSniffer disable error on exit - vendor/bin/phpcs --config-set ignore_warnings_on_exit 1 ## PHP Copy/Paste Detector diff --git a/README.md b/README.md index 25fc2a23..c3615b72 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Oyst 1-Click plugin for Magento [![Build Status](https://travis-ci.org/oystparis/oyst-1click-magento.svg?branch=master)](https://travis-ci.org/oystparis/oyst-1click-magento) -[![Latest Stable Version](https://img.shields.io/badge/latest-1.12.0-green.svg)](https://github.com/oystparis/oyst-1click-magento/releases) +[![Latest Stable Version](https://img.shields.io/badge/latest-1.13.0-green.svg)](https://github.com/oystparis/oyst-1click-magento/releases/latest) [![Magento = 1.7.x.x](https://img.shields.io/badge/magento-1.7-blue.svg)](#) [![Magento = 1.8.x.x](https://img.shields.io/badge/magento-1.8-blue.svg)](#) [![Magento = 1.9.x.x](https://img.shields.io/badge/magento-1.9-blue.svg)](#) diff --git a/app/code/community/Oyst/OneClick/Block/Adminhtml/Field/LogActions.php b/app/code/community/Oyst/OneClick/Block/Adminhtml/Field/LogActions.php index ae4547dc..77e6eac3 100644 --- a/app/code/community/Oyst/OneClick/Block/Adminhtml/Field/LogActions.php +++ b/app/code/community/Oyst/OneClick/Block/Adminhtml/Field/LogActions.php @@ -35,7 +35,7 @@ class Oyst_OneClick_Block_Adminhtml_Field_LogActions extends Mage_Adminhtml_Bloc */ public function __construct(array $args = array()) { - $this->_logFiles = array('system.log', 'exception.log', Oyst_OneClick_Helper_Data::MODULE_NAME . '.log'); + $this->_logFiles = array('system.log', 'exception.log', Oyst_OneClick_Helper_Data::MODULE_NAME . '.log', 'error_oyst.log'); parent::__construct($args); } diff --git a/app/code/community/Oyst/OneClick/Block/Adminhtml/System/Config/Form/Fieldset/Carrier/Mapping.php b/app/code/community/Oyst/OneClick/Block/Adminhtml/System/Config/Form/Fieldset/Carrier/Mapping.php index 827be035..699daddf 100644 --- a/app/code/community/Oyst/OneClick/Block/Adminhtml/System/Config/Form/Fieldset/Carrier/Mapping.php +++ b/app/code/community/Oyst/OneClick/Block/Adminhtml/System/Config/Form/Fieldset/Carrier/Mapping.php @@ -30,22 +30,26 @@ class Oyst_OneClick_Block_Adminhtml_System_Config_Form_Fieldset_Carrier_Mapping */ public function render(Varien_Data_Form_Element_Abstract $element) { - $html = $this->_getHeaderHtml($element); - $val = $this->getAllCarrierCode(); - if (isset($val) && !empty($val)) { - foreach ($val as $v) { - if (false !== strpos($v['value'], '_about')) { - continue; - } + try { + $html = $this->_getHeaderHtml($element); + $val = $this->getAllCarrierCode(); + if (isset($val) && !empty($val)) { + foreach ($val as $v) { + if (false !== strpos($v['value'], '_about')) { + continue; + } - $html .= $this->getHeadingFieldHtml($element, $v); - $html .= $this->getMappingFieldHtml($element, $v); - $html .= $this->getDelayFieldHtml($element, $v); - $html .= $this->getNameFieldHtml($element, $v); + $html .= $this->getHeadingFieldHtml($element, $v); + $html .= $this->getMappingFieldHtml($element, $v); + $html .= $this->getDelayFieldHtml($element, $v); + $html .= $this->getNameFieldHtml($element, $v); + } } - } - $html .= $this->_getFooterHtml($element); + $html .= $this->_getFooterHtml($element); + } catch (Exception $e) { + $html = ''; + } return $html; } @@ -185,7 +189,7 @@ protected function getDelayFieldHtml($fieldset, $group) 'default' => 1, 'inherit' => $inherit, 'value' => $data, - 'class' => 'validate-number validate-oyst-shipment-delay', + //'class' => 'validate-number validate-oyst-shipment-delay', 'comment' => Mage::helper('oyst_oneclick')->__('Value in hours'), 'can_use_default_value' => $this->getForm()->canUseDefaultValue($e), 'can_use_website_value' => $this->getForm()->canUseWebsiteValue($e), diff --git a/app/code/community/Oyst/OneClick/Block/Checkout/Tracking.php b/app/code/community/Oyst/OneClick/Block/Checkout/Tracking.php new file mode 100644 index 00000000..41ee1502 --- /dev/null +++ b/app/code/community/Oyst/OneClick/Block/Checkout/Tracking.php @@ -0,0 +1,83 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/** + * Checkout Tracking Block + */ +class Oyst_OneClick_Block_Checkout_Tracking extends Mage_Core_Block_Abstract +{ + protected $_order; + + protected function _toHtml() + { + if (!$this->getOrder()->getId()) { + return ''; + } + + return ''; + } + + protected function getOrder() + { + if (!isset($this->_order)) { + $this->_order = Mage::getModel('sales/order')->load(Mage::getSingleton('checkout/session')->getLastOrderId()); + } + + return $this->_order; + } + + protected function getTrackerBaseUrl() + { + $isCustomEnvProd = Mage::getStoreConfig('oyst/oneclick/mode') == 'custom'; + + foreach(array('staging', 'sandbox', 'test') as $env) { + if (strpos(Mage::getStoreConfig('oyst/oneclick/api_url'), $env) !== false) { + $isCustomEnvProd = false; + break; + } + } + + if (Mage::getStoreConfig('oyst/oneclick/mode') == 'prod' || $isCustomEnvProd) { + return 'https://tkr.11rupt.io/'; + } else { + return 'https://staging-tkr.11rupt.eu/'; + } + } + + protected function getExtraParameters() + { + $extraParameters = array( + 'extra_parameters[amount]='.$this->getOrder()->getGrandTotal(), + 'extra_parameters[paymentMethod]='.$this->getOrder()->getPayment()->getMethod(), + 'extra_parameters[currency]='.$this->getOrder()->getOrderCurrencyCode(), + 'extra_parameters[referrer]='.urlencode(Mage::helper('core/url')->getCurrentUrl()), + 'extra_parameters[userEmail]='.urlencode($this->getOrder()->getCustomerEmail()), + 'extra_parameters[orderId]='.$this->getOrder()->getIncrementId(), + ); + + if ($this->getOrder()->getCustomerId()) { + $extraParameters['extra_parameters[userId]'] = $this->getOrder()->getCustomerId(); + } + + return implode('&', $extraParameters); + } + + protected function getParameters() + { + $parameters = array( + 'version=1', + 'type=track', + 'event=Confirmation%20Displayed' + ); + + return implode('&', $parameters); + } +} \ No newline at end of file diff --git a/app/code/community/Oyst/OneClick/Block/OneClick.php b/app/code/community/Oyst/OneClick/Block/OneClick.php index 065fd80a..e215c7a8 100644 --- a/app/code/community/Oyst/OneClick/Block/OneClick.php +++ b/app/code/community/Oyst/OneClick/Block/OneClick.php @@ -40,8 +40,11 @@ public function isButtonEnabled() return false; } - // TODO Change code attribute to avoid confusions - if ($this->getProduct()->getIsOneclickActiveOnProduct()) { + if (Mage::getStoreConfig('oyst/oneclick/force_button_display_on_product')) { + return true; + } + + if ($this->getProduct()->getIsOneclickDisableOnProduct()) { return false; } @@ -92,7 +95,7 @@ public function getButtonCustomization($path = '') { $buttonCustomization = ''; - $genericCustomizationAttributes = array('theme', 'color', 'rounded', 'smart'); + $genericCustomizationAttributes = array('theme', 'color', 'rounded', 'smart', 'sticky'); foreach ($genericCustomizationAttributes as $customizationAttribute) { $config = Mage::getStoreConfig('oyst/oneclick/button_' . $customizationAttribute); @@ -100,7 +103,7 @@ public function getButtonCustomization($path = '') continue; } - if (in_array($customizationAttribute, array('rounded', 'smart'))) { + if (in_array($customizationAttribute, array('rounded', 'smart', 'sticky'))) { $config = filter_var($config, FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false'; } @@ -118,17 +121,6 @@ public function getButtonCustomization($path = '') $buttonCustomization .= sprintf(" data-" . $customizationAttribute . "='%s'", $config); } - $specificCustomizationAttributes = array('height', 'width'); - - foreach ($specificCustomizationAttributes as $customizationAttribute) { - $config = Mage::getStoreConfig('oyst/oneclick/' . $path . 'button_' . $customizationAttribute); - if (empty($config)) { - continue; - } - - $buttonCustomization .= sprintf(" data-" . $customizationAttribute . "='%s'", $config); - } - return $buttonCustomization; } diff --git a/app/code/community/Oyst/OneClick/Helper/Data.php b/app/code/community/Oyst/OneClick/Helper/Data.php index 9d84f3f8..f2520d6b 100644 --- a/app/code/community/Oyst/OneClick/Helper/Data.php +++ b/app/code/community/Oyst/OneClick/Helper/Data.php @@ -26,6 +26,10 @@ class Oyst_OneClick_Helper_Data extends Mage_Core_Helper_Abstract const XML_PATH_RESTRICT_ALLOW_IPS = 'restrict_allow_ips'; + const STATUS_OYST_PAYMENT_ACCEPTED = 'oyst_payment_accepted'; + + const STATUS_OYST_PAYMENT_FRAUD = 'oyst_payment_fraud'; + /** * Get config from Magento * @@ -56,8 +60,8 @@ public function getModuleVersion() */ public function getSdkVersion() { - /** @var Oyst_OneClick_Model_Api $oystModel */ - $oystModel = Mage::getModel('oyst_oneclick/api'); + /** @var Oyst_OneClick_Model_ApiWrapper_Client $oystModel */ + $oystModel = Mage::getModel('oyst_oneclick/apiWrapper_client'); return $oystModel->getSdkVersion(); } @@ -109,8 +113,8 @@ public function setIsInitialized($identifier, $isInitialized = true) public function isApiKeyValid() { try { - /** @var Oyst_OneClick_Model_Api $api */ - $api = Mage::getModel('oyst_oneclick/api'); + /** @var Oyst_OneClick_Model_ApiWrapper_Client $api */ + $api = Mage::getModel('oyst_oneclick/apiWrapper_client'); $api->isApiKeyValid(); } catch (Exception $e) { /** @var Oyst_OneClick_Helper_Data $oystHelper */ @@ -185,28 +189,6 @@ public function isPaymentMethodOyst(Mage_Sales_Model_Order $order) return false !== strpos($order->getPayment()->getMethod(), $freepayPaymentMethod->getCode()); } - /** - * Get metadata string. - * - * @return null|string - */ - public function getTrackingMeta() - { - return '' . PHP_EOL - . '' . PHP_EOL - . '' . PHP_EOL - . '' . PHP_EOL - . '' . PHP_EOL - . '' . PHP_EOL - . '' . PHP_EOL; - } - /** * Checks for open refund transaction * @@ -284,4 +266,36 @@ public function isIpAllowed($storeId = null) return $allow; } + + public function handleQuoteErrors(Mage_Sales_Model_Quote $quote) + { + if ($quote->getHasError()) { + $errorMessages = array(); + foreach ($quote->getErrors() as $error) { + $errorMessages[] = $error->getCode(); + } + throw new Mage_Checkout_Exception(implode('\n', $errorMessages)); + } + + return $this; + } + + public function addQuoteExtraData($quote, $key, $value) + { + $extraData = json_decode($quote->getOystExtraData(), true); + + if(empty($extraData)) { + $extraData = array(); + } + + $extraData[$key] = $value; + + $quote->setOystExtraData(json_encode($extraData)); + } + + public function getSalesObjectExtraData($salesObject, $key) + { + $extraData = json_decode($salesObject->getOystExtraData(), true); + return isset($extraData[$key]) ? $extraData[$key] : null; + } } diff --git a/app/code/community/Oyst/OneClick/Model/ApiWrapper/AbstractType.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/AbstractType.php new file mode 100644 index 00000000..0366a256 --- /dev/null +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/AbstractType.php @@ -0,0 +1,21 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +class Oyst_OneClick_Model_ApiWrapper_AbstractType extends Mage_Core_Model_Abstract +{ + /** @var Oyst_OneClick_Model_ApiWrapper_Client $_oystClient */ + protected $_oystClient; + + public function __construct() + { + $this->_oystClient = Mage::getModel('oyst_oneclick/apiWrapper_client'); + } +} diff --git a/app/code/community/Oyst/OneClick/Model/Api.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Client.php similarity index 97% rename from app/code/community/Oyst/OneClick/Model/Api.php rename to app/code/community/Oyst/OneClick/Model/ApiWrapper/Client.php index 24cd0875..850e0c1d 100644 --- a/app/code/community/Oyst/OneClick/Model/Api.php +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Client.php @@ -12,13 +12,11 @@ use Oyst\Api\OystApiClientFactory; use Oyst\Api\OystCatalogApi; use Oyst\Classes\OystUserAgent; -use Oyst\Api\OystPaymentApi; -use Oyst\Classes\OystPrice; /** * API Model */ -class Oyst_OneClick_Model_Api extends Mage_Core_Model_Abstract +class Oyst_OneClick_Model_ApiWrapper_Client extends Mage_Core_Model_Abstract { /* * API length diff --git a/app/code/community/Oyst/OneClick/Model/Catalog/ApiWrapper.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Catalog.php similarity index 63% rename from app/code/community/Oyst/OneClick/Model/Catalog/ApiWrapper.php rename to app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Catalog.php index 5f0efc1c..6b192874 100644 --- a/app/code/community/Oyst/OneClick/Model/Catalog/ApiWrapper.php +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Catalog.php @@ -11,18 +11,12 @@ use Oyst\Api\OystApiClientFactory; use Oyst\Api\OystCatalogApi; -use Oyst\Classes\OystCarrier; -use Oyst\Classes\OneClickShipment; -use Oyst\Classes\ShipmentAmount; /** - * Catalog ApiWrapper Model + * ApiWrapper_Type_Catalog Model */ -class Oyst_OneClick_Model_Catalog_ApiWrapper extends Mage_Core_Model_Abstract +class Oyst_OneClick_Model_ApiWrapper_Type_Catalog extends Oyst_OneClick_Model_ApiWrapper_AbstractType { - /** @var Oyst_OneClick_Model_Api $_oystClient */ - protected $_oystClient; - /** @var OystCatalogApi $_catalogApi */ protected $_catalogApi; @@ -33,7 +27,7 @@ class Oyst_OneClick_Model_Catalog_ApiWrapper extends Mage_Core_Model_Abstract public function __construct() { - $this->_oystClient = Mage::getModel('oyst_oneclick/api'); + parent::__construct(); $this->_catalogApi = $this->_oystClient->getClient($this->_type); } @@ -56,13 +50,9 @@ protected function _getConfig($code) */ public function getShipmentTypes() { - try { - if (!isset($this->_shipmentTypes)) { - $this->_shipmentTypes = $this->_catalogApi->getShipmentTypes(); - $this->_oystClient->validateResult($this->_catalogApi); - } - } catch (Exception $e) { - Mage::logException($e); + if (!isset($this->_shipmentTypes)) { + $this->_shipmentTypes = $this->_catalogApi->getShipmentTypes(); + $this->_oystClient->validateResult($this->_catalogApi); } return $this->_shipmentTypes; diff --git a/app/code/community/Oyst/OneClick/Model/OneClick/ApiWrapper.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/OneClick.php similarity index 60% rename from app/code/community/Oyst/OneClick/Model/OneClick/ApiWrapper.php rename to app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/OneClick.php index 08939295..da006a1d 100644 --- a/app/code/community/Oyst/OneClick/Model/OneClick/ApiWrapper.php +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/OneClick.php @@ -15,20 +15,19 @@ use Oyst\Classes\OneClickCustomization; use Oyst\Classes\OneClickNotifications; use Oyst\Classes\OneClickOrderParams; +use Oyst\Classes\OystAddress; +use Oyst\Classes\OystUser; /** - * OneClick ApiWrapper Model + * ApiWrapper_Type_OneClick Model */ -class Oyst_OneClick_Model_OneClick_ApiWrapper extends Oyst_OneClick_Model_Api +class Oyst_OneClick_Model_ApiWrapper_Type_OneClick extends Oyst_OneClick_Model_ApiWrapper_AbstractType { // In modal timer is 5 minutes, 6 is to ensure it's over const CONFIG_XML_PATH_OYST_CHECKOUT_MODAL_TIMER = 'oyst/oneclick/checkout_modal_timer'; const CONFIG_XML_PATH_OYST_PENDING_STATUS_FAILOVER_TIMER = 'oyst/oneclick/pending_status_failover_timer'; - /** @var Oyst_OneClick_Model_Api $oystClient */ - protected $oystClient; - /** @var OystOneClickApi $oneClickApi */ protected $oneClickApi; @@ -39,8 +38,9 @@ class Oyst_OneClick_Model_OneClick_ApiWrapper extends Oyst_OneClick_Model_Api public function __construct() { - $this->oystClient = Mage::getModel('oyst_oneclick/api'); - $this->oneClickApi = $this->oystClient->getClient($this->type); + parent::__construct(); + $this->oneClickApi = $this->_oystClient->getClient($this->type); + $this->quote = Mage::getSingleton('checkout/cart')->getQuote(); } /** @@ -66,44 +66,31 @@ protected function getConfig($code) */ public function authorizeOrder($dataFormated) { - Mage::helper('oyst_oneclick')->log('$dataFormated'); - Mage::helper('oyst_oneclick')->log($dataFormated); - - $this->getCartItems($dataFormated); - /** @var Oyst_OneClick_Model_Catalog $oystCatalog */ $oystCatalog = Mage::getModel('oyst_oneclick/catalog'); $oystProducts = $oystCatalog->getOystProducts($dataFormated); - if (count($oystProducts) === 0) { - $oystProducts[] = $oystCatalog->addDummyOystProduct(); - } if (isset($oystProducts['has_error'])) { return $oystProducts; } $notifications = $this->getOneClickNotifications(); - $dataFormated['preload'] = filter_var($dataFormated['preload'], FILTER_VALIDATE_BOOLEAN); - - // Book initial quantity - if (!$dataFormated['preload'] && $this->getConfig('should_ask_stock')) { - $notifications->addEvent('order.stock.released'); - } - $orderParams = $this->getOneClickOrderParams($dataFormated); + $user = $this->getUser(); + $orderParams = $this->getOneClickOrderParams(); $context = $this->getContext(); - $customization = $this->getOneClickCustomization($dataFormated); + $customization = $this->getOneClickCustomization(); try { $response = $this->oneClickApi->authorizeOrderV2( $oystProducts, $notifications, - null, + $user, $orderParams, $context, $customization ); - $this->oystClient->validateResult($this->oneClickApi); + $this->_oystClient->validateResult($this->oneClickApi); } catch (Exception $e) { Mage::logException($e); } @@ -120,7 +107,6 @@ private function getOneClickNotifications() { $notifications = new OneClickNotifications(); $notifications->setShouldAskShipments(true); - $notifications->setShouldAskStock($this->getConfig('should_ask_stock')); $notifications->setUrl($this->getConfig('notification_url')); if ($notifications->isShouldAskShipments()) { @@ -131,16 +117,57 @@ private function getOneClickNotifications() } /** - * Get OneClickOrderParams configuration. + * Get OystUser. * - * @param array $dataFormated + * @return null|OystUser + */ + protected function getUser() + { + $oystUser = null; + + if (Mage::getSingleton('customer/session')->isLoggedIn()) { + /** @var Mage_Customer_Model_Customer $customer */ + $customer = Mage::getSingleton('customer/session')->getCustomer(); + + $oystUser = new OystUser(); + + $oystUser + ->setFirstName($customer->getFirstname()) + ->setLastName($customer->getLastname()) + ->setEmail($customer->getEmail()); + + /** @var Mage_Customer_Model_Address $address */ + $address = $customer->getDefaultShippingAddress(); + + if ($address) { + $oystAddress = new OystAddress(); + $oystAddress + ->setFirstName($address->getFirstname()) + ->setLastName($address->getLastname()) + ->setCompanyName($address->getCompany()) + ->setStreet($address->getStreet()) + ->setPostCode($address->getPostcode()) + ->setCity($address->getCity()) + ->setCountry($address->getCountry()) + ->setComplementary($address->getComplementary()); + + $oystUser->addAddress($address); + } + } + + return $oystUser; + } + + /** + * Get OneClickOrderParams configuration. * * @return OneClickOrderParams */ - private function getOneClickOrderParams($dataFormated) + private function getOneClickOrderParams() { $orderParams = new OneClickOrderParams(); $orderParams->setManageQuantity($this->getConfig('allow_quantity_change')); + $orderParams->setIsMaterialized(!$this->quote->isVirtual()); if ($delay = Mage::getStoreConfig('oyst/oneclick/order_delay')) { $orderParams->setDelay($delay); @@ -150,9 +177,7 @@ private function getOneClickOrderParams($dataFormated) $orderParams->setShouldReinitBuffer($reinitialize); } - if (isset($dataFormated['isCheckoutCart'])) { - $orderParams->setIsCheckoutCart(true); - } + $orderParams->setIsCheckoutCart(true); if ($allowDiscountCoupon = Mage::getStoreConfig('oyst/oneclick/allow_discount_coupon_from_modal')) { $orderParams->setAllowDiscountCoupon($allowDiscountCoupon); @@ -194,89 +219,20 @@ private function getContext() /** * Get one click customization. * - * @param array $dataFormated - * * @return OneClickCustomization */ - private function getOneClickCustomization($dataFormated) + private function getOneClickCustomization() { $customization = new OneClickCustomization(); - if (isset($dataFormated['isCheckoutCart'])) { - $customization->setCta( - Mage::getStoreConfig('oyst/oneclick/checkout_cart_cta_label', Mage::app()->getStore()->getStoreId()), - Mage::helper('oyst_oneclick')->getRedirectUrl() - ); - } + $customization->setCta( + Mage::getStoreConfig('oyst/oneclick/checkout_cart_cta_label', Mage::app()->getStore()->getStoreId()), + Mage::helper('oyst_oneclick')->getRedirectUrl() + ); return $customization; } - /** - * Get cart items - * - * @param array $dataFormated - */ - public function getCartItems(&$dataFormated) - { - $products = array(); - - /** @var Mage_Sales_Model_Quote quote */ - if (!isset($this->quote) - || $this->quote->getId() != $dataFormated['quoteId'] - ) { - $this->quote = Mage::getModel('sales/quote')->load($dataFormated['quoteId']); - } - - /** @var Mage_Sales_Model_Quote $items */ - $items = $this->quote->getAllVisibleItems(); - - $returnItems = array(); - - /** @var Mage_Sales_Model_Quote_Item $item */ - foreach ($items as $item) { - if ($item->getHasChildren()) { - foreach ($item->getChildren() as $child) { - $returnItems[] = $child; - } - } else { - $returnItems[] = $item; - } - } - - /** @var Mage_Sales_Model_Quote_Item $item */ - foreach ($returnItems as $item) { - if (!is_null($item->getParentItem())) { - $products[] = array( - 'productId' => $item->getParentItem()->getProductId(), - 'quantity' => $item->getParentItem()->getQty(), - 'configurableProductChildId' => $item->getProductId(), - ); - } else { - $products[] = array( - 'productId' => $item->getProductId(), - 'quantity' => $item->getQty(), - ); - } - } - - if (isset($dataFormated['substract_quote_items_qtys'])) { - foreach ($dataFormated['substract_quote_items_qtys']['products'] as $memoProduct) { - foreach ($products as $key => $product) { - if ($memoProduct['productId'] == $product['productId']) { - $products[$key]['quantity'] = $products[$key]['quantity'] - $memoProduct['quantity']; - if ($products[$key]['quantity'] == 0) { - unset($products[$key]); - } - } - } - } - } - - $dataFormated['products'] = $products; - Mage::helper('oyst_oneclick')->log($dataFormated['products']); - } - /** * Validate Oyst order status * @@ -286,8 +242,8 @@ public function getCartItems(&$dataFormated) */ public function isOystOrderStatusValid($oystOrderId) { - /** @var Oyst_OneClick_Model_Order_ApiWrapper $orderApi */ - $orderApi = Mage::getModel('oyst_oneClick/order_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Order $orderApi */ + $orderApi = Mage::getModel('oyst_oneclick/apiWrapper_type_order'); try { $response = $orderApi->getOrder($oystOrderId); diff --git a/app/code/community/Oyst/OneClick/Model/Order/ApiWrapper.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Order.php similarity index 90% rename from app/code/community/Oyst/OneClick/Model/Order/ApiWrapper.php rename to app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Order.php index 7fbbe2c0..3e148381 100644 --- a/app/code/community/Oyst/OneClick/Model/Order/ApiWrapper.php +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Order.php @@ -14,13 +14,10 @@ use Oyst\Classes\OystPrice; /** - * Order ApiWrapper Model + * ApiWrapper_Type_Order Model */ -class Oyst_OneClick_Model_Order_ApiWrapper extends Mage_Core_Model_Abstract +class Oyst_OneClick_Model_ApiWrapper_Type_Order extends Oyst_OneClick_Model_ApiWrapper_AbstractType { - /** @var Oyst_OneClick_Model_Api $_oystClient */ - protected $_oystClient; - /** @var OystOrderApi $_orderApi */ protected $_orderApi; @@ -28,7 +25,7 @@ class Oyst_OneClick_Model_Order_ApiWrapper extends Mage_Core_Model_Abstract public function __construct() { - $this->_oystClient = Mage::getModel('oyst_oneclick/api'); + parent::__construct(); $this->_orderApi = $this->_oystClient->getClient($this->_type); } diff --git a/app/code/community/Oyst/OneClick/Model/Payment/ApiWrapper.php b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Payment.php similarity index 87% rename from app/code/community/Oyst/OneClick/Model/Payment/ApiWrapper.php rename to app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Payment.php index 0bcd3e2f..b04fd960 100644 --- a/app/code/community/Oyst/OneClick/Model/Payment/ApiWrapper.php +++ b/app/code/community/Oyst/OneClick/Model/ApiWrapper/Type/Payment.php @@ -14,9 +14,9 @@ use Oyst\Api\OystOneClickApi; /** - * Payment_ApiWrapper Model + * ApiWrapper_Type_Payment Model */ -class Oyst_OneClick_Model_Payment_ApiWrapper extends Mage_Core_Model_Abstract +class Oyst_OneClick_Model_ApiWrapper_Type_Payment extends Oyst_OneClick_Model_ApiWrapper_AbstractType { /** * Hard coded currency @@ -25,15 +25,12 @@ class Oyst_OneClick_Model_Payment_ApiWrapper extends Mage_Core_Model_Abstract const TYPE = OystApiClientFactory::ENTITY_PAYMENT; - /** @var Oyst_OneClick_Model_Api $_oystClient */ - protected $_oystClient; - /** @var OystOneClickApi $_oneClickApi */ protected $_oneClickApi; public function __construct() { - $this->_oystClient = Mage::getModel('oyst_oneclick/api'); + parent::__construct(); $this->_oneClickApi = $this->_oystClient->getClient(self::TYPE); } diff --git a/app/code/community/Oyst/OneClick/Model/Cart.php b/app/code/community/Oyst/OneClick/Model/Cart.php index 509ebd96..235b89b8 100644 --- a/app/code/community/Oyst/OneClick/Model/Cart.php +++ b/app/code/community/Oyst/OneClick/Model/Cart.php @@ -16,18 +16,23 @@ class Oyst_OneClick_Model_Cart { public function initOystCheckout($params) { + Mage::helper('oyst_oneclick')->log('$params'); + Mage::helper('oyst_oneclick')->log($params); + if (!empty($params['add_to_cart_form']) && !$params['preload'] ) { - $substractQuoteItemsQtys = array('quoteId' => $params['quoteId']); - Mage::getModel('oyst_oneclick/oneClick_apiWrapper')->getCartItems($substractQuoteItemsQtys); - $params['substract_quote_items_qtys'] = $substractQuoteItemsQtys; - $this->_addToCart($params['add_to_cart_form']); unset($params['form_key']); } - $response = $this->_authorizeOrder($params); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_OneClick $response */ + $response = Mage::getModel('oyst_oneclick/apiWrapper_type_oneClick')->authorizeOrder($params); + + if (empty($response)) { + throw new Exception(Mage::helper('oyst_oneclick')->__('Invalid Authorize Order Response.')); + } + return $response; } @@ -43,6 +48,7 @@ protected function _addToCart($addToCartFormParams) } $product = $this->_initProduct($addToCartFormParams); + if (!$product) { throw new Exception(Mage::helper('oyst_oneclick')->__('Product is not available')); } @@ -54,15 +60,17 @@ protected function _addToCart($addToCartFormParams) $cart->addProductsByIds(explode(',', $related)); } - Mage::dispatchEvent('oyst_oneclick_checkout_type_oyst_add_to_cart', array('cart' => $cart, 'add_to_cart_form_params' => $addToCartFormParams)); + Mage::dispatchEvent('oyst_oneclick_model_cart_add_to_cart', array('cart' => $cart, 'add_to_cart_form_params' => $addToCartFormParams)); $cart->save(); + return true; } protected function _initProduct($addToCartFormParams) { - $productId = isset($addToCartFormParams['product']) ? $addToCartFormParams['product'] : null; + $productId = isset($addToCartFormParams['product']) ? (int) $addToCartFormParams['product'] : null; + if ($productId) { $product = Mage::getModel('catalog/product') ->setStoreId(Mage::app()->getStore()->getId()) @@ -71,16 +79,26 @@ protected function _initProduct($addToCartFormParams) return $product; } } + return false; } - protected function _authorizeOrder($params) + /** + * Mage_Sales_Model_Quote_Address caches items after each collectTotals call. Some extensions calls collectTotals + * after adding new item to quote in observers. So we need clear this cache before adding new item to quote. + */ + public function resetCartForSave() { - $response = Mage::getModel('oyst_oneclick/oneClick_apiWrapper')->authorizeOrder($params); - if (empty($response)) { - throw new Exception(Mage::helper('oyst_oneclick')->__('Invalid Authorize Order Response.')); - } + $cart = Mage::getSingleton('checkout/cart'); - return $response; + $cart->getQuote()->setDataChanges(true); + $cart->getQuote()->setTotalsCollectedFlag(false); + + foreach ($cart->getQuote()->getAllAddresses() as $address) { + /** @var $address Mage_Sales_Model_Quote_Address */ + $address->unsetData('cached_items_all'); + $address->unsetData('cached_items_nominal'); + $address->unsetData('cached_items_nonominal'); + } } } diff --git a/app/code/community/Oyst/OneClick/Model/Catalog.php b/app/code/community/Oyst/OneClick/Model/Catalog.php index fb84cfa5..74aaf8aa 100644 --- a/app/code/community/Oyst/OneClick/Model/Catalog.php +++ b/app/code/community/Oyst/OneClick/Model/Catalog.php @@ -13,7 +13,6 @@ use Oyst\Classes\OneClickMerchantDiscount; use Oyst\Classes\OneClickOrderCartEstimate; use Oyst\Classes\OneClickShipmentCatalogLess; -use Oyst\Classes\OneClickStock; use Oyst\Classes\OystCarrier; use Oyst\Classes\OystCategory; use Oyst\Classes\OystPrice; @@ -33,21 +32,9 @@ class Oyst_OneClick_Model_Catalog extends Mage_Core_Model_Abstract Mage_Catalog_Model_Product_Type::TYPE_SIMPLE, Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE, Mage_Catalog_Model_Product_Type::TYPE_GROUPED, - //Mage_Catalog_Model_Product_Type::TYPE_BUNDLE, - //Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL, - //Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE, - ); - - /** - * Translate Product attribute for Oyst <-> Magento - * - * @var array - */ - protected $productAttrTranslate = array( - 'status' => array( - 'lib_property' => 'active', - 'type' => 'bool', - ), + Mage_Catalog_Model_Product_Type::TYPE_BUNDLE, + Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL, + Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE, ); /** @@ -55,54 +42,20 @@ class Oyst_OneClick_Model_Catalog extends Mage_Core_Model_Abstract * * @var array */ - protected $customAttributesCode = array('color', 'size'); - - /** - * Selected system attribute code - * - * @var array - */ - protected $systemSelectedAttributesCode = array(); - - /** - * Variations attribute code - * - * @var array - */ - protected $variationAttributesCode = array('price', 'final_price'); + protected $customAttributesCode = array(); /** - * User defined attribute code + * Custom attribute code * * @var array */ - protected $userDefinedAttributeCode = array(); - - /** - * @var array - */ - protected $productsIds = null; - - /** - * @var array - */ - protected $productsQuantities = null; - - /** - * @var array - */ - protected $products = array(); + protected $configurableAttributesCode = array(); /** * @var int */ protected $configurableProductChildId = null; - /** - * @var null|Mage_CatalogInventory_Model_Stock_Item - */ - private $stockItem = null; - /** * @var bool Used to check if it's the first api call to display the button */ @@ -143,14 +96,7 @@ public function processNotification($event, $apiData) // Create new notification in db with status 'start' /** @var Oyst_OneClick_Model_Notification $notification */ $notification = Mage::getModel('oyst_oneclick/notification'); - $notification->setData(array( - 'event' => $event, - 'oyst_data' => Zend_Json::encode($apiData), - 'status' => Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_START, - 'created_at' => Mage::getModel('core/date')->gmtDate(), - 'executed_at' => Mage::getModel('core/date')->gmtDate(), - )); - $notification->save(); + $notification->registerNotificationStart($event, $apiData); Mage::helper('oyst_oneclick')->log('Start processing notification: ' . $notification->getNotificationId()); // Do action for each event type @@ -159,16 +105,6 @@ public function processNotification($event, $apiData) $response = $this->cartEstimate($apiData); break; - // Reduce qty in order or cancel booking - case 'order.stock.released': - $response = $this->stockReleased($apiData); - break; - - // Increase qty in order - case 'order.stock.book': - $response = $this->stockBook($apiData); - break; - default: $response = ''; Mage::helper('oyst_oneclick')->log('No action defined for event ' . $event); @@ -176,99 +112,16 @@ public function processNotification($event, $apiData) } // Save new status and result in db - $notification->setStatus(Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_FINISHED) + $notification ->setMageResponse($response) - ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) - ->save(); + ->registerNotificationFinish(); Mage::helper('oyst_oneclick')->log('End processing notification: ' . $notification->getNotificationId()); return $response; } /** - * Get products. - * - * @param array $data Products send from ajax call - * - * @return Mage_Catalog_Model_Resource_Product_Collection|null - */ - private function getProducts($data) - { - $childrenIds = $stockFilter = array(); - - foreach ($data as $item) { - $index = 'productId'; - - if (array_key_exists('configurableProductChildId', $item) && $item['configurableProductChildId']) { - $childrenIds[$item['configurableProductChildId']] = $item['productId']; - $index = 'configurableProductChildId'; - } - - $this->products[$item['productId']]['quantity'] = $stockFilter[$item[$index]] = $item['quantity']; - } - - if (!count($this->products) - || (!$this->checkItemsQty($stockFilter) && !$this->isPreload) - ) { - return array(); - } - - $products = $this->getProductCollection(array_keys($this->products)); - - if (count($childrenIds)) { - $childProducts = $this->getProductCollection(array_keys($childrenIds)); - - foreach ($childProducts as $childProduct) { - $this->products[$childrenIds[$childProduct->getId()]]['childProduct'] = $childProduct; - } - } - - return $products; - } - - /** - * Get products collection. - * - * @param array $data Product Ids - * - * @return Mage_Catalog_Model_Resource_Product_Collection - */ - private function getProductCollection($data) - { - $products = Mage::getResourceModel('catalog/product_collection') - ->addFieldToFilter('entity_id', array('in' => $data)) - ->addFinalPrice() - ->addAttributeToSelect('*'); - - return $products; - } - - /** - * Check items quantity. - * - * @param array $data Product Ids - * - * @return bool - */ - private function checkItemsQty($data) - { - $stockItems = Mage::getModel('cataloginventory/stock_item') - ->getCollection() - ->addFieldToFilter('product_id', array('in' => array_keys($data))) - ->addStockFilter(Mage::getModel('cataloginventory/stock')); - - foreach ($stockItems as $stockItem) { - $checkQuoteItemQty = $stockItem->checkQuoteItemQty($data[$stockItem->getProductId()], $stockItem->getQty()); - if ($checkQuoteItemQty->getData('has_error')) { - return false; - } - } - - return true; - } - - /** - * Return OystProduct array + * Return OystProduct array. * * @param array $dataFormated * @@ -276,162 +129,106 @@ private function checkItemsQty($data) */ public function getOystProducts($dataFormated) { - $this->isPreload = filter_var($dataFormated['preload'], FILTER_VALIDATE_BOOLEAN); + $oystProducts = array(); - $products = $this->getProducts($dataFormated['products']); + if ($this->isPreload = $dataFormated['preload']) { + $oystProducts[] = $this->addDummyOystProduct(); + } else { + $this->loadCustomAttributesCode(); - $this->userDefinedAttributeCode = $this->getUserDefinedAttributeCode(); - $this->systemSelectedAttributesCode = $this->getSystemSelectedAttributeCode(); + /** @var Mage_Sales_Model_Quote $quote */ + $quote = $this->getQuote(); - $productsFormated = array(); - foreach ($products as $product) { - if (isset($this->products[$product->getId()]['childProduct']) && - ($childId = $this->products[$product->getId()]['childProduct']->getId())) { - $this->configurableProductChildId = $childId; - } + /** @var Mage_Sales_Model_Quote_Item $quoteItem */ + foreach ($quote->getAllVisibleItems() as $quoteItem) { + if ($quoteItem->getData('is_free_product') + || $quoteItem->getData('oyst_skip_item_in_authorize')) { + continue; + } - $quantity = $this->products[$product->getId()]['quantity']; - $productsFormated[] = $this->format(array($product), $quantity); + if ($quoteItem->getProduct()->isConfigurable()) { + $parentQuoteItem = $quote->getItemsCollection()->getItemByColumnValue('parent_item_id', $quoteItem->getId()); + $this->configurableProductChildId = $parentQuoteItem->getProductId(); + } - // Book initial quantity - if (!$this->isPreload && $this->getConfig('should_ask_stock') && 0 !== $quantity) { - $productId = isset($this->configurableProductChildId) ? $this->configurableProductChildId : $product->getId(); - $this->stockItemToBook($productId, $quantity); - Mage::helper('oyst_oneclick')->log( - sprintf('Book initial qty %s for productId %s', $quantity, $productId) - ); - } + $oystProducts[] = $this->format($quoteItem); - $this->configurableProductChildId = null; + $this->configurableProductChildId = null; + $this->configurableAttributesCode = array(); + } } - return $productsFormated; + return $oystProducts; } /** * Transform Database Data to formatted product * - * @param Mage_Catalog_Model_Product[] $products - * @param int $qty + * @param Mage_Sales_Model_Quote_Item $quoteItem * * @return OystProduct */ - protected function format($products, $qty = null) + protected function format($quoteItem) { - $oystProduct = $this->addDummyOystProduct(); - - foreach ($products as $product) { - if (!$product->isConfigurable() && !is_null($this->configurableProductChildId) && $product->getId() != $this->configurableProductChildId) { - continue; - } - - // this price is overwritten later with taxes and others stuff - $price = new OystPrice(1, $this->getCatalogBaseCurrencyCode()); - - $qty = is_null($qty) ? 1 : $qty; - - $oystProduct = new OystProduct($product->getEntityId(), $product->getName(), $price, $qty); + /** @var Mage_Catalog_Model_Product $product */ + $product = Mage::getModel('catalog/product')->load($quoteItem->getProductId()); + if (!empty($this->configurableProductChildId) + && $product->isConfigurable()) { + $childProduct = Mage::getModel('catalog/product')->load($this->configurableProductChildId); + $this->setConfigurableAttributesCode($product); + } - // Get product attributes - $this->getAttributes($product, $this->productAttrTranslate, $oystProduct); + // This price is overwritten later with taxes and others stuff + $price = new OystPrice(1, $this->getCatalogBaseCurrencyCode()); - // Add others attributes - // Don't get price from child product - if (in_array($product->getId(), array_keys($this->products))) { - $this->addAmount($product, $oystProduct); - } + $oystProduct = new OystProduct($product->getId(), $product->getName(), $price, $quoteItem->getQty()); - $this->addComplexAttributes($product, $oystProduct); - $this->addImages($product, $oystProduct); - $this->addCustomAttributesToInformation($product, $oystProduct); + $this->addAmount($oystProduct, $quoteItem); + $this->addComplexAttributes($product, $oystProduct); + $this->addImages($product, $oystProduct); + $this->addCustomAttributesToInformations(isset($childProduct) ? $childProduct : $product, $oystProduct); + $this->addOptionsToInformations($oystProduct, $quoteItem); - if ($product->isConfigurable()) { - $this->addVariations($product, $oystProduct); - } + $oystProduct->__set('reference', $product->getEntityId() . ';' . $quoteItem->getId()); - // @TODO Temporary code, waiting to allow any kind of field in product e.g. variation_reference - // in release stock event - if ($product->isConfigurable()) { - $oystProduct->__set('reference', $product->getId() . ';' . $this->configurableProductChildId); - $oystProduct->__set('variation_reference', $this->configurableProductChildId); - } + // @TODO Temporary code, waiting to allow any kind of field in product e.g. variation_reference + if ($product->isConfigurable()) { + $oystProduct->__set('reference', $product->getId() . ';' . $quoteItem->getId() . ';' . $this->configurableProductChildId); + $oystProduct->__set('variation_reference', $this->configurableProductChildId); } return $oystProduct; } /** - * Return the user defined attributes code + * Return the selected custom attributes code * * @return array */ - protected function getUserDefinedAttributeCode() + protected function loadCustomAttributesCode() { - /** @var Mage_Eav_Model_Entity_Type $type */ - $type = Mage::getModel('eav/entity_type'); - $type->loadByCode('catalog_product'); - - /** @var $attrs Mage_Eav_Model_Resource_Entity_Attribute_Collection */ - $attrs = Mage::getResourceModel('eav/entity_attribute_collection') - ->setEntityTypeFilter($type) - ->addFieldToFilter('is_user_defined', true) - ->addFieldToFilter('frontend_input', 'select'); - - $userDefinedAttributeCode = array(); - /** @var $attribute Mage_Eav_Model_Entity_Attribute */ - foreach ($attrs as $attribute) { - $userDefinedAttributeCode[] = $attribute->getAttributeCode(); - } - - return $userDefinedAttributeCode; - } - - /** - * Return the selected system attributes code - * - * @return array - */ - protected function getSystemSelectedAttributeCode() - { - $code = 'systemattributes'; + $code = 'customattributes'; $attrsIds = explode(',', Mage::getStoreConfig("oyst/oneclick/$code")); - $systemSelectedAttributeCode = array(); - foreach ($attrsIds as $attributeId) { - $attribute = Mage::getResourceModel('eav/entity_attribute_collection') - ->addFieldToFilter('attribute_id', $attributeId) - ->addFieldToSelect('attribute_code') - // @codingStandardsIgnoreLine - ->getFirstItem() - ; + $attributes = Mage::getResourceModel('eav/entity_attribute_collection') + ->addFieldToFilter('attribute_id', array('in' => $attrsIds)) + ->addFieldToSelect('attribute_code') + ; - $systemSelectedAttributeCode[] = $attribute->getAttributeCode(); + foreach ($attributes as $attribute) { + $this->customAttributesCode[] = $attribute->getAttributeCode(); } - - return $systemSelectedAttributeCode; } /** - * Return the product attributes code defined by user - * - * @param Mage_Catalog_Model_Product $product - * @param $userDefinedAttributeCode - * * @return array */ - protected function getProductAttributeCodeDefinedByUser(Mage_Catalog_Model_Product $product, $userDefinedAttributeCode) + protected function getProductAttributesCode() { - $attributes = $product->getAttributes(); - $productAttributeCode = array(); - foreach ($attributes as $attribute) { - $productAttributeCode[] = $attribute->getAttributeCode(); - } - $attributeCodes = array_unique( array_merge( - array_intersect($userDefinedAttributeCode, $productAttributeCode), $this->customAttributesCode, - $this->systemSelectedAttributesCode + $this->configurableAttributesCode ) ); @@ -439,215 +236,26 @@ protected function getProductAttributeCodeDefinedByUser(Mage_Catalog_Model_Produ } /** - * Get product attributes - * - * @param Mage_Catalog_Model_Product $product - * @param array $translateAttribute - * @param OystProduct $oystProduct - */ - protected function getAttributes(Mage_Catalog_Model_Product $product, array $translateAttribute, OystProduct &$oystProduct) - { - foreach ($translateAttribute as $attributeCode => $simpleAttribute) { - if ($data = $product->getData($attributeCode)) { - if ($simpleAttribute['type'] == 'jsonb') { - $data = Zend_Json::encode(array( - 'meta' => $data, - )); - } else { - settype($data, $simpleAttribute['type']); - } - - if ($data !== null) { - $oystProduct->__set($simpleAttribute['lib_property'], ($data)); - } - } elseif (array_key_exists('required', $simpleAttribute) && $simpleAttribute['required'] == true) { - if ('jsonb' == $simpleAttribute['type']) { - $data = '{}'; - } else { - $data = 'Empty'; - settype($data, $simpleAttribute['type']); - } - } - } - } - - /** - * Add variations attributes to product + * Add price to oyst product. * * @param Mage_Catalog_Model_Product $product * @param OystProduct $oystProduct - * - * @return array + * @param Mage_Sales_Model_Quote $quote */ - protected function addVariations(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) + protected function addAmount(OystProduct &$oystProduct, Mage_Sales_Model_Quote_Item $quoteItem) { - if (!$this->isPreload && isset($this->products[$product->getId()]['childProduct'])) { - $variationProductsFormated = $this->format(array($this->products[$product->getId()]['childProduct'])); - if (property_exists($variationProductsFormated, 'informations')) { - $oystProduct->__set('informations', $variationProductsFormated->__get('informations')); - } - } - } - - /** - * Add price to product - * - * @param Mage_Catalog_Model_Product $product - * @param OystProduct $oystProduct - */ - protected function addAmount(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) - { - $prices = $this->getPrices($product); - $oystPriceIncludingTaxes = new OystPrice($prices['price-including-tax'], $this->getCatalogBaseCurrencyCode()); + $oystPriceIncludingTaxes = $this->getOystPriceFromQuoteItem($quoteItem); $oystProduct->__set('amountIncludingTax', $oystPriceIncludingTaxes); - - if (isset($prices['price-excluding-tax'])) { - $oystPriceExcludingTaxes = new OystPrice($prices['price-excluding-tax'], $this->getCatalogBaseCurrencyCode()); - $oystProduct->__set('amount_excluding_taxes', $oystPriceExcludingTaxes->toArray()); - } } - /** - * Get prices - * - * @param Mage_Catalog_Model_Product $product - * @param Mage_Catalog_Model_Product $configurable - * @param integer $storeId - * - * @return array - */ - protected function getPrices(Mage_Catalog_Model_Product $product, $storeId = null) + protected function getOystPriceFromQuoteItem(Mage_Sales_Model_Quote_Item $quoteItem) { - $store = Mage::app()->getStore($storeId); - $priceIncludesTax = Mage::helper('tax')->priceIncludesTax($store); - - $calculator = Mage::getSingleton('tax/calculation'); - $taxClassId = $product->getTaxClassId(); - $request = $calculator->getRateRequest(null, null, null, $store); - $taxPercent = $calculator->getRate($request->setProductClassId($taxClassId)); + /** @var Mage_Checkout_Helper_Data $checkout */ + $checkout = Mage::helper('checkout'); - $price = $product->getPrice(); - $finalPrice = $product->getFinalPrice(); + $priceInclTax = round($checkout->getPriceInclTax($quoteItem), 2); - if ($product->isConfigurable()) { - $price = $product->getPrice(); - $finalPrice = $product->getFinalPrice(); - $configurablePrice = 0; - $configurableOldPrice = 0; - - $attributes = $product->getTypeInstance(true)->getConfigurableAttributes($product); - $attributes = Mage::helper('core')->decorateArray($attributes); - if ($attributes) { - foreach ($attributes as $attribute) { - $productAttribute = $attribute->getProductAttribute(); - - if ($this->isPreload) { - $attributeValue = Mage::getResourceModel('catalog/product')->getAttributeRawValue($this->configurableProductChildId, $productAttribute->getAttributeCode(), $storeId); - } else { - $attributeValue = $this->products[$product->getId()]['childProduct']->getData($productAttribute->getAttributeCode()); - } - - // @codingStandardsIgnoreLine - if (count($attribute->getPrices()) > 0) { - foreach ($attribute->getPrices() as $priceChange) { - if (is_array($priceChange) && array_key_exists('value_index', $priceChange) && - $priceChange['value_index'] == $attributeValue - ) { - $configurableOldPrice += (float)($priceChange['is_percent'] ? - (((float)$priceChange['pricing_value']) * $price / 100) : - $priceChange['pricing_value']); - $configurablePrice += (float)($priceChange['is_percent'] ? - (((float)$priceChange['pricing_value']) * $finalPrice / 100) : - $priceChange['pricing_value']); - } - } - } - } - } - $product->setConfigurablePrice($configurablePrice); - $product->setParentId(true); - Mage::dispatchEvent( - 'catalog_product_type_configurable_price', - array('product' => $product) - ); - - $configurablePrice = $product->getConfigurablePrice(); - $productType = $product; - - if (Mage::getStoreConfig('oyst/oneclick/configurable_price')) { - $productType = Mage::getModel('catalog/product')->load($this->configurableProductChildId); - } - - $price = $productType->getPrice() + $configurableOldPrice; - $finalPrice = $productType->getFinalPrice() + $configurablePrice; - } - - if ($product->isGrouped()) { - $price = 0; - $finalPrice = 0; - $childs = Mage::getModel('catalog/product_type_grouped')->getChildrenIds($product->getId()); - $childs = $childs[Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED]; - foreach ($childs as $value) { - $price += Mage::getResourceModel('catalog/product')->getAttributeRawValue($value, 'price', $store->getId()); - $finalPrice += Mage::getResourceModel('catalog/product')->getAttributeRawValue($value, 'final_price', $store->getId()); - } - $priceIncludingTax = Mage::helper('tax')->getPrice( - $product->setTaxPercent(null), - $price, - true - ); - $finalPriceIncludingTax = Mage::helper('tax')->getPrice( - $product->setTaxPercent(null), - $finalPrice, - true - ); - } - - $priceIncludingTax = $price; - $finalPriceIncludingTax = $finalPrice; - if (!$priceIncludesTax) { - $data['price-excluding-tax'] = round($finalPrice, 2); - $priceIncludingTax = $price + $calculator->calcTaxAmount($price, $taxPercent, false); - $finalPriceIncludingTax = $finalPrice + $calculator->calcTaxAmount($finalPrice, $taxPercent, false); - } - - if (Mage::getStoreConfig(Mage_Weee_Helper_Data::XML_PATH_FPT_ENABLED)) { - $amount = Mage::getModel('weee/tax')->getWeeeAmount($product, null, null, $storeId); - $priceIncludingTax += $amount; - $finalPriceIncludingTax += $amount; - } - - // Get prices - $data['price-including-tax'] = round($finalPriceIncludingTax, 2); - $data['price-before-discount'] = round($priceIncludingTax, 2); - $discountAmount = $priceIncludingTax - $finalPriceIncludingTax; - $data['discount-amount'] = $discountAmount > 0 ? round($discountAmount, 2) : '0'; - $data['discount-percent'] = $discountAmount > 0 ? round( - ($discountAmount * 100) / $priceIncludingTax, - 0 - ) : '0'; - $data['start-date-discount'] = $product->getSpecialFromDate(); - $data['end-date-discount'] = $product->getSpecialToDate(); - - // Retrieving promotions - $dateTs = Mage::app()->getLocale()->storeTimeStamp($product->getStoreId()); - if (method_exists(Mage::getResourceModel('catalogrule/rule'), 'getRulesFromProduct')) { - $promo = Mage::getResourceModel('catalogrule/rule')->getRulesFromProduct($dateTs, $product->getStoreId(), 1, $product->getId()); - } elseif (method_exists(Mage::getResourceModel('catalogrule/rule'), 'getRulesForProduct')) { - $promo = Mage::getResourceModel('catalogrule/rule')->getRulesForProduct($dateTs, $product->getStoreId(), $product->getId()); - } - - if (count($promo)) { - $promo = $promo[0]; - - $from = isset($promo['from_time']) ? $promo['from_time'] : $promo['from_date']; - $to = isset($promo['to_time']) ? $promo['to_time'] : $promo['to_date']; - - $data['start-date-discount'] = date('Y-m-d H:i:s', strtotime($from)); - $data['end-date-discount'] = null === $to ? '' : date('Y-m-d H:i:s', strtotime($to)); - } - - return $data; + return new OystPrice($priceInclTax, $this->getCatalogBaseCurrencyCode()); } /** @@ -662,32 +270,6 @@ protected function addComplexAttributes(Mage_Catalog_Model_Product $product, Oys $oystProduct->__set('materialized', !($product->isVirtual()) ? true : false); } - /** - * Add categories to product array - * - * @param Mage_Catalog_Model_Product $product - * @param OystProduct $oystProduct - */ - protected function addCategories(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) - { - /** @var Mage_Catalog_Model_Resource_Category_Collection $categoryCollection */ - $categoryCollection = $product->getCategoryCollection() - ->addAttributeToSelect('name') - ->addAttributeToSelect('url_key'); - - $categories = array(); - - /** @var Mage_Catalog_Model_Category $category */ - foreach ($categoryCollection as $category) { - // Count slash to determine if it's a main category - $isMain = substr_count($category->getPath(), '/') == 2; - $oystCategory = new OystCategory($category->getId(), $category->getName(), $isMain); - $categories[] = $oystCategory->toArray(); - } - - $oystProduct->__set('categories', $categories); - } - /** * Add picture link of product * @@ -720,33 +302,20 @@ protected function addImages(Mage_Catalog_Model_Product $product, OystProduct &$ } /** - * Add related product of parent product - * - * @param Mage_Catalog_Model_Product $product - * @param OystProduct $oystProduct - */ - protected function addRelatedProducts(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) - { - if ($relatedProducts = $product->getRelatedProductIds()) { - $oystProduct->__set('related_products', $relatedProducts); - } - } - - /** - * Add custom attributes to product information field + * Add custom attributes to oyst product informations. * * @param Mage_Catalog_Model_Product $product * @param OystProduct $oystProduct - * @param array $userDefinedAttributeCode */ - protected function addCustomAttributesToInformation(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) + protected function addCustomAttributesToInformations(Mage_Catalog_Model_Product $product, OystProduct &$oystProduct) { - $attributeCodes = $this->getProductAttributeCodeDefinedByUser($product, $this->userDefinedAttributeCode); + $attributeCodes = $this->getProductAttributesCode(); Mage::helper('oyst_oneclick')->log('$attributeCodes'); Mage::helper('oyst_oneclick')->log($attributeCodes); $informations = array(); + $description = array(); foreach ($attributeCodes as $attributeCode) { $value = ''; @@ -762,8 +331,49 @@ protected function addCustomAttributesToInformation(Mage_Catalog_Model_Product $ Mage::helper('oyst_oneclick')->log('$attributeCode: ' . $attributeCode . ' - value: ' . $value); $informations[$attributeCode] = $value; + if (in_array($attributeCode, $this->configurableAttributesCode)) { + $description[] = $attribute->getStoreLabel() . ':'. $value; + } } $oystProduct->__set('informations', $informations); + $oystProduct->__set('description', implode(', ', $description)); + } + + /** + * Add product custom options to oyst product informations. + * + * @param OystProduct $oystProduct + * @param Mage_Sales_Model_Quote_Item $quoteItem + */ + protected function addOptionsToInformations(OystProduct &$oystProduct, Mage_Sales_Model_Quote_Item $quoteItem) + { + $productOptions = array(); + + /* @var $helper Mage_Catalog_Helper_Product_Configuration */ + $helper = Mage::helper('catalog/product_configuration'); + + // @codingStandardsIgnoreLine + $options = $helper->getCustomOptions($quoteItem); + + foreach ($options as $option) { + $productOptions[$option['label']] = $option['value']; + } + + $oystProduct->__set('informations', array_merge($oystProduct->__get('informations'), $productOptions)); + } + + protected function getQuote() + { + /** @var Mage_Sales_Model_Quote $quote */ + $quote = Mage::registry('oyst-quote'); + + if (is_null($quote)) { + /** @var Mage_Checkout_Model_Session $oystRelatedQuoteId */ + $oystRelatedQuoteId = Mage::getSingleton('checkout/session')->getOystRelatedQuoteId(); + $quote = Mage::getModel('sales/quote')->load($oystRelatedQuoteId); + } + + return $quote; } /** @@ -804,6 +414,7 @@ public function cartEstimate($apiData) $magentoQuoteBuilder = Mage::getModel('oyst_oneclick/magento_quote', $apiData); $magentoQuoteBuilder->syncQuoteFacade(); + Mage::helper('oyst_oneclick')->handleQuoteErrors($magentoQuoteBuilder->getQuote()); // Object to format data of EndpointShipment $oneClickOrderCartEstimate = new OneClickOrderCartEstimate(); @@ -816,6 +427,10 @@ public function cartEstimate($apiData) $this->getCartAmount($apiData, $magentoQuoteBuilder, $oneClickOrderCartEstimate); + $this->getCartItems($magentoQuoteBuilder, $oneClickOrderCartEstimate); + + $this->getNewsletterOptin($magentoQuoteBuilder, $oneClickOrderCartEstimate); + return $oneClickOrderCartEstimate->toJson(); } @@ -849,8 +464,12 @@ private function validateCoupon($apiData, &$magentoQuoteBuilder, &$oneClickOrder * @param Oyst_OneClick_Model_Magento_Quote $magentoQuoteBuilder * @param OneClickOrderCartEstimate $oneClickOrderCartEstimate */ - private function getShipments($apiData, &$magentoQuoteBuilder, &$oneClickOrderCartEstimate) + protected function getShipments($apiData, &$magentoQuoteBuilder, &$oneClickOrderCartEstimate) { + if ($magentoQuoteBuilder->getQuote()->isVirtual()) { + return; + } + /** @var Mage_Core_Model_Store $storeId */ $storeId = Mage::getModel('core/store')->load($apiData['order']['context']['store_id']); @@ -919,9 +538,18 @@ private function getShipments($apiData, &$magentoQuoteBuilder, &$oneClickOrderCa $oystCarrier ); - if ($rateCode === $this->getConfig('carrier_default')) { - $shipment->setPrimary(true); - $isPrimarySet = true; + if($address->getShippingMethod()) { + if ($rateCode === $address->getShippingMethod()) { + $shipment->setPrimary(true); + $shipment->getAmount()->setValue($address->getShippingInclTax()); + $isPrimarySet = true; + } + } else { + if ($rateCode === $this->getConfig('carrier_default')) { + $shipment->setPrimary(true); + $shipment->getAmount()->setValue($address->getShippingInclTax()); + $isPrimarySet = true; + } } $oneClickOrderCartEstimate->addShipment($shipment); @@ -942,7 +570,7 @@ private function getShipments($apiData, &$magentoQuoteBuilder, &$oneClickOrderCa * @param Oyst_OneClick_Model_Magento_Quote $magentoQuoteBuilder * @param OneClickOrderCartEstimate $oneClickOrderCartEstimate */ - private function getCartRules(&$magentoQuoteBuilder, &$oneClickOrderCartEstimate) + protected function getCartRules(&$magentoQuoteBuilder, &$oneClickOrderCartEstimate) { $discountRules = array(); @@ -970,7 +598,8 @@ private function getCartRules(&$magentoQuoteBuilder, &$oneClickOrderCartEstimate $quoteItemData['qty'] ); $freeItem->__set('title', $quoteItemData['name']); - + $thumbnail = Mage::helper('catalog/image')->init($quoteItems->getItemById($quoteItemData['item_id'])->getProduct(), 'thumbnail'); + $freeItem->__set('images', array($thumbnail->__toString())); $oneClickOrderCartEstimate->addFreeItems($freeItem); continue; @@ -992,7 +621,7 @@ private function getCartRules(&$magentoQuoteBuilder, &$oneClickOrderCartEstimate ->setOrder('sort_order', $salesRuleCollection::SORT_ORDER_ASC); foreach ($total->getFullInfo() as $salesRuleId => $discountInfo) { - if(!in_array($salesRuleId, explode(',', $quoteAppliedRuleIds))) { + if (!in_array($salesRuleId, explode(',', $quoteAppliedRuleIds))) { continue; } @@ -1031,7 +660,7 @@ private function getCartRules(&$magentoQuoteBuilder, &$oneClickOrderCartEstimate * @param Oyst_OneClick_Model_Magento_Quote $magentoQuoteBuilder * @param OneClickOrderCartEstimate $oneClickOrderCartEstimate */ - private function getCartAmount($apiData, &$magentoQuoteBuilder, &$oneClickOrderCartEstimate) + protected function getCartAmount($apiData, &$magentoQuoteBuilder, &$oneClickOrderCartEstimate) { // Get order amount $totals = $magentoQuoteBuilder->getQuote()->getTotals(); @@ -1102,159 +731,93 @@ protected function getConfigMappingName($code, $storeId) } /** - * - * - * @return mixed + * This method is required because the API service authorize Order which is called on preload + * does not accept an empty cart, so we have to artificially force a dummy product + * @return OystProduct */ - private function stockReleased($apiData) + public function addDummyOystProduct() { - try { - if (!isset($apiData['products'])) { - throw new \InvalidArgumentException(Mage::helper('oyst_oneclick')->__('Products info is missing')); - } - - foreach ($apiData['products'] as $product) { - $qty = isset($product['quantity']) ? $product['quantity'] : 1; - - if (0 === $qty) { - continue; - } - - $productId = $product['reference']; - - // @TODO Temporary code, waiting to allow any kind of field in product e.g. variation_reference - // in release stock event - if (false !== strpos($productId, ';')) { - $p = explode(';', $productId); - $product['reference'] = $p[0]; - $product['variation_reference'] = $p[1]; - } - - if (isset($product['variation_reference'])) { - $productId = $product['variation_reference']; - } + $price = new OystPrice(1, $this->getCatalogBaseCurrencyCode()); - /** @var Mage_CatalogInventory_Model_Stock_Item stockItem */ - $this->stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId); + return new OystProduct(1, 'Dummy Product', $price, 1); + } - if (!$this->stockItem->getId()) { - $this->stockItem->setProductId($productId); - $this->stockItem->setStockId(Mage::getModel('cataloginventory/stock')->getId()); - } + public function getCatalogBaseCurrencyCode($storeId = null) + { + return Mage::app()->getStore($storeId)->getBaseCurrencyCode(); + } - if ($this->stockItem->getManageStock()) { - $this->stockItem->setQty($this->stockItem->getQty() + $qty); - $this->stockItem->setIsInStock((int)($qty > 0)); // Set the Product to InStock - // @codingStandardsIgnoreLine - $this->stockItem->save(); - } - } - } catch (Exception $e) { - Mage::logException($e); - } + protected function getForbiddenSalesRulesActions() + { + $transport = new Varien_Object(); + $transport->setForbiddenSalesRulesActions(array('add_gift')); + Mage::dispatchEvent('oyst_oneclick_model_catalog_get_forbidden_sales_rules_actions', array( + 'transport' => $transport + )); + return $transport->getForbiddenSalesRulesActions(); } /** - * Book stock item(s) + * Get cart items. * - * @return string + * @param Oyst_OneClick_Model_Magento_Quote $magentoQuoteBuilder + * @param OneClickOrderCartEstimate $oneClickOrderCartEstimate */ - private function stockBook($apiData) + protected function getCartItems($magentoQuoteBuilder, $oneClickOrderCartEstimate) { - try { - if (isset($apiData['items'])) { - foreach ($apiData['items'] as $item) { - $qty = $item['quantity']; - $productId = $item['reference']; - - // @TODO Temporary code, waiting to allow any kind of field in product e.g. variation_reference - // in release stock event - if (false !== strpos($productId, ';')) { - $p = explode(';', $productId); - $productId['reference'] = $p[0]; - $item['variation_reference'] = $p[1]; - } + $oystItems = array(); - if (isset($item['variation_reference'])) { - $productId = $item['variation_reference']; - } + foreach ($magentoQuoteBuilder->getQuote()->getAllItems() as $item) { + if ($item->getParentItemId()) { + continue; + } - $this->stockItemToBook($productId, $qty); - } - } else { - $qty = $apiData['quantity']; + $oystPriceIncludingTaxes = $this->getOystPriceFromQuoteItem($item); - $productId = $apiData['product_reference']; + $reference = null; - // @TODO Temporary code, waiting to allow any kind of field in product e.g. variation_reference - // in release stock event - if (false !== strpos($productId, ';')) { - $p = explode(';', $productId); - $productId = $p[0]; - $apiData['variation_reference'] = $p[1]; - } - - if (isset($apiData['variation_reference'])) { - $productId = $apiData['variation_reference']; + if (in_array($item->getProductType(), array(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE))) { + $childItem = null; + foreach ($magentoQuoteBuilder->getQuote()->getAllItems() as $tmpItem) { + if ($tmpItem->getParentItemId() == $item->getId()) { + $childItem = $tmpItem; + break; + } } - - $stockItemToBook = $this->stockItemToBook($productId, $qty); - - /** @var OneClickStock $stockBookResponse */ - $stockBookResponse = new OneClickStock($stockItemToBook, $apiData['product_reference']); - - return Zend_Json::encode($stockBookResponse->toArray()); + $reference = $item->getProductId() . ';' . $item->getId() . ';' . $childItem->getProductId(); + } else { + $reference = $item->getProductId() . ';' . $item->getId(); } - } catch (Exception $e) { - Mage::logException($e); - } - } - /** - * Book a stock unit - * - * @return string - */ - public function stockItemToBook($productId, $qty) - { - /** @var Mage_Catalog_Model_Product $product */ - $product = Mage::getModel('catalog/product')->load($productId); + $oystItem = new OneClickItem($reference, $oystPriceIncludingTaxes, $item->getQty()); - /** @var Mage_CatalogInventory_Model_Stock_Item stockItem */ - $this->stockItem = $product->getStockItem(); - $stockItemToBook = $this->stockItem->getQty() >= $qty ? $qty : 0; + $oystPriceForCrossedOutAmount = $this->getOystPriceFromQuoteItem($item); + $oystPriceForCrossedOutAmount->setValue($item->getProduct()->getPrice()); + if ($oystPriceIncludingTaxes->getValue() < $oystPriceForCrossedOutAmount->getValue()) { + $oystItem->__set('crossedOutAmount', $oystPriceForCrossedOutAmount); + $oystItem->__set('message', Mage::helper('oyst_oneclick')->__('Oyst has recognized you as a customer, so you benefit a promotion on this product.')); + } - if ($stockItemToBook) { - $this->stockItem->setData('qty', $this->stockItem->getQty() - $stockItemToBook); - $this->stockItem->save(); + $oystItems[] = $oystItem; } - return $stockItemToBook; - } - - /** - * This method is required because the API service authorize Order which is called on preload - * does not accept an empty cart, so we have to artificially force a dummy product - * @return OystProduct - */ - public function addDummyOystProduct() - { - $price = new OystPrice(1, $this->getCatalogBaseCurrencyCode()); - return new OystProduct(1, 'Dummy Product', $price, 1); + $oneClickOrderCartEstimate->setItems($oystItems); } - public function getCatalogBaseCurrencyCode($storeId = null) + protected function setConfigurableAttributesCode(Mage_Catalog_Model_Product $product) { - return Mage::app()->getStore($storeId)->getBaseCurrencyCode(); + foreach (Mage::getModel('catalog/product_type_configurable')->getConfigurableAttributes($product) as $attribute) { + $this->configurableAttributesCode[] = $attribute->getData('product_attribute')->getAttributeCode(); + } } - protected function getForbiddenSalesRulesActions() + protected function getNewsletterOptin($magentoQuoteBuilder, $oneClickOrderCartEstimate) { - $transport = new Varien_Object(); - $transport->setForbiddenSalesRulesActions(array('add_gift')); - Mage::dispatchEvent('oyst_oneclick_model_catalog_get_forbidden_sales_rules_actions', array( - 'transport' => $transport - )); - return $transport->getForbiddenSalesRulesActions(); + if ($magentoQuoteBuilder->getQuote()->getCustomerId()) { + $customer = $magentoQuoteBuilder->getQuote()->getCustomer(); + $oneClickOrderCartEstimate->setNewsletterOptin( + Mage::getModel('newsletter/subscriber')->loadByCustomer($customer)->isSubscribed() + ); + } } } diff --git a/app/code/community/Oyst/OneClick/Model/Magento/Order.php b/app/code/community/Oyst/OneClick/Model/Magento/Order.php index 510aa0ea..bc97446e 100644 --- a/app/code/community/Oyst/OneClick/Model/Magento/Order.php +++ b/app/code/community/Oyst/OneClick/Model/Magento/Order.php @@ -22,15 +22,23 @@ class Oyst_OneClick_Model_Magento_Order private $additionalData = array(); - public function __construct(Mage_Sales_Model_Quote $quote) + /** @var string[] API response */ + private $apiData = null; + + public function __construct($orderResponse) + { + $this->apiData = $orderResponse; + } + + public function setQuote(Mage_Sales_Model_Quote $quote) { $this->quote = $quote; + return $this; } public function setAdditionalData($additionalData) { $this->additionalData = $additionalData; - return $this; } @@ -42,16 +50,27 @@ public function getOrder() return $this->order; } - public function buildOrder() - { - $this->createOrder(); - } - - private function createOrder() + public function saveOrder() { try { + if (!$this->quote->getCustomerId() + && Mage::getStoreConfig('oyst/oneclick/new_customer_account')) { + $customer = $this->createCustomer( + $this->quote->getCustomerFirstname(), $this->quote->getCustomerLastname(), $this->quote->getCustomerEmail() + ); + $this->quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER); + $this->quote->setCustomer($customer); + //$this->quote->save(); + } + + if (!$this->quote->getCustomerId()) { + $this->quote->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); + $this->quote->setCustomerIsGuest(true); + } else { + $this->quote->setCustomerIsGuest(false); + } + $this->order = $this->placeOrder(); - $this->order->setCreatedAt($this->quote->getCreatedAt()); $this->order->save(); $this->quote->setIsActive(false)->save(); } catch (Exception $e) { @@ -102,4 +121,59 @@ private function placeOrder() return $orderObj; } + + /** + * Create new customer. + * + * @param string $firstname + * @param string $lastname + * @param string $email + * + * @return false|Mage_Core_Model_Abstract + */ + private function createCustomer($firstname, $lastname, $email) + { + /** @var Mage_Customer_Model_Customer $customer */ + $customer = Mage::getModel('customer/customer'); + $store = Mage::app()->getStore(); + $websiteId = $store->getWebsiteId(); + + try { + $customer->setWebsiteId($websiteId) + ->setStore($store) + ->setFirstname($this->quote->getCustomerFirstname()) + ->setLastname($this->quote->getCustomerLastname()) + ->setEmail($this->quote->getCustomerEmail()); + $customer->save(); + + // Send welcome email + $customer->sendNewAccountEmail('registered', '', $store->getId(), $customer->generatePassword(16)); + + /** @var Mage_Customer_Model_Address $address */ + $address = Mage::getModel('customer/address'); + $quoteAddress = $this->quote->isVirtual() ? $this->quote->getBillingAddress() : $this->quote->getShippingAddress(); + + $address->setCustomerId($customer->getId()) + ->setFirstname($customer->getFirstname()) + ->setLastname($customer->getLastname()) + ->setCountryId($quoteAddress->getCountryId()) + ->setPostcode($quoteAddress->getPostcode()) + ->setCity($quoteAddress->getCity()) + ->setTelephone($quoteAddress->getTelephone()) + ->setStreet($quoteAddress->getStreet()) + ->setIsDefaultBilling(true) + ->setIsDefaultShipping(true) + ->setSaveInAddressBook(true); + if (($validateRes = $address->validate())!==true) { + throw new Exception(implode('\n', $validateRes)); + } + $address->save(); + } catch (Exception $e) { + Mage::helper('oyst_oneclick')->log($e->getMessage()); + } + + Mage::dispatchEvent('oyst_oneclick_model_magento_order_create_customer_after', array('quote' => $this->quote, 'request' => $this->apiData, 'customer' => $customer)); + + return $customer; + } } diff --git a/app/code/community/Oyst/OneClick/Model/Magento/Quote.php b/app/code/community/Oyst/OneClick/Model/Magento/Quote.php index 5a2030b6..6b2014cd 100644 --- a/app/code/community/Oyst/OneClick/Model/Magento/Quote.php +++ b/app/code/community/Oyst/OneClick/Model/Magento/Quote.php @@ -22,9 +22,6 @@ class Oyst_OneClick_Model_Magento_Quote /** @var string[] API response */ private $apiData = null; - /** @var int Website id */ - private $websiteId = null; - public function __construct($orderResponse) { $this->apiData = $orderResponse; @@ -52,8 +49,8 @@ public function syncQuoteFacade() $storeId = $this->apiData['order']['context']['store_id']; $this->syncQuote($quoteId, $storeId); - $this->syncQuoteItems(); $this->syncCustomer(); + $this->syncQuoteItems(); $this->syncAddresses(); $this->syncCoupons(); $this->syncShippingMethod(); @@ -61,8 +58,8 @@ public function syncQuoteFacade() Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_quote_facade', array('api_data' => $this->apiData, 'quote' => $this->quote)); - $this->quote->getShippingAddress()->setCollectShippingRates(true); - $this->quote->setAppliedRuleIds(null)->setTotalsCollectedFlag(false)->collectTotals()->save(); + $this->wrapQuoteEnsureCollectTotals(); + $this->quote->save(); } catch (Exception $e) { Mage::helper('oyst_oneclick')->log('Error build quote: ' . $e->getMessage()); throw $e; @@ -85,60 +82,14 @@ private function syncQuote($quoteId, $storeId = null) $this->quote->setRemoteIp($this->apiData['order']['context']['remote_addr']); $this->quote->setIsMultiShipping(false); - $this->quote->setIsSuperMode(true); + //$this->quote->setIsSuperMode(true); $this->quote->setCreatedAt($this->apiData['order']['created_at']); $this->quote->setUpdatedAt($this->apiData['order']['created_at']); $this->quote->setOystOrderId($this->apiData['order']['id']); - Mage::getSingleton('checkout/cart')->setQuote($this->quote); - } + Mage::getSingleton('checkout/session')->replaceQuote($this->quote); - /** - * Create new customer. - * - * @param string $firstname - * @param string $lastname - * @param string $email - * - * @return false|Mage_Core_Model_Abstract - */ - private function createCustomer($firstname, $lastname, $email) - { - /** @var Mage_Customer_Model_Customer $customer */ - $customer = Mage::getModel('customer/customer'); - $store = Mage::app()->getStore(); - - try { - $customer->setWebsiteId($this->websiteId) - ->setStore($store) - ->setFirstname($firstname) - ->setLastname($lastname) - ->setEmail($email); - $customer->save(); - - // Send welcome email - $customer->sendNewAccountEmail('registered', '', $store->getId(), $customer->generatePassword(16)); - - /** @var Mage_Customer_Model_Address $address */ - $address = Mage::getModel('customer/address'); - - $address->setCustomerId($customer->getId()) - ->setFirstname($customer->getFirstname()) - ->setLastname($customer->getLastname()) - ->setCountryId($this->apiData['order']['user']['address']['country']) - ->setPostcode($this->apiData['order']['user']['address']['postcode']) - ->setCity($this->apiData['order']['user']['address']['city']) - ->setTelephone($this->apiData['order']['user']['phone']) - ->setStreet($this->apiData['order']['user']['address']['postcode']) - ->setIsDefaultBilling(true) - ->setIsDefaultShipping(true) - ->setSaveInAddressBook(true); - $address->save(); - } catch (Exception $e) { - Mage::helper('oyst_oneclick')->log($e->getMessage()); - } - - return $customer; + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_quote_after', array('quote' => $this->quote, 'request' => $this->apiData)); } private function syncCustomer() @@ -166,20 +117,15 @@ private function syncCustomer() $this->quote->setCustomerLastname($lastname); $this->quote->setCustomerEmail($email); - $checkoutMethod = Mage_Checkout_Model_Type_Onepage::METHOD_GUEST; - - if (Mage::getStoreConfig('oyst/oneclick/new_customer_account')) { - $customer = $this->createCustomer($firstname, $lastname, $email); - $checkoutMethod = Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER; - } - - if ($customer instanceof Mage_Customer_Model_Customer && !$customer->getId()) { - $this->quote->setCustomerIsGuest(true); - $this->quote->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); - } + $this->quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_GUEST); + $this->quote->setCustomerId(null); + } - $this->quote->setCheckoutMethod($checkoutMethod); + if ($customer instanceof Mage_Customer_Model_Customer) { + Mage::getSingleton('customer/session')->setCustomer($customer); } + + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_customer_after', array('quote' => $this->quote, 'request' => $this->apiData)); } /** @@ -187,15 +133,15 @@ private function syncCustomer() * * @return bool|Mage_Customer_Model_Customer */ - private function getCustomer() + protected function getCustomer() { - $this->websiteId = Mage::getModel('core/store') + $websiteId = Mage::getModel('core/store') ->load($this->apiData['order']['context']['store_id']) ->getWebsiteId(); /** @var Mage_Customer_Model_Customer $customer */ $customer = Mage::getModel('customer/customer'); - $customer->setWebsiteId($this->websiteId); + $customer->setWebsiteId($websiteId); $customer->loadByEmail($this->apiData['order']['user']['email']); if ($customer->getId()) { @@ -218,22 +164,34 @@ private function syncAddresses() $billingAddress->isObjectNew(false); $billingAddress->setSaveInAddressBook(false); - $billingAddress->setShouldIgnoreValidation(true); + if (($validateRes = $billingAddress->validate())!==true) { + throw new Mage_Checkout_Exception(implode('\n', $validateRes)); + } - /** @var Mage_Sales_Model_Quote_Address $shippingAddress */ - $shippingAddress = $this->quote->getShippingAddress(); - $shippingInfoFormated = $this->getAddressData($shippingAddress); - $shippingAddress->setSameAsBilling(0); // maybe just set same as billing? - $shippingAddress->addData($shippingInfoFormated); - $shippingAddress->implodeStreetAddress(); - $shippingAddress->isObjectNew(false); - - $shippingAddress->setSaveInAddressBook(false); - $shippingAddress->setShouldIgnoreValidation(true); + if (!$this->quote->isVirtual()) { + /** @var Mage_Sales_Model_Quote_Address $shippingAddress */ + $shippingAddress = $this->quote->getShippingAddress(); + $shippingInfoFormated = $this->getAddressData($shippingAddress); + $shippingAddress->setSameAsBilling(0); // maybe just set same as billing? + $shippingAddress->addData($shippingInfoFormated); + $shippingAddress->implodeStreetAddress(); + $shippingAddress->isObjectNew(false); + + $shippingAddress->setSaveInAddressBook(false); + if (($validateRes = $shippingAddress->validate())!==true) { + throw new Mage_Checkout_Exception(implode('\n', $validateRes)); + } + } + + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_addresses_after', array('quote' => $this->quote, 'request' => $this->apiData)); } private function syncShippingMethod() { + if ($this->quote->isVirtual()) { + return; + } + $shippingAddress = $this->quote->getShippingAddress(); $storeId = $this->apiData['order']['context']['store_id']; @@ -242,12 +200,11 @@ private function syncShippingMethod() $shippingDescription = Mage::getStoreConfig('oyst_oneclick/carrier_name/' . $shippingMethod, $storeId); if (isset($this->apiData['order']['shipment']) && - isset($this->apiData['order']['shipment']['carrier']) && - isset($this->apiData['order']['shipment']['carrier']['id']) && + isset($this->apiData['order']['shipment']['id']) && 'SHIPMENT-404' != $this->apiData['order']['shipment']['id'] ) { - $shippingMethod = $this->apiData['order']['shipment']['carrier']['id']; - $shippingDescription = $this->apiData['order']['shipment']['carrier']['name']; + $shippingMethod = $this->apiData['order']['shipment']['id']; + $shippingDescription = Mage::getStoreConfig('oyst_oneclick/carrier_name/' . $shippingMethod, $storeId); } $shippingAddress->setCollectShippingRates(true); @@ -277,9 +234,29 @@ private function syncShippingMethod() } } } + // MEANS THAT SHIPPING METHOD REQUESTED BY OYST ONECLICK IS NOT AVAILABLE SO WE CHOOSE THE CHEAPEST ONE + if (empty($realShippingMethod)) { + $tmpCheapestPrice = null; + foreach ($rates as $rate) { + $rateData = $rate->toArray(); + + if (!Mage::getStoreConfig('oyst_oneclick/carrier_mapping/' . $rateData['code'])) { + continue; + } + + if (!isset($tmpCheapestPrice)) { + $tmpCheapestPrice = $rateData['price']; + } + if ($rateData['price'] <= $tmpCheapestPrice) { + $realShippingMethod = $rateData['code']; + } + } + } $shippingAddress->setShippingMethod($realShippingMethod); $shippingAddress->setShippingDescription($shippingDescription); + + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_shipping_method_after', array('quote' => $this->quote, 'request' => $this->apiData)); } /** @@ -289,7 +266,7 @@ private function syncShippingMethod() * * @return array */ - private function getAddressData(Mage_Sales_Model_Quote_Address $address) + protected function getAddressData(Mage_Sales_Model_Quote_Address $address) { $customerAddress = $this->apiData['order']['user']['address']; @@ -348,14 +325,16 @@ private function syncCoupons() if (isset($this->apiData['order']['applied_coupons'])) { $appliedCoupons = $this->apiData['order']['applied_coupons']; foreach ($appliedCoupons as $appliedCoupon) { - if ($appliedCoupon['value'] == $this->apiData['order']['context']['applied_coupons']) { + if ($appliedCoupon == $this->apiData['order']['context']['applied_coupons']) { continue; } - $this->quote->setCouponCode($appliedCoupon['value']); + $this->quote->setCouponCode($appliedCoupon); break; } } } + + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_coupons_after', array('quote' => $this->quote, 'request' => $this->apiData)); } private function syncQuoteItems() @@ -367,12 +346,6 @@ private function syncQuoteItems() foreach (explode(';', $item['product']['reference']) as $productReference) { $productReferences[] = array('ref' => $productReference, 'qty' => $item['quantity']); } - - if (isset($item['product']['variation_reference'])) { - $this->handleIncreaseStock($item['product']['variation_reference'], $item['quantity']); - } else { - $this->handleIncreaseStock($item['product']['reference'], $item['quantity']); - } } $cartData = array(); @@ -396,39 +369,9 @@ private function syncQuoteItems() $cart = Mage::getSingleton('checkout/cart'); $cartData = $cart->suggestItemsQty($cartData); - $cart->updateItems($cartData)->save(); - - return $this; - } - - private function handleIncreaseStock($productId, $qty) - { - // Increase stock with qty decreased when order was made if should_ask_stock is enabled - if (Mage::getStoreConfig('oyst/oneclick/should_ask_stock') && - isset($this->apiData['event']) && - 'order.v2.new' === $this->apiData['event']) { - Mage::helper('oyst_oneclick')->log( - sprintf( - 'Increase stock of product_id %s with %s', - $productId, - $qty - ) - ); - - /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */ - $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId); - - $isStockManaged = $stockItem->getData('use_config_manage_stock') ? - Mage::getStoreConfig('cataloginventory/item_options/manage_stock') : - $stockItem->getData('manage_stock'); - - if ($isStockManaged) { - $stockItem->setData('is_in_stock', 1); // Set the Product to InStock - $stockItem->addQty($qty); - // @codingStandardsIgnoreLine - $stockItem->save(); - } - } + $cart->updateItems($cartData); + Mage::helper('oyst_oneclick')->handleQuoteErrors($this->quote); + $cart->save(); return $this; } @@ -443,7 +386,22 @@ private function syncPaymentMethodData() $payment ->importData(array('method' => $paymentMethod->getCode())) - ->setCcLast4(substr($this->apiData['order']['user']['card']['preview'], -4)) + ->setCcLast4(substr($this->apiData['order']['user']['card']['preview'], -4)); + + Mage::dispatchEvent('oyst_oneclick_model_magento_quote_sync_payment_method_after', array('quote' => $this->quote, 'request' => $this->apiData)); + + $payment ->save(); } + + protected function wrapQuoteEnsureCollectTotals() + { + $this->quote->getShippingAddress()->setCollectShippingRates(true); + $this->quote->getBillingAddress()->isObjectNew(true); + $this->quote->getShippingAddress()->isObjectNew(true); + $this->quote->setAppliedRuleIds(null)->setTotalsCollectedFlag(false)->collectTotals(); + $this->quote->getBillingAddress()->isObjectNew(false); + $this->quote->getShippingAddress()->isObjectNew(false); + return $this; + } } diff --git a/app/code/community/Oyst/OneClick/Model/Notification.php b/app/code/community/Oyst/OneClick/Model/Notification.php index bddd8d66..9ce506b7 100644 --- a/app/code/community/Oyst/OneClick/Model/Notification.php +++ b/app/code/community/Oyst/OneClick/Model/Notification.php @@ -18,6 +18,8 @@ class Oyst_OneClick_Model_Notification extends Mage_Core_Model_Abstract const NOTIFICATION_STATUS_FINISHED = 'finished'; + const NOTIFICATION_STATUS_FAIL = 'fail'; + const NOTIFICATION_STATUS_ZOMBIE = 'zombie'; const XML_PATH_NOTIFICATIONS_UPDATE_MAX_DELAY = 'oyst/oneclick/notifications_update_max_delay'; @@ -122,4 +124,30 @@ public function updateNotificationsStatus() } } } + + public function registerNotificationStart($event, $data) + { + $this->setData(array( + 'event' => $event, + 'oyst_data' => Zend_Json::encode($data), + 'status' => self::NOTIFICATION_STATUS_START, + 'created_at' => Mage::getModel('core/date')->gmtDate(), + 'executed_at' => Mage::getModel('core/date')->gmtDate(), + )); + $this->save(); + } + + public function registerNotificationFinish() + { + $this->setStatus(self::NOTIFICATION_STATUS_FINISHED) + ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) + ->save(); + } + + public function registerNotificationFail() + { + $this->setStatus(self::NOTIFICATION_STATUS_FAIL) + ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) + ->save(); + } } diff --git a/app/code/community/Oyst/OneClick/Model/Observer.php b/app/code/community/Oyst/OneClick/Model/Observer.php index 5bdeaa15..1ea2a973 100644 --- a/app/code/community/Oyst/OneClick/Model/Observer.php +++ b/app/code/community/Oyst/OneClick/Model/Observer.php @@ -87,8 +87,8 @@ public function salesOrderPaymentCancel(Varien_Event_Observer $observer) $oystHelper->log('Start send cancelOrRefund of order id : ' . $order->getId()); - /** @var Oyst_OneClick_Model_Payment_ApiWrapper $response */ - $response = Mage::getModel('oyst_oneclick/payment_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Payment $response */ + $response = Mage::getModel('oyst_oneclick/apiWrapper_type_payment'); $response->cancelOrRefund($order->getPayment()->getLastTransId()); $oystHelper->log('Waiting from cancelOrRefund notification of order id : ' . $order->getId()); diff --git a/app/code/community/Oyst/OneClick/Model/Order.php b/app/code/community/Oyst/OneClick/Model/Order.php index 0ed35d8a..869d3228 100644 --- a/app/code/community/Oyst/OneClick/Model/Order.php +++ b/app/code/community/Oyst/OneClick/Model/Order.php @@ -63,16 +63,7 @@ public function processNotification($event, $apiData) // Create new notification in db with status 'start' $notification = Mage::getModel('oyst_oneclick/notification'); - $notification->setData( - array( - 'event' => $this->eventNotification, - 'oyst_data' => Zend_Json::encode($apiData), - 'status' => Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_START, - 'created_at' => Mage::getModel('core/date')->gmtDate(), - 'executed_at' => Mage::getModel('core/date')->gmtDate(), - ) - ); - $notification->save(); + $notification->registerNotificationStart($this->eventNotification, $apiData); // When notification already processed if (!is_null($magentoOrderId = $lastNotification->isOrderProcessed($oystOrderId))) { @@ -81,23 +72,31 @@ public function processNotification($event, $apiData) 'message' => 'notification has been already processed.', )); } else { - // Sync Order From Api - $result = $this->sync(array( - 'oyst_order_id' => $oystOrderId, - )); - $magentoOrderId = $result['magento_order_id']; - - $response = Zend_Json::encode(array( - 'magento_order_id' => $result['magento_order_id'], - )); + try { + // Sync Order From Api + $result = $this->sync(array( + 'oyst_order_id' => $oystOrderId, + )); + $magentoOrderId = $result['magento_order_id']; + + $response = Zend_Json::encode(array( + 'magento_order_id' => $result['magento_order_id'], + )); + } catch(Exception $e) { + $notification + ->setMageResponse(Zend_Json::encode(array( + 'message' => $e->getMessage() . ' see : error_oyst.log', + ))) + ->registerNotificationFail(); + throw $e; + } } // Save new status and result in db - $notification->setStatus(Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_FINISHED) + $notification ->setMageResponse($response) ->setOrderId($magentoOrderId) - ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) - ->save(); + ->registerNotificationFinish(); return $response; } @@ -115,8 +114,8 @@ public function sync($params) $oystOrderId = $params['oyst_order_id']; // Sync API - /** @var Oyst_OneClick_Model_Order_ApiWrapper $orderApi */ - $orderApi = Mage::getModel('oyst_oneclick/order_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Order $orderApi */ + $orderApi = Mage::getModel('oyst_oneclick/apiWrapper_type_order'); try { $this->orderResponse = $orderApi->getOrder($oystOrderId); @@ -145,12 +144,25 @@ private function createMagentoOrder($oystOrderId) Mage::register('order_status_changing', true); /** @var Oyst_OneClick_Model_Magento_Quote $magentoQuoteBuilder */ - $magentoQuoteBuilder = Mage::getModel('oyst_oneclick/magento_quote', $this->orderResponse); - $magentoQuoteBuilder->syncQuoteFacade(); + $quote = Mage::getModel('sales/quote')->load($this->orderResponse['order']['context']['quote_id']); + Mage::helper('oyst_oneclick')->addQuoteExtraData( + $quote, 'newsletter_optin', $this->orderResponse['order']['newsletter_optin'] + ); + $quote->collectTotals(); + + Mage::dispatchEvent( + 'oyst_oneclick_model_order_create_magento_order_before', + array('quote' => $quote) + ); /** @var Oyst_OneClick_Model_Magento_Order $magentoOrderBuilder */ - $magentoOrderBuilder = Mage::getModel('oyst_oneclick/magento_order', $magentoQuoteBuilder->getQuote()); - $magentoOrderBuilder->buildOrder(); + $magentoOrderBuilder = Mage::getModel('oyst_oneclick/magento_order', $this->orderResponse); + $magentoOrderBuilder->setQuote($quote)->saveOrder(); + + Mage::dispatchEvent( + 'oyst_oneclick_model_order_create_magento_order_after', + array('quote' => $quote, 'order' => $magentoOrderBuilder->getOrder()) + ); $magentoOrderBuilder->getOrder()->addStatusHistoryComment( Mage::helper('oyst_oneclick')->__( @@ -165,7 +177,7 @@ private function createMagentoOrder($oystOrderId) Mage::unregister('order_status_changing'); - $this->clearCart($magentoQuoteBuilder->getQuote()->getQuoteId(), $oystOrderId); + $this->clearCart($quote->getQuoteId(), $oystOrderId); $magentoOrderBuilder->getOrder()->sendNewOrderEmail(); @@ -182,8 +194,8 @@ private function changeStatus(Mage_Sales_Model_Order $order) // Update Oyst order to accepted and auto-generate invoice if (in_array($currentStatus, array(OystOrderStatus::PENDING))) { - /** @var Oyst_OneClick_Model_Order_ApiWrapper $orderApiClient */ - $orderApiClient = Mage::getModel('oyst_oneclick/order_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Order $orderApiClient */ + $orderApiClient = Mage::getModel('oyst_oneclick/apiWrapper_type_order'); try { $response = $orderApiClient->updateOrder($this->orderResponse['order']['id'], OystOrderStatus::ACCEPTED, $order->getIncrementId()); @@ -191,13 +203,21 @@ private function changeStatus(Mage_Sales_Model_Order $order) $this->initTransaction($order); - $order->addStatusHistoryComment( - Mage::helper('oyst_oneclick')->__( - '%s update order status to: "%s".', - $this->paymentMethod, - OystOrderStatus::ACCEPTED - ) - ); + if (!$order->getPayment()->getIsFraudDetected()) { + $status = Mage::getStoreConfig('oyst/oneclick/order_status_payment_accepted'); + $order->setState( + Mage_Sales_Model_Order::STATE_PROCESSING, + $status ? $status : Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_ACCEPTED, + Mage::helper('oyst_oneclick')->__( + '%s update order status to: "%s".', + $this->paymentMethod, + OystOrderStatus::ACCEPTED + ) + ); + } else { + $status = Mage::getStoreConfig('oyst/oneclick/order_status_payment_fraud'); + $order->setStatus($status ? $status : Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_FRAUD); + } $invIncrementIDs = array(); if ($order->hasInvoices()) { @@ -224,6 +244,11 @@ private function changeStatus(Mage_Sales_Model_Order $order) $order->cancel(); } + Mage::dispatchEvent( + 'oyst_oneclick_model_order_change_status_after', + array('order' => $order) + ); + $order->save(); } @@ -251,6 +276,11 @@ private function initTransaction(Mage_Sales_Model_Order $order) if (Mage::helper('oyst_oneclick')->getConfig('enable_invoice_auto_generation')) { $payment->registerCaptureNotification($helper->getHumanAmount($this->orderResponse['order']['order_amount']['value'])); } + + Mage::dispatchEvent( + 'oyst_oneclick_model_order_init_transaction_after', + array('payment' => $payment, 'order' => $order) + ); } /** diff --git a/app/code/community/Oyst/OneClick/Model/Payment/Data.php b/app/code/community/Oyst/OneClick/Model/Payment/Data.php index 08c5d03e..fbc434bb 100644 --- a/app/code/community/Oyst/OneClick/Model/Payment/Data.php +++ b/app/code/community/Oyst/OneClick/Model/Payment/Data.php @@ -60,16 +60,7 @@ public function processNotification($event, $data) // Create new notification in db with status 'start' $notification = Mage::getModel('oyst_oneclick/notification'); - $notification->setData( - array( - 'event' => $event, - 'oyst_data' => Zend_Json::encode($data), - 'status' => Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_START, - 'created_at' => Mage::getSingleton('core/date')->gmtDate(), - 'executed_at' => Mage::getSingleton('core/date')->gmtDate(), - ) - ); - $notification->save(); + $notification->registerNotificationStart($event, $data); // Get order_increment_id if (empty($data['order_increment_id'])) { @@ -93,9 +84,7 @@ public function processNotification($event, $data) // If data asynchronous payment notification is success, we invoice the order, else we cancel if (Oyst_OneClick_Model_Payment_Method_Freepay::EVENT_CODE_FRAUD_VALIDATION == $data['event_code'] && $data['success']) { //save new status and result in db - $notification->setStatus(Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_FINISHED) - ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) - ->save(); + $notification->registerNotificationFinish(); // @TODO implement fraud validation return 'by-pass fraud validation'; @@ -123,10 +112,9 @@ public function processNotification($event, $data) } //save new status and result in db - $notification->setStatus(Oyst_OneClick_Model_Notification::NOTIFICATION_STATUS_FINISHED) + $notification ->setOrderId($result['order_id']) - ->setExecutedAt(Mage::getSingleton('core/date')->gmtDate()) - ->save(); + ->registerNotificationFinish(); return json_encode(array('order_id' => $result['order_id'])); } @@ -265,6 +253,11 @@ protected function _addTransaction($order, $transactionData) $payment->registerCaptureNotification($amount, true); } + Mage::dispatchEvent( + 'oyst_oneclick_model_payment_data_add_transaction_after', + array('payment' => $payment, 'order' => $order) + ); + $order->save(); } } @@ -278,8 +271,8 @@ public function getPaymentUrl() { $params = $this->_constructParams(); - /** @var Oyst_OneClick_Model_Payment_ApiWrapper $paymentApiWrapper */ - $paymentApiWrapper = Mage::getModel('oyst_oneclick/payment_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Payment $paymentApiWrapper */ + $paymentApiWrapper = Mage::getModel('oyst_oneclick/apiWrapper_type_payment'); $response = $paymentApiWrapper->getPaymentUrl($params); return $response; @@ -437,7 +430,7 @@ protected function _getCustomerInfosFromQuote($quote) * * @return float|int $amount */ - private function getFormatAmount($transactionData) + protected function getFormatAmount($transactionData) { $amount = !empty($transactionData['amount']) ? !empty($transactionData['amount']['value']) ? $transactionData['amount']['value'] : 0 : 0; diff --git a/app/code/community/Oyst/OneClick/Model/Payment/Method/Freepay.php b/app/code/community/Oyst/OneClick/Model/Payment/Method/Freepay.php index 95684af5..0a9f9741 100644 --- a/app/code/community/Oyst/OneClick/Model/Payment/Method/Freepay.php +++ b/app/code/community/Oyst/OneClick/Model/Payment/Method/Freepay.php @@ -58,8 +58,8 @@ public function getOrderPlaceRedirectUrl() */ public function refund(Varien_Object $payment, $amount) { - /** @var Oyst_OneClick_Model_Payment_ApiWrapper $api */ - $api = Mage::getModel('oyst_oneclick/payment_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Payment $api */ + $api = Mage::getModel('oyst_oneclick/apiWrapper_type_payment'); $api->cancelOrRefund($payment->getLastTransId(), $amount); diff --git a/app/code/community/Oyst/OneClick/Model/Payment/Method/Oneclick.php b/app/code/community/Oyst/OneClick/Model/Payment/Method/Oneclick.php index bbf05ee6..8590dd60 100644 --- a/app/code/community/Oyst/OneClick/Model/Payment/Method/Oneclick.php +++ b/app/code/community/Oyst/OneClick/Model/Payment/Method/Oneclick.php @@ -28,6 +28,7 @@ class Oyst_OneClick_Model_Payment_Method_Oneclick extends Mage_Payment_Model_Met protected $_canUseCheckout = false; protected $_canUseForMultishipping = false; protected $_canManageRecurringProfiles = false; + protected $_canReviewPayment = true; /** * @return string @@ -63,8 +64,8 @@ public function refund(Varien_Object $payment, $amount) } try { - /** @var Oyst_OneClick_Model_Order_ApiWrapper $api */ - $api = Mage::getModel('oyst_oneclick/order_apiWrapper'); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Order $api */ + $api = Mage::getModel('oyst_oneclick/apiWrapper_type_order'); $api->refund($payment->getOrder()->getOystOrderId(), $amount); } catch (Exception $e) { /** @var Oyst_OneClick_Helper_Data $oystHelper */ @@ -84,4 +85,16 @@ public function refund(Varien_Object $payment, $amount) return $this; } + + public function denyPayment(Mage_Payment_Model_Info $payment) + { + parent::denyPayment($payment); + return true; + } + + public function acceptPayment(Mage_Payment_Model_Info $payment) + { + parent::acceptPayment($payment); + return true; + } } diff --git a/app/code/community/Oyst/OneClick/Model/System/Config/Source/Systemattributes.php b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Customattributes.php similarity index 91% rename from app/code/community/Oyst/OneClick/Model/System/Config/Source/Systemattributes.php rename to app/code/community/Oyst/OneClick/Model/System/Config/Source/Customattributes.php index efde4108..307c81e7 100644 --- a/app/code/community/Oyst/OneClick/Model/System/Config/Source/Systemattributes.php +++ b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Customattributes.php @@ -12,7 +12,7 @@ /** * Mode Model */ -class Oyst_OneClick_Model_System_Config_Source_Systemattributes +class Oyst_OneClick_Model_System_Config_Source_Customattributes { public function toOptionArray() { @@ -22,7 +22,6 @@ public function toOptionArray() $attributeModel = Mage::getModel('eav/entity_attribute'); $attrs = $attributeModel->getCollection() ->setEntityTypeFilter($type) - ->addFieldToFilter('is_user_defined', false) ->addFieldToFilter('frontend_input', 'select'); $array = array(); diff --git a/app/code/community/Oyst/OneClick/Model/System/Config/Source/Mode.php b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Mode.php index 7c9be07d..7580b47f 100644 --- a/app/code/community/Oyst/OneClick/Model/System/Config/Source/Mode.php +++ b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Mode.php @@ -25,8 +25,8 @@ class Oyst_OneClick_Model_System_Config_Source_Mode */ public function toOptionArray() { - /** @var Oyst_OneClick_Model_Api $oystClient */ - $oystApi = Mage::getModel('oyst_oneclick/api'); + /** @var Oyst_OneClick_Model_ApiWrapper_Client $oystClient */ + $oystApi = Mage::getModel('oyst_oneclick/apiWrapper_client'); $list = array(); foreach ($oystApi->getEnvironments() as $environment) { diff --git a/app/code/community/Oyst/OneClick/Model/System/Config/Source/ShipmentTypesList.php b/app/code/community/Oyst/OneClick/Model/System/Config/Source/ShipmentTypesList.php index cf124ba2..25a9c0b5 100644 --- a/app/code/community/Oyst/OneClick/Model/System/Config/Source/ShipmentTypesList.php +++ b/app/code/community/Oyst/OneClick/Model/System/Config/Source/ShipmentTypesList.php @@ -21,9 +21,9 @@ class Oyst_OneClick_Model_System_Config_Source_ShipmentTypesList extends Mage_Co */ public function toOptionArray() { - /** @var Oyst_OneClick_Model_OneClick_ApiWrapper $oneclickApi */ - $oneclickApi = Mage::getSingleton('oyst_oneclick/catalog_apiWrapper'); - $shipmentTypes = $oneclickApi->getShipmentTypes(); + /** @var Oyst_OneClick_Model_ApiWrapper_Type_Catalog $catalogApi */ + $catalogApi = Mage::getSingleton('oyst_oneclick/apiWrapper_type_catalog'); + $shipmentTypes = $catalogApi->getShipmentTypes(); $shipmentTypesList = array( array('value' => 0, 'label' => Mage::helper('oyst_oneclick')->__('Disabled')), diff --git a/app/code/community/Oyst/OneClick/Model/System/Config/Source/Status/Fraud.php b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Status/Fraud.php new file mode 100644 index 00000000..c945bec9 --- /dev/null +++ b/app/code/community/Oyst/OneClick/Model/System/Config/Source/Status/Fraud.php @@ -0,0 +1,20 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/** + * Refund status + */ +class Oyst_OneClick_Model_System_Config_Source_Status_Fraud extends Mage_Adminhtml_Model_System_Config_Source_Order_Status +{ + protected $_stateStatuses = array( + Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, + ); +} diff --git a/app/code/community/Oyst/OneClick/controllers/Checkout/CartController.php b/app/code/community/Oyst/OneClick/controllers/Checkout/CartController.php index b62213c6..7913f7fb 100644 --- a/app/code/community/Oyst/OneClick/controllers/Checkout/CartController.php +++ b/app/code/community/Oyst/OneClick/controllers/Checkout/CartController.php @@ -43,15 +43,25 @@ public function returnAction() $customer = Mage::getModel('customer/customer')->setWebsiteId($websiteId) ->loadByEmail($order->getCustomerEmail()); - /** @var Mage_Customer_Model_Session $session */ - $session = Mage::getSingleton('customer/session'); - $session->loginById($customer->getId()); - $session->setCustomerAsLoggedIn($customer); + if ($customer->getId()) { + /** @var Mage_Customer_Model_Session $session */ + $session = Mage::getSingleton('customer/session'); + $session->loginById($customer->getId()); + $session->setCustomerAsLoggedIn($customer); + + $newsletterOptin = Mage::helper('oyst_oneclick')->getSalesObjectExtraData($order, 'newsletter_optin'); + if ($newsletterOptin != Mage::getModel('newsletter/subscriber')->loadByCustomer($customer)->isSubscribed()) { + $customer + ->setIsSubscribed($newsletterOptin) + ->save(); + } + } $session = Mage::getSingleton('checkout/type_onepage')->getCheckout(); $session->setLastQuoteId($order->getQuoteId()) ->setLastSuccessQuoteId($order->getQuoteId()) - ->setLastOrderId($order->getId()); + ->setLastOrderId($order->getId()) + ->setLastRealOrderId($order->getIncrementId()); $successUrl = Mage::getStoreConfig('oyst/oneclick/checkout_cart_cta_success_page'); @@ -64,7 +74,7 @@ public function returnAction() /** @var Mage_Sales_Model_Quote $oystOrderId */ $oystOrderId = Mage::getModel('sales/quote')->load($oystRelatedQuoteId)->getOystOrderId(); - if (!Mage::getModel('oyst_oneclick/oneclick_apiWrapper')->isOystOrderStatusValid($oystOrderId)) { + if (!Mage::getModel('oyst_oneclick/apiWrapper_type_oneClick')->isOystOrderStatusValid($oystOrderId)) { $this->data = Mage::getBaseUrl() . Oyst_OneClick_Helper_Data::FAILURE_URL; } } @@ -89,22 +99,26 @@ private function sendResponse() public function initOystCheckoutAction() { $params = $this->getRequest()->getParams(); - $params['quoteId'] = Mage::getSingleton('checkout/session')->getQuoteId(); - if (!$params['quoteId']) { + $params['quote_id'] = Mage::getSingleton('checkout/session')->getQuoteId(); + + if (!$params['quote_id']) { Mage::getSingleton('checkout/cart')->save(); - $params['quoteId'] = Mage::getSingleton('checkout/session')->getQuoteId(); + $params['quote_id'] = Mage::getSingleton('checkout/session')->getQuoteId(); + Mage::getModel('oyst_oneclick/cart')->resetCartForSave(); } + $quote = Mage::getSingleton('checkout/cart')->getQuote(); + Mage::register('oyst-quote', $quote, true); + $params['preload'] = filter_var($params['preload'], FILTER_VALIDATE_BOOLEAN); - if (isset($params['isCheckoutCart'])) { - $params['isCheckoutCart'] = filter_var($params['isCheckoutCart'], FILTER_VALIDATE_BOOLEAN); - } $params['add_to_cart_form'] = isset($params['add_to_cart_form']) ? Zend_Json::decode($params['add_to_cart_form']) : null; try { + Mage::getSingleton('checkout/session')->setOystRelatedQuoteId($quote->getId()); + + /** @var Oyst_OneClick_Model_Cart $oystCart */ $oystCart = Mage::getModel('oyst_oneclick/cart'); $this->data = $oystCart->initOystCheckout($params); - Mage::getSingleton('checkout/session')->setOystRelatedQuoteId($params['quoteId']); } catch (Exception $e) { Mage::helper('oyst_oneclick')->log($e->__toString()); $this->data = array('has_error' => 1, 'message' => $e->getMessage()); diff --git a/app/code/community/Oyst/OneClick/controllers/NotificationsController.php b/app/code/community/Oyst/OneClick/controllers/NotificationsController.php index 155b4390..9c68312c 100644 --- a/app/code/community/Oyst/OneClick/controllers/NotificationsController.php +++ b/app/code/community/Oyst/OneClick/controllers/NotificationsController.php @@ -23,9 +23,15 @@ public function indexAction() { $event = $this->getRequest()->getPost('event'); $data = $this->getRequest()->getPost('data'); + $input = $this->getRequest()->getRawBody(); - // @codingStandardsIgnoreLine - $post = (array)Zend_Json::decode(str_replace("\n", '', file_get_contents('php://input'))); + try { + // @codingStandardsIgnoreLine + $post = (array)Zend_Json::decode(str_replace("\n", '', $input)); + } catch (\Exception $e) { + $this->traceException($e, $input); + return $this->badRequest('Invalid JSON Data '.json_encode($input)); + } // Set the type and data from notification url if (empty($event) && empty($data) && !empty($post)) { @@ -55,8 +61,6 @@ public function indexAction() break; // OneClick case 'order.cart.estimate': - case 'order.stock.book': - case 'order.stock.released': $modelName = 'oyst_oneclick/catalog'; break; // FreePay @@ -76,11 +80,21 @@ public function indexAction() /** @var Oyst_OneClick_Model_Catalog|Oyst_OneClick_Model_Order $model */ $model = Mage::getModel($modelName); } catch (\Exception $e) { + $this->traceException($e, $data); return $this->badRequest('Model name ' . $modelName . ' is missing. ' . $e->getMessage()); } - /** @var Oyst_OneClick_Model_Catalog|Oyst_OneClick_Model_Order $model */ - $response = $model->processNotification($event, $data); + try { + /** @var Oyst_OneClick_Model_Catalog|Oyst_OneClick_Model_Order $model */ + Mage::app()->getStore()->setConfig(Mage_Directory_Helper_Data::XML_PATH_STATES_REQUIRED, ''); + $response = $model->processNotification($event, $data); + } catch (\Mage_Checkout_Exception $e) { + $this->traceException($e, $data); + return $this->badRequest($e->getMessage()); + } catch (\Exception $e) { + $this->traceException($e, $data); + return $this->errorResponse($e->getMessage()); + } if ('cgi-fcgi' === php_sapi_name()) { $this->getResponse()->setHeader('Content-type', 'application/json'); @@ -100,6 +114,28 @@ public function badRequest($message = null) $this->getResponse() ->clearHeaders() ->setHeader('HTTP/1.1', '400 Bad Request') - ->setBody('400 Bad Request' . $message); + ->setBody(json_encode(array('error' => 'M1-Oyst-Error', 'message' => $message))); + } + + /** + * @param string $message + */ + public function errorResponse($message = null) + { + if (isset($message)) { + $message = ': ' . (string)$message; + } + + $this->getResponse() + ->clearHeaders() + ->setHeader('HTTP/1.1', '500 Internal Server Error') + ->setBody('500 Internal Server Error' . $message); + } + + protected function traceException($exception, $input) + { + Mage::log($input, null, 'error_oyst.log', true); + Mage::log($exception->__toString(), null, 'error_oyst.log', true); + return $this; } } diff --git a/app/code/community/Oyst/OneClick/data/oyst_oneclick_setup/data-upgrade-1.13.1-1.13.2.php b/app/code/community/Oyst/OneClick/data/oyst_oneclick_setup/data-upgrade-1.13.1-1.13.2.php new file mode 100644 index 00000000..2843d8a7 --- /dev/null +++ b/app/code/community/Oyst/OneClick/data/oyst_oneclick_setup/data-upgrade-1.13.1-1.13.2.php @@ -0,0 +1,47 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/* @var Mage_Core_Model_Resource_Setup $this */ +$installer = $this; + +$data = array(); +$data[] = array( + 'status' => Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_ACCEPTED, + 'label' => 'Oyst Payment Accepted', +); +$data[] = array( + 'status' => Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_FRAUD, + 'label' => 'Oyst Payment Fraud', +); +$installer->getConnection()->insertArray( + $installer->getTable('sales/order_status'), + array('status', 'label'), + $data +); + +$data = array(); +$data[] = array( + 'status' => Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_ACCEPTED, + 'state' => Mage_Sales_Model_Order::STATE_PROCESSING, + 'is_default' => 0 +); +$data[] = array( + 'status' => Oyst_OneClick_Helper_Data::STATUS_OYST_PAYMENT_FRAUD, + 'state' => Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW, + 'is_default' => 0 +); + +$installer->getConnection()->insertArray( + $installer->getTable('sales/order_status_state'), + array('status', 'state', 'is_default'), + $data +); + diff --git a/app/code/community/Oyst/OneClick/etc/config.xml b/app/code/community/Oyst/OneClick/etc/config.xml index c39d18f1..be165da5 100644 --- a/app/code/community/Oyst/OneClick/etc/config.xml +++ b/app/code/community/Oyst/OneClick/etc/config.xml @@ -2,7 +2,7 @@ - 1.12.0 + 1.13.11 @@ -43,11 +43,17 @@ * + + * + * + + * + @@ -231,7 +237,6 @@ //cdn.oyst.com/ 1 1 - 1 1 default disable @@ -248,6 +253,9 @@ -5 minutes 6 3 + processing + fraud + 1 0 diff --git a/app/code/community/Oyst/OneClick/etc/system.xml b/app/code/community/Oyst/OneClick/etc/system.xml index 4f012071..61fc35f3 100644 --- a/app/code/community/Oyst/OneClick/etc/system.xml +++ b/app/code/community/Oyst/OneClick/etc/system.xml @@ -304,6 +304,24 @@ + + + + select + adminhtml/system_config_source_yesno + oyst/oneclick/button_sticky + 45 + 1 + 1 + 1 + + +
general
+ 1 +
+
+
+ @@ -671,13 +689,14 @@ - - - + + + + Yes creation of the invoice when the order is created, the "Due amount" will be 0.
No the order remains with a "Due amount" and the invoice is not created.]]>
select adminhtml/system_config_source_yesno - oyst/oneclick/should_ask_stock - 20 + oyst/oneclick/enable_invoice_auto_generation + 25 1 1 1 @@ -687,16 +706,14 @@ 1 -
+ - - - - Yes creation of the invoice when the order is created, the "Due amount" will be 0.
No the order remains with a "Due amount" and the invoice is not created.]]>
+ + select - adminhtml/system_config_source_yesno - oyst/oneclick/enable_invoice_auto_generation - 25 + adminhtml/system_config_source_order_status_processing + oyst/oneclick/order_status_payment_accepted + 27 1 1 1 @@ -706,7 +723,24 @@ 1 -
+ + + + + select + oyst_oneclick/system_config_source_status_fraud + oyst/oneclick/order_status_payment_fraud + 28 + 1 + 1 + 1 + + +
general
+ 1 +
+
+
@@ -762,14 +796,31 @@ + + + + select + adminhtml/system_config_source_yesno + oyst/oneclick/force_button_display_on_product + 42 + 1 + 1 + 1 + + +
general
+ 1 +
+
+
- - - + + + multiselect - oyst_oneclick/system_config_source_systemattributes - oyst/oneclick/systemattributes + oyst_oneclick/system_config_source_customattributes + oyst/oneclick/customattributes 45 1 1 @@ -781,7 +832,7 @@ 1 - + diff --git a/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.12.0-1.13.0.php b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.12.0-1.13.0.php new file mode 100644 index 00000000..591d3823 --- /dev/null +++ b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.12.0-1.13.0.php @@ -0,0 +1,17 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/* @var Mage_Core_Model_Resource_Setup $this */ +$installer = $this; + +$installer->run("UPDATE `{$this->getTable('eav_attribute')}` SET `attribute_code` = 'is_oneclick_disable_on_product' WHERE `attribute_code` = 'is_oneclick_active_on_product';"); + +$installer->endSetup(); diff --git a/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.0-1.13.1.php b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.0-1.13.1.php new file mode 100644 index 00000000..d4cb5277 --- /dev/null +++ b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.0-1.13.1.php @@ -0,0 +1,20 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/* @var Mage_Core_Model_Resource_Setup $this */ +$installer = $this; + +$installer->getConnection()->dropForeignKey( + $installer->getTable('oyst_oneclick/notification'), + $installer->getFkName('oyst_oneclick/notification', 'order_id', 'sales/order', 'entity_id') +); + +$installer->endSetup(); diff --git a/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.9-1.13.9.php b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.9-1.13.9.php new file mode 100644 index 00000000..103b20c9 --- /dev/null +++ b/app/code/community/Oyst/OneClick/sql/oyst_oneclick_setup/mysql4-upgrade-1.13.9-1.13.9.php @@ -0,0 +1,37 @@ + <@oyst> + * @category Oyst + * @package Oyst_OneClick + * @copyright Copyright (c) 2017 Oyst (http://www.oyst.com) + */ + +/* @var $installer Mage_Checkout_Model_Mysql4_Setup */ +$installer = $this; + +/* @var $this Mage_Core_Model_Resource_Setup */ +$installer->startSetup(); + +$sales = new Mage_Sales_Model_Mysql4_Setup('sales_setup'); +$sales->startSetup(); + +// Add attribute to order and quote for synchronisation +$sales->addAttribute( + 'order', + 'oyst_extra_data', + array( + 'type' => 'text', + ) +); +$sales->addAttribute( + 'quote', + 'oyst_extra_data', + array( + 'type' => 'text', + ) +); + +$installer->endSetup(); diff --git a/app/design/frontend/base/default/layout/oyst_oneclick.xml b/app/design/frontend/base/default/layout/oyst_oneclick.xml index 93d1c364..7f1b98d4 100644 --- a/app/design/frontend/base/default/layout/oyst_oneclick.xml +++ b/app/design/frontend/base/default/layout/oyst_oneclick.xml @@ -14,13 +14,6 @@ - - - - - - - @@ -89,4 +82,10 @@ + + + + + + diff --git a/app/design/frontend/base/default/template/oyst/oneclick/checkout/cart/oneclick.phtml b/app/design/frontend/base/default/template/oyst/oneclick/checkout/cart/oneclick.phtml index 6a4534c0..8715dfad 100644 --- a/app/design/frontend/base/default/template/oyst/oneclick/checkout/cart/oneclick.phtml +++ b/app/design/frontend/base/default/template/oyst/oneclick/checkout/cart/oneclick.phtml @@ -24,8 +24,7 @@ (function () { if ("function" === typeof oystOneClick) { var oystOneClickConfig = { - 'oneClickUrl': getOneClickUrl(); ?>, - 'isCheckoutCart': true + 'oneClickUrl': getOneClickUrl(); ?> }; oystOneClick(oystOneClickConfig); diff --git a/app/design/frontend/base/default/template/oyst/oneclick/product/view/oneclick.phtml b/app/design/frontend/base/default/template/oyst/oneclick/product/view/oneclick.phtml index fbd46fb4..e5409212 100644 --- a/app/design/frontend/base/default/template/oyst/oneclick/product/view/oneclick.phtml +++ b/app/design/frontend/base/default/template/oyst/oneclick/product/view/oneclick.phtml @@ -29,7 +29,6 @@ if ($this->isSupportedProduct() && $this->isButtonEnabled()) : if ("function" === typeof oystOneClick) { var oystOneClickConfig = { 'oneClickUrl': getOneClickUrl(); ?>, - 'isCheckoutCart': false, 'addToCartProductFormId': 'product_addtocart_form', 'isProductAddtocartFormValidate': escapeHtml($this->isProductAddtocartFormValidate()); ?>, 'addtocartButtonsClass': Yes creation of the invoice when the order is created, the ""Due amount"" will be 0.
No the order remains with a ""Due amount"" and the invoice is not created.","Yes creation of the invoice when the order is created, the ""Due amount"" will be 0.
No the order remains with a ""Due amount"" and the invoice is not created." "Button theme","Button theme" @@ -188,3 +187,5 @@ "Allowed IPs (comma separated)","Allowed IPs (comma separated)" "Leave empty for access from any location.","Leave empty for access from any location." + +"Oyst has recognized you as a customer, so you benefit a promotion on this product.","Oyst has recognized you as a customer, so you benefit a promotion on this product." diff --git a/app/locale/fr_FR/Oyst_OneClick.csv b/app/locale/fr_FR/Oyst_OneClick.csv index bc245f8a..c697d5d1 100644 --- a/app/locale/fr_FR/Oyst_OneClick.csv +++ b/app/locale/fr_FR/Oyst_OneClick.csv @@ -39,7 +39,6 @@ "Enable native form validator to add to cart","Activer le validateur natif de formulaire d'ajout au panier" "To use a custom validator, disable and implement a javascript function isCustomProductAddtocartFormValid","Pour utiliser un validateur custom, désactiver et implémenter une fonction javascript isCustomProductAddtocartFormValid" "Allow the customer to change the quantity of purchases in the payment modal","Autoriser le client à modifier la quantité des achats depuis la modale de paiement" -"Should ask stock","Intérroger le stock" "Enable invoice auto-generation","Activer la génération automatique de la facture" "Yes creation of the invoice when the order is created, the ""Due amount"" will be 0.
No the order remains with a ""Due amount"" and the invoice is not created.","Oui création de la facture à la création de la commande, le ""Montant dû"" sera à 0.
Non la commande reste avec un ""Montant dû"" et la facture n'est pas créée." "Button theme","Thème du bouton" @@ -188,3 +187,5 @@ "Allowed IPs (comma separated)","Adresses IP autorisées (séparées par des virgules)" "Leave empty for access from any location.","Laissez vide pour l'accès de n'importe quel endroit." + +"Oyst has recognized you as a customer, so you benefit a promotion on this product.","Oyst vous a identifié en tant que client, vous bénéficiez d'une promotion sur ce produit." diff --git a/build.config.php b/build.config.php new file mode 100644 index 00000000..3fa51f6e --- /dev/null +++ b/build.config.php @@ -0,0 +1,62 @@ + getcwd() . '/travis_release', + 'archive_files' => 'Oyst_OneClick.tar', + + // The Magento Connect extension name. Must be unique on Magento Connect + // Has no relation to your code module name. Will be the Connect extension name + 'extension_name' => 'Oyst_OneClick', + + // Your extension version. By default, if you're creating an extension from a + // single Magento module, the tar-to-connect script will look to make sure this + // matches the module version. You can skip this check by setting the + // skip_version_compare value to true + 'extension_version' => '1.12.0', + 'skip_version_compare' => true, + + // You can also have the package script use the version in the module you + // are packaging with. + 'auto_detect_version' => false, + + // Where on your local system you'd like to build the files to + 'path_output' => getcwd() . '/travis_release', + + // Magento Connect license value. + 'stability' => 'stable', + + // Magento Connect license value + 'license' => 'Apache', + + // Magento Connect channel value. This should almost always (always?) be community + 'channel' => 'community', + + // Magento Connect information fields. + 'summary' => 'Oyst 1-Click is a purchase button which enables your customers to buy in 1 clic directly from your product page.', + 'description' => 'Oyst 1-Click helps e-commerce website to multiply their conversion rate by 2:
+
    +
  • Multiply your conversion rate by 2 on desktop and by 5 on mobile ;
  • +
  • Prevent cart abandonment between the product page and the payment confirmation-thrive thanks to Oyst community, our network effect will bring you more customers ;
  • +
  • A boon for purchases on mobile where conversion rate are particularly low.
  • +
+Oyst 1-Click is powered by strong security technologies:
+
    +
  • Our technology Everkey uses cross-checking among 117 criteria (data science, biometrics) to prevent any fraud) ;
  • +
  • We have a partnership with Adyen, one of the global leaders of online payment (Uber, Blablacar, Airbnb).
  • +
', + 'notes' => 'Check https://github.com/oystparis/oyst-1click-magento/releases/latest for details.', + + // Magento Connect author information. If author_email is foo@example.com, script will + // prompt you for the correct name. Should match your http://www.magentocommerce.com/ + // login email address + 'author_name' => 'Oyst', + 'author_user' => '1Click', + 'author_email' => 'plugin@oyst.com', + + // PHP min/max fields for Connect. I don't know if anyone uses these, but you should + // probably check that they're accurate + 'php_min' => '5.3.0', + 'php_max' => '8.0.0', +); diff --git a/skin/frontend/base/default/js/oyst/oneclick.js b/skin/frontend/base/default/js/oyst/oneclick.js index 17d8760f..6b8ce60c 100644 --- a/skin/frontend/base/default/js/oyst/oneclick.js +++ b/skin/frontend/base/default/js/oyst/oneclick.js @@ -35,10 +35,8 @@ function oystOneClick(config) { ready(function () { var form = new FormData(); + form.append("preload", opts.preload); - if (config.isCheckoutCart) { - form.append("isCheckoutCart", config.isCheckoutCart); - } if (config.addToCartProductFormId) { var isErrorsInForm = null; @@ -72,6 +70,9 @@ function oystOneClick(config) { } }); form.append("add_to_cart_form", JSON.stringify(addToCartFormData)); + $$('#'+config.addToCartProductFormId+' input[type="file"]').each(function(elem){ + form.append(elem.name, elem.files[0]); + }); } } @@ -111,7 +112,7 @@ function oystOneClick(config) { cb(isErrorsInForm, data.url); - if (messageProductViewElem) { + if (messageProductViewElem && messageProductViewElem.parentNode) { messageProductViewElem.parentNode.removeChild(messageProductViewElem); } } @@ -123,17 +124,18 @@ function oystOneClick(config) { }; var allowOystRedirectSelf = true; - window.addEventListener('message', function(event){ - if (event.data.type == 'ORDER_COMPLETE' && config.isCheckoutCart) { - allowOystRedirectSelf = false; + window.addEventListener("message", function (event) { + if (event.data.type == "ORDER_COMPLETE" + || event.data.type == "ORDER_CONVERSION") { + allowOystRedirectSelf = false; } - if (event.data.type == 'ORDER_CANCEL') { - allowOystRedirectSelf = true; + if (event.data.type == "ORDER_CANCEL") { + allowOystRedirectSelf = true; } - if (event.data.type == 'MODAL_CLOSE' && allowOystRedirectSelf) { - window.location.reload(false); + if (event.data.type == "MODAL_CLOSE" && allowOystRedirectSelf) { + window.location.reload(false); } }); } diff --git a/var/connect/Oyst_OneClick.xml b/var/connect/Oyst_OneClick.xml index 8b60b10b..f450296f 100644 --- a/var/connect/Oyst_OneClick.xml +++ b/var/connect/Oyst_OneClick.xml @@ -1,5 +1,5 @@ <_> - E8Le1MFN0FYXDMdj + UwVbhCE8nCZMnDpm Oyst_OneClick community @@ -19,20 +19,18 @@ Oyst 1-Click is powered by strong security technologies:<br /> </ul> Apache https://www.apache.org/licenses/LICENSE-2.0.txt - 1.12.0 + 1.13.11 stable Check https://github.com/oystparis/oyst-1click-magento/releases/latest for details. - + Oyst - - 1Click - - plugin@oyst.com - + + 2018-06-11 + 5.3.0 8.0.0 @@ -50,7 +48,7 @@ Oyst 1-Click is powered by strong security technologies:<br /> - + diff --git a/var/connect/package.xml b/var/connect/package.xml index 4be03e4e..a95ad0ce 100644 --- a/var/connect/package.xml +++ b/var/connect/package.xml @@ -1,28 +1,28 @@ Oyst_OneClick - 0.1.2-beta-1 + 1.13.11 stable Apache community <strong>Oyst 1-Click</strong> is a purchase button which enables your customers to buy in 1 clic directly from your product page. <strong>Oyst 1-Click</strong> helps e-commerce website to multiply their conversion rate by 2:<br /> -<ul> -<li>Multiply your conversion rate by 2 on desktop and by 5 on mobile ;</li> -<li>Prevent cart abandonment between the product page and the payment confirmation-thrive thanks to Oyst community, our network effect will bring you more customers ;</li> -<li>A boon for purchases on mobile where conversion rate are particularly low.</li> -</ul> -Oyst 1-Click is powered by strong security technologies:<br /> -<ul> -<li>Our technology Everkey uses cross-checking among 117 criteria (data science, biometrics) to prevent any fraud) ;</li> -<li>We have a partnership with Adyen, one of the global leaders of online payment (Uber, Blablacar, Airbnb).</li> -</ul> - Check https://github.com/OystParis/oyst-1click-magento for details. + <ul> + <li>Multiply your conversion rate by 2 on desktop and by 5 on mobile ;</li> + <li>Prevent cart abandonment between the product page and the payment confirmation-thrive thanks to Oyst community, our network effect will bring you more customers ;</li> + <li>A boon for purchases on mobile where conversion rate are particularly low.</li> + </ul> + Oyst 1-Click is powered by strong security technologies:<br /> + <ul> + <li>Our technology Everkey uses cross-checking among 117 criteria (data science, biometrics) to prevent any fraud) ;</li> + <li>We have a partnership with Adyen, one of the global leaders of online payment (Uber, Blablacar, Airbnb).</li> + </ul> + Check https://github.com/oystparis/oyst-1click-magento/releases/latest for details. Oyst1Clickplugin@oyst.com - 2017-10-12 - - + 2018-06-11 + + 5.3.08.0.0