diff --git a/CHANGELOG.md b/CHANGELOG.md index bd296367839e4c7e2c7832ee4575772b604f0e45..1ec149d4a95f161422e47a9d6764198902fa4cdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +2.0.0.0-dev85 +============= +* Service layer updates: + * Implemented API for the CatalogInventory module + * Refactored the external usages of the CatalogInventory module to service +* Fixed bugs: + * Fixed an issue where a coupon usage option was not comprehensible enough + * Fixed an issue where products selection for adding to a bundle option was lost when switching between pages with product grids + * Fixed an issue where Google Content was not sending the correct 'description' attribute + * Fixed an issue where custom attributes were not displayed in layered navigation after a product import + * Fixed an issue where the Category URL keys did not work correctly after saving + * Fixed an issue where an admin could not create a Target rule with a certain Products to Display condition + * Fixed a jQuery error on a product page in the Admin panel, which appeared when switching between product tabs +* Framework Improvements: + * Created ProductsCustomOptions Service API for Catalog module + * Created DownloadableLink Service API for Catalog module +* GitHub requests: + * [#257] JSON loading should follow OWASP recommendation + 2.0.0.0-dev84 ============= * Fixed bugs: diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php index 51a736542ccb7cfa46e5437e41ac46ce4f82491a..1ea1f1c1741fec336e5d1e7999a737dd1a502f25 100644 --- a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php +++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php @@ -95,7 +95,7 @@ class Notification extends \Magento\Backend\App\AbstractAction } catch (\Exception $e) { $responseData['success'] = false; } - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->create('Magento\Core\Helper\Data')->jsonEncode($responseData) ); } diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php index 29e66dce686eefd9e7111ee0c1010dbe17341c17..e41fb155f05627bb03d76c8723e88736a2d62aea 100644 --- a/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php +++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php @@ -40,7 +40,7 @@ class Survey extends \Magento\Backend\App\Action if ($this->getRequest()->getParam('isAjax', false)) { $this->_objectManager->get('Magento\AdminNotification\Model\Survey')->saveSurveyViewed(true); } - $this->getResponse()->setBody(\Zend_Json::encode(array('survey_decision_saved' => 1))); + $this->getResponse()->representJson(\Zend_Json::encode(array('survey_decision_saved' => 1))); } /** diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php index ae2f578fcef0b918f4ab3d98e27e21a4ee0130ce..d32a72c10614767d66a2c145af14143ece17cd9c 100644 --- a/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php +++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php @@ -41,10 +41,7 @@ class Message extends \Magento\Backend\App\AbstractAction foreach ($messageCollection->getItems() as $item) { $result[] = array('severity' => $item->getSeverity(), 'text' => $item->getText()); } - $this->getResponse()->setHeader( - 'Content-Type', - 'application/json' - )->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) ); } diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php index 6aafb88564b8202a0d3a4f8679c63f912d4cc875..c8d74de1e48406c4344b91c4d288dd5675bfad88 100644 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php +++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php @@ -170,11 +170,14 @@ class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create 'sales/order_create/' ); } - - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } else { $result = array('error_messages' => __('Please choose a payment method.')); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -238,7 +241,7 @@ class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create public function returnQuoteAction() { $this->_returnQuote(); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1)) ); } diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php index 8af1616b5a5592bb12eb4594f1c4f0e25c3143dc..2ce624c8dfc63a66c0818baa6c26720e969f0b1d 100644 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php +++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php @@ -84,6 +84,8 @@ class Payment extends \Magento\Backend\App\Action } $this->_sessionQuote->getQuote()->getPayment()->save(); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } diff --git a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php index e601ca8b7f05e8011875a55f3a07433b9f096caf..708d048c5bd14593accfa37206c61bad6379229e 100644 --- a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php +++ b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php @@ -76,6 +76,8 @@ class Payment extends \Magento\Framework\App\Action\Action } $this->_session->getQuote()->getPayment()->save(); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php index 8aa9a9938ad48680a3aa2e20f278bd1c5b0e151e..0f1916b3c51653993bf029ecc30523f4a97e72f3 100644 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php +++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php @@ -207,7 +207,9 @@ class Payment extends \Magento\Framework\App\Action\Action ); } else { $result = array('error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment'); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -219,7 +221,7 @@ class Payment extends \Magento\Framework\App\Action\Action public function returnQuoteAction() { $this->_returnCustomerQuote(); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1)) ); } diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Observer.php b/app/code/Magento/Authorizenet/Model/Directpost/Observer.php index 3b1efcc2ce38b37fdcbee872db87367a8f70db43..06820ffd10b8d52a759283e60621f92046a711b4 100644 --- a/app/code/Magento/Authorizenet/Model/Directpost/Observer.php +++ b/app/code/Magento/Authorizenet/Model/Directpost/Observer.php @@ -137,7 +137,7 @@ class Observer $result['directpost'] = array('fields' => $requestToAuthorizenet->getData()); $response->clearHeader('Location'); - $response->setBody($this->_coreData->jsonEncode($result)); + $response->representJson($this->_coreData->jsonEncode($result)); } } } diff --git a/app/code/Magento/Backend/App/AbstractAction.php b/app/code/Magento/Backend/App/AbstractAction.php index 80e53fe5608fff53cbe5eb1b5196623a3d8e4b3a..9d533f7018a669afd39d18cea34b05a695c90385 100644 --- a/app/code/Magento/Backend/App/AbstractAction.php +++ b/app/code/Magento/Backend/App/AbstractAction.php @@ -280,7 +280,7 @@ abstract class AbstractAction extends \Magento\Framework\App\Action\Action $this->_actionFlag->set('', self::FLAG_NO_DISPATCH, true); $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); if ($this->getRequest()->getQuery('isAjax', false) || $this->getRequest()->getQuery('ajax', false)) { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get( 'Magento\Core\Helper\Data' )->jsonEncode( diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php b/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php index e89fa65b80b89dc6ad208f1fe85c771e884902e6..d11fec390d711f60f65c2bb3ab6f3c64f1655e39 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php @@ -58,7 +58,7 @@ class Ajax extends Action } catch (\Exception $e) { $response = "{error:true,message:'" . $e->getMessage() . "'}"; } - $this->getResponse()->setBody($response); + $this->getResponse()->representJson($response); $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); } diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth.php index a9a5c542608bb8e26fe18263249e01dc96b6143d..a7ac7f33901520d9355c6f977e6e0d165a3ee5f9 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/Auth.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth.php @@ -67,7 +67,7 @@ class Auth extends AbstractAction */ public function deniedJsonAction() { - $this->getResponse()->setBody($this->_getDeniedJson()); + $this->getResponse()->representJson($this->_getDeniedJson()); } /** diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Index.php index dac4abff50c075a7a5d54c53f11e525cf7d05f12..dd154d0dc1a7efde1bf5b06863d1fa077ece9722 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/Index.php @@ -99,8 +99,9 @@ class Index extends AbstractAction } } } - - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($items)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($items) + ); } /** diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php index a4110fbe5c0688f4fbfb4440bad51f1138cfafe3..ec91e6b450147f8fc1953553d8307716b2ce58c1 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php @@ -180,6 +180,6 @@ class Storage extends \Magento\Backend\App\Action } $result['state'] = $state; $result = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result); - $this->_response->setBody($result); + $this->_response->representJson($result); } } diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php index edcdb47925af60462e6ec4a303149f4a485d3f7b..3c8a8e7e9d0c1ec6b57d398c6d84516bc08029a8 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php @@ -149,7 +149,7 @@ class Variable extends Action $response->setError(true); $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** @@ -223,7 +223,7 @@ class Variable extends Action true ); $variables = array($storeContactVariabls, $customVariables); - $this->getResponse()->setBody(\Zend_Json::encode($variables)); + $this->getResponse()->representJson(\Zend_Json::encode($variables)); } /** diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php index c330de76277de58bb77cab6d158bb40a1b718314..0020666a60fa8339acd73007409c4a627295ffd3 100644 --- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php +++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php @@ -183,7 +183,7 @@ class Urlrewrite extends Action public function categoriesJsonAction() { $categoryId = $this->getRequest()->getParam('id', null); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get( 'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree' )->getTreeArray( diff --git a/app/code/Magento/Backend/view/adminhtml/templates/page/js/components.phtml b/app/code/Magento/Backend/view/adminhtml/templates/page/js/components.phtml index b1edc724bcaea6a3266fda72129cb59428ec4c4d..f53f3ca75148c184b4b3cec2e39ae6ee2ea163e2 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/page/js/components.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/page/js/components.phtml @@ -99,6 +99,9 @@ '<?php echo $this->getViewFileUrl('jquery/jstree/jquery.hotkeys.js') ?>', '<?php echo $this->getViewFileUrl('jquery/jstree/jquery.jstree.js') ?>', '<?php echo $this->getViewFileUrl('Magento_Catalog::js/category-tree.js') ?>' + ], + collapsible: [ + '<?php echo $this->getViewFileUrl('mage/collapsible.js') ?>' ] }) /** diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php index 0bee25a18940e32bf3cf26742ed6aec59e824362..30e2108db14b80a702b4437d7dd2bdabbaa5e603 100644 --- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php @@ -173,7 +173,7 @@ class Index extends \Magento\Backend\App\Action . 'putting your store into maintenance mode." ) ); - return $this->getResponse()->setBody($response->toJson()); + return $this->getResponse()->representJson($response->toJson()); } } @@ -211,7 +211,7 @@ class Index extends \Magento\Backend\App\Action $this->maintenanceMode->turnOff(); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** @@ -308,7 +308,7 @@ class Index extends \Magento\Backend\App\Action if (!$passwordValid) { $response->setError(__('Please correct the password.')); $backupManager->setErrorMessage(__('Please correct the password.')); - return $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } if ($this->getRequest()->getParam('maintenance_mode')) { @@ -327,7 +327,7 @@ class Index extends \Magento\Backend\App\Action . 'putting your store into maintenance mode." ) ); - return $this->getResponse()->setBody($response->toJson()); + return $this->getResponse()->representJson($response->toJson()); } } @@ -380,7 +380,7 @@ class Index extends \Magento\Backend\App\Action $this->maintenanceMode->turnOff(); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php index 804d3ecce63f5937257433cb6bd3036868e4e2d0..9ff68dfb5cb5f666143b392e5dc88aa8a27a7bba 100644 --- a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php +++ b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/Items/Renderer.php @@ -23,6 +23,8 @@ */ namespace Magento\Bundle\Block\Adminhtml\Sales\Order\Items; +use Magento\Catalog\Model\Product\Type\AbstractType; + /** * Adminhtml sales order item renderer */ @@ -56,11 +58,12 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend { $itemsArray = array(); + $items = false; if ($item instanceof \Magento\Sales\Model\Order\Invoice\Item) { $items = $item->getInvoice()->getAllItems(); - } else if ($item instanceof \Magento\Sales\Model\Order\Shipment\Item) { + } elseif ($item instanceof \Magento\Sales\Model\Order\Shipment\Item) { $items = $item->getShipment()->getAllItems(); - } else if ($item instanceof \Magento\Sales\Model\Order\Creditmemo\Item) { + } elseif ($item instanceof \Magento\Sales\Model\Order\Creditmemo\Item) { $items = $item->getCreditmemo()->getAllItems(); } @@ -96,11 +99,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return true; } else { @@ -110,11 +110,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return false; } else { @@ -126,9 +123,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend $options = $this->getOrderItem()->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && $options['shipment_type'] == \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return true; } @@ -150,11 +146,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } else { @@ -164,11 +157,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return false; } else { @@ -180,9 +170,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend $options = $this->getOrderItem()->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } @@ -208,10 +197,9 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend } /** - * @param mixed $item * @return array */ - public function getOrderOptions($item = null) + public function getOrderOptions() { $result = array(); $options = $this->getOrderItem()->getProductOptions(); @@ -269,8 +257,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\DefaultRend */ public function canShowPriceInfo($item) { - if ($item->getOrderItem()->getParentItem() && $this->isChildCalculated() || - !$item->getOrderItem()->getParentItem() && !$this->isChildCalculated() + if ($item->getOrderItem()->getParentItem() && $this->isChildCalculated() + || !$item->getOrderItem()->getParentItem() && !$this->isChildCalculated() ) { return true; } diff --git a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php index e075233f623b6ad49cba204b0f71b832ac7e15da..070b02878a5c3c030c1620885e3c565edfa962d6 100644 --- a/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php +++ b/app/code/Magento/Bundle/Block/Adminhtml/Sales/Order/View/Items/Renderer.php @@ -23,6 +23,8 @@ */ namespace Magento\Bundle\Block\Adminhtml\Sales\Order\View\Items; +use Magento\Catalog\Model\Product\Type\AbstractType; + /** * Adminhtml sales order item renderer */ @@ -57,11 +59,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return true; } else { @@ -71,11 +70,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && - $options['shipment_type'] == - \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return false; } else { @@ -87,9 +83,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ $options = $this->getOrderItem()->getProductOptions(); if ($options) { - if (isset( - $options['shipment_type'] - ) && $options['shipment_type'] == \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY + if (isset($options['shipment_type']) + && $options['shipment_type'] == AbstractType::SHIPMENT_SEPARATELY ) { return true; } @@ -108,11 +103,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ if ($parentItem) { $options = $parentItem->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } else { @@ -122,11 +114,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ } else { $options = $item->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && - $options['product_calculations'] == - \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return false; } else { @@ -138,9 +127,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ $options = $this->getItem()->getProductOptions(); if ($options) { - if (isset( - $options['product_calculations'] - ) && $options['product_calculations'] == \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD + if (isset($options['product_calculations']) + && $options['product_calculations'] == AbstractType::CALCULATE_CHILD ) { return true; } @@ -214,8 +202,8 @@ class Renderer extends \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\ */ public function canShowPriceInfo($item) { - if ($item->getParentItem() && $this->isChildCalculated() || - !$item->getParentItem() && !$this->isChildCalculated() + if ($item->getParentItem() && $this->isChildCalculated() + || !$item->getParentItem() && !$this->isChildCalculated() ) { return true; } diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php index 59202b3d80a3693c1f13023603501582730fb34d..a7a700fd32c5c201e20578e366b18d955b9fcb24 100644 --- a/app/code/Magento/Bundle/Model/Product/Type.php +++ b/app/code/Magento/Bundle/Model/Product/Type.php @@ -356,6 +356,11 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType ); $product->unsetData('msrp'); $product->unsetData('msrp_display_actual_price_type'); + + /** unset product custom options for dynamic price */ + if ($product->hasData('product_options')) { + $product->unsetData('product_options'); + } } $product->canAffectOptions(false); diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js b/app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js index 78b2b5f9ee78728f77a02eafe7d50cb0629377c5..586738ab20aa7c97e8e347b6cc10eca2e1d3e278 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js @@ -91,6 +91,8 @@ bSelection.gridSelection.set(optionIndex, $H({})); bSelection.gridRemoval = $H({}); bSelection.gridSelectedProductSkus = productSkus; + + $selectionGrid.on('contentUpdated', bSelection.gridUpdateCallback); $selectionGrid.on('change', '.col-id input', function () {//_on can't be used because of grid reloading var tr = $(this).closest('tr'); if ($(this).is(':checked')) { diff --git a/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php b/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php index 744d4682092027d8f09133cd765430e6beb7e608..9c7622334aec94fbc037a81608542b279008a40a 100644 --- a/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php +++ b/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php @@ -47,7 +47,7 @@ class Refresh extends \Magento\Backend\App\Action )->setIsAjax( true )->toHtml(); - $this->getResponse()->setBody(json_encode(array('imgSrc' => $captchaModel->getImgSrc()))); + $this->getResponse()->representJson(json_encode(array('imgSrc' => $captchaModel->getImgSrc()))); $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); } } diff --git a/app/code/Magento/Captcha/Controller/Refresh.php b/app/code/Magento/Captcha/Controller/Refresh.php index 31955e40fe851752d085d593d156a262ae191afb..f505d6cd974ad6a2c85b002a82af5273a6b3abe2 100644 --- a/app/code/Magento/Captcha/Controller/Refresh.php +++ b/app/code/Magento/Captcha/Controller/Refresh.php @@ -47,7 +47,7 @@ class Refresh extends \Magento\Framework\App\Action\Action )->setIsAjax( true )->toHtml(); - $this->getResponse()->setBody(json_encode(array('imgSrc' => $captchaModel->getImgSrc()))); + $this->getResponse()->representJson(json_encode(array('imgSrc' => $captchaModel->getImgSrc()))); $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); } } diff --git a/app/code/Magento/Captcha/Model/Observer.php b/app/code/Magento/Captcha/Model/Observer.php index 020d9334ff812dcce645dca918100dfd69028b2f..9704e53eebca7c180cfa6a0e4e47efad38e3319e 100644 --- a/app/code/Magento/Captcha/Model/Observer.php +++ b/app/code/Magento/Captcha/Model/Observer.php @@ -246,7 +246,7 @@ class Observer if (!$captchaModel->isCorrect($this->_getCaptchaString($controller->getRequest(), $formId))) { $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true); $result = array('error' => 1, 'message' => __('Incorrect CAPTCHA')); - $controller->getResponse()->setBody($this->_coreData->jsonEncode($result)); + $controller->getResponse()->representJson($this->_coreData->jsonEncode($result)); } } } @@ -270,7 +270,7 @@ class Observer if (!$captchaModel->isCorrect($this->_getCaptchaString($controller->getRequest(), $formId))) { $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true); $result = array('error' => 1, 'message' => __('Incorrect CAPTCHA')); - $controller->getResponse()->setBody($this->_coreData->jsonEncode($result)); + $controller->getResponse()->representJson($this->_coreData->jsonEncode($result)); } } } diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php index 49e90dcd85063bd7d74a2066a788f531f6f4b69f..7db4980deaa39cbf100b69068f0bb1d14fd4e55a 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php @@ -38,24 +38,34 @@ class Inventory extends \Magento\Backend\Block\Widget * * @var \Magento\Catalog\Helper\Data */ - protected $_catalogData; + protected $catalogData; /** * Core registry * * @var \Magento\Framework\Registry */ - protected $_coreRegistry; + protected $coreRegistry; /** * @var \Magento\CatalogInventory\Model\Source\Stock */ - protected $_stock; + protected $stock; /** * @var \Magento\CatalogInventory\Model\Source\Backorders */ - protected $_backorders; + protected $backorders; + + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + + /** + * @var \Magento\Catalog\Helper\Product\Inventory + */ + protected $inventoryHelper; /** * @param \Magento\Backend\Block\Template\Context $context @@ -63,6 +73,8 @@ class Inventory extends \Magento\Backend\Block\Widget * @param \Magento\CatalogInventory\Model\Source\Stock $stock * @param \Magento\Catalog\Helper\Data $catalogData * @param \Magento\Framework\Registry $coreRegistry + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + * @param \Magento\Catalog\Helper\Product\Inventory $inventoryHelper * @param array $data */ public function __construct( @@ -71,12 +83,16 @@ class Inventory extends \Magento\Backend\Block\Widget \Magento\CatalogInventory\Model\Source\Stock $stock, \Magento\Catalog\Helper\Data $catalogData, \Magento\Framework\Registry $coreRegistry, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, + \Magento\Catalog\Helper\Product\Inventory $inventoryHelper, array $data = array() ) { - $this->_stock = $stock; - $this->_backorders = $backorders; - $this->_catalogData = $catalogData; - $this->_coreRegistry = $coreRegistry; + $this->stock = $stock; + $this->backorders = $backorders; + $this->catalogData = $catalogData; + $this->coreRegistry = $coreRegistry; + $this->stockItemService = $stockItemService; + $this->inventoryHelper = $inventoryHelper; parent::__construct($context, $data); } @@ -85,8 +101,8 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getBackordersOption() { - if ($this->_catalogData->isModuleEnabled('Magento_CatalogInventory')) { - return $this->_backorders->toOptionArray(); + if ($this->catalogData->isModuleEnabled('Magento_CatalogInventory')) { + return $this->backorders->toOptionArray(); } return array(); @@ -99,8 +115,8 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getStockOption() { - if ($this->_catalogData->isModuleEnabled('Magento_CatalogInventory')) { - return $this->_stock->toOptionArray(); + if ($this->catalogData->isModuleEnabled('Magento_CatalogInventory')) { + return $this->stock->toOptionArray(); } return array(); @@ -113,17 +129,17 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getProduct() { - return $this->_coreRegistry->registry('product'); + return $this->coreRegistry->registry('product'); } /** * Retrieve Catalog Inventory Stock Item Model * - * @return \Magento\CatalogInventory\Model\Stock\Item + * @return \Magento\CatalogInventory\Service\V1\Data\StockItem */ - public function getStockItem() + public function getStockItemDo() { - return $this->getProduct()->getStockItem(); + return $this->stockItemService->getStockItem($this->getProduct()->getId()); } /** @@ -132,14 +148,7 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getFieldValue($field) { - if ($this->getStockItem()) { - return $this->getStockItem()->getDataUsingMethod($field); - } - - return $this->_scopeConfig->getValue( - \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_ITEM . $field, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); + return $this->inventoryHelper->getFieldValue($field, $this->getStockItemDo()); } /** @@ -148,16 +157,7 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getConfigFieldValue($field) { - if ($this->getStockItem()) { - if ($this->getStockItem()->getData('use_config_' . $field) == 0) { - return $this->getStockItem()->getData($field); - } - } - - return $this->_scopeConfig->getValue( - \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_ITEM . $field, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); + return $this->inventoryHelper->getConfigFieldValue($field, $this->getStockItemDo()); } /** @@ -166,10 +166,7 @@ class Inventory extends \Magento\Backend\Block\Widget */ public function getDefaultConfigValue($field) { - return $this->_scopeConfig->getValue( - \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_ITEM . $field, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); + return $this->inventoryHelper->getDefaultConfigValue($field); } /** diff --git a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php index 1ec50c290837206657d73db203409b4307ed0ba3..0e5cc16085e42c14069940c8b1978f56ac90e0f4 100644 --- a/app/code/Magento/Catalog/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Catalog/Block/Product/AbstractProduct.php @@ -137,7 +137,7 @@ abstract class AbstractProduct extends \Magento\Framework\View\Element\Template protected $reviewRenderer; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; diff --git a/app/code/Magento/Catalog/Block/Product/Context.php b/app/code/Magento/Catalog/Block/Product/Context.php index 8f23e8f9b5484c67c55dfc8fefaf599a11637da7..df1b21decebbd7e161612e317c68f75700cdb184 100644 --- a/app/code/Magento/Catalog/Block/Product/Context.php +++ b/app/code/Magento/Catalog/Block/Product/Context.php @@ -84,7 +84,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context protected $reviewRenderer; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; @@ -123,7 +123,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context * @param \Magento\Theme\Helper\Layout $layoutHelper * @param \Magento\Catalog\Helper\Image $imageHelper * @param ReviewRendererInterface $reviewRenderer - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -162,7 +162,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context \Magento\Theme\Helper\Layout $layoutHelper, \Magento\Catalog\Helper\Image $imageHelper, ReviewRendererInterface $reviewRenderer, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService ) { $this->imageHelper = $imageHelper; $this->layoutHelper = $layoutHelper; @@ -204,7 +204,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context } /** - * @return \Magento\CatalogInventory\Service\V1\StockItem + * @return \Magento\CatalogInventory\Service\V1\StockItemService */ public function getStockItemService() { diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php index 82c523c7e252d99fc02961ff01ca06d0b55d359f..e2b3ed2915361779d64871a4b1a6b66e0f535fae 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php @@ -174,8 +174,7 @@ class Category extends \Magento\Backend\App\Action 'category_prepare_ajax_response', array('response' => $eventResponse, 'controller' => $this) ); - $this->getResponse()->setHeader('Content-type', 'application/json', true); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($eventResponse->getData()) ); return; @@ -246,7 +245,7 @@ class Category extends \Magento\Backend\App\Action if (!($category = $this->_initCategory())) { return; } - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_view->getLayout()->createBlock( 'Magento\Catalog\Block\Adminhtml\Category\Tree' )->getTreeJson( @@ -512,7 +511,7 @@ class Category extends \Magento\Backend\App\Action $block = $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Category\Tree'); $root = $block->getRoot(); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get( 'Magento\Core\Helper\Data' )->jsonEncode( @@ -543,7 +542,7 @@ class Category extends \Magento\Backend\App\Action $categoryId = (int)$this->getRequest()->getParam('id'); if ($categoryId) { $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get( 'Magento\Core\Helper\Data' )->jsonEncode( @@ -560,7 +559,7 @@ class Category extends \Magento\Backend\App\Action */ public function suggestCategoriesAction() { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_view->getLayout()->createBlock( 'Magento\Catalog\Block\Adminhtml\Category\Tree' )->getSuggestedCategoriesJson( diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php index 584baa55b3b53695f8037eaa699764cd4c8e05c1..72b8c542ec160f769491a52587bf50df12b40af8 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php @@ -75,7 +75,7 @@ class Widget extends \Magento\Backend\App\Action $this->_coreRegistry->register('current_category', $category); } $categoryTreeBlock = $this->_getCategoryTreeBlock()->setSelectedCategories(explode(',', $selected)); - $this->getResponse()->setBody($categoryTreeBlock->getTreeJson($category)); + $this->getResponse()->representJson($categoryTreeBlock->getTreeJson($category)); } } diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php index 590abfe64646bba73df782d74dc6f529f3dced73..400d9c773e21710432a3f19e279578963a990aad 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php @@ -521,7 +521,7 @@ class Product extends \Magento\Backend\App\Action $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** @@ -786,7 +786,7 @@ class Product extends \Magento\Backend\App\Action public function suggestProductTemplatesAction() { $this->productBuilder->build($this->getRequest()); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode( $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Product\TemplateSelector') ->getSuggestedTemplates($this->getRequest()->getParam('label_part')) @@ -801,7 +801,7 @@ class Product extends \Magento\Backend\App\Action */ public function suggestAttributesAction() { - $this->getResponse()->setBody( + $this->getResponse()->srepresentJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode( $this->_view->getLayout()->createBlock( 'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes\Search' @@ -846,12 +846,12 @@ class Product extends \Magento\Backend\App\Action ->setSortOrder('0') ->save(); - $this->getResponse()->setBody($attribute->toJson()); + $this->getResponse()->representJson($attribute->toJson()); } catch (\Exception $e) { $response = new \Magento\Framework\Object(); $response->setError(false); $response->setMessage($e->getMessage()); - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } } } diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php index 102e33268f7e77c662c7c05d8624271483f54e49..3b5b5442ccb415fa0f27e033c11e4cc905559bc6 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php @@ -47,25 +47,33 @@ class Attribute extends Action */ protected $_catalogProduct; + /** + * @var \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder + */ + protected $stockItemBuilder; + /** * @param Action\Context $context * @param \Magento\Catalog\Helper\Product\Edit\Action\Attribute $helper * @param \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor * @param \Magento\Catalog\Helper\Product $catalogProduct + * @param \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder */ public function __construct( Action\Context $context, \Magento\Catalog\Helper\Product\Edit\Action\Attribute $helper, \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor, \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor, - \Magento\Catalog\Helper\Product $catalogProduct + \Magento\Catalog\Helper\Product $catalogProduct, + \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder ) { parent::__construct($context); $this->_helper = $helper; $this->_productFlatIndexerProcessor = $productFlatIndexerProcessor; $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor; $this->_catalogProduct = $catalogProduct; + $this->stockItemBuilder = $stockItemBuilder; } /** @@ -148,31 +156,18 @@ class Attribute extends Action ->updateAttributes($this->_helper->getProductIds(), $attributesData, $storeId); } if ($inventoryData) { - $stockItem = $this->_objectManager->create('Magento\CatalogInventory\Model\Stock\Item'); - $stockItem->setProcessIndexEvents(false); - $stockItemSaved = false; + /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */ + $stockItemService = $this->_objectManager + ->create('Magento\CatalogInventory\Service\V1\StockItemService'); foreach ($this->_helper->getProductIds() as $productId) { - $stockItem->setData(array()); - $stockItem->loadByProduct($productId)->setProductId($productId); - - $stockDataChanged = false; - foreach ($inventoryData as $k => $v) { - $stockItem->setDataUsingMethod($k, $v); - if ($stockItem->dataHasChangedFor($k)) { - $stockDataChanged = true; - } - } - if ($stockDataChanged) { - $stockItem->save(); - $stockItemSaved = true; + $stockItemDo = $stockItemService->getStockItem($productId); + if (!$stockItemDo->getProductId()) { + $inventoryData[] = $productId; } - } - if ($stockItemSaved) { - $this->_objectManager->get('Magento\Index\Model\Indexer')->indexEvents( - \Magento\CatalogInventory\Model\Stock\Item::ENTITY, - \Magento\Index\Model\Event::TYPE_SAVE + $stockItemService->saveStockItem( + $this->stockItemBuilder->mergeDataObjectWithArray($stockItemDo, $inventoryData) ); } } @@ -297,6 +292,6 @@ class Attribute extends Action $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } } diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php index fa5614a851b95d271c2e1410bc82f71b2fb3b29b..e4806b7a9fb43d80781ca4dff9a22ae117af1730 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php @@ -229,7 +229,7 @@ class Attribute extends \Magento\Backend\App\Action $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php index 466320d93611c9f77af7915f034be22f681e5cff..a8a3f1f448bf0409380876f1e8363ca97d37aee4 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php @@ -70,7 +70,9 @@ class Gallery extends \Magento\Backend\App\Action $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode()); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php index c7c3b595b8c0f7b6c619a6c5b3017de37ec09652..36ba0bd9f6a5d06897dcbc784ebcfe6028972605 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php @@ -182,7 +182,7 @@ class Set extends \Magento\Backend\App\Action )->jsonEncode( array('messages' => $block->getGroupedHtml(), 'error' => $hasError, 'id' => $model->getId()) ); - $this->getResponse()->setBody($body); + $this->getResponse()->representJson($body); } else { if ($hasError) { $this->_redirect('catalog/*/add'); @@ -200,7 +200,7 @@ class Set extends \Magento\Backend\App\Action $response['error'] = 0; $response['url'] = $this->getUrl('catalog/*/'); } - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) ); } diff --git a/app/code/Magento/Catalog/Helper/Product/Inventory.php b/app/code/Magento/Catalog/Helper/Product/Inventory.php new file mode 100644 index 0000000000000000000000000000000000000000..71b013914d42e2dce9537f299afb232e5f454d0c --- /dev/null +++ b/app/code/Magento/Catalog/Helper/Product/Inventory.php @@ -0,0 +1,114 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Catalog\Helper\Product; + +use \Magento\CatalogInventory\Service\V1\Data\StockItem; +use Magento\Framework\App\Helper\Context; +use \Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * Catalog Product Inventory Helper + */ +class Inventory extends \Magento\Framework\App\Helper\AbstractHelper +{ + /** + * @var ScopeConfigInterface + */ + protected $scopeConfig; + + /** + * @param Context $context + * @param ScopeConfigInterface $scopeConfig + */ + public function __construct( + Context $context, + ScopeConfigInterface $scopeConfig + ) { + $this->scopeConfig = $scopeConfig; + parent::__construct($context); + } + + /** + * @param string $field + * @param StockItem $dataObject + * @return mixed + */ + public function getFieldValue($field, StockItem $dataObject) + { + if ($dataObject->getStockId()) { + return $this->getDoFieldData($field, $dataObject); + } + + return $this->getDefaultConfigValue($field); + } + + /** + * @param string $field + * @param StockItem $dataObject + * @return mixed|null|string + */ + public function getConfigFieldValue($field, StockItem $dataObject) + { + if ($dataObject->getStockId()) { + if ($this->getDoFieldData('use_config_' . $field, $dataObject) == 0) { + return $this->getDoFieldData($field, $dataObject); + } + } + + return $this->getDefaultConfigValue($field); + } + + /** + * @param string $field + * @return string|null + */ + public function getDefaultConfigValue($field) + { + return $this->scopeConfig->getValue( + \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_ITEM . $field, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + } + + /** + * @param string $field + * @param StockItem $dataObject + * @return mixed + * @throws \BadMethodCallException + */ + public function getDoFieldData($field, StockItem $dataObject) + { + $possibleMethods = array( + 'get' . \Magento\Framework\Service\DataObjectConverter::snakeCaseToCamelCase($field), + 'is' . \Magento\Framework\Service\DataObjectConverter::snakeCaseToCamelCase($field) + ); + + foreach ($possibleMethods as $method) { + if (method_exists($dataObject, $method)) { + return $dataObject->{$method}(); + } + } + throw new \BadMethodCallException(__('Field "%1" was not found in DO "%2".', $field, get_class($dataObject))); + } +} diff --git a/app/code/Magento/Catalog/Model/Indexer/Url.php b/app/code/Magento/Catalog/Model/Indexer/Url.php index aa720e963b1fe8df07d07a06425751b6e0d1c0ce..0a1dd8dc3a23e5cb29a514ae87408072129f6687 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Url.php +++ b/app/code/Magento/Catalog/Model/Indexer/Url.php @@ -277,7 +277,7 @@ class Url extends \Magento\Index\Model\Indexer\AbstractIndexer $this->_catalogUrl->clearStoreInvalidRewrites(); // Maybe some categories were moved foreach ($data['rewrite_category_ids'] as $categoryId) { - $this->_catalogUrl->refreshCategoryRewrite($categoryId); + $this->_catalogUrl->refreshCategoryRewrite($categoryId, null, true, true); } } } diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index 99317d82065d730982a99e6175c5197bbc416856..23aed6b00544498e2287ec004a978e25c3751235 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -1440,9 +1440,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn */ public function getAttributeText($attributeCode) { - return $this->getResource()->getAttribute( - $attributeCode - )->getSource()->getOptionText( + return $this->getResource()->getAttribute($attributeCode)->getSource()->getOptionText( $this->getData($attributeCode) ); } diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php index f82734a2e955c6ae144ced2a45fb334fd175cab0..f83fd3ae758512cb8028d4ac206e109f34de4fad 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Stock.php @@ -32,23 +32,23 @@ use Magento\Catalog\Model\Product; class Stock extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend { /** - * Stock item factory + * Stock item service * - * @var \Magento\CatalogInventory\Model\Stock\ItemFactory + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ - protected $_stockItemFactory; + protected $stockItemService; /** * Construct * * @param \Magento\Framework\Logger $logger - * @param \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */ public function __construct( \Magento\Framework\Logger $logger, - \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService ) { - $this->_stockItemFactory = $stockItemFactory; + $this->stockItemService = $stockItemService; parent::__construct($logger); } @@ -60,11 +60,10 @@ class Stock extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend */ public function afterLoad($object) { - $item = $this->_stockItemFactory->create(); - $item->loadByProduct($object); + $stockItemDo = $this->stockItemService->getStockItem($object->getId()); $object->setData( $this->getAttribute()->getAttributeCode(), - array('is_in_stock' => $item->getIsInStock(), 'qty' => $item->getQty()) + array('is_in_stock' => $stockItemDo->getIsInStock(), 'qty' => $stockItemDo->getQty()) ); return parent::afterLoad($object); } diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php index d6e9f7754e16440e0266385ac572c28394d69718..dc3b95fb27cd725d2de8c77856d416f0a70cfb97 100644 --- a/app/code/Magento/Catalog/Model/Product/Option.php +++ b/app/code/Magento/Catalog/Model/Product/Option.php @@ -37,6 +37,8 @@ use Magento\Framework\Model\AbstractModel; * @method \Magento\Catalog\Model\Product\Option setProductId(int $value) * @method string getType() * @method \Magento\Catalog\Model\Product\Option setType(string $value) + * @method string getTitle() + * @method \Magento\Catalog\Model\Product\Option seTitle(string $value) * @method int getIsRequire() * @method \Magento\Catalog\Model\Product\Option setIsRequire(int $value) * @method string getSku() @@ -118,12 +120,18 @@ class Option extends AbstractModel */ protected $string; + /** + * @var Option\Validator\Pool + */ + protected $validatorPool; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param Option\Value $productOptionValue - * @param \Magento\Catalog\Model\Product\Option\Type\Factory $optionFactory + * @param Option\Type\Factory $optionFactory * @param \Magento\Framework\Stdlib\String $string + * @param Option\Validator\Pool $validatorPool * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -134,12 +142,14 @@ class Option extends AbstractModel Option\Value $productOptionValue, \Magento\Catalog\Model\Product\Option\Type\Factory $optionFactory, \Magento\Framework\Stdlib\String $string, + Option\Validator\Pool $validatorPool, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() ) { $this->_productOptionValue = $productOptionValue; $this->_optionFactory = $optionFactory; + $this->validatorPool = $validatorPool; $this->string = $string; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -328,6 +338,7 @@ class Option extends AbstractModel public function saveOptions() { foreach ($this->getOptions() as $option) { + $this->_validatorBeforeSave = null; $this->setData( $option )->setData( @@ -337,6 +348,8 @@ class Option extends AbstractModel 'store_id', $this->getProduct()->getStoreId() ); + /** Reset is delete flag from the previous iteration */ + $this->isDeleted(false); if ($this->getData('option_id') == '0') { $this->unsetData('option_id'); @@ -567,4 +580,12 @@ class Option extends AbstractModel } return $this; } + + /** + * {@inheritdoc} + */ + protected function _getValidationRulesBeforeSave() + { + return $this->validatorPool->get($this->getType()); + } } diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..6433e327fcb86af321f3be4baedd70ecc16b55ce --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php @@ -0,0 +1,163 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +use Zend_Validate_Exception; +use Magento\Catalog\Model\Product\Option; + +class DefaultValidator extends \Magento\Framework\Validator\AbstractValidator +{ + /** + * Product option types + * + * @var string[] + */ + protected $productOptionTypes; + + /** + * Price types + * + * @var string[] + */ + protected $priceTypes; + + /** + * @param \Magento\Catalog\Model\ProductOptions\ConfigInterface $productOptionConfig + * @param \Magento\Catalog\Model\Config\Source\Product\Options\Price $priceConfig + */ + public function __construct( + \Magento\Catalog\Model\ProductOptions\ConfigInterface $productOptionConfig, + \Magento\Catalog\Model\Config\Source\Product\Options\Price $priceConfig + ) { + foreach ($productOptionConfig->getAll() as $option) { + foreach ($option['types'] as $type) { + $this->productOptionTypes[] = $type['name']; + } + } + + foreach ($priceConfig->toOptionArray() as $item) { + $this->priceTypes[] = $item['value']; + } + } + + /** + * Returns true if and only if $value meets the validation requirements + * + * If $value fails validation, then this method returns false, and + * getMessages() will return an array of messages that explain why the + * validation failed. + * + * @param \Magento\Catalog\Model\Product\Option $value + * @return boolean + * @throws Zend_Validate_Exception If validation of $value is impossible + */ + public function isValid($value) + { + $messages = array(); + + if (!$this->validateOptionRequiredFields($value)) { + $messages['option required fields'] = 'Missed values for option required fields'; + } + + if (!$this->validateOptionType($value)) { + $messages['option type'] = 'Invalid option type'; + } + + if (!$this->validateOptionValue($value)) { + $messages['option values'] = 'Invalid option value'; + } + + $this->_addMessages($messages); + + return empty($messages); + } + + /** + * Validate option required fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionRequiredFields(Option $option) + { + return !$this->isEmpty($option->getTitle()) && !$this->isEmpty($option->getType()); + } + + /** + * Validate option type fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionType(Option $option) + { + return $this->isInRange($option->getType(), $this->productOptionTypes); + } + + /** + * Validate option type fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionValue(Option $option) + { + return $this->isInRange($option->getPriceType(), $this->priceTypes) && !$this->isNegative($option->getPrice()); + } + + /** + * Check whether value is empty + * + * @param mixed $value + * @return bool + */ + protected function isEmpty($value) + { + return empty($value); + } + + /** + * Check whether value is in range + * + * @param string $value + * @param array $range + * @return bool + */ + protected function isInRange($value, array $range) + { + return in_array($value, $range); + } + + /** + * Check whether value is not negative + * + * @param string $value + * @return bool + */ + protected function isNegative($value) + { + return intval($value) < 0; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/File.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/File.php new file mode 100644 index 0000000000000000000000000000000000000000..02cdbd28712614427516bc980e46ee554dbde8c6 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/File.php @@ -0,0 +1,42 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +use Magento\Catalog\Model\Product\Option; + +class File extends DefaultValidator +{ + /** + * Validate option type fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionValue(Option $option) + { + $result = parent::validateOptionValue($option); + return $result && !$this->isNegative($option->getImageSizeX())&& !$this->isNegative($option->getImageSizeY()); + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/Pool.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/Pool.php new file mode 100644 index 0000000000000000000000000000000000000000..6d36f834d63b7c78e82b92f7e2e48120c6f9ffa0 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/Pool.php @@ -0,0 +1,52 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class Pool +{ + /** + * @var \Zend_Validate_Interface + */ + protected $validators; + + /** + * @param \Zend_Validate_Interface[] $validators + */ + public function __construct(array $validators) + { + $this->validators = $validators; + } + + /** + * Get validator + * + * @param string $type + * @return \Zend_Validate_Interface + */ + public function get($type) + { + return isset($this->validators[$type]) ? $this->validators[$type] : $this->validators['default']; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php new file mode 100644 index 0000000000000000000000000000000000000000..37a8dfc9ad0b815a3f6be371ed8b71c1c508e0f3 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +use Magento\Catalog\Model\Product\Option; + +class Select extends DefaultValidator +{ + /** + * Check if all values are marked for removal + * + * @param array $values + * @return bool + */ + protected function checkAllValuesRemoved($values) + { + foreach ($values as $value) { + if (!array_key_exists('is_delete', $value) || $value['is_delete'] != 1) { + return false; + } + } + return true; + } + + /** + * Validate option type fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionValue(Option $option) + { + $values = $option->getData('values'); + if (!is_array($values) || $this->isEmpty($values)) { + return false; + } + + //forbid removal of last value for option + if ($this->checkAllValuesRemoved($values)) { + return false; + } + + foreach ($option->getData('values') as $value) { + $type = isset($value['price_type']) ? $value['price_type'] : ''; + $price = isset($value['price']) ? $value['price'] : 0; + $title = isset($value['title']) ? $value['title'] : ''; + if (!$this->isInRange($type, $this->priceTypes) || $this->isNegative($price) || $this->isEmpty($title)) { + return false; + } + } + return true; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/Text.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/Text.php new file mode 100644 index 0000000000000000000000000000000000000000..949de1775a09788b21c942cabbdd377e03943f48 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/Text.php @@ -0,0 +1,42 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +use Magento\Catalog\Model\Product\Option; + +class Text extends DefaultValidator +{ + /** + * Validate option type fields + * + * @param Option $option + * @return bool + */ + protected function validateOptionValue(Option $option) + { + $result = parent::validateOptionValue($option); + return $result && !$this->isNegative($option->getMaxCharacters()); + } +} diff --git a/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php b/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php index f333654da3c99fb85fe99b50c000a4b665ecfeea..70eb37b606d5a2ba9c3cd1c27ee9cb3ba57adab1 100644 --- a/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php +++ b/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php @@ -57,7 +57,7 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Zend_Db_Adapter_Abstract $connection - * + * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -179,7 +179,7 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo $attributeIds )->where( 't_d.store_id = ?', - 0 + $adapter->getIfNullSql('t_s.store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID) ); } else { $select = parent::_getLoadAttributesSelect($table)->where('store_id = ?', $this->getDefaultStoreId()); diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php index fea812a89549cd69ef023cbdfa8699b29547afa9..e2af327803e4ea452aa3f9001b5147be26165216 100644 --- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php @@ -138,19 +138,25 @@ class Source extends AbstractEav array('store_id', 'website_id') )->joinLeft( array('d' => $this->getTable('catalog_product_entity_int')), - '1 = 1 AND d.store_id = 0', + '1 = 1 AND (d.store_id = 0 OR d.store_id = s.store_id)', array('entity_id', 'attribute_id', 'value') - )->joinInner( + )->joinLeft( array('d2' => $this->getTable('catalog_product_entity_int')), sprintf( - 'd.entity_id = d2.entity_id AND d2.attribute_id = %s AND d2.value = %s AND d.store_id = 0', + 'd.entity_id = d2.entity_id AND d2.attribute_id = %s AND d2.value = %s AND d.store_id = d2.store_id', $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'status')->getId(), ProductStatus::STATUS_ENABLED ), array() )->where( 's.store_id != 0' - ); + )->where( + 'd.value IS NOT NULL' + )->where( + 'd2.value IS NOT NULL' + )->group(array( + 's.store_id', 's.website_id', 'd.entity_id', 'd.attribute_id', 'd.value' + )); if (!is_null($entityIds)) { $subSelect->where('d.entity_id IN(?)', $entityIds); @@ -248,7 +254,7 @@ class Source extends AbstractEav array('value' => $productValueExpression) )->where( 'pvd.store_id=?', - \Magento\Store\Model\Store::DEFAULT_STORE_ID + $adapter->getIfNullSql('pvs.store_id', \Magento\Store\Model\Store::DEFAULT_STORE_ID) )->where( 'cs.store_id!=?', \Magento\Store\Model\Store::DEFAULT_STORE_ID diff --git a/app/code/Magento/Catalog/Model/Url.php b/app/code/Magento/Catalog/Model/Url.php index 2e45f495e765e2d38be558499f7052462bd6f63b..fbd489bce824576548f183f04e1c1876aa4acb7e 100644 --- a/app/code/Magento/Catalog/Model/Url.php +++ b/app/code/Magento/Catalog/Model/Url.php @@ -302,7 +302,7 @@ class Url } $this->clearStoreInvalidRewrites($storeId); - $this->refreshCategoryRewrite($this->getStores($storeId)->getRootCategoryId(), $storeId, false); + $this->refreshCategoryRewrite($this->getStores($storeId)->getRootCategoryId(), $storeId, false, false); $this->refreshProductRewrites($storeId); $this->getResource()->clearCategoryProduct($storeId); @@ -315,10 +315,15 @@ class Url * @param \Magento\Framework\Object $category * @param string $parentPath * @param bool $refreshProducts + * @param bool $changeRequestPath * @return $this */ - protected function _refreshCategoryRewrites(\Magento\Framework\Object $category, $parentPath = null, $refreshProducts = true) - { + protected function _refreshCategoryRewrites( + \Magento\Framework\Object $category, + $parentPath = null, + $refreshProducts = true, + $changeRequestPath = false + ) { if ($category->getId() != $this->getStores($category->getStoreId())->getRootCategoryId()) { if ($category->getUrlKey() == '') { $urlKey = $this->getCategoryModel()->formatUrlKey($category->getName()); @@ -328,7 +333,7 @@ class Url $idPath = $this->generatePath('id', null, $category); $targetPath = $this->generatePath('target', null, $category); - $requestPath = $this->getCategoryRequestPath($category, $parentPath); + $requestPath = $this->getCategoryRequestPath($category, $parentPath, $changeRequestPath); $rewriteData = array( 'store_id' => $category->getStoreId(), @@ -366,7 +371,12 @@ class Url } foreach ($category->getChilds() as $child) { - $this->_refreshCategoryRewrites($child, $category->getUrlPath() . '/', $refreshProducts); + $this->_refreshCategoryRewrites( + $child, + $category->getUrlPath() . '/', + $refreshProducts, + $changeRequestPath + ); } return $this; @@ -483,13 +493,18 @@ class Url * @param int $categoryId * @param int|null $storeId * @param bool $refreshProducts + * @param bool $changeRequestPath * @return $this */ - public function refreshCategoryRewrite($categoryId, $storeId = null, $refreshProducts = true) - { + public function refreshCategoryRewrite( + $categoryId, + $storeId = null, + $refreshProducts = true, + $changeRequestPath = false + ) { if (is_null($storeId)) { foreach ($this->getStores() as $store) { - $this->refreshCategoryRewrite($categoryId, $store->getId(), $refreshProducts); + $this->refreshCategoryRewrite($categoryId, $store->getId(), $refreshProducts, $changeRequestPath); } return $this; } @@ -506,7 +521,7 @@ class Url $categoryIds = array_merge($categoryIds, array_keys($category->getAllChilds())); } $this->_rewrites = $this->getResource()->prepareRewrites($storeId, $categoryIds); - $this->_refreshCategoryRewrites($category, null, $refreshProducts); + $this->_refreshCategoryRewrites($category, null, $refreshProducts, $changeRequestPath); unset($category); $this->_rewrites = array(); @@ -743,14 +758,15 @@ class Url * * @param \Magento\Framework\Object $category * @param string $parentPath + * @param bool $changeRequestPath * @return string */ - public function getCategoryRequestPath($category, $parentPath) + public function getCategoryRequestPath($category, $parentPath, $changeRequestPath = false) { $storeId = $category->getStoreId(); $idPath = $this->generatePath('id', null, $category); $categoryUrlSuffix = $this->getCategoryUrlSuffix($storeId); - + $pathSuffix = '(\-[0-9]+)?'; if (isset($this->_rewrites[$idPath])) { $this->_rewrite = $this->_rewrites[$idPath]; $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath(); @@ -770,7 +786,10 @@ class Url $parentPath = $this->_catalogCategory->getCategoryUrlPath($parentPath, true, $storeId); $requestPath = $parentPath . $urlKey; - $regexp = '/^' . preg_quote($requestPath, '/') . '(\-[0-9]+)?' . preg_quote($categoryUrlSuffix, '/') . '$/i'; + if ($changeRequestPath) { + $pathSuffix = ''; + } + $regexp = '/^' . preg_quote($requestPath, '/') . $pathSuffix . preg_quote($categoryUrlSuffix, '/') . '$/i'; if (isset($existingRequestPath) && preg_match($regexp, $existingRequestPath)) { return $existingRequestPath; } diff --git a/app/code/Magento/Catalog/Service/V1/Data/Converter.php b/app/code/Magento/Catalog/Service/V1/Data/Converter.php index 57dc8d19b55530b7828285f8fc192766503ee9c9..e7c82fd5a0865aee4ba4d533a711c36419718627 100644 --- a/app/code/Magento/Catalog/Service/V1/Data/Converter.php +++ b/app/code/Magento/Catalog/Service/V1/Data/Converter.php @@ -23,7 +23,6 @@ */ namespace Magento\Catalog\Service\V1\Data; -use Magento\Catalog\Service\V1\Data\ProductBuilder; use Magento\Catalog\Service\V1\Data\Product as ProductDataObject; /** diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option.php new file mode 100644 index 0000000000000000000000000000000000000000..bac5ba32df272979ca33c27d35e3a19c4ab679df --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option.php @@ -0,0 +1,96 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data; + +class Option extends \Magento\Framework\Service\Data\AbstractObject +{ + const OPTION_ID = 'option_id'; + const TITLE = 'title'; + const TYPE = 'type'; + const SORT_ORDER = 'sort_order'; + const IS_REQUIRE = 'is_require'; + const METADATA = 'metadata'; + + /** + * Get option id + * + * @return int|null + */ + public function getOptionId() + { + return $this->_get(self::OPTION_ID); + } + + /** + * Get option title + * + * @return string + */ + public function getTitle() + { + return $this->_get(self::TITLE); + } + + /** + * Get option type + * + * @return string + */ + public function getType() + { + return $this->_get(self::TYPE); + } + + /** + * Get sort order + * + * @return int + */ + public function getSortOrder() + { + return $this->_get(self::SORT_ORDER); + } + + /** + * Get is require + * + * @return bool + * @SuppressWarnings(PHPMD.BooleanGetMethodName) + */ + public function getIsRequire() + { + return $this->_get(self::IS_REQUIRE); + } + + /** + * Get option metadata + * + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata[] + */ + public function getMetadata() + { + return $this->_get(self::METADATA); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Converter.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Converter.php new file mode 100644 index 0000000000000000000000000000000000000000..5ee17d07c225c13548c43488420cf54cf68463ec --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Converter.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface as MetadataConverter; + +class Converter +{ + /** + * @var MetadataConverter + */ + protected $metadataConverter; + + /** + * @param MetadataConverter $valueConverter + */ + public function __construct(MetadataConverter $valueConverter) + { + $this->metadataConverter = $valueConverter; + } + + /** + * Convert data object to array + * + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + * @return array + */ + public function convert(\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option) + { + $output = [ + 'option_id' => $option->getOptionId(), + 'title' => $option->getTitle(), + 'type' => $option->getType(), + 'sort_order' => $option->getSortOrder(), + 'is_require' => $option->getIsRequire() + ]; + $output = array_merge($output, $this->metadataConverter->convert($option)); + return $output; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata.php new file mode 100644 index 0000000000000000000000000000000000000000..9c9a653ea7846072c9b2148c5e38dfadadc0c464 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata.php @@ -0,0 +1,69 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option; + +class Metadata extends \Magento\Framework\Service\Data\Eav\AbstractObject +{ + const PRICE = 'price'; + const PRICE_TYPE = 'price_type'; + const SKU = 'sku'; + const SORT_ORDER = 'sort_order'; + const FILE_EXTENSION = 'file_extension'; + const IMAGE_SIZE_X = 'image_size_x'; + const IMAGE_SIZE_Y = 'image_size_y'; + const MAX_CHARACTERS = 'max_characters'; + const TITLE = 'title'; + const OPTION_TYPE_ID = 'option_type_id'; + + /** + * Get price + * + * @return float + */ + public function getPrice() + { + return $this->_get(self::PRICE); + } + + /** + * Get price type + * + * @return string + */ + public function getPriceType() + { + return $this->_get(self::PRICE_TYPE); + } + + /** + * Get Sku + * + * @return string + */ + public function getSku() + { + return $this->_get(self::SKU); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Composite.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Composite.php new file mode 100644 index 0000000000000000000000000000000000000000..229898e5ead75c0c7b38f3801a808c6352fd6102 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Composite.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface; + +class Composite implements ConverterInterface +{ + /** + * @var ConverterInterface[] + */ + protected $converters; + + /** + * @param ConverterInterface[] $converters + */ + public function __construct(array $converters) + { + $this->converters = $converters; + } + + /** + * {@inheritdoc} + */ + public function convert(\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option) + { + $type = $option->getType(); + $converter = isset($this->converters[$type]) ? $this->converters[$type] : $this->converters['default']; + return $converter->convert($option); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverter.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverter.php new file mode 100644 index 0000000000000000000000000000000000000000..1341080351f54737ae851a2d5b798adba218369c --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverter.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface; + +class DefaultConverter implements ConverterInterface +{ + /** + * Convert option data object value to array representation + * + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + * @return array + */ + public function convert(\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option) + { + /** @var Metadata $value */ + $value = current($option->getMetadata()); + $output = [ + Metadata::PRICE => $value->getPrice(), + Metadata::PRICE_TYPE => $value->getPriceType(), + Metadata::SKU => $value->getSku(), + ]; + + foreach ($value->getCustomAttributes() as $attribute) { + $output[$attribute->getAttributeCode()] = $attribute->getValue(); + } + return $output; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Select.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Select.php new file mode 100644 index 0000000000000000000000000000000000000000..b0e7cb2f23e1f99e1d167d8f4cdd3b2eb9e83123 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/Select.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option; +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface; + +class Select implements ConverterInterface +{ + /** + * {@inheritdoc} + */ + public function convert(Option $option) + { + $output = []; + foreach ($option->getMetadata() as $value) { + $attributes = $value->getCustomAttributes(); + $valueItem = [ + Metadata::PRICE => $value->getPrice(), + Metadata::PRICE_TYPE => $value->getPriceType(), + Metadata::SKU => $value->getSku() + ]; + foreach ($attributes as $attribute) { + $valueItem[$attribute->getAttributeCode()] = $attribute->getValue(); + } + $output[] = $valueItem; + } + return ['values' => $output]; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ConverterInterface.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ConverterInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..b1e92b754a273f09e4a5b58d19bfffde72d3ef8d --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ConverterInterface.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +interface ConverterInterface +{ + /** + * Convert option data object value to array representation + * + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + * @return array + */ + public function convert(\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option); +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader.php new file mode 100644 index 0000000000000000000000000000000000000000..b479efe75c1b0fa7844a3edf371c9b62ea9c5992 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader.php @@ -0,0 +1,56 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class Reader implements ReaderInterface +{ + /** + * @var ReaderInterface[] + */ + protected $valueReaders; + + /** + * @param ReaderInterface[] $valueReaders + */ + public function __construct($valueReaders) + { + $this->valueReaders = $valueReaders; + } + + /** + * Load option value + * + * @param \Magento\Catalog\Model\Product\Option $option + * @return Metadata[] + */ + public function read(\Magento\Catalog\Model\Product\Option $option) + { + $type = $option->getType(); + $reader = isset($this->valueReaders[$type]) ? $this->valueReaders[$type] : $this->valueReaders['default']; + return $reader->read($option); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReader.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReader.php new file mode 100644 index 0000000000000000000000000000000000000000..8c4ffa0fdc6ec6ac185056e0cabf649baa6e428f --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReader.php @@ -0,0 +1,72 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\MetadataBuilder; +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface; + +class DefaultReader implements ReaderInterface +{ + /** + * @var MetadataBuilder + */ + protected $valueBuilder; + + /** + * @param MetadataBuilder $valueBuilder + */ + public function __construct(MetadataBuilder $valueBuilder) + { + $this->valueBuilder = $valueBuilder; + } + + /** + * {@inheritdoc} + */ + public function read(\Magento\Catalog\Model\Product\Option $option) + { + $fields = [ + Metadata::PRICE => $option->getPrice(), + Metadata::PRICE_TYPE => $option->getPriceType(), + Metadata::SKU => $option->getSku() + ]; + $fields = array_merge($fields, $this->getCustomAttributes($option)); + $value = $this->valueBuilder->populateWithArray($fields)->create(); + return [$value]; + } + + /** + * Get custom attributes + * + * @param \Magento\Catalog\Model\Product\Option $option + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function getCustomAttributes(\Magento\Catalog\Model\Product\Option $option) + { + return []; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/File.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/File.php new file mode 100644 index 0000000000000000000000000000000000000000..e7f36b3b92f6733e64c2f4b6c298bfaaef738e60 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/File.php @@ -0,0 +1,42 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class File extends DefaultReader +{ + /** + * {@inheritdoc} + */ + protected function getCustomAttributes(\Magento\Catalog\Model\Product\Option $option) + { + return [ + Metadata::FILE_EXTENSION => $option->getFileExtension(), + Metadata::IMAGE_SIZE_X => $option->getImageSizeX(), + Metadata::IMAGE_SIZE_Y => $option->getImageSizeY(), + ]; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Select.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Select.php new file mode 100644 index 0000000000000000000000000000000000000000..093b683723448df3ac1e648a99f1f5ae1b12707e --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Select.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\MetadataBuilder; +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface; + +class Select implements ReaderInterface +{ + /** + * @var MetadataBuilder + */ + protected $metadataBuilder; + + /** + * @param MetadataBuilder $metadataBuilder + */ + public function __construct(MetadataBuilder $metadataBuilder) + { + $this->metadataBuilder = $metadataBuilder; + } + + /** + * {@inheritdoc} + */ + public function read(\Magento\Catalog\Model\Product\Option $option) + { + $output = []; + foreach ($option->getValues() as $value) { + $output[] = $this->metadataBuilder->populateWithArray( + [ + Metadata::PRICE => $value->getPrice(), + Metadata::PRICE_TYPE => $value->getPriceType(), + Metadata::SKU => $value->getSku(), + Metadata::TITLE => $value->getTitle(), + Metadata::SORT_ORDER => $value->getSortOrder(), + Metadata::OPTION_TYPE_ID => $value->getId() + ] + )->create(); + } + return $output; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Text.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Text.php new file mode 100644 index 0000000000000000000000000000000000000000..00264921875a08d9b6709997e2318e9cdd137032 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/Text.php @@ -0,0 +1,38 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class Text extends DefaultReader +{ + /** + * {@inheritdoc} + */ + protected function getCustomAttributes(\Magento\Catalog\Model\Product\Option $option) + { + return [Metadata::MAX_CHARACTERS => $option->getMaxCharacters()]; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderInterface.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..c384bc1a619e45ea031b568a860a0212d1ab9f01 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderInterface.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +interface ReaderInterface +{ + /** + * Read product option custom attributes value + * + * @param \Magento\Catalog\Model\Product\Option $option + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata[] + */ + public function read(\Magento\Catalog\Model\Product\Option $option); +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/MetadataBuilder.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/MetadataBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..620857ccc3967670f56b129faaae0b46125a1734 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/MetadataBuilder.php @@ -0,0 +1,98 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option; + +use Magento\Framework\Service\Data\Eav\AttributeValueBuilder; + +class MetadataBuilder extends \Magento\Framework\Service\Data\Eav\AbstractObjectBuilder +{ + /** + * @var string[] + */ + protected $customAttributeCodes = [ + Metadata::SORT_ORDER, + Metadata::TITLE, + Metadata::FILE_EXTENSION, + Metadata::IMAGE_SIZE_X, + Metadata::IMAGE_SIZE_Y, + Metadata::MAX_CHARACTERS, + Metadata::OPTION_TYPE_ID + ]; + + /** + * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory + * @param AttributeValueBuilder $valueBuilder + * @param array $customAttributeCodes + */ + public function __construct( + \Magento\Framework\Service\Data\ObjectFactory $objectFactory, + AttributeValueBuilder $valueBuilder, + array $customAttributeCodes = array() + ) { + parent::__construct($objectFactory, $valueBuilder); + $this->customAttributeCodes = array_merge($this->customAttributeCodes, $customAttributeCodes); + } + + /** + * Set price + * + * @param float $value + * @return $this + */ + public function setPrice($value) + { + return $this->_set(Metadata::PRICE, $value); + } + + /** + * Set price type + * + * @param string $value + * @return $this + */ + public function setPriceType($value) + { + return $this->_set(Metadata::PRICE_TYPE, $value); + } + + /** + * Set Sku + * + * @param string $value + * @return $this + */ + public function setSku($value) + { + return $this->_set(Metadata::SKU, $value); + } + + /** + * {@inheritdoc} + */ + public function getCustomAttributesCodes() + { + return array_merge($this->customAttributeCodes, parent::getCustomAttributesCodes()); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionBuilder.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..c56dddae5720a9d5ca5fd2250ee3d4ef8f1ddc19 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionBuilder.php @@ -0,0 +1,94 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data; + +class OptionBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder +{ + /** + * Set option id + * + * @param int|null $value + * @return $this + */ + public function setOptionId($value) + { + return $this->_set(Option::OPTION_ID, $value); + } + + /** + * Set option title + * + * @param string $value + * @return $this + */ + public function setTitle($value) + { + return $this->_set(Option::TITLE, $value); + } + + /** + * Set option type + * + * @param string $value + * @return $this + */ + public function setType($value) + { + return $this->_set(Option::TYPE, $value); + } + + /** + * Set sort order + * + * @param int $value + * @return $this + */ + public function setSortOrder($value) + { + return $this->_set(Option::SORT_ORDER, $value); + } + + /** + * Set is require + * + * @param bool $value + * @return $this + */ + public function setIsRequire($value) + { + return $this->_set(Option::IS_REQUIRE, $value); + } + + /** + * Set option metadata + * + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata[] $value + * @return $this + */ + public function setMetadata($value) + { + return $this->_set(Option::METADATA, $value); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionType.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionType.php new file mode 100644 index 0000000000000000000000000000000000000000..e55da5970ac3811d8554fbbfbf5b0b92b3c8c64f --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionType.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data; + +class OptionType extends \Magento\Framework\Service\Data\AbstractObject +{ + const LABEL = 'label'; + const CODE = 'code'; + const GROUP = 'group'; + + /** + * Get option type label + * + * @return string + */ + public function getLabel() + { + return $this->_get(self::LABEL); + } + + /** + * Get option type code + * + * @return string + */ + public function getCode() + { + return $this->_get(self::CODE); + } + + /** + * Get option type group + * + * @return string + */ + public function getGroup() + { + return $this->_get(self::GROUP); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionTypeBuilder.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionTypeBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..ea08d6857c9d8e10da2b8c155024e48411aac4ea --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/Data/OptionTypeBuilder.php @@ -0,0 +1,61 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data; + +class OptionTypeBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder +{ + /** + * Set option type label + * + * @param string $value + * @return $this + */ + public function setLabel($value) + { + return $this->_set(OptionType::LABEL, $value); + } + + /** + * Set option type code + * + * @param string $value + * @return $this + */ + public function setCode($value) + { + return $this->_set(OptionType::CODE, $value); + } + + /** + * Set option type group + * + * @param string $value + * @return $this + */ + public function setGroup($value) + { + return $this->_set(OptionType::GROUP, $value); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadService.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadService.php new file mode 100644 index 0000000000000000000000000000000000000000..1c1ac4bbc2b1e85fd80872ca6b7d772f5060e1eb --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadService.php @@ -0,0 +1,146 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +use Magento\Framework\Exception\NoSuchEntityException; + +class ReadService implements \Magento\Catalog\Service\V1\Product\CustomOptions\ReadServiceInterface +{ + /** + * Product Option Config + * + * @var \Magento\Catalog\Model\ProductOptions\ConfigInterface + */ + protected $productOptionConfig; + + /** + * @var Data\OptionTypeBuilder + */ + protected $optionTypeBuilder; + + /** + * @var Data\OptionBuilder + */ + protected $optionBuilder; + + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + protected $productRepository; + + /** + * @var Data\Option\Metadata\ReaderInterface + */ + protected $optionMetadataReader; + + /** + * @param \Magento\Catalog\Model\ProductOptions\ConfigInterface $productOptionConfig + * @param Data\OptionTypeBuilder $optionTypeBuilder + * @param Data\OptionBuilder $optionBuilder + * @param \Magento\Catalog\Model\ProductRepository $productRepository + * @param Data\Option\Metadata\ReaderInterface $optionMetadataReader + */ + public function __construct( + \Magento\Catalog\Model\ProductOptions\ConfigInterface $productOptionConfig, + Data\OptionTypeBuilder $optionTypeBuilder, + Data\OptionBuilder $optionBuilder, + \Magento\Catalog\Model\ProductRepository $productRepository, + Data\Option\Metadata\ReaderInterface $optionMetadataReader + ) { + $this->productOptionConfig = $productOptionConfig; + $this->optionTypeBuilder = $optionTypeBuilder; + $this->optionBuilder = $optionBuilder; + $this->productRepository = $productRepository; + $this->optionMetadataReader = $optionMetadataReader; + } + + /** + * {@inheritdoc} + */ + public function getTypes() + { + $output = []; + foreach ($this->productOptionConfig->getAll() as $option) { + foreach ($option['types'] as $type) { + if ($type['disabled']) { + continue; + } + $itemData = [ + Data\OptionType::LABEL => __($type['label']), + Data\OptionType::CODE => $type['name'], + Data\OptionType::GROUP => __($option['label']) + ]; + $output[] = $this->optionTypeBuilder->populateWithArray($itemData)->create(); + } + } + return $output; + } + + /** + * {@inheritdoc} + */ + public function getList($productSku) + { + $product = $this->productRepository->get($productSku); + $output = []; + /** @var $option \Magento\Catalog\Model\Product\Option */ + foreach ($product->getOptions() as $option) { + $output[] = $this->_createOptionDataObject($option); + } + return $output; + } + + /** + * {@inheritdoc} + */ + public function get($productSku, $optionId) + { + $product = $this->productRepository->get($productSku); + $option = $product->getOptionById($optionId); + if ($option === null) { + throw new NoSuchEntityException(); + } + return $this->_createOptionDataObject($option); + } + + /** + * Create option data object + * + * @param \Magento\Catalog\Model\Product\Option $option + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option array + */ + protected function _createOptionDataObject(\Magento\Catalog\Model\Product\Option $option) + { + $data = array( + Data\Option::OPTION_ID => $option->getId(), + Data\Option::TITLE => $option->getTitle(), + Data\Option::TYPE => $option->getType(), + Data\Option::IS_REQUIRE => $option->getIsRequire(), + Data\Option::SORT_ORDER => $option->getSortOrder(), + Data\Option::METADATA => $this->optionMetadataReader->read($option) + ); + return $this->optionBuilder->populateWithArray($data)->create(); + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..f5381e836aefe03e674a223311775e3b383789ee --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceInterface.php @@ -0,0 +1,54 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +interface ReadServiceInterface +{ + /** + * Get custom option types + * + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionType[] + */ + public function getTypes(); + + /** + * Get the list of custom options for a specific product + * + * @param string $productSku + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option[] + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function getList($productSku); + + /** + * Get custom option for a specific product + * + * @param string $productSku + * @param string $optionId + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function get($productSku, $optionId); +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteService.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteService.php new file mode 100644 index 0000000000000000000000000000000000000000..55d299596182ae08dd5709494975cea0e31a838f --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteService.php @@ -0,0 +1,211 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionBuilder; +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class WriteService implements WriteServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + protected $productRepository; + + /** + * @var Data\Option\Converter + */ + protected $optionConverter; + + /** + * @var Data\Option\Metadata\ReaderInterface + */ + protected $optionMetadataReader; + + /** + * @var OptionBuilder + */ + protected $optionBuilder; + + /** + * @var \Magento\Catalog\Model\Product\OptionFactory + */ + protected $optionFactory; + + /** + * @param OptionBuilder $optionBuilder + * @param Data\Option\Converter $optionConverter + * @param \Magento\Catalog\Model\ProductRepository $productRepository + * @param Data\Option\Metadata\ReaderInterface $optionMetadataReader + * @param \Magento\Catalog\Model\Product\OptionFactory $optionFactory + */ + public function __construct( + OptionBuilder $optionBuilder, + Data\Option\Converter $optionConverter, + \Magento\Catalog\Model\ProductRepository $productRepository, + Data\Option\Metadata\ReaderInterface $optionMetadataReader, + \Magento\Catalog\Model\Product\OptionFactory $optionFactory + ) { + $this->optionBuilder = $optionBuilder; + $this->optionConverter = $optionConverter; + $this->productRepository = $productRepository; + $this->optionMetadataReader = $optionMetadataReader; + $this->optionFactory = $optionFactory; + } + + /** + * {@inheritdoc} + */ + public function add($productSku, \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option) + { + $product = $this->productRepository->get($productSku); + $optionData = $this->optionConverter->convert($option); + + $product->setCanSaveCustomOptions(true); + $product->setProductOptions([$optionData]); + + $existingOptions = $product->getOptions(); + + try { + $product->save(); + } catch (\Exception $e) { + throw new CouldNotSaveException('Could not save product option'); + } + + $productId = $product->getId(); + $product->reset(); + $product->load($productId); + $currentOptions = $product->getOptions(); + + $newID = array_diff(array_keys($currentOptions), array_keys($existingOptions)); + if (empty($newID)) { + throw new CouldNotSaveException('Could not save product option'); + } + $newID = current($newID); + /** @var \Magento\Catalog\Model\Product\Option $newOption */ + $newOption = $currentOptions[$newID]; + $data= array( + Data\Option::OPTION_ID => $newOption->getId(), + Data\Option::TITLE => $newOption->getTitle(), + Data\Option::TYPE => $newOption->getType(), + Data\Option::IS_REQUIRE => $newOption->getIsRequire(), + Data\Option::SORT_ORDER => $newOption->getSortOrder(), + Data\Option::METADATA => $this->optionMetadataReader->read($newOption) + ); + $optionDataObject = $this->optionBuilder->populateWithArray($data)->create(); + return $optionDataObject; + } + + /** + * {@inheritdoc} + */ + public function remove($productSku, $optionId) + { + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($productSku); + $options = $product->getOptions(); + $option = $this->optionFactory->create(); + $option->load($optionId); + if (!$option->getId() || !isset($options[$option->getId()])) { + throw NoSuchEntityException::singleField('optionId', $optionId); + } + + unset($options[$optionId]); + try { + $option->delete(); + if (empty($options)) { + $product->setHasOptions(false); + $product->save(); + } + } catch (\Exception $e) { + throw new CouldNotSaveException('Could not remove custom option'); + } + return true; + } + + /** + * Mark original values for removal if they are absent among new values + * + * @param $newValues array + * @param $originalValues \Magento\Catalog\Model\Product\Option\Value[] + * @return array + */ + protected function markRemovedValues($newValues, $originalValues) + { + $idsToLeave = []; + + foreach ($newValues as $newValue) { + if (array_key_exists(Metadata::OPTION_TYPE_ID, $newValue)) { + $idsToLeave[] = $newValue[Metadata::OPTION_TYPE_ID]; + } + } + + /** @var $originalValue \Magento\Catalog\Model\Product\Option\Value */ + foreach ($originalValues as $originalValue) { + if (!in_array($originalValue->getData(Metadata::OPTION_TYPE_ID), $idsToLeave)) { + $originalValue->setData('is_delete', 1); + $newValues[] = $originalValue->getData(); + } + } + + return $newValues; + } + + /** + * {@inheritdoc} + */ + public function update( + $productSku, + $optionId, + \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + ) { + $product = $this->productRepository->get($productSku); + $optionData = $this->optionConverter->convert($option); + if (!$product->getOptionById($optionId)) { + throw new NoSuchEntityException(); + } + $optionData['option_id'] = $optionId; + $originalValues = $product->getOptionById($optionId)->getValues(); + if (array_key_exists('values', $optionData)) { + $optionData['values'] = $this->markRemovedValues($optionData['values'], $originalValues); + } + + $product->setCanSaveCustomOptions(true); + $product->setProductOptions([$optionData]); + + try { + $product->save(); + } catch (\Exception $e) { + throw new CouldNotSaveException('Could not save custom option'); + } + + return true; + } +} diff --git a/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..72ab9d5ee2429e9a36338786f033c0989b8b6ef1 --- /dev/null +++ b/app/code/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceInterface.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +interface WriteServiceInterface +{ + /** + * Remove custom option from product + * + * @param string $productSku + * @param int $optionId + * @throws \Magento\Framework\Exception\NoSuchEntityException|\Magento\Framework\Exception\CouldNotSaveException + * @return bool + */ + public function remove($productSku, $optionId); + + /** + * Add custom option to the product + * + * @param string $productSku + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + * @return \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option + */ + public function add($productSku, \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option); + + /** + * Add custom option to the product + * + * @param string $productSku + * @param string $optionId + * @param \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + * @return bool + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function update( + $productSku, + $optionId, + \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option $option + ); +} diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index a7f281199ba85d18f5cacb13fd9a35a12db92f03..6d0094742eefd8b3be804834148edddf64d1ee47 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -51,6 +51,10 @@ <preference for="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface" type="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapper\Composite" /> <preference for="Magento\Catalog\Service\V1\Product\GroupPriceServiceInterface" type="Magento\Catalog\Service\V1\Product\GroupPriceService" /> <preference for="Magento\Catalog\Service\V1\Product\TierPriceServiceInterface" type="Magento\Catalog\Service\V1\Product\TierPriceService" /> + <preference for="Magento\Catalog\Service\V1\Product\CustomOptions\ReadServiceInterface" type="Magento\Catalog\Service\V1\Product\CustomOptions\ReadService" /> + <preference for="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface" type="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader" /> + <preference for="Magento\Catalog\Service\V1\Product\CustomOptions\WriteServiceInterface" type="Magento\Catalog\Service\V1\Product\CustomOptions\WriteService" /> + <preference for="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface" type="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Composite" /> <type name="Magento\Log\Model\Resource\Log"> <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" /> </type> @@ -401,4 +405,43 @@ </argument> </arguments> </type> + <type name="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader"> + <arguments> + <argument name="valueReaders" xsi:type="array"> + <item name="default" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\DefaultReader</item> + <item name="field" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Text</item> + <item name="area" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Text</item> + <item name="file" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\File</item> + <item name="drop_down" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Select</item> + <item name="radio" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Select</item> + <item name="checkbox" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Select</item> + <item name="multiple" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader\Select</item> + </argument> + </arguments> + </type> + <type name="Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Composite"> + <arguments> + <argument name="converters" xsi:type="array"> + <item name="default" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\DefaultConverter</item> + <item name="drop_down" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Select</item> + <item name="radio" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Select</item> + <item name="checkbox" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Select</item> + <item name="multiple" xsi:type="object">Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Select</item> + </argument> + </arguments> + </type> + <type name="Magento\Catalog\Model\Product\Option\Validator\Pool"> + <arguments> + <argument name="validators" xsi:type="array"> + <item name="default" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\DefaultValidator</item> + <item name="drop_down" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Select</item> + <item name="radio" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Select</item> + <item name="checkbox" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Select</item> + <item name="multiple" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Select</item> + <item name="text" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Text</item> + <item name="area" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\Text</item> + <item name="file" xsi:type="object">Magento\Catalog\Model\Product\Option\Validator\File</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml index 68c16392095b0cea35355c50e250d407b8626ed3..f4048537474042835b38c8d1a0c7776913a6708d 100644 --- a/app/code/Magento/Catalog/etc/webapi.xml +++ b/app/code/Magento/Catalog/etc/webapi.xml @@ -289,4 +289,40 @@ <resource ref="Magento_Catalog::catalog"/> </resources> </route> + <route url="/V1/products/options/types" method="GET"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\ReadServiceInterface" method="getTypes"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> + <route url="/V1/products/:productSku/options" method="GET"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\ReadServiceInterface" method="getList"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> + <route url="/V1/products/:productSku/options/:optionId" method="GET"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\ReadServiceInterface" method="get"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> + <route url="/V1/products/:productSku/options" method="POST"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\WriteServiceInterface" method="add"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> + <route url="/V1/products/:productSku/options/:optionId" method="PUT"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\WriteServiceInterface" method="update"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> + <route url="/V1/products/:productSku/options/:optionId" method="DELETE"> + <service class="Magento\Catalog\Service\V1\Product\CustomOptions\WriteServiceInterface" method="remove"/> + <resources> + <resource ref="Magento_Catalog::catalog"/> + </resources> + </route> </routes> diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/tab/inventory.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/tab/inventory.phtml index b9a4bc194def1eb786bcbb0da164bc1c46820b70..3144968c7b2c63274afe4165f327e5e78726ccdf 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/tab/inventory.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/tab/inventory.phtml @@ -207,9 +207,10 @@ <span><?php echo __('Enable Qty Increments') ?></span> </label> <div class="control"> + <?php $qtyIncrementsEnabled = $this->getFieldValue('enable_qty_increments'); ?> <select id="inventory_enable_qty_increments" name="<?php echo $this->getFieldSuffix() ?>[stock_data][enable_qty_increments]" <?php echo $_readonly;?>> - <option value="1"><?php echo __('Yes') ?></option> - <option value="0"<?php if ($this->getConfigFieldValue('enable_qty_increments') == 0): ?> selected="selected"<?php endif; ?>><?php echo __('No') ?></option> + <option value="1"<?php if ($qtyIncrementsEnabled): ?> selected="selected"<?php endif; ?>><?php echo __('Yes') ?></option> + <option value="0"<?php if (!$qtyIncrementsEnabled): ?> selected="selected"<?php endif; ?>><?php echo __('No') ?></option> </select> <input type="hidden" id="inventory_enable_qty_increments_default" value="<?php echo $this->getDefaultConfigValue('enable_qty_increments'); ?>"> <?php $_checked = ($this->getFieldValue('use_config_enable_qty_inc') || $this->IsNew()) ? 'checked="checked"' : '' ?> diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/tabs.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/tabs.phtml index bb4e97755e6ac7c2918916414eaa87c6659c9432..7e97028f5746d54171140fa95373ca087c0f6537 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/tabs.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/product/edit/tabs.phtml @@ -43,13 +43,12 @@ <?php $isBasic = $tabGroupCode == \Magento\Catalog\Block\Adminhtml\Product\Edit\Tabs::BASIC_TAB_GROUP_CODE; ?> <div id="<?php echo $tabGroupId ?>" <?php if (!$isBasic): ?> - data-mage-init='{"accordion":{"active":<?php echo $this->isAdvancedTabGroupActive() ? '0' : 'false' ?>, "collapsible": true}}' + data-mage-init='{"collapsible":{"active": <?php echo $this->isAdvancedTabGroupActive() ? 'true' : 'false' ?>, "collapsible": true}}' <?php endif;?>> - <h3 <?php echo $this->getUiId('title') ?>> - <?php echo $isBasic ? __('Basic Settings') - : __('Advanced Settings') ?> + <h3 <?php echo $this->getUiId('title') ?> data-role="title" <?php if (!$isBasic): ?>class="ui-accordion-header"<?php endif;?>> + <span data-role="trigger"> <?php echo $isBasic ? __('Basic Settings') : __('Advanced Settings') ?></span> </h3> - <ul <?php echo $this->getUiId('tab', $tabGroupId) ?> class="tabs"> + <ul <?php echo $this->getUiId('tab', $tabGroupId) ?> class="tabs" data-role="content"> <?php foreach ($tabs as $_tab): ?> <?php if (!$this->canShowTab($_tab) || $_tab->getParentTab() || ($_tab->getGroupCode() && $_tab->getGroupCode() != $tabGroupCode) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 2e4f8fc812f4ec31c466197795e035c4c280f4e2..8903427a9ae05673de5c1b4a63729f0271659a56 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -60,6 +60,8 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity const COL_SKU = 'sku'; + const COL_VISIBILITY = 'visibility'; + /** * Pairs of attribute set ID-to-name. * @@ -323,7 +325,9 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity $productTypes = $this->_exportConfig->getEntityTypes($this->getEntityTypeCode()); foreach ($productTypes as $productTypeName => $productTypeConfig) { if (!($model = $this->_typeFactory->create($productTypeConfig['model']))) { - throw new \Magento\Framework\Model\Exception("Entity type model '{$productTypeConfig['model']}' is not found"); + throw new \Magento\Framework\Model\Exception( + "Entity type model '{$productTypeConfig['model']}' is not found" + ); } if (!$model instanceof \Magento\CatalogImportExport\Model\Export\Product\Type\AbstractType) { throw new \Magento\Framework\Model\Exception( @@ -748,6 +752,8 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity set_time_limit(0); $this->_prepareEntityCollection($this->_getEntityCollection()); + $this->_getEntityCollection()->setOrder('has_options', 'asc'); + $this->_getEntityCollection()->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID); $writer = $this->getWriter(); $page = 0; while (true) { @@ -821,7 +827,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity $this->_attributeValues[$attrCode], array_flip($attrValue) ); - $rowMultiselects[$itemId][$attrCode] = $attrValue; + $rowMultiselects[$storeId][$itemId][$attrCode] = $attrValue; } else { if (isset($this->_attributeValues[$attrCode][$attrValue])) { $attrValue = $this->_attributeValues[$attrCode][$attrValue]; @@ -842,6 +848,9 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity // mark row as not empty $rowIsEmpty = false; } + if (!empty($rowMultiselects[$storeId][$itemId][$attrCode])) { + $rowIsEmpty = false; + } } if ($rowIsEmpty) { // remove empty rows @@ -986,6 +995,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity $dataRow[self::COL_SKU] = null; $dataRow[self::COL_ATTR_SET] = null; $dataRow[self::COL_TYPE] = null; + $dataRow[self::COL_VISIBILITY] = $productData[$defaultStoreId][self::COL_VISIBILITY]; } else { $dataRow[self::COL_STORE] = null; if (isset($stockItemRows[$productId])) { @@ -1021,90 +1031,96 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); } $dataRow = $this->rowCustomizer->addData($dataRow, $productId); - if (!empty($rowMultiselects[$productId])) { - foreach ($rowMultiselects[$productId] as $attrKey => $attrVal) { - if (!empty($rowMultiselects[$productId][$attrKey])) { - $dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$attrKey]); + if (!empty($rowMultiselects[$storeId][$productId])) { + foreach ($rowMultiselects[$storeId][$productId] as $attrKey => $attrVal) { + if (!empty($rowMultiselects[$storeId][$productId][$attrKey])) { + $dataRow[$attrKey] = array_shift($rowMultiselects[$storeId][$productId][$attrKey]); } } } $exportData[] = $dataRow; - } - // calculate largest links block - $largestLinks = 0; - if (isset($linksRows[$productId])) { - $linksRowsKeys = array_keys($linksRows[$productId]); - foreach ($linksRowsKeys as $linksRowsKey) { - $largestLinks = max($largestLinks, count($linksRows[$productId][$linksRowsKey])); - } - } - $additionalRowsCount = max( - count($rowCategories[$productId]), - count($rowWebsites[$productId]), - $largestLinks - ); - if (!empty($rowTierPrices[$productId])) { - $additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId])); - } - if (!empty($rowGroupPrices[$productId])) { - $additionalRowsCount = max($additionalRowsCount, count($rowGroupPrices[$productId])); - } - if (!empty($mediaGalery[$productId])) { - $additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId])); - } - if (!empty($customOptionsData[$productId])) { - $additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId])); - } - $additionalRowsCount = $this->rowCustomizer->getAdditionalRowsCount($additionalRowsCount, $productId); - if (!empty($rowMultiselects[$productId])) { - foreach ($rowMultiselects[$productId] as $attributes) { - $additionalRowsCount = max($additionalRowsCount, count($attributes)); - } - } + // calculate largest links block + $largestLinks = 0; - if ($additionalRowsCount) { - for ($i = 0; $i < $additionalRowsCount; $i++) { - $dataRow = array(); - - $this->_updateDataWithCategoryColumns($dataRow, $rowCategories, $productId); - if ($rowWebsites[$productId]) { - $dataRow['_product_websites'] = $this->_websiteIdToCode[array_shift( - $rowWebsites[$productId] - )]; - } - if (!empty($rowTierPrices[$productId])) { - $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); + if (isset($linksRows[$productId])) { + $linksRowsKeys = array_keys($linksRows[$productId]); + foreach ($linksRowsKeys as $linksRowsKey) { + $largestLinks = max($largestLinks, count($linksRows[$productId][$linksRowsKey])); } - if (!empty($rowGroupPrices[$productId])) { - $dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId])); - } - if (!empty($mediaGalery[$productId])) { - $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); + } + $additionalRowsCount = max( + count($rowCategories[$productId]), + count($rowWebsites[$productId]), + $largestLinks + ); + if (!empty($rowTierPrices[$productId])) { + $additionalRowsCount = max($additionalRowsCount, count($rowTierPrices[$productId])); + } + if (!empty($rowGroupPrices[$productId])) { + $additionalRowsCount = max($additionalRowsCount, count($rowGroupPrices[$productId])); + } + if (!empty($mediaGalery[$productId])) { + $additionalRowsCount = max($additionalRowsCount, count($mediaGalery[$productId])); + } + if (!empty($customOptionsData[$productId])) { + $additionalRowsCount = max($additionalRowsCount, count($customOptionsData[$productId])); + } + $additionalRowsCount = $this->rowCustomizer + ->getAdditionalRowsCount($additionalRowsCount, $productId); + if (!empty($rowMultiselects[$storeId][$productId])) { + foreach ($rowMultiselects[$storeId][$productId] as $attributes) { + $additionalRowsCount = max($additionalRowsCount, count($attributes)); } - foreach ($linkIdColPrefix as $linkId => &$colPrefix) { - if (!empty($linksRows[$productId][$linkId])) { - $linkData = array_shift($linksRows[$productId][$linkId]); - $dataRow[$colPrefix . 'position'] = $linkData['position']; - $dataRow[$colPrefix . 'sku'] = $linkData['sku']; - - if (null !== $linkData['default_qty']) { - $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; + } + + if ($additionalRowsCount) { + for ($i = 0; $i < $additionalRowsCount; $i++) { + $dataRow = array(); + if ($defaultStoreId != $storeId) { + $dataRow[self::COL_STORE] = $this->_storeIdToCode[$storeId]; + } + $this->_updateDataWithCategoryColumns($dataRow, $rowCategories, $productId); + if ($rowWebsites[$productId]) { + $dataRow['_product_websites'] = $this->_websiteIdToCode[array_shift( + $rowWebsites[$productId] + )]; + } + if (!empty($rowTierPrices[$productId])) { + $dataRow = array_merge($dataRow, array_shift($rowTierPrices[$productId])); + } + if (!empty($rowGroupPrices[$productId])) { + $dataRow = array_merge($dataRow, array_shift($rowGroupPrices[$productId])); + } + if (!empty($mediaGalery[$productId])) { + $dataRow = array_merge($dataRow, array_shift($mediaGalery[$productId])); + } + foreach ($linkIdColPrefix as $linkId => &$colPrefix) { + if (!empty($linksRows[$productId][$linkId])) { + $linkData = array_shift($linksRows[$productId][$linkId]); + $dataRow[$colPrefix . 'position'] = $linkData['position']; + $dataRow[$colPrefix . 'sku'] = $linkData['sku']; + + if (null !== $linkData['default_qty']) { + $dataRow[$colPrefix . 'default_qty'] = $linkData['default_qty']; + } } } - } - if (!empty($customOptionsData[$productId])) { - $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); - } - $dataRow = $this->rowCustomizer->addData($dataRow, $productId); - if (!empty($rowMultiselects[$productId])) { - foreach ($rowMultiselects[$productId] as $attrKey => $attrVal) { - if (!empty($rowMultiselects[$productId][$attrKey])) { - $dataRow[$attrKey] = array_shift($rowMultiselects[$productId][$attrKey]); + if (!empty($customOptionsData[$productId])) { + $dataRow = array_merge($dataRow, array_shift($customOptionsData[$productId])); + } + $dataRow = $this->rowCustomizer->addData($dataRow, $productId); + if (!empty($rowMultiselects[$storeId][$productId])) { + foreach ($rowMultiselects[$storeId][$productId] as $attrKey => $attrVal) { + if (!empty($rowMultiselects[$storeId][$productId][$attrKey])) { + $dataRow[$attrKey] = array_shift( + $rowMultiselects[$storeId][$productId][$attrKey] + ); + } } } + $exportData[] = $dataRow; } - $exportData[] = $dataRow; } } } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index a8607a1a938aaf8c75a612e8088ffbdbf50a39bb..5a63675b971da8730e79e2d833f9df26768635a5 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -289,6 +289,34 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity '_media_is_disabled' ); + /** + * @var array + */ + protected $defaultStockData = [ + 'manage_stock' => 1, + 'use_config_manage_stock' => 1, + 'qty' => 0, + 'min_qty' => 0, + 'use_config_min_qty' => 1, + 'min_sale_qty' => 1, + 'use_config_min_sale_qty' => 1, + 'max_sale_qty' => 10000, + 'use_config_max_sale_qty' => 1, + 'is_qty_decimal' => 0, + 'backorders' => 0, + 'use_config_backorders' => 1, + 'notify_stock_qty' => 1, + 'use_config_notify_stock_qty' => 1, + 'enable_qty_increments' => 0, + 'use_config_enable_qty_inc' => 1, + 'qty_increments' => 0, + 'use_config_qty_increments' => 1, + 'is_in_stock' => 0, + 'low_stock_date' => null, + 'stock_status_changed_auto' => 0, + 'is_decimal_divided' => 0 + ]; + /** * Column names that holds images files names * @@ -360,7 +388,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity protected $_catalogData = null; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; @@ -436,11 +464,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ protected $_stockResItemFac; - /** - * @var \Magento\CatalogInventory\Model\Stock\ItemFactory - */ - protected $_stockItemFactory; - /** * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface */ @@ -451,6 +474,16 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ protected $dateTime; + /** + * @var \Magento\Index\Model\Indexer + */ + protected $indexer; + + /** + * @var \Magento\Indexer\Model\Indexer + */ + protected $newIndexer; + /** * @var \Magento\Framework\Logger */ @@ -470,7 +503,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity * @param \Magento\ImportExport\Model\Resource\Helper $resourceHelper * @param \Magento\Framework\Stdlib\String $string * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Catalog\Helper\Data $catalogData * @param \Magento\ImportExport\Model\Import\Config $importConfig * @param \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceFactory $resourceFactory @@ -486,10 +519,11 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity * @param \Magento\CatalogImportExport\Model\Import\UploaderFactory $uploaderFactory * @param \Magento\Framework\App\Filesystem $filesystem * @param \Magento\CatalogInventory\Model\Resource\Stock\ItemFactory $stockResItemFac - * @param \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Framework\Logger $logger + * @param \Magento\Index\Model\Indexer $indexer + * @param \Magento\Indexer\Model\Indexer $newIndexer * @param array $data */ public function __construct( @@ -501,7 +535,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity \Magento\ImportExport\Model\Resource\Helper $resourceHelper, \Magento\Framework\Stdlib\String $string, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Catalog\Helper\Data $catalogData, \Magento\ImportExport\Model\Import\Config $importConfig, \Magento\CatalogImportExport\Model\Import\Proxy\Product\ResourceFactory $resourceFactory, @@ -517,10 +551,11 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity \Magento\CatalogImportExport\Model\Import\UploaderFactory $uploaderFactory, \Magento\Framework\App\Filesystem $filesystem, \Magento\CatalogInventory\Model\Resource\Stock\ItemFactory $stockResItemFac, - \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Framework\Logger $logger, + \Magento\Index\Model\Indexer $indexer, + \Magento\Indexer\Model\Indexer $newIndexer, array $data = array() ) { $this->_eventManager = $eventManager; @@ -539,9 +574,10 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $this->_uploaderFactory = $uploaderFactory; $this->_mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::MEDIA_DIR); $this->_stockResItemFac = $stockResItemFac; - $this->_stockItemFactory = $stockItemFactory; $this->_localeDate = $localeDate; $this->dateTime = $dateTime; + $this->indexer = $indexer; + $this->newIndexer = $newIndexer; $this->_logger = $logger; parent::__construct($coreData, $importExportData, $importData, $config, $resource, $resourceHelper, $string); $this->_optionEntity = isset( @@ -624,12 +660,12 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $this->_deleteProducts(); } else { $this->_saveProducts(); - $this->_saveStockItem(); - $this->_saveLinks(); - $this->getOptionEntity()->importData(); - foreach ($this->_productTypeModels as $productType => $productTypeModel) { + foreach ($this->_productTypeModels as $productTypeModel) { $productTypeModel->saveData(); } + $this->_saveLinks(); + $this->_saveStockItem(); + $this->getOptionEntity()->importData(); } $this->_eventManager->dispatch('catalog_product_import_finish_before', array('adapter' => $this)); return true; @@ -1289,6 +1325,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity 'attribute_set_id' => $this->_newSku[$rowSku]['attr_set_id'], 'type_id' => $this->_newSku[$rowSku]['type_id'], 'sku' => $rowSku, + 'has_options' => isset($rowData['has_options']) ? $rowData['has_options'] : 0, 'created_at' => $this->dateTime->now(), 'updated_at' => $this->dateTime->now() ); @@ -1725,38 +1762,12 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity */ protected function _saveStockItem() { - $defaultStockData = array( - 'manage_stock' => 1, - 'use_config_manage_stock' => 1, - 'qty' => 0, - 'min_qty' => 0, - 'use_config_min_qty' => 1, - 'min_sale_qty' => 1, - 'use_config_min_sale_qty' => 1, - 'max_sale_qty' => 10000, - 'use_config_max_sale_qty' => 1, - 'is_qty_decimal' => 0, - 'backorders' => 0, - 'use_config_backorders' => 1, - 'notify_stock_qty' => 1, - 'use_config_notify_stock_qty' => 1, - 'enable_qty_increments' => 0, - 'use_config_enable_qty_inc' => 1, - 'qty_increments' => 0, - 'use_config_qty_increments' => 1, - 'is_in_stock' => 0, - 'low_stock_date' => null, - 'stock_status_changed_auto' => 0, - 'is_decimal_divided' => 0 - ); - /** @var $stockResource \Magento\CatalogInventory\Model\Resource\Stock\Item */ $stockResource = $this->_stockResItemFac->create(); $entityTable = $stockResource->getMainTable(); - while ($bunch = $this->_dataSourceModel->getNextBunch()) { $stockData = array(); - + $productIdsToReindex = array(); // Format bunch to stock data rows foreach ($bunch as $rowNum => $rowData) { if (!$this->isRowAllowedToImport($rowData, $rowNum)) { @@ -1769,46 +1780,48 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $row = array(); $row['product_id'] = $this->_newSku[$rowData[self::COL_SKU]]['entity_id']; - $row['stock_id'] = 1; + $productIdsToReindex[] = $row['product_id']; + $row['stock_id'] = \Magento\CatalogInventory\Model\Stock\Item::DEFAULT_STOCK_ID; - /** @var $stockItem \Magento\CatalogInventory\Model\Stock\Item */ - $stockItem = $this->_stockItemFactory->create(); - $stockItem->loadByProduct($row['product_id']); - $existStockData = $stockItem->getData(); + $stockItemDo = $this->stockItemService->getStockItem($row['product_id']); + $existStockData = $stockItemDo->__toArray(); $row = array_merge( - $defaultStockData, - array_intersect_key($existStockData, $defaultStockData), - array_intersect_key($rowData, $defaultStockData), + $this->defaultStockData, + array_intersect_key($existStockData, $this->defaultStockData), + array_intersect_key($rowData, $this->defaultStockData), $row ); - $stockItem->setData($row); - if ($this->stockItemService->isQty($this->_newSku[$rowData[self::COL_SKU]]['type_id'])) { - if ($stockItem->verifyNotification()) { - $stockItem->setLowStockDate( - $this->_localeDate->date( - null, - null, - null, - false - )->toString( - \Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT - ) + if ($this->stockItemService->verifyNotification($row['product_id'])) { + $row['low_stock_date'] = $this->_localeDate->date( + null, + null, + null, + false + )->toString( + \Magento\Framework\Stdlib\DateTime::DATETIME_INTERNAL_FORMAT ); } - $stockItem->setStockStatusChangedAuto((int)(!$stockItem->verifyStock())); + $row['stock_status_changed_auto'] = (int) !$this->stockItemService->verifyStock($row['product_id']); } else { - $stockItem->setQty(0); + $row['qty'] = 0; } - $stockData[] = $stockItem->unsetOldData()->getData(); + $stockData[] = $row; } // Insert rows - if ($stockData) { + if (!empty($stockData)) { $this->_connection->insertOnDuplicate($entityTable, $stockData); } + + if ($productIdsToReindex) { + $this->indexer->getProcessByCode('cataloginventory_stock')->getIndexer()->reindexAll(); + $this->indexer->getProcessByCode('catalog_product_attribute')->getIndexer()->reindexAll(); + $this->newIndexer->load('catalog_product_category')->reindexList($productIdsToReindex); + $this->newIndexer->load('catalog_product_price')->reindexList($productIdsToReindex); + } } return $this; } diff --git a/app/code/Magento/CatalogImportExport/etc/module.xml b/app/code/Magento/CatalogImportExport/etc/module.xml index c770dde9d5ef5b5ab15576e3af2a2ef50d5df4a6..1bf9a1ca0174c510177f65376befeb72b85517ba 100644 --- a/app/code/Magento/CatalogImportExport/etc/module.xml +++ b/app/code/Magento/CatalogImportExport/etc/module.xml @@ -30,6 +30,8 @@ <module name="Magento_Catalog"/> <module name="Magento_Eav"/> <module name="Magento_ImportExport"/> + <module name="Magento_Index"/> + <module name="Magento_Indexer"/> <module name="Magento_Store"/> <module name="Magento_CatalogInventory"/> <module name="Magento_Customer"/> diff --git a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php index 947ef525c3bf391252400c2b1ab8b96f8f3aa8a0..d8b57d513fe8a25b6b933145edd199a8af58c4af 100644 --- a/app/code/Magento/CatalogInventory/Block/Qtyincrements.php +++ b/app/code/Magento/CatalogInventory/Block/Qtyincrements.php @@ -47,20 +47,20 @@ class Qtyincrements extends Template implements IdentityInterface protected $_coreRegistry; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Registry $registry - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Registry $registry, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_coreRegistry = $registry; diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php index ac375618d6102f53d56fefe4d6add3cf5b0bdee6..6577cdf072b405d4e648781e8032797894fba6dd 100644 --- a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php +++ b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php @@ -44,20 +44,20 @@ abstract class AbstractStockqty extends \Magento\Framework\View\Element\Template protected $_coreRegistry; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Framework\Registry $registry - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Framework\Registry $registry, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_coreRegistry = $registry; diff --git a/app/code/Magento/CatalogInventory/Helper/Data.php b/app/code/Magento/CatalogInventory/Helper/Data.php index cf88006dc27235f83f68d6fa66332a2eef4825a7..54849de6512062f5f1b762bedf0aafefddc4c5f2 100644 --- a/app/code/Magento/CatalogInventory/Helper/Data.php +++ b/app/code/Magento/CatalogInventory/Helper/Data.php @@ -64,7 +64,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $config */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -108,7 +107,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper } /** - * Check if creditmemo items auto return option is enabled + * Check if credit memo items auto return option is enabled * * @return bool */ diff --git a/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php b/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php index e2adf1a3ad1b1dc1c97bce0fe38bccd71a5c513f..2f7b6bee2e46e59603b9f1dd79f96947e9d7d8aa 100644 --- a/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php +++ b/app/code/Magento/CatalogInventory/Helper/Minsaleqty.php @@ -37,7 +37,7 @@ class Minsaleqty * * @var \Magento\Framework\App\Config\ScopeConfigInterface */ - protected $_scopeConfig; + protected $scopeConfig; /** * @var \Magento\Framework\Math\Random @@ -52,7 +52,7 @@ class Minsaleqty \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Framework\Math\Random $mathRandom ) { - $this->_scopeConfig = $scopeConfig; + $this->scopeConfig = $scopeConfig; $this->mathRandom = $mathRandom; } @@ -62,7 +62,7 @@ class Minsaleqty * @param int|float|string|null $qty * @return float|null */ - protected function _fixQty($qty) + protected function fixQty($qty) { return !empty($qty) ? (float) $qty : null; } @@ -73,16 +73,16 @@ class Minsaleqty * @param int|float|string|array $value * @return string */ - protected function _serializeValue($value) + protected function serializeValue($value) { if (is_numeric($value)) { - $data = (double)$value; - return (string)$data; - } else if (is_array($value)) { + $data = (float) $value; + return (string) $data; + } elseif (is_array($value)) { $data = array(); foreach ($value as $groupId => $qty) { if (!array_key_exists($groupId, $data)) { - $data[$groupId] = $this->_fixQty($qty); + $data[$groupId] = $this->fixQty($qty); } } if (count($data) == 1 && array_key_exists(CustomerGroupService::CUST_GROUP_ALL, $data)) { @@ -100,10 +100,10 @@ class Minsaleqty * @param int|float|string $value * @return array */ - protected function _unserializeValue($value) + protected function unserializeValue($value) { if (is_numeric($value)) { - return array(CustomerGroupService::CUST_GROUP_ALL => $this->_fixQty($value)); + return array(CustomerGroupService::CUST_GROUP_ALL => $this->fixQty($value)); } elseif (is_string($value) && !empty($value)) { return unserialize($value); } else { @@ -117,7 +117,7 @@ class Minsaleqty * @param string|array $value * @return bool */ - protected function _isEncodedArrayFieldValue($value) + protected function isEncodedArrayFieldValue($value) { if (!is_array($value)) { return false; @@ -140,12 +140,12 @@ class Minsaleqty * @param array $value * @return array */ - protected function _encodeArrayFieldValue(array $value) + protected function encodeArrayFieldValue(array $value) { $result = array(); foreach ($value as $groupId => $qty) { $resultId = $this->mathRandom->getUniqueHash('_'); - $result[$resultId] = array('customer_group_id' => $groupId, 'min_sale_qty' => $this->_fixQty($qty)); + $result[$resultId] = array('customer_group_id' => $groupId, 'min_sale_qty' => $this->fixQty($qty)); } return $result; } @@ -156,7 +156,7 @@ class Minsaleqty * @param array $value * @return array */ - protected function _decodeArrayFieldValue(array $value) + protected function decodeArrayFieldValue(array $value) { $result = array(); unset($value['__empty']); @@ -168,7 +168,7 @@ class Minsaleqty continue; } $groupId = $row['customer_group_id']; - $qty = $this->_fixQty($row['min_sale_qty']); + $qty = $this->fixQty($row['min_sale_qty']); $result[$groupId] = $qty; } return $result; @@ -183,14 +183,14 @@ class Minsaleqty */ public function getConfigValue($customerGroupId, $store = null) { - $value = $this->_scopeConfig->getValue( + $value = $this->scopeConfig->getValue( \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MIN_SALE_QTY, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store ); - $value = $this->_unserializeValue($value); - if ($this->_isEncodedArrayFieldValue($value)) { - $value = $this->_decodeArrayFieldValue($value); + $value = $this->unserializeValue($value); + if ($this->isEncodedArrayFieldValue($value)) { + $value = $this->decodeArrayFieldValue($value); } $result = null; foreach ($value as $groupId => $qty) { @@ -201,7 +201,7 @@ class Minsaleqty $result = $qty; } } - return $this->_fixQty($result); + return $this->fixQty($result); } /** @@ -212,9 +212,9 @@ class Minsaleqty */ public function makeArrayFieldValue($value) { - $value = $this->_unserializeValue($value); - if (!$this->_isEncodedArrayFieldValue($value)) { - $value = $this->_encodeArrayFieldValue($value); + $value = $this->unserializeValue($value); + if (!$this->isEncodedArrayFieldValue($value)) { + $value = $this->encodeArrayFieldValue($value); } return $value; } @@ -227,10 +227,10 @@ class Minsaleqty */ public function makeStorableArrayFieldValue($value) { - if ($this->_isEncodedArrayFieldValue($value)) { - $value = $this->_decodeArrayFieldValue($value); + if ($this->isEncodedArrayFieldValue($value)) { + $value = $this->decodeArrayFieldValue($value); } - $value = $this->_serializeValue($value); + $value = $this->serializeValue($value); return $value; } } diff --git a/app/code/Magento/CatalogInventory/Model/Observer.php b/app/code/Magento/CatalogInventory/Model/Observer.php index 18a9c826bc1af45d0fbbd5392b9d34abf90ee644..62f5455a63395a8c8705df344ae48823a144c5ae 100644 --- a/app/code/Magento/CatalogInventory/Model/Observer.php +++ b/app/code/Magento/CatalogInventory/Model/Observer.php @@ -111,6 +111,55 @@ class Observer */ protected $_priceIndexer; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + + /** + * @var \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder + */ + protected $stockItemBuilder; + + /** + * @var \Magento\CatalogInventory\Model\Stock\ItemRegistry + */ + protected $stockItemRegistry; + + /** + * @var array + */ + protected $paramListToCheck = [ + 'use_config_min_qty' => [ + 'item' => 'stock_data/min_qty', + 'config' => 'stock_data/use_config_min_qty', + ], + 'use_config_min_sale_qty' => [ + 'item' => 'stock_data/min_sale_qty', + 'config' => 'stock_data/use_config_min_sale_qty', + ], + 'use_config_max_sale_qty' => [ + 'item' => 'stock_data/max_sale_qty', + 'config' => 'stock_data/use_config_max_sale_qty', + ], + 'use_config_backorders' => [ + 'item' => 'stock_data/backorders', + 'config' => 'stock_data/use_config_backorders', + ], + 'use_config_notify_stock_qty' => [ + 'item' => 'stock_data/notify_stock_qty', + 'config' => 'stock_data/use_config_notify_stock_qty', + ], + 'use_config_enable_qty_inc' => [ + 'item' => 'stock_data/enable_qty_increments', + 'config' => 'stock_data/use_config_enable_qty_inc', + ], + 'use_config_qty_increments' => [ + 'item' => 'stock_data/qty_increments', + 'config' => 'stock_data/use_config_qty_increments', + ], + ]; + /** * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer * @param Resource\Indexer\Stock $resourceIndexerStock @@ -121,7 +170,9 @@ class Observer * @param \Magento\CatalogInventory\Helper\Data $catalogInventoryData * @param Stock\ItemFactory $stockItemFactory * @param StockFactory $stockFactory - * @param Stock\StatusFactory $stockStatusFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + * @param \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder + * @param Stock\ItemRegistry $stockItemRegistry */ public function __construct( \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer, @@ -133,7 +184,9 @@ class Observer \Magento\CatalogInventory\Helper\Data $catalogInventoryData, \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory, StockFactory $stockFactory, - \Magento\CatalogInventory\Model\Stock\StatusFactory $stockStatusFactory + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, + \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder, + \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry ) { $this->_priceIndexer = $priceIndexer; $this->_resourceIndexerStock = $resourceIndexerStock; @@ -144,7 +197,9 @@ class Observer $this->_catalogInventoryData = $catalogInventoryData; $this->_stockItemFactory = $stockItemFactory; $this->_stockFactory = $stockFactory; - $this->_stockStatusFactory = $stockStatusFactory; + $this->stockItemService = $stockItemService; + $this->stockItemBuilder = $stockItemBuilder; + $this->stockItemRegistry = $stockItemRegistry; } /** @@ -157,30 +212,8 @@ class Observer { $product = $observer->getEvent()->getProduct(); if ($product instanceof \Magento\Catalog\Model\Product) { - $productId = intval($product->getId()); - if (!isset($this->_stockItemsArray[$productId])) { - $this->_stockItemsArray[$productId] = $this->_stockItemFactory->create(); - } - $productStockItem = $this->_stockItemsArray[$productId]; - $productStockItem->assignProduct($product); - } - return $this; - } - - /** - * Remove stock information from static variable - * - * @param EventObserver $observer - * @return $this - */ - public function removeInventoryData($observer) - { - $product = $observer->getEvent()->getProduct(); - if ($product instanceof \Magento\Catalog\Model\Product - && $product->getId() - && isset($this->_stockItemsArray[$product->getId()]) - ) { - unset($this->_stockItemsArray[$product->getId()]); + $stockItem = $this->stockItemRegistry->retrieve($product->getId()); + $this->_stockStatus->assignProduct($product, $stockItem->getStockId(), $product->getStockStatus()); } return $this; } @@ -198,7 +231,7 @@ class Observer if ($productCollection->hasFlag('require_stock_items')) { $this->_stockFactory->create()->addItemsToProducts($productCollection); } else { - $this->_stockStatusFactory->create()->addStockStatusToProducts($productCollection); + $this->_stockStatus->addStockStatusToProducts($productCollection); } return $this; } @@ -233,69 +266,41 @@ class Observer return $this; } - $item = $product->getStockItem(); - if (!$item) { - $item = $this->_stockItemFactory->create(); - } - $this->_prepareItemForSave($item, $product); - $item->save(); + $this->saveStockItemData($product); return $this; } /** * Prepare stock item data for save * - * @param Item $item * @param \Magento\Catalog\Model\Product $product * @return $this */ - protected function _prepareItemForSave($item, $product) + protected function saveStockItemData($product) { - $item->addData($product->getStockData()) - ->setProduct($product) - ->setProductId($product->getId()) - ->setStockId($item->getStockId()); - - $paramListToCheck = [ - 'use_config_min_qty' => [ - 'item' => 'stock_data/min_qty', - 'config' => 'stock_data/use_config_min_qty', - ], - 'use_config_min_sale_qty' => [ - 'item' => 'stock_data/min_sale_qty', - 'config' => 'stock_data/use_config_min_sale_qty', - ], - 'use_config_max_sale_qty' => [ - 'item' => 'stock_data/max_sale_qty', - 'config' => 'stock_data/use_config_max_sale_qty', - ], - 'use_config_backorders' => [ - 'item' => 'stock_data/backorders', - 'config' => 'stock_data/use_config_backorders', - ], - 'use_config_notify_stock_qty' => [ - 'item' => 'stock_data/notify_stock_qty', - 'config' => 'stock_data/use_config_notify_stock_qty', - ], - 'use_config_enable_qty_inc' => [ - 'item' => 'stock_data/enable_qty_increments', - 'config' => 'stock_data/use_config_enable_qty_inc', - ], - 'use_config_qty_increments' => [ - 'item' => 'stock_data/qty_increments', - 'config' => 'stock_data/use_config_qty_increments', - ], - ]; - foreach ($paramListToCheck as $dataKey => $configPath) { + $stockItemData = $product->getStockData(); + $stockItemData['product_id'] = $product->getId(); + /** + * @todo Should be refactored together with \Magento\CatalogInventory\Model\Stock\Item::getStockId + */ + $stockItemData['stock_id'] = \Magento\CatalogInventory\Model\Stock\Item::DEFAULT_STOCK_ID; + + foreach ($this->paramListToCheck as $dataKey => $configPath) { if (null !== $product->getData($configPath['item']) && null === $product->getData($configPath['config'])) { - $item->setData($dataKey, false); + $stockItemData[$dataKey] = false; } } $originalQty = $product->getData('stock_data/original_inventory_qty'); if (strlen($originalQty) > 0) { - $item->setQtyCorrection($item->getQty() - $originalQty); + $stockItemData['qty_correction'] = $stockItemData['qty'] - $originalQty; } + + $stockItemDo = $this->stockItemService->getStockItem($product->getId()); + $this->stockItemService->saveStockItem( + $this->stockItemBuilder->mergeDataObjectWithArray($stockItemDo, $stockItemData) + ); + return $this; } @@ -385,7 +390,8 @@ class Observer } else { $stockItem = null; if ($quoteItem->getProduct()) { - $stockItem = $quoteItem->getProduct()->getStockItem(); + /** @var Item $stockItem */ + $stockItem = $this->stockItemRegistry->retrieve($quoteItem->getProduct()->getId()); } $items[$productId] = array('item' => $stockItem, 'qty' => $quoteItem->getTotalQty()); } diff --git a/app/code/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventory.php b/app/code/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventory.php index f3c2260206e23363d988c679c1bba274b92360f2..2df401b74d666ac442b8105e67661771a7d6bf3b 100644 --- a/app/code/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventory.php +++ b/app/code/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventory.php @@ -25,6 +25,20 @@ namespace Magento\CatalogInventory\Model\Product\CopyConstructor; class CatalogInventory implements \Magento\Catalog\Model\Product\CopyConstructorInterface { + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + + /** + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + */ + public function __construct( + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + ) { + $this->stockItemService = $stockItemService; + } + /** * Copy product inventory data (used for product duplicate functionality) * @@ -34,23 +48,22 @@ class CatalogInventory implements \Magento\Catalog\Model\Product\CopyConstructor */ public function build(\Magento\Catalog\Model\Product $product, \Magento\Catalog\Model\Product $duplicate) { - $duplicate->unsStockItem(); - $stockData = array( + $stockData = [ 'use_config_min_qty' => 1, 'use_config_min_sale_qty' => 1, 'use_config_max_sale_qty' => 1, 'use_config_backorders' => 1, 'use_config_notify_stock_qty' => 1 - ); - /** @var \Magento\CatalogInventory\Model\Stock\Item $currentStockItem */ - $currentStockItem = $product->getStockItem(); - if ($currentStockItem) { - $stockData += array( - 'use_config_enable_qty_inc' => $currentStockItem->getData('use_config_enable_qty_inc'), - 'enable_qty_increments' => $currentStockItem->getData('enable_qty_increments'), - 'use_config_qty_increments' => $currentStockItem->getData('use_config_qty_increments'), - 'qty_increments' => $currentStockItem->getData('qty_increments') - ); + ]; + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $currentStockItemDo */ + $currentStockItemDo = $this->stockItemService->getStockItem($product->getId()); + if ($currentStockItemDo->getStockId()) { + $stockData += [ + 'use_config_enable_qty_inc' => $currentStockItemDo->isUseConfigEnableQtyInc(), + 'enable_qty_increments' => $currentStockItemDo->isEnableQtyIncrements(), + 'use_config_qty_increments' => $currentStockItemDo->isUseConfigQtyIncrements(), + 'qty_increments' => $currentStockItemDo->getQtyIncrements(), + ]; } $duplicate->setStockData($stockData); } diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index 043a1c889b1e009bf35cf8b7b092d85c79695c97..5707643895888c2ab454e3552cf2a9ba5d615d96 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -37,16 +37,24 @@ class QuantityValidator */ protected $stockItemInitializer; + /** + * @var \Magento\CatalogInventory\Model\Stock\ItemFactory + */ + protected $stockItemFactory; + /** * @param QuantityValidator\Initializer\Option $optionInitializer * @param QuantityValidator\Initializer\StockItem $stockItemInitializer + * @param \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory */ public function __construct( QuantityValidator\Initializer\Option $optionInitializer, - QuantityValidator\Initializer\StockItem $stockItemInitializer + QuantityValidator\Initializer\StockItem $stockItemInitializer, + \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory ) { $this->optionInitializer = $optionInitializer; $this->stockItemInitializer = $stockItemInitializer; + $this->stockItemFactory = $stockItemFactory; } /** @@ -73,15 +81,16 @@ class QuantityValidator $qty = $quoteItem->getQty(); /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ - $stockItem = $quoteItem->getProduct()->getStockItem(); + $stockItem = $this->stockItemFactory->create()->loadByProduct($quoteItem->getProduct()); $parentStockItem = false; /** - * Check if product in stock. For composite products check base (parent) item stosk status + * Check if product in stock. For composite products check base (parent) item stock status */ if ($quoteItem->getParentItem()) { - $parentStockItem = $quoteItem->getParentItem()->getProduct()->getStockItem(); + $parentStockItem = $this->stockItemFactory->create() + ->loadByProduct($quoteItem->getParentItem()->getProduct()); } if ($stockItem) { @@ -136,6 +145,7 @@ class QuantityValidator } foreach ($options as $option) { + $result = $this->optionInitializer->initialize($option, $quoteItem, $qty); if ($result->getHasError()) { $option->setHasError(true); diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php index 89e4ea5d1330ee938c1dea969fae7c5f01398669..35b9643b850ece58229b2a5b2efad5d5cfe96b4a 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php @@ -32,41 +32,41 @@ class Option */ protected $quoteItemQtyList; + /** + * @var \Magento\CatalogInventory\Model\Stock\ItemRegistry + */ + protected $stockItemRegistry; + /** * @param QuoteItemQtyList $quoteItemQtyList + * @param \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry */ - public function __construct(QuoteItemQtyList $quoteItemQtyList) - { + public function __construct( + QuoteItemQtyList $quoteItemQtyList, + \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry + ) { $this->quoteItemQtyList = $quoteItemQtyList; + $this->stockItemRegistry = $stockItemRegistry; } /** - * Initialize item option + * Init stock item * * @param \Magento\Sales\Model\Quote\Item\Option $option * @param \Magento\Sales\Model\Quote\Item $quoteItem - * @param int $qty - * - * @return \Magento\Framework\Object * + * @return \Magento\CatalogInventory\Model\Stock\Item * @throws \Magento\Framework\Model\Exception + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function initialize( + public function getStockItem( \Magento\Sales\Model\Quote\Item\Option $option, - \Magento\Sales\Model\Quote\Item $quoteItem, - $qty + \Magento\Sales\Model\Quote\Item $quoteItem ) { - $optionValue = $option->getValue(); - $optionQty = $qty * $optionValue; - $increaseOptionQty = ($quoteItem->getQtyToAdd() ? $quoteItem->getQtyToAdd() : $qty) * $optionValue; - - /* @var $stockItem \Magento\CatalogInventory\Model\Stock\Item */ - $stockItem = $option->getProduct()->getStockItem(); - - if (!$stockItem instanceof \Magento\CatalogInventory\Model\Stock\Item) { + $stockItem = $this->stockItemRegistry->retrieve($option->getProduct()->getId()); + if (!$stockItem->getId()) { throw new \Magento\Framework\Model\Exception(__('The stock item for Product in option is not valid.')); } - /** * define that stock item is child for composite product */ @@ -76,6 +76,27 @@ class Option */ $stockItem->setSuppressCheckQtyIncrements(true); + return $stockItem; + } + + /** + * Initialize item option + * + * @param \Magento\Sales\Model\Quote\Item\Option $option + * @param \Magento\Sales\Model\Quote\Item $quoteItem + * @param int $qty + * + * @return \Magento\Framework\Object + * @throws \Magento\Framework\Model\Exception + */ + public function initialize( + \Magento\Sales\Model\Quote\Item\Option $option, + \Magento\Sales\Model\Quote\Item $quoteItem, + $qty + ) { + $optionValue = $option->getValue(); + $optionQty = $qty * $optionValue; + $increaseOptionQty = ($quoteItem->getQtyToAdd() ? $quoteItem->getQtyToAdd() : $qty) * $optionValue; $qtyForCheck = $this->quoteItemQtyList->getQty( $option->getProduct()->getId(), $quoteItem->getId(), @@ -83,6 +104,7 @@ class Option $increaseOptionQty ); + $stockItem = $this->getStockItem($option, $quoteItem); $result = $stockItem->checkQuoteItemQty($optionQty, $qtyForCheck, $optionValue); if (!is_null($result->getItemIsQtyDecimal())) { diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock.php index f2eac8752673983084e3cb090b49af5b7a7e47ed..780b01605e9c87d1450a7891624774290048a73a 100644 --- a/app/code/Magento/CatalogInventory/Model/Resource/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock.php @@ -79,7 +79,7 @@ class Stock extends \Magento\Framework\Model\Resource\Db\AbstractDb protected $_stock; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; @@ -104,14 +104,14 @@ class Stock extends \Magento\Framework\Model\Resource\Db\AbstractDb /** * @param \Magento\Framework\App\Resource $resource - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\CatalogInventory\Model\StockFactory $stockFactory * @param \Magento\Framework\Stdlib\DateTime $dateTime */ public function __construct( \Magento\Framework\App\Resource $resource, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\CatalogInventory\Model\StockFactory $stockFactory, \Magento\Framework\Stdlib\DateTime $dateTime diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item.php index 49bef03231110baaa8d8f8fbd430464b67282140..dbc92f34dc3e2fc7c72ba619dd9df46d0c1b6dc6 100644 --- a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item.php @@ -102,7 +102,7 @@ class Item extends \Magento\Framework\Model\Resource\Db\AbstractDb { if ($columns === null) { $adapter = $this->_getReadAdapter(); - $isManageStock = (int)$this->_scopeConfig->getValue( + $isManageStock = (int) $this->_scopeConfig->getValue( \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MANAGE_STOCK, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php index 466d1020ffa0550a637076a6758a096859f156cf..63e7109d8d1379ec65958196ff646613daa5ffb6 100644 --- a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php @@ -100,17 +100,13 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb $websites = array_keys($object->getWebsites($websiteId)); $adapter = $this->_getWriteAdapter(); foreach ($websites as $websiteId) { - $select = $adapter->select()->from( - $this->getMainTable() - )->where( - 'product_id = :product_id' - )->where( - 'website_id = :website_id' - )->where( - 'stock_id = :stock_id' - ); + $select = $adapter->select()->from($this->getMainTable()) + ->where('product_id = :product_id') + ->where('website_id = :website_id') + ->where('stock_id = :stock_id'); $bind = array(':product_id' => $productId, ':website_id' => $websiteId, ':stock_id' => $stockId); - if ($row = $adapter->fetchRow($select, $bind)) { + $row = $adapter->fetchRow($select, $bind); + if ($row) { $bind = array('qty' => $qty, 'stock_status' => $status); $where = array( $adapter->quoteInto('product_id=?', (int)$row['product_id']), @@ -148,19 +144,11 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb $productIds = array($productIds); } - $select = $this->_getReadAdapter()->select()->from( - $this->getMainTable(), - array('product_id', 'stock_status') - )->where( - 'product_id IN(?)', - $productIds - )->where( - 'stock_id=?', - (int)$stockId - )->where( - 'website_id=?', - (int)$websiteId - ); + $select = $this->_getReadAdapter()->select() + ->from($this->getMainTable(), array('product_id', 'stock_status')) + ->where('product_id IN(?)', $productIds) + ->where('stock_id=?', (int) $stockId) + ->where('website_id=?', (int) $websiteId); return $this->_getReadAdapter()->fetchPairs($select); } @@ -212,13 +200,10 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb $select = $this->_getReadAdapter()->select()->from( array('e' => $this->getTable('catalog_product_entity')), array('entity_id', 'type_id') - )->order( - 'entity_id ASC' - )->where( - 'entity_id > :entity_id' - )->limit( - $limit - ); + ) + ->order('entity_id ASC') + ->where('entity_id > :entity_id') + ->limit($limit); return $this->_getReadAdapter()->fetchPairs($select, array(':entity_id' => $lastEntityId)); } @@ -311,19 +296,10 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb $adapter = $this->_getReadAdapter(); if ($storeId === null || $storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID) { - $select = $adapter->select()->from( - $attributeTable, - array('entity_id', 'value') - )->where( - 'entity_id IN (?)', - $productIds - )->where( - 'attribute_id = ?', - $attribute->getAttributeId() - )->where( - 'store_id = ?', - \Magento\Store\Model\Store::DEFAULT_STORE_ID - ); + $select = $adapter->select()->from($attributeTable, array('entity_id', 'value')) + ->where('entity_id IN (?)', $productIds) + ->where('attribute_id = ?', $attribute->getAttributeId()) + ->where('store_id = ?', \Magento\Store\Model\Store::DEFAULT_STORE_ID); $rows = $adapter->fetchPairs($select); } else { diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status/Collection.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status/Collection.php new file mode 100644 index 0000000000000000000000000000000000000000..e893c58d0d2da9c2d7646378530747546442dd45 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status/Collection.php @@ -0,0 +1,81 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogInventory\Model\Resource\Stock\Status; + +/** + * Stock status collection resource model + */ +class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection +{ + /** + * Initialize resource model + * + * @return void + */ + protected function _construct() + { + $this->_init( + 'Magento\CatalogInventory\Model\Stock\Status', + 'Magento\CatalogInventory\Model\Resource\Stock\Status' + ); + } + + /** + * Filter status by website + * + * @param \Magento\Store\Model\Website $website + * @return $this + */ + public function addWebsiteFilter(\Magento\Store\Model\Website $website) + { + $this->addFieldToFilter('website_id', $website->getWebsiteId()); + return $this; + } + + /** + * Add filter by quantity to collection + * + * @param float $qty + * @return $this + */ + public function addQtyFilter($qty) + { + return $this->addFieldToFilter('main_table.qty', ['lteq' => $qty]); + } + + /** + * Initialize select object + * + * @return $this + */ + protected function _initSelect() + { + return parent::_initSelect()->getSelect()->join( + array('cp_table' => $this->getTable('catalog_product_entity')), + 'main_table.product_id = cp_table.entity_id', + array('sku', 'type_id') + ); + } +} diff --git a/app/code/Magento/CatalogInventory/Model/Stock.php b/app/code/Magento/CatalogInventory/Model/Stock.php index a832a2952a2f846dcb99184f78771a245b0ca561..dc0245c89452fd8dce81379db6ced604ce553e9e 100644 --- a/app/code/Magento/CatalogInventory/Model/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Stock.php @@ -49,10 +49,15 @@ class Stock extends \Magento\Framework\Model\AbstractModel const DEFAULT_STOCK_ID = 1; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; + /** + * @var Stock\Status + */ + protected $stockStatus; + /** * Store model manager * @@ -72,13 +77,20 @@ class Stock extends \Magento\Framework\Model\AbstractModel */ protected $_collectionFactory; + /** + * @var \Magento\Catalog\Model\ProductFactory + */ + protected $productFactory; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param Resource\Stock\Item\CollectionFactory $collectionFactory - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + * @param Stock\Status $stockStatus * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param Stock\ItemFactory $stockItemFactory + * @param \Magento\Catalog\Model\ProductFactory $productFactory * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -87,9 +99,11 @@ class Stock extends \Magento\Framework\Model\AbstractModel \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\CatalogInventory\Model\Resource\Stock\Item\CollectionFactory $collectionFactory, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, + \Magento\CatalogInventory\Model\Stock\Status $stockStatus, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\CatalogInventory\Model\Stock\ItemFactory $stockItemFactory, + \Magento\Catalog\Model\ProductFactory $productFactory, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() @@ -98,8 +112,10 @@ class Stock extends \Magento\Framework\Model\AbstractModel $this->_collectionFactory = $collectionFactory; $this->stockItemService = $stockItemService; + $this->stockStatus = $stockStatus; $this->_storeManager = $storeManager; $this->_stockItemFactory = $stockItemFactory; + $this->productFactory = $productFactory; } /** @@ -128,18 +144,20 @@ class Stock extends \Magento\Framework\Model\AbstractModel */ public function addItemsToProducts($productCollection) { - $items = $this->getItemCollection()->addProductsFilter( - $productCollection - )->joinStockStatus( - $productCollection->getStoreId() - )->load(); + $items = $this->getItemCollection()->addProductsFilter($productCollection) + ->joinStockStatus($productCollection->getStoreId()) + ->load(); $stockItems = array(); foreach ($items as $item) { $stockItems[$item->getProductId()] = $item; } foreach ($productCollection as $product) { if (isset($stockItems[$product->getId()])) { - $stockItems[$product->getId()]->assignProduct($product); + $this->stockStatus->assignProduct( + $product, + $stockItems[$product->getId()]->getStockId(), + $product->getStockStatus() + ); } } return $this; @@ -155,6 +173,19 @@ class Stock extends \Magento\Framework\Model\AbstractModel return $this->_collectionFactory->create()->addStockFilter($this->getId()); } + /** + * Get Product type + * + * @param int $productId + * @return string + */ + protected function getProductType($productId) + { + $product = $this->productFactory->create(); + $product->load($productId); + return $product->getTypeId(); + } + /** * Prepare array($productId=>$qty) based on array($productId => array('qty'=>$qty, 'item'=>$stockItem)) * @@ -171,7 +202,7 @@ class Stock extends \Magento\Framework\Model\AbstractModel $stockItem = $item['item']; } $canSubtractQty = $stockItem->getId() && $stockItem->canSubtractQty(); - if ($canSubtractQty && $this->stockItemService->isQty($stockItem->getTypeId())) { + if ($canSubtractQty && $this->stockItemService->isQty($this->getProductType($productId))) { $qtys[$productId] = $item['qty']; } } @@ -240,7 +271,7 @@ class Stock extends \Magento\Framework\Model\AbstractModel } /** @var Item $stockItem */ $stockItem = $this->_stockItemFactory->create()->loadByProduct($productId); - if ($this->stockItemService->isQty($stockItem->getTypeId())) { + if ($this->stockItemService->isQty($this->getProductType($productId))) { if ($item->getStoreId()) { $stockItem->setStoreId($item->getStoreId()); } @@ -263,7 +294,7 @@ class Stock extends \Magento\Framework\Model\AbstractModel { /** @var Item $stockItem */ $stockItem = $this->_stockItemFactory->create()->loadByProduct($productId); - if ($stockItem->getId() && $this->stockItemService->isQty($stockItem->getTypeId())) { + if ($stockItem->getId() && $this->stockItemService->isQty($this->getProductType($productId))) { $stockItem->addQty($qty); if ($stockItem->getCanBackInStock() && $stockItem->getQty() > $stockItem->getMinQty()) { $stockItem->setIsInStock(true)->setStockStatusChangedAutomaticallyFlag(true); diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Stock/Item.php index 0bad5e7727a8f97448958edb4da1cc35068d3697..772335e07bdf6808f17ef70212052c278381a1a3 100644 --- a/app/code/Magento/CatalogInventory/Model/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/Stock/Item.php @@ -131,6 +131,11 @@ class Item extends \Magento\Framework\Model\AbstractModel */ const ENTITY = 'cataloginventory_stock_item'; + /** + * Default stock id + */ + const DEFAULT_STOCK_ID = 1; + /** * @var array */ @@ -179,10 +184,15 @@ class Item extends \Magento\Framework\Model\AbstractModel protected $_catalogInventoryMinsaleqty; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; + /** + * @var \Magento\CatalogInventory\Model\Stock\ItemRegistry + */ + protected $stockItemRegistry; + /** * Core store config * @@ -238,7 +248,8 @@ class Item extends \Magento\Framework\Model\AbstractModel * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Index\Model\Indexer $indexer * @param Status $stockStatus - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + * @param ItemRegistry $stockItemRegistry * @param \Magento\CatalogInventory\Helper\Minsaleqty $catalogInventoryMinsaleqty * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -256,7 +267,8 @@ class Item extends \Magento\Framework\Model\AbstractModel \Magento\Customer\Model\Session $customerSession, \Magento\Index\Model\Indexer $indexer, Status $stockStatus, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, + \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry, \Magento\CatalogInventory\Helper\Minsaleqty $catalogInventoryMinsaleqty, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -274,6 +286,7 @@ class Item extends \Magento\Framework\Model\AbstractModel $this->_indexer = $indexer; $this->_stockStatus = $stockStatus; $this->stockItemService = $stockItemService; + $this->stockItemRegistry = $stockItemRegistry; $this->_catalogInventoryMinsaleqty = $catalogInventoryMinsaleqty; $this->_scopeConfig = $scopeConfig; $this->_storeManager = $storeManager; @@ -301,7 +314,7 @@ class Item extends \Magento\Framework\Model\AbstractModel */ public function getStockId() { - return 1; + return self::DEFAULT_STOCK_ID; } /** @@ -395,26 +408,6 @@ class Item extends \Magento\Framework\Model\AbstractModel return $storeId; } - /** - * Adding stock data to product - * - * @param Product $product - * @return $this - */ - public function assignProduct(Product $product) - { - if (!$this->getId() || !$this->getProductId()) { - $this->_getResource()->loadByProductId($this, $product->getId()); - $this->setOrigData(); - } - - $this->setProduct($product); - $product->setStockItem($this); - $product->setIsInStock($this->getIsInStock()); - $this->_stockStatus->assignProduct($product, $this->getStockId(), $this->getStockStatus()); - return $this; - } - /** * Retrieve minimal quantity available for item status in stock * @@ -902,11 +895,10 @@ class Item extends \Magento\Framework\Model\AbstractModel protected function _beforeSave() { parent::_beforeSave(); - // see if quantity is defined for this item type - $typeId = $this->getTypeId(); - if ($productTypeId = $this->getProductTypeId()) { - $typeId = $productTypeId; - } + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productFactory->create(); + $product->load($this->getProductId()); + $typeId = $product->getTypeId() ? $product->getTypeId() : $this->getTypeId(); $isQty = $this->stockItemService->isQty($typeId); @@ -1039,9 +1031,7 @@ class Item extends \Magento\Framework\Model\AbstractModel foreach ($productsByGroups as $productsInGroup) { $qty = 0; foreach ($productsInGroup as $childProduct) { - if ($childProduct->hasStockItem()) { - $qty += $childProduct->getStockItem()->getStockQty(); - } + $qty += $this->stockItemRegistry->retrieve($childProduct->getId())->getStockQty(); } if (null === $stockQty || $qty < $stockQty) { $stockQty = $qty; diff --git a/app/code/Magento/CatalogInventory/Model/Stock/ItemRegistry.php b/app/code/Magento/CatalogInventory/Model/Stock/ItemRegistry.php index 7f3d7deef5a81f217e3800a84aadc5e53b7c0b6f..0ec4cd4274f79bf0912a8b9fe3689ecf861ecec8 100644 --- a/app/code/Magento/CatalogInventory/Model/Stock/ItemRegistry.php +++ b/app/code/Magento/CatalogInventory/Model/Stock/ItemRegistry.php @@ -61,7 +61,7 @@ class ItemRegistry extends \Magento\Framework\Model\AbstractModel */ public function retrieve($productId) { - if (!isset($this->stockItemRegistry[$productId])) { + if (empty($this->stockItemRegistry[$productId])) { /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ $stockItem = $this->stockItemFactory->create(); @@ -71,4 +71,14 @@ class ItemRegistry extends \Magento\Framework\Model\AbstractModel return $this->stockItemRegistry[$productId]; } + + /** + * @param int $productId + * @return $this + */ + public function erase($productId) + { + $this->stockItemRegistry[$productId] = null; + return $this; + } } diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Stock/Status.php index 747c344d39a93803a3806e2f82c22945752c7227..273029ea2283d1ce2c72fe01406cf9a989f20a4f 100644 --- a/app/code/Magento/CatalogInventory/Model/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/Stock/Status.php @@ -502,12 +502,6 @@ class Status extends \Magento\Framework\Model\AbstractModel } } - /* back compatible stock item */ - foreach ($productCollection as $product) { - $object = new \Magento\Framework\Object(array('is_in_stock' => $product->getData('is_salable'))); - $product->setStockItem($object); - } - return $this; } diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteria.php b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteria.php new file mode 100644 index 0000000000000000000000000000000000000000..9749bd1d0584c020f897130e0f5a890c12ede113 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteria.php @@ -0,0 +1,68 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Low stock criteria data object + */ +class LowStockCriteria extends AbstractObject +{ + /**#@+ + * Stock status object data keys + */ + const QTY = 'qty'; + const PAGE_SIZE = 'page_size'; + const CURRENT_PAGE = 'current_page'; + /**#@-*/ + + /** + * @return float + */ + public function getQty() + { + return $this->_get(self::QTY); + } + + /** + * Get page size + * + * @return int|null + */ + public function getPageSize() + { + return $this->_get(self::PAGE_SIZE); + } + + /** + * Get current page + * + * @return int|null + */ + public function getCurrentPage() + { + return $this->_get(self::CURRENT_PAGE); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteriaBuilder.php b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteriaBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..bd8e901e44b2f9e6f08007ddcaf7b1ad62063dbb --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockCriteriaBuilder.php @@ -0,0 +1,63 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +/** + * Low stock criteria builder + */ +class LowStockCriteriaBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder +{ + /** + * Set page size + * + * @param float $qty + * @return $this + */ + public function setQty($qty) + { + return $this->_set(LowStockCriteria::QTY, $qty); + } + + /** + * Set page size + * + * @param int $pageSize + * @return $this + */ + public function setPageSize($pageSize) + { + return $this->_set(LowStockCriteria::PAGE_SIZE, $pageSize); + } + + /** + * Set current page + * + * @param int $currentPage + * @return $this + */ + public function setCurrentPage($currentPage) + { + return $this->_set(LowStockCriteria::CURRENT_PAGE, $currentPage); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResult.php b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResult.php new file mode 100644 index 0000000000000000000000000000000000000000..9da2be7298291831be4b5659153aca68b55dd1f9 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResult.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Low stock search result data object + */ +class LowStockResult extends AbstractObject +{ + /**#@+ + * Low stock search result object data keys + */ + const PRODUCT_SKU_LIST = 'items'; + const SEARCH_CRITERIA = 'search_criteria'; + const TOTAL_COUNT = 'total_count'; + /**#@-*/ + + /** + * Get items + * + * @return string[] + */ + public function getItems() + { + return is_null($this->_get(self::PRODUCT_SKU_LIST)) ? array() : $this->_get(self::PRODUCT_SKU_LIST); + } + + /** + * Get search criteria + * + * @return \Magento\CatalogInventory\Service\V1\Data\LowStockCriteria + */ + public function getSearchCriteria() + { + return $this->_get(self::SEARCH_CRITERIA); + } + + /** + * Get total count + * + * @return int + */ + public function getTotalCount() + { + return $this->_get(self::TOTAL_COUNT); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResultBuilder.php b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResultBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..1f4e01a9207ef6c2b66e22f80f55c4fd23289dec --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/LowStockResultBuilder.php @@ -0,0 +1,63 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +/** + * Low stock search result builder object + */ +class LowStockResultBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder +{ + /** + * Set search criteria + * + * @param LowStockCriteria $searchCriteria + * @return $this + */ + public function setSearchCriteria(LowStockCriteria $searchCriteria) + { + return $this->_set(LowStockResult::SEARCH_CRITERIA, $searchCriteria); + } + + /** + * Set total count + * + * @param int $totalCount + * @return $this + */ + public function setTotalCount($totalCount) + { + return $this->_set(LowStockResult::TOTAL_COUNT, $totalCount); + } + + /** + * Set items + * + * @param array $items + * @return $this + */ + public function setItems($items) + { + return $this->_set(LowStockResult::PRODUCT_SKU_LIST, $items); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetails.php b/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetails.php new file mode 100644 index 0000000000000000000000000000000000000000..79c275304cf15d56b5c2a13aed06b6f173056fd2 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetails.php @@ -0,0 +1,176 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Stock item details data object + */ +class StockItemDetails extends AbstractObject +{ + /**#@+ + * Stock item object data keys + */ + const QTY = 'qty'; + + const MIN_QTY = 'min_qty'; + + const IS_QTY_DECIMAL = 'is_qty_decimal'; + + const BACKORDERS = 'backorders'; + + const MIN_SALE_QTY = 'min_sale_qty'; + + const MAX_SALE_QTY = 'max_sale_qty'; + + const IS_IN_STOCK = 'is_in_stock'; + + const LOW_STOCK_DATE = 'low_stock_date'; + + const NOTIFY_STOCK_QTY = 'notify_stock_qty'; + + const MANAGE_STOCK = 'manage_stock'; + + const STOCK_STATUS_CHANGED_AUTO = 'stock_status_changed_auto'; + + const QTY_INCREMENTS = 'qty_increments'; + + const ENABLE_QTY_INCREMENTS = 'enable_qty_increments'; + + const IS_DECIMAL_DIVIDED = 'is_decimal_divided'; + /**#@-*/ + + /** + * @return float + */ + public function getQty() + { + return $this->_get(self::QTY); + } + + /** + * @return float + */ + public function getMinQty() + { + return $this->_get(self::MIN_QTY); + } + + /** + * @return bool + */ + public function getIsQtyDecimal() + { + return $this->_get(self::IS_QTY_DECIMAL); + } + + /** + * @return bool + */ + public function isBackorders() + { + return $this->_get(self::BACKORDERS); + } + + /** + * @return float + */ + public function getMinSaleQty() + { + return $this->_get(self::MIN_SALE_QTY); + } + + /** + * @return float + */ + public function getMaxSaleQty() + { + return $this->_get(self::MAX_SALE_QTY); + } + + /** + * @return bool + */ + public function getIsInStock() + { + return $this->_get(self::IS_IN_STOCK); + } + + /** + * @return string + */ + public function getLowStockDate() + { + return $this->_get(self::LOW_STOCK_DATE); + } + + /** + * @return float + */ + public function getNotifyStockQty() + { + return $this->_get(self::NOTIFY_STOCK_QTY); + } + + /** + * @return bool + */ + public function isManageStock() + { + return $this->_get(self::MANAGE_STOCK); + } + + /** + * @return bool + */ + public function isStockStatusChangedAuto() + { + return $this->_get(self::STOCK_STATUS_CHANGED_AUTO); + } + + /** + * @return float + */ + public function getQtyIncrements() + { + return $this->_get(self::QTY_INCREMENTS); + } + + /** + * @return bool + */ + public function isEnableQtyIncrements() + { + return $this->_get(self::ENABLE_QTY_INCREMENTS); + } + + /** + * @return bool + */ + public function getIsDecimalDivided() + { + return $this->_get(self::IS_DECIMAL_DIVIDED); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetailsBuilder.php b/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetailsBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..7ee9ae24a2957952c3ff36979914982eb3b1c784 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/StockItemDetailsBuilder.php @@ -0,0 +1,158 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +/** + * Stock item details data builder + */ +class StockItemDetailsBuilder extends AbstractObjectBuilder +{ + /** + * @param int $qty + * @return $this + */ + public function setQty($qty) + { + return $this->_set(StockItemDetails::QTY, $qty); + } + + /** + * @param int $minQty + * @return $this + */ + public function setMinQty($minQty) + { + return $this->_set(StockItemDetails::MIN_QTY, $minQty); + } + + /** + * @param bool $isQtyDecimal + * @return $this + */ + public function setIsQtyDecimal($isQtyDecimal) + { + return $this->_set(StockItemDetails::IS_QTY_DECIMAL, $isQtyDecimal); + } + + /** + * @param bool $backorders + * @return $this + */ + public function setBackorders($backorders) + { + return $this->_set(StockItemDetails::BACKORDERS, $backorders); + } + + /** + * @param float $minSaleQty + * @return $this + */ + public function setMinSaleQty($minSaleQty) + { + return $this->_set(StockItemDetails::MIN_SALE_QTY, $minSaleQty); + } + + /** + * @param float $maxSaleQty + * @return $this + */ + public function setMaxSaleQty($maxSaleQty) + { + return $this->_set(StockItemDetails::MAX_SALE_QTY, $maxSaleQty); + } + + /** + * @param bool $isInStock + * @return $this + */ + public function setIsInStock($isInStock) + { + return $this->_set(StockItemDetails::IS_IN_STOCK, $isInStock); + } + + /** + * @param string $lowStockDate + * @return $this + */ + public function setLowStockDate($lowStockDate) + { + return $this->_set(StockItemDetails::LOW_STOCK_DATE, $lowStockDate); + } + + /** + * @param float $notifyStockQty + * @return $this + */ + public function setNotifyStockQty($notifyStockQty) + { + return $this->_set(StockItemDetails::NOTIFY_STOCK_QTY, $notifyStockQty); + } + + /** + * @param bool $manageStock + * @return $this + */ + public function setManageStock($manageStock) + { + return $this->_set(StockItemDetails::MANAGE_STOCK, $manageStock); + } + + /** + * @param bool $stockStatusChangedAuto + * @return $this + */ + public function setStockStatusChangedAuto($stockStatusChangedAuto) + { + return $this->_set(StockItemDetails::STOCK_STATUS_CHANGED_AUTO, $stockStatusChangedAuto); + } + + /** + * @param float $qtyIncrements + * @return $this + */ + public function setQtyIncrements($qtyIncrements) + { + return $this->_set(StockItemDetails::QTY_INCREMENTS, $qtyIncrements); + } + + /** + * @param bool $enableQtyIncrements + * @return $this + */ + public function setEnableQtyIncrements($enableQtyIncrements) + { + return $this->_set(StockItemDetails::ENABLE_QTY_INCREMENTS, $enableQtyIncrements); + } + + /** + * @param bool $isDecimalDivided + * @return $this + */ + public function setIsDecimalDivided($isDecimalDivided) + { + return $this->_set(StockItemDetails::IS_DECIMAL_DIVIDED, $isDecimalDivided); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatus.php b/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatus.php new file mode 100644 index 0000000000000000000000000000000000000000..62d942b34a6f45fe14e71b6661e7ba5fc1b237cb --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatus.php @@ -0,0 +1,57 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +/** + * Stock status data object + */ +class StockStatus extends AbstractObject +{ + /**#@+ + * Stock status object data keys + */ + const STOCK_STATUS = 'is_in_stock'; + + const STOCK_QTY = 'qty'; + + /**#@-*/ + + /** + * @return bool + */ + public function getIsInStock() + { + return $this->_get(self::STOCK_STATUS); + } + + /** + * @return int + */ + public function getQty() + { + return $this->_get(self::STOCK_QTY); + } +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatusBuilder.php b/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatusBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..f5c06c0054d038c3e37248794a0983ab2afa9298 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Service/V1/Data/StockStatusBuilder.php @@ -0,0 +1,33 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Service\V1\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +/** + * Stock status data builder + */ +class StockStatusBuilder extends AbstractObjectBuilder +{ +} diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockItem.php b/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php similarity index 75% rename from app/code/Magento/CatalogInventory/Service/V1/StockItem.php rename to app/code/Magento/CatalogInventory/Service/V1/StockItemService.php index c1d1b9cc4c62a5dcec2227beade9adf2aea031ed..10aad3710111f2fe24737aaffa3f5daa7ca75dd9 100644 --- a/app/code/Magento/CatalogInventory/Service/V1/StockItem.php +++ b/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php @@ -23,10 +23,13 @@ */ namespace Magento\CatalogInventory\Service\V1; +use Magento\Catalog\Service\V1\Product\ProductLoader; +use Magento\Framework\Exception\NoSuchEntityException; + /** * Stock item service */ -class StockItem implements StockItemInterface +class StockItemService implements StockItemServiceInterface { /** * @var \Magento\CatalogInventory\Model\Stock\ItemRegistry @@ -50,19 +53,27 @@ class StockItem implements StockItemInterface */ protected $stockItemBuilder; + /** + * @var ProductLoader + */ + protected $productLoader; + /** * @param \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $config * @param Data\StockItemBuilder $stockItemBuilder + * @param ProductLoader $productLoader */ public function __construct( \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry, \Magento\Catalog\Model\ProductTypes\ConfigInterface $config, - Data\StockItemBuilder $stockItemBuilder + Data\StockItemBuilder $stockItemBuilder, + ProductLoader $productLoader ) { $this->stockItemRegistry = $stockItemRegistry; $this->config = $config; $this->stockItemBuilder = $stockItemBuilder; + $this->productLoader = $productLoader; } /** @@ -77,59 +88,54 @@ class StockItem implements StockItemInterface } /** - * @param \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo - * @return $this + * @param string $productSku + * @return \Magento\CatalogInventory\Service\V1\Data\StockItem + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function saveStockItem($stockItemDo) + public function getStockItemBySku($productSku) { - $stockItem = $this->stockItemRegistry->retrieve($stockItemDo->getProductId()); - $stockItem->setData($stockItemDo->__toArray()); - $stockItem->save(); - return $this; + $product = $this->productLoader->load($productSku); + if (!$product->getId()) { + throw new NoSuchEntityException("Product with SKU \"{$productSku}\" does not exist"); + } + $stockItem = $this->stockItemRegistry->retrieve($product->getId()); + $this->stockItemBuilder->populateWithArray($stockItem->getData()); + return $this->stockItemBuilder->create(); } /** - * @param int $productId - * @param int $qty + * @param \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo * @return $this */ - public function subtractQty($productId, $qty) + public function saveStockItem($stockItemDo) { - $stockItem = $this->stockItemRegistry->retrieve($productId); - $stockItem->subtractQty($qty); + $stockItem = $this->stockItemRegistry->retrieve($stockItemDo->getProductId()); + $stockItem->setData($stockItemDo->__toArray()); + $stockItem->save(); + $this->stockItemRegistry->erase($stockItemDo->getProductId()); return $this; } /** - * @param int $productId - * @return bool + * @param string $productSku + * @param \Magento\CatalogInventory\Service\V1\Data\StockItemDetails $stockItemDetailsDo + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function canSubtractQty($productId) + public function saveStockItemBySku($productSku, Data\StockItemDetails $stockItemDetailsDo) { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->canSubtractQty(); - } - - /** - * @param int $productId - * @param int $qty - * @return $this - */ - public function addQty($productId, $qty) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - $stockItem->addQty($qty); - return $this; - } + $product = $this->productLoader->load($productSku); + if (!$product->getId()) { + throw new NoSuchEntityException("Product with SKU \"{$productSku}\" does not exist"); + } - /** - * @param int $productId - * @return int - */ - public function getMinQty($productId) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->getMinQty(); + $stockItem = $this->stockItemRegistry->retrieve($product->getId()); + $stockItemDo = $this->stockItemBuilder->populateWithArray($stockItem->getData())->create(); + $dataToSave = $this->stockItemBuilder->mergeDataObjectWithArray( + $stockItemDo, + $stockItemDetailsDo->__toArray() + )->__toArray(); + return $stockItem->setData($dataToSave)->save()->getId(); } /** @@ -152,16 +158,6 @@ class StockItem implements StockItemInterface return $stockItem->getMaxSaleQty(); } - /** - * @param int $productId - * @return float - */ - public function getNotifyStockQty($productId) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->getNotifyStockQty(); - } - /** * @param int $productId * @return bool @@ -182,16 +178,6 @@ class StockItem implements StockItemInterface return $stockItem->getQtyIncrements(); } - /** - * @param int $productId - * @return int - */ - public function getBackorders($productId) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->getBackorders(); - } - /** * @param int $productId * @return int @@ -202,27 +188,6 @@ class StockItem implements StockItemInterface return $stockItem->getManageStock(); } - /** - * @param int $productId - * @return bool - */ - public function getCanBackInStock($productId) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->getCanBackInStock(); - } - - /** - * @param int $productId - * @param int $qty - * @return bool - */ - public function checkQty($productId, $qty) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->checkQty($qty); - } - /** * @param int $productId * @param int $qty @@ -289,17 +254,6 @@ class StockItem implements StockItemInterface return $stockItem->getStockQty(); } - /** - * @param int $productId - * @param int $qty - * @return \Magento\Framework\Object - */ - public function checkQtyIncrements($productId, $qty) - { - $stockItem = $this->stockItemRegistry->retrieve($productId); - return $stockItem->checkQtyIncrements($qty); - } - /** * @param int $productTypeId * @return bool @@ -315,7 +269,7 @@ class StockItem implements StockItemInterface /** * @param int|null $filter - * @return bool + * @return bool|array */ public function getIsQtyTypeIds($filter = null) { diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockItemInterface.php b/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php similarity index 73% rename from app/code/Magento/CatalogInventory/Service/V1/StockItemInterface.php rename to app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php index fa2d737de7a36f8dd5b8997f1d77a5b4d6513cad..f99ff0a56d919b2cd0cc3fe6530246066b6cc703 100644 --- a/app/code/Magento/CatalogInventory/Service/V1/StockItemInterface.php +++ b/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php @@ -26,7 +26,7 @@ namespace Magento\CatalogInventory\Service\V1; /** * Stock item interface */ -interface StockItemInterface +interface StockItemServiceInterface { /** * @param int $productId @@ -35,36 +35,25 @@ interface StockItemInterface public function getStockItem($productId); /** - * @param \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItem + * @param string $productSku * @return \Magento\CatalogInventory\Service\V1\Data\StockItem + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function saveStockItem($stockItem); - - /** - * @param int $productId - * @param int $qty - * @return $this - */ - public function subtractQty($productId, $qty); - - /** - * @param int $productId - * @return bool - */ - public function canSubtractQty($productId); + public function getStockItemBySku($productSku); /** - * @param int $productId - * @param int $qty - * @return $this + * @param \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItem + * @return \Magento\CatalogInventory\Service\V1\Data\StockItem */ - public function addQty($productId, $qty); + public function saveStockItem($stockItem); /** - * @param int $productId - * @return int + * @param string $productSku + * @param \Magento\CatalogInventory\Service\V1\Data\StockItemDetails $stockItemDetailsDo + * @return string + * @throws \Magento\Framework\Exception\NoSuchEntityException */ - public function getMinQty($productId); + public function saveStockItemBySku($productSku, Data\StockItemDetails $stockItemDetailsDo); /** * @param int $productId @@ -78,12 +67,6 @@ interface StockItemInterface */ public function getMaxSaleQty($productId); - /** - * @param int $productId - * @return int - */ - public function getNotifyStockQty($productId); - /** * @param int $productId * @return bool @@ -96,31 +79,12 @@ interface StockItemInterface */ public function getQtyIncrements($productId); - /** - * @param int $productId - * @return int - */ - public function getBackorders($productId); - /** * @param int $productId * @return int mixed */ public function getManageStock($productId); - /** - * @param int $productId - * @return bool - */ - public function getCanBackInStock($productId); - - /** - * @param int $productId - * @param int $qty - * @return bool - */ - public function checkQty($productId, $qty); - /** * @param int $productId * @param int $qty @@ -163,13 +127,6 @@ interface StockItemInterface */ public function getStockQty($productId); - /** - * @param int $productId - * @param int $qty - * @return bool - */ - public function checkQtyIncrements($productId, $qty); - /** * @param int $productTypeId * @return bool diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockStatusService.php b/app/code/Magento/CatalogInventory/Service/V1/StockStatusService.php index 9457bc59849b85958ac93659aa89ad2497d3dc65..c4fbbec8f3cf73b1fb305ccc56fe693c5126d9a1 100644 --- a/app/code/Magento/CatalogInventory/Service/V1/StockStatusService.php +++ b/app/code/Magento/CatalogInventory/Service/V1/StockStatusService.php @@ -25,6 +25,7 @@ namespace Magento\CatalogInventory\Service\V1; use Magento\CatalogInventory\Model\Stock; use Magento\CatalogInventory\Model\Stock\Status; +use Magento\Framework\Exception\NoSuchEntityException; /** * Service related to Product Stock Status @@ -36,19 +37,141 @@ class StockStatusService implements StockStatusServiceInterface */ protected $stockStatus; + /** + * @var \Magento\Store\Model\Resolver\Website + */ + protected $scopeResolver; + + /** + * @var \Magento\Catalog\Service\V1\Product\ProductLoader + */ + protected $productLoader; + + /** + * @var StockItemService + */ + protected $stockItemService; + + /** + * @var Data\StockStatusBuilder + */ + protected $stockStatusBuilder; + + /** + * @var \Magento\CatalogInventory\Model\Resource\Stock\Status\CollectionFactory + */ + protected $itemsFactory; + + /** + * @var Data\LowStockResultBuilder + */ + protected $lowStockResultBuilder; + /** * @param Status $stockStatus + * @param StockItemService $stockItemService + * @param \Magento\Catalog\Service\V1\Product\ProductLoader $productLoader + * @param \Magento\Store\Model\Resolver\Website $scopeResolver + * @param Data\StockStatusBuilder $stockStatusBuilder + * @param \Magento\CatalogInventory\Model\Resource\Stock\Status\CollectionFactory $itemsFactory + * @param Data\LowStockResultBuilder $lowStockResultBuilder */ - public function __construct(Status $stockStatus) - { + public function __construct( + Status $stockStatus, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, + \Magento\Catalog\Service\V1\Product\ProductLoader $productLoader, + \Magento\Store\Model\Resolver\Website $scopeResolver, + Data\StockStatusBuilder $stockStatusBuilder, + \Magento\CatalogInventory\Model\Resource\Stock\Status\CollectionFactory $itemsFactory, + Data\LowStockResultBuilder $lowStockResultBuilder + ) { $this->stockStatus = $stockStatus; + $this->stockItemService = $stockItemService; + $this->productLoader = $productLoader; + $this->scopeResolver = $scopeResolver; + $this->stockStatusBuilder = $stockStatusBuilder; + $this->itemsFactory = $itemsFactory; + $this->lowStockResultBuilder = $lowStockResultBuilder; } /** * {@inheritdoc} */ - public function getProductStockStatus($productIds, $websiteId, $stockId = Stock::DEFAULT_STOCK_ID) + public function getProductStockStatus($productId, $websiteId, $stockId = Stock::DEFAULT_STOCK_ID) { - return $this->stockStatus->getProductStockStatus($productIds, $websiteId, $stockId); + $stockStatusData = $this->stockStatus->getProductStockStatus([$productId], $websiteId, $stockId); + $stockStatus = empty($stockStatusData[$productId]) ? null : $stockStatusData[$productId]; + + return $stockStatus; + } + + /** + * Assign Stock Status to Product + * + * @param \Magento\Catalog\Model\Product $product + * @param int $stockId + * @param int $stockStatus + * @return \Magento\CatalogInventory\Service\V1\StockStatusService + */ + public function assignProduct( + \Magento\Catalog\Model\Product $product, + $stockId = Stock::DEFAULT_STOCK_ID, + $stockStatus = null + ) { + $this->stockStatus->assignProduct($product, $stockId, $stockStatus); + return $this; + } + + /** + * {inheritdoc} + */ + public function getProductStockStatusBySku($sku) + { + $product = $this->productLoader->load($sku); + $productId = $product->getId(); + if (!$productId) { + throw new NoSuchEntityException("Product with SKU \"{$sku}\" does not exist"); + } + + $data = $this->stockStatus->getProductStockStatus( + [$productId], + $this->scopeResolver->getScope()->getId() + ); + $stockStatus = (bool)$data[$productId]; + + $result = [ + Data\StockStatus::STOCK_STATUS => $stockStatus, + Data\StockStatus::STOCK_QTY => $this->stockItemService->getStockQty($productId) + ]; + + $this->stockStatusBuilder->populateWithArray($result); + + return $this->stockStatusBuilder->create(); + } + + /** + * Retrieves a list of SKU's with low inventory qty + * + * {@inheritdoc} + */ + public function getLowStockItems($lowStockCriteria) + { + /** @var \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection $itemCollection */ + $itemCollection = $this->itemsFactory->create(); + $itemCollection->addWebsiteFilter($this->scopeResolver->getScope()); + $itemCollection->addQtyFilter($lowStockCriteria->getQty()); + $itemCollection->setCurPage($lowStockCriteria->getCurrentPage()); + $itemCollection->setPageSize($lowStockCriteria->getPageSize()); + + $countOfItems = $itemCollection->getSize(); + $listOfSku = []; + foreach ($itemCollection as $item) { + $listOfSku[] = $item->getSku(); + } + + $this->lowStockResultBuilder->setSearchCriteria($lowStockCriteria); + $this->lowStockResultBuilder->setTotalCount($countOfItems); + $this->lowStockResultBuilder->setItems($listOfSku); + return $this->lowStockResultBuilder->create(); } } diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockStatusServiceInterface.php b/app/code/Magento/CatalogInventory/Service/V1/StockStatusServiceInterface.php index 30214e24014f84650f9bb1517c12798dc81ef86d..95fca6c21a104675345e41d408646cd8776bbb63 100644 --- a/app/code/Magento/CatalogInventory/Service/V1/StockStatusServiceInterface.php +++ b/app/code/Magento/CatalogInventory/Service/V1/StockStatusServiceInterface.php @@ -33,10 +33,25 @@ interface StockStatusServiceInterface /** * Retrieve Product Stock Status * - * @param int[] $productIds + * @param int $productId * @param int $websiteId * @param int $stockId * @return array */ - public function getProductStockStatus($productIds, $websiteId, $stockId = Stock::DEFAULT_STOCK_ID); + public function getProductStockStatus($productId, $websiteId, $stockId = Stock::DEFAULT_STOCK_ID); + + /** + * @param string $sku + * @return \Magento\CatalogInventory\Service\V1\Data\StockStatus + * @throw \Magento\Framework\Exception\NoSuchEntityException + */ + public function getProductStockStatusBySku($sku); + + /** + * Retrieves a list of SKU's with low inventory qty + * + * @param \Magento\CatalogInventory\Service\V1\Data\LowStockCriteria $lowStockCriteria + * @return \Magento\CatalogInventory\Service\V1\Data\LowStockResult contains string[] + */ + public function getLowStockItems($lowStockCriteria); } diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml index bad18e477cf54c66ddac909dd55ccdcfb26fb099..1d3ac028b4b723200a0dfa8061982d3c6bd424ed 100644 --- a/app/code/Magento/CatalogInventory/etc/di.xml +++ b/app/code/Magento/CatalogInventory/etc/di.xml @@ -25,6 +25,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> <preference for="Magento\CatalogInventory\Service\V1\StockStatusServiceInterface" type="Magento\CatalogInventory\Service\V1\StockStatusService" /> + <preference for="Magento\CatalogInventory\Service\V1\StockItemServiceInterface" type="Magento\CatalogInventory\Service\V1\StockItemService" /> <type name="Magento\CatalogInventory\Model\Observer"> <arguments> <argument name="resourceIndexerStock" xsi:type="object">Magento\CatalogInventory\Model\Resource\Indexer\Stock\Proxy</argument> diff --git a/app/code/Magento/CatalogInventory/etc/events.xml b/app/code/Magento/CatalogInventory/etc/events.xml index e1ec586ba12eff7b22317f8238c459ccd6b71bd5..e68c5c32c5301e95c5741324a86991dbfb7d9183 100644 --- a/app/code/Magento/CatalogInventory/etc/events.xml +++ b/app/code/Magento/CatalogInventory/etc/events.xml @@ -30,9 +30,6 @@ <event name="catalog_product_load_after"> <observer name="inventory" instance="Magento\CatalogInventory\Model\Observer" method="addInventoryData" /> </event> - <event name="catalog_product_clear"> - <observer name="inventory" instance="Magento\CatalogInventory\Model\Observer" method="removeInventoryData" /> - </event> <event name="catalog_product_collection_load_after"> <observer name="inventory" instance="Magento\CatalogInventory\Model\Observer" method="addStockStatusToCollection" /> </event> diff --git a/app/code/Magento/CatalogInventory/etc/webapi.xml b/app/code/Magento/CatalogInventory/etc/webapi.xml new file mode 100644 index 0000000000000000000000000000000000000000..de443919ca730e49350c997a39c913a9e12ea34e --- /dev/null +++ b/app/code/Magento/CatalogInventory/etc/webapi.xml @@ -0,0 +1,53 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd"> + <route url="/V1/stockItem/:productSku" method="GET"> + <service class="Magento\CatalogInventory\Service\V1\StockItemServiceInterface" method="getStockItemBySku"/> + <resources> + <resource ref="Magento_CatalogInventory::cataloginventory"/> + </resources> + </route> + <route url="/V1/stockItem/:productSku" method="POST"> + <service class="Magento\CatalogInventory\Service\V1\StockItemServiceInterface" method="saveStockItemBySku"/> + <resources> + <resource ref="Magento_CatalogInventory::cataloginventory"/> + </resources> + </route> + <route url="/V1/stockItem/status/:sku" method="GET"> + <service class="Magento\CatalogInventory\Service\V1\StockStatusServiceInterface" + method="getProductStockStatusBySku"/> + <resources> + <resource ref="Magento_CatalogInventory::cataloginventory"/> + </resources> + </route> + <route url="/V1/stockItem/lowStock/" method="PUT"> + <service class="Magento\CatalogInventory\Service\V1\StockStatusServiceInterface" method="getLowStockItems"/> + <resources> + <resource ref="Magento_CatalogInventory::cataloginventory"/> + </resources> + </route> +</routes> diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php index 487e127dd3d3c4502fb6f565cf801443013a292b..aa41d5983ac2ab87deba70838877885f568830f7 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php @@ -127,7 +127,7 @@ class Widget extends Action )->setCategoryIds( array($categoryId) ); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $block->getTreeJson($category) ); } diff --git a/app/code/Magento/CatalogSearch/Controller/Ajax.php b/app/code/Magento/CatalogSearch/Controller/Ajax.php index dcddb02ece0b4fff661b8bc709cb6d53336523e9..319fb28ed17e76f082e03b6728672da256d815ba 100644 --- a/app/code/Magento/CatalogSearch/Controller/Ajax.php +++ b/app/code/Magento/CatalogSearch/Controller/Ajax.php @@ -43,6 +43,6 @@ class Ajax extends Action } $suggestData = $this->_objectManager->get('Magento\CatalogSearch\Helper\Data')->getSuggestData(); - $this->getResponse()->setHeader('Content-type', 'application/json', true)->setBody(json_encode($suggestData)); + $this->getResponse()->representJson(json_encode($suggestData)); } } diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php index fb010b723c4e2464c8c1b08dbbcba59fcba5e7f8..54f37d367e8c59e53a1c605d7da46cc258f8675c 100644 --- a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php +++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php @@ -71,7 +71,9 @@ class Index extends \Magento\Backend\App\Action $this->_objectManager->get('Magento\Framework\Logger')->logException($e); $result['message'] = __('Validation failed.'); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Checkout/Controller/Onepage.php b/app/code/Magento/Checkout/Controller/Onepage.php index e2bec519374b558d0d5506f57f31ab37f13ffb55..6e3c6b7b7b8ad77e2b0f9de4807f5259d603214f 100755 --- a/app/code/Magento/Checkout/Controller/Onepage.php +++ b/app/code/Magento/Checkout/Controller/Onepage.php @@ -344,7 +344,9 @@ class Onepage extends Action if ($this->getRequest()->isPost()) { $method = $this->getRequest()->getPost('method'); $result = $this->getOnepage()->saveCheckoutMethod($method); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -388,7 +390,9 @@ class Onepage extends Action } } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -414,7 +418,9 @@ class Onepage extends Action 'html' => $this->_getShippingMethodsHtml() ); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -438,7 +444,7 @@ class Onepage extends Action array('request' => $this->getRequest(), 'quote' => $this->getOnepage()->getQuote()) ); $this->getOnepage()->getQuote()->collectTotals(); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) ); @@ -449,7 +455,9 @@ class Onepage extends Action ); } $this->getOnepage()->getQuote()->collectTotals()->save(); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -494,7 +502,9 @@ class Onepage extends Action $this->_objectManager->get('Magento\Framework\Logger')->logException($e); $result['error'] = __('Unable to set Payment Method'); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -564,7 +574,7 @@ class Onepage extends Action $result['error_messages'] = __( 'Please agree to all the terms and conditions before placing the order.' ); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) ); return; @@ -643,7 +653,9 @@ class Onepage extends Action $result['redirect'] = $redirectUrl; } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php index 6e08d5989b41ae4eba70b780cc1a97699a171296..5b9813aa09c9661c1749eadd4a615d6dca31d509 100644 --- a/app/code/Magento/Checkout/Model/Cart.php +++ b/app/code/Magento/Checkout/Model/Cart.php @@ -89,7 +89,7 @@ class Cart extends \Magento\Framework\Object implements \Magento\Checkout\Model\ protected $messageManager; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; @@ -102,7 +102,7 @@ class Cart extends \Magento\Framework\Object implements \Magento\Checkout\Model\ * @param Session $checkoutSession * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Framework\Message\ManagerInterface $messageManager - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( @@ -114,7 +114,7 @@ class Cart extends \Magento\Framework\Object implements \Magento\Checkout\Model\ Session $checkoutSession, \Magento\Customer\Model\Session $customerSession, \Magento\Framework\Message\ManagerInterface $messageManager, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_eventManager = $eventManager; diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php index 2bb5d511fe5355654e4cd8a5990a4cd5ddb70b0e..c572f8794fbffa1b24c3d54a183783a01961eca7 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php @@ -90,14 +90,16 @@ class Images extends \Magento\Backend\App\Action { try { $this->_initAction(); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_view->getLayout()->createBlock( 'Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Tree' )->getTreeJson() ); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -114,7 +116,9 @@ class Images extends \Magento\Backend\App\Action $this->_view->renderLayout(); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -133,7 +137,9 @@ class Images extends \Magento\Backend\App\Action } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -148,7 +154,9 @@ class Images extends \Magento\Backend\App\Action $this->getStorage()->deleteDirectory($path); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -180,7 +188,9 @@ class Images extends \Magento\Backend\App\Action } } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -198,7 +208,9 @@ class Images extends \Magento\Backend\App\Action } catch (\Exception $e) { $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode()); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php index 3425fda9d527b7dd26b49ce5e2b283dd9d3df0e4..74bb63b1fa1c651d50805d03f5cc99c6b78f5013 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php @@ -58,6 +58,11 @@ class Matrix extends \Magento\Backend\Block\Template */ protected $_localeCurrency; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemServiceInterface + */ + protected $stockItemService; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType @@ -65,6 +70,7 @@ class Matrix extends \Magento\Backend\Block\Template * @param \Magento\Catalog\Model\ProductFactory $productFactory * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency + * @param \Magento\CatalogInventory\Service\V1\StockItemServiceInterface $stockItemService * @param array $data */ public function __construct( @@ -74,6 +80,7 @@ class Matrix extends \Magento\Backend\Block\Template \Magento\Catalog\Model\ProductFactory $productFactory, \Magento\Framework\Registry $coreRegistry, \Magento\Framework\Locale\CurrencyInterface $localeCurrency, + \Magento\CatalogInventory\Service\V1\StockItemServiceInterface $stockItemService, array $data = array() ) { $this->_configurableType = $configurableType; @@ -81,6 +88,7 @@ class Matrix extends \Magento\Backend\Block\Template $this->_config = $config; $this->_coreRegistry = $coreRegistry; $this->_localeCurrency = $localeCurrency; + $this->stockItemService = $stockItemService; parent::__construct($context, $data); } @@ -287,4 +295,13 @@ class Matrix extends \Magento\Backend\Block\Template { return $this->getUrl('catalog/product_gallery/upload'); } + + /** + * @param int $productId + * @return float + */ + public function getProductStockQty($productId) + { + return $this->stockItemService->getStockItem($productId)->getQty(); + } } diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php index 676dbc3aee039814247a4f554e88da8a92f813bd..e6f5549ad2f7680583ef59c84a5b0ed96bd72167 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php @@ -71,7 +71,7 @@ class SuggestConfigurableAttributes extends Action */ public function indexAction() { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->coreHelper->jsonEncode( $this->attributeList->getSuggestedAttributes($this->getRequest()->getParam('label_part')) ) diff --git a/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php b/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php index 6cb61684da9bb67d8145f2b6581e127e6b229f17..a1a12127f1e1d4f98ee7ee0d2118c7b3726562d2 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php +++ b/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php @@ -31,24 +31,23 @@ class ConfigurableProduct * Initialize stock item for configurable product type * * @param \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option $subject + * @param callable $proceed * @param \Magento\Sales\Model\Quote\Item\Option $option * @param \Magento\Sales\Model\Quote\Item $quoteItem - * @param int $qty * - * @return void + * @return \Magento\CatalogInventory\Model\Stock\Item * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function beforeInitialize( + public function aroundGetStockItem( \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option $subject, + \Closure $proceed, \Magento\Sales\Model\Quote\Item\Option $option, - \Magento\Sales\Model\Quote\Item $quoteItem, - $qty + \Magento\Sales\Model\Quote\Item $quoteItem ) { - /* @var $stockItem \Magento\CatalogInventory\Model\Stock\Item */ - $stockItem = $option->getProduct()->getStockItem(); - + $stockItem = $proceed($option, $quoteItem); if ($quoteItem->getProductType() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) { $stockItem->setProductName($quoteItem->getName()); } + return $stockItem; } } diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml index 249759260aef72f8203c5c3b9f4f62e52f9f78fb..1dddc29458c3a9278dbedc92ea8fc1186184c49f 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml @@ -131,7 +131,7 @@ $productByUsedAttributes = $this->getAssociatedProducts(); <td class="col-price" data-column="price"> <?php echo $this->renderPrice($price);?> </td> - <td class="col-qty" data-column="qty"><?php echo $product->getStockItem()->getQty()?></td> + <td class="col-qty" data-column="qty"><?php echo $this->getProductStockQty($product->getId()) ?></td> <td class="col-weight" data-column="weight"><?php echo $product->getWeight()?></td> <?php foreach ($usedProductAttributes as $attribute) { diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Index.php index 7a07a12c9b66bf90c0390f4686c9ff1a8814720b..3f943deeb082b92468369137f575ede1bdaa8ecd 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index.php @@ -793,7 +793,7 @@ class Index extends \Magento\Backend\App\Action $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** diff --git a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php index 3e3b0bd1d9443363c2b6b96c887d89aced9448d2..0c45c2ec434c0e6424b6ff76e06c5cc02b16913a 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php @@ -85,6 +85,6 @@ class Validatevat extends \Magento\Backend\App\Action ); $body = $coreHelper->jsonEncode(array('valid' => $valid, 'group' => $groupId, 'success' => $success)); - $this->getResponse()->setBody($body); + $this->getResponse()->representJson($body); } } diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php index 212faed41bebd4c7610d2b1f305bda17b1873e12..c3be7c77fd320c8ab764afda9f5852f8527d7d3f 100644 --- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php +++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php @@ -108,7 +108,7 @@ class Editor extends \Magento\Backend\App\Action $this->_objectManager->get('Magento\Framework\Logger')->logException($e); $response = array('error' => __('Sorry, but we can\'t load the theme list.')); } - $this->getResponse()->setBody($coreHelper->jsonEncode($response)); + $this->getResponse()->representJson($coreHelper->jsonEncode($response)); } /** @@ -204,12 +204,9 @@ class Editor extends \Magento\Backend\App\Action $response = array('message' => $successMessage, 'themeId' => $themeCustomization->getId()); } catch (\Exception $e) { $this->_objectManager->get('Magento\Framework\Logger')->logException($e); - $this->getResponse()->setBody( - $coreHelper->jsonEncode(array('error' => __('This theme is not assigned.'))) - ); $response = array('error' => true, 'message' => __('This theme is not assigned.')); } - $this->getResponse()->setBody($coreHelper->jsonEncode($response)); + $this->getResponse()->representJson($coreHelper->jsonEncode($response)); } /** @@ -239,7 +236,7 @@ class Editor extends \Magento\Backend\App\Action $this->_objectManager->get('Magento\Framework\Logger')->logException($e); $response = array('error' => true, 'message' => __('This theme is not saved.')); } - $this->getResponse()->setBody($coreHelper->jsonEncode($response)); + $this->getResponse()->representJson($coreHelper->jsonEncode($response)); } /** @@ -281,7 +278,7 @@ class Editor extends \Magento\Backend\App\Action /** @var $coreHelper \Magento\Core\Helper\Data */ $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data'); - $this->getResponse()->setBody($coreHelper->jsonEncode($response)); + $this->getResponse()->representJson($coreHelper->jsonEncode($response)); } /** @@ -359,7 +356,7 @@ class Editor extends \Magento\Backend\App\Action } /** @var $coreHelper \Magento\Core\Helper\Data */ $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data'); - $this->getResponse()->setBody($coreHelper->jsonEncode($response)); + $this->getResponse()->representJson($coreHelper->jsonEncode($response)); } /** diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php index 6698e14fd5e0e895079919e0f172c2e900b83651..5024da14ad9981dbf0b0c7026811cd938039c5ed 100644 --- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php +++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php @@ -36,7 +36,7 @@ class Files extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Fi public function treeJsonAction() { try { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_view->getLayout()->createBlock( 'Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Files\Tree' )->getTreeJson( @@ -45,7 +45,9 @@ class Files extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Fi ); } catch (\Exception $e) { $this->_objectManager->get('Magento\Framework\Logger')->logException($e); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array()) + ); } } @@ -66,7 +68,9 @@ class Files extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Fi ); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } } diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php index 9e2ba5c8dc3435a447adc22ee06d92168ec94f68..bacd1b8d584651dcd394552babe00c12accc6f11 100644 --- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php +++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php @@ -80,7 +80,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => __('We cannot upload the CSS file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -114,7 +116,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => __('We can\'t save the custom css file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -130,7 +134,9 @@ class Tools extends \Magento\Backend\App\Action $customization = $editableTheme->getCustomization(); $customJsFiles = $customization->getFilesByType(\Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE); $result = array('error' => false, 'files' => $customization->generateFileInfo($customJsFiles)); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } catch (\Exception $e) { $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } @@ -165,7 +171,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => __('We cannot upload the JS file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -210,7 +218,9 @@ class Tools extends \Magento\Backend\App\Action $result = array('error' => true, 'message' => __('We cannot upload the CSS file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -244,7 +254,9 @@ class Tools extends \Magento\Backend\App\Action $result = array('error' => true, 'message' => __('We can\'t save image sizes.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -286,7 +298,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => $errorMessage); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -330,7 +344,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => $errorMessage); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -377,7 +393,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => $errorMessage); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -430,7 +448,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => $errorMessage); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** @@ -464,7 +484,9 @@ class Tools extends \Magento\Backend\App\Action $response = array('error' => true, 'message' => $errorMessage); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); } /** diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 0022a288e52e037984e797017e2bf8c3550db0b6..6b24d9a09baf9e27332d158fd03a36059c3fae78 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -28,25 +28,26 @@ use Magento\Sales\Model\Quote\Address\RateRequest; use Magento\Sales\Model\Quote\Address\RateResult\Error; use Magento\Shipping\Model\Carrier\AbstractCarrier; use Magento\Shipping\Model\Rate\Result; +use Magento\Catalog\Model\Product\Type; /** * DHL International (API v1.4) */ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shipping\Model\Carrier\CarrierInterface { - /** + /**#@+ * Carrier Product indicator */ const DHL_CONTENT_TYPE_DOC = 'D'; - const DHL_CONTENT_TYPE_NON_DOC = 'N'; + /**#@-*/ - /** + /**#@+ * Minimum allowed values for shipping package dimensions */ const DIMENSION_MIN_CM = 3; - const DIMENSION_MIN_IN = 1; + /**#@-*/ /** * Container types that could be customized @@ -65,21 +66,21 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin * * @var RateRequest|null */ - protected $_request = null; + protected $_request; /** * Rate result data * * @var Result|null */ - protected $_result = null; + protected $_result; /** * Countries parameters data * * @var \Magento\Shipping\Model\Simplexml\Element|null */ - protected $_countryParams = null; + protected $_countryParams; /** * Errors placeholder @@ -198,6 +199,11 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin */ protected $_httpClientFactory; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory @@ -221,6 +227,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin * @param \Magento\Framework\App\Filesystem $filesystem * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( @@ -237,6 +244,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Shipping\Helper\Carrier $carrierHelper, \Magento\Framework\Stdlib\DateTime\DateTime $coreDate, \Magento\Framework\Module\Dir\Reader $configReader, @@ -257,6 +265,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $this->mathDivision = $mathDivision; $this->_dateTime = $dateTime; $this->_httpClientFactory = $httpClientFactory; + $this->stockItemService = $stockItemService; parent::__construct( $scopeConfig, $rateErrorFactory, @@ -271,6 +280,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $countryFactory, $currencyFactory, $directoryData, + $stockItemService, $data ); if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_DOC) { @@ -322,21 +332,14 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $origCity = $this->_getDefaultValue($requestDhl->getOrigCity(), Shipment::XML_PATH_STORE_CITY); $origPostcode = $this->_getDefaultValue($requestDhl->getOrigPostcode(), Shipment::XML_PATH_STORE_ZIP); - $requestDhl->setOrigCompanyName( - $origCompanyName - )->setCountryId( - $origCountryId - )->setOrigState( - $origState - )->setOrigCity( - $origCity - )->setOrigPostal( - $origPostcode - ); + $requestDhl->setOrigCompanyName($origCompanyName) + ->setCountryId($origCountryId) + ->setOrigState($origState) + ->setOrigCity($origCity) + ->setOrigPostal($origPostcode); $this->setRequest($requestDhl); $this->_result = $this->_getQuotes(); - $this->_updateFreeMethodQuote($request); return $this->_result; @@ -350,12 +353,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin */ protected function _setFreeMethodRequest($freeMethod) { - $rawRequest = $this->_rawRequest; - - $rawRequest->setFreeMethodRequest(true); - $freeWeight = $this->getTotalNumOfBoxes($rawRequest->getFreeMethodWeight()); - $rawRequest->setWeight($freeWeight); - $rawRequest->setService($freeMethod); + $this->_rawRequest->setFreeMethodRequest(true); + $freeWeight = $this->getTotalNumOfBoxes($this->_rawRequest->getFreeMethodWeight()); + $this->_rawRequest->setWeight($freeWeight); + $this->_rawRequest->setService($freeMethod); } /** @@ -376,10 +377,9 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin */ protected function _addParams(\Magento\Framework\Object $requestObject) { - $request = $this->_request; foreach ($this->_requestVariables as $code => $objectCode) { - if ($request->getDhlId()) { - $value = $request->getData($objectCode['code']); + if ($this->_request->getDhlId()) { + $value = $this->_request->getData($objectCode['code']); } else { $value = $this->getConfigData($code); } @@ -423,45 +423,29 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $shippingWeight = $request->getPackageWeight(); - $requestObject->setValue( - round($request->getPackageValue(), 2) - )->setValueWithDiscount( - $request->getPackageValueWithDiscount() - )->setCustomsValue( - $request->getPackageCustomsValue() - )->setDestStreet( - $this->string->substr(str_replace("\n", '', $request->getDestStreet()), 0, 35) - )->setDestStreetLine2( - $request->getDestStreetLine2() - )->setDestCity( - $request->getDestCity() - )->setOrigCompanyName( - $request->getOrigCompanyName() - )->setOrigCity( - $request->getOrigCity() - )->setOrigPhoneNumber( - $request->getOrigPhoneNumber() - )->setOrigPersonName( - $request->getOrigPersonName() - )->setOrigEmail( - $this->_scopeConfig->getValue( - 'trans_email/ident_general/email', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, - $requestObject->getStoreId() + $requestObject->setValue(round($request->getPackageValue(), 2)) + ->setValueWithDiscount($request->getPackageValueWithDiscount()) + ->setCustomsValue($request->getPackageCustomsValue()) + ->setDestStreet($this->string->substr(str_replace("\n", '', $request->getDestStreet()), 0, 35)) + ->setDestStreetLine2($request->getDestStreetLine2()) + ->setDestCity($request->getDestCity()) + ->setOrigCompanyName($request->getOrigCompanyName()) + ->setOrigCity($request->getOrigCity()) + ->setOrigPhoneNumber($request->getOrigPhoneNumber()) + ->setOrigPersonName($request->getOrigPersonName()) + ->setOrigEmail( + $this->_scopeConfig->getValue( + 'trans_email/ident_general/email', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $requestObject->getStoreId() + ) ) - )->setOrigCity( - $request->getOrigCity() - )->setOrigPostal( - $request->getOrigPostal() - )->setOrigStreetLine2( - $request->getOrigStreetLine2() - )->setDestPhoneNumber( - $request->getDestPhoneNumber() - )->setDestPersonName( - $request->getDestPersonName() - )->setDestCompanyName( - $request->getDestCompanyName() - ); + ->setOrigCity($request->getOrigCity()) + ->setOrigPostal($request->getOrigPostal()) + ->setOrigStreetLine2($request->getOrigStreetLine2()) + ->setDestPhoneNumber($request->getDestPhoneNumber()) + ->setDestPersonName($request->getDestPersonName()) + ->setDestCompanyName($request->getDestCompanyName()); $originStreet2 = $this->_scopeConfig->getValue( Shipment::XML_PATH_STORE_ADDRESS2, @@ -485,23 +469,17 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin // for DHL, Puerto Rico state for US will assume as Puerto Rico country // for Puerto Rico, dhl will ship as international - if ($destCountry == self::USA_COUNTRY_ID && ($request->getDestPostcode() == '00912' || - $request->getDestRegionCode() == self::PUERTORICO_COUNTRY_ID) + if ($destCountry == self::USA_COUNTRY_ID + && ($request->getDestPostcode() == '00912' || $request->getDestRegionCode() == self::PUERTORICO_COUNTRY_ID) ) { $destCountry = self::PUERTORICO_COUNTRY_ID; } - $requestObject->setDestCountryId( - $destCountry - )->setDestState( - $request->getDestRegionCode() - )->setWeight( - $shippingWeight - )->setFreeMethodWeight( - $request->getFreeMethodWeight() - )->setOrderShipment( - $request->getOrderShipment() - ); + $requestObject->setDestCountryId($destCountry) + ->setDestState($request->getDestRegionCode()) + ->setWeight($shippingWeight) + ->setFreeMethodWeight($request->getFreeMethodWeight()) + ->setOrderShipment($request->getOrderShipment()); if ($request->getPackageId()) { $requestObject->setPackageId($request->getPackageId()); @@ -522,7 +500,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin public function getAllowedMethods() { $contentType = $this->getConfigData('content_type'); - $allowedMethods = array(); + if ($this->_isDomestic) { $allowedMethods = array_merge( explode(',', $this->getConfigData('doc_methods')), @@ -709,9 +687,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $fullItems = array(); foreach ($allItems as $item) { - if ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE && - $item->getProduct()->getShipmentType() - ) { + if ($item->getProductType() == Type::TYPE_BUNDLE && $item->getProduct()->getShipmentType()) { continue; } @@ -724,17 +700,23 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin if (!$item->getParentItem()->getProduct()->getShipmentType()) { continue; } - $qty = $item->getIsQtyDecimal() ? $item->getParentItem()->getQty() : $item->getParentItem()->getQty() * - $item->getQty(); + if ($item->getIsQtyDecimal()) { + $qty = $item->getParentItem()->getQty(); + } else { + $qty = $item->getParentItem()->getQty() * $item->getQty(); + } } $itemWeight = $item->getWeight(); - if ($item->getIsQtyDecimal() && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE - ) { - $stockItem = $item->getProduct()->getStockItem(); - if ($stockItem->getIsDecimalDivided()) { - if ($stockItem->getEnableQtyIncrements() && $stockItem->getQtyIncrements()) { - $itemWeight = $itemWeight * $stockItem->getQtyIncrements(); + if ($item->getIsQtyDecimal() && $item->getProductType() != Type::TYPE_BUNDLE) { + $productId = $item->getProduct()->getId(); + $isDecimalDivided = $this->stockItemService->getStockItem($productId) + ->getIsDecimalDivided(); + if ($isDecimalDivided) { + if ($this->stockItemService->getEnableQtyIncrements($productId) + && $this->stockItemService->getQtyIncrements($productId) + ) { + $itemWeight = $itemWeight * $this->stockItemService->getQtyIncrements($productId); $qty = round($item->getWeight() / $itemWeight * $qty); $changeQty = false; } else { @@ -759,10 +741,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin return array(); } - if ($changeQty && - !$item->getParentItem() && - $item->getIsQtyDecimal() && - $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + if ($changeQty + && !$item->getParentItem() + && $item->getIsQtyDecimal() + && $item->getProductType() != Type::TYPE_BUNDLE ) { $qty = 1; } @@ -1022,9 +1004,9 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin // IsDutiable flag and Dutiable node indicates that cargo is not a documentation $nodeBkgDetails->addChild('IsDutiable', 'Y'); $nodeDutiable = $nodeGetQuote->addChild('Dutiable'); - $baseCurrencyCode = $this->_storeManager->getWebsite( - $this->_request->getWebsiteId() - )->getBaseCurrencyCode(); + $baseCurrencyCode = $this->_storeManager + ->getWebsite($this->_request->getWebsiteId()) + ->getBaseCurrencyCode(); $nodeDutiable->addChild('DeclaredCurrency', $baseCurrencyCode); $nodeDutiable->addChild('DeclaredValue', sprintf("%.2F", $rawRequest->getValue())); } @@ -1059,12 +1041,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin if (strpos(trim($response), '<?xml') === 0) { $xml = simplexml_load_string($response); if (is_object($xml)) { - if (in_array( - $xml->getName(), - array('ErrorResponse', 'ShipmentValidateErrorResponse') - ) || isset( - $xml->GetQuoteResponse->Note->Condition - ) + if (in_array($xml->getName(), array('ErrorResponse', 'ShipmentValidateErrorResponse')) + || isset($xml->GetQuoteResponse->Note->Condition) ) { $code = null; $data = null; @@ -1082,7 +1060,9 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin break; } } - throw new \Magento\Framework\Model\Exception(__('Error #%1 : %2', trim($code), trim($data))); + throw new \Magento\Framework\Model\Exception( + __('Error #%1 : %2', trim($code), trim($data)) + ); } $code = isset($nodeCondition->ConditionCode) ? (string)$nodeCondition->ConditionCode : 0; @@ -1142,26 +1122,18 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin */ protected function _addRate(\SimpleXMLElement $shipmentDetails) { - if (isset( - $shipmentDetails->ProductShortName - ) && isset( - $shipmentDetails->ShippingCharge - ) && isset( - $shipmentDetails->GlobalProductCode - ) && isset( - $shipmentDetails->CurrencyCode - ) && array_key_exists( - (string)$shipmentDetails->GlobalProductCode, - $this->getAllowedMethods() - ) + if (isset($shipmentDetails->ProductShortName) + && isset($shipmentDetails->ShippingCharge) + && isset($shipmentDetails->GlobalProductCode) + && isset($shipmentDetails->CurrencyCode) + && array_key_exists((string)$shipmentDetails->GlobalProductCode, $this->getAllowedMethods()) ) { // DHL product code, e.g. '3', 'A', 'Q', etc. $dhlProduct = (string)$shipmentDetails->GlobalProductCode; - $totalEstimate = (double)(string)$shipmentDetails->ShippingCharge; + $totalEstimate = (float)(string)$shipmentDetails->ShippingCharge; $currencyCode = (string)$shipmentDetails->CurrencyCode; - $baseCurrencyCode = $this->_storeManager->getWebsite( - $this->_request->getWebsiteId() - )->getBaseCurrencyCode(); + $baseCurrencyCode = $this->_storeManager->getWebsite($this->_request->getWebsiteId()) + ->getBaseCurrencyCode(); $dhlProductDescription = $this->getDhlProductTitle($dhlProduct); if ($currencyCode != $baseCurrencyCode) { @@ -1193,8 +1165,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin ); if (!empty($this->_rates)) { foreach ($this->_rates as $product) { - if ($product['data']['term'] == $data['term'] && - $product['data']['price_total'] == $data['price_total'] + if ($product['data']['term'] == $data['term'] + && $product['data']['price_total'] == $data['price_total'] ) { return $this; } @@ -1387,19 +1359,12 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $packageWeight += $piece['params']['weight']; } - $request->setPackages( - $packages - )->setPackageWeight( - $packageWeight - )->setPackageValue( - $customsValue - )->setValueWithDiscount( - $customsValue - )->setPackageCustomsValue( - $customsValue - )->setFreeMethodWeight( - 0 - ); + $request->setPackages($packages) + ->setPackageWeight($packageWeight) + ->setPackageValue($customsValue) + ->setValueWithDiscount($customsValue) + ->setPackageCustomsValue($customsValue) + ->setFreeMethodWeight(0); } /** @@ -1462,10 +1427,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $xml->addChild('LanguageCode', 'EN', ''); $xml->addChild('PiecesEnabled', 'Y', ''); - /* Billing */ + /** Billing */ $nodeBilling = $xml->addChild('Billing', '', ''); $nodeBilling->addChild('ShipperAccountNumber', (string)$this->getConfigData('account')); - /* + /** * Method of Payment: * S (Shipper) * R (Receiver) @@ -1473,14 +1438,14 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin */ $nodeBilling->addChild('ShippingPaymentType', 'S'); - /* + /** * Shipment bill to account – required if Shipping PaymentType is other than 'S' */ $nodeBilling->addChild('BillingAccountNumber', (string)$this->getConfigData('account')); $nodeBilling->addChild('DutyPaymentType', 'S'); $nodeBilling->addChild('DutyAccountNumber', (string)$this->getConfigData('account')); - /* Receiver */ + /** Receiver */ $nodeConsignee = $xml->addChild('Consignee', '', ''); $companyName = $rawRequest->getRecipientContactCompanyName() ? $rawRequest @@ -1511,7 +1476,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $nodeContact->addChild('PersonName', substr($rawRequest->getRecipientContactPersonName(), 0, 34)); $nodeContact->addChild('PhoneNumber', substr($rawRequest->getRecipientContactPhoneNumber(), 0, 24)); - /* Commodity + /** + * Commodity * The CommodityCode element contains commodity code for shipment contents. Its * value should lie in between 1 to 9999.This field is mandatory. */ @@ -1523,7 +1489,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $rawRequest->getRecipientAddressCountryCode() ); - /* Dutiable */ + /** Dutiable */ if ($this->getConfigData('content_type') == self::DHL_CONTENT_TYPE_NON_DOC && !$this->_isDomestic) { $nodeDutiable = $xml->addChild('Dutiable', '', ''); $nodeDutiable->addChild( @@ -1534,7 +1500,8 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $nodeDutiable->addChild('DeclaredCurrency', $baseCurrencyCode); } - /* Reference + /** + * Reference * This element identifies the reference information. It is an optional field in the * shipment validation request. Only the first reference will be taken currently. */ @@ -1542,10 +1509,10 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin $nodeReference->addChild('ReferenceID', 'shipment reference'); $nodeReference->addChild('ReferenceType', 'St'); - /* Shipment Details */ + /** Shipment Details */ $this->_shipmentDetails($xml, $rawRequest, $originRegion); - /* Shipper */ + /** Shipper */ $nodeShipper = $xml->addChild('Shipper', '', ''); $nodeShipper->addChild('ShipperID', (string)$this->getConfigData('account')); $nodeShipper->addChild('CompanyName', $rawRequest->getShipperContactCompanyName()); @@ -1659,15 +1626,12 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin if (!$originRegion) { $nodeShipmentDetails->addChild('Weight', round($rawRequest->getPackageWeight(), 1)); - $nodeShipmentDetails->addChild('WeightUnit', substr($this->_getWeightUnit(), 0, 1)); - $nodeShipmentDetails->addChild('GlobalProductCode', $rawRequest->getShippingMethod()); $nodeShipmentDetails->addChild('LocalProductCode', $rawRequest->getShippingMethod()); - $nodeShipmentDetails->addChild('Date', $this->_coreDate->date('Y-m-d')); $nodeShipmentDetails->addChild('Contents', 'DHL Parcel'); - /* + /** * The DoorTo Element defines the type of delivery service that applies to the shipment. * The valid values are DD (Door to Door), DA (Door to Airport) , AA and DC (Door to * Door non-compliant) @@ -1691,14 +1655,12 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin } $nodeShipmentDetails->addChild('PackageType', $packageType); $nodeShipmentDetails->addChild('Weight', $rawRequest->getPackageWeight()); - $nodeShipmentDetails->addChild('DimensionUnit', substr($this->_getDimensionUnit(), 0, 1)); $nodeShipmentDetails->addChild('WeightUnit', substr($this->_getWeightUnit(), 0, 1)); - $nodeShipmentDetails->addChild('GlobalProductCode', $rawRequest->getShippingMethod()); $nodeShipmentDetails->addChild('LocalProductCode', $rawRequest->getShippingMethod()); - /* + /** * The DoorTo Element defines the type of delivery service that applies to the shipment. * The valid values are DD (Door to Door), DA (Door to Airport) , AA and DC (Door to * Door non-compliant) @@ -1750,14 +1712,14 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin foreach ($trackings as $tracking) { $xml->addChild('AWBNumber', $tracking, ''); } - /* + /** * Checkpoint details selection flag * LAST_CHECK_POINT_ONLY * ALL_CHECK_POINTS */ $xml->addChild('LevelOfDetails', 'ALL_CHECK_POINTS', ''); - /* + /** * Value that indicates for getting the tracking details with the additional * piece details and its respective Piece Details, Piece checkpoints along with * Shipment Details if queried. @@ -1810,18 +1772,14 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin if (!is_object($xml)) { $errorTitle = __('Response is in the wrong format'); } - if (is_object( - $xml - ) && (isset( - $xml->Response->Status->ActionStatus - ) && $xml->Response->Status->ActionStatus == 'Failure' || isset( - $xml->GetQuoteResponse->Note->Condition - )) + if (is_object($xml) + && (isset($xml->Response->Status->ActionStatus) + && $xml->Response->Status->ActionStatus == 'Failure' + || isset($xml->GetQuoteResponse->Note->Condition)) ) { if (isset($xml->Response->Status->Condition)) { $nodeCondition = $xml->Response->Status->Condition; } - $code = isset($nodeCondition->ConditionCode) ? (string)$nodeCondition->ConditionCode : 0; $data = isset($nodeCondition->ConditionData) ? (string)$nodeCondition->ConditionData : ''; $this->_errors[$code] = __('Error #%1 : %2', $code, $data); @@ -1845,16 +1803,12 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin if (isset($shipmentInfo->ShipmentEvent)) { foreach ($shipmentInfo->ShipmentEvent as $shipmentEvent) { $shipmentEventArray = array(); - $shipmentEventArray['activity'] = (string)$shipmentEvent->ServiceEvent->EventCode . - ' ' . - (string)$shipmentEvent->ServiceEvent->Description; + $shipmentEventArray['activity'] = (string)$shipmentEvent->ServiceEvent->EventCode + . ' ' . (string)$shipmentEvent->ServiceEvent->Description; $shipmentEventArray['deliverydate'] = (string)$shipmentEvent->Date; $shipmentEventArray['deliverytime'] = (string)$shipmentEvent->Time; $shipmentEventArray['deliverylocation'] = (string)$shipmentEvent->ServiceArea - ->Description . - ' [' . - (string)$shipmentEvent->ServiceArea->ServiceAreaCode . - ']'; + ->Description . ' [' . (string)$shipmentEvent->ServiceArea->ServiceAreaCode . ']'; $packageProgress[] = $shipmentEventArray; } $awbinfoData['progressdetail'] = $packageProgress; diff --git a/app/code/Magento/Dhl/etc/module.xml b/app/code/Magento/Dhl/etc/module.xml index f2422aba3b8d07960adc891fc50cfed3516b2075..a0e44e807650aa11a8aa32759b5b619bb793d130 100644 --- a/app/code/Magento/Dhl/etc/module.xml +++ b/app/code/Magento/Dhl/etc/module.xml @@ -34,6 +34,7 @@ <module name="Magento_Sales"/> <module name="Magento_Checkout"/> <module name="Magento_Catalog"/> + <module name="Magento_CatalogInventory"/> </depends> </module> </config> diff --git a/app/code/Magento/Directory/Controller/Adminhtml/Json.php b/app/code/Magento/Directory/Controller/Adminhtml/Json.php index cd9547813aa0adad77acfc2c1546f7e090344cdd..af8e1ea22051dd8d24283c191ae4745cb780f5aa 100644 --- a/app/code/Magento/Directory/Controller/Adminhtml/Json.php +++ b/app/code/Magento/Directory/Controller/Adminhtml/Json.php @@ -54,6 +54,8 @@ class Json extends \Magento\Backend\App\Action } } } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($arrRes)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($arrRes) + ); } } diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php index 340555eecebe2a0c9a08ed31c05a4e7356814d10..cc2f352164739c7a9be45ff1ef8e5962169cfe4a 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php @@ -113,7 +113,9 @@ class File extends \Magento\Backend\App\Action $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode()); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Downloadable/Model/Product/Type.php b/app/code/Magento/Downloadable/Model/Product/Type.php index d11ca2dd414222288f0c3eefa6801f5a9ac17b75..e9c082f78589750708b6cd1f20984ec2b3d7fe94 100644 --- a/app/code/Magento/Downloadable/Model/Product/Type.php +++ b/app/code/Magento/Downloadable/Model/Product/Type.php @@ -292,6 +292,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual $sampleModel->setSampleFile($sampleFileName); } $sampleModel->save(); + $product->setLastAddedSampleId($sampleModel->getId()); } } if ($_deleteItems) { @@ -366,6 +367,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual $linkModel->setSampleFile($linkSampleFileName); } $linkModel->save(); + $product->setLastAddedLinkId($linkModel->getId()); } } if ($_deleteItems) { diff --git a/app/code/Magento/Downloadable/Service/V1/Data/FileContent.php b/app/code/Magento/Downloadable/Service/V1/Data/FileContent.php new file mode 100644 index 0000000000000000000000000000000000000000..8b6c6a80df253d548299ba0d8a2ea71572d77c72 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/Data/FileContent.php @@ -0,0 +1,52 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +use \Magento\Framework\Service\Data\AbstractObject; + +class FileContent extends AbstractObject +{ + const DATA = 'data'; + const NAME = 'name'; + + /** + * Retrieve data (base64 encoded content) + * + * @return string + */ + public function getData() + { + return $this->_get(self::DATA); + } + + /** + * Retrieve file name + * + * @return string + */ + public function getName() + { + return $this->_get(self::NAME); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/Data/FileContentBuilder.php b/app/code/Magento/Downloadable/Service/V1/Data/FileContentBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..b0c443c3da917417eb8cc6d28cb564aae7dfe2a0 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/Data/FileContentBuilder.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +use \Magento\Framework\Service\Data\AbstractObjectBuilder; + +class FileContentBuilder extends AbstractObjectBuilder +{ + /** + * Set data (base64 encoded content) + * + * @param string $data + * @return $this + */ + public function setData($data) + { + return $this->_set(FileContent::DATA, $data); + } + + /** + * Set file name + * + * @param string $name + * @return $this + */ + public function setName($name) + { + return $this->_set(FileContent::NAME, $name); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploader.php b/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploader.php new file mode 100644 index 0000000000000000000000000000000000000000..57ff82e322defdbb5b3df8057b12046a4b03ebd6 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploader.php @@ -0,0 +1,167 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +use \Magento\Core\Model\File\Uploader; +use \Magento\Framework\Io\File; +use \Magento\Framework\App\Filesystem; +use \Magento\Core\Model\File\Validator\NotProtectedExtension; +use \Magento\Core\Helper\File\Storage; +use \Magento\Core\Helper\File\Storage\Database; +use \Magento\Downloadable\Model\Link as LinkConfig; +use \Magento\Downloadable\Model\Sample as SampleConfig; + +class FileContentUploader extends Uploader implements FileContentUploaderInterface +{ + /** + * Default MIME type + */ + const DEFAULT_MIME_TYPE = 'application/octet-stream'; + + /** + * Filename prefix for temporary files + * + * @var string + */ + protected $filePrefix = 'magento_api'; + + /** + * @var \Magento\Framework\Filesystem\Directory\WriteInterface + */ + protected $mediaDirectory; + + /** + * @var \Magento\Framework\Filesystem\Directory\WriteInterface + */ + protected $systemTmpDirectory; + + /** + * @var LinkConfig + */ + protected $linkConfig; + + /** + * @var SampleConfig + */ + protected $sampleConfig; + + /** + * @param Database $coreFileStorageDb + * @param Storage $coreFileStorage + * @param NotProtectedExtension $validator + * @param Filesystem $filesystem + * @param LinkConfig $linkConfig + * @param SampleConfig $sampleConfig + */ + public function __construct( + Database $coreFileStorageDb, + Storage $coreFileStorage, + NotProtectedExtension $validator, + Filesystem $filesystem, + LinkConfig $linkConfig, + SampleConfig $sampleConfig + ) { + $this->_validator = $validator; + $this->_coreFileStorage = $coreFileStorage; + $this->_coreFileStorageDb = $coreFileStorageDb; + $this->mediaDirectory = $filesystem->getDirectoryWrite(Filesystem::MEDIA_DIR); + $this->systemTmpDirectory = $filesystem->getDirectoryWrite(Filesystem::SYS_TMP_DIR); + $this->linkConfig = $linkConfig; + $this->sampleConfig = $sampleConfig; + } + + /** + * Decode base64 encoded content and save it in system tmp folder + * + * @param FileContent $fileContent + * @return array + */ + protected function decodeContent(FileContent $fileContent) + { + $tmpFileName = $this->getTmpFileName(); + $fileSize = $this->systemTmpDirectory->writeFile($tmpFileName, base64_decode($fileContent->getData())); + + return array( + 'name' => $fileContent->getName(), + 'type' => self::DEFAULT_MIME_TYPE, + 'tmp_name' => $this->systemTmpDirectory->getAbsolutePath($tmpFileName), + 'error' => 0, + 'size' => $fileSize, + ); + } + + /** + * Generate temporary file name + * + * @return string + */ + protected function getTmpFileName() + { + return uniqid($this->filePrefix, true); + } + + /** + * {@inheritdoc} + */ + public function upload(FileContent $fileContent, $contentType) + { + $this->_file = $this->decodeContent($fileContent); + if (!file_exists($this->_file['tmp_name'])) { + throw new \InvalidArgumentException('There was an error during file content upload.'); + } + $this->_fileExists = true; + $this->_uploadType = self::SINGLE_STYLE; + $this->setAllowRenameFiles(true); + $this->setFilesDispersion(true); + $result = $this->save($this->getDestinationDirectory($contentType)); + $result['status'] = 'new'; + $result['name'] = substr($result['file'], strrpos($result['file'], '/') + 1); + return $result; + } + + /** + * Retrieve destination directory for given content type + * + * @param string $contentType + * @return string + * @throws \InvalidArgumentException + */ + protected function getDestinationDirectory($contentType) + { + switch ($contentType) { + case 'link_file': + $directory = $this->mediaDirectory->getAbsolutePath($this->linkConfig->getBaseTmpPath()); + break; + case 'link_sample_file': + $directory = $this->mediaDirectory->getAbsolutePath($this->linkConfig->getBaseSampleTmpPath()); + break; + case 'sample': + $directory = $this->mediaDirectory->getAbsolutePath($this->sampleConfig->getBaseTmpPath()); + break; + default: + throw new \InvalidArgumentException('Invalid downloadable file content type.'); + } + return $directory; + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploaderInterface.php b/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploaderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..e50ec68dfc3495c2ba85c3753eb7956c3f13a1d5 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/Data/FileContentUploaderInterface.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +interface FileContentUploaderInterface +{ + /** + * Upload provided downloadable file content + * + * @param FileContent $fileContent + * @param string $contentType + * @return array + * @throws \InvalidArgumentException + */ + public function upload(FileContent $fileContent, $contentType); +} diff --git a/app/code/Magento/Downloadable/Service/V1/Data/FileContentValidator.php b/app/code/Magento/Downloadable/Service/V1/Data/FileContentValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..5c0615c498a7a709279050c0bc42259ef46037aa --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/Data/FileContentValidator.php @@ -0,0 +1,65 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +use \Magento\Framework\Exception\InputException; + +class FileContentValidator +{ + /** + * Check if gallery entry content is valid + * + * @param FileContent $fileContent + * @return bool + * @throws InputException + */ + public function isValid(FileContent $fileContent) + { + $decodedContent = @base64_decode($fileContent->getData(), true); + if (empty($decodedContent)) { + throw new InputException('Provided content must be valid base64 encoded data.'); + } + + if (!$this->isFileNameValid($fileContent->getName())) { + throw new InputException('Provided file name contains forbidden characters.'); + } + return true; + } + + /** + * Check if given filename is valid + * + * @param string $fileName + * @return bool + */ + protected function isFileNameValid($fileName) + { + // Cannot contain \ / : * ? " < > | + if (!preg_match('/^[^\\/?*:";<>()|{}\\\\]+$/', $fileName)) { + return false; + } + return true; + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContent.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContent.php new file mode 100644 index 0000000000000000000000000000000000000000..72de1163db15feeaae8e92ba631d135e2158b14c --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContent.php @@ -0,0 +1,153 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use \Magento\Framework\Service\Data\AbstractObject; + +class DownloadableLinkContent extends AbstractObject +{ + const TITLE = 'title'; + const PRICE = 'price'; + const NUMBER_OF_DOWNLOADS = 'number_of_downloads'; + const UNLIMITED = 'unlimited'; + const SHAREABLE = 'shareable'; + const SORT_ORDER = 'sort_order'; + const LINK_FILE = 'link_file'; + const LINK_URL = 'link_url'; + const LINK_TYPE = 'link_type'; + const SAMPLE_FILE = 'file'; + const SAMPLE_URL = 'url'; + const SAMPLE_TYPE = 'sample_type'; + + /** + * Retrieve link title + * + * @return string + */ + public function getTitle() + { + return $this->_get(self::TITLE); + } + + /** + * Retrieve link sort order + * + * @return int + */ + public function getSortOrder() + { + return $this->_get(self::SORT_ORDER); + } + + /** + * Retrieve link price + * + * @return string + */ + public function getPrice() + { + return $this->_get(self::PRICE); + } + + /** + * Retrieve number of allowed downloads of the link + * + * @return int + */ + public function getNumberOfDownloads() + { + return $this->_get(self::NUMBER_OF_DOWNLOADS); + } + + /** + * Check if link is shareable + * + * @return bool + */ + public function isShareable() + { + return $this->_get(self::SHAREABLE); + } + + /** + * Retrieve link file content + * + * @return \Magento\Downloadable\Service\V1\Data\FileContent|null + */ + public function getLinkFile() + { + return $this->_get(self::LINK_FILE); + } + + /** + * Retrieve link URL + * + * @return string|null + */ + public function getLinkUrl() + { + return $this->_get(self::LINK_URL); + } + + /** + * Retrieve link type ('url' or 'file') + * + * @return string|null + */ + public function getLinkType() + { + return $this->_get(self::LINK_TYPE); + } + + /** + * Retrieve sample file content + * + * @return \Magento\Downloadable\Service\V1\Data\FileContent|null + */ + public function getSampleFile() + { + return $this->_get(self::SAMPLE_FILE); + } + + /** + * Retrieve sample URL + * + * @return string|null + */ + public function getSampleUrl() + { + return $this->_get(self::SAMPLE_URL); + } + + /** + * Retrieve sample type ('url' or 'file') + * + * @return string|null + */ + public function getSampleType() + { + return $this->_get(self::SAMPLE_TYPE); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentBuilder.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..f344be1800ead0eb861aff23b316f95e17993c11 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentBuilder.php @@ -0,0 +1,153 @@ +<?php +/** + * Downloadable Link Builder + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use \Magento\Framework\Service\Data\AbstractObjectBuilder; +use \Magento\Downloadable\Service\V1\Data\FileContent; + +class DownloadableLinkContentBuilder extends AbstractObjectBuilder +{ + /** + * Set link title + * + * @param string $title + * @return $this + */ + public function setTitle($title) + { + return $this->_set(DownloadableLinkContent::TITLE, $title); + } + + /** + * Set link sort order + * + * @param int $sortOrder + * @return $this + */ + public function setSortOrder($sortOrder) + { + return $this->_set(DownloadableLinkContent::SORT_ORDER, $sortOrder); + } + + /** + * Set link price + * + * @param string $price + * @return $this + */ + public function setPrice($price) + { + return $this->_set(DownloadableLinkContent::PRICE, $price); + } + + /** + * Set number of allowed downloads of the link + * + * @param int $numberOfDownloads + * @return $this + */ + public function setNumberOfDownloads($numberOfDownloads) + { + return $this->_set(DownloadableLinkContent::NUMBER_OF_DOWNLOADS, $numberOfDownloads); + } + + /** + * Check if link is shareable + * + * @param bool $shareable + * @return $this + */ + public function setShareable($shareable) + { + return $this->_set(DownloadableLinkContent::SHAREABLE, $shareable); + } + + /** + * Set link file content + * + * @param FileContent $linkFile + * @return $this + */ + public function setLinkFile(FileContent $linkFile) + { + return $this->_set(DownloadableLinkContent::LINK_FILE, $linkFile); + } + + /** + * Set link URL + * + * @param string $linkUrl + * @return $this + */ + public function setLinkUrl($linkUrl) + { + return $this->_set(DownloadableLinkContent::LINK_URL, $linkUrl); + } + + /** + * Set link type ('url' or 'file') + * + * @param string $linkType + * @return $this + */ + public function setLinkType($linkType) + { + return $this->_set(DownloadableLinkContent::LINK_TYPE, $linkType); + } + + /** + * Set sample file content + * + * @param FileContent $sampleFile + * @return $this + */ + public function setSampleFile($sampleFile) + { + return $this->_set(DownloadableLinkContent::SAMPLE_FILE, $sampleFile); + } + + /** + * Set sample URL + * + * @param string $sampleUrl + * @return $this + */ + public function setSampleUrl($sampleUrl) + { + return $this->_set(DownloadableLinkContent::SAMPLE_URL, $sampleUrl); + } + + /** + * Set sample type ('url' or 'file') + * + * @param string $sampleType + * @return $this + */ + public function setSampleType($sampleType) + { + return $this->_set(DownloadableLinkContent::SAMPLE_TYPE, $sampleType); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidator.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..13413efd2d4dcddcc7b590c515bf8e4e162f896d --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidator.php @@ -0,0 +1,120 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use \Magento\Downloadable\Service\V1\Data\FileContentValidator; +use \Magento\Framework\Url\Validator as UrlValidator; +use \Magento\Framework\Exception\InputException; + +class DownloadableLinkContentValidator +{ + /** + * @var FileContentValidator + */ + protected $fileContentValidator; + + /** + * @var UrlValidator + */ + protected $urlValidator; + + /** + * @param FileContentValidator $fileContentValidator + * @param UrlValidator $urlValidator + */ + public function __construct( + FileContentValidator $fileContentValidator, + UrlValidator $urlValidator + ) { + $this->fileContentValidator = $fileContentValidator; + $this->urlValidator = $urlValidator; + } + + /** + * Check if link content is valid + * + * @param DownloadableLinkContent $linkContent + * @return bool + * @throws InputException + */ + public function isValid(DownloadableLinkContent $linkContent) + { + if (!is_numeric($linkContent->getPrice()) || $linkContent->getPrice() < 0) { + throw new InputException('Link price must have numeric positive value.'); + } + if (!is_int($linkContent->getNumberOfDownloads()) || $linkContent->getNumberOfDownloads() < 0) { + throw new InputException('Number of downloads must be a positive integer.'); + } + if (!is_int($linkContent->getSortOrder()) || $linkContent->getSortOrder() < 0) { + throw new InputException('Sort order must be a positive integer.'); + } + + $this->validateLinkResource($linkContent); + $this->validateSampleResource($linkContent); + return true; + } + + /** + * Validate link resource (file or URL) + * + * @param DownloadableLinkContent $linkContent + * @throws InputException + * @return void + */ + protected function validateLinkResource(DownloadableLinkContent $linkContent) + { + if ($linkContent->getLinkType() == 'url' + && !$this->urlValidator->isValid($linkContent->getLinkUrl()) + ) { + throw new InputException('Link URL must have valid format.'); + } + if ($linkContent->getLinkType() == 'file' + && (!$linkContent->getLinkFile() || !$this->fileContentValidator->isValid($linkContent->getLinkFile())) + ) { + throw new InputException('Provided file content must be valid base64 encoded data.'); + } + } + + /** + * Validate sample resource (file or URL) + * + * @param DownloadableLinkContent $linkContent + * @throws InputException + * @return void + */ + protected function validateSampleResource(DownloadableLinkContent $linkContent) + { + if ($linkContent->getSampleType() == 'url' + && !$this->urlValidator->isValid($linkContent->getSampleUrl()) + ) { + throw new InputException('Sample URL must have valid format.'); + } + if ($linkContent->getSampleType() == 'file' + && (!$linkContent->getSampleFile() || !$this->fileContentValidator->isValid($linkContent->getSampleFile())) + ) { + throw new InputException('Provided file content must be valid base64 encoded data.'); + } + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfo.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..0e841b08e7fb3918de2916f1a153d39161105b29 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfo.php @@ -0,0 +1,130 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use Magento\Framework\Service\Data\AbstractObject; + +class DownloadableLinkInfo extends AbstractObject +{ + const ID = 'id'; + + const TITLE = 'title'; + + const SORT_ORDER = 'sort_order'; + + const SHAREABLE = 'shareable'; + + const PRICE = 'price'; + + const NUMBER_OF_DOWNLOADS = 'number_of_downloads'; + + const SAMPLE_RESOURCE = 'sample_resource'; + + const LINK_RESOURCE = 'link_resource'; + + /** + * Product link id + * + * @return int|null Sample(or link) id + */ + public function getId() + { + return $this->_get(self::ID); + } + + /** + * Link title + * + * @return string|null + */ + public function getTitle() + { + return $this->_get(self::TITLE); + } + + /** + * Sort order index for link + * + * @return int + */ + public function getSortOrder() + { + return (int)$this->_get(self::SORT_ORDER); + } + + /** + * Link shareable status + * 0 -- No + * 1 -- Yes + * 2 -- Use config default value + * + * @return int + */ + public function getShareable() + { + return (int)$this->_get(self::SHAREABLE); + } + + /** + * Link price + * + * @return float + */ + public function getPrice() + { + return $this->_get(self::PRICE); + } + + /** + * Number of downloads per user + * Null for unlimited downloads + * + * @return int|null + */ + public function getNumberOfDownloads() + { + return $this->_get(self::NUMBER_OF_DOWNLOADS); + } + + /** + * File or URL of sample if any + * + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo|null + */ + public function getSampleResource() + { + return $this->_get(self::SAMPLE_RESOURCE); + } + + /** + * File or URL of link + * + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo + */ + public function getLinkResource() + { + return $this->_get(self::LINK_RESOURCE); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfoBuilder.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfoBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..28853bfc59b203570c6dbacbb14bbde6503cf152 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkInfoBuilder.php @@ -0,0 +1,111 @@ +<?php +/** + * Downloadable Link Info Builder + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +class DownloadableLinkInfoBuilder extends AbstractObjectBuilder +{ + /** + * @param int|null $value + * @return $this + */ + public function setId($value) + { + return $this->_set(DownloadableLinkInfo::ID, $value); + } + + /** + * @param string $value + * @return $this + */ + public function setTitle($value) + { + return $this->_set(DownloadableLinkInfo::TITLE, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setSortOrder($value) + { + return $this->_set(DownloadableLinkInfo::SORT_ORDER, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setShareable($value) + { + return $this->_set(DownloadableLinkInfo::SHAREABLE, $value); + } + + /** + * Link price + * + * @param float|null $value + * @return $this + */ + public function setPrice($value = 0.0) + { + return $this->_set(DownloadableLinkInfo::PRICE, $value); + } + + /** + * Number of downloads per user + * + * @param int|null $value + * @return $this + */ + public function setNumberOfDownloads($value = null) + { + return $this->_set(DownloadableLinkInfo::NUMBER_OF_DOWNLOADS, $value); + } + + /** + * Sample data object + * + * @param \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo|null $value + * @return $this + */ + public function setSampleResource($value = null) + { + return $this->_set(DownloadableLinkInfo::SAMPLE_RESOURCE, $value); + } + + /** + * Link data object + * + * @param \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo $value + * @return $this + */ + public function setLinkResource($value) + { + return $this->_set(DownloadableLinkInfo::LINK_RESOURCE, $value); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfo.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..29959bea145ebb51e6a5a7e5b7b652535e71f654 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfo.php @@ -0,0 +1,66 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use \Magento\Framework\Service\Data\AbstractObject; + +class DownloadableResourceInfo extends AbstractObject +{ + const FILE = 'file'; + + const URL = 'url'; + + const TYPE = 'type'; + + /** + * Return file path or null when type is 'url' + * + * @return string|null relative file path + */ + public function getFile() + { + return $this->_get(self::FILE); + } + + /** + * Return URL or NULL when type is 'file' + * + * @return string|null file URL + */ + public function getUrl() + { + return $this->_get(self::URL); + } + + /** + * Possible types are 'file' and 'url' + * + * @return string + */ + public function getType() + { + return $this->_get(self::TYPE); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfoBuilder.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfoBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..13549c5801ff7bc9f7f994c0c84340ed54010f3f --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableResourceInfoBuilder.php @@ -0,0 +1,70 @@ +<?php +/** + * Downloadable Link Builder + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +class DownloadableResourceInfoBuilder extends AbstractObjectBuilder +{ + /** + * Set file path + * + * @param string|null $value + * @return $this + */ + public function setFile($value) + { + return $this->_set(DownloadableResourceInfo::FILE, $value); + } + + /** + * Set URL + * + * @param string|null $value + * @return $this + */ + public function setUrl($value) + { + return $this->_set(DownloadableResourceInfo::URL, $value); + } + + /** + * Set value type + * + * @param string $value + * @throws \Magento\Framework\Exception\InputException + * @return $this + */ + public function setType($value) + { + $allowedValues = ['url', 'file']; + if (!in_array($value, $allowedValues)) { + $values = '\'' . implode('\' and \'', $allowedValues) . '\''; + throw new \Magento\Framework\Exception\InputException('Allowed type values are '. $values); + } + return $this->_set(DownloadableResourceInfo::TYPE, $value); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfo.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfo.php new file mode 100644 index 0000000000000000000000000000000000000000..532d15fbf0608e7b090e046520492208c9c7a18c --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfo.php @@ -0,0 +1,78 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use \Magento\Framework\Service\Data\AbstractObject; + +class DownloadableSampleInfo extends AbstractObject +{ + const ID = 'id'; + + const TITLE = 'title'; + + const SORT_ORDER = 'sort_order'; + + const SAMPLE_RESOURCE = 'sample_resource'; + + /** + * Product sample id + * + * @return int|null Sample(or link) id + */ + public function getId() + { + return $this->_get(self::ID); + } + + /** + * Sample title + * + * @return string + */ + public function getTitle() + { + return $this->_get(self::TITLE); + } + + /** + * File or URL of sample + * + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo + */ + public function getSampleResource() + { + return $this->_get(self::SAMPLE_RESOURCE); + } + + /** + * Sort order index for sample + * + * @return int + */ + public function getSortOrder() + { + return (int)$this->_get(self::SORT_ORDER); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfoBuilder.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfoBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..7540f4b11e7cc6065a322570667b679edd0fe5fd --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableSampleInfoBuilder.php @@ -0,0 +1,69 @@ +<?php +/** + * Downloadable Link Builder + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +use Magento\Framework\Service\Data\AbstractObjectBuilder; + +class DownloadableSampleInfoBuilder extends AbstractObjectBuilder +{ + /** + * @param string $value + * @return $this + */ + public function setTitle($value) + { + return $this->_set(DownloadableLinkInfo::TITLE, $value); + } + + /** + * @param int|null $value + * @return $this + */ + public function setId($value) + { + return $this->_set(DownloadableLinkInfo::ID, $value); + } + + /** + * @param int $value + * @return $this + */ + public function setSortOrder($value) + { + return $this->_set(DownloadableLinkInfo::SORT_ORDER, $value); + } + + /** + * File or URL of sample if any + * + * @param \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo $sampleResource + * @return $this + */ + public function setSampleResource($sampleResource) + { + return $this->_set(DownloadableLinkInfo::SAMPLE_RESOURCE, $sampleResource); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadService.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadService.php new file mode 100644 index 0000000000000000000000000000000000000000..b2f7368e857fce7d3296aeefd175244048034c79 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadService.php @@ -0,0 +1,177 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +class ReadService implements ReadServiceInterface +{ + /** + * @var \Magento\Catalog\Model\ProductRepository + */ + protected $productRepository; + + /** + * @var \Magento\Downloadable\Model\Product\Type + */ + protected $downloadableType; + + /** + * @var \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkInfoBuilder + */ + protected $linkBuilder; + + /** + * @var \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableSampleInfoBuilder + */ + protected $sampleBuilder; + + /** + * @var \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfoBuilder + */ + protected $resourceBuilder; + + /** + * @param \Magento\Catalog\Model\ProductRepository $productRepository + * @param \Magento\Downloadable\Model\Product\Type $downloadableType + * @param Data\DownloadableLinkInfoBuilder $linkBuilder + * @param Data\DownloadableSampleInfoBuilder $sampleBuilder + * @param Data\DownloadableResourceInfoBuilder $resourceBuilder + */ + public function __construct( + \Magento\Catalog\Model\ProductRepository $productRepository, + \Magento\Downloadable\Model\Product\Type $downloadableType, + \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkInfoBuilder $linkBuilder, + \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableSampleInfoBuilder $sampleBuilder, + \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfoBuilder $resourceBuilder + ) { + $this->productRepository = $productRepository; + $this->downloadableType = $downloadableType; + $this->linkBuilder = $linkBuilder; + $this->sampleBuilder = $sampleBuilder; + $this->resourceBuilder = $resourceBuilder; + } + + /** + * {@inheritdoc} + */ + public function getLinks($productSku) + { + $linkList = []; + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($productSku); + $links = $this->downloadableType->getLinks($product); + /** @var \Magento\Downloadable\Model\Link $link */ + foreach ($links as $link) { + $linkList[] = $this->buildLink($link); + } + return $linkList; + } + + /** + * Build a link data object + * + * @param \Magento\Downloadable\Model\Link $resourceData + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkInfo + */ + protected function buildLink($resourceData) + { + $this->setBasicFields($resourceData, $this->linkBuilder); + $this->linkBuilder->setPrice($resourceData->getPrice()); + $this->linkBuilder->setNumberOfDownloads($resourceData->getNumberOfDownloads()); + $this->linkBuilder->setShareable($resourceData->getIsShareable()); + $this->linkBuilder->setLinkResource($this->entityInfoGenerator('link', $resourceData)); + return $this->linkBuilder->create(); + } + + /** + * Subroutine for buildLink and buildSample + * + * @param \Magento\Downloadable\Model\Link|\Magento\Downloadable\Model\Sample $resourceData + * @param Data\DownloadableLinkInfoBuilder|Data\DownloadableSampleInfoBuilder $builder + * @return null + */ + protected function setBasicFields($resourceData, $builder) + { + $builder->populateWithArray([]); + $builder->setId($resourceData->getId()); + $storeTitle = $resourceData->getStoreTitle(); + $title = $resourceData->getTitle(); + if (!empty($storeTitle)) { + $builder->setTitle($storeTitle); + } else { + $builder->setTitle($title); + } + $builder->setSortOrder($resourceData->getSortOrder()); + $builder->setSampleResource($this->entityInfoGenerator('sample', $resourceData)); + } + + /** + * Build a sample data object + * + * @param \Magento\Downloadable\Model\Sample $resourceData + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableSampleInfo + */ + protected function buildSample($resourceData) + { + $this->setBasicFields($resourceData, $this->sampleBuilder); + return $this->sampleBuilder->create(); + } + + /** + * Build file info data object + * + * @param string $entityType 'link' or 'sample' + * @param \Magento\Downloadable\Model\Link|\Magento\Downloadable\Model\Sample $resourceData + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfo|null + */ + protected function entityInfoGenerator($entityType, $resourceData) + { + $type = $resourceData->getData($entityType . '_type'); + if (empty($type)) { + return null; + } + $this->resourceBuilder->populateWithArray([]); + $this->resourceBuilder->setType($type); + $this->resourceBuilder->setUrl($resourceData->getData($entityType . '_url')); + $this->resourceBuilder->setFile($resourceData->getData($entityType . '_file')); + return $this->resourceBuilder->create(); + + } + + /** + * {@inheritdoc} + */ + public function getSamples($productSku) + { + $sampleList = []; + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->productRepository->get($productSku); + $samples = $this->downloadableType->getSamples($product); + /** @var \Magento\Downloadable\Model\Sample $sample */ + foreach ($samples as $sample) { + $sampleList[] = $this->buildSample($sample); + } + return $sampleList; + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceInterface.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..8cdfc74a0497bf2ad958e641ebc9bfcf6deb5bef --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceInterface.php @@ -0,0 +1,44 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +interface ReadServiceInterface +{ + /** + * List of samples for downloadable product + * + * @param string $productSku + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableSampleInfo[] + */ + public function getSamples($productSku); + + /** + * List of links with associated samples + * + * @param string $productSku + * @return \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkInfo[] + */ + public function getLinks($productSku); +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteService.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteService.php new file mode 100644 index 0000000000000000000000000000000000000000..10a01277a5114b0d593a2db547900766c1772302 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteService.php @@ -0,0 +1,200 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +use \Magento\Downloadable\Service\V1\Data\FileContentUploaderInterface; +use \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent; +use \Magento\Catalog\Model\ProductRepository; +use \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContentValidator; +use \Magento\Downloadable\Model\Link; +use \Magento\Framework\Exception\InputException; +use \Magento\Framework\Json\EncoderInterface; +use \Magento\Downloadable\Model\LinkFactory; +use \Magento\Framework\Exception\NoSuchEntityException; + +class WriteService implements WriteServiceInterface +{ + /** + * @var ProductRepository + */ + protected $productRepository; + + /** + * @var DownloadableLinkContentValidator + */ + protected $linkContentValidator; + + /** + * @var FileContentUploaderInterface + */ + protected $fileContentUploader; + + /** + * @var EncoderInterface + */ + protected $jsonEncoder; + + /** + * @var \Magento\Downloadable\Model\LinkFactory + */ + protected $linkFactory; + + /** + * @param ProductRepository $productRepository + * @param DownloadableLinkContentValidator $linkContentValidator + * @param FileContentUploaderInterface $fileContentUploader + * @param EncoderInterface $jsonEncoder + * @param LinkFactory $linkFactory + */ + public function __construct( + ProductRepository $productRepository, + DownloadableLinkContentValidator $linkContentValidator, + FileContentUploaderInterface $fileContentUploader, + EncoderInterface $jsonEncoder, + LinkFactory $linkFactory + ) { + $this->productRepository = $productRepository; + $this->linkContentValidator = $linkContentValidator; + $this->fileContentUploader = $fileContentUploader; + $this->jsonEncoder = $jsonEncoder; + $this->linkFactory = $linkFactory; + } + + /** + * {@inheritdoc} + */ + public function create($productSku, DownloadableLinkContent $linkContent, $isGlobalScopeContent = false) + { + $product = $this->productRepository->get($productSku, true); + if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) { + throw new InputException('Product type of the product must be \'downloadable\'.'); + } + if (!$this->linkContentValidator->isValid($linkContent)) { + throw new InputException('Provided link information is invalid.'); + } + + if (!in_array($linkContent->getLinkType(), array('url', 'file'))) { + throw new InputException('Invalid link type.'); + } + $title = $linkContent->getTitle(); + if (empty($title)) { + throw new InputException('Link title cannot be empty.'); + } + + $linkData = array( + 'link_id' => 0, + 'is_delete' => 0, + 'type' => $linkContent->getLinkType(), + 'sort_order' => $linkContent->getSortOrder(), + 'title' => $linkContent->getTitle(), + 'price' => $linkContent->getPrice(), + 'number_of_downloads' => $linkContent->getNumberOfDownloads(), + 'is_shareable' => $linkContent->isShareable() + ); + + if ($linkContent->getLinkType() == 'file') { + $linkData['file'] = $this->jsonEncoder->encode(array( + $this->fileContentUploader->upload($linkContent->getLinkFile(), 'link_file') + )); + } else { + $linkData['link_url'] = $linkContent->getLinkUrl(); + } + + if ($linkContent->getSampleType() == 'file') { + $linkData['sample']['type'] = 'file'; + $linkData['sample']['file'] = $this->jsonEncoder->encode(array( + $this->fileContentUploader->upload($linkContent->getSampleFile(), 'link_sample_file') + )); + } elseif ($linkContent->getSampleType() == 'url') { + $linkData['sample']['type'] = 'url'; + $linkData['sample']['url'] = $linkContent->getSampleUrl(); + } + + $downloadableData = array('link' => array($linkData)); + $product->setDownloadableData($downloadableData); + if ($isGlobalScopeContent) { + $product->setStoreId(0); + } + $product->save(); + return $product->getLastAddedLinkId(); + } + + /** + * {@inheritdoc} + */ + public function update($productSku, $linkId, DownloadableLinkContent $linkContent, $isGlobalScopeContent = false) + { + $product = $this->productRepository->get($productSku, true); + /** @var $link \Magento\Downloadable\Model\Link */ + $link = $this->linkFactory->create()->load($linkId); + if (!$link->getId()) { + throw new NoSuchEntityException('There is no downloadable link with provided ID.'); + } + if ($link->getProductId() != $product->getId()) { + throw new InputException('Provided downloadable link is not related to given product.'); + } + if (!$this->linkContentValidator->isValid($linkContent)) { + throw new InputException('Provided link information is invalid.'); + } + if ($isGlobalScopeContent) { + $product->setStoreId(0); + } + $title = $linkContent->getTitle(); + if (empty($title)) { + if ($isGlobalScopeContent) { + throw new InputException('Link title cannot be empty.'); + } + // use title from GLOBAL scope + $link->setTitle(null); + } else { + $link->setTitle($linkContent->getTitle()); + } + + $link->setProductId($product->getId()) + ->setStoreId($product->getStoreId()) + ->setWebsiteId($product->getStore()->getWebsiteId()) + ->setProductWebsiteIds($product->getWebsiteIds()) + ->setSortOrder($linkContent->getSortOrder()) + ->setPrice($linkContent->getPrice()) + ->setIsShareable($linkContent->isShareable()) + ->setNumberOfDownloads($linkContent->getNumberOfDownloads()) + ->save(); + return true; + } + + /** + * {@inheritdoc} + */ + public function delete($linkId) + { + /** @var $link \Magento\Downloadable\Model\Link */ + $link = $this->linkFactory->create()->load($linkId); + if (!$link->getId()) { + throw new NoSuchEntityException('There is no downloadable link with provided ID.'); + } + $link->delete(); + return true; + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceInterface.php b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..d3668b4deba4e120c56e5a0df0d8e4d2cbf0e098 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceInterface.php @@ -0,0 +1,60 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +use \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent; + +interface WriteServiceInterface +{ + /** + * Add downloadable link to the given product + * + * @param string $productSku + * @param \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent $linkContent + * @param bool $isGlobalScopeContent + * @return int link ID + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function create($productSku, DownloadableLinkContent $linkContent, $isGlobalScopeContent = false); + + /** + * Update downloadable link of the given product (link type and its resources cannot be changed) + * + * @param string $productSku + * @param int $linkId + * @param \Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent $linkContent + * @param bool $isGlobalScopeContent + * @return bool + */ + public function update($productSku, $linkId, DownloadableLinkContent $linkContent, $isGlobalScopeContent = false); + + /** + * Delete downloadable link + * + * @param int $linkId + * @return bool + */ + public function delete($linkId); +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContent.php b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContent.php new file mode 100644 index 0000000000000000000000000000000000000000..349d35f84f736c49b0b0597fecc0357a21c2f388 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContent.php @@ -0,0 +1,86 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample\Data; + +use \Magento\Framework\Service\Data\AbstractObject; + +class DownloadableSampleContent extends AbstractObject +{ + const TITLE = 'title'; + const SORT_ORDER = 'sort_order'; + const SAMPLE_FILE = 'file'; + const SAMPLE_URL = 'url'; + const SAMPLE_TYPE = 'sample_type'; + + /** + * Retrieve sample title + * + * @return string + */ + public function getTitle() + { + return $this->_get(self::TITLE); + } + + /** + * Retrieve sample type ('url' or 'file') + * + * @return string|null + */ + public function getSampleType() + { + return $this->_get(self::SAMPLE_TYPE); + } + + /** + * Retrieve sample file content + * + * @return \Magento\Downloadable\Service\V1\Data\FileContent|null + */ + public function getSampleFile() + { + return $this->_get(self::SAMPLE_FILE); + } + + /** + * Retrieve sample sort order + * + * @return int + */ + public function getSortOrder() + { + return $this->_get(self::SORT_ORDER); + } + + /** + * Retrieve sample URL + * + * @return string|null + */ + public function getSampleUrl() + { + return $this->_get(self::SAMPLE_URL); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentBuilder.php b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..11b7b09c34293b683473318cfc4ae50161f5c529 --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentBuilder.php @@ -0,0 +1,87 @@ +<?php +/** + * Downloadable Link Builder + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample\Data; + +use \Magento\Framework\Service\Data\AbstractObjectBuilder; +use \Magento\Downloadable\Service\V1\Data\FileContent; + +class DownloadableSampleContentBuilder extends AbstractObjectBuilder +{ + /** + * Set link title + * + * @param string $title + * @return $this + */ + public function setTitle($title) + { + return $this->_set(DownloadableSampleContent::TITLE, $title); + } + + /** + * Set sample file content + * + * @param FileContent $sampleFile + * @return $this + */ + public function setSampleFile($sampleFile) + { + return $this->_set(DownloadableSampleContent::SAMPLE_FILE, $sampleFile); + } + + /** + * Set sample type ('url' or 'file') + * + * @param string $sampleType + * @return $this + */ + public function setSampleType($sampleType) + { + return $this->_set(DownloadableSampleContent::SAMPLE_TYPE, $sampleType); + } + + /** + * Set sample URL + * + * @param string $sampleUrl + * @return $this + */ + public function setSampleUrl($sampleUrl) + { + return $this->_set(DownloadableSampleContent::SAMPLE_URL, $sampleUrl); + } + + /** + * Set sample sort order + * + * @param int $sortOrder + * @return $this + */ + public function setSortOrder($sortOrder) + { + return $this->_set(DownloadableSampleContent::SORT_ORDER, $sortOrder); + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidator.php b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..1677d150fd579d7fe1ad716c06e979081149300b --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidator.php @@ -0,0 +1,94 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample\Data; + +use \Magento\Downloadable\Service\V1\Data\FileContentValidator; +use \Magento\Framework\Url\Validator as UrlValidator; +use \Magento\Framework\Exception\InputException; + +class DownloadableSampleContentValidator +{ + /** + * @var UrlValidator + */ + protected $urlValidator; + + /** + * @var FileContentValidator + */ + protected $fileContentValidator; + + /** + * @param FileContentValidator $fileContentValidator + * @param UrlValidator $urlValidator + */ + public function __construct( + FileContentValidator $fileContentValidator, + UrlValidator $urlValidator + ) { + $this->fileContentValidator = $fileContentValidator; + $this->urlValidator = $urlValidator; + } + + /** + * Check if sample content is valid + * + * @param DownloadableSampleContent $sampleContent + * @return bool + * @throws InputException + */ + public function isValid(DownloadableSampleContent $sampleContent) + { + if (!is_int($sampleContent->getSortOrder()) || $sampleContent->getSortOrder() < 0) { + throw new InputException('Sort order must be a positive integer.'); + } + + $this->validateSampleResource($sampleContent); + return true; + } + + /** + * Validate sample resource (file or URL) + * + * @param DownloadableSampleContent $sampleContent + * @throws InputException + * @return void + */ + protected function validateSampleResource(DownloadableSampleContent $sampleContent) + { + $sampleFile = $sampleContent->getSampleFile(); + if ($sampleContent->getSampleType() == 'file' + && (!$sampleFile || !$this->fileContentValidator->isValid($sampleFile)) + ) { + throw new InputException('Provided file content must be valid base64 encoded data.'); + } + + if ($sampleContent->getSampleType() == 'url' + && !$this->urlValidator->isValid($sampleContent->getSampleUrl()) + ) { + throw new InputException('Sample URL must have valid format.'); + } + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteService.php b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteService.php new file mode 100644 index 0000000000000000000000000000000000000000..2fc1545949a651a799f2e0e36a845c4e8e1c81fb --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteService.php @@ -0,0 +1,188 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample; + +use \Magento\Downloadable\Service\V1\Data\FileContentUploaderInterface; +use \Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent; +use \Magento\Catalog\Model\ProductRepository; +use \Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContentValidator; +use \Magento\Framework\Exception\InputException; +use \Magento\Framework\Json\EncoderInterface; +use \Magento\Downloadable\Model\SampleFactory; +use \Magento\Framework\Exception\NoSuchEntityException; + +class WriteService implements WriteServiceInterface +{ + /** + * @var ProductRepository + */ + protected $productRepository; + + /** + * @var DownloadableSampleContentValidator + */ + protected $contentValidator; + + /** + * @var FileContentUploaderInterface + */ + protected $fileContentUploader; + + /** + * @var EncoderInterface + */ + protected $jsonEncoder; + + /** + * @var \Magento\Downloadable\Model\LinkFactory + */ + protected $linkFactory; + + /** + * @param ProductRepository $productRepository + * @param DownloadableSampleContentValidator $contentValidator + * @param FileContentUploaderInterface $fileContentUploader + * @param EncoderInterface $jsonEncoder + * @param SampleFactory $sampleFactory + */ + public function __construct( + ProductRepository $productRepository, + DownloadableSampleContentValidator $contentValidator, + FileContentUploaderInterface $fileContentUploader, + EncoderInterface $jsonEncoder, + SampleFactory $sampleFactory + ) { + $this->productRepository = $productRepository; + $this->contentValidator = $contentValidator; + $this->fileContentUploader = $fileContentUploader; + $this->jsonEncoder = $jsonEncoder; + $this->sampleFactory = $sampleFactory; + } + + /** + * {@inheritdoc} + */ + public function create($productSku, DownloadableSampleContent $sampleContent, $isGlobalScopeContent = false) + { + $product = $this->productRepository->get($productSku, true); + if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) { + throw new InputException('Product type of the product must be \'downloadable\'.'); + } + if (!$this->contentValidator->isValid($sampleContent)) { + throw new InputException('Provided sample information is invalid.'); + } + + if (!in_array($sampleContent->getSampleType(), array('url', 'file'))) { + throw new InputException('Invalid sample type.'); + } + + $title = $sampleContent->getTitle(); + if (empty($title)) { + throw new InputException('Sample title cannot be empty.'); + } + + $sampleData = array( + 'sample_id' => 0, + 'is_delete' => 0, + 'type' => $sampleContent->getSampleType(), + 'sort_order' => $sampleContent->getSortOrder(), + 'title' => $sampleContent->getTitle(), + ); + + if ($sampleContent->getSampleType() == 'file') { + $sampleData['file'] = $this->jsonEncoder->encode(array( + $this->fileContentUploader->upload($sampleContent->getSampleFile(), 'sample') + )); + } else { + $sampleData['sample_url'] = $sampleContent->getSampleUrl(); + } + + $downloadableData = array('sample' => array($sampleData)); + $product->setDownloadableData($downloadableData); + if ($isGlobalScopeContent) { + $product->setStoreId(0); + } + $product->save(); + return $product->getLastAddedSampleId(); + } + + /** + * {@inheritdoc} + */ + public function update( + $productSku, + $sampleId, + DownloadableSampleContent $sampleContent, + $isGlobalScopeContent = false + ) { + $product = $this->productRepository->get($productSku, true); + /** @var $sample \Magento\Downloadable\Model\Sample */ + $sample = $this->sampleFactory->create()->load($sampleId); + if (!$sample->getId()) { + throw new NoSuchEntityException('There is no downloadable sample with provided ID.'); + } + if ($sample->getProductId() != $product->getId()) { + throw new InputException('Provided downloadable sample is not related to given product.'); + } + if (!$this->contentValidator->isValid($sampleContent)) { + throw new InputException('Provided sample information is invalid.'); + } + if ($isGlobalScopeContent) { + $product->setStoreId(0); + } + + $title = $sampleContent->getTitle(); + if (empty($title)) { + if ($isGlobalScopeContent) { + throw new InputException('Sample title cannot be empty.'); + } + // use title from GLOBAL scope + $sample->setTitle(null); + } else { + $sample->setTitle($sampleContent->getTitle()); + } + + $sample->setProductId($product->getId()) + ->setStoreId($product->getStoreId()) + ->setSortOrder($sampleContent->getSortOrder()) + ->save(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function delete($sampleId) + { + /** @var $sample \Magento\Downloadable\Model\Sample */ + $sample = $this->sampleFactory->create()->load($sampleId); + if (!$sample->getId()) { + throw new NoSuchEntityException('There is no downloadable sample with provided ID.'); + } + $sample->delete(); + return true; + } +} diff --git a/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceInterface.php b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..572dbe3f353ba279fac3b9c250f506fd73dbb16f --- /dev/null +++ b/app/code/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceInterface.php @@ -0,0 +1,65 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample; + +use \Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent; + +interface WriteServiceInterface +{ + /** + * Add downloadable sample to the given product + * + * @param string $productSku + * @param \Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent $sampleContent + * @param bool $isGlobalScopeContent + * @return int sample ID + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function create($productSku, DownloadableSampleContent $sampleContent, $isGlobalScopeContent = false); + + /** + * Update downloadable sample of the given product (sample type and its resource cannot be changed) + * + * @param string $productSku + * @param int $sampleId + * @param \Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent $sampleContent + * @param bool $isGlobalScopeContent + * @return bool + */ + public function update( + $productSku, + $sampleId, + DownloadableSampleContent $sampleContent, + $isGlobalScopeContent = false + ); + + /** + * Delete downloadable sample + * + * @param int $sampleId + * @return bool + */ + public function delete($sampleId); +} diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 8d51abb5b4681e1cc34f8e484eefb735d898164f..4f186c9934ecf7071814d37cf8243e78bb1f9867 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -75,4 +75,8 @@ </argument> </arguments> </type> + <preference for="\Magento\Downloadable\Service\V1\DownloadableLink\ReadServiceInterface" type="\Magento\Downloadable\Service\V1\DownloadableLink\ReadService" /> + <preference for="\Magento\Downloadable\Service\V1\DownloadableLink\WriteServiceInterface" type="\Magento\Downloadable\Service\V1\DownloadableLink\WriteService" /> + <preference for="\Magento\Downloadable\Service\V1\Data\FileContentUploaderInterface" type="\Magento\Downloadable\Service\V1\Data\FileContentUploader" /> + <preference for="\Magento\Downloadable\Service\V1\DownloadableSample\WriteServiceInterface" type="\Magento\Downloadable\Service\V1\DownloadableSample\WriteService" /> </config> diff --git a/app/code/Magento/Downloadable/etc/webapi.xml b/app/code/Magento/Downloadable/etc/webapi.xml new file mode 100644 index 0000000000000000000000000000000000000000..fd1001d7890ad5095ead1deed16e70641d1ef6c5 --- /dev/null +++ b/app/code/Magento/Downloadable/etc/webapi.xml @@ -0,0 +1,76 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd"> + <route url="/V1/products/:productSku/downloadable-links" method="GET"> + <service class="Magento\Downloadable\Service\V1\DownloadableLink\ReadServiceInterface" method="getLinks"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/:productSku/downloadable-links/samples" method="GET"> + <service class="Magento\Downloadable\Service\V1\DownloadableLink\ReadServiceInterface" method="getSamples"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/:productSku/downloadable-links" method="POST"> + <service class="Magento\Downloadable\Service\V1\DownloadableLink\WriteServiceInterface" method="create"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/:productSku/downloadable-links/:linkId" method="PUT"> + <service class="Magento\Downloadable\Service\V1\DownloadableLink\WriteServiceInterface" method="update"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/downloadable-links/:linkId" method="DELETE"> + <service class="Magento\Downloadable\Service\V1\DownloadableLink\WriteServiceInterface" method="delete"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/:productSku/downloadable-links/samples" method="POST"> + <service class="Magento\Downloadable\Service\V1\DownloadableSample\WriteServiceInterface" method="create"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/:productSku/downloadable-links/samples/:sampleId" method="PUT"> + <service class="Magento\Downloadable\Service\V1\DownloadableSample\WriteServiceInterface" method="update"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> + <route url="/V1/products/downloadable-links/samples/:sampleId" method="DELETE"> + <service class="Magento\Downloadable\Service\V1\DownloadableSample\WriteServiceInterface" method="delete"/> + <resources> + <resource ref="Magento_Downloadable::downloadable" /> + </resources> + </route> +</routes> diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php index d037f999c20397a5dd443459c79ae72cd90c7a84..5ff4a9bd0d1613c9069c97fc2ab4518989b5931a 100644 --- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php +++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php @@ -347,7 +347,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db if (is_numeric($attribute)) { $attribute = $this->getEntity()->getAttribute($attribute)->getAttributeCode(); - } else if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AttributeInterface) { + } elseif ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AttributeInterface) { $attribute = $attribute->getAttributeCode(); } @@ -357,7 +357,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '(' . implode(') OR (', $sqlArr) . ')'; - } else if (is_string($attribute)) { + } elseif (is_string($attribute)) { if ($condition === null) { $condition = ''; } diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php index 6f9f80768f503b49584a672c0e155d3d8fab0a1c..95fececde1f968a51c5235ed6dee95c59a759c77 100644 --- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php +++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php @@ -261,7 +261,7 @@ class Template extends \Magento\Backend\App\Action $templateBlock = $this->_view->getLayout()->createBlock('Magento\Email\Block\Adminhtml\Template\Edit'); $template->setData('orig_template_used_default_for', $templateBlock->getUsedDefaultForPaths(false)); - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($template->getData()) ); } catch (\Exception $e) { diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php index 2b1a595d3f397be2c806a24451d6e238dc1306d0..8582336c63588e22be78146d49a16898ca2b1462 100644 --- a/app/code/Magento/Fedex/Model/Carrier.php +++ b/app/code/Magento/Fedex/Model/Carrier.php @@ -133,6 +133,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C * @param \Magento\Directory\Model\CountryFactory $countryFactory * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory * @param \Magento\Directory\Helper\Data $directoryData + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Logger $logger * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Module\Dir\Reader $configReader @@ -155,6 +156,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Logger $logger, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Module\Dir\Reader $configReader, @@ -177,6 +179,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C $countryFactory, $currencyFactory, $directoryData, + $stockItemService, $data ); $wsdlBasePath = $configReader->getModuleDir('etc', 'Magento_Fedex') . '/wsdl/'; diff --git a/app/code/Magento/Fedex/etc/module.xml b/app/code/Magento/Fedex/etc/module.xml index 1635c68fe69c14cf718442eaedc53aba73552d70..8f13222ae32a69598908b2b77a36ff40c39b4540 100644 --- a/app/code/Magento/Fedex/etc/module.xml +++ b/app/code/Magento/Fedex/etc/module.xml @@ -32,6 +32,7 @@ <module name="Magento_Core"/> <module name="Magento_Catalog"/> <module name="Magento_Sales"/> + <module name="Magento_CatalogInventory"/> </depends> </module> </config> diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php index 0510cf67eae97d1f133519d5df59489a95203f8e..c92b4d9cc1feb96e91dc4def8a395f08c800cf47 100644 --- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php +++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php @@ -348,9 +348,8 @@ class Items extends \Magento\Backend\App\Action public function statusAction() { if ($this->getRequest()->isAjax()) { - $this->getResponse()->setHeader('Content-Type', 'application/json'); $params = array('is_running' => $this->_getFlag()->isLocked()); - return $this->getResponse()->setBody( + return $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($params) ); } @@ -377,10 +376,7 @@ class Items extends \Magento\Backend\App\Action ) ); if ($this->getRequest()->isAjax()) { - $this->getResponse()->setHeader( - 'Content-Type', - 'application/json' - )->setBody( + $this->getResponse()->representJson( $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('redirect' => $redirectUrl)) ); } else { diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Content.php b/app/code/Magento/GoogleShopping/Model/Attribute/Content.php index 7633d70cd5c868ca50db3550e378c2b7b4134faa..b750290f0f9762b72fcb30a19acfdfdbbcbb0b0e 100644 --- a/app/code/Magento/GoogleShopping/Model/Attribute/Content.php +++ b/app/code/Magento/GoogleShopping/Model/Attribute/Content.php @@ -42,7 +42,7 @@ class Content extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute { $mapValue = $this->getProductAttributeValue($product); $description = $this->getGroupAttributeDescription(); - if (!is_null($description)) { + if (!is_null($description) && !is_null($description->getAttributeId())) { $mapValue = $description->getProductAttributeValue($product); } diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php index ec2d14c25857b7c872f4a1456e910025ad08c37e..154086e87ced19c3026d01aa6226446096cf6f0b 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php @@ -470,4 +470,15 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product) { } + + /** + * {@inheritdoc} + */ + public function beforeSave($product) + { + if ($product->hasData('product_options')) { + throw new \Exception('Custom options for grouped product type are not supported'); + } + return parent::beforeSave($product); + } } diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php index ab82118a0f789ace288175d6261807a5dcc13364..e161451c1eb8ee6cb374361d43ac112a1c769a39 100644 --- a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php +++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php @@ -266,7 +266,7 @@ class Integration extends Action } if ($this->getRequest()->isXmlHttpRequest()) { $isTokenExchange = $integration->getEndpoint() && $integration->getIdentityLinkUrl() ? '1' : '0'; - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_coreHelper->jsonEncode( array('integrationId' => $integration->getId(), 'isTokenExchange' => $isTokenExchange) ) @@ -446,7 +446,7 @@ class Integration extends Action IntegrationModel::CONSUMER_ID => $integration->getConsumerId(), 'popup_content' => $popupContent ); - $this->getResponse()->setBody($this->_coreHelper->jsonEncode($result)); + $this->getResponse()->representJson($this->_coreHelper->jsonEncode($result)); } catch (\Magento\Framework\Model\Exception $e) { $this->messageManager->addError($e->getMessage()); $this->_redirect('*/*'); @@ -494,7 +494,7 @@ class Integration extends Action protected function _redirect($path, $arguments = array()) { if ($this->getRequest()->isXmlHttpRequest()) { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_coreHelper->jsonEncode(array('_redirect' => $this->getUrl($path, $arguments))) ); return $this; diff --git a/app/code/Magento/Paypal/Model/Observer.php b/app/code/Magento/Paypal/Model/Observer.php index c2d6515ab78eea95b61c32718384e7199dce2081..5a8782ba83130dfe5f1a784c377c8faf3430a608 100644 --- a/app/code/Magento/Paypal/Model/Observer.php +++ b/app/code/Magento/Paypal/Model/Observer.php @@ -202,7 +202,7 @@ class Observer $result['redirect'] = false; $result['success'] = false; $controller->getResponse()->clearHeader('Location'); - $controller->getResponse()->setBody($this->_coreData->jsonEncode($result)); + $controller->getResponse()->representJson($this->_coreData->jsonEncode($result)); } } } diff --git a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View/Items.php b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View/Items.php index 665f4e87a0f73adc04bed801fbe23d8a3f6f1a7e..b6a979ea3ce17b0a8fcf5c9e9c0510caa36f476d 100644 --- a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View/Items.php +++ b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View/Items.php @@ -25,8 +25,6 @@ namespace Magento\RecurringPayment\Block\Adminhtml\Payment\View; /** * Adminhtml recurring payment items grid - * - * @author Magento Core Team <core@magentocommerce.com> */ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { @@ -34,6 +32,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems * Retrieve required options from parent * * @return void + * @throws \Magento\Framework\Model\Exception */ protected function _beforeToHtml() { diff --git a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php index 7989688d704d8bd9ce277d41fd75269632bd5fc9..839db3bcb646852e9081af123528ba724135df49 100644 --- a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php @@ -47,7 +47,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection protected $_inventoryItemTableAlias = 'lowstock_inventory_item'; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ protected $stockItemService; @@ -78,7 +78,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection * @param \Magento\Catalog\Model\Resource\Product $product * @param \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory * @param \Magento\Catalog\Model\Product\Type $productType - * @param \Magento\CatalogInventory\Service\V1\StockItem $stockItemService + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\CatalogInventory\Model\Resource\Stock\Item $itemResource * @param mixed $connection * @@ -106,7 +106,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection \Magento\Catalog\Model\Resource\Product $product, \Magento\Reports\Model\Event\TypeFactory $eventTypeFactory, \Magento\Catalog\Model\Product\Type $productType, - \Magento\CatalogInventory\Service\V1\StockItem $stockItemService, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\CatalogInventory\Model\Resource\Stock\Item $itemResource, $connection = null ) { diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product.php b/app/code/Magento/Review/Controller/Adminhtml/Product.php index e2877ab095828df0a98f81ce4c02364b30af10ec..c96d02271c38b9f70b131f7ff57e8ac2eb0ce4e5 100644 --- a/app/code/Magento/Review/Controller/Adminhtml/Product.php +++ b/app/code/Magento/Review/Controller/Adminhtml/Product.php @@ -370,7 +370,7 @@ class Product extends \Magento\Backend\App\Action $response->setError(1); $response->setMessage(__('We can\'t get the product ID.')); } - $this->getResponse()->setBody($response->toJSON()); + $this->getResponse()->representJson($response->toJSON()); } /** diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php index d7f7c8d3bb78cad053bcc435191f2e84ff1f5fff..aca5ad37d2e0908a22f817a38271204b1bda2792 100644 --- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php +++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php @@ -404,7 +404,7 @@ abstract class AbstractCondition extends \Magento\Framework\Object implements Co if (in_array($option['value'], $value)) { $valueArr[] = $option['label']; } - } else { + } elseif (isset($option['value'])) { if (is_array($option['value'])) { foreach ($option['value'] as $optionValue) { if ($optionValue['value'] == $value) { diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php index c984002ae1eaf2bee9f7e47c569ef238ecc47544..0980463bccff908677415044accac3c89e17205c 100644 --- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php +++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php @@ -217,6 +217,15 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon ->setEntityTypeFilter($entityTypeId) ->load() ->toOptionArray(); + } elseif ($this->getAttribute() === 'type_id') { + foreach ($selectReady as $value => $label) { + if (is_array($label) && isset($label['value'])) { + $selectOptions[] = $label; + } else { + $selectOptions[] = array('value' => $value, 'label' => $label); + } + } + $selectReady = null; } elseif (is_object($this->getAttributeObject())) { $attributeObject = $this->getAttributeObject(); if ($attributeObject->usesSource()) { diff --git a/app/code/Magento/Sales/Block/Adminhtml/Items/AbstractItems.php b/app/code/Magento/Sales/Block/Adminhtml/Items/AbstractItems.php index e2a0a0bb002fd5fc39e9d0c5f617a191e324da84..ec740624191627e9a4ad4e02002f187b50d41cc7 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Items/AbstractItems.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Items/AbstractItems.php @@ -51,33 +51,33 @@ class AbstractItems extends \Magento\Backend\Block\Template * * @var bool|null */ - protected $_canEditQty = null; + protected $_canEditQty; /** * Core registry * * @var \Magento\Framework\Registry */ - protected $_coreRegistry = null; + protected $_coreRegistry; /** - * @var \Magento\Catalog\Model\ProductFactory + * @var \Magento\CatalogInventory\Service\V1\StockItemService */ - protected $_productFactory; + protected $stockItemService; /** * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Registry $registry * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, - \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Registry $registry, array $data = array() ) { - $this->_productFactory = $productFactory; + $this->stockItemService = $stockItemService; $this->_coreRegistry = $registry; parent::__construct($context, $data); } @@ -331,14 +331,14 @@ class AbstractItems extends \Magento\Backend\Block\Template public function displayPriceInclTax(\Magento\Framework\Object $item) { $qty = $item->getQtyOrdered() ? $item->getQtyOrdered() : ($item->getQty() ? $item->getQty() : 1); - $baseTax = $item->getTaxBeforeDiscount() ? $item - ->getTaxBeforeDiscount() : ($item - ->getTaxAmount() ? $item - ->getTaxAmount() : 0); - $tax = $item->getBaseTaxBeforeDiscount() ? $item - ->getBaseTaxBeforeDiscount() : ($item - ->getBaseTaxAmount() ? $item - ->getBaseTaxAmount() : 0); + + $baseTax = $item->getTaxBeforeDiscount() + ? $item->getTaxBeforeDiscount() + : ($item->getTaxAmount() ? $item->getTaxAmount() : 0); + + $tax = $item->getBaseTaxBeforeDiscount() + ? $item->getBaseTaxBeforeDiscount() + : ($item->getBaseTaxAmount() ? $item->getBaseTaxAmount() : 0); $basePriceTax = 0; $priceTax = 0; @@ -362,14 +362,13 @@ class AbstractItems extends \Magento\Backend\Block\Template */ public function displaySubtotalInclTax($item) { - $baseTax = $item->getTaxBeforeDiscount() ? $item - ->getTaxBeforeDiscount() : ($item - ->getTaxAmount() ? $item - ->getTaxAmount() : 0); - $tax = $item->getBaseTaxBeforeDiscount() ? $item - ->getBaseTaxBeforeDiscount() : ($item - ->getBaseTaxAmount() ? $item - ->getBaseTaxAmount() : 0); + $baseTax = $item->getTaxBeforeDiscount() + ? $item->getTaxBeforeDiscount() + : ($item->getTaxAmount() ? $item->getTaxAmount() : 0); + + $tax = $item->getBaseTaxBeforeDiscount() + ? $item->getBaseTaxBeforeDiscount() + : ($item->getBaseTaxAmount() ? $item->getBaseTaxAmount() : 0); return $this->displayPrices($item->getBaseRowTotal() + $baseTax, $item->getRowTotal() + $tax); } @@ -397,7 +396,7 @@ class AbstractItems extends \Magento\Backend\Block\Template } /** - * Retrieve tax with persent html content + * Retrieve tax with percent html content * * @param \Magento\Framework\Object $item * @return string @@ -462,11 +461,8 @@ class AbstractItems extends \Magento\Backend\Block\Template * Disable editing of quantity of item if creating of shipment forced * and ship partially disabled for order */ - if ($this->getOrder()->getForcedShipmentWithInvoice() && ($this->canShipPartially( - $this->getOrder() - ) || $this->canShipPartiallyItem( - $this->getOrder() - )) + if ($this->getOrder()->getForcedShipmentWithInvoice() + && ($this->canShipPartially($this->getOrder()) || $this->canShipPartiallyItem($this->getOrder())) ) { return false; } @@ -527,11 +523,11 @@ class AbstractItems extends \Magento\Backend\Block\Template */ public function canReturnToStock() { - if ($this->_scopeConfig->getValue( + $canSubtract = $this->_scopeConfig->getValue( \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT, \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) - ) { + ); + if ($canSubtract) { return true; } else { return false; @@ -546,20 +542,21 @@ class AbstractItems extends \Magento\Backend\Block\Template */ public function canReturnItemToStock($item = null) { - $canReturnToStock = $this->_scopeConfig->getValue( - \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ); - if (!is_null($item)) { + if (null !== $item) { if (!$item->hasCanReturnToStock()) { - $product = $this->_productFactory->create()->load($item->getOrderItem()->getProductId()); - if ($product->getId() && $product->getStockItem()->getManageStock()) { + $productId = $item->getOrderItem()->getProductId(); + if ($productId && $this->stockItemService->getManageStock($productId)) { $item->setCanReturnToStock(true); } else { $item->setCanReturnToStock(false); } } $canReturnToStock = $item->getCanReturnToStock(); + } else { + $canReturnToStock = $this->_scopeConfig->getValue( + \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); } return $canReturnToStock; } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Items/Renderer/DefaultRenderer.php b/app/code/Magento/Sales/Block/Adminhtml/Items/Renderer/DefaultRenderer.php index f78de758024c3e0dfd5b48ec093872b02afd9f96..f7f6c1028c7eee9a1368ffabfc19cac772511777 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Items/Renderer/DefaultRenderer.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Items/Renderer/DefaultRenderer.php @@ -27,8 +27,6 @@ use Magento\Sales\Model\Order\Item; /** * Adminhtml sales order item renderer - * - * @author Magento Core Team <core@magentocommerce.com> */ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php index e814cc6f8ab8a4b6c660dbc9ae967b629c4f5fc8..10431e2c48be9d414dd838b89d20bafe97089f0e 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php @@ -29,8 +29,6 @@ use Magento\Framework\Session\SessionManagerInterface; /** * Adminhtml sales order create items grid block - * - * @author Magento Core Team <core@magentocommerce.com> */ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate { @@ -46,7 +44,7 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate * * @var \Magento\Tax\Helper\Data */ - protected $_taxData = null; + protected $_taxData; /** * Wishlist factory @@ -76,6 +74,11 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate */ protected $_messageHelper; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Model\Session\Quote $sessionQuote @@ -85,6 +88,7 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate * @param \Magento\Tax\Model\Config $taxConfig * @param \Magento\Tax\Helper\Data $taxData * @param \Magento\GiftMessage\Helper\Message $messageHelper + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( @@ -96,6 +100,7 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate \Magento\Tax\Model\Config $taxConfig, \Magento\Tax\Helper\Data $taxData, \Magento\GiftMessage\Helper\Message $messageHelper, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_messageHelper = $messageHelper; @@ -103,6 +108,7 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate $this->_giftMessageSave = $giftMessageSave; $this->_taxConfig = $taxConfig; $this->_taxData = $taxData; + $this->stockItemService = $stockItemService; parent::__construct($context, $sessionQuote, $orderCreate, $data); } @@ -132,24 +138,27 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate $item->setQty($item->getQty()); if (!$item->getMessage()) { - //Getting stock items for last quantity validation before grid display + //Getting product ids for stock item last quantity validation before grid display $stockItemToCheck = array(); $childItems = $item->getChildren(); if (count($childItems)) { foreach ($childItems as $childItem) { - $stockItemToCheck[] = $childItem->getProduct()->getStockItem(); + $stockItemToCheck[] = $childItem->getProduct()->getId(); } } else { - $stockItemToCheck[] = $item->getProduct()->getStockItem(); + $stockItemToCheck[] = $item->getProduct()->getId(); } - foreach ($stockItemToCheck as $stockItem) { - if ($stockItem instanceof \Magento\CatalogInventory\Model\Stock\Item) { - $check = $stockItem->checkQuoteItemQty($item->getQty(), $item->getQty(), $item->getQty()); - $item->setMessage($check->getMessage()); - $item->setHasError($check->getHasError()); - } + foreach ($stockItemToCheck as $productId) { + $check = $this->stockItemService->checkQuoteItemQty( + $productId, + $item->getQty(), + $item->getQty(), + $item->getQty() + ); + $item->setMessage($check->getMessage()); + $item->setHasError($check->getHasError()); } } @@ -227,7 +236,6 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate if (is_null($item)) { return $this->_messageHelper->getIsMessagesAvailable('items', $this->getQuote(), $this->getStore()); } - return $this->_messageHelper->getIsMessagesAvailable('item', $item, $this->getStore()); } @@ -249,12 +257,9 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate */ public function displayTotalsIncludeTax() { - $res = $this->_taxConfig->displayCartSubtotalInclTax( - $this->getStore() - ) || $this->_taxConfig->displayCartSubtotalBoth( - $this->getStore() - ); - return $res; + $result = $this->_taxConfig->displayCartSubtotalInclTax($this->getStore()) + || $this->_taxConfig->displayCartSubtotalBoth($this->getStore()); + return $result; } /** @@ -265,15 +270,13 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate public function getSubtotal() { $address = $this->getQuoteAddress(); - if ($this->displayTotalsIncludeTax()) { - if ($address->getSubtotalInclTax()) { - return $address->getSubtotalInclTax(); - } - return $address->getSubtotal() + $address->getTaxAmount(); - } else { + if (!$this->displayTotalsIncludeTax()) { return $address->getSubtotal(); } - return false; + if ($address->getSubtotalInclTax()) { + return $address->getSubtotalInclTax(); + } + return $address->getSubtotal() + $address->getTaxAmount(); } /** @@ -372,13 +375,13 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate $html = ''; $prices = $item->getProduct()->getTierPrice(); if ($prices) { - $info = $item->getProductType() == - \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE ? $this->_getBundleTierPriceInfo( - $prices - ) : $this->_getTierPriceInfo( - $prices - ); - $html = implode('<br/>', $info); + if ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { + $info = $this->_getBundleTierPriceInfo($prices); + } else { + $info = $this->_getTierPriceInfo($prices); + } + + $html = implode('<br />', $info); } return $html; } @@ -428,19 +431,13 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate $this->_moveToCustomerStorage = true; if ($optionIds = $item->getOptionByCode('option_ids')) { foreach (explode(',', $optionIds->getValue()) as $optionId) { - if ($option = $item->getProduct()->getOptionById($optionId)) { - $optionValue = $item->getOptionByCode('option_' . $option->getId())->getValue(); - + $option = $item->getProduct()->getOptionById($optionId); + if ($option) { $optionStr .= $option->getTitle() . ':'; - $quoteItemOption = $item->getOptionByCode('option_' . $option->getId()); - $group = $option->groupFactory( - $option->getType() - )->setOption( - $option - )->setQuoteItemOption( - $quoteItemOption - ); + $group = $option->groupFactory($option->getType()) + ->setOption($option) + ->setQuoteItemOption($quoteItemOption); $optionStr .= $group->getEditableOptionValue($quoteItemOption->getValue()); $optionStr .= "\n"; diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php index 843964182bc51e9c2c48855da3cb5384c8d4650e..2a6765fe2e89128a9b03c3a23caa7989fef9edee 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php @@ -24,7 +24,7 @@ namespace Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create; /** - * Adminhtml creditmemo items grid + * Adminhtml credit memo items grid */ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { @@ -38,24 +38,24 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems * * @var \Magento\Sales\Helper\Data */ - protected $_salesData = null; + protected $_salesData; /** * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Registry $registry * @param \Magento\Sales\Helper\Data $salesData * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, - \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Registry $registry, \Magento\Sales\Helper\Data $salesData, array $data = array() ) { $this->_salesData = $salesData; - parent::__construct($context, $productFactory, $registry, $data); + parent::__construct($context, $stockItemService, $registry, $data); } /** @@ -139,7 +139,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems } /** - * Retrieve order totalbar block data + * Retrieve order total bar block data * * @return array */ @@ -147,17 +147,17 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { $this->setPriceDataObject($this->getOrder()); - $totalbarData = array(); - $totalbarData[] = array(__('Paid Amount'), $this->displayPriceAttribute('total_invoiced'), false); - $totalbarData[] = array(__('Refund Amount'), $this->displayPriceAttribute('total_refunded'), false); - $totalbarData[] = array(__('Shipping Amount'), $this->displayPriceAttribute('shipping_invoiced'), false); - $totalbarData[] = array(__('Shipping Refund'), $this->displayPriceAttribute('shipping_refunded'), false); - $totalbarData[] = array(__('Order Grand Total'), $this->displayPriceAttribute('grand_total'), true); - return $totalbarData; + $totalBarData = array(); + $totalBarData[] = array(__('Paid Amount'), $this->displayPriceAttribute('total_invoiced'), false); + $totalBarData[] = array(__('Refund Amount'), $this->displayPriceAttribute('total_refunded'), false); + $totalBarData[] = array(__('Shipping Amount'), $this->displayPriceAttribute('shipping_invoiced'), false); + $totalBarData[] = array(__('Shipping Refund'), $this->displayPriceAttribute('shipping_refunded'), false); + $totalBarData[] = array(__('Order Grand Total'), $this->displayPriceAttribute('grand_total'), true); + return $totalBarData; } /** - * Retrieve creditmemo model instance + * Retrieve credit memo model instance * * @return \Magento\Sales\Model\Order\Creditmemo */ @@ -238,21 +238,23 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems if ($this->_canReturnToStock) { $canReturnToStock = false; foreach ($this->getCreditmemo()->getAllItems() as $item) { - $product = $this->_productFactory->create()->load($item->getOrderItem()->getProductId()); - if ($product->getId() && $product->getStockItem()->getManageStock()) { - $item->setCanReturnToStock($canReturnToStock = true); + $productId = $item->getOrderItem()->getProductId(); + if ($productId && $this->stockItemService->getManageStock($productId)) { + $canReturnToStock = true; + $item->setCanReturnToStock($canReturnToStock); } else { $item->setCanReturnToStock(false); } } - $this->getCreditmemo()->getOrder()->setCanReturnToStock($this->_canReturnToStock = $canReturnToStock); + $this->_canReturnToStock = $canReturnToStock; + $this->getCreditmemo()->getOrder()->setCanReturnToStock($this->_canReturnToStock); } } return $this->_canReturnToStock; } /** - * Check allow to send new creditmemo email + * Check allow to send new credit memo email * * @return bool */ diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View/Items.php index 18eee6b475b5d008260170695007a03f252e4a7c..a685c0dbd2dc78aaeea4665ad6315afa7f5da0f8 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View/Items.php @@ -25,8 +25,6 @@ namespace Magento\Sales\Block\Adminhtml\Order\Creditmemo\View; /** * Adminhtml sales item renderer - * - * @author Magento Core Team <core@magentocommerce.com> */ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create/Items.php index 3ec26424e0e1275486d5a1f3b076ee569e7846be..5cecff1a0092a00923ca8a676f9cdeb040f2050d 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create/Items.php @@ -40,24 +40,24 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems * * @var \Magento\Sales\Helper\Data */ - protected $_salesData = null; + protected $_salesData; /** * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Registry $registry * @param \Magento\Sales\Helper\Data $salesData * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, - \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Registry $registry, \Magento\Sales\Helper\Data $salesData, array $data = array() ) { $this->_salesData = $salesData; - parent::__construct($context, $productFactory, $registry, $data); + parent::__construct($context, $stockItemService, $registry, $data); } /** @@ -74,14 +74,14 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems array('class' => 'update-button', 'label' => __('Update Qty\'s'), 'onclick' => $onclick) ); $this->_disableSubmitButton = true; - $_submitButtonClass = ' disabled'; + $submitButtonClass = ' disabled'; foreach ($this->getInvoice()->getAllItems() as $item) { /** * @see bug #14839 */ if ($item->getQty()/* || $this->getSource()->getData('base_grand_total')*/) { $this->_disableSubmitButton = false; - $_submitButtonClass = ''; + $submitButtonClass = ''; break; } } @@ -95,7 +95,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems 'Magento\Backend\Block\Widget\Button', array( 'label' => $_submitLabel, - 'class' => 'save submit-button primary' . $_submitButtonClass, + 'class' => 'save submit-button primary' . $submitButtonClass, 'onclick' => 'disableElements(\'submit-button\');$(\'edit_form\').submit()', 'disabled' => $this->_disableSubmitButton ) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View/Items.php index 5bdc307678a9c9344e223d95e0703427eb66ac8a..4c691e3b7ef96899ba6d5d489ae4e6a353c59c56 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View/Items.php @@ -25,8 +25,6 @@ namespace Magento\Sales\Block\Adminhtml\Order\Invoice\View; /** * Adminhtml sales item renderer - * - * @author Magento Core Team <core@magentocommerce.com> */ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items.php index ed4dbdf541c1c9925b6fcad9f04e97450fc54826..50d72a5b4b56841560c695951041d2c2bd758442 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items.php @@ -27,8 +27,6 @@ use Magento\Sales\Model\Resource\Order\Item\Collection; /** * Adminhtml order items grid - * - * @author Magento Core Team <core@magentocommerce.com> */ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php index 27b502c28a3c262fa62546d00ad920c420c01cfe..a8fa90a493aeb328b1ffd17f247ed09adaa6b167 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php @@ -27,7 +27,6 @@ use Magento\Sales\Model\Order\Item; /** * Adminhtml sales order item renderer - * */ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { @@ -45,9 +44,16 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems */ protected $_checkoutHelper; + /** + * Giftmessage object + * + * @var \Magento\GiftMessage\Model\Message + */ + protected $_giftMessage = array(); + /** * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Registry $registry * @param \Magento\GiftMessage\Helper\Message $messageHelper * @param \Magento\Checkout\Helper\Data $checkoutHelper @@ -55,7 +61,7 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems */ public function __construct( \Magento\Backend\Block\Template\Context $context, - \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Registry $registry, \Magento\GiftMessage\Helper\Message $messageHelper, \Magento\Checkout\Helper\Data $checkoutHelper, @@ -63,7 +69,7 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems ) { $this->_checkoutHelper = $checkoutHelper; $this->_messageHelper = $messageHelper; - parent::__construct($context, $productFactory, $registry, $data); + parent::__construct($context, $stockItemService, $registry, $data); } /** @@ -107,13 +113,6 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems return $this->getRequest()->getParam('reload') != 1; } - /** - * Giftmessage object - * - * @var \Magento\GiftMessage\Model\Message - */ - protected $_giftMessage = array(); - /** * Retrieve default value for giftmessage sender * @@ -146,14 +145,14 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems if ($this->getItem()->getOrder()) { if ($this->getItem()->getOrder()->getShippingAddress()) { return $this->getItem()->getOrder()->getShippingAddress()->getName(); - } else if ($this->getItem()->getOrder()->getBillingAddress()) { + } elseif ($this->getItem()->getOrder()->getBillingAddress()) { return $this->getItem()->getOrder()->getBillingAddress()->getName(); } } if ($this->getItem()->getShippingAddress()) { return $this->getItem()->getShippingAddress()->getName(); - } else if ($this->getItem()->getBillingAddress()) { + } elseif ($this->getItem()->getBillingAddress()) { return $this->getItem()->getBillingAddress()->getName(); } diff --git a/app/code/Magento/Sales/Block/Reorder/Sidebar.php b/app/code/Magento/Sales/Block/Reorder/Sidebar.php index aec1518410413088e5dee94810ed1b0e7c1b9f30..59f5f8f969997ba426b0a32f62e3c973281d91b5 100644 --- a/app/code/Magento/Sales/Block/Reorder/Sidebar.php +++ b/app/code/Magento/Sales/Block/Reorder/Sidebar.php @@ -23,14 +23,21 @@ */ namespace Magento\Sales\Block\Reorder; +use Magento\Framework\View\Block\IdentityInterface; + /** * Sales order view block * * @method Sidebar setOrders(\Magento\Sales\Model\Resource\Order\Collection $ordersCollection) * @method \Magento\Sales\Model\Resource\Order\Collection|null getOrders() */ -class Sidebar extends \Magento\Framework\View\Element\Template implements \Magento\Framework\View\Block\IdentityInterface +class Sidebar extends \Magento\Framework\View\Element\Template implements IdentityInterface { + /** + * Limit of orders in side bar + */ + const SIDEBAR_ORDER_LIMIT = 5; + /** * @var string */ @@ -56,12 +63,18 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen */ protected $httpContext; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Magento\Sales\Model\Resource\Order\CollectionFactory $orderCollectionFactory * @param \Magento\Sales\Model\Order\Config $orderConfig * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Framework\App\Http\Context $httpContext + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( @@ -70,12 +83,14 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen \Magento\Sales\Model\Order\Config $orderConfig, \Magento\Customer\Model\Session $customerSession, \Magento\Framework\App\Http\Context $httpContext, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_orderCollectionFactory = $orderCollectionFactory; $this->_orderConfig = $orderConfig; $this->_customerSession = $customerSession; $this->httpContext = $httpContext; + $this->stockItemService = $stockItemService; parent::__construct($context, $data); $this->_isScopePrivate = true; } @@ -100,25 +115,14 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen */ public function initOrders() { - $customerId = $this->getCustomerId() - ? $this->getCustomerId() - : $this->_customerSession->getCustomerId(); - - $orders = $this->_orderCollectionFactory->create()->addAttributeToFilter( - 'customer_id', - $customerId - )->addAttributeToFilter( - 'status', - array('in' => $this->_orderConfig->getVisibleOnFrontStatuses()) - )->addAttributeToSort( - 'created_at', - 'desc' - )->setPage( - 1, - 1 - ); - //TODO: add filter by current website + $customerId = $this->getCustomerId() ? $this->getCustomerId() : $this->_customerSession->getCustomerId(); + $orders = $this->_orderCollectionFactory->create() + ->addAttributeToFilter('customer_id', $customerId) + ->addAttributeToFilter('status', array('in' => $this->_orderConfig->getVisibleOnFrontStatuses())) + ->addAttributeToSort('created_at', 'desc') + ->setPage(1, 1); + //TODO: add filter by current website $this->setOrders($orders); } @@ -131,7 +135,7 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen { $items = array(); $order = $this->getLastOrder(); - $limit = 5; + $limit = self::SIDEBAR_ORDER_LIMIT; if ($order) { $website = $this->_storeManager->getStore()->getWebsiteId(); @@ -154,7 +158,7 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen public function isItemAvailableForReorder(\Magento\Sales\Model\Order\Item $orderItem) { if ($orderItem->getProduct()) { - return $orderItem->getProduct()->getStockItem()->getIsInStock(); + return $this->stockItemService->getIsInStock($orderItem->getProduct()->getId()); } return false; } @@ -177,12 +181,12 @@ class Sidebar extends \Magento\Framework\View\Element\Template implements \Magen */ public function getLastOrder() { - if ($this->getOrders()) { - foreach ($this->getOrders() as $order) { - return $order; - } + if (!$this->getOrders()) { + return false; + } + foreach ($this->getOrders() as $order) { + return $order; } - return false; } /** diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order.php b/app/code/Magento/Sales/Controller/Adminhtml/Order.php index da85ffbc0b0df5907e0af6d3f9397ec446cae334..a133311875721ced54c6189c5b79d2b0302304d1 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order.php @@ -346,7 +346,7 @@ class Order extends \Magento\Backend\App\Action } if (is_array($response)) { $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); - $this->getResponse()->setBody($response); + $this->getResponse()->representJson($response); } } } diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php index ba04710ceba00c2bc2934b7623bf0273a6ab73e3..407c9c46c298951d1d877ac3d32c8032ca230c99 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php @@ -274,17 +274,21 @@ class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\Abstract public function updateQtyAction() { try { - $creditmemo = $this->_initCreditmemo(true); + $this->_initCreditmemo(true); $this->_view->loadLayout(); $response = $this->_view->getLayout()->getBlock('order_items')->toHtml(); } catch (\Magento\Framework\Model\Exception $e) { $response = array('error' => true, 'message' => $e->getMessage()); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } catch (\Exception $e) { $response = array('error' => true, 'message' => __('Cannot update the item\'s quantity.')); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } - $this->getResponse()->setBody($response); + if (is_array($response)) { + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); + } } /** @@ -431,12 +435,16 @@ class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\Abstract $response = $this->_view->getLayout()->getBlock('creditmemo_comments')->toHtml(); } catch (\Magento\Framework\Model\Exception $e) { $response = array('error' => true, 'message' => $e->getMessage()); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } catch (\Exception $e) { $response = array('error' => true, 'message' => __('Cannot add new comment.')); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } - $this->getResponse()->setBody($response); + if (is_array($response)) { + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); + } } /** diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php index fe3cbe0dffdbf5e8e752b4a2069052596c68c9a6..ac9deb269c5eac8b2b47cddcf5804519cc180f61 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php @@ -257,12 +257,16 @@ class Invoice extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoic $response = $this->_view->getLayout()->getBlock('order_items')->toHtml(); } catch (Exception $e) { $response = array('error' => true, 'message' => $e->getMessage()); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } catch (\Exception $e) { $response = array('error' => true, 'message' => __('Cannot update item quantity.')); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } - $this->getResponse()->setBody($response); + if (is_array($response)) { + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); + } } /** @@ -467,12 +471,16 @@ class Invoice extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoic $response = $this->_view->getLayout()->getBlock('invoice_comments')->toHtml(); } catch (Exception $e) { $response = array('error' => true, 'message' => $e->getMessage()); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } catch (\Exception $e) { $response = array('error' => true, 'message' => __('Cannot add new comment.')); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } - $this->getResponse()->setBody($response); + if (is_array($response)) { + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); + } } /** diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 4ce2ec237a0565632d27e0df909935da8b541701..f20714821098ff61f96d16b325131365ada6cfae 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -187,6 +187,11 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode */ protected $_scopeConfig; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\ObjectManager $objectManager * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -205,6 +210,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode * @param \Magento\Customer\Helper\Data $customerHelper * @param CustomerGroupServiceInterface $customerGroupService * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data */ public function __construct( @@ -225,6 +231,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode \Magento\Customer\Helper\Data $customerHelper, CustomerGroupServiceInterface $customerGroupService, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_objectManager = $objectManager; @@ -244,6 +251,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode $this->_customerHelper = $customerHelper; $this->_customerGroupService = $customerGroupService; $this->_scopeConfig = $scopeConfig; + $this->stockItemService = $stockItemService; parent::__construct($data); } @@ -979,12 +987,11 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode } if ($item) { - if ($item->getProduct()->getStockItem()) { - if (!$item->getProduct()->getStockItem()->getIsQtyDecimal()) { - $itemQty = (int)$itemQty; - } else { - $item->setIsQtyDecimal(1); - } + $stockItemDo = $this->stockItemService->getStockItem($item->getProduct()->getId()); + if ($stockItemDo->getStockId() && !$stockItemDo->getIsQtyDecimal()) { + $itemQty = (int)$itemQty; + } else { + $item->setIsQtyDecimal(1); } $itemQty = $itemQty > 0 ? $itemQty : 1; if (isset($info['custom_price'])) { diff --git a/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php b/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php index 87c042146abbd32867daca222420baec0080a3da..f143e968898db8e77f2b4d3334b87449a375701a 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php @@ -32,6 +32,20 @@ namespace Magento\Sales\Model\AdminOrder\Product\Quote; class Initializer { + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + + /** + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + */ + public function __construct( + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService + ) { + $this->stockItemService = $stockItemService; + } + /** * @param \Magento\Sales\Model\Quote $quote * @param \Magento\Catalog\Model\Product $product @@ -43,8 +57,9 @@ class Initializer \Magento\Catalog\Model\Product $product, \Magento\Framework\Object $config ) { - $stockItem = $product->getStockItem(); - if ($stockItem && $stockItem->getIsQtyDecimal()) { + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */ + $stockItemDo = $this->stockItemService->getStockItem($product->getId()); + if ($stockItemDo->getStockId() && $stockItemDo->getIsQtyDecimal()) { $product->setIsQtyDecimal(1); } else { $config->setQty((int)$config->getQty()); diff --git a/app/code/Magento/Sales/Model/Convert/Quote.php b/app/code/Magento/Sales/Model/Convert/Quote.php index c91e3d058e9b9c8bf868c326189ed230379aa2d0..2ab28baada57a2fd96a54c6255559dac489f7a90 100644 --- a/app/code/Magento/Sales/Model/Convert/Quote.php +++ b/app/code/Magento/Sales/Model/Convert/Quote.php @@ -22,11 +22,11 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +namespace Magento\Sales\Model\Convert; + /** * Quote data convert model */ -namespace Magento\Sales\Model\Convert; - class Quote extends \Magento\Framework\Object { /** @@ -34,7 +34,7 @@ class Quote extends \Magento\Framework\Object * * @var \Magento\Framework\Event\ManagerInterface */ - protected $_eventManager = null; + protected $_eventManager; /** * @var \Magento\Sales\Model\OrderFactory @@ -101,18 +101,11 @@ class Quote extends \Magento\Framework\Object $order = $this->_orderFactory->create(); } /* @var $order \Magento\Sales\Model\Order */ - - $order->setIncrementId( - $quote->getReservedOrderId() - )->setStoreId( - $quote->getStoreId() - )->setQuoteId( - $quote->getId() - )->setQuote( - $quote - )->setCustomer( - $quote->getCustomer() - ); + $order->setIncrementId($quote->getReservedOrderId()) + ->setStoreId($quote->getStoreId()) + ->setQuoteId($quote->getId()) + ->setQuote($quote) + ->setCustomer($quote->getCustomer()); $this->_objectCopyService->copyFieldsetToTarget('sales_convert_quote', 'to_order', $quote, $order); $this->_eventManager->dispatch('sales_convert_quote_to_order', array('order' => $order, 'quote' => $quote)); @@ -149,15 +142,11 @@ class Quote extends \Magento\Framework\Object */ public function addressToOrderAddress(\Magento\Sales\Model\Quote\Address $address) { - $orderAddress = $this->_orderAddressFactory->create()->setStoreId( - $address->getStoreId() - )->setAddressType( - $address->getAddressType() - )->setCustomerId( - $address->getCustomerId() - )->setCustomerAddressId( - $address->getCustomerAddressId() - ); + $orderAddress = $this->_orderAddressFactory->create() + ->setStoreId($address->getStoreId()) + ->setAddressType($address->getAddressType()) + ->setCustomerId($address->getCustomerId()) + ->setCustomerAddressId($address->getCustomerAddressId()); $this->_objectCopyService->copyFieldsetToTarget( 'sales_convert_quote_address', @@ -208,23 +197,15 @@ class Quote extends \Magento\Framework\Object */ public function itemToOrderItem(\Magento\Sales\Model\Quote\Item\AbstractItem $item) { - $orderItem = $this->_orderItemFactory->create()->setStoreId( - $item->getStoreId() - )->setQuoteItemId( - $item->getId() - )->setQuoteParentItemId( - $item->getParentItemId() - )->setProductId( - $item->getProductId() - )->setProductType( - $item->getProductType() - )->setQtyBackordered( - $item->getBackorders() - )->setProduct( - $item->getProduct() - )->setBaseOriginalPrice( - $item->getBaseOriginalPrice() - ); + $orderItem = $this->_orderItemFactory->create() + ->setStoreId($item->getStoreId()) + ->setQuoteItemId($item->getId()) + ->setQuoteParentItemId($item->getParentItemId()) + ->setProductId($item->getProductId()) + ->setProductType($item->getProductType()) + ->setQtyBackordered($item->getBackorders()) + ->setProduct($item->getProduct()) + ->setBaseOriginalPrice($item->getBaseOriginalPrice()); $options = $item->getProductOrderOptions(); if (!$options) { diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index 78eea184faa49cfce459f1747082e622ab8e86d9..efb987cf10c71235d0b2661f6021353c389ff78d 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -407,7 +407,7 @@ class Creditmemo extends \Magento\Sales\Model\AbstractModel } /** - * @return array + * @return \Magento\Sales\Model\Order\Creditmemo\Item[] */ public function getAllItems() { diff --git a/app/code/Magento/Sales/Model/Quote.php b/app/code/Magento/Sales/Model/Quote.php index 72808e0480709133713aaa56cf4f768542e7519d..d30e2ff1db9e79731d0b2a6f4172fbc8ea7927a2 100644 --- a/app/code/Magento/Sales/Model/Quote.php +++ b/app/code/Magento/Sales/Model/Quote.php @@ -299,6 +299,11 @@ class Quote extends \Magento\Framework\Model\AbstractModel */ protected $_addressConverter; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -307,20 +312,21 @@ class Quote extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\Config\ScopeConfigInterface $config - * @param \Magento\Sales\Model\Quote\AddressFactory $quoteAddressFactory + * @param Quote\AddressFactory $quoteAddressFactory * @param \Magento\Customer\Model\CustomerFactory $customerFactory * @param CustomerGroupServiceInterface $customerGroupService - * @param \Magento\Sales\Model\Resource\Quote\Item\CollectionFactory $quoteItemCollectionFactory - * @param \Magento\Sales\Model\Quote\ItemFactory $quoteItemFactory + * @param Resource\Quote\Item\CollectionFactory $quoteItemCollectionFactory + * @param Quote\ItemFactory $quoteItemFactory * @param \Magento\Framework\Message\Factory $messageFactory - * @param \Magento\Sales\Model\Status\ListFactory $statusListFactory + * @param Status\ListFactory $statusListFactory * @param \Magento\Catalog\Model\ProductFactory $productFactory - * @param \Magento\Sales\Model\Quote\PaymentFactory $quotePaymentFactory - * @param \Magento\Sales\Model\Resource\Quote\Payment\CollectionFactory $quotePaymentCollectionFactory + * @param Quote\PaymentFactory $quotePaymentFactory + * @param Resource\Quote\Payment\CollectionFactory $quotePaymentCollectionFactory * @param \Magento\Framework\Object\Copy $objectCopyService * @param \Magento\Customer\Model\Converter $converter * @param \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService * @param \Magento\Customer\Model\Address\Converter $addressConverter + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -347,6 +353,7 @@ class Quote extends \Magento\Framework\Model\AbstractModel \Magento\Customer\Model\Converter $converter, \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService, \Magento\Customer\Model\Address\Converter $addressConverter, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() @@ -370,6 +377,7 @@ class Quote extends \Magento\Framework\Model\AbstractModel $this->_converter = $converter; $this->_addressService = $addressService; $this->_addressConverter = $addressConverter; + $this->stockItemService = $stockItemService; parent::__construct($context, $registry, $resource, $resourceCollection, $data); } @@ -725,7 +733,7 @@ class Quote extends \Magento\Framework\Model\AbstractModel /** * Get Data Object addresses of the customer * - * TODO: Refactor to use addressDataObject property is used insead of customer model MAGETWO-19930 + * TODO: Refactor to use addressDataObject property is used instead of customer model MAGETWO-19930 * * @return AddressDataObject[] */ @@ -1111,7 +1119,9 @@ class Quote extends \Magento\Framework\Model\AbstractModel public function hasItemsWithDecimalQty() { foreach ($this->getAllItems() as $item) { - if ($item->getProduct()->getStockItem() && $item->getProduct()->getStockItem()->getIsQtyDecimal()) { + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */ + $stockItemDo = $this->stockItemService->getStockItem($item->getProduct()->getId()); + if ($stockItemDo->getStockId() && $stockItemDo->getIsQtyDecimal()) { return true; } } @@ -1279,7 +1289,9 @@ class Quote extends \Magento\Framework\Model\AbstractModel $request = new \Magento\Framework\Object(array('qty' => $request)); } if (!$request instanceof \Magento\Framework\Object) { - throw new \Magento\Framework\Model\Exception(__('We found an invalid request for adding product to quote.')); + throw new \Magento\Framework\Model\Exception( + __('We found an invalid request for adding product to quote.') + ); } $cartCandidates = $product->getTypeInstance()->prepareForCartAdvanced($request, $product, $processMode); @@ -1427,7 +1439,9 @@ class Quote extends \Magento\Framework\Model\AbstractModel { $item = $this->getItemById($itemId); if (!$item) { - throw new \Magento\Framework\Model\Exception(__('This is the wrong quote item id to update configuration.')); + throw new \Magento\Framework\Model\Exception( + __('This is the wrong quote item id to update configuration.') + ); } $productId = $item->getProduct()->getId(); @@ -1673,18 +1687,18 @@ class Quote extends \Magento\Framework\Model\AbstractModel $address->collectTotals(); - $this->setSubtotal((double)$this->getSubtotal() + $address->getSubtotal()); - $this->setBaseSubtotal((double)$this->getBaseSubtotal() + $address->getBaseSubtotal()); + $this->setSubtotal((float)$this->getSubtotal() + $address->getSubtotal()); + $this->setBaseSubtotal((float)$this->getBaseSubtotal() + $address->getBaseSubtotal()); $this->setSubtotalWithDiscount( - (double)$this->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount() + (float)$this->getSubtotalWithDiscount() + $address->getSubtotalWithDiscount() ); $this->setBaseSubtotalWithDiscount( - (double)$this->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount() + (float)$this->getBaseSubtotalWithDiscount() + $address->getBaseSubtotalWithDiscount() ); - $this->setGrandTotal((double)$this->getGrandTotal() + $address->getGrandTotal()); - $this->setBaseGrandTotal((double)$this->getBaseGrandTotal() + $address->getBaseGrandTotal()); + $this->setGrandTotal((float)$this->getGrandTotal() + $address->getGrandTotal()); + $this->setBaseGrandTotal((float)$this->getBaseGrandTotal() + $address->getBaseGrandTotal()); } $this->_salesData->checkQuoteAmount($this, $this->getGrandTotal()); @@ -1731,7 +1745,7 @@ class Quote extends \Magento\Framework\Model\AbstractModel $this->setVirtualItemsQty($this->getVirtualItemsQty() + $item->getQty()); } $this->setItemsCount($this->getItemsCount() + 1); - $this->setItemsQty((double)$this->getItemsQty() + $item->getQty()); + $this->setItemsQty((float)$this->getItemsQty() + $item->getQty()); } return $this; diff --git a/app/code/Magento/Sales/Model/Quote/Item.php b/app/code/Magento/Sales/Model/Quote/Item.php index 557efea73a5220d08fce1f92c2a28966fe3d8c0b..2d365304e7444425a123558f345ac6209ea241a4 100644 --- a/app/code/Magento/Sales/Model/Quote/Item.php +++ b/app/code/Magento/Sales/Model/Quote/Item.php @@ -48,8 +48,6 @@ namespace Magento\Sales\Model\Quote; * @method \Magento\Sales\Model\Quote\Item setName(string $value) * @method string getDescription() * @method \Magento\Sales\Model\Quote\Item setDescription(string $value) - * @method string getAppliedRuleIds() - * @method \Magento\Sales\Model\Quote\Item setAppliedRuleIds(string $value) * @method string getAdditionalData() * @method \Magento\Sales\Model\Quote\Item setAdditionalData(string $value) * @method int getFreeShipping() @@ -63,19 +61,11 @@ namespace Magento\Sales\Model\Quote; * @method float getBasePrice() * @method \Magento\Sales\Model\Quote\Item setBasePrice(float $value) * @method float getCustomPrice() - * @method float getDiscountPercent() - * @method \Magento\Sales\Model\Quote\Item setDiscountPercent(float $value) - * @method float getDiscountAmount() - * @method \Magento\Sales\Model\Quote\Item setDiscountAmount(float $value) - * @method float getBaseDiscountAmount() - * @method \Magento\Sales\Model\Quote\Item setBaseDiscountAmount(float $value) * @method float getTaxPercent() * @method \Magento\Sales\Model\Quote\Item setTaxPercent(float $value) * @method \Magento\Sales\Model\Quote\Item setTaxAmount(float $value) * @method \Magento\Sales\Model\Quote\Item setBaseTaxAmount(float $value) - * @method float getRowTotal() * @method \Magento\Sales\Model\Quote\Item setRowTotal(float $value) - * @method float getBaseRowTotal() * @method \Magento\Sales\Model\Quote\Item setBaseRowTotal(float $value) * @method float getRowTotalWithDiscount() * @method \Magento\Sales\Model\Quote\Item setRowTotalWithDiscount(float $value) @@ -92,11 +82,9 @@ namespace Magento\Sales\Model\Quote; * @method \Magento\Sales\Model\Quote\Item setRedirectUrl(string $value) * @method float getBaseCost() * @method \Magento\Sales\Model\Quote\Item setBaseCost(float $value) - * @method float getPriceInclTax() * @method \Magento\Sales\Model\Quote\Item setPriceInclTax(float $value) * @method float getBasePriceInclTax() * @method \Magento\Sales\Model\Quote\Item setBasePriceInclTax(float $value) - * @method float getRowTotalInclTax() * @method \Magento\Sales\Model\Quote\Item setRowTotalInclTax(float $value) * @method float getBaseRowTotalInclTax() * @method \Magento\Sales\Model\Quote\Item setBaseRowTotalInclTax(float $value) @@ -178,7 +166,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem * Flag stating that options were successfully saved * */ - protected $_flagOptionsSaved = null; + protected $_flagOptionsSaved; /** * Array of errors associated with this quote item @@ -202,6 +190,11 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem */ protected $_compareHelper; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -210,6 +203,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem * @param \Magento\Framework\Locale\FormatInterface $localeFormat * @param Item\OptionFactory $itemOptionFactory * @param \Magento\Sales\Helper\Quote\Item\Compare $compareHelper + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\Db $resourceCollection * @param array $data @@ -224,6 +218,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem \Magento\Framework\Locale\FormatInterface $localeFormat, \Magento\Sales\Model\Quote\Item\OptionFactory $itemOptionFactory, \Magento\Sales\Helper\Quote\Item\Compare $compareHelper, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\Db $resourceCollection = null, array $data = array() @@ -232,6 +227,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem $this->_localeFormat = $localeFormat; $this->_itemOptionFactory = $itemOptionFactory; $this->_compareHelper = $compareHelper; + $this->stockItemService = $stockItemService; parent::__construct($context, $registry, $productFactory, $resource, $resourceCollection, $data); } @@ -375,7 +371,8 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem $qtyOptions = array(); foreach ($this->getOptions() as $option) { /** @var $option \Magento\Sales\Model\Quote\Item\Option */ - if (is_object($option->getProduct()) && $option->getProduct()->getId() != $this->getProduct()->getId() + if (is_object($option->getProduct()) + && $option->getProduct()->getId() != $this->getProduct()->getId() ) { $productIds[$option->getProduct()->getId()] = $option->getProduct()->getId(); } @@ -417,27 +414,19 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem $product->setStoreId($this->getQuote()->getStoreId()); $product->setCustomerGroupId($this->getQuote()->getCustomerGroupId()); } - $this->setData( - 'product', - $product - )->setProductId( - $product->getId() - )->setProductType( - $product->getTypeId() - )->setSku( - $this->getProduct()->getSku() - )->setName( - $product->getName() - )->setWeight( - $this->getProduct()->getWeight() - )->setTaxClassId( - $product->getTaxClassId() - )->setBaseCost( - $product->getCost() - ); - - if ($product->getStockItem()) { - $this->setIsQtyDecimal($product->getStockItem()->getIsQtyDecimal()); + $this->setData('product', $product) + ->setProductId($product->getId()) + ->setProductType($product->getTypeId()) + ->setSku($this->getProduct()->getSku()) + ->setName($product->getName()) + ->setWeight($this->getProduct()->getWeight()) + ->setTaxClassId($product->getTaxClassId()) + ->setBaseCost($product->getCost()); + + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDo */ + $stockItemDo = $this->stockItemService->getStockItem($product->getId()); + if ($stockItemDo->getStockId()) { + $this->setIsQtyDecimal($stockItemDo->getIsQtyDecimal()); } $this->_eventManager->dispatch( @@ -544,7 +533,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem /** * Return real product type of item * - * @return unknown + * @return string */ public function getRealProductType() { diff --git a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Main.php b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Main.php index 509ca9042678f6c3022567320da882cd5bc2e87a..31e5e0695611bb7f87d8714d74fb37f818ef809f 100644 --- a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Main.php +++ b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Main.php @@ -242,7 +242,10 @@ class Main extends \Magento\Backend\Block\Widget\Form\Generic implements \Magent $fieldset->addField( 'uses_per_customer', 'text', - array('name' => 'uses_per_customer', 'label' => __('Uses per Customer')) + array('name' => 'uses_per_customer', + 'label' => __('Uses per Customer'), + 'note' => __('Usage limit enforced for logged in customers only.') + ) ); $dateFormat = $this->_localeDate->getDateFormat(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT); diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php index 95a0e3041163747f6736bba1f80689e216081ac6..71e3c20fb3746744c8df1bb9cf67a10d2afc9cce 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php @@ -499,7 +499,9 @@ class Quote extends \Magento\Backend\App\Action $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Shipping/Block/Adminhtml/Create/Items.php b/app/code/Magento/Shipping/Block/Adminhtml/Create/Items.php index 47c319b91e090bfaff7c8db98748e22cb1307f40..e1d2b6a60c21abeacc0a38bba1b34c471787de2b 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/Create/Items.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/Create/Items.php @@ -33,7 +33,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems * * @var \Magento\Sales\Helper\Data */ - protected $_salesData = null; + protected $_salesData; /** * @var \Magento\Shipping\Model\CarrierFactory @@ -42,7 +42,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems /** * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Catalog\Model\ProductFactory $productFactory + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Registry $registry * @param \Magento\Sales\Helper\Data $salesData * @param \Magento\Shipping\Model\CarrierFactory $carrierFactory @@ -50,7 +50,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems */ public function __construct( \Magento\Backend\Block\Template\Context $context, - \Magento\Catalog\Model\ProductFactory $productFactory, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Registry $registry, \Magento\Sales\Helper\Data $salesData, \Magento\Shipping\Model\CarrierFactory $carrierFactory, @@ -58,7 +58,7 @@ class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems ) { $this->_salesData = $salesData; $this->_carrierFactory = $carrierFactory; - parent::__construct($context, $productFactory, $registry, $data); + parent::__construct($context, $stockItemService, $registry, $data); } /** diff --git a/app/code/Magento/Shipping/Block/Adminhtml/View/Items.php b/app/code/Magento/Shipping/Block/Adminhtml/View/Items.php index 706e5a44c9f66cb7221ea501f95eae7095f7950b..127114d9e7aa31d1eb60f9c3849e07c158e87c73 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/View/Items.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/View/Items.php @@ -22,14 +22,11 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +namespace Magento\Shipping\Block\Adminhtml\View; /** * Adminhtml sales item renderer - * - * @author Magento Core Team <core@magentocommerce.com> */ -namespace Magento\Shipping\Block\Adminhtml\View; - class Items extends \Magento\Sales\Block\Adminhtml\Items\AbstractItems { /** diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php index 89797072eaf91b6723c09ebbcd669cd8dc39ba82..8a2967cbb17e4a1fbdcb58a8ec6059abf6d2dfaf 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php @@ -301,7 +301,7 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip } } if ($isNeedCreateLabel) { - $this->getResponse()->setBody($responseAjax->toJson()); + $this->getResponse()->representJson($responseAjax->toJson()); } else { $this->_redirect('sales/order/view', array('order_id' => $shipment->getOrderId())); } @@ -383,9 +383,12 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip $response = array('error' => true, 'message' => __('Cannot add tracking number.')); } if (is_array($response)) { - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); } - $this->getResponse()->setBody($response); } /** @@ -417,9 +420,12 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip $response = array('error' => true, 'message' => __('Cannot load track with retrieving identifier.')); } if (is_array($response)) { - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); } - $this->getResponse()->setBody($response); } /** @@ -448,12 +454,16 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip $response = $this->_view->getLayout()->getBlock('shipment_comments')->toHtml(); } catch (\Magento\Framework\Model\Exception $e) { $response = array('error' => true, 'message' => $e->getMessage()); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } catch (\Exception $e) { $response = array('error' => true, 'message' => __('Cannot add new comment.')); - $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response); } - $this->getResponse()->setBody($response); + if (is_array($response)) { + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response) + ); + } else { + $this->getResponse()->setBody($response); + } } /** @@ -546,7 +556,7 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip $response->setMessage(__('An error occurred while creating shipping label.')); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php index 4e49f5597e96121c7b84a280be67949b412a94f9..4b06f80ee66a3e3c2198dd806e2eecba41c41fc5 100644 --- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php +++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php @@ -107,6 +107,11 @@ abstract class AbstractCarrierOnline extends AbstractCarrier */ protected $_currencyFactory; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * Raw rate request data * @@ -128,6 +133,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier * @param \Magento\Directory\Model\CountryFactory $countryFactory * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory * @param \Magento\Directory\Helper\Data $directoryData + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -146,6 +152,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, array $data = array() ) { $this->_xmlElFactory = $xmlElFactory; @@ -158,6 +165,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier $this->_countryFactory = $countryFactory; $this->_currencyFactory = $currencyFactory; $this->_directoryData = $directoryData; + $this->stockItemService = $stockItemService; parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data); } @@ -303,19 +311,23 @@ abstract class AbstractCarrierOnline extends AbstractCarrier $defaultErrorMsg = __('The shipping module is not available.'); $showMethod = $this->getConfigData('showmethod'); + /** @var $item \Magento\Sales\Model\Quote\Item */ foreach ($this->getAllItems($request) as $item) { - if ($item->getProduct() && $item->getProduct()->getId()) { - $weight = $item->getProduct()->getWeight(); - $stockItem = $item->getProduct()->getStockItem(); + $product = $item->getProduct(); + if ($product && $product->getId()) { + $weight = $product->getWeight(); + $stockItemData = $this->stockItemService->getStockItem($product->getId()); $doValidation = true; - if ($stockItem->getIsQtyDecimal() && $stockItem->getIsDecimalDivided()) { - if ($stockItem->getEnableQtyIncrements() && $stockItem->getQtyIncrements()) { - $weight = $weight * $stockItem->getQtyIncrements(); + if ($stockItemData->getIsQtyDecimal() && $stockItemData->getIsDecimalDivided()) { + if ($this->stockItemService->getEnableQtyIncrements($product->getId()) + && $this->stockItemService->getQtyIncrements($product->getId()) + ) { + $weight = $weight * $this->stockItemService->getQtyIncrements($product->getId()); } else { $doValidation = false; } - } elseif ($stockItem->getIsQtyDecimal() && !$stockItem->getIsDecimalDivided()) { + } elseif ($stockItemData->getIsQtyDecimal() && !$stockItemData->getIsDecimalDivided()) { $weight = $weight * $item->getQty(); } diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php index 21d3a7f0c1609560b2b256342c074ae5793c57fb..1ce2afa6532749c189a559a187ee1868c0dc9b28 100644 --- a/app/code/Magento/Shipping/Model/Shipping.php +++ b/app/code/Magento/Shipping/Model/Shipping.php @@ -91,6 +91,11 @@ class Shipping implements RateCollectorInterface */ protected $mathDivision; + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService + */ + protected $stockItemService; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Shipping\Model\Config $shippingConfig @@ -100,6 +105,7 @@ class Shipping implements RateCollectorInterface * @param \Magento\Shipping\Model\Shipment\RequestFactory $shipmentRequestFactory * @param \Magento\Directory\Model\RegionFactory $regionFactory * @param \Magento\Framework\Math\Division $mathDivision + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, @@ -109,7 +115,8 @@ class Shipping implements RateCollectorInterface \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory, \Magento\Shipping\Model\Shipment\RequestFactory $shipmentRequestFactory, \Magento\Directory\Model\RegionFactory $regionFactory, - \Magento\Framework\Math\Division $mathDivision + \Magento\Framework\Math\Division $mathDivision, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService ) { $this->_scopeConfig = $scopeConfig; $this->_shippingConfig = $shippingConfig; @@ -119,6 +126,7 @@ class Shipping implements RateCollectorInterface $this->_shipmentRequestFactory = $shipmentRequestFactory; $this->_regionFactory = $regionFactory; $this->mathDivision = $mathDivision; + $this->stockItemService = $stockItemService; } /** @@ -328,9 +336,10 @@ class Shipping implements RateCollectorInterface $maxWeight = (double)$carrier->getConfigData('max_package_weight'); + /** @var $item \Magento\Sales\Model\Quote\Item */ foreach ($allItems as $item) { - if ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE && - $item->getProduct()->getShipmentType() + if ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + && $item->getProduct()->getShipmentType() ) { continue; } @@ -344,17 +353,22 @@ class Shipping implements RateCollectorInterface if (!$item->getParentItem()->getProduct()->getShipmentType()) { continue; } - $qty = $item->getIsQtyDecimal() ? $item->getParentItem()->getQty() : $item->getParentItem()->getQty() * - $item->getQty(); + $qty = $item->getIsQtyDecimal() + ? $item->getParentItem()->getQty() + : $item->getParentItem()->getQty() * $item->getQty(); } $itemWeight = $item->getWeight(); - if ($item->getIsQtyDecimal() && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + if ($item->getIsQtyDecimal() + && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE ) { - $stockItem = $item->getProduct()->getStockItem(); - if ($stockItem->getIsDecimalDivided()) { - if ($stockItem->getEnableQtyIncrements() && $stockItem->getQtyIncrements()) { - $itemWeight = $itemWeight * $stockItem->getQtyIncrements(); + $productId = $item->getProduct()->getId(); + + if ($this->stockItemService->getStockItem($productId)->getIsDecimalDivided()) { + if ($this->stockItemService->getEnableQtyIncrements($productId) + && $this->stockItemService->getQtyIncrements($productId) + ) { + $itemWeight = $itemWeight * $this->stockItemService->getQtyIncrements($productId); $qty = round($item->getWeight() / $itemWeight * $qty); $changeQty = false; } else { @@ -380,10 +394,10 @@ class Shipping implements RateCollectorInterface return array(); } - if ($changeQty && - !$item->getParentItem() && - $item->getIsQtyDecimal() && - $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE + if ($changeQty + && !$item->getParentItem() + && $item->getIsQtyDecimal() + && $item->getProductType() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE ) { $qty = 1; } diff --git a/app/code/Magento/Shipping/Model/Shipping/Labels.php b/app/code/Magento/Shipping/Model/Shipping/Labels.php index 5383041a400d4c7049d477293caec5bb5761415a..d9f8d6780f9d9b4c3026ad5ca2402dceb9e30340 100644 --- a/app/code/Magento/Shipping/Model/Shipping/Labels.php +++ b/app/code/Magento/Shipping/Model/Shipping/Labels.php @@ -49,6 +49,7 @@ class Labels extends \Magento\Shipping\Model\Shipping * @param \Magento\Shipping\Model\Shipment\RequestFactory $shipmentRequestFactory * @param \Magento\Directory\Model\RegionFactory $regionFactory * @param \Magento\Framework\Math\Division $mathDivision + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Backend\Model\Auth\Session $authSession * @param \Magento\Shipping\Model\Shipment\Request $request */ @@ -61,6 +62,7 @@ class Labels extends \Magento\Shipping\Model\Shipping \Magento\Shipping\Model\Shipment\RequestFactory $shipmentRequestFactory, \Magento\Directory\Model\RegionFactory $regionFactory, \Magento\Framework\Math\Division $mathDivision, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Backend\Model\Auth\Session $authSession, \Magento\Shipping\Model\Shipment\Request $request ) { @@ -74,7 +76,8 @@ class Labels extends \Magento\Shipping\Model\Shipping $rateResultFactory, $shipmentRequestFactory, $regionFactory, - $mathDivision + $mathDivision, + $stockItemService ); } diff --git a/app/code/Magento/Shipping/etc/module.xml b/app/code/Magento/Shipping/etc/module.xml index e187b74e6aacecfa0fcc50954af9fa3a396cb411..f9efc8cd20265d1beecb9b352a37dd19f9e23b14 100644 --- a/app/code/Magento/Shipping/etc/module.xml +++ b/app/code/Magento/Shipping/etc/module.xml @@ -42,6 +42,7 @@ <module name="Magento_Payment"/> <module name="Magento_Theme"/> <module name="Magento_Tax"/> + <module name="Magento_CatalogInventory"/> </depends> </module> </config> diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php index c7a08386d417e1dd7bc0828ab32ee26cd411506b..09310a3b95d7e372a142d613bba9957306d55e3b 100644 --- a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php +++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php @@ -185,7 +185,7 @@ class Rate extends \Magento\Backend\App\Action ) ); } - $this->getResponse()->setBody($responseContent); + $this->getResponse()->representJson($responseContent); } /** @@ -321,7 +321,7 @@ class Rate extends \Magento\Backend\App\Action array('success' => false, 'error_message' => __('An error occurred while deleting this tax rate.')) ); } - $this->getResponse()->setBody($responseContent); + $this->getResponse()->representJson($responseContent); } /** diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax.php index 4286cf94cec92b7c5501f912cf4cb2d3e89a436a..fa8f0be6eb3a5c67e7cc442e571401f3eef49544 100644 --- a/app/code/Magento/Tax/Controller/Adminhtml/Tax.php +++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax.php @@ -74,7 +74,7 @@ class Tax extends \Magento\Backend\App\Action ) ); } - $this->getResponse()->setBody($responseContent); + $this->getResponse()->representJson($responseContent); } /** @@ -108,7 +108,7 @@ class Tax extends \Magento\Backend\App\Action array('success' => false, 'error_message' => __('Something went wrong deleting this tax class.')) ); } - $this->getResponse()->setBody($responseContent); + $this->getResponse()->representJson($responseContent); } /** diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php index 54b2a41d9f9570e195d2c3b8dd4d4f171a18261b..5bbad678967c34d99d9a7e86b1ba388572bdaed0 100644 --- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php +++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php @@ -272,7 +272,9 @@ class Theme extends \Magento\Backend\App\Action $result = array('error' => true, 'message' => __('We cannot upload the CSS file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -317,7 +319,9 @@ class Theme extends \Magento\Backend\App\Action $result = array('error' => true, 'message' => __('We cannot upload the JS file.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php index b3388af0069cc9e912e51d185c17a48f28c0ee88..11d2d82a2a491b73ce11f0fe52b786eb5e0ed8bb 100644 --- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php +++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php @@ -75,7 +75,7 @@ class Files extends \Magento\Backend\App\Action public function treeJsonAction() { try { - $this->getResponse()->setBody( + $this->getResponse()->representJson( $this->_view->getLayout()->createBlock( 'Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Tree' )->getTreeJson( @@ -84,7 +84,9 @@ class Files extends \Magento\Backend\App\Action ); } catch (\Exception $e) { $this->_objectManager->get('Magento\Framework\Logger')->logException($e); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array()) + ); } } @@ -105,7 +107,9 @@ class Files extends \Magento\Backend\App\Action $result = array('error' => true, 'message' => __('Sorry, there was an unknown error.')); $this->_objectManager->get('Magento\Framework\Logger')->logException($e); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -120,7 +124,9 @@ class Files extends \Magento\Backend\App\Action $this->_getStorage()->deleteDirectory($path); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -139,7 +145,9 @@ class Files extends \Magento\Backend\App\Action $this->_getSession()->setStoragePath($this->storage->getCurrentPath()); } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } @@ -156,7 +164,9 @@ class Files extends \Magento\Backend\App\Action } catch (\Exception $e) { $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode()); } - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } /** @@ -203,7 +213,9 @@ class Files extends \Magento\Backend\App\Action } } catch (\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } diff --git a/app/code/Magento/Theme/view/frontend/layout/print.xml b/app/code/Magento/Theme/view/frontend/layout/print.xml index 3158fc4654c9370f8f3c633c51c6f627ede6df04..a804c6c21a0418a2d9867cc4e6083278053f66d1 100644 --- a/app/code/Magento/Theme/view/frontend/layout/print.xml +++ b/app/code/Magento/Theme/view/frontend/layout/print.xml @@ -27,7 +27,12 @@ <block class="Magento\Theme\Block\Html" name="root" output="1" template="print.phtml"> <block class="Magento\Theme\Block\Html\Head" name="head" as="head"/> <container name="after_body_start" as="after_body_start" label="Page Top"/> - <container name="content" as="content" label="Main Content Area"/> + <container name="main" as="main" label="Main Content Container" htmlTag="div" htmlClass="column main"> + <container name="content.top" label="Main Content Top"/> + <container name="content" label="Main Content Area"/> + <container name="content.aside" label="Main Content Aside"/> + <container name="content.bottom" label="Main Content Bottom"/> + </container> </block> <update handle="default_head_blocks"/> <referenceBlock name="head"> diff --git a/app/code/Magento/Translation/Controller/Ajax.php b/app/code/Magento/Translation/Controller/Ajax.php index 258cde173a30e9b358b869224326ffcbaedc0b6b..70fd664195a915d974af73a3b1a245e61e2d74ff 100644 --- a/app/code/Magento/Translation/Controller/Ajax.php +++ b/app/code/Magento/Translation/Controller/Ajax.php @@ -58,8 +58,7 @@ class Ajax extends \Magento\Framework\App\Action\Action } catch (\Exception $e) { $response = "{error:true,message:'" . $e->getMessage() . "'}"; } - $this->getResponse()->setBody($response); - + $this->getResponse()->representJson($response); $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true); } } diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php index 85f3345115a26b5a5a31645816b188faf33b75de..08346039f3ce3736e61ca6cd15f11706c51bcbdc 100644 --- a/app/code/Magento/Ups/Model/Carrier.php +++ b/app/code/Magento/Ups/Model/Carrier.php @@ -147,6 +147,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface * @param \Magento\Directory\Model\CountryFactory $countryFactory * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory * @param \Magento\Directory\Helper\Data $directoryData + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Framework\Logger $logger * @param \Magento\Framework\Locale\FormatInterface $localeFormat * @param Config $configHelper @@ -168,6 +169,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, \Magento\Framework\Logger $logger, \Magento\Framework\Locale\FormatInterface $localeFormat, Config $configHelper, @@ -190,6 +192,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface $countryFactory, $currencyFactory, $directoryData, + $stockItemService, $data ); } diff --git a/app/code/Magento/Ups/etc/module.xml b/app/code/Magento/Ups/etc/module.xml index 5e3c327c26d0fa92d39824f47f98da6ff8df2c0f..ae8aab01ae5f0cd3993eca55493ea7be6d07abaa 100644 --- a/app/code/Magento/Ups/etc/module.xml +++ b/app/code/Magento/Ups/etc/module.xml @@ -32,6 +32,7 @@ <module name="Magento_Sales"/> <module name="Magento_Shipping"/> <module name="Magento_Directory"/> + <module name="Magento_CatalogInventory"/> </depends> </module> </config> diff --git a/app/code/Magento/User/Controller/Adminhtml/User.php b/app/code/Magento/User/Controller/Adminhtml/User.php index d515bc6b32e6822782de3d70eeecb72d3719a24c..38eacb24a784e92f8b47aacb695d93843bf49045 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User.php +++ b/app/code/Magento/User/Controller/Adminhtml/User.php @@ -167,7 +167,7 @@ class User extends \Magento\Backend\App\AbstractAction $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->getResponse()->setBody($response->toJson()); + $this->getResponse()->representJson($response->toJson()); } /** diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index c150954b7866c0bdc56c9f19dd563646cd2da1a4..af59af66dd7fc7b296491390e9e42359cd479f42 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -145,6 +145,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C * @param \Magento\Directory\Model\CountryFactory $countryFactory * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory * @param \Magento\Directory\Helper\Data $directoryData + * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService * @param \Magento\Shipping\Helper\Carrier $carrierHelper * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory @@ -166,6 +167,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C \Magento\Directory\Model\CountryFactory $countryFactory, \Magento\Directory\Model\CurrencyFactory $currencyFactory, \Magento\Directory\Helper\Data $directoryData, + \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService, CarrierHelper $carrierHelper, \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory, \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory, @@ -188,6 +190,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C $countryFactory, $currencyFactory, $directoryData, + $stockItemService, $data ); } diff --git a/app/code/Magento/Usps/etc/module.xml b/app/code/Magento/Usps/etc/module.xml index fb7bdbc8ba9f3dfc87df8a47d259fec0b1676457..8ef5554d20703e8a7c464f5dfe864f003413bba9 100644 --- a/app/code/Magento/Usps/etc/module.xml +++ b/app/code/Magento/Usps/etc/module.xml @@ -32,6 +32,7 @@ <module name="Magento_Core"/> <module name="Magento_Catalog"/> <module name="Magento_Sales"/> + <module name="Magento_CatalogInventory"/> </depends> </module> </config> diff --git a/app/code/Magento/Webapi/Controller/ErrorProcessor.php b/app/code/Magento/Webapi/Controller/ErrorProcessor.php index 357e3737e100be1f36964411ca48dd805129a5c8..fb6519eef84bdf1c1a9ab108af3e4791d5ff3452 100644 --- a/app/code/Magento/Webapi/Controller/ErrorProcessor.php +++ b/app/code/Magento/Webapi/Controller/ErrorProcessor.php @@ -143,7 +143,7 @@ class ErrorProcessor $stackTrace ); - } else if ($exception instanceof WebapiException) { + } elseif ($exception instanceof WebapiException) { $maskedException = $exception; } else { $maskedException = new WebapiException( diff --git a/app/code/Magento/Webapi/Model/PathProcessor.php b/app/code/Magento/Webapi/Model/PathProcessor.php index 710ef1cc54b9f8e4126cb82cf588055490808bce..5dc7ed484bb7cedc2d5bbe00a3cb8d439542d1ec 100644 --- a/app/code/Magento/Webapi/Model/PathProcessor.php +++ b/app/code/Magento/Webapi/Model/PathProcessor.php @@ -54,6 +54,7 @@ class PathProcessor $path = '/' . implode('/', $pathParts); return explode('/', ltrim($path, '/'), 2); } + /** * Process path info * diff --git a/app/code/Magento/Webapi/Model/Rest/Config.php b/app/code/Magento/Webapi/Model/Rest/Config.php index 5111a6b6a82f24100e09879a0d413f51fad60d04..56ccb5d485d3f68be9431b0ff3631ab7246289f7 100644 --- a/app/code/Magento/Webapi/Model/Rest/Config.php +++ b/app/code/Magento/Webapi/Model/Rest/Config.php @@ -36,30 +36,20 @@ class Config * HTTP methods supported by REST. */ const HTTP_METHOD_GET = 'GET'; - const HTTP_METHOD_DELETE = 'DELETE'; - const HTTP_METHOD_PUT = 'PUT'; - const HTTP_METHOD_POST = 'POST'; - /**#@-*/ /**#@+ * Keys that a used for config internal representation. */ const KEY_IS_SECURE = 'isSecure'; - const KEY_CLASS = 'class'; - const KEY_METHOD = 'method'; - const KEY_ROUTE_PATH = 'routePath'; - const KEY_ACL_RESOURCES = 'resources'; - const KEY_PARAMETERS = 'parameters'; - /*#@-*/ /** @var ModelConfig */ @@ -98,17 +88,11 @@ class Config $this->_formatRoutePath($routeData[self::KEY_ROUTE_PATH]) ); - $route->setServiceClass( - $routeData[self::KEY_CLASS] - )->setServiceMethod( - $routeData[self::KEY_METHOD] - )->setSecure( - $routeData[self::KEY_IS_SECURE] - )->setAclResources( - $routeData[self::KEY_ACL_RESOURCES] - )->setParameters( - $routeData[self::KEY_PARAMETERS] - ); + $route->setServiceClass($routeData[self::KEY_CLASS]) + ->setServiceMethod($routeData[self::KEY_METHOD]) + ->setSecure($routeData[self::KEY_IS_SECURE]) + ->setAclResources($routeData[self::KEY_ACL_RESOURCES]) + ->setParameters($routeData[self::KEY_PARAMETERS]); return $route; } diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget.php index e70b2e7b0ed1ab26a196089aff8517424bd0ae70..a4ff2b83d17626ffe7a828b0b8879f773305102f 100644 --- a/app/code/Magento/Widget/Controller/Adminhtml/Widget.php +++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget.php @@ -108,7 +108,9 @@ class Widget extends \Magento\Backend\App\Action } } catch (\Magento\Framework\Model\Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); - $this->getResponse()->setBody($this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)); + $this->getResponse()->representJson( + $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result) + ); } } diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php index 5ab886a6d959d342312bf5cddc21f63c26ea82e0..fba0cf6307695f5655257c3b77df8d946fc35978 100644 --- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php +++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php @@ -203,7 +203,9 @@ class Instance extends \Magento\Backend\App\Action $response->setError(true); $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()); } - $this->setBody($response->toJson()); + $responseJson = $response->toJson(); + $this->_translateInline->processResponseBody($responseJson, true); + $this->getResponse()->representJson($responseJson); } /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php index 274a2276817ebcb078a121252f1283fdd5273c26..757925811cda507a2a75034209d47c57c487911f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.php @@ -60,7 +60,7 @@ class ProductForm extends FormTabs * * @var string */ - protected $advancedSettings = '#ui-accordion-product_info_tabs-advanced-header-0[aria-selected="false"]'; + protected $advancedSettings = '#product_info_tabs-advanced [data-role="trigger"]'; /** * Advanced tab list diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php index 4972a686f670c53e523e6ffe073f28a2474c5964..d9d81ec8cc94127d8b60800d0c0b3ec9cab92ab4 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php @@ -87,7 +87,7 @@ class ProductForm extends FormTabs * * @var string */ - protected $advancedSettings = '#ui-accordion-product_info_tabs-advanced-header-0[aria-selected="false"]'; + protected $advancedSettings = '#product_info_tabs-advanced [data-role="trigger"]'; /** * Advanced tab list diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/CompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/CompareTest.php index a1c4fe65e02e310574de1e43b14c3a3eb190e03e..3940cf21690f935ece8b4c9393d72c5ae0f0da69 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/CompareTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/CompareTest.php @@ -30,11 +30,15 @@ class CompareTest extends \PHPUnit_Framework_TestCase */ protected $_helper; + /** + * @var \Magento\Framework\ObjectManager + */ + protected $_objectManager; + protected function setUp() { - $this->_helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - 'Magento\Catalog\Helper\Product\Compare' - ); + $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->_helper = $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare'); } /** @@ -43,9 +47,7 @@ class CompareTest extends \PHPUnit_Framework_TestCase public function testGetListUrl() { /** @var $empty \Magento\Catalog\Helper\Product\Compare */ - $empty = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Helper\Product\Compare' - ); + $empty = $this->_objectManager->create('Magento\Catalog\Helper\Product\Compare'); $this->assertContains('/catalog/product_compare/index/', $empty->getListUrl()); $this->_populateCompareList(); @@ -57,11 +59,12 @@ class CompareTest extends \PHPUnit_Framework_TestCase $this->_testGetProductUrl('getAddUrl', '/catalog/product_compare/add/'); } + /** + * @magentoAppIsolation enabled + */ public function testGetAddToWishlistParams() { - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product' - ); + $product = $this->_objectManager->create('Magento\Catalog\Model\Product'); $product->setId(10); $json = $this->_helper->getAddToWishlistParams($product); $params = (array)json_decode($json); @@ -109,8 +112,8 @@ class CompareTest extends \PHPUnit_Framework_TestCase */ public function testCalculate() { - /** @var $session \Magento\Catalog\Model\Session */ - $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Session'); + /** @var \Magento\Catalog\Model\Session $session */ + $session = $this->_objectManager->get('Magento\Catalog\Model\Session'); try { $session->unsCatalogCompareItemsCount(); $this->assertFalse($this->_helper->hasItems()); @@ -137,9 +140,7 @@ class CompareTest extends \PHPUnit_Framework_TestCase protected function _testGetProductUrl($method, $expectedFullAction) { - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product' - ); + $product = $this->_objectManager->create('Magento\Catalog\Model\Product'); $product->setId(10); $url = $this->_helper->{$method}($product); $this->assertContains($expectedFullAction, $url); @@ -150,18 +151,12 @@ class CompareTest extends \PHPUnit_Framework_TestCase */ protected function _populateCompareList() { - $productOne = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product' - ); - $productTwo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product' - ); + $productOne = $this->_objectManager->create('Magento\Catalog\Model\Product'); + $productTwo = $this->_objectManager->create('Magento\Catalog\Model\Product'); $productOne->load(10); $productTwo->load(11); /** @var $compareList \Magento\Catalog\Model\Product\Compare\ListCompare */ - $compareList = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product\Compare\ListCompare' - ); + $compareList = $this->_objectManager->create('Magento\Catalog\Model\Product\Compare\ListCompare'); $compareList->addProduct($productOne)->addProduct($productTwo); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTest.php index 8bf3211aa3114c97ab4c9c3db6c16c59ae358577..3e5f2ac1b227a831ff4e3750be59d554d7be6860 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTest.php @@ -164,6 +164,9 @@ class AbstractTest extends \PHPUnit_Framework_TestCase $this->assertSame($sku, $this->_model->getAttributeById($sku->getId(), $product)); } + /** + * @magentoAppIsolation enabled + */ public function testIsVirtual() { $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index 8a7b64eed198aaf9217e893d153f8c4bae0782b5..3caa3e17b647a8e6ab2aa7904221eb4b2f258050 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -31,333 +31,193 @@ $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create */ /** @var $category \Magento\Catalog\Model\Category */ $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 3 -)->setName( - 'Category 1' -)->setParentId( - 2 -)->setPath( - '1/2/3' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 1 -)->save(); +$category->setId(3) + ->setName('Category 1') + ->setParentId(2) + ->setPath('1/2/3') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(1) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 4 -)->setName( - 'Category 1.1' -)->setParentId( - 3 -)->setPath( - '1/2/3/4' -)->setLevel( - 3 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setIsAnchor( - true -)->setPosition( - 1 -)->save(); +$category->setId(4) + ->setName('Category 1.1') + ->setParentId(3) + ->setPath('1/2/3/4') + ->setLevel(3) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setIsAnchor(true) + ->setPosition(1) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 5 -)->setName( - 'Category 1.1.1' -)->setParentId( - 4 -)->setPath( - '1/2/3/4/5' -)->setLevel( - 4 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 1 -)->setCustomUseParentSettings( - 0 -)->setCustomDesign( - 'Magento/blank' -)->save(); +$category->setId(5) + ->setName('Category 1.1.1') + ->setParentId(4) + ->setPath('1/2/3/4/5') + ->setLevel(4) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(1) + ->setCustomUseParentSettings(0) + ->setCustomDesign('Magento/blank') + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 6 -)->setName( - 'Category 2' -)->setParentId( - 2 -)->setPath( - '1/2/6' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 2 -)->save(); +$category->setId(6) + ->setName('Category 2') + ->setParentId(2) + ->setPath('1/2/6') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(2) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 7 -)->setName( - 'Movable' -)->setParentId( - 2 -)->setPath( - '1/2/7' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 3 -)->save(); +$category->setId(7) + ->setName('Movable') + ->setParentId(2) + ->setPath('1/2/7') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(3) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 8 -)->setName( - 'Inactive' -)->setParentId( - 2 -)->setPath( - '1/2/8' -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - false -)->setPosition( - 4 -)->save(); +$category->setId(8) + ->setName('Inactive') + ->setParentId(2) + ->setPath('1/2/8') + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(false) + ->setPosition(4) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 9 -)->setName( - 'Movable Position 1' -)->setParentId( - 2 -)->setPath( - '1/2/9' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 5 -)->save(); +$category->setId(9) + ->setName('Movable Position 1') + ->setParentId(2) + ->setPath('1/2/9') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(5) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 10 -)->setName( - 'Movable Position 2' -)->setParentId( - 2 -)->setPath( - '1/2/10' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 6 -)->save(); +$category->setId(10) + ->setName('Movable Position 2') + ->setParentId(2) + ->setPath('1/2/10') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(6) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 11 -)->setName( - 'Movable Position 3' -)->setParentId( - 2 -)->setPath( - '1/2/11' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 7 -)->save(); +$category->setId(11) + ->setName('Movable Position 3') + ->setParentId(2) + ->setPath('1/2/11') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(7) + ->save(); $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Category'); -$category->setId( - 12 -)->setName( - 'Category 12' -)->setParentId( - 2 -)->setPath( - '1/2/12' -)->setLevel( - 2 -)->setAvailableSortBy( - 'name' -)->setDefaultSortBy( - 'name' -)->setIsActive( - true -)->setPosition( - 8 -)->save(); +$category->setId(12) + ->setName('Category 12') + ->setParentId(2) + ->setPath('1/2/12') + ->setLevel(2) + ->setAvailableSortBy('name') + ->setDefaultSortBy('name') + ->setIsActive(true) + ->setPosition(8) + ->save(); /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 1 -)->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') -)->setStoreId( - 1 -)->setWebsiteIds( - array(1) -)->setName( - 'Simple Product' -)->setSku( - 'simple' -)->setPrice( - 10 -)->setWeight( - 18 -)->setStockData( - array('use_config_manage_stock' => 0) -)->setCategoryIds( - array(2, 3, 4) -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); +$product->load(1); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setStoreId(1) + ->setWebsiteIds(array(1)) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setWeight(18) + ->setStockData(array('use_config_manage_stock' => 0)) + ->setCategoryIds(array(2, 3, 4)) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 2 -)->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') -)->setStoreId( - 1 -)->setWebsiteIds( - array(1) -)->setName( - 'Simple Product Two' -)->setSku( - '12345' // SKU intentionally contains digits only -)->setPrice( - 45.67 -)->setWeight( - 56 -)->setStockData( - array('use_config_manage_stock' => 0) -)->setCategoryIds( - array(5) -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); +$product->load(2); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(2) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setStoreId(1) + ->setWebsiteIds(array(1)) + ->setName('Simple Product Two') + ->setSku('12345') // SKU intentionally contains digits only + ->setPrice(45.67) + ->setWeight(56) + ->setStockData(array('use_config_manage_stock' => 0)) + ->setCategoryIds(array(5)) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 3 -)->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') -)->setStoreId( - 1 -)->setWebsiteIds( - array(1) -)->setName( - 'Simple Product Not Visible On Frontend' -)->setSku( - 'simple' -)->setPrice( - 15 -)->setWeight( - 2 -)->setStockData( - array('use_config_manage_stock' => 0) -)->setCategoryIds( - array(10, 11, 12) -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); +$product->load(3); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(3) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setStoreId(1) + ->setWebsiteIds(array(1)) + ->setName('Simple Product Not Visible On Frontend') + ->setSku('simple') + ->setPrice(15) + ->setWeight(2) + ->setStockData(array('use_config_manage_stock' => 0)) + ->setCategoryIds(array(10, 11, 12)) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 4 -)->setAttributeSetId( - $installer->getAttributeSetId('catalog_product', 'Default') -)->setStoreId( - 1 -)->setWebsiteIds( - array(1) -)->setName( - 'Simple Product Three' -)->setSku( - 'simple' -)->setPrice( - 10 -)->setWeight( - 18 -)->setStockData( - array('use_config_manage_stock' => 0) -)->setCategoryIds( - array(10, 11, 12) -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); +$product->load(4); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(4) + ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) + ->setStoreId(1) + ->setWebsiteIds(array(1)) + ->setName('Simple Product Three') + ->setSku('simple') + ->setPrice(10) + ->setWeight(18) + ->setStockData(array('use_config_manage_stock' => 0)) + ->setCategoryIds(array(10, 11, 12)) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php index 2214971347d03f5b4d4ac08c8263c273b05a8c23..48fe277589b518788ea0a9cfe0626c2d29909d1c 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products.php @@ -25,126 +25,70 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 10 -)->setAttributeSetId( - 4 -)->setName( - 'Simple Product' -)->setSku( - 'simple1' -)->setIsObjectNew( - true -)->setTaxClassId( - 'none' -)->setDescription( - 'description' -)->setShortDescription( - 'short description' -)->setOptionsContainer( - 'container1' -)->setMsrpDisplayActualPriceType( - \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_IN_CART -)->setPrice( - 10 -)->setWeight( - 1 -)->setMetaTitle( - 'meta title' -)->setMetaKeyword( - 'meta keyword' -)->setMetaDescription( - 'meta description' -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->setWebsiteIds( - array(1) -)->setCateroryIds( - array() -)->setStockData( - array('use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1) -)->save(); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(10) + ->setAttributeSetId(4) + ->setName('Simple Product') + ->setSku('simple1') + ->setIsObjectNew(true) + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_IN_CART) + ->setPrice(10) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds(array(1)) + ->setCateroryIds(array()) + ->setStockData(array('use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1)) + ->save(); $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 11 -)->setAttributeSetId( - 4 -)->setName( - 'Simple Product2' -)->setSku( - 'simple2' -)->setIsObjectNew()->setTaxClassId( - 'none' -)->setDescription( - 'description' -)->setShortDescription( - 'short description' -)->setOptionsContainer( - 'container1' -)->setMsrpEnabled( - \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_YES -)->setMsrpDisplayActualPriceType( - \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_ON_GESTURE -)->setPrice( - 20 -)->setWeight( - 1 -)->setMetaTitle( - 'meta title' -)->setMetaKeyword( - 'meta keyword' -)->setMetaDescription( - 'meta description' -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->setWebsiteIds( - array(1) -)->setCateroryIds( - array() -)->setStockData( - array('use_config_manage_stock' => 1, 'qty' => 50, 'is_qty_decimal' => 0, 'is_in_stock' => 1) -)->save(); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(11) + ->setAttributeSetId(4) + ->setName('Simple Product2') + ->setSku('simple2') + ->setIsObjectNew() + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpEnabled(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_YES) + ->setMsrpDisplayActualPriceType(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type::TYPE_ON_GESTURE) + ->setPrice(20) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds(array(1)) + ->setCateroryIds(array()) + ->setStockData(array('use_config_manage_stock' => 1, 'qty' => 50, 'is_qty_decimal' => 0, 'is_in_stock' => 1)) + ->save(); $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 12 -)->setAttributeSetId( - 4 -)->setName( - 'Simple Product 3' -)->setSku( - 'simple3' -)->setIsObjectNew()->setTaxClassId( - 'none' -)->setDescription( - 'description' -)->setShortDescription( - 'short description' -)->setMsrpEnabled( - \Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_NO -)->setPrice( - 30 -)->setWeight( - 1 -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED -)->setWebsiteIds( - array(1) -)->setCateroryIds( - array() -)->setStockData( - array('use_config_manage_stock' => 1, 'qty' => 140, 'is_qty_decimal' => 0, 'is_in_stock' => 1) -)->save(); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setId(12) + ->setAttributeSetId(4) + ->setName('Simple Product 3') + ->setSku('simple3') + ->setIsObjectNew() + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setMsrpEnabled(\Magento\Catalog\Model\Product\Attribute\Source\Msrp\Type\Enabled::MSRP_ENABLE_NO) + ->setPrice(30) + ->setWeight(1) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED) + ->setWebsiteIds(array(1)) + ->setCateroryIds(array()) + ->setStockData(array('use_config_manage_stock' => 1, 'qty' => 140, 'is_qty_decimal' => 0, 'is_in_stock' => 1)) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index ab660709210bc8d248a0103a7692cce21637af05..6551b02c94c0ef701bf107b0ba2d02763d531744 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -59,16 +59,12 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) ) ) ->setDescription('Description with <b>html tag</b>') - ->setMetaTitle('meta title') ->setMetaKeyword('meta keyword') ->setMetaDescription('meta description') - ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->setCategoryIds(array(2)) - ->setStockData( array( 'use_config_manage_stock' => 1, diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price.php index 99100c73f2ee697f19f915454488490c6c73d12f..3a0102013444ceefb929d14d79d9aaaf1c06b9e8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_special_price.php @@ -24,32 +24,18 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - 'simple' -)->setId( - 1 -)->setAttributeSetId( - 4 -)->setWebsiteIds( - array(1) -)->setName( - 'Simple Product' -)->setSku( - 'simple' -)->setPrice( - 10 -)->setMetaTitle( - 'meta title' -)->setMetaKeyword( - 'meta keyword' -)->setMetaDescription( - 'meta description' -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->setStockData( - array('use_config_manage_stock' => 0) -)->setStockData()->setSpecialPrice( - '5.99' -)->save(); +$product->setTypeId('simple') + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds(array(1)) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(array('use_config_manage_stock' => 0)) + ->setSpecialPrice('5.99') + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php index 368ca224cb6a0c55fddfed2b0da61b631376175b..af83f2260be9bec808e4950e21cd019eedb29454 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php @@ -24,24 +24,14 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL -)->setId( - 21 -)->setAttributeSetId( - 4 -)->setWebsiteIds( - array(1) -)->setName( - 'Virtual Product' -)->setSku( - 'virtual-product' -)->setPrice( - 10 -)->setTaxClassId( - 0 -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL) + ->setId(21) + ->setAttributeSetId(4) + ->setWebsiteIds(array(1)) + ->setName('Virtual Product') + ->setSku('virtual-product') + ->setPrice(10) + ->setTaxClassId(0) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options.php index 322a1717e4d6b04343ce7887eff2f1163a864211..334a1b12bb8eb7204eabccd6f73201332c7f30fd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options.php @@ -51,5 +51,154 @@ $product->setTypeId( )->setCanSaveCustomOptions( true )->setProductOptions( - array(array('title' => 'test_option_code_1', 'type' => 'field', 'is_require' => true)) + array( + [ + 'title' => 'test_option_code_1', + 'type' => 'field', + 'is_require' => true, + 'sort_order' => 1, + 'price' => 10.0, + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 10 + ], + [ + 'title' => 'area option', + 'type' => 'area', + 'is_require' => false, + 'sort_order' => 2, + 'price' => 20.0, + 'price_type' => 'percent', + 'sku' => 'sku2', + 'max_characters' => 20 + ], + [ + 'title' => 'file option', + 'type' => 'file', + 'is_require' => true, + 'sort_order' => 3, + 'price' => 30.0, + 'price_type' => 'percent', + 'sku' => 'sku3', + 'file_extension' => 'jpg, png, gif', + 'image_size_x' => 10, + 'image_size_y' => 20 + + ], + [ + 'title' => 'drop_down option', + 'type' => 'drop_down', + 'is_require' => true, + 'sort_order' => 4, + 'values' => [ + [ + 'title' => 'drop_down option 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'drop_down option 1 sku', + 'sort_order' => 1, + ], + [ + 'title' => 'drop_down option 2', + 'price' => 20, + 'price_type' => 'fixed', + 'sku' => 'drop_down option 2 sku', + 'sort_order' => 2, + ], + ], + ], + [ + 'title' => 'radio option', + 'type' => 'radio', + 'is_require' => true, + 'sort_order' => 5, + 'values' => [ + [ + 'title' => 'radio option 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'radio option 1 sku', + 'sort_order' => 1, + ], + [ + 'title' => 'radio option 2', + 'price' => 20, + 'price_type' => 'fixed', + 'sku' => 'radio option 2 sku', + 'sort_order' => 2, + ], + ], + ], + [ + 'title' => 'checkbox option', + 'type' => 'checkbox', + 'is_require' => true, + 'sort_order' => 6, + 'values' => [ + [ + 'title' => 'checkbox option 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'checkbox option 1 sku', + 'sort_order' => 1, + ], + [ + 'title' => 'checkbox option 2', + 'price' => 20, + 'price_type' => 'fixed', + 'sku' => 'checkbox option 2 sku', + 'sort_order' => 2, + ], + ], + ], + [ + 'title' => 'multiple option', + 'type' => 'multiple', + 'is_require' => true, + 'sort_order' => 7, + 'values' => [ + [ + 'title' => 'multiple option 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'multiple option 1 sku', + 'sort_order' => 1, + ], + [ + 'title' => 'multiple option 2', + 'price' => 20, + 'price_type' => 'fixed', + 'sku' => 'multiple option 2 sku', + 'sort_order' => 2, + ], + ], + ], + [ + 'title' => 'date option', + 'type' => 'date', + 'price' => 80.0, + 'price_type' => 'fixed', + 'sku' => 'date option sku', + 'is_require' => true, + 'sort_order' => 8 + ], + [ + 'title' => 'date_time option', + 'type' => 'date_time', + 'price' => 90.0, + 'price_type' => 'fixed', + 'is_require' => true, + 'sort_order' => 9, + 'sku' => 'date_time option sku' + ], + [ + 'title' => 'time option', + 'type' => 'time', + 'price' => 100.0, + 'price_type' => 'fixed', + 'is_require' => true, + 'sku' => 'time option sku', + 'sort_order' => 10 + ] + ) )->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..6ffb72acf9bb123fe18604ce907ad2648eb8c84e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options_rollback.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(1); +if ($product->getId()) { + $product->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options.php new file mode 100644 index 0000000000000000000000000000000000000000..2b221f5f36f26c19125f69b91bcc030ede950e5e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->setTypeId( + 'simple' +)->setId( + 1 +)->setAttributeSetId( + 4 +)->setWebsiteIds( + array(1) +)->setName( + 'Simple Product Without Custom Options' +)->setSku( + 'simple' +)->setPrice( + 10 +)->setMetaTitle( + 'meta title' +)->setMetaKeyword( + 'meta keyword' +)->setMetaDescription( + 'meta description' +)->setVisibility( + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH +)->setStatus( + \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED +)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..6ffb72acf9bb123fe18604ce907ad2648eb8c84e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_without_options_rollback.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry'); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); +$product->load(1); +if ($product->getId()) { + $product->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 4d95deec49897b29dbf86d55c50eafd93e07934d..246101344bb2fbcf413182864f4611965cfd714f 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -529,7 +529,11 @@ class ProductTest extends \PHPUnit_Framework_TestCase ) . "\n"; $data = 'data://text/plain;base64,' . base64_encode($data); - $fixture = new \Magento\ImportExport\Model\Import\Source\Csv($data); + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $fixture = $objectManager->create( + 'Magento\ImportExport\Model\Import\Source\Csv', + array('$fileOrStream' => $data) + ); foreach (\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( 'Magento\Catalog\Model\Resource\Product\Collection' @@ -537,7 +541,6 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->fail("Unexpected precondition - product exists: '{$product->getId()}'."); } - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $uploader = $this->getMock( 'Magento\CatalogImportExport\Model\Import\Uploader', array('init'), @@ -676,4 +679,45 @@ class ProductTest extends \PHPUnit_Framework_TestCase "There should not be any linked upsell SKUs. The original" . " product SKU linked does not import cleanly." ); } + + /** + * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDataFixture Magento/Core/_files/store.php + * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php + * @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php + */ + public function testProductsWithMultipleStores() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + $filesystem = $objectManager->create('Magento\Framework\App\Filesystem'); + $directory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::ROOT_DIR); + + $source = new \Magento\ImportExport\Model\Import\Source\Csv( + __DIR__ . '/_files/products_multiple_stores.csv', + $directory + ); + $this->_model->setParameters( + array('behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product') + )->setSource( + $source + )->isDataValid(); + + $this->_model->importData(); + + /** @var \Magento\Catalog\Model\Product $product */ + $product = $objectManager->create('Magento\Catalog\Model\Product'); + $id = $product->getIdBySku('Configurable 03'); + $product->load($id); + $this->assertEquals('1', $product->getHasOptions()); + + $objectManager->get('Magento\Store\Model\StoreManagerInterface')->setCurrentStore('fixturestore'); + + /** @var \Magento\Catalog\Model\Product $simpleProduct */ + $simpleProduct = $objectManager->create('Magento\Catalog\Model\Product'); + $id = $simpleProduct->getIdBySku('Configurable 03-option_0'); + $simpleProduct->load($id); + $this->assertEquals('Option Label', $simpleProduct->getAttributeText('attribute_with_option')); + $this->assertEquals(array(2, 4), $simpleProduct->getAvailableInCategories()); + } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_multiple_stores.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_multiple_stores.csv new file mode 100644 index 0000000000000000000000000000000000000000..1dc4a16f7412d24e94eb5058f3f6736304b5555e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_multiple_stores.csv @@ -0,0 +1,6 @@ +sku,_store,_attribute_set,_type,_category,_root_category,_product_websites,test_configurable,cost,country_of_manufacture,created_at,custom_design,custom_design_from,custom_design_to,custom_layout_update,description,gallery,gift_message_available,gift_wrapping_available,gift_wrapping_price,has_options,image,image_label,is_returnable,manufacturer,meta_description,meta_keyword,meta_title,minimal_price,msrp,msrp_display_actual_price_type,msrp_enabled,name,news_from_date,news_to_date,options_container,page_layout,price,quantity_and_stock_status,related_tgtr_position_behavior,related_tgtr_position_limit,required_options,short_description,attribute_with_option,small_image,small_image_label,special_from_date,special_price,special_to_date,status,tax_class_id,thumbnail,thumbnail_label,updated_at,upsell_tgtr_position_behavior,upsell_tgtr_position_limit,url_key,url_path,visibility,weight,qty,min_qty,use_config_min_qty,is_qty_decimal,backorders,use_config_backorders,min_sale_qty,use_config_min_sale_qty,max_sale_qty,use_config_max_sale_qty,is_in_stock,notify_stock_qty,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,_related_sku,_related_position,_crosssell_sku,_crosssell_position,_upsell_sku,_upsell_position,_associated_sku,_associated_default_qty,_associated_position,_tier_price_website,_tier_price_customer_group,_tier_price_qty,_tier_price_price,_group_price_website,_group_price_customer_group,_group_price_price,_media_attribute_id,_media_image,_media_label,_media_position,_media_is_disabled,_super_products_sku,_super_attribute_code,_super_attribute_option,_super_attribute_price_corr +"Configurable 03-option_0",,Default,virtual,"Category 1/Category 1.1","Default Category",base,Option 1,,,"2014-06-13 07:34:02",,,,,,,,,,0,,,"Use config",,"Configurable 03 ","Configurable 03","Configurable 03",,,"Use config","Use config","Configurable 03-option_0",,,"Block after Info Column",,10.0000,"In Stock",,,0,,,,,,,,1,2,,,"2014-06-13 07:35:59",,,configurable-03-option_0,configurable-03-option_0.html,1,,99999.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,1,1,1,0.0000,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,, +,fixturestore,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"Option Label",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +"Configurable 03-option_1",,Default,virtual,"Category 1/Category 1.1","Default Category",base,Option 2,,,"2014-06-13 07:34:05",,,,,,,,,,0,,,"Use config",,"Configurable 03 ","Configurable 03","Configurable 03",,,"Use config","Use config","Configurable 03-option_1",,,"Block after Info Column",,10.0000,"In Stock",,,0,,,,,,,,1,2,,,"2014-06-13 07:34:05",,,configurable-03-option_1,configurable-03-option_1.html,1,,99999.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,1,1,1,0.0000,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,, +"Configurable 03",,Default,configurable,"Category 1/Category 1.1","Default Category",base,,,,"2014-06-13 07:34:07",,,,,,,,,,1,,,"Use config",,"Configurable 03 ","Configurable 03","Configurable 03",,,"Use config","Use config","Configurable 03",,,"Block after Info Column",,10.0000,"In Stock",,,1,,,,,,,,1,2,,,"2014-06-13 07:36:32",,,configurable-03,configurable-03.html,4,,0.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,1,1,1,0.0000,1,0,0,,,,,,,,,,,,,,,,,,,,,,"Configurable 03-option_0",test_configurable,Option 1,1.0000 +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"Configurable 03-option_1",test_configurable,Option 2,2.0000 diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product.php index 728caf069f7277418e592b35a38d4b4e9a5f0c3d..cfa71dcb2aa19bffbc97749764a44842acc033ee 100644 --- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product.php +++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product.php @@ -22,7 +22,7 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -require __DIR__ . '/../../../Magento/Downloadable/_files/product.php'; +require __DIR__ . '/../../../Magento/Downloadable/_files/product_downloadable.php'; /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php index 5bd46f2824fc0b4d0d1a5f3623bc6adc829eb0a3..5a529226aefacd8ad2ad5223ce925191deaf128f 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php @@ -463,16 +463,15 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase */ public function testGenerateSimpleProductsWithPartialData($productsData) { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */ + $stockItemService = $objectManager->get('Magento\CatalogInventory\Service\V1\StockItemService'); $this->_product->setNewVariationsAttributeSetId(4); $generatedProducts = $this->_model->generateSimpleProducts($this->_product, $productsData); foreach ($generatedProducts as $productId) { - /** @var $product \Magento\Catalog\Model\Product */ - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Product' - ); - $product->load($productId); - $this->assertEquals('0', $product->getStockItem()->getData('manage_stock')); - $this->assertEquals('1', $product->getStockItem()->getData('is_in_stock')); + $stockItemData = $stockItemService->getStockItem($productId); + $this->assertEquals('0', $stockItemData->isManageStock()); + $this->assertEquals('1', $stockItemData->getIsInStock()); } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php new file mode 100644 index 0000000000000000000000000000000000000000..697509c8e586b0c37cf3467787aea8925269e745 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* Create attribute */ +/** @var $installer \Magento\Catalog\Model\Resource\Setup */ +$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Catalog\Model\Resource\Setup', + array('resourceName' => 'catalog_setup') +); +/** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Catalog\Model\Resource\Eav\Attribute' +); +$attribute->setData( + array( + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 1, + 'is_configurable' => 1, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => array('Test Configurable'), + 'backend_type' => 'int', + 'option' => array( + 'value' => array('option_0' => array('Option 1'), 'option_1' => array('Option 2')), + 'order' => array('option_0' => 1, 'option_1' => 2) + ) + ) +); +$attribute->save(); + +/* Assign attribute to attribute set */ +$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php index 8db4d372003e781e487dbe1f85379333a4009073..7a9e71d2604b12057ab73de58112cdbd080d3d73 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php @@ -22,48 +22,13 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -/* Create attribute */ +require __DIR__ . '/configurable_attribute.php'; + /** @var $installer \Magento\Catalog\Model\Resource\Setup */ $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( 'Magento\Catalog\Model\Resource\Setup', array('resourceName' => 'catalog_setup') ); -/** @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */ -$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Resource\Eav\Attribute' -); -$attribute->setData( - array( - 'attribute_code' => 'test_configurable', - 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), - 'is_global' => 1, - 'is_user_defined' => 1, - 'frontend_input' => 'select', - 'is_unique' => 0, - 'is_required' => 1, - 'is_configurable' => 1, - 'is_searchable' => 0, - 'is_visible_in_advanced_search' => 0, - 'is_comparable' => 0, - 'is_filterable' => 0, - 'is_filterable_in_search' => 0, - 'is_used_for_promo_rules' => 0, - 'is_html_allowed_on_front' => 1, - 'is_visible_on_front' => 0, - 'used_in_product_listing' => 0, - 'used_for_sort_by' => 0, - 'frontend_label' => array('Test Configurable'), - 'backend_type' => 'int', - 'option' => array( - 'value' => array('option_0' => array('Option 1'), 'option_1' => array('Option 2')), - 'order' => array('option_0' => 1, 'option_1' => 2) - ) - ) -); -$attribute->save(); - -/* Assign attribute to attribute set */ -$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId()); /* Create simple products per each option */ /** @var $options \Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection */ diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php index 2d240dbee960174b05614329d9552623236c2fd4..67d35942ac72d530558fd5068dd1b33eb21d37c0 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php @@ -23,32 +23,18 @@ */ $customer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Customer\Model\Customer'); /** @var Magento\Customer\Model\Customer $customer */ -$customer->setWebsiteId( - 1 -)->setId( - 1 -)->setEntityTypeId( - 1 -)->setAttributeSetId( - 1 -)->setEmail( - 'customer@example.com' -)->setPassword( - 'password' -)->setGroupId( - 1 -)->setStoreId( - 1 -)->setIsActive( - 1 -)->setFirstname( - 'Firstname' -)->setLastname( - 'Lastname' -)->setDefaultBilling( - 1 -)->setDefaultShipping( - 1 -); +$customer->setWebsiteId(1) + ->setId(1) + ->setEntityTypeId(1) + ->setAttributeSetId(1) + ->setEmail('customer@example.com') + ->setPassword('password') + ->setGroupId(1) + ->setStoreId(1) + ->setIsActive(1) + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->setDefaultBilling(1) + ->setDefaultShipping(1); $customer->isObjectNew(true); $customer->save(); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/ProductTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/ProductTest.php index ab80ab13ae0f601df3361ff94be90f5ca93ef898..becf1073dcd27087afd4ba416f0030485784844e 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/ProductTest.php @@ -30,7 +30,7 @@ namespace Magento\Downloadable\Controller; class ProductTest extends \Magento\TestFramework\TestCase\AbstractController { /** - * @magentoDataFixture Magento/Downloadable/_files/product.php + * @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php */ public function testViewAction() { diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php index 6db305ce849e394ef58ba49d1abba0b40c9a4cf8..2b405109d202aa10a031b509f6a94408ea006196 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Product/TypeTest.php @@ -42,7 +42,7 @@ class TypeTest extends \PHPUnit_Framework_TestCase } /** - * @magentoDataFixture Magento/Downloadable/_files/product_with_files.php + * @magentoDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php * @magentoAppArea adminhtml */ public function testDeleteTypeSpecificData() diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php similarity index 100% rename from dev/tests/integration/testsuite/Magento/Downloadable/_files/product.php rename to dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..6e6a5f7085c2ef107cd9f8021363548b8c106109 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php @@ -0,0 +1,24 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_with_files.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php similarity index 100% rename from dev/tests/integration/testsuite/Magento/Downloadable/_files/product_with_files.php rename to dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..6e6a5f7085c2ef107cd9f8021363548b8c106109 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files_rollback.php @@ -0,0 +1,24 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php index f9f373c06b99594b877f47a060410ad2d769346a..0b498eb491793118eb56c5fcaf1c52396ad5b772 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php @@ -50,7 +50,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase } /** - * @magentoDataFixture Magento/Downloadable/_files/product.php + * @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php * @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php */ public function testInitFromOrderShippingAddressSameAsBillingWhenEmpty() @@ -69,7 +69,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase } /** - * @magentoDataFixture Magento/Downloadable/_files/product.php + * @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php * @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php * @magentoDataFixture Magento/Sales/_files/order_shipping_address_same_as_billing.php */ @@ -90,7 +90,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase } /** - * @magentoDataFixture Magento/Downloadable/_files/product.php + * @magentoDataFixture Magento/Downloadable/_files/product_downloadable.php * @magentoDataFixture Magento/Downloadable/_files/order_with_downloadable_product.php * @magentoDataFixture Magento/Sales/_files/order_shipping_address_different_to_billing.php */ diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php index cda5374ec0538b571fade82a170bd515a5ed802c..8b346afc80c030a4d43d770b5de20415092585a3 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_info.php @@ -28,30 +28,21 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product'); -$product->setTypeId( - 'virtual' -)->setId( - 1 -)->setAttributeSetId( - 4 -)->setName( - 'Simple Product' -)->setSku( - 'simple' -)->setPrice( - 10 -)->setStockData( - array( +$product->setTypeId('virtual') + ->setId(1) + ->setAttributeSetId(4) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setStockData(array( 'use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1 - ) -)->setVisibility( - \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH -)->setStatus( - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED -)->save(); + )) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->save(); $product->load(1); $addressData = include __DIR__ . '/address_data.php'; diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php index f8477b69b25aa0d9b54e58cc996b67173b7ffd80..f8a3e8daeacccbf0e486fc82204eb3238b0cf16c 100644 --- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php +++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php @@ -46,6 +46,7 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase } /** + * @magentoAppIsolation enabled * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoDataFixture Magento/Tax/_files/tax_classes.php diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index cd8801dbfbc8ba8b51f16333434d78b824f75518..b58bd0afe7cbe5b5dd59e0ae8821952b729bae66 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -1744,6 +1744,36 @@ return array( 'Magento\Framework\View\Asset\ModuleNotation\Resolver::convertModuleNotationToPath' ], ['getViewFile', 'Magento\Framework\View\FileSystem', 'Magento\Framework\View\Asset\File::getSourceFile()'], + [ + '_unserializeValue', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::unserializeValue' + ], + [ + '_isEncodedArrayFieldValue', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::isEncodedArrayFieldValue' + ], + [ + '_serializeValue', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::serializeValue' + ], + [ + '_fixQty', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::fixQty' + ], + [ + '_encodeArrayFieldValue', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::encodeArrayFieldValue' + ], + [ + '_decodeArrayFieldValue', + 'Magento\CatalogInventory\Helper\Minsaleqty', + 'Magento\CatalogInventory\Helper\Minsaleqty::decodeArrayFieldValue' + ], ['updateOrderAction', 'Magento\Paypal\Controller\Express\AbstractExpress'], ['updateOrder', 'Magento\Paypal\Model\Express\Checkout'], ['_matchBnCountryCode', 'Magento\Paypal\Model\Config'], diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php index ea68041a59f14391e3beea45e31c915b8aa6ffa1..330062a24478d82b30a63b1d519ec87f1d07acff 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php @@ -339,4 +339,5 @@ return array( ['_inventoryModel', 'Magento\AdvancedCheckout\Model\Resource\Sku\Errors\Grid\Collection'], ['_productInstance', 'Magento\CatalogInventory\Model\Stock\Item'], ['_regionBuilder', 'Magento\Customer\Model\Address\Converter'], + ['_scopeConfig', 'Magento\CatalogInventory\Helper\Minsaleqty', 'scopeConfig'], ); diff --git a/dev/tests/unit/testsuite/Magento/Authorizenet/Model/Directpost/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Authorizenet/Model/Directpost/ObserverTest.php index 9778cc6afbd5b056f702ca0414ab7a12b91b50cc..6334978d52bd862f8dc6979be73b6ae245937551 100644 --- a/dev/tests/unit/testsuite/Magento/Authorizenet/Model/Directpost/ObserverTest.php +++ b/dev/tests/unit/testsuite/Magento/Authorizenet/Model/Directpost/ObserverTest.php @@ -125,7 +125,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase $this->returnValue('encoded response') ); $response->expects($this->once())->method('clearHeader')->with('Location'); - $response->expects($this->once())->method('setBody')->with('encoded response'); + $response->expects($this->once())->method('representJson')->with('encoded response'); $this->model->addAdditionalFieldsToResponseFrontend($observer); } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php index 83151ae6df0cd8bbb591cb366fac9d5fba157262..975711fdd96aa7ddda0e7d76e0354d12b5097bdb 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php @@ -136,7 +136,7 @@ class WidgetTest extends \PHPUnit_Framework_TestCase ); $testHtml = '<div>Some test html</div>'; $this->chooserBlockMock->expects($this->once())->method('getTreeJson')->will($this->returnValue($testHtml)); - $this->responseMock->expects($this->once())->method('setBody')->with($this->equalTo($testHtml)); + $this->responseMock->expects($this->once())->method('representJson')->with($this->equalTo($testHtml)); $this->controller->categoriesJsonAction(); } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php index f2de2a7b003349ca5ce3d0c9a1ee9d449e8e66aa..11037157cb78473f5e7569b0ee4506ae60c65788 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/StockTest.php @@ -30,58 +30,52 @@ class StockTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Catalog\Model\Product\Attribute\Backend\Stock */ - protected $_model; + protected $model; /** - * @var \Magento\CatalogInventory\Model\Stock\Item + * @var \Magento\CatalogInventory\Service\V1\StockItemServiceInterface */ - protected $_inventory; + protected $stockItemService; /** * @var \Magento\TestFramework\Helper\ObjectManager */ - protected $_objectHelper; + protected $objectHelper; protected function setUp() { - $this->_objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this); - $this->_inventory = $this->getMock( - 'Magento\CatalogInventory\Model\Stock\Item', - array('getIsInStock', 'getQty', 'loadByProduct', '__wakeup'), - array(), - '', - false - ); + $this->objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->stockItemService = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\StockItemService') + ->disableOriginalConstructor() + ->getMock(); - $stockItemFactory = $this->getMock( - 'Magento\CatalogInventory\Model\Stock\ItemFactory', - array('create'), - array(), - '', - false - ); - $stockItemFactory->expects($this->any())->method('create')->will($this->returnValue($this->_inventory)); - $this->_model = $this->_objectHelper->getObject( + $this->model = $this->objectHelper->getObject( 'Magento\Catalog\Model\Product\Attribute\Backend\Stock', - array('data' => array('inventory' => $this->_inventory), 'stockItemFactory' => $stockItemFactory) + array('stockItemService' => $this->stockItemService) ); $attribute = $this->getMock('Magento\Framework\Object', array('getAttributeCode')); - $attribute->expects( - $this->atLeastOnce() - )->method( - 'getAttributeCode' - )->will( - $this->returnValue(self::ATTRIBUTE_NAME) - ); - $this->_model->setAttribute($attribute); + $attribute->expects($this->atLeastOnce()) + ->method('getAttributeCode') + ->will($this->returnValue(self::ATTRIBUTE_NAME)); + $this->model->setAttribute($attribute); } public function testAfterLoad() { - $this->_inventory->expects($this->once())->method('getIsInStock')->will($this->returnValue(1)); - $this->_inventory->expects($this->once())->method('getQty')->will($this->returnValue(5)); - $object = new \Magento\Framework\Object(); - $this->_model->afterLoad($object); + $productId = 2; + $stockItemDo = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItem') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockItemService->expects($this->once()) + ->method('getStockItem') + ->with($productId) + ->will($this->returnValue($stockItemDo)); + + $stockItemDo->expects($this->once())->method('getIsInStock')->will($this->returnValue(1)); + $stockItemDo->expects($this->once())->method('getQty')->will($this->returnValue(5)); + $object = new \Magento\Framework\Object(['id' => $productId]); + $this->model->afterLoad($object); $data = $object->getData(); $this->assertEquals(1, $data[self::ATTRIBUTE_NAME]['is_in_stock']); $this->assertEquals(5, $data[self::ATTRIBUTE_NAME]['qty']); @@ -100,7 +94,7 @@ class StockTest extends \PHPUnit_Framework_TestCase $this->assertEquals(2, $stockData['qty']); $this->assertNotEmpty($object->getData(self::ATTRIBUTE_NAME)); - $this->_model->beforeSave($object); + $this->model->beforeSave($object); $stockData = $object->getStockData(); $this->assertEquals(1, $stockData['is_in_stock']); @@ -117,7 +111,7 @@ class StockTest extends \PHPUnit_Framework_TestCase ) ); - $this->_model->beforeSave($object); + $this->model->beforeSave($object); $stockData = $object->getStockData(); $this->assertNull($stockData['qty']); @@ -132,7 +126,7 @@ class StockTest extends \PHPUnit_Framework_TestCase ) ); - $this->_model->beforeSave($object); + $this->model->beforeSave($object); $stockData = $object->getStockData(); $this->assertEquals(0, $stockData['qty']); diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/DefaultValidatorTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/DefaultValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5df12e54d03902eeec2482f912cc827b20b08e0b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/DefaultValidatorTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class DefaultValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Option\Validator\DefaultValidator + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueMock; + + protected function setUp() + { + $configMock = $this->getMock('Magento\Catalog\Model\ProductOptions\ConfigInterface'); + $priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price(); + $config = [ + [ + 'label' => 'group label 1', + 'types' => [ + [ + 'label' => 'label 1.1', + 'name' => 'name 1.1', + 'disabled' => false + ], + ] + ], + [ + 'label' => 'group label 2', + 'types' => [ + [ + 'label' => 'label 2.2', + 'name' => 'name 2.2', + 'disabled' => true + ], + ] + ], + ]; + $configMock->expects($this->once())->method('getAll')->will($this->returnValue($config)); + $methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', '__wakeup']; + $this->valueMock = $this->getMock('Magento\Catalog\Model\Product\Option', $methods, [], '', false); + $this->validator = new \Magento\Catalog\Model\Product\Option\Validator\DefaultValidator( + $configMock, + $priceConfigMock + ); + } + + public function testIsValidSuccess() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->assertTrue($this->validator->isValid($this->valueMock)); + $this->assertEmpty($this->validator->getMessages()); + } + + public function testIsValidFail() + { + $this->valueMock->expects($this->once())->method('getTitle'); + $this->valueMock->expects($this->once())->method('getType'); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('some_new_value')); + $this->valueMock->expects($this->never())->method('getPrice'); + $messages = [ + 'option required fields' => 'Missed values for option required fields', + 'option type' => 'Invalid option type', + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } + + public function testValidationNegativePrice() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(-12)); + + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/FileTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/FileTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2c9e6913719ce29d5a422cfcec98afee60d0f950 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/FileTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class FileTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Option\Validator\File + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueMock; + + protected function setUp() + { + $configMock = $this->getMock('Magento\Catalog\Model\ProductOptions\ConfigInterface'); + $priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price(); + $config = [ + [ + 'label' => 'group label 1', + 'types' => [ + [ + 'label' => 'label 1.1', + 'name' => 'name 1.1', + 'disabled' => false + ], + ] + ], + [ + 'label' => 'group label 2', + 'types' => [ + [ + 'label' => 'label 2.2', + 'name' => 'name 2.2', + 'disabled' => true + ], + ] + ], + ]; + $configMock->expects($this->once())->method('getAll')->will($this->returnValue($config)); + $methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', 'getImageSizeX', 'getImageSizeY','__wakeup']; + $this->valueMock = $this->getMock('Magento\Catalog\Model\Product\Option', $methods, [], '', false); + $this->validator = new \Magento\Catalog\Model\Product\Option\Validator\File( + $configMock, + $priceConfigMock + ); + } + + public function testIsValidSuccess() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getImageSizeY')->will($this->returnValue(15)); + $this->assertEmpty($this->validator->getMessages()); + $this->assertTrue($this->validator->isValid($this->valueMock)); + } + + public function testIsValidWithNegativeImageSize() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(-10)); + $this->valueMock->expects($this->never())->method('getImageSizeY'); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } + + public function testIsValidWithNegativeImageSizeY() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getImageSizeY')->will($this->returnValue(-10)); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/PoolTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/PoolTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cb9ece9ea1603dc272cf6cda63bf5aa9fb2937fa --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/PoolTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class PoolTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Option\Validator\Pool + */ + protected $pool; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $defaultValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $selectValidatorMock; + + protected function setUp() + { + $this->defaultValidatorMock = $this->getMock( + 'Magento\Catalog\Model\Product\Option\Validator\DefaultValidator', [], [], '', false + ); + $this->selectValidatorMock = $this->getMock( + 'Magento\Catalog\Model\Product\Option\Validator\Select', [], [], '', false + ); + $this->pool = new \Magento\Catalog\Model\Product\Option\Validator\Pool( + ['default' => $this->defaultValidatorMock, 'select' => $this->selectValidatorMock] + ); + } + + public function testGetSelectValidator() + { + $this->assertEquals($this->selectValidatorMock, $this->pool->get('select')); + } + + public function testGetDefaultValidator() + { + $this->assertEquals($this->defaultValidatorMock, $this->pool->get('default')); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/SelectTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/SelectTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c762db457bdae2523959b0c418d791225d8aabb7 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/SelectTest.php @@ -0,0 +1,178 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class SelectTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Option\Validator\Select + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueMock; + + protected function setUp() + { + $configMock = $this->getMock('Magento\Catalog\Model\ProductOptions\ConfigInterface'); + $priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price(); + $config = [ + [ + 'label' => 'group label 1', + 'types' => [ + [ + 'label' => 'label 1.1', + 'name' => 'name 1.1', + 'disabled' => false + ], + ] + ], + [ + 'label' => 'group label 2', + 'types' => [ + [ + 'label' => 'label 2.2', + 'name' => 'name 2.2', + 'disabled' => true + ], + ] + ], + ]; + $configMock->expects($this->once())->method('getAll')->will($this->returnValue($config)); + $methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', '__wakeup', 'getData']; + $this->valueMock = $this->getMock('Magento\Catalog\Model\Product\Option', $methods, [], '', false); + $this->validator = new \Magento\Catalog\Model\Product\Option\Validator\Select( + $configMock, + $priceConfigMock + ); + } + + + /** + * @param array $value + * @dataProvider isValidSuccessDataProvider + */ + public function testIsValidSuccess($value) + { + $value = [ + 'price_type' => 'fixed', + 'price' => '10', + 'title' => 'Some Title' + ]; + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->never())->method('getPriceType'); + $this->valueMock->expects($this->never())->method('getPrice'); + $this->valueMock->expects($this->any())->method('getData')->with('values')->will($this->returnValue([$value])); + $this->assertTrue($this->validator->isValid($this->valueMock)); + $this->assertEmpty($this->validator->getMessages()); + } + + public function isValidSuccessDataProvider() + { + $value = [ + 'price_type' => 'fixed', + 'price' => '10', + 'title' => 'Some Title' + ]; + + $valueWithoutAllData = [ + 'some_data' =>'data' + ]; + + return [ + 'all_data' => [$value], + 'not_all_data' => [$valueWithoutAllData] + ]; + } + + public function testIsValidateWithInvalidOptionValues() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->never())->method('getPriceType'); + $this->valueMock->expects($this->never())->method('getPrice'); + $this->valueMock + ->expects($this->once()) + ->method('getData') + ->with('values') + ->will($this->returnValue('invalid_data')); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } + + public function testIsValidateWithEmptyValues() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->never())->method('getPriceType'); + $this->valueMock->expects($this->never())->method('getPrice'); + $this->valueMock->expects($this->any())->method('getData')->with('values')->will($this->returnValue([])); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } + + /** + * @param string $priceType + * @param int $price + * @param string|null $title + * @dataProvider isValidateWithInvalidDataDataProvider + */ + public function testIsValidateWithInvalidData($priceType, $price, $title) + { + $value = [ + 'price_type' => $priceType, + 'price' => $price, + 'title' => $title + ]; + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->never())->method('getPriceType'); + $this->valueMock->expects($this->never())->method('getPrice'); + $this->valueMock->expects($this->any())->method('getData')->with('values')->will($this->returnValue([$value])); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } + + public function isValidateWithInvalidDataDataProvider() + { + return [ + 'invalid_price' => ['fixed', -10, 'Title'], + 'invalid_price_type' => ['some_value', '10', 'Title'], + 'empty_title' => ['fixed', 10, null] + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/TextTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/TextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..08e277fd102eaaa9f02116bf6c801c2159df5b40 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Option/Validator/TextTest.php @@ -0,0 +1,98 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Model\Product\Option\Validator; + +class TextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\Product\Option\Validator\Text + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueMock; + + protected function setUp() + { + $configMock = $this->getMock('Magento\Catalog\Model\ProductOptions\ConfigInterface'); + $priceConfigMock = new \Magento\Catalog\Model\Config\Source\Product\Options\Price(); + $config = [ + [ + 'label' => 'group label 1', + 'types' => [ + [ + 'label' => 'label 1.1', + 'name' => 'name 1.1', + 'disabled' => false + ], + ] + ], + [ + 'label' => 'group label 2', + 'types' => [ + [ + 'label' => 'label 2.2', + 'name' => 'name 2.2', + 'disabled' => true + ], + ] + ], + ]; + $configMock->expects($this->once())->method('getAll')->will($this->returnValue($config)); + $methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', '__wakeup', 'getMaxCharacters']; + $this->valueMock = $this->getMock('Magento\Catalog\Model\Product\Option', $methods, [], '', false); + $this->validator = new \Magento\Catalog\Model\Product\Option\Validator\Text( + $configMock, + $priceConfigMock + ); + } + + public function testIsValidSuccess() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getMaxCharacters')->will($this->returnValue(10)); + $this->assertTrue($this->validator->isValid($this->valueMock)); + $this->assertEmpty($this->validator->getMessages()); + } + + public function testIsValidWithNegativeMaxCharacters() + { + $this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title')); + $this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1')); + $this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed')); + $this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10)); + $this->valueMock->expects($this->once())->method('getMaxCharacters')->will($this->returnValue(-10)); + $messages = [ + 'option values' => 'Invalid option value' + ]; + $this->assertFalse($this->validator->isValid($this->valueMock)); + $this->assertEquals($messages, $this->validator->getMessages()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php deleted file mode 100644 index bc4c977b81dc94b28c5e80b358895a0c79b0d937..0000000000000000000000000000000000000000 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -namespace Magento\Catalog\Model\Resource\Product\Indexer\Eav; - -use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; - -class SourceTest extends \PHPUnit_Framework_TestCase -{ - /** @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source */ - protected $source; - - /** @var ObjectManagerHelper */ - protected $objectManagerHelper; - - /** @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject */ - protected $resource; - - /** @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $config; - - /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $managerInterface; - - /** @var \Magento\Catalog\Model\Resource\Helper|\PHPUnit_Framework_MockObject_MockObject */ - protected $helper; - - protected function setUp() - { - $this->resource = $this->getMock( - 'Magento\Framework\App\Resource', - ['getConnection', 'getTableName'], - [], - '', - false - ); - $this->config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false); - $this->managerInterface = $this->getMock('Magento\Framework\Event\ManagerInterface'); - $this->helper = $this->getMock('Magento\Catalog\Model\Resource\Helper', [], [], '', false); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->source = $this->objectManagerHelper->getObject( - 'Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source', - [ - 'resource' => $this->resource, - 'eavConfig' => $this->config, - 'eventManager' => $this->managerInterface, - 'resourceHelper' => $this->helper - ] - ); - } - - /** - * Test `reindexEntity` method - */ - public function testReindexEntities() - { - $query = $this->getMockBuilder('PDO_Statement')->setMethods(['fetch'])->disableOriginalConstructor()->getMock(); - $query->expects($this->any())->method('fetch')->will($this->returnValue([])); - - $select = $this->getMockBuilder('\Magento\Framework\DB\Select')->setMethods([ - 'select', 'from', 'where', 'join', 'joinLeft', 'joinInner', - 'assemble', 'columns', 'insertFromSelect', 'query', 'deleteFromSelect' - ])->disableOriginalConstructor()->getMock(); - $select->expects($this->any())->method('from')->withAnyParameters()->will($this->returnSelf()); - $select->expects($this->any())->method('where')->will($this->returnSelf()); - $select->expects($this->any())->method('join')->will($this->returnSelf()); - $select->expects($this->any())->method('query')->will($this->returnValue($query)); - $select->expects($this->any())->method('columns')->will($this->returnSelf()); - $select->expects($this->any())->method('joinLeft')->will($this->returnSelf()); - $select->expects($this->any())->method('insertFromSelect')->will($this->returnSelf()); - $select->expects($this->any())->method('deleteFromSelect')->with('catalog_product_index_eav_tmp') - ->will($this->returnValue($query)); - $select->expects($this->once())->method('joinInner') - ->with( - array('d2' => 'catalog_product_entity_int'), - 'd.entity_id = d2.entity_id AND d2.attribute_id = 96 AND d2.value = 1 AND d.store_id = 0' - )->will($this->returnSelf()); - - $adapter = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql') - ->setMethods([ - 'select', 'delete', 'beginTransaction', 'getTransactionLevel', 'fetchCol', 'query', 'quoteInto', - 'describeTable', 'commit' - ])->disableOriginalConstructor()->getMock(); - $adapter->expects($this->any())->method('select')->will($this->returnValue($select)); - $adapter->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(1)); - $adapter->expects($this->any())->method('fetchCol')->will($this->returnValue([1])); - $adapter->expects($this->any())->method('query')->will($this->returnValue($query)); - $adapter->expects($this->any())->method('describeTable')->will($this->returnValue([])); - $adapter->expects($this->any())->method('commit')->will($this->returnValue(null)); - - - $this->resource->expects($this->any())->method('getConnection')->with('core_write') - ->will($this->returnValue($adapter)); - $this->resource->expects($this->at(4))->method('getTableName')->with('catalog_product_index_eav_tmp') - ->will($this->returnArgument(0)); - $this->resource->expects($this->at(8))->method('getTableName')->with('catalog_product_entity_int') - ->will($this->returnArgument(0)); - - - $attribute = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')->disableOriginalConstructor() - ->setMethods(['getId', '__sleep', '__wakeup', 'getBackend', 'getTable', 'isScopeGlobal'])->getMock(); - $attribute->expects($this->once())->method('getId')->will($this->returnValue(96)); - $attribute->expects($this->any())->method('getBackend')->will($this->returnSelf()); - $attribute->expects($this->any())->method('getTable')->will($this->returnValue('some_table')); - $attribute->expects($this->any())->method('isScopeGlobal')->will($this->returnValue(true)); - $this->config->expects($this->any())->method('getAttribute')->will($this->returnValue($attribute)); - - $this->source->reindexEntities([1]); - } -} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php index 664200410d15702f47258d9cbf26844d7e417d3b..332aac74feb1dcfa32cbd355693f03e52e84ed70 100644 --- a/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php +++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/UrlTest.php @@ -30,15 +30,179 @@ class UrlTest extends \PHPUnit_Framework_TestCase */ protected $_model; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_resourceModel; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_urlFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_storeModel; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_productModel; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_categoryModel; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_categoryFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_categoryHelper; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $_rewriteModel; + /** * @var \Magento\TestFramework\Helper\ObjectManager */ protected $_objectManager; + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ protected function setUp() { + $this->_resourceModel = $this->getMock( + '\Magento\Catalog\Model\Resource\Url', + array( + '__wakeup', + 'getStores', + 'clearStoreInvalidRewrites', + 'getProductsByStore', + 'prepareRewrites', + 'getCategories', + 'getCategory', + 'getCategoryModel', + 'loadCategoryChilds', + 'checkRequestPaths', + 'saveRewrite', + 'clearCategoryProduct', + 'getCategoryParentPath', + 'findFinalTargetPath', + 'deleteRewriteRecord', + 'saveCategoryAttribute', + 'getProductsByCategory', + 'deleteCategoryProductStoreRewrites' + ), + array(), + '', + false + ); + $this->_urlFactory = $this->getMock( + '\Magento\Catalog\Model\Resource\UrlFactory', + array( + 'create', + 'formatUrlKey', + 'getUrlPath' + ) + ); + $this->_storeModel = $this->getMock( + '\Magento\Store\Model\Store', + array( + '__wakeup', + 'getId', + 'getRootCategoryId' + ), + array(), + '', + false + ); + $this->_productModel = $this->getMock( + 'Magento\Catalog\Model\Product', + array( + '__wakeup', + 'getCategoryIds', + 'getId', + 'getResource', + 'getUrlPath' + ), + array(), + '', + false + ); + $this->_categoryModel = $this->getMock( + 'Magento\Catalog\Model\Category', + array( + '__wakeup', + 'getId', + 'getStoreId', + 'getChilds', + 'getAllChilds', + 'formatUrlKey', + 'getUrlKey', + 'getCategoryUrlPath', + 'getName' + ), + array(), + '', + false + ); + $this->_categoryFactory = $this->getMock('\Magento\Catalog\Model\CategoryFactory'); + $this->_categoryHelper = $this->getMock( + 'Magento\Catalog\Helper\Category', + array( + 'getCategoryUrlPath', + 'getCategoryUrlSuffix' + ), + array(), + '', + false + ); + $this->_rewriteModel = $this->getMock( + 'Magento\UrlRewrite\Model\UrlRewrite', + array( + '__wakeup', + 'getRequestPath' + ), + array(), + '', + false + ); + $this->_objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); - $this->_model = $this->_objectManager->getObject('Magento\Catalog\Model\Url'); + $this->_model = $this->_objectManager->getObject( + 'Magento\Catalog\Model\Url', + array( + 'urlFactory' => $this->_urlFactory, + 'catalogCategoryFactory' => $this->_categoryFactory, + 'catalogCategory' => $this->_categoryHelper + ) + ); + + $this->_urlFactory->expects($this->any())->method('create') + ->will($this->returnValue($this->_resourceModel)); + $this->_resourceModel->expects($this->any())->method('getCategory') + ->will($this->returnValue($this->_categoryModel)); + $this->_resourceModel->expects($this->any())->method('loadCategoryChilds') + ->will($this->returnValue($this->_categoryModel)); + $this->_resourceModel->expects($this->any())->method('saveRewrite') + ->will($this->returnSelf()); + $this->_categoryModel->expects($this->any())->method('getId') + ->will($this->returnValue(1)); + $this->_categoryModel->expects($this->any())->method('getStoreId') + ->will($this->returnValue(1)); + $this->_categoryModel->expects($this->any())->method('getChilds') + ->will($this->returnSelf()); + $this->_storeModel->expects($this->any())->method('getId') + ->will($this->returnValue(1)); } public function testGenerateUniqueIdPath() @@ -48,4 +212,102 @@ class UrlTest extends \PHPUnit_Framework_TestCase $this->assertContains('_', $path); $this->assertNotEquals($path, $this->_model->generateUniqueIdPath()); } + + public function testRefreshRewrites() + { + $rewrite = array('category/1' => $this->_rewriteModel); + $validatedPath = 'validated_path.html'; + + $this->_urlFactory->expects($this->any())->method('formatUrlKey') + ->will($this->returnValue('url_formatted')); + $this->_urlFactory->expects($this->any())->method('getUrlPath') + ->will($this->returnValue($validatedPath)); + $this->_resourceModel->expects($this->any())->method('prepareRewrites') + ->will($this->returnValue($rewrite)); + $this->_resourceModel->expects($this->at(0))->method('getStores') + ->will($this->returnValue(array($this->_storeModel))); + $this->_resourceModel->expects($this->any())->method('getStores') + ->will($this->returnValue($this->_storeModel)); + $this->_resourceModel->expects($this->once())->method('clearStoreInvalidRewrites') + ->will($this->returnSelf()); + $this->_resourceModel->expects($this->at(14))->method('getProductsByStore') + ->will($this->returnValue(null)); + $this->_resourceModel->expects($this->any())->method('getProductsByStore') + ->will($this->returnValue(array($this->_productModel))); + $this->_resourceModel->expects($this->any())->method('getCategories') + ->will($this->returnValue(array($this->_categoryModel))); + $this->_resourceModel->expects($this->once())->method('checkRequestPaths') + ->will($this->returnValue($validatedPath)); + $this->_resourceModel->expects($this->once())->method('clearCategoryProduct') + ->will($this->returnSelf()); + $this->_productModel->expects($this->any())->method('getCategoryIds') + ->will($this->returnValue(array(1))); + $this->_productModel->expects($this->any())->method('getId') + ->will($this->returnValue(1)); + $this->_productModel->expects($this->any())->method('getResource') + ->will($this->returnValue($this->_resourceModel)); + $this->_productModel->expects($this->once())->method('getUrlPath') + ->will($this->returnValue($validatedPath)); + $this->_storeModel->expects($this->any())->method('getRootCategoryId') + ->will($this->returnValue(1)); + + $this->_model->refreshRewrites(); + } + + /** + * @param string $targetPathExecute + * @param bool $changeRequestPath + * + * @dataProvider refreshcategoryRewriteDataProvider + */ + public function testRefreshCategoryRewrite($targetPathExecute, $changeRequestPath) + { + $categoryId = 1; + $rewrite = array('category/1' => $this->_rewriteModel); + + $this->_resourceModel->expects($this->once())->method('prepareRewrites') + ->will($this->returnValue($rewrite)); + $this->_resourceModel->expects($this->at(0))->method('getStores') + ->will($this->returnValue(array($this->_storeModel))); + $this->_resourceModel->expects($this->once())->method('getStores') + ->will($this->returnValue($this->_storeModel)); + $this->_resourceModel->expects($this->any())->method('getCategoryModel') + ->will($this->returnValue($this->_categoryModel)); + $this->_resourceModel->expects($this->once())->method('getCategoryParentPath') + ->will($this->returnValue('parent_path')); + $this->_resourceModel->expects($this->any())->method('deleteRewriteRecord') + ->will($this->returnSelf()); + $this->_resourceModel->expects($this->any())->method('saveCategoryAttribute') + ->will($this->returnSelf()); + $this->_resourceModel->expects($this->any())->method('getProductsByCategory') + ->will($this->returnValue(null)); + $this->_resourceModel->expects($this->any())->method('deleteCategoryProductStoreRewrites') + ->will($this->returnSelf()); + $this->_resourceModel->expects($this->$targetPathExecute())->method('findFinalTargetPath') + ->will($this->returnValue('category/1')); + $this->_categoryModel->expects($this->any())->method('getAllChilds') + ->will($this->returnValue(array($this->_categoryModel))); + $this->_categoryModel->expects($this->any())->method('formatUrlKey') + ->will($this->returnValue('url_formatted')); + $this->_categoryModel->expects($this->any())->method('getUrlKey') + ->will($this->returnValue('url_key')); + $this->_categoryModel->expects($this->any())->method('getCategoryUrlPath') + ->will($this->returnValue('category_parent_path')); + $this->_categoryHelper->expects($this->once())->method('getCategoryUrlPath') + ->will($this->returnValue('category_parent_path')); + $this->_categoryHelper->expects($this->once())->method('getCategoryUrlSuffix') + ->will($this->returnValue('suffics')); + $this->_rewriteModel->expects($this->once())->method('getRequestPath') + ->will($this->returnValue('category_parent_pathurl_formatted-1suffics')); + + $this->_model->refreshCategoryRewrite($categoryId, '', true, $changeRequestPath); + } + + public function refreshcategoryRewriteDataProvider() + { + return array( + array('once', true), + array('never', false) + ); + } } diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/ConverterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..13ae317e89bad84a5387ff588e6755b67b88e028 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/ConverterTest.php @@ -0,0 +1,79 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option; + +class ConverterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Converter + */ + protected $service; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $metadataConverterMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + + protected function setUp() + { + $this->metadataConverterMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface' + ); + $this->optionMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false + ); + + $this->service = new Converter($this->metadataConverterMock); + } + + public function testConvert() + { + $this->optionMock->expects($this->any())->method('getOptionId')->will($this->returnValue('123456')); + $this->optionMock->expects($this->any())->method('getTitle')->will($this->returnValue('Some Title')); + $this->optionMock->expects($this->any())->method('getType')->will($this->returnValue('Type')); + $this->optionMock->expects($this->any())->method('getSortOrder')->will($this->returnValue('12')); + $this->optionMock->expects($this->any())->method('getIsRequire')->will($this->returnValue(true)); + $options = [ + 'option_id' => '123456', + 'title' => 'Some Title', + 'type' => 'Type', + 'sort_order' => '12', + 'is_require' => true + ]; + $this->metadataConverterMock + ->expects($this->once()) + ->method('convert') + ->with($this->optionMock) + ->will($this->returnValue($options)); + $this->assertEquals($options, $this->service->convert($this->optionMock)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/CompositeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/CompositeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c9a8371352d251e7da1cc5a185c98b93646a4601 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/CompositeTest.php @@ -0,0 +1,106 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface; + +class CompositeTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Composite + */ + protected $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $converterMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $converterSelectMock; + + protected function setUp() + { + $this->converterMock = $this->getMock( + 'Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ConverterInterface' + ); + $this->converterSelectMock = $this->getMock( + 'Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter\Select', + [], + [], + '', + false + ); + $this->model = new Composite(['default' => $this->converterMock, 'select' => $this->converterSelectMock]); + } + + public function testConverterWithSelectType() + { + $this->optionMock = + $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', + [], + [], + '', + false + ); + $this->optionMock->expects($this->once())->method('getType')->will($this->returnValue('select')); + $this->converterSelectMock + ->expects($this + ->once()) + ->method('convert') + ->with($this->optionMock) + ->will($this->returnValue('Expected Result')); + $this->assertEquals('Expected Result', $this->model->convert($this->optionMock)); + } + + public function testConverterWithDefaultType() + { + $this->optionMock = + $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', + [], + [], + '', + false + ); + $this->optionMock->expects($this->once())->method('getType')->will($this->returnValue('other')); + $this->converterMock + ->expects($this + ->once()) + ->method('convert') + ->with($this->optionMock) + ->will($this->returnValue('Expected Result')); + $this->assertEquals('Expected Result', $this->model->convert($this->optionMock)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverterTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5bd3a254a692070feab3182e11d96d9c15c323ec --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/DefaultConverterTest.php @@ -0,0 +1,108 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class DefaultConverterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var DefaultConverter + */ + protected $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMetadata; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $attributeValueMock; + + protected function setUp() + { + $this->optionMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', + [], + [], + '', + false + ); + $this->attributeValueMock = $this->getMock( + '\Magento\Framework\Service\Data\Eav\AttributeValue', + [], + [], + '', + false + ); + $this->model = new DefaultConverter(); + } + + public function testConverter() + { + $this->optionMetadata = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata', + [], + [], + '', + false + ); + $this->optionMock + ->expects($this->once()) + ->method('getMetadata') + ->will($this->returnValue(array($this->optionMetadata))); + $this->optionMetadata->expects($this->once())->method('getPrice')->will($this->returnValue(100.12)); + $this->optionMetadata->expects($this->once())->method('getPriceType')->will($this->returnValue('USD')); + $this->optionMetadata->expects($this->once())->method('getSku')->will($this->returnValue('product_sku')); + $this->optionMetadata + ->expects($this->once()) + ->method('getCustomAttributes') + ->will($this->returnValue(array($this->attributeValueMock))); + $this->attributeValueMock + ->expects($this->once()) + ->method('getAttributeCode') + ->will($this->returnValue('attribute')); + $this->attributeValueMock + ->expects($this->once()) + ->method('getValue') + ->will($this->returnValue('value')); + $expectedOutput = array( + Metadata::PRICE => 100.12, + Metadata::PRICE_TYPE => 'USD', + Metadata::SKU => 'product_sku', + 'attribute' => 'value' + ); + $this->assertEquals($expectedOutput, $this->model->convert($this->optionMock)); + } + +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/SelectTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/SelectTest.php new file mode 100644 index 0000000000000000000000000000000000000000..40a25343f17fa2fa1090f9a648b21a05d1418b5c --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Converter/SelectTest.php @@ -0,0 +1,99 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Converter; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class SelectTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Select + */ + protected $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMetadataMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $attributeValueMock; + + protected function setUp() + { + $this->optionMock = + $this->getMock('\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false); + $this->optionMetadataMock = + $this->getMock('\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata', [], [], '', false); + $this->attributeValueMock = + $this->getMock('\Magento\Framework\Service\Data\Eav\AttributeValue', [], [], '', false); + $this->model = new Select(); + } + + public function testConverter() + { + $this->optionMock + ->expects($this->any()) + ->method('getMetadata') + ->will($this->returnValue(array('select' => $this->optionMetadataMock))); + $this->optionMetadataMock->expects($this->any())->method('getPrice')->will($this->returnValue(99.99)); + $this->optionMetadataMock->expects($this->any())->method('getPriceType')->will($this->returnValue('USD')); + $this->optionMetadataMock->expects($this->any())->method('getSku')->will($this->returnValue('product_sku')); + $this->optionMetadataMock + ->expects($this->any()) + ->method('getOptionTypeId') + ->will($this->returnValue('value option_type_id')); + $this->optionMetadataMock + ->expects($this->any()) + ->method('getCustomAttributes') + ->will($this->returnValue(array($this->attributeValueMock))); + $this->attributeValueMock + ->expects($this->once()) + ->method('getAttributeCode') + ->will($this->returnValue('attribute_code')); + $this->attributeValueMock + ->expects($this->once()) + ->method('getValue') + ->will($this->returnValue('attribute_value')); + $expectedValues= array( + 'values' => array( + '0' => array( + Metadata::PRICE => 99.99, + Metadata::PRICE_TYPE => 'USD', + Metadata::SKU => 'product_sku', + 'attribute_code' => 'attribute_value' + ) + )); + $this->assertEquals($expectedValues, $this->model->convert($this->optionMock)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReaderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..dfa5c16c973621c52c5f16e7705aad48f9e6d348 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/DefaultReaderTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class DefaultReaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + /** + * @var DefaultReader + */ + protected $service; + + protected function setUp() + { + $this->valueBuilderMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\MetadataBuilder', [], [], '', false + ); + $this->optionMock = $this->getMock( + '\Magento\Catalog\Model\Product\Option', ['getPrice', 'getPriceType', 'getSku', '__wakeup'], [], '', false + ); + $this->service = new DefaultReader($this->valueBuilderMock); + } + + public function testRead() + { + $this->optionMock->expects($this->once())->method('getPrice')->will($this->returnValue('10')); + $this->optionMock->expects($this->once())->method('getPriceType')->will($this->returnValue('USD')); + $this->optionMock->expects($this->once())->method('getSku')->will($this->returnValue('product_sku')); + $fields = [ + Metadata::PRICE => '10', + Metadata::PRICE_TYPE => 'USD' , + Metadata::SKU => 'product_sku' + ]; + $this->valueBuilderMock->expects($this->once()) + ->method('populateWithArray') + ->with($fields) + ->will($this->returnValue($this->valueBuilderMock)); + $this->valueBuilderMock->expects($this->once())->method('create')->will($this->returnValue('Expected value')); + $this->assertEquals(array('Expected value'), $this->service->read($this->optionMock)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/SelectTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/SelectTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e03e065c51901680607b35d2e72dd7061b73551b --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/Reader/SelectTest.php @@ -0,0 +1,89 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader; + +use \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class SelectTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Select + */ + protected $service; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $valueBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + protected function setUp() + { + $this->valueBuilderMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\MetadataBuilder', [], [], '', false + ); + $this->optionMock = $this->getMock( + '\Magento\Catalog\Model\Product\Option', [], [], '', false + ); + $this->service = new Select($this->valueBuilderMock); + } + + public function testRead() + { + $valueMock = $this->getMock( + '\Magento\Catalog\Model\Product\Option', + ['getPrice', 'getPriceType', 'getSku', 'getTitle', 'getSortOrder', 'getId', '__wakeup'], + [], + '', + false + ); + $this->optionMock->expects($this->any())->method('getValues')->will($this->returnValue(array($valueMock))); + $valueMock->expects($this->once())->method('getPrice')->will($this->returnValue('35')); + $valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('USD')); + $valueMock->expects($this->once())->method('getSku')->will($this->returnValue('product_sku')); + $valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('Some Title')); + $valueMock->expects($this->once())->method('getSortOrder')->will($this->returnValue('0')); + $valueMock->expects($this->once())->method('getId')->will($this->returnValue('12345678')); + $fields = [ + Metadata::PRICE => '35', + Metadata::PRICE_TYPE => 'USD' , + Metadata::SKU => 'product_sku', + Metadata::TITLE => 'Some Title', + Metadata::SORT_ORDER => '0', + Metadata::OPTION_TYPE_ID => '12345678' + ]; + $this->valueBuilderMock + ->expects($this->any())->method('populateWithArray') + ->with($fields) + ->will($this->returnValue($this->valueBuilderMock)); + $this->valueBuilderMock->expects($this->once())->method('create')->will($this->returnValue($fields)); + $this->assertEquals(array($fields), $this->service->read($this->optionMock)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5b3d0eb68e21ec5f419570c354941dbc4cb1d21d --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/Data/Option/Metadata/ReaderTest.php @@ -0,0 +1,80 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +use Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata; + +class ReaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader + */ + protected $reader; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $defaultReaderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $selectReaderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + protected function setUp() + { + $this->defaultReaderMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface'); + $this->selectReaderMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface'); + $this->optionMock = + $this->getMock('Magento\Catalog\Model\Product\Option', ['getType', '__wakeup'], [], '', false); + $this->reader = new \Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader( + [ + 'default' => $this->defaultReaderMock, + 'select' => $this->selectReaderMock + ] + ); + } + + public function testReadOptionWithTypeText() + { + $this->optionMock->expects($this->once())->method('getType')->will($this->returnValue('text')); + $this->defaultReaderMock->expects($this->once())->method('read')->with($this->optionMock); + $this->reader->read($this->optionMock); + } + + public function testReadOptionWithTypeSelect() + { + $this->optionMock->expects($this->once())->method('getType')->will($this->returnValue('select')); + $this->selectReaderMock->expects($this->once())->method('read')->with($this->optionMock); + $this->reader->read($this->optionMock); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..49fcb0632366dc3c058fed6c206bf48214d00bcc --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/ReadServiceTest.php @@ -0,0 +1,181 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +class ReadServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ReadService + */ + protected $service; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $configMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionTypeBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productRepositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMetadataReaderMock; + + protected function setUp() + { + $helper = new \Magento\TestFramework\Helper\ObjectManager($this); + + $this->configMock = $this->getMock('Magento\Catalog\Model\ProductOptions\ConfigInterface'); + $this->optionTypeBuilderMock = $this->getMock( + 'Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionTypeBuilder', + [], + [], + '', + false + ); + + $this->productRepositoryMock = $this->getMock('Magento\Catalog\Model\ProductRepository', [], [], '', false); + + $this->optionBuilderMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionBuilder', [], [], '', false); + $this->optionMetadataReaderMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface'); + $this->service = $helper->getObject( + '\Magento\Catalog\Service\V1\Product\CustomOptions\ReadService', + [ + 'productOptionConfig' => $this->configMock, + 'optionTypeBuilder' => $this->optionTypeBuilderMock, + 'optionBuilder' => $this->optionBuilderMock, + 'productRepository' => $this->productRepositoryMock, + 'optionMetadataReader' => $this->optionMetadataReaderMock + ] + ); + } + + public function testGetTypes() + { + $config = [ + [ + 'label' => 'group label 1', + 'types' => [ + [ + 'label' => 'label 1.1', + 'name' => 'name 1.1', + 'disabled' => false + ], + ] + ], + [ + 'label' => 'group label 2', + 'types' => [ + [ + 'label' => 'label 2.2', + 'name' => 'name 2.2', + 'disabled' => true + ], + ] + ], + ]; + + $this->configMock->expects($this->once())->method('getAll')->will($this->returnValue($config)); + + $expectedConfig = [ + 'label' => 'label 1.1', + 'code' => 'name 1.1', + 'group' => 'group label 1' + ]; + + $object = $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionType', [], [], '', false); + $this->optionTypeBuilderMock->expects($this->once()) + ->method('populateWithArray') + ->with($expectedConfig) + ->will($this->returnSelf()); + + $this->optionTypeBuilderMock->expects($this->once())->method('create')->will($this->returnValue($object)); + + $this->assertEquals([$object], $this->service->getTypes()); + } + + public function testGetList() + { + $productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $this->productRepositoryMock + ->expects($this->once()) + ->method('get') + ->with('product_sku') + ->will($this->returnValue($productMock)); + $value = [ + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 10 + ]; + $options[] = [ + Data\Option::OPTION_ID => 10, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + Data\Option::METADATA => $value + ]; + $methods = array('getId', 'getTitle', 'getType', 'getIsRequire', 'getSortOrder', '__wakeup'); + $optionMock = $this->getMock('\Magento\Catalog\Model\Product\Option', $methods, [], '', false); + $optionData = $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false); + $productMock + ->expects($this->once()) + ->method('getOptions') + ->will($this->returnValue(array($optionMock))); + $optionMock->expects($this->once())->method('getId')->will($this->returnValue(10)); + $optionMock->expects($this->once())->method('getTitle')->will($this->returnValue('Some title')); + $optionMock->expects($this->once())->method('getType')->will($this->returnValue('text')); + $optionMock->expects($this->once())->method('getIsRequire')->will($this->returnValue(true)); + $optionMock->expects($this->once())->method('getSortOrder')->will($this->returnValue(10)); + $this->optionMetadataReaderMock + ->expects($this->once()) + ->method('read') + ->with($optionMock) + ->will($this->returnValue($value)); + $this->optionBuilderMock + ->expects($this->once()) + ->method('populateWithArray') + ->with($options[0]) + ->will($this->returnSelf()); + $this->optionBuilderMock->expects($this->once())->method('create')->will($this->returnValue($optionData)); + + $this->assertEquals(array($optionData), $this->service->getList('product_sku')); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9527f570afbbd9489bb4e398454eca1d6143dcca --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/CustomOptions/WriteServiceTest.php @@ -0,0 +1,402 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Catalog\Service\V1\Product\CustomOptions; + +class WriteServiceTest extends \PHPUnit_Framework_TestCase +{ + + const PRODUCT_SKU = 'simple'; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $repositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionTypeBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionConverterMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $factoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMetadataReaderMock; + + /** + * @var \Magento\Catalog\Service\V1\Product\CustomOptions\WriteService + */ + protected $writeService; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $optionMock; + + protected function setUp() + { + $this->optionTypeBuilderMock = $this->getMock( + 'Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\Reader', + [], + [], + '', + false + ); + + $this->repositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', + [], + [], + '', + false + ); + $methods = [ + 'getOptions', + 'getOptionById', + 'setProductOptions', + 'setHasOptions', + 'save', + 'load', + 'reset', + 'getId', + '__wakeup', + 'setCanSaveCustomOptions' + ]; + $this->productMock = $this->getMock('Magento\Catalog\Model\Product', $methods, [], '', false); + + $this->optionConverterMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Converter', [], [], '', false); + + $this->repositoryMock + ->expects($this->once()) + ->method('get') + ->with(self::PRODUCT_SKU) + ->will($this->returnValue($this->productMock)); + + $this->optionBuilderMock = + $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\OptionBuilder', [], [], '', false); + + $this->optionMetadataReaderMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option\Metadata\ReaderInterface' + ); + + $this->factoryMock = $this->getMock( + '\Magento\Catalog\Model\Product\OptionFactory', ['create'], [], '', false, false + ); + + $this->optionMock = $this->getMock( + '\Magento\Catalog\Model\Product\Option', + ['__sleep', '__wakeup', 'getId', 'getTitle', 'getType', 'delete', 'getIsRequire', 'getSortOrder', 'load'], + [], + '', + false, + false + ); + + $this->factoryMock->expects($this->any())->method('create')->will($this->returnValue($this->optionMock)); + + $this->writeService = new \Magento\Catalog\Service\V1\Product\CustomOptions\WriteService( + $this->optionBuilderMock, + $this->optionConverterMock, + $this->repositoryMock, + $this->optionMetadataReaderMock, + $this->factoryMock + ); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + * @expectedExceptionMessage No such entity with optionId = 10 + */ + public function testRemoveFromProductWithoutOptions() + { + $this->optionMock->expects($this->once())->method('load')->with(10); + $this->productMock->expects($this->once())->method('getOptions')->will($this->returnValue(array())); + $this->productMock->expects($this->never())->method('getOptionById'); + $this->writeService->remove(self::PRODUCT_SKU, 10); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + * @expectedExceptionMessage No such entity with optionId = 10 + */ + public function testRemoveNotExistingOption() + { + $options[1] = [ + Data\Option::OPTION_ID => 10, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + ]; + $this->productMock->expects($this->once())->method('getOptions')->will($this->returnValue($options)); + $this->optionMock->expects($this->never())->method('delete'); + $this->writeService->remove(self::PRODUCT_SKU, 10); + } + + public function testSuccessRemove() + { + $this->optionMock->expects($this->once())->method('load')->with(10); + $this->optionMock->expects($this->any())->method('getId')->will($this->returnValue(10)); + + $this->productMock + ->expects($this->once()) + ->method('getOptions') + ->will($this->returnValue([10 => $this->optionMock])); + + $this->optionMock->expects($this->once())->method('delete'); + $this->productMock->expects($this->once())->method('setHasOptions')->with(false); + $this->productMock->expects($this->once())->method('save'); + + $this->assertTrue($this->writeService->remove(self::PRODUCT_SKU, 10)); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testCanNotRemove() + { + $this->optionMock->expects($this->once())->method('load')->with(10); + $this->optionMock->expects($this->any())->method('getId')->will($this->returnValue(10)); + + $this->productMock + ->expects($this->once()) + ->method('getOptions') + ->will($this->returnValue([10 => $this->optionMock])); + + $this->optionMock->expects($this->once())->method('delete'); + $this->productMock->expects($this->once())->method('setHasOptions')->with(false); + $this->productMock->expects($this->once())->method('save')->will($this->throwException(new \Exception())); + $this->writeService->remove(self::PRODUCT_SKU, 10); + } + + public function testRemoveMetadata() + { + $optionId = 231; + $optionDataMock = $this->getMock( + '\Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', + ['getValues'], + [], + '', + false + ); + + $optionData = [ + 'option_id' => $optionId, + 'values' => [ + ['option_type_id' => 1], + ['option_type_id' => 2], + ], + ]; + $updatedData = $optionData; + $updatedData['values'][] = ['option_type_id' => 939, 'is_delete' => 1]; + + $metaDataMock1 = $this->getMock('\Magento\Catalog\Model\Product\Option\Value', [], [], '', false); + $metaDataMock2 = $this->getMock('\Magento\Catalog\Model\Product\Option\Value', [], [], '', false); + $metaDataMock3 = $this->getMock('\Magento\Catalog\Model\Product\Option\Value', [], [], '', false); + $map1 = [ + ['option_type_id', null, 1], + ['', null, ['option_type_id' => 1]], + ]; + $map2 = [ + ['option_type_id', null, 2], + ['', null, ['option_type_id' => 2]], + ]; + $map3 = [ + ['option_type_id', null, 939], + ['', null, ['option_type_id' => 939, 'is_delete' => 1]], + ]; + + $originalValues = [$metaDataMock1, $metaDataMock2, $metaDataMock3]; + + + $this->optionConverterMock->expects($this->once()) + ->method('convert') + ->with($optionDataMock) + ->will($this->returnValue($optionData)); + $this->productMock->expects($this->exactly(2)) + ->method('getOptionById') + ->will($this->returnValue($optionDataMock)); + $optionDataMock->expects($this->once())->method('getValues')->will($this->returnValue($originalValues)); + + // preparation for markValuesForRemoval() + $metaDataMock1->expects($this->any())->method('getData')->will($this->returnValueMap($map1)); + $metaDataMock2->expects($this->any())->method('getData')->will($this->returnValueMap($map2)); + $metaDataMock3->expects($this->any())->method('getData')->will($this->returnValueMap($map3)); + $metaDataMock3->expects($this->once())->method('setData')->with('is_delete', 1); + + // update() + $this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true); + $this->productMock->expects($this->once())->method('setProductOptions')->with([$updatedData]); + $this->productMock->expects($this->once())->method('save'); + + $this->assertTrue($this->writeService->update(self::PRODUCT_SKU, $optionId, $optionDataMock)); + } + + public function testAdd() + { + $optionData = $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false); + $convertedOptions = [ + Data\Option::OPTION_ID => null, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 10 + ]; + $this->optionConverterMock + ->expects($this->once()) + ->method('convert') + ->with($optionData) + ->will($this->returnValue($convertedOptions)); + + $existingOptions = [1 => null, 2 => null]; + $currentOptions = [1 => null, 2 => null, 10 => $this->optionMock]; + + $this->productMock->expects($this->at(2)) + ->method('getOptions')->will($this->returnValue($existingOptions)); + $this->productMock->expects($this->at(7)) + ->method('getOptions')->will($this->returnValue($currentOptions)); + + $this->productMock->expects($this->once())->method('getId')->will($this->returnValue(1)); + $this->productMock->expects($this->once())->method('reset'); + $this->productMock->expects($this->once())->method('load')->with(1); + + $this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true); + $this->productMock->expects($this->once())->method('setProductOptions')->with([$convertedOptions]); + $this->productMock->expects($this->once())->method('save'); + + $this->optionMock->expects($this->once())->method('getId')->will($this->returnValue(10)); + $this->optionMock->expects($this->once())->method('getTitle')->will($this->returnValue('Some title')); + $this->optionMock->expects($this->once())->method('getType')->will($this->returnValue('text')); + $this->optionMock->expects($this->once())->method('getIsRequire')->will($this->returnValue(true)); + $this->optionMock->expects($this->once())->method('getSortOrder')->will($this->returnValue(10)); + + $this->optionMetadataReaderMock->expects($this->once())->method('read')->will($this->returnValue('some value')); + + $expectedData = [ + Data\Option::OPTION_ID => 10, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + 'metadata' => 'some value' + ]; + + $this->optionBuilderMock->expects($this->once()) + ->method('populateWithArray')->with($expectedData)->will($this->returnSelf()); + $this->optionBuilderMock->expects($this->once())->method('create')->will($this->returnValue($optionData)); + + $this->assertEquals($optionData, $this->writeService->add(self::PRODUCT_SKU, $optionData)); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testAddWithException() + { + $optionData = $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false); + $convertedOptions = [ + Data\Option::OPTION_ID => null, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 10 + ]; + $this->optionConverterMock + ->expects($this->once()) + ->method('convert') + ->with($optionData) + ->will($this->returnValue($convertedOptions)); + + $this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true); + $this->productMock->expects($this->once())->method('setProductOptions')->with([$convertedOptions]); + $this->productMock->expects($this->once())->method('save'); + + $existingOptions = [1 => null, 2 => null]; + $currentOptions = [1 => null, 2 => null]; + + $this->productMock->expects($this->at(2)) + ->method('getOptions')->will($this->returnValue($existingOptions)); + $this->productMock->expects($this->at(7)) + ->method('getOptions')->will($this->returnValue($currentOptions)); + + $this->productMock->expects($this->once())->method('getId')->will($this->returnValue(1)); + $this->productMock->expects($this->once())->method('reset'); + $this->productMock->expects($this->once())->method('load')->with(1); + $this->writeService->add(self::PRODUCT_SKU, $optionData); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testAddWithExceptionDuringSave() + { + $optionData = $this->getMock('Magento\Catalog\Service\V1\Product\CustomOptions\Data\Option', [], [], '', false); + $convertedOptions = [ + Data\Option::OPTION_ID => 10, + Data\Option::TITLE => 'Some title', + Data\Option::TYPE => 'text', + Data\Option::IS_REQUIRE => true, + Data\Option::SORT_ORDER => 10, + 'price_type' => 'fixed', + 'sku' => 'sku1', + 'max_characters' => 10 + ]; + $this->optionConverterMock + ->expects($this->once()) + ->method('convert') + ->with($optionData) + ->will($this->returnValue($convertedOptions)); + + $this->productMock->expects($this->once())->method('setCanSaveCustomOptions')->with(true); + $this->productMock->expects($this->once())->method('setProductOptions')->with([$convertedOptions]); + $this->productMock->expects($this->once())->method('save')->will($this->throwException(new \Exception())); + $this->writeService->add(self::PRODUCT_SKU, $optionData); + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/QtyincrementsTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/QtyincrementsTest.php index c84beb18cdae50f1cc749e27d446b55cc915fe4a..a54aca81fadf059e1f32edde5075855ca293e0ef 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/QtyincrementsTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/QtyincrementsTest.php @@ -39,7 +39,7 @@ class QtyincrementsTest extends \PHPUnit_Framework_TestCase protected $registryMock; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */ protected $stockItemService; @@ -47,7 +47,13 @@ class QtyincrementsTest extends \PHPUnit_Framework_TestCase { $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); $this->registryMock = $this->getMock('Magento\Framework\Registry', [], [], '', false); - $this->stockItemService = $this->getMock('Magento\CatalogInventory\Service\V1\StockItem', [], [], '', false); + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); $this->block = $objectManager->getObject( 'Magento\CatalogInventory\Block\Qtyincrements', diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/Stockqty/DefaultStockqtyTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/Stockqty/DefaultStockqtyTest.php index 2a54673367f52215e7fac8daccb7817a421938ad..64c482a5b10328f7d7362229509400d8f7c798c5 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/Stockqty/DefaultStockqtyTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Block/Stockqty/DefaultStockqtyTest.php @@ -39,7 +39,7 @@ class DefaultStockqtyTest extends \PHPUnit_Framework_TestCase protected $registryMock; /** - * @var \Magento\CatalogInventory\Service\V1\StockItem|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */ protected $stockItemService; @@ -47,7 +47,13 @@ class DefaultStockqtyTest extends \PHPUnit_Framework_TestCase { $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); $this->registryMock = $this->getMock('Magento\Framework\Registry', array(), array(), '', false); - $this->stockItemService = $this->getMock('Magento\CatalogInventory\Service\V1\StockItem', [], [], '', false); + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); $this->block = $objectManager->getObject( 'Magento\CatalogInventory\Block\Stockqty\DefaultStockqty', diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/DataTest.php new file mode 100644 index 0000000000000000000000000000000000000000..61568042a515225d1c06b934d05153564c1206e9 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/DataTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogInventory\Helper; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Class DataTest + */ +class DataTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\CatalogInventory\Helper\Data */ + protected $data; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\App\Helper\Context|\PHPUnit_Framework_MockObject_MockObject */ + protected $contextMock; + + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeConfigMock; + + protected function setUp() + { + $this->contextMock = $this->getMock('Magento\Framework\App\Helper\Context', [], [], '', false); + $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->data = $this->objectManagerHelper->getObject( + 'Magento\CatalogInventory\Helper\Data', + [ + 'context' => $this->contextMock, + 'scopeConfig' => $this->scopeConfigMock + ] + ); + } + + public function testGetConfigItemOptions() + { + $configOptions = [ + 'min_qty', + 'backorders', + 'min_sale_qty', + 'max_sale_qty', + 'notify_stock_qty', + 'manage_stock', + 'enable_qty_increments', + 'qty_increments', + 'is_decimal_divided' + ]; + $this->assertSame($configOptions, $this->data->getConfigItemOptions()); + } + + public function testIsShowOutOfStock() + { + $this->scopeConfigMock->expects($this->once()) + ->method('isSetFlag') + ->with( + $this->equalTo(Data::XML_PATH_SHOW_OUT_OF_STOCK), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) + ->will($this->returnValue(true)); + $this->assertTrue($this->data->isShowOutOfStock()); + } + + public function testIsAutoReturnEnabled() + { + $this->scopeConfigMock->expects($this->once()) + ->method('isSetFlag') + ->with( + $this->equalTo(Data::XML_PATH_ITEM_AUTO_RETURN), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) + ->will($this->returnValue(true)); + $this->assertTrue($this->data->isAutoReturnEnabled()); + } + + public function testIsDisplayProductStockStatus() + { + $this->scopeConfigMock->expects($this->once()) + ->method('isSetFlag') + ->with( + $this->equalTo(Data::XML_PATH_DISPLAY_PRODUCT_STOCK_STATUS), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) + ->will($this->returnValue(true)); + $this->assertTrue($this->data->isDisplayProductStockStatus()); + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/MinsaleqtyTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/MinsaleqtyTest.php new file mode 100644 index 0000000000000000000000000000000000000000..967e1ab70d196d77c49eb940613eaee45f3a128f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Helper/MinsaleqtyTest.php @@ -0,0 +1,164 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogInventory\Helper; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Class MinsaleqtyTest + */ +class MinsaleqtyTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\CatalogInventory\Helper\Minsaleqty */ + protected $minsaleqty; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeConfigMock; + + /** @var \Magento\Framework\Math\Random|\PHPUnit_Framework_MockObject_MockObject */ + protected $randomMock; + + protected function setUp() + { + $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $this->randomMock = $this->getMock('Magento\Framework\Math\Random'); + $this->randomMock->expects($this->any()) + ->method('getUniqueHash') + ->with($this->equalTo('_')) + ->will($this->returnValue('unique_hash')); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->minsaleqty = $this->objectManagerHelper->getObject( + 'Magento\CatalogInventory\Helper\Minsaleqty', + [ + 'scopeConfig' => $this->scopeConfigMock, + 'mathRandom' => $this->randomMock + ] + ); + } + + /** + * @param int $customerGroupId + * @param int|null $store + * @param float $minSaleQty + * @param float|null $result + * @dataProvider getConfigValueDataProvider + */ + public function testGetConfigValue($customerGroupId, $store, $minSaleQty, $result) + { + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with( + $this->equalTo(\Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MIN_SALE_QTY), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE), + $this->equalTo($store) + ) + ->will($this->returnValue($minSaleQty)); + $this->assertSame($result, $this->minsaleqty->getConfigValue($customerGroupId, $store)); + } + + /** + * @return array + */ + public function getConfigValueDataProvider() + { + return [ + [1, 2, '20', 20.], + [0, null, '', null], + [3, null, '', null], + [2, 1, 'a:2:{i:1;s:4:"20.5";i:2;s:4:"34.2";}', 34.2], + [1, 44, 'a:2:{i:1;s:4:"20.5";i:2;s:4:"34.2";}', 20.5], + [5, 4, 'a:1:{i:0;a:2:{s:17:"customer_group_id";i:5;s:12:"min_sale_qty";d:40.10000000000000;}}', 40.1], + [5, 4, 'a:1:{i:0;a:2:{s:17:"customer_group_id";i:32000;s:12:"min_sale_qty";d:2.5;}}', 2.5], + ]; + } + + /** + * @param string|array $value + * @param array $result + * @dataProvider makeArrayFieldValueDataProvider + */ + public function testMakeArrayFieldValue($value, $result) + { + $this->assertSame($result, $this->minsaleqty->makeArrayFieldValue($value)); + } + + /** + * @return array + */ + public function makeArrayFieldValueDataProvider() + { + return [ + ['', []], + ['20', ['unique_hash' => ['customer_group_id' => 32000, 'min_sale_qty' => 20.]]], + [ + 'a:1:{i:0;a:2:{s:17:"customer_group_id";i:32000;s:12:"min_sale_qty";d:2.5;}} ', + [['customer_group_id' => 32000, 'min_sale_qty' => 2.5]] + ], + ]; + } + + /** + * @param string|array $value + * @param string $result + * @dataProvider makeStorableArrayFieldValueDataProvider + */ + public function testMakeStorableArrayFieldValue($value, $result) + { + $this->assertSame($result, $this->minsaleqty->makeStorableArrayFieldValue($value)); + } + + /** + * @return array + */ + public function makeStorableArrayFieldValueDataProvider() + { + return [ + [false, ''], + ['', ''], + ['22', '22'], + [[], 'a:0:{}'], + [ + ['customer_group_id' => 32000, 'min_sale_qty' => 2.5], + 'a:2:{s:17:"customer_group_id";d:32000;s:12:"min_sale_qty";d:2.5;}' + ], + [ + [['customer_group_id' => 32000, 'min_sale_qty' => 2.5]], + '2.5' + ], + [ + [['customer_group_id' => 2, 'min_sale_qty' => 2.5]], + 'a:1:{i:2;d:2.5;}' + ], + [ + [['min_sale_qty' => 2.5]], + 'a:1:{i:0;d:1;}' + ], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..02cbeeaaa1b65e04f1d7c964a12371d333e74cfa --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php @@ -0,0 +1,197 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Model; + +/** + * Class ObserverTest + */ +class ObserverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Observer + */ + protected $model; + + /** + * @var \Magento\CatalogInventory\Model\Stock\ItemRegistry|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemRegistry; + + /** + * @var \Magento\CatalogInventory\Model\Stock\Status|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockStatus; + + /** + * @var \Magento\CatalogInventory\Model\StockFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockFactory; + + /** + * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventObserver; + + /** + * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject + */ + protected $event; + + protected function setUp() + { + $this->stockItemRegistry = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\ItemRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockStatus = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockFactory = $this->getMockBuilder('Magento\CatalogInventory\Model\StockFactory') + ->setMethods(['create']) + ->getMock(); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\CatalogInventory\Model\Observer', + [ + 'stockItemRegistry' => $this->stockItemRegistry, + 'stockStatus' => $this->stockStatus, + 'stockFactory' => $this->stockFactory + ] + ); + + $this->event = $this->getMockBuilder('Magento\Framework\Event') + ->disableOriginalConstructor() + ->setMethods(['getProduct', 'getCollection']) + ->getMock(); + + $this->eventObserver = $this->getMockBuilder('Magento\Framework\Event\Observer') + ->disableOriginalConstructor() + ->setMethods(['getEvent']) + ->getMock(); + $this->eventObserver->expects($this->atLeastOnce()) + ->method('getEvent') + ->will($this->returnValue($this->event)); + } + + public function testAddInventoryData() + { + $productId = 4; + $stockId = 6; + $stockStatus = true; + + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->setMethods(['getId', 'getStockStatus', '__wakeup']) + ->getMock(); + $product->expects($this->once()) + ->method('getId') + ->will($this->returnValue($productId)); + $product->expects($this->once()) + ->method('getStockStatus') + ->will($this->returnValue($stockStatus)); + + $this->event->expects($this->once()) + ->method('getProduct') + ->will($this->returnValue($product)); + + $stockItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') + ->disableOriginalConstructor() + ->getMock(); + $stockItem->expects($this->once()) + ->method('getStockId') + ->will($this->returnValue($stockId)); + + $this->stockItemRegistry->expects($this->once()) + ->method('retrieve') + ->with($productId) + ->will($this->returnValue($stockItem)); + + $this->stockStatus->expects($this->once()) + ->method('assignProduct') + ->with($product, $stockId, $stockStatus) + ->will($this->returnSelf()); + + $this->assertEquals($this->model, $this->model->addInventoryData($this->eventObserver)); + } + + public function testAddStockStatusToCollection() + { + $requireStockItems = false; + + $productCollection = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Collection') + ->disableOriginalConstructor() + ->setMethods(['hasFlag']) + ->getMock(); + $this->event->expects($this->once()) + ->method('getCollection') + ->will($this->returnValue($productCollection)); + + $productCollection->expects($this->once()) + ->method('hasFlag') + ->with('require_stock_items') + ->will($this->returnValue($requireStockItems)); + + $this->stockStatus->expects($this->once()) + ->method('addStockStatusToProducts') + ->with($productCollection) + ->will($this->returnSelf()); + + $this->assertEquals($this->model, $this->model->addStockStatusToCollection($this->eventObserver)); + } + + public function testAddStockStatusToCollectionRequireStockItems() + { + $requireStockItems = true; + + $productCollection = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Collection') + ->disableOriginalConstructor() + ->setMethods(['hasFlag']) + ->getMock(); + $this->event->expects($this->once()) + ->method('getCollection') + ->will($this->returnValue($productCollection)); + + $productCollection->expects($this->once()) + ->method('hasFlag') + ->with('require_stock_items') + ->will($this->returnValue($requireStockItems)); + + $stock = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockFactory->expects($this->once()) + ->method('create') + ->will($this->returnValue($stock)); + + $stock->expects($this->once()) + ->method('addItemsToProducts') + ->with($productCollection) + ->will($this->returnSelf()); + + $this->assertEquals($this->model, $this->model->addStockStatusToCollection($this->eventObserver)); + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventoryTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventoryTest.php index 92badefbf510ca562906b2714f134077e734e68a..89707d8beb7d3941cffb94e1dd755adb8fde1719 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventoryTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Product/CopyConstructor/CatalogInventoryTest.php @@ -28,50 +28,78 @@ class CatalogInventoryTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\CatalogInventory\Model\Product\CopyConstructor\CatalogInventory */ - protected $_model; + protected $model; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_productMock; + protected $productMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_duplicateMock; + protected $duplicateMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\CatalogInventory\Service\V1\Data\StockItem|\PHPUnit_Framework_MockObject_MockObject */ - protected $_stockItemMock; + protected $stockItemDoMock; + + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + protected $objectManager; + + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemServiceMock; protected function setUp() { - $this->_model = new \Magento\CatalogInventory\Model\Product\CopyConstructor\CatalogInventory(); - - $this->_productMock = $this->getMock( + $this->productMock = $this->getMock( '\Magento\Catalog\Model\Product', - array('__wakeup', 'getStockItem'), + array('__wakeup'), array(), '', false ); - $this->_duplicateMock = $this->getMock( + $this->duplicateMock = $this->getMock( '\Magento\Catalog\Model\Product', - array('setStockData', 'unsStockItem', '__wakeup'), + array('setStockData', '__wakeup'), array(), '', false ); - $this->_stockItemMock = $this->getMock( - 'Magento\CatalogInventory\Model\Stock\Item', - array(), - array(), + $this->stockItemDoMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\Data\StockItem', + [ + 'getStockId', + 'isUseConfigEnableQtyInc', + 'isEnableQtyIncrements', + 'isUseConfigQtyIncrements', + 'getQtyIncrements' + ], + [], + '', + false + ); + + $this->stockItemServiceMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + ['getStockItem'], + [], '', false ); + + $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $this->objectManager->getObject( + 'Magento\CatalogInventory\Model\Product\CopyConstructor\CatalogInventory', + ['stockItemService' => $this->stockItemServiceMock] + ); } public function testBuildWithoutCurrentProductStockItem() @@ -83,12 +111,14 @@ class CatalogInventoryTest extends \PHPUnit_Framework_TestCase 'use_config_backorders' => 1, 'use_config_notify_stock_qty' => 1 ); - $this->_duplicateMock->expects($this->once())->method('unsStockItem'); - $this->_productMock->expects($this->once())->method('getStockItem')->will($this->returnValue(null)); + $this->stockItemDoMock->expects($this->any())->method('getStockId')->will($this->returnValue(false)); - $this->_duplicateMock->expects($this->once())->method('setStockData')->with($expectedData); + $this->stockItemServiceMock->expects($this->once()) + ->method('getStockItem') + ->will($this->returnValue($this->stockItemDoMock)); - $this->_model->build($this->_productMock, $this->_duplicateMock); + $this->duplicateMock->expects($this->once())->method('setStockData')->with($expectedData); + $this->model->build($this->productMock, $this->duplicateMock); } public function testBuildWithCurrentProductStockItem() @@ -104,19 +134,26 @@ class CatalogInventoryTest extends \PHPUnit_Framework_TestCase 'use_config_qty_increments' => 'use_config_qty_increments', 'qty_increments' => 'qty_increments' ); - $this->_duplicateMock->expects($this->once())->method('unsStockItem'); - $this->_productMock->expects( - $this->once() - )->method( - 'getStockItem' - )->will( - $this->returnValue($this->_stockItemMock) - ); + $this->stockItemServiceMock->expects($this->once()) + ->method('getStockItem') + ->will($this->returnValue($this->stockItemDoMock)); - $this->_stockItemMock->expects($this->any())->method('getData')->will($this->returnArgument(0)); + $this->stockItemDoMock->expects($this->any())->method('getStockId')->will($this->returnValue(50)); - $this->_duplicateMock->expects($this->once())->method('setStockData')->with($expectedData); + $this->stockItemDoMock->expects($this->any()) + ->method('isUseConfigEnableQtyInc') + ->will($this->returnValue('use_config_enable_qty_inc')); + $this->stockItemDoMock->expects($this->any()) + ->method('isEnableQtyIncrements') + ->will($this->returnValue('enable_qty_increments')); + $this->stockItemDoMock->expects($this->any()) + ->method('isUseConfigQtyIncrements') + ->will($this->returnValue('use_config_qty_increments')); + $this->stockItemDoMock->expects($this->any()) + ->method('getQtyIncrements') + ->will($this->returnValue('qty_increments')); - $this->_model->build($this->_productMock, $this->_duplicateMock); + $this->duplicateMock->expects($this->once())->method('setStockData')->with($expectedData); + $this->model->build($this->productMock, $this->duplicateMock); } } diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php index e3cdd5ccd77a98415f3389cbcb09fcc597f27d0a..149a5d8aba7014923df53db33acbd019a4b71c06 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php @@ -60,6 +60,16 @@ class OptionTest extends \PHPUnit_Framework_TestCase */ protected $resultMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemRegistryMock; + + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + protected $objectManager; + protected function setUp() { $optionMethods = array( @@ -86,7 +96,8 @@ class OptionTest extends \PHPUnit_Framework_TestCase 'setSuppressCheckQtyIncrements', 'checkQuoteItemQty', '__wakeup', - 'unsIsChildItem' + 'unsIsChildItem', + 'getId', ); $this->stockItemMock = $this->getMock( 'Magento\CatalogInventory\Model\Stock\Item', @@ -95,7 +106,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase '', false ); - $productMethods = array('getStockItem', 'getId', '__wakeup'); + $productMethods = array('getId', '__wakeup'); $this->productMock = $this->getMock('Magento\Catalog\Model\Product', $productMethods, array(), '', false); $this->qtyItemListMock = $this->getMock( 'Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\QuoteItemQtyList', @@ -113,8 +124,22 @@ class OptionTest extends \PHPUnit_Framework_TestCase '__wakeup' ); $this->resultMock = $this->getMock('Magento\Framework\Object', $resultMethods, array(), '', false); - $this->validator = new \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option( - $this->qtyItemListMock + + $this->stockItemRegistryMock = $this->getMock( + 'Magento\CatalogInventory\Model\Stock\ItemRegistry', + ['retrieve', '__wakeup'], + [], + '', + false + ); + + $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->validator = $this->objectManager->getObject( + 'Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option', + [ + 'quoteItemQtyList' => $this->qtyItemListMock, + 'stockItemRegistry' => $this->stockItemRegistryMock, + ] ); } @@ -127,18 +152,18 @@ class OptionTest extends \PHPUnit_Framework_TestCase $this->optionMock->expects($this->once())->method('getValue')->will($this->returnValue($optionValue)); $this->quoteMock->expects($this->exactly(2))->method('getQtyToAdd')->will($this->returnValue($qtyToAdd)); $this->optionMock->expects($this->any())->method('getProduct')->will($this->returnValue($this->productMock)); - //stock item verification - $this->productMock->expects( - $this->once() - )->method( - 'getStockItem' - )->will( - $this->returnValue($this->stockItemMock) - ); + $this->stockItemMock->expects($this->once())->method('setIsChildItem')->with(true); $this->stockItemMock->expects($this->once())->method('setSuppressCheckQtyIncrements')->with(true); - $this->productMock->expects($this->once())->method('getId')->will($this->returnValue('product_id')); - $this->quoteMock->expects($this->once())->method('getId')->will($this->returnValue('quote_item_id')); + $this->stockItemMock->expects($this->once())->method('getId')->will($this->returnValue(true)); + + $this->stockItemRegistryMock + ->expects($this->once()) + ->method('retrieve') + ->will($this->returnValue($this->stockItemMock)); + + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + $this->quoteMock->expects($this->any())->method('getId')->will($this->returnValue('quote_item_id')); $this->quoteMock->expects($this->once())->method('getQuoteId')->will($this->returnValue('quote_id')); $this->qtyItemListMock->expects( $this->once() @@ -200,17 +225,18 @@ class OptionTest extends \PHPUnit_Framework_TestCase $this->optionMock->expects($this->once())->method('getValue')->will($this->returnValue($optionValue)); $this->quoteMock->expects($this->once())->method('getQtyToAdd')->will($this->returnValue(false)); $this->optionMock->expects($this->any())->method('getProduct')->will($this->returnValue($this->productMock)); - $this->productMock->expects( - $this->once() - )->method( - 'getStockItem' - )->will( - $this->returnValue($this->stockItemMock) - ); + $this->stockItemMock->expects($this->once())->method('setIsChildItem')->with(true); $this->stockItemMock->expects($this->once())->method('setSuppressCheckQtyIncrements')->with(true); - $this->productMock->expects($this->once())->method('getId')->will($this->returnValue('product_id')); - $this->quoteMock->expects($this->once())->method('getId')->will($this->returnValue('quote_item_id')); + $this->stockItemMock->expects($this->once())->method('getId')->will($this->returnValue(true)); + + $this->stockItemRegistryMock + ->expects($this->once()) + ->method('retrieve') + ->will($this->returnValue($this->stockItemMock)); + + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + $this->quoteMock->expects($this->any())->method('getId')->will($this->returnValue('quote_item_id')); $this->quoteMock->expects($this->once())->method('getQuoteId')->will($this->returnValue('quote_id')); $this->qtyItemListMock->expects( $this->once() @@ -257,8 +283,15 @@ class OptionTest extends \PHPUnit_Framework_TestCase $qty = 10; $this->optionMock->expects($this->once())->method('getValue')->will($this->returnValue($optionValue)); $this->quoteMock->expects($this->once())->method('getQtyToAdd')->will($this->returnValue(false)); - $this->optionMock->expects($this->once())->method('getProduct')->will($this->returnValue($this->productMock)); - $this->productMock->expects($this->once())->method('getStockItem')->will($this->returnValue(10)); + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue('product_id')); + $this->optionMock->expects($this->any())->method('getProduct')->will($this->returnValue($this->productMock)); + $this->stockItemMock->expects($this->once())->method('getId')->will($this->returnValue(false)); + + $this->stockItemRegistryMock + ->expects($this->once()) + ->method('retrieve') + ->will($this->returnValue($this->stockItemMock)); + $this->validator->initialize($this->optionMock, $this->quoteMock, $qty); } } diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Resource/Stock/Status/CollectionTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Resource/Stock/Status/CollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..176bb0cc7eb57dc29c7e32161999e75a106ed761 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Resource/Stock/Status/CollectionTest.php @@ -0,0 +1,103 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\CatalogInventory\Model\Resource\Stock\Status; + +/** + * Test for \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection + */ +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $resource; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $connection; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $select; + + /** + * @var \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection + */ + protected $model; + + protected function setUp() + { + $this->select = $this->getMock('Magento\Framework\DB\Select', [], [], '', false); + $this->connection = $this->getMock('Magento\Framework\DB\Adapter\Pdo\Mysql', [], [], '', false); + $this->connection->expects($this->atLeastOnce())->method('select')->will($this->returnValue($this->select)); + $this->connection->expects($this->atLeastOnce())->method('quoteIdentifier')->will($this->returnArgument(0)); + $this->resource = $this->getMock('Magento\CatalogInventory\Model\Resource\Stock\Status', [], [], '', false); + $this->resource->expects($this->any())->method('getReadConnection') + ->will($this->returnValue($this->connection)); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\CatalogInventory\Model\Resource\Stock\Status\Collection', + [ + 'resource' => $this->resource, + ] + ); + } + + /** + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::__construct + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::_construct + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::addWebsiteFilter + */ + public function testAddingWebsiteFilter() + { + $website = $this->getMock('Magento\Store\Model\Website', ['getWebsiteId', '__wakeup'], [], '', false); + $website->expects($this->atLeastOnce())->method('getWebsiteId')->will($this->returnValue(1)); + $this->connection->expects($this->atLeastOnce())->method('prepareSqlCondition')->with('website_id', 1) + ->will($this->returnValue('condition_string')); + $this->select->expects($this->atLeastOnce())->method('where') + ->with('condition_string', $this->anything(), $this->anything()); + $this->model->addWebsiteFilter($website); + } + + /** + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::__construct + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::_construct + * @covers \Magento\CatalogInventory\Model\Resource\Stock\Status\Collection::addQtyFilter + */ + public function testAddingQtyFilter() + { + $qty = 3; + $this->connection->expects($this->atLeastOnce()) + ->method('prepareSqlCondition') + ->with('main_table.qty', ['lteq' => $qty]) + ->will($this->returnValue('condition_string')); + $this->select->expects($this->atLeastOnce())->method('where') + ->with('condition_string', $this->anything(), $this->anything()); + $this->model->addQtyFilter($qty); + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php index 1a209a447ce78f7f5258127a64c30ce763dca375..7f60919b7a2eb57821a8420822fc3ffd70ecf14e 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php @@ -65,6 +65,9 @@ class ItemTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $storeManager; + /** @var \Magento\CatalogInventory\Model\Stock\ItemRegistry|\PHPUnit_Framework_MockObject_MockObject */ + protected $stockItemRegistry; + protected function setUp() { $this->resource = $this->getMock( @@ -109,6 +112,14 @@ class ItemTest extends \PHPUnit_Framework_TestCase $this->scopeConfig = $this->getMock('Magento\Framework\App\Config', [], [], '', false); $this->storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface', [], [], '', false); + $this->stockItemRegistry = $this->getMock( + '\Magento\CatalogInventory\Model\Stock\ItemRegistry', + ['retrieve', '__wakeup'], + [], + '', + false + ); + $this->objectManagerHelper = new ObjectManagerHelper($this); $this->item = $this->objectManagerHelper->getObject( 'Magento\CatalogInventory\Model\Stock\Item', @@ -119,7 +130,8 @@ class ItemTest extends \PHPUnit_Framework_TestCase 'scopeConfig' => $this->scopeConfig, 'storeManager' => $this->storeManager, 'productFactory' => $productFactory, - 'resource' => $this->resource + 'resource' => $this->resource, + 'stockItemRegistry' => $this->stockItemRegistry ] ); } @@ -194,8 +206,8 @@ class ItemTest extends \PHPUnit_Framework_TestCase protected function prepareNotCompositeProductMock() { $productGroup = [ - [$this->getGroupProductMock(), $this->getGroupProductMock(), $this->getGroupProductMock()], - [$this->getGroupProductMock(), $this->getGroupProductMock()], + [$this->getGroupProductMock(0), $this->getGroupProductMock(1), $this->getGroupProductMock(2)], + [$this->getGroupProductMock(3), $this->getGroupProductMock(4)], ]; $typeInstance = $this->getMock( @@ -216,26 +228,26 @@ class ItemTest extends \PHPUnit_Framework_TestCase } /** + * @param int $at * @return \PHPUnit_Framework_MockObject_MockObject */ - protected function getGroupProductMock() + protected function getGroupProductMock($at) { $product = $this->getMock( 'Magento\Catalog\Model\Product', - ['hasStockItem', 'getStockItem', 'getStockQty', '__wakeup'], + ['getStockQty', '__wakeup'], [], '', false ); - $product->expects($this->once()) - ->method('hasStockItem') - ->will($this->returnValue(true)); - $product->expects($this->once()) - ->method('getStockItem') - ->will($this->returnSelf()); $product->expects($this->once()) ->method('getStockQty') ->will($this->returnValue(2)); + + $this->stockItemRegistry->expects($this->at($at)) + ->method('retrieve') + ->will($this->returnValue($product)); + return $product; } diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/StockTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/StockTest.php new file mode 100644 index 0000000000000000000000000000000000000000..20b00923a81644a10c70fb61a765ea9a7a12829f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/StockTest.php @@ -0,0 +1,205 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\CatalogInventory\Model; + +use Magento\CatalogInventory\Model\Resource\Stock\Item\CollectionFactory; + +/** + * Class StockTest + */ +class StockTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Stock + */ + protected $model; + + /** + * @var \Magento\CatalogInventory\Model\Stock\Status|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockStatus; + + /** + * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $collectionFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemService; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productFactory; + + protected function setUp() + { + $this->collectionFactory = $this + ->getMockBuilder('Magento\CatalogInventory\Model\Resource\Stock\Item\CollectionFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->stockStatus = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockItemService = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\StockItemService') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockItemFactory = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\ItemFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->productFactory = $this->getMockBuilder('Magento\Catalog\Model\ProductFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\CatalogInventory\Model\Stock', + [ + 'stockStatus' => $this->stockStatus, + 'collectionFactory' => $this->collectionFactory, + 'stockItemService' => $this->stockItemService, + 'stockItemFactory' => $this->stockItemFactory, + 'productFactory' => $this->productFactory + ] + ); + } + + public function testAddItemsToProducts() + { + $storeId = 3; + $productOneId = 1; + $productOneStatus = \Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK; + $productTwoId = 2; + $productThreeId = 3; + + $stockItemProductId = $productOneId; + $stockItemStockId = \Magento\CatalogInventory\Model\Stock::DEFAULT_STOCK_ID; + + $productCollection = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Collection') + ->disableOriginalConstructor() + ->setMethods(['getStoreId', 'getIterator']) + ->getMock(); + + $stockItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') + ->disableOriginalConstructor() + ->getMock(); + $stockItem->expects($this->atLeastOnce()) + ->method('getProductId') + ->will($this->returnValue($stockItemProductId)); + $stockItem->expects($this->atLeastOnce()) + ->method('getStockId') + ->will($this->returnValue($stockItemStockId)); + + $itemCollection = $this->getMockBuilder('Magento\CatalogInventory\Model\Resource\Stock\Item\Collection') + ->disableOriginalConstructor() + ->getMock(); + $itemCollection->expects($this->atLeastOnce()) + ->method('addStockFilter') + ->with(Stock::DEFAULT_STOCK_ID) + ->will($this->returnSelf()); + $itemCollection->expects($this->atLeastOnce()) + ->method('addProductsFilter') + ->with($productCollection) + ->will($this->returnSelf()); + $itemCollection->expects($this->atLeastOnce()) + ->method('joinStockStatus') + ->with($storeId) + ->will($this->returnSelf()); + $itemCollection->expects($this->atLeastOnce()) + ->method('load') + ->will($this->returnValue([$stockItem])); + + $this->collectionFactory->expects($this->atLeastOnce()) + ->method('create') + ->will($this->returnValue($itemCollection)); + + + $productOne = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->setMethods(['getId', 'getStockStatus', '__wakeup']) + ->getMock(); + $productOne->expects($this->atLeastOnce()) + ->method('getId') + ->will($this->returnValue($productOneId)); + $productOne->expects($this->atLeastOnce()) + ->method('getStockStatus') + ->will($this->returnValue($productOneStatus)); + $productTwo = $this->getMockBuilder('Magento\Catalog\Model\Product')->disableOriginalConstructor()->getMock(); + $productTwo->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($productTwoId)); + $productThree = $this->getMockBuilder('Magento\Catalog\Model\Product')->disableOriginalConstructor()->getMock(); + $productThree->expects($this->atLeastOnce())->method('getId')->will($this->returnValue($productThreeId)); + + $productCollection->expects($this->atLeastOnce())->method('getStoreId')->will($this->returnValue($storeId)); + $productCollection->expects($this->any()) + ->method('getIterator') + ->will($this->returnValue(new \ArrayIterator([$productOne, $productTwo, $productThree]))); + + + $this->stockStatus->expects($this->once()) + ->method('assignProduct') + ->with($productOne, $stockItemStockId, $productOneStatus); + + $this->assertEquals($this->model, $this->model->addItemsToProducts($productCollection)); + } + + /** + * @covers \Magento\CatalogInventory\Model\Stock::getProductType + */ + public function testGettingProductType() + { + $productId = 1; + $qty = 1; + $productType = 'simple'; + + $stockItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') + ->disableOriginalConstructor() + ->getMock(); + $stockItem->expects($this->atLeastOnce())->method('loadByProduct')->with($productId)->will($this->returnSelf()); + $stockItem->expects($this->any())->method('getId')->will($this->returnValue(1)); + + $this->stockItemFactory->expects($this->atLeastOnce())->method('create')->will($this->returnValue($stockItem)); + + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $product->expects($this->atLeastOnce())->method('load')->with($productId); + $product->expects($this->atLeastOnce())->method('getTypeId')->will($this->returnValue($productType)); + $this->productFactory->expects($this->atLeastOnce())->method('create')->will($this->returnValue($product)); + + $this->stockItemService->expects($this->once())->method('isQty')->with($productType); + $this->model->backItemQty($productId, $qty); + } +} diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemServiceTest.php similarity index 51% rename from dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemTest.php rename to dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemServiceTest.php index 4e50dc52e000860cc00cd9554ee2cabdd90a8872..61357b0d5156126d3918b582a4247e493225f62e 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockItemServiceTest.php @@ -29,10 +29,10 @@ use Magento\Catalog\Model\ProductTypes\ConfigInterface; /** * Class StockItemTest */ -class StockItemTest extends \PHPUnit_Framework_TestCase +class StockItemServiceTest extends \PHPUnit_Framework_TestCase { /** - * @var StockItem + * @var StockItemService */ protected $model; @@ -51,6 +51,11 @@ class StockItemTest extends \PHPUnit_Framework_TestCase */ protected $stockItemBuilder; + /** + * @var \Magento\Catalog\Service\V1\Product\ProductLoader|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productLoader; + protected function setUp() { $this->stockItemRegistry = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\ItemRegistry') @@ -61,11 +66,24 @@ class StockItemTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->stockItemBuilder = $this->getMockBuilder( - 'Magento\CatalogInventory\Service\V1\Data\StockItemBuilder' - )->disableOriginalConstructor()->getMock(); + $this->stockItemBuilder = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItemBuilder') + ->disableOriginalConstructor() + ->getMock(); - $this->model = new StockItem($this->stockItemRegistry, $this->config, $this->stockItemBuilder); + $this->productLoader = $this->getMockBuilder('Magento\Catalog\Service\V1\Product\ProductLoader') + ->disableOriginalConstructor() + ->getMock(); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [ + 'stockItemRegistry' => $this->stockItemRegistry, + 'config' => $this->config, + 'stockItemBuilder' => $this->stockItemBuilder, + 'productLoader' => $this->productLoader + ] + ); } public function testGetStockItem() @@ -108,7 +126,7 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $stockItemDo = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItem') ->disableOriginalConstructor() ->getMock(); - $stockItemDo->expects($this->once()) + $stockItemDo->expects($this->any()) ->method('getProductId') ->will($this->returnValue($productId)); $stockItemDo->expects($this->once()) @@ -129,59 +147,12 @@ class StockItemTest extends \PHPUnit_Framework_TestCase ->with($productId) ->will($this->returnValue($stockItemModel)); - $this->assertEquals($this->model, $this->model->saveStockItem($stockItemDo)); - } - - public function testSubtractQty() - { - $productId = 123; - $qty = 1.5; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('subtractQty') - ->with($qty); - - $this->assertEquals($this->model, $this->model->subtractQty($productId, $qty)); - } - - public function testCanSubtractQty() - { - $productId = 23; - $result = false; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('canSubtractQty') - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->canSubtractQty($productId)); - } - - public function testAddQty() - { - $productId = 143; - $qty = 3.5; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('addQty') - ->with($qty); - - $this->assertEquals($this->model, $this->model->addQty($productId, $qty)); - } - - public function testGetMinQty() - { - $productId = 53; - $result = 3; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('getMinQty') - ->will($this->returnValue($result)); + $this->stockItemRegistry->expects($this->once()) + ->method('erase') + ->with($productId) + ->will($this->returnValue($stockItemModel)); - $this->assertEquals($result, $this->model->getMinQty($productId)); + $this->assertEquals($this->model, $this->model->saveStockItem($stockItemDo)); } public function testGetMinSaleQty() @@ -210,19 +181,6 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $this->assertEquals($result, $this->model->getMaxSaleQty($productId)); } - public function testGetNotifyStockQty() - { - $productId = 12; - $result = 15.3; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('getNotifyStockQty') - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->getNotifyStockQty($productId)); - } - public function testEnableQtyIncrements() { $productId = 48; @@ -249,19 +207,6 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $this->assertEquals($result, $this->model->getQtyIncrements($productId)); } - public function testGetBackorders() - { - $productId = 34; - $result = 2; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('getBackorders') - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->getBackorders($productId)); - } - public function testGetManageStock() { $productId = 32; @@ -275,34 +220,6 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $this->assertEquals($result, $this->model->getManageStock($productId)); } - public function testGetCanBackInStock() - { - $productId = 59; - $result = false; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('getCanBackInStock') - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->getCanBackInStock($productId)); - } - - public function testCheckQty() - { - $productId = 143; - $qty = 3.5; - $result = false; - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('checkQty') - ->with($qty) - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->checkQty($productId, $qty)); - } - public function testSuggestQty() { $productId = 143; @@ -391,21 +308,6 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $this->assertEquals($result, $this->model->getStockQty($productId)); } - public function testCheckQtyIncrements() - { - $productId = 86; - $qty = 6; - $result = $this->getMock('Magento\Framework\Object'); - - $stockItemModel = $this->getStockItemModel($productId); - $stockItemModel->expects($this->once()) - ->method('checkQtyIncrements') - ->with($qty) - ->will($this->returnValue($result)); - - $this->assertEquals($result, $this->model->checkQtyIncrements($productId, $qty)); - } - public function testIsQty() { $configAll = [ @@ -443,6 +345,243 @@ class StockItemTest extends \PHPUnit_Framework_TestCase $this->assertEquals($resultFalse, $this->model->getIsQtyTypeIds(false)); } + /** + * @param string $productSku + * @param int $productId + * @param [] $stockItemData + * @dataProvider getStockItemBySkuDataProvider + */ + public function testGetStockItemBySku($productSku, $productId, $stockItemData) + { + // 1. Get mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + /** @var \Magento\CatalogInventory\Model\Stock\Item|\PHPUnit_Framework_MockObject_MockObject $stockItem */ + $stockItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') + ->disableOriginalConstructor() + ->getMock(); + + /** @var Data\StockItem|\PHPUnit_Framework_MockObject_MockObject $stockItemDataObject */ + $stockItemDataObject = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItem') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $stockItem->expects($this->any())->method('getData')->will($this->returnValue($stockItemData)); + + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + + $this->stockItemRegistry->expects($this->any())->method('retrieve')->will($this->returnValueMap([ + [$productId, $stockItem] + ])); + + $this->stockItemBuilder->expects($this->any()) + ->method('create') + ->will($this->returnValue($stockItemDataObject)); + + // 3. Set expectations + $this->stockItemBuilder->expects($this->any())->method('populateWithArray')->with($stockItemData); + + // 4. Run tested method + $result = $this->model->getStockItemBySku($productSku); + + // 5. Compare actual result with expected result + $this->assertEquals($stockItemDataObject, $result); + } + + /** + * @return array + */ + public function getStockItemBySkuDataProvider() + { + return [ + ['sku1', 1, ['stock_item_id' => 123]], + ['sku1', 1, []], + ]; + } + + /** + * @param string $productSku + * @param int $productId + * @dataProvider getStockItemBySkuWithExceptionDataProvider + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testGetStockItemBySkuWithException($productSku, $productId) + { + // 1. Get mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + + // 3. Run tested method + $this->model->getStockItemBySku($productSku); + } + + /** + * @return array + */ + public function getStockItemBySkuWithExceptionDataProvider() + { + return [ + ['sku1', null], + ['sku1', false], + ['sku1', 0], + ]; + } + + /** + * @param string $productSku + * @param int $productId + * @param array $stockItemData + * @param array $stockItemDetailsDoData + * @param array $dataToSave + * @param int $savedStockItemId + * @dataProvider saveStockItemBySkuDataProvider + */ + public function testSaveStockItemBySku( + $productSku, + $productId, + $stockItemData, + $stockItemDetailsDoData, + $dataToSave, + $savedStockItemId + ) { + // 1. Create mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + /** @var \Magento\CatalogInventory\Model\Stock\Item|\PHPUnit_Framework_MockObject_MockObject $stockItem */ + $stockItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') + ->disableOriginalConstructor() + ->getMock(); + + /** @var Data\StockItem|\PHPUnit_Framework_MockObject_MockObject $stockItemDataObject */ + $stockItemDataObject = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItem') + ->disableOriginalConstructor() + ->getMock(); + + /** @var Data\StockItem|\PHPUnit_Framework_MockObject_MockObject $stockItemDataObjectMerged */ + $stockItemDataObjectMerged = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItem') + ->disableOriginalConstructor() + ->getMock(); + + /** @var Data\StockItemDetails|\PHPUnit_Framework_MockObject_MockObject $stockItemDetailsDo */ + $stockItemDetailsDo = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItemDetails') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + + $stockItem->expects($this->any())->method('getData')->will($this->returnValue($stockItemData)); + $stockItem->expects($this->any())->method('save')->will($this->returnSelf()); + $stockItem->expects($this->any())->method('getId')->will($this->returnValue($savedStockItemId)); + + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + + $this->stockItemRegistry->expects($this->any())->method('retrieve')->will($this->returnValueMap([ + [$productId, $stockItem] + ])); + + $this->stockItemBuilder->expects($this->any()) + ->method('create') + ->will($this->returnValue($stockItemDataObject)); + + $stockItemDetailsDo->expects($this->any()) + ->method('__toArray') + ->will($this->returnValue($stockItemDetailsDoData)); + + $this->stockItemBuilder->expects($this->any()) + ->method('mergeDataObjectWithArray') + ->will($this->returnValue($stockItemDataObjectMerged)); + + $stockItemDataObjectMerged->expects($this->any()) + ->method('__toArray') + ->will($this->returnValue($dataToSave)); + + // 3. Set expectations + $stockItem->expects($this->any())->method('setData')->with($dataToSave)->will($this->returnSelf()); + $this->stockItemBuilder->expects($this->any()) + ->method('populateWithArray') + ->with($stockItemData) + ->will($this->returnSelf()); + + // 4. Run tested method + $result = $this->model->saveStockItemBySku($productSku, $stockItemDetailsDo); + + // 5. Compare actual result with expected result + $this->assertEquals($savedStockItemId, $result); + } + + /** + * @return array + */ + public function saveStockItemBySkuDataProvider() + { + return [ + ['sku1', 1, ['key1' => 'value1'], ['key2' => 'value2'], ['key3' => 'value3'], 123], + ['sku1', 1, [], [], [], 123], + ]; + } + + /** + * @param string $productSku + * @param int $productId + * @dataProvider saveStockItemBySkuWithExceptionDataProvider + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testSaveStockItemBySkuWithException($productSku, $productId) + { + // 1. Get mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + /** @var Data\StockItemDetails|\PHPUnit_Framework_MockObject_MockObject $stockItemDetailsDo */ + $stockItemDetailsDo = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockItemDetails') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + + // 3. Run tested method + $this->model->saveStockItemBySku($productSku, $stockItemDetailsDo); + } + + /** + * @return array + */ + public function saveStockItemBySkuWithExceptionDataProvider() + { + return [ + ['sku1', null], + ['sku1', false], + ['sku1', 0], + ]; + } + /** * @param int $productId * @return \PHPUnit_Framework_MockObject_MockObject diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockStatusServiceTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockStatusServiceTest.php index 456c4e007ab7f714f37816ae2f601495f84d3871..99144a4220814b426e08898157ca334c2b8a671a 100644 --- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockStatusServiceTest.php +++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Service/V1/StockStatusServiceTest.php @@ -23,48 +23,337 @@ */ namespace Magento\CatalogInventory\Service\V1; -use Magento\CatalogInventory\Model\Stock\Status; - /** * Test for Magento\CatalogInventory\Service\V1\StockStatusService */ class StockStatusServiceTest extends \PHPUnit_Framework_TestCase { /** - * @param int[] $productIds + * @var StockStatusService + */ + protected $model; + + /** + * @var \Magento\CatalogInventory\Model\Stock\Status|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockStatus; + + /** + * @var \Magento\Catalog\Service\V1\Product\ProductLoader|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productLoader; + + /** + * @var \Magento\Store\Model\Resolver\Website|\PHPUnit_Framework_MockObject_MockObject + */ + protected $scopeResolver; + + /** + * @var Data\StockStatusBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockStatusBuilder; + + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemService; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $lowStockResultBuilder; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $itemsFactory; + + protected function setUp() + { + $this->stockStatus = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status') + ->disableOriginalConstructor() + ->getMock(); + + $this->productLoader = $this->getMockBuilder('Magento\Catalog\Service\V1\Product\ProductLoader') + ->disableOriginalConstructor() + ->getMock(); + + $this->scopeResolver = $this->getMockBuilder('Magento\Store\Model\Resolver\Website') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockStatusBuilder = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockStatusBuilder') + ->disableOriginalConstructor() + ->getMock(); + + $this->stockItemService = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\StockItemService') + ->disableOriginalConstructor() + ->getMock(); + + $this->lowStockResultBuilder = $this->getMock( + 'Magento\CatalogInventory\Service\V1\Data\LowStockResultBuilder', + [], + [], + '', + false + ); + $this->itemsFactory = $this->getMock( + 'Magento\CatalogInventory\Model\Resource\Stock\Status\CollectionFactory', + ['create'], + [], + '', + false + ); + + $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\CatalogInventory\Service\V1\StockStatusService', + [ + 'stockStatus' => $this->stockStatus, + 'productLoader' => $this->productLoader, + 'scopeResolver' => $this->scopeResolver, + 'stockStatusBuilder' => $this->stockStatusBuilder, + 'stockItemService' => $this->stockItemService, + 'itemsFactory' => $this->itemsFactory, + 'lowStockResultBuilder' => $this->lowStockResultBuilder + ] + ); + } + + /** + * @param int $productId * @param int $websiteId * @param int $stockId - * @param [] $expectedResult + * @param mixed $expectedResult * @dataProvider getProductStockStatusDataProvider */ - public function testGetProductStockStatus($productIds, $websiteId, $stockId, $expectedResult) + public function testGetProductStockStatus($productId, $websiteId, $stockId, $expectedResult) + { + $this->stockStatus->expects($this->once()) + ->method('getProductStockStatus') + ->with([$productId], $websiteId, $stockId) + ->will($this->returnValue([$productId => 'expected_result'])); + + $result = $this->model->getProductStockStatus($productId, $websiteId, $stockId); + + $this->assertEquals($expectedResult, $result); + } + + /** + * @return array + */ + public function getProductStockStatusDataProvider() + { + $productId = 1; + return [ + [$productId, 3, 4, 'expected_result'], + ]; + } + + public function testAssignProduct() { - // 1 Create mocks - $stockStatus = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status') + $product = $this->getMockBuilder('Magento\Catalog\Model\Product')->disableOriginalConstructor()->getMock(); + $stockId = 1; + $stockStatus = false; + + $this->stockStatus->expects($this->once()) + ->method('assignProduct') + ->with($product, $stockId, $stockStatus) + ->will($this->returnSelf()); + + $this->assertEquals($this->model, $this->model->assignProduct($product, $stockId, $stockStatus)); + } + + /** + * @param string $productSku + * @param int $productId + * @param int $websiteId + * @param array $productStockStatusArray + * @param int $stockQty + * @param array $array + * @dataProvider getProductStockStatusBySkuDataProvider + */ + public function testGetProductStockStatusBySku( + $productSku, + $productId, + $websiteId, + $productStockStatusArray, + $stockQty, + $array + ) { + // 1. Create mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') ->disableOriginalConstructor() ->getMock(); - $model = new StockStatusService($stockStatus); - // 2. Set expectations - $stockStatus->expects($this->once()) + /** @var \Magento\Framework\App\ScopeInterface|\PHPUnit_Framework_MockObject_MockObject $scope */ + $scope = $this->getMockBuilder('Magento\Framework\App\ScopeInterface') + ->disableOriginalConstructor() + ->getMock(); + + /** + * @var \Magento\CatalogInventory\Service\V1\Data\StockStatus|\PHPUnit_Framework_MockObject_MockObject $scope + */ + $stockStatusDataObject = $this->getMockBuilder('Magento\CatalogInventory\Service\V1\Data\StockStatus') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $this->scopeResolver->expects($this->any())->method('getScope')->will($this->returnValue($scope)); + $scope->expects($this->any())->method('getId')->will($this->returnValue($websiteId)); + $this->stockStatusBuilder->expects($this->any()) + ->method('create') + ->will($this->returnValue($stockStatusDataObject)); + + // 3. Set expectations + $this->stockStatus->expects($this->any()) ->method('getProductStockStatus') - ->with($productIds, $websiteId, $stockId) - ->will($this->returnValue($expectedResult)); + ->with([$productId], $websiteId) + ->will($this->returnValue($productStockStatusArray)); - // 3. Run tested method - $result = $model->getProductStockStatus($productIds, $websiteId, $stockId); + $this->stockItemService->expects($this->any()) + ->method('getStockQty') + ->will($this->returnValueMap([[$productId, $stockQty]])); + + $this->stockStatusBuilder->expects($this->any())->method('populateWithArray')->with($array); + + // 4. Run tested method + $result = $this->model->getProductStockStatusBySku($productSku); // 5. Compare actual result with expected result - $this->assertEquals($expectedResult, $result); + $this->assertEquals($stockStatusDataObject, $result); } /** * @return array */ - public function getProductStockStatusDataProvider() + public function getProductStockStatusBySkuDataProvider() + { + $productId = 123; + + $productStatusInStock = true; + $fullStockQty = 456; + + $productStatusOutOfStock = false; + $emptyStockQty = 0; + return [ + [ + 'sku1', + $productId, + 1, + [$productId => $productStatusInStock], + $fullStockQty, + [ + Data\StockStatus::STOCK_STATUS => $productStatusInStock, + Data\StockStatus::STOCK_QTY => $fullStockQty + ] + ], + [ + 'sku1', + $productId, + 1, + [$productId => $productStatusOutOfStock], + $emptyStockQty, + [ + Data\StockStatus::STOCK_STATUS => $productStatusOutOfStock, + Data\StockStatus::STOCK_QTY => $emptyStockQty + ] + ], + ]; + } + + /** + * @param string $productSku + * @param int $productId + * @dataProvider getProductStockWithExceptionStatusBySkuDataProvider + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + */ + public function testGetProductStockWithExceptionStatusBySku($productSku, $productId) + { + // 1. Create mocks + /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */ + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->getMock(); + + // 2. Set fixtures + $this->productLoader->expects($this->any())->method('load')->will($this->returnValueMap([ + [$productSku, $product] + ])); + $product->expects($this->any())->method('getId')->will($this->returnValue($productId)); + + // 3. Run tested method + $this->model->getProductStockStatusBySku($productSku); + } + + /** + * @return array + */ + public function getProductStockWithExceptionStatusBySkuDataProvider() { return [ - [[1,2], 3, 4, []], + ['sku1', null], + ['sku1', false], + ['sku1', 0], + ]; + } + + /** + * @covers \Magento\CatalogInventory\Service\V1\StockStatusService::getLowStockItems + */ + public function testGetterOfLowStockItems() + { + $websiteId = 1; + $criteriaData = [ + 'qty' => 1, + 'current_page' => 1, + 'page_size' => 10 ]; + $scope = $this->getMockBuilder('Magento\Store\Model\Website') + ->disableOriginalConstructor() + ->getMock(); + $scope->expects($this->any())->method('getId')->will($this->returnValue($websiteId)); + $this->scopeResolver->expects($this->any())->method('getScope')->will($this->returnValue($scope)); + + $builder = $this->getMockBuilder('Magento\Framework\Service\Data\AbstractObjectBuilder') + ->disableOriginalConstructor() + ->getMock(); + $builder->expects($this->any())->method('getData')->will($this->returnValue($criteriaData)); + + $statusItem = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status') + ->setMethods(['__wakeup', 'getSku']) + ->disableOriginalConstructor() + ->getMock(); + $statusItem->expects($this->any())->method('getSku')->will($this->returnValue('test_sku')); + + $collection = $this->getMockBuilder('Magento\CatalogInventory\Model\Resource\Stock\Status\Collection') + ->disableOriginalConstructor() + ->getMock(); + $collection->expects($this->any())->method('getSize')->will($this->returnValue(1)); + $collection->expects($this->any())->method('getIterator') + ->will($this->returnValue(new \ArrayIterator([$statusItem]))); + $this->itemsFactory->expects($this->once())->method('create')->will($this->returnValue($collection)); + + /** @var \Magento\Framework\Service\Data\AbstractObjectBuilder $builder */ + $lowStockCriteria = new Data\LowStockCriteria($builder); + + // Expected results + $collection->expects($this->atLeastOnce())->method('addWebsiteFilter')->with($scope); + $collection->expects($this->atLeastOnce())->method('addQtyFilter')->with($criteriaData['qty']); + $collection->expects($this->atLeastOnce())->method('setCurPage')->with($criteriaData['current_page']); + $collection->expects($this->atLeastOnce())->method('setPageSize')->with($criteriaData['page_size']); + + $this->lowStockResultBuilder->expects($this->atLeastOnce())->method('setSearchCriteria') + ->with($lowStockCriteria); + $this->lowStockResultBuilder->expects($this->atLeastOnce())->method('setTotalCount')->with(1); + $this->lowStockResultBuilder->expects($this->atLeastOnce())->method('setItems')->with(['test_sku']); + + // Run tested method + $this->model->getLowStockItems($lowStockCriteria); } } diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php index aa7e63f09d08f0cae9f8ed365f04387daa308301..e1c795c886e23f329e2d82c49d1a3f2d2391f63e 100644 --- a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php +++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php @@ -40,13 +40,19 @@ class CartTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ protected $checkoutSessionMock; - /** @var \Magento\CatalogInventory\Service\V1\StockItem|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */ protected $stockItemMock; protected function setUp() { $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false); - $this->stockItemMock = $this->getMock('Magento\CatalogInventory\Service\V1\StockItem', [], [], '', false); + $this->stockItemMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->cart = $this->objectManagerHelper->getObject( diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php index f32303c1d8f11c939bb6cbd26963654b21c48231..3170cf72a6edc4014a84c3091a9e6bcc3ed8aba2 100644 --- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php @@ -104,7 +104,7 @@ class SuggestConfigurableAttributesTest extends \PHPUnit_Framework_TestCase )->will( $this->returnValue('body') ); - $this->responseMock->expects($this->once())->method('setBody')->with('body'); + $this->responseMock->expects($this->once())->method('representJson')->with('body'); $this->suggestAttributes->indexAction(); } } diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php index c137b2a823bf592ec946f90854dcc73856fb29c8..012af56733eb23a8f4b565469552c1f2a83bc6be 100644 --- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php +++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php @@ -27,9 +27,9 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase { /** * @param array $data - * @dataProvider beforeInitializeDataProvider + * @dataProvider aroundGetStockItemDataProvider */ - public function testBeforeInitialize(array $data) + public function testAroundGetStockItem(array $data) { $subjectMock = $this->getMock( 'Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option', @@ -53,29 +53,22 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase $stockItemMock->expects($this->$matcherMethod()) ->method('setProductName'); - $productMock = $this->getMock( - 'Magento\Catalog\Model\Product', array('getStockItem', '__wakeup'), array(), '', false - ); - $productMock->expects($this->once()) - ->method('getStockItem') - ->will($this->returnValue($stockItemMock)); - $optionMock = $this->getMock( 'Magento\Sales\Model\Quote\Item\Option', array('getProduct', '__wakeup'), array(), '', false ); - $optionMock->expects($this->once()) - ->method('getProduct') - ->will($this->returnValue($productMock)); - $model = new ConfigurableProduct; - $model->beforeInitialize($subjectMock, $optionMock, $quoteItemMock, 0); + $proceed = function () use ($stockItemMock) { + return $stockItemMock; + }; + $model = new ConfigurableProduct; + $model->aroundGetStockItem($subjectMock, $proceed, $optionMock, $quoteItemMock, 0); } /** * @return array */ - public function beforeInitializeDataProvider() + public function aroundGetStockItemDataProvider() { return array( array( diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/Data/FileContentValidatorTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/Data/FileContentValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9ca32b1c4b1519ccc2e31343478ab019476d2537 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/Data/FileContentValidatorTest.php @@ -0,0 +1,117 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\Data; + +class FileContentValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var FileContentValidator + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $fileContentMock; + + protected function setUp() + { + $this->validator = new FileContentValidator(); + $this->fileContentMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContent', + array(), + array(), + '', + false + ); + } + + public function testIsValid() + { + $this->fileContentMock->expects($this->any())->method('getData')->will($this->returnValue( + base64_encode('test content') + )); + $this->fileContentMock->expects($this->any())->method('getName')->will($this->returnValue( + 'valid_name' + )); + + $this->assertTrue($this->validator->isValid($this->fileContentMock)); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Provided content must be valid base64 encoded data. + */ + public function testIsValidThrowsExceptionIfProvidedContentIsNotBase64Encoded() + { + $this->fileContentMock->expects($this->any())->method('getData')->will($this->returnValue( + 'not_a_base64_encoded_content' + )); + $this->fileContentMock->expects($this->any())->method('getName')->will($this->returnValue( + 'valid_name' + )); + $this->assertTrue($this->validator->isValid($this->fileContentMock)); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Provided file name contains forbidden characters. + * @dataProvider getInvalidNames + * @param string $fileName + */ + public function testIsValidThrowsExceptionIfProvidedImageNameContainsForbiddenCharacters($fileName) + { + $this->fileContentMock->expects($this->any())->method('getData')->will($this->returnValue( + base64_encode('test content') + )); + $this->fileContentMock->expects($this->any())->method('getName')->will($this->returnValue( + $fileName + )); + $this->assertTrue($this->validator->isValid($this->fileContentMock)); + } + + /** + * @return array + */ + public function getInvalidNames() + { + return array( + array('test\test'), + array('test/test'), + array('test:test'), + array('test"test'), + array('test*test'), + array('test;test'), + array('test?test'), + array('test{test'), + array('test}test'), + array('test|test'), + array('test(test'), + array('test)test'), + array('test<test'), + array('test>test'), + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidatorTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..db4f20fbd72b6f3dc6e944590d6d71559d28698a --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/Data/DownloadableLinkContentValidatorTest.php @@ -0,0 +1,261 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink\Data; + +class DownloadableLinkContentValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var DownloadableLinkContentValidator + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $fileValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $urlValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $linkFileMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $sampleFileMock; + + protected function setUp() + { + $this->fileValidatorMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContentValidator', + array(), + array(), + '', + false + ); + $this->urlValidatorMock = $this->getMock( + '\Magento\Framework\Url\Validator', + array(), + array(), + '', + false + ); + $this->linkFileMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContent', + array(), + array(), + '', + false + ); + $this->sampleFileMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContent', + array(), + array(), + '', + false + ); + $this->validator = new DownloadableLinkContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + } + + public function testIsValid() + { + $linkContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'price' => 10.1, + 'shareable' => true, + 'number_of_downloads' => 100, + 'link_type' => 'file', + 'sample_type' => 'file', + ); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $contentMock = $this->getLinkContentMock($linkContentData); + $this->assertTrue($this->validator->isValid($contentMock)); + } + + /** + * @param string|int|float $sortOrder + * @dataProvider getInvalidSortOrder + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Sort order must be a positive integer. + */ + public function testIsValidThrowsExceptionIfSortOrderIsInvalid($sortOrder) + { + $linkContentData = array( + 'title' => 'Title', + 'sort_order' => $sortOrder, + 'price' => 10.1, + 'shareable' => true, + 'number_of_downloads' => 100, + 'link_type' => 'file', + 'sample_type' => 'file', + ); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $contentMock = $this->getLinkContentMock($linkContentData); + $this->validator->isValid($contentMock); + } + + /** + * @return array + */ + public function getInvalidSortOrder() + { + return array( + array(-1), + array('string'), + array(1.1), + ); + } + + /** + * @param string|int|float $price + * @dataProvider getInvalidPrice + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Link price must have numeric positive value. + */ + public function testIsValidThrowsExceptionIfPriceIsInvalid($price) + { + $linkContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'price' => $price, + 'shareable' => true, + 'number_of_downloads' => 100, + 'link_type' => 'file', + 'sample_type' => 'file', + ); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $contentMock = $this->getLinkContentMock($linkContentData); + $this->validator->isValid($contentMock); + } + + /** + * @return array + */ + public function getInvalidPrice() + { + return array( + array(-1), + array('string'), + ); + } + + /** + * @param string|int|float $numberOfDownloads + * @dataProvider getInvalidNumberOfDownloads + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Number of downloads must be a positive integer. + */ + public function testIsValidThrowsExceptionIfNumberOfDownloadsIsInvalid($numberOfDownloads) + { + $linkContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'price' => 10.5, + 'shareable' => true, + 'number_of_downloads' => $numberOfDownloads, + 'link_type' => 'file', + 'sample_type' => 'file', + ); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $contentMock = $this->getLinkContentMock($linkContentData); + $this->validator->isValid($contentMock); + } + + /** + * @return array + */ + public function getInvalidNumberOfDownloads() + { + return array( + array(-1), + array(2.71828), + array('string'), + ); + } + + /** + * @param array $linkContentData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getLinkContentMock(array $linkContentData) + { + $contentMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent', + array(), + array(), + '', + false + ); + $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( + $linkContentData['title'] + )); + $contentMock->expects($this->any())->method('getPrice')->will($this->returnValue( + $linkContentData['price'] + )); + $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( + $linkContentData['sort_order'] + )); + $contentMock->expects($this->any())->method('isShareable')->will($this->returnValue( + $linkContentData['shareable'] + )); + $contentMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue( + $linkContentData['number_of_downloads'] + )); + $contentMock->expects($this->any())->method('getLinkType')->will($this->returnValue( + $linkContentData['link_type'] + )); + $contentMock->expects($this->any())->method('getLinkFile')->will($this->returnValue( + $this->linkFileMock + )); + if (isset($linkContentData['link_url'])) { + $contentMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue( + $linkContentData['link_url'] + )); + } + if (isset($linkContentData['sample_url'])) { + $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( + $linkContentData['sample_url'] + )); + } + if (isset($linkContentData['sample_type'])) { + $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue( + $linkContentData['sample_type'] + )); + } + $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( + $this->sampleFileMock + )); + return $contentMock; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..97020571853d64b16977ca47f649c9b12cf7a0fb --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php @@ -0,0 +1,302 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +use Magento\TestFramework\Helper\ObjectManager; + +class ReadServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + protected $objectHelper; + + /** + * @var \Magento\Downloadable\Service\V1\DownloadableLink\ReadService + */ + protected $service; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $repositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productTypeMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + protected function setUp() + { + $this->objectHelper = new ObjectManager($this); + + $this->repositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', [], [], '', false); + $this->productTypeMock = $this->getMock('\Magento\Downloadable\Model\Product\Type', [], [], '', false); + + $linkBuilder = $this->objectHelper->getObject( + 'Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkInfoBuilder' + ); + + $sampleBuilder = $this->objectHelper->getObject( + 'Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableSampleInfoBuilder' + ); + + $resourceBuilder = $this->objectHelper->getObject( + '\Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableResourceInfoBuilder' + ); + $this->service = $this->objectHelper->getObject( + '\Magento\Downloadable\Service\V1\DownloadableLink\ReadService', + [ + 'productRepository' => $this->repositoryMock, + 'downloadableType' => $this->productTypeMock, + 'linkBuilder' => $linkBuilder, + 'sampleBuilder' => $sampleBuilder, + 'resourceBuilder' => $resourceBuilder, + ] + ); + + $this->productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false); + } + + /** + * @dataProvider getLinksProvider + */ + public function testGetLinks($inputData, $inputFileData, $expectationData) + { + $productSku = 'downloadable_sku'; + + $this->repositoryMock->expects($this->once()) + ->method('get') + ->with($productSku) + ->will($this->returnValue($this->productMock)); + + $linkMock = $this->getMock( + '\Magento\Downloadable\Model\Link', + [ + 'getId', 'getStoreTitle', 'getTitle', 'getPrice', 'getNumberOfDownloads', + 'getSortOrder', 'getIsShareable', 'getData', '__wakeup' + ], + [], + '', + false + ); + + $this->productTypeMock->expects($this->once()) + ->method('getLinks') + ->with($this->productMock) + ->will($this->returnValue([$linkMock])); + + $this->setLinkAssertions($linkMock, $inputData, $inputFileData); + + $links = $this->service->getLinks($productSku); + $this->assertEquals(1, count($links)); + $this->assertEquals($expectationData, reset($links)->__toArray()); + } + + /** + * @dataProvider getSamplesProvider + */ + public function testGetSamples($inputData, $inputFileData, $expectationData) + { + $productSku = 'downloadable_sku'; + + $this->repositoryMock->expects($this->once()) + ->method('get') + ->with($productSku) + ->will($this->returnValue($this->productMock)); + + $sampleMock = $this->getMock( + '\Magento\Downloadable\Model\Sample', + [ + 'getId', 'getStoreTitle', 'getTitle', + 'getSortOrder', 'getData', '__wakeup' + ], + [], + '', + false + ); + + $this->productTypeMock->expects($this->once()) + ->method('getSamples') + ->with($this->productMock) + ->will($this->returnValue([$sampleMock])); + + $this->setSampleAssertions($sampleMock, $inputData, $inputFileData); + + $samples = $this->service->getSamples($productSku); + $this->assertEquals(1, count($samples)); + $this->assertEquals($expectationData, reset($samples)->__toArray()); + } + + protected function setLinkAssertions($resource, $inputData, $fileData) + { + $resource->expects($this->once())->method('getId')->will($this->returnValue($inputData['id'])); + $resource->expects($this->once())->method('getStoreTitle') + ->will($this->returnValue($inputData['store_title'])); + $resource->expects($this->once())->method('getTitle') + ->will($this->returnValue($inputData['title'])); + $resource->expects($this->any())->method('getPrice') + ->will($this->returnValue($inputData['price'])); + $resource->expects($this->once())->method('getNumberOfDownloads') + ->will($this->returnValue($inputData['number_of_downloads'])); + $resource->expects($this->once())->method('getSortOrder') + ->will($this->returnValue($inputData['sort_order'])); + $resource->expects($this->once())->method('getIsShareable') + ->will($this->returnValue($inputData['is_shareable'])); + $resource->expects($this->any())->method('getData')->will($this->returnValueMap($fileData)); + + } + + protected function setSampleAssertions($resource, $inputData, $fileData) + { + $resource->expects($this->once())->method('getId')->will($this->returnValue($inputData['id'])); + $resource->expects($this->once())->method('getStoreTitle') + ->will($this->returnValue($inputData['store_title'])); + $resource->expects($this->once())->method('getTitle') + ->will($this->returnValue($inputData['title'])); + $resource->expects($this->once())->method('getSortOrder') + ->will($this->returnValue($inputData['sort_order'])); + $resource->expects($this->any())->method('getData')->will($this->returnValueMap($fileData)); + + } + + public function getLinksProvider() + { + $linkData = [ + 'id' => 324, + 'store_title' => 'rock melody', + 'title' => 'just melody', + 'price' => 23, + 'number_of_downloads' => 3, + 'sort_order' => 21, + 'is_shareable' => 2, + ]; + + $linkDataGlobalTitle = $linkData; + $linkDataGlobalTitle['store_title'] = null; + $linkDataGlobalTitle['title'] = 'global title'; + + $linkFileData = [ + ['link_type', null, 'url'], + ['link_url', null, 'http://link.url'], + ['link_file', null, ''], + ['sample_type', null, 'file'], + ['sample_url', null, ''], + ['sample_file', null, '/r/o/rock.melody.ogg'], + ]; + + $linkUrl = [ + 'type' => 'url', + 'url' => 'http://link.url', + 'file' => '', + ]; + + $sampleFile = [ + 'type' => 'file', + 'url' => '', + 'file' => '/r/o/rock.melody.ogg', + ]; + + $linkExpectation = [ + 'id' => $linkData['id'], + 'title' => $linkData['store_title'], + 'price' => $linkData['price'], + 'number_of_downloads' => $linkData['number_of_downloads'], + 'sort_order' => $linkData['sort_order'], + 'shareable' => $linkData['is_shareable'], + 'link_resource' => $linkUrl, + 'sample_resource' => $sampleFile, + ]; + + $linkExpectationGlobalTitle = $linkExpectation; + $linkExpectationGlobalTitle['title'] = 'global title'; + + return [ + 'linksWithStoreTitle' => [ + $linkData, + $linkFileData, + $linkExpectation + ], + 'linksWithGlobalTitle' => [ + $linkDataGlobalTitle, + $linkFileData, + $linkExpectationGlobalTitle + ], + ]; + } + + public function getSamplesProvider() + { + $sampleData = [ + 'id' => 324, + 'store_title' => 'rock melody sample', + 'title' => 'just melody sample', + 'sort_order' => 21, + ]; + + $sampleDataGlobalTitle = $sampleData; + $sampleDataGlobalTitle['store_title'] = null; + $sampleDataGlobalTitle['title'] = 'sample global title'; + + $sampleFileData = [ + ['sample_type', null, 'file'], + ['sample_url', null, ''], + ['sample_file', null, '/r/o/rock.melody.ogg'], + ]; + + $sampleFile = [ + 'type' => 'file', + 'url' => '', + 'file' => '/r/o/rock.melody.ogg', + ]; + + $sampleExpectation = [ + 'id' => $sampleData['id'], + 'title' => $sampleData['store_title'], + 'sort_order' => $sampleData['sort_order'], + 'sample_resource' => $sampleFile, + ]; + + $linkExpectationGlobalTitle = $sampleExpectation; + $linkExpectationGlobalTitle['title'] = 'sample global title'; + + return [ + 'samplesWithStoreTitle' => [ + $sampleData, + $sampleFileData, + $sampleExpectation + ], + 'samplesWithGlobalTitle' => [ + $sampleDataGlobalTitle, + $sampleFileData, + $linkExpectationGlobalTitle + ], + ]; + } +} \ No newline at end of file diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0cd7cb1ac1d52e937e43ff483bc09c16cb0539da --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php @@ -0,0 +1,347 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableLink; + +class WriteServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $repositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $contentValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $contentUploaderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $jsonEncoderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $linkFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + /** + * @var WriteService + */ + protected $service; + + protected function setUp() + { + $this->repositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', array(), array(), '', false); + $this->contentValidatorMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContentValidator', + array(), + array(), + '', + false + ); + $this->contentUploaderMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContentUploaderInterface' + ); + $this->jsonEncoderMock = $this->getMock( + '\Magento\Framework\Json\EncoderInterface' + ); + $this->linkFactoryMock = $this->getMock( + '\Magento\Downloadable\Model\LinkFactory', + array('create'), + array(), + '', + false + ); + $this->productMock = $this->getMock( + '\Magento\Catalog\Model\Product', + array('__wakeup', 'getTypeId', 'setDownloadableData', 'save', 'getId', 'getStoreId', 'getStore', + 'getWebsiteIds'), + array(), + '', + false + ); + $this->service = new WriteService( + $this->repositoryMock, + $this->contentValidatorMock, + $this->contentUploaderMock, + $this->jsonEncoderMock, + $this->linkFactoryMock + ); + } + + /** + * @param array $linkContentData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getLinkContentMock(array $linkContentData) + { + $contentMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableLink\Data\DownloadableLinkContent', + array(), + array(), + '', + false + ); + + $contentMock->expects($this->any())->method('getPrice')->will($this->returnValue( + $linkContentData['price'] + )); + $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( + $linkContentData['title'] + )); + $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( + $linkContentData['sort_order'] + )); + $contentMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue( + $linkContentData['number_of_downloads'] + )); + $contentMock->expects($this->any())->method('isShareable')->will($this->returnValue( + $linkContentData['shareable'] + )); + if (isset($linkContentData['link_type'])) { + $contentMock->expects($this->any())->method('getLinkType')->will($this->returnValue( + $linkContentData['link_type'] + )); + } + if (isset($linkContentData['link_url'])) { + $contentMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue( + $linkContentData['link_url'] + )); + } + return $contentMock; + } + + public function testCreate() + { + $productSku = 'simple'; + $linkContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'price' => 10.1, + 'shareable' => true, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://example.com/' + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable')); + $linkContentMock = $this->getLinkContentMock($linkContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock) + ->will($this->returnValue(true)); + + $this->productMock->expects($this->once())->method('setDownloadableData')->with(array( + 'link' => array( + array( + 'link_id' => 0, + 'is_delete' => 0, + 'type' => $linkContentData['link_type'], + 'sort_order' => $linkContentData['sort_order'], + 'title' => $linkContentData['title'], + 'price' => $linkContentData['price'], + 'number_of_downloads' => $linkContentData['number_of_downloads'], + 'is_shareable' => $linkContentData['shareable'], + 'link_url' => $linkContentData['link_url'], + ), + ), + )); + $this->productMock->expects($this->once())->method('save'); + $this->service->create($productSku, $linkContentMock); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Link title cannot be empty. + */ + public function testCreateThrowsExceptionIfTitleIsEmpty() + { + $productSku = 'simple'; + $linkContentData = array( + 'title' => '', + 'sort_order' => 1, + 'price' => 10.1, + 'number_of_downloads' => 100, + 'shareable' => true, + 'link_type' => 'url', + 'link_url' => 'http://example.com/' + ); + + $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable')); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $linkContentMock = $this->getLinkContentMock($linkContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock) + ->will($this->returnValue(true)); + + $this->productMock->expects($this->never())->method('save'); + + $this->service->create($productSku, $linkContentMock); + + } + + public function testUpdate() + { + $websiteId = 1; + $linkId = 1; + $productSku = 'simple'; + $productId = 1; + $linkContentData = array( + 'title' => 'Updated Title', + 'sort_order' => 1, + 'price' => 10.1, + 'shareable' => true, + 'number_of_downloads' => 100, + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $storeMock = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false); + $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId)); + $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); + $linkMock = $this->getMock( + '\Magento\Downloadable\Model\Link', + array('__wakeup', 'setTitle', 'setPrice', 'setSortOrder', 'setIsShareable', 'setNumberOfDownloads', 'getId', + 'setProductId', 'setStoreId', 'setWebsiteId', 'setProductWebsiteIds', 'load', 'save', 'getProductId'), + array(), + '', + false + ); + $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock)); + $linkContentMock = $this->getLinkContentMock($linkContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock) + ->will($this->returnValue(true)); + + $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId)); + $linkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId)); + $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setTitle')->with($linkContentData['title']) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setSortOrder')->with($linkContentData['sort_order']) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setPrice')->with($linkContentData['price']) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setIsShareable')->with($linkContentData['shareable']) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setNumberOfDownloads')->with($linkContentData['number_of_downloads']) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setProductId')->with($productId) + ->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setStoreId')->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setWebsiteId')->with($websiteId)->will($this->returnSelf()); + $linkMock->expects($this->once())->method('setProductWebsiteIds')->will($this->returnSelf()); + $linkMock->expects($this->once())->method('save')->will($this->returnSelf()); + + $this->assertTrue($this->service->update($productSku, $linkId, $linkContentMock)); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Link title cannot be empty. + */ + public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() + { + $linkId = 1; + $productSku = 'simple'; + $productId = 1; + $linkContentData = array( + 'title' => '', + 'sort_order' => 1, + 'price' => 10.1, + 'number_of_downloads' => 100, + 'shareable' => true, + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $linkMock = $this->getMock( + '\Magento\Downloadable\Model\Link', + array('__wakeup', 'getId', 'load', 'save', 'getProductId'), + array(), + '', + false + ); + $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId)); + $linkMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId)); + $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf()); + $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock)); + $linkContentMock = $this->getLinkContentMock($linkContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkContentMock) + ->will($this->returnValue(true)); + + $linkMock->expects($this->never())->method('save'); + + $this->service->update($productSku, $linkId, $linkContentMock, true); + } + + public function testDelete() + { + $linkId = 1; + $linkMock = $this->getMock( + '\Magento\Downloadable\Model\Link', + array(), + array(), + '', + false + ); + $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock)); + $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf()); + $linkMock->expects($this->any())->method('getId')->will($this->returnValue($linkId)); + $linkMock->expects($this->once())->method('delete'); + + $this->assertTrue($this->service->delete($linkId)); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + * @expectedExceptionMessage There is no downloadable link with provided ID. + */ + public function testDeleteThrowsExceptionIfLinkIdIsNotValid() + { + $linkId = 1; + $linkMock = $this->getMock( + '\Magento\Downloadable\Model\Link', + array(), + array(), + '', + false + ); + $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($linkMock)); + $linkMock->expects($this->once())->method('load')->with($linkId)->will($this->returnSelf()); + $linkMock->expects($this->once())->method('getId'); + $linkMock->expects($this->never())->method('delete'); + + $this->service->delete($linkId); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidatorTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..76fab606d9726de9e0f9b638558b12d059f5cfcd --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/Data/DownloadableSampleContentValidatorTest.php @@ -0,0 +1,155 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample\Data; + +class DownloadableSampleContentValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var DownloadableSampleContentValidator + */ + protected $validator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $fileValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $urlValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $linkFileMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $sampleFileMock; + + protected function setUp() + { + $this->fileValidatorMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContentValidator', + array(), + array(), + '', + false + ); + $this->urlValidatorMock = $this->getMock( + '\Magento\Framework\Url\Validator', + array(), + array(), + '', + false + ); + $this->sampleFileMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContent', + array(), + array(), + '', + false + ); + $this->validator = new DownloadableSampleContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + } + + public function testIsValid() + { + $sampleContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'sample_type' => 'file', + ); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $contentMock = $this->getSampleContentMock($sampleContentData); + $this->assertTrue($this->validator->isValid($contentMock)); + } + + /** + * @param string|int|float $sortOrder + * @dataProvider getInvalidSortOrder + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Sort order must be a positive integer. + */ + public function testIsValidThrowsExceptionIfSortOrderIsInvalid($sortOrder) + { + $sampleContentData = array( + 'title' => 'Title', + 'sort_order' => $sortOrder, + 'sample_type' => 'file', + ); + $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->validator->isValid($this->getSampleContentMock($sampleContentData)); + } + + /** + * @return array + */ + public function getInvalidSortOrder() + { + return array( + array(-1), + array(1.1), + array('string'), + ); + } + + /** + * @param array $sampleContentData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getSampleContentMock(array $sampleContentData) + { + $contentMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent', + array(), + array(), + '', + false + ); + $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( + $sampleContentData['title'] + )); + + $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( + $sampleContentData['sort_order'] + )); + $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue( + $sampleContentData['sample_type'] + )); + if (isset($sampleContentData['sample_url'])) { + $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( + $sampleContentData['sample_url'] + )); + } + $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( + $this->sampleFileMock + )); + return $contentMock; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..17c4a9b4f7a2627133e266e86d7eb70c160b3d7d --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php @@ -0,0 +1,313 @@ +<?php +/** + * + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license {license_sample} + */ +namespace Magento\Downloadable\Service\V1\DownloadableSample; + +class WriteServiceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $repositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $contentValidatorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $contentUploaderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $jsonEncoderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $sampleFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + /** + * @var WriteService + */ + protected $service; + + protected function setUp() + { + $this->productMock = $this->getMock( + '\Magento\Catalog\Model\Product', + array('__wakeup', 'getTypeId', 'setDownloadableData', 'save', 'getId', 'getStoreId'), + array(), + '', + false + ); + $this->repositoryMock = $this->getMock('\Magento\Catalog\Model\ProductRepository', array(), array(), '', false); + $this->contentValidatorMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContentValidator', + array(), + array(), + '', + false + ); + $this->contentUploaderMock = $this->getMock( + '\Magento\Downloadable\Service\V1\Data\FileContentUploaderInterface' + ); + $this->jsonEncoderMock = $this->getMock( + '\Magento\Framework\Json\EncoderInterface' + ); + $this->sampleFactoryMock = $this->getMock( + '\Magento\Downloadable\Model\SampleFactory', + array('create'), + array(), + '', + false + ); + + $this->service = new WriteService( + $this->repositoryMock, + $this->contentValidatorMock, + $this->contentUploaderMock, + $this->jsonEncoderMock, + $this->sampleFactoryMock + ); + } + + /** + * @param array $sampleContentData + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getSampleContentMock(array $sampleContentData) + { + $contentMock = $this->getMock( + '\Magento\Downloadable\Service\V1\DownloadableSample\Data\DownloadableSampleContent', + array(), + array(), + '', + false + ); + + + $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( + $sampleContentData['title'] + )); + $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( + $sampleContentData['sort_order'] + )); + + if (isset($sampleContentData['sample_type'])) { + $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue( + $sampleContentData['sample_type'] + )); + } + if (isset($sampleContentData['sample_url'])) { + $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( + $sampleContentData['sample_url'] + )); + } + return $contentMock; + } + + public function testCreate() + { + $productSku = 'simple'; + $sampleContentData = array( + 'title' => 'Title', + 'sort_order' => 1, + 'sample_type' => 'url', + 'sample_url' => 'http://example.com/' + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable')); + $sampleContentMock = $this->getSampleContentMock($sampleContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock) + ->will($this->returnValue(true)); + + $this->productMock->expects($this->once())->method('setDownloadableData')->with(array( + 'sample' => array( + array( + 'sample_id' => 0, + 'is_delete' => 0, + 'type' => $sampleContentData['sample_type'], + 'sort_order' => $sampleContentData['sort_order'], + 'title' => $sampleContentData['title'], + 'sample_url' => $sampleContentData['sample_url'], + ), + ), + )); + $this->productMock->expects($this->once())->method('save'); + $this->service->create($productSku, $sampleContentMock); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Sample title cannot be empty. + */ + public function testCreateThrowsExceptionIfTitleIsEmpty() + { + $productSku = 'simple'; + $sampleContentData = array( + 'title' => '', + 'sort_order' => 1, + 'sample_type' => 'url', + 'sample_url' => 'http://example.com/' + ); + + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getTypeId')->will($this->returnValue('downloadable')); + $sampleContentMock = $this->getSampleContentMock($sampleContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock) + ->will($this->returnValue(true)); + + $this->productMock->expects($this->never())->method('save'); + + $this->service->create($productSku, $sampleContentMock); + + } + + public function testUpdate() + { + $sampleId = 1; + $productId = 1; + $productSku = 'simple'; + $sampleContentData = array( + 'title' => 'Updated Title', + 'sort_order' => 1, + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $sampleMock = $this->getMock( + '\Magento\Downloadable\Model\Sample', + array('__wakeup', 'setTitle', 'setSortOrder', 'getId', 'setProductId', 'setStoreId', + 'load', 'save', 'getProductId'), + array(), + '', + false + ); + $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock)); + $sampleContentMock = $this->getSampleContentMock($sampleContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock) + ->will($this->returnValue(true)); + + $sampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId)); + $sampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId)); + $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('setTitle')->with($sampleContentData['title']) + ->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('setSortOrder')->with($sampleContentData['sort_order']) + ->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('setProductId')->with($productId) + ->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('setStoreId')->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('save')->will($this->returnSelf()); + + $this->assertTrue($this->service->update($productSku, $sampleId, $sampleContentMock)); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage Sample title cannot be empty. + */ + public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() + { + $sampleId = 1; + $productSku = 'simple'; + $productId = 1; + $sampleContentData = array( + 'title' => '', + 'sort_order' => 1, + ); + $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) + ->will($this->returnValue($this->productMock)); + $this->productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); + $sampleMock = $this->getMock( + '\Magento\Downloadable\Model\Sample', + array('__wakeup', 'getId', 'load', 'save', 'getProductId'), + array(), + '', + false + ); + $sampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId)); + $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf()); + $sampleMock->expects($this->any())->method('getProductId')->will($this->returnValue($productId)); + $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock)); + $sampleContentMock = $this->getSampleContentMock($sampleContentData); + $this->contentValidatorMock->expects($this->any())->method('isValid')->with($sampleContentMock) + ->will($this->returnValue(true)); + + $sampleMock->expects($this->never())->method('save'); + + $this->service->update($productSku, $sampleId, $sampleContentMock, true); + } + + public function testDelete() + { + $sampleId = 1; + $sampleMock = $this->getMock( + '\Magento\Downloadable\Model\Sample', + array(), + array(), + '', + false + ); + $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock)); + $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf()); + $sampleMock->expects($this->any())->method('getId')->will($this->returnValue($sampleId)); + $sampleMock->expects($this->once())->method('delete'); + + $this->assertTrue($this->service->delete($sampleId)); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + * @expectedExceptionMessage There is no downloadable sample with provided ID. + */ + public function testDeleteThrowsExceptionIfSampleIdIsNotValid() + { + $sampleId = 1; + $sampleMock = $this->getMock( + '\Magento\Downloadable\Model\Sample', + array(), + array(), + '', + false + ); + $this->sampleFactoryMock->expects($this->once())->method('create')->will($this->returnValue($sampleMock)); + $sampleMock->expects($this->once())->method('load')->with($sampleId)->will($this->returnSelf()); + $sampleMock->expects($this->once())->method('getId'); + $sampleMock->expects($this->never())->method('delete'); + + $this->service->delete($sampleId); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Response/HttpTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Response/HttpTest.php index 5ca1d4a12865a0b4116275c4beff4d998ac071cf..b258cb23cc46c9f0aad7cde9b6bab8c28430108e 100644 --- a/dev/tests/unit/testsuite/Magento/Framework/App/Response/HttpTest.php +++ b/dev/tests/unit/testsuite/Magento/Framework/App/Response/HttpTest.php @@ -159,4 +159,15 @@ class HttpTest extends \PHPUnit_Framework_TestCase $this->assertEquals($cacheControl, $this->_model->getHeader('Cache-Control')['value']); $this->assertEquals($expires, $this->_model->getHeader('Expires')['value']); } + + /** + * Test setting body in JSON format + */ + public function testRepresentJson() + { + $this->_model->setHeader('Content-Type', 'text/javascript'); + $this->_model->representJson('json_string'); + $this->assertEquals('application/json', $this->_model->getHeader('Content-Type')['value']); + $this->assertEquals('json_string', $this->_model->getBody('default')); + } } diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ff0cf157981757382116ac3413856972f7323a12 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/ContentTest.php @@ -0,0 +1,135 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\GoogleShopping\Model\Attribute; + +class ContentTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider convertAttributeDataProvider + * @param int|null $attributeId + * @param string $description + * @param string $mapValue + */ + public function testConvertAttribute($attributeId, $description, $mapValue) + { + $product = $this->getMock( + '\Magento\Catalog\Model\Product', + array('getDescription', '__wakeup'), + array(), + '', + false + ); + $product->expects($this->any())->method('getDescription')->will($this->returnValue($description)); + + $defaultFrontend = $this->getMock( + 'Magento\Eav\Model\Entity\Attribute\Frontend\DefaultFrontend', + array('getValue'), + array(), + '', + false + ); + $defaultFrontend->expects($this->any()) + ->method('getValue') + ->with($product) + ->will($this->returnValue($mapValue)); + + $attribute = $this->getMock( + '\Magento\Catalog\Model\Entity\Attribute', + array('getFrontend', '__wakeup'), + array(), + '', + false + ); + $attribute->expects($this->any())->method('getFrontend')->will($this->returnValue($defaultFrontend)); + + $productHelper = $this->getMock( + '\Magento\GoogleShopping\Helper\Product', + array('getProductAttribute'), + array(), + '', + false + ); + $productHelper->expects($this->any()) + ->method('getProductAttribute') + ->with($product, $attributeId) + ->will($this->returnValue($attribute)); + + + $gsData = $this->getMock( + '\Magento\GoogleShopping\Helper\Data', + array('cleanAtomAttribute'), + array(), + '', + false + ); + $gsData->expects($this->once()) + ->method('cleanAtomAttribute') + ->with($mapValue) + ->will($this->returnValue($mapValue)); + + $model = (new \Magento\TestFramework\Helper\ObjectManager($this)) + ->getObject( + '\Magento\GoogleShopping\Model\Attribute\Content', + array('gsProduct' => $productHelper, 'gsData' => $gsData) + ); + + $service = $this->getMock('Zend_Gdata_App', array('newContent', 'setText'), array(), '', false); + $service->expects($this->once())->method('newContent')->will($this->returnSelf()); + $service->expects($this->once())->method('setText')->with($mapValue)->will($this->returnValue($mapValue)); + + $entry = $this->getMock( + '\Magento\Framework\Gdata\Gshopping\Entry', + array('getService', 'setContent'), + array(), + '', + false + ); + $entry->expects($this->once())->method('getService')->will($this->returnValue($service)); + $entry->expects($this->once())->method('setContent')->with($mapValue); + + $groupAttributeDescription = $this->getMock( + '\Magento\GoogleShopping\Model\Attribute\DefaultAttribute', + array(), + array(), + '', + false + ); + + $model->setGroupAttributeDescription($groupAttributeDescription); + $model->setAttributeId($attributeId); + + $this->assertEquals($entry, $model->convertAttribute($product, $entry)); + } + + /** + * @return array + */ + public function convertAttributeDataProvider() + { + return array( + array(1, 'description', 'short description'), + array(null, 'description', 'description'), + ); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php index 9bb9fe60207c823a07b6663d502be4d847ee3360..33bcd4f14abed3575d43e823e29efe7008f58a0d 100644 --- a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php +++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php @@ -808,7 +808,7 @@ HANDLE; $this->_viewMock->expects($this->once())->method('renderLayout'); $this->_responseMock->expects($this->once())->method('getBody'); - $this->_responseMock->expects($this->once())->method('setBody'); + $this->_responseMock->expects($this->once())->method('representJson'); $controller->tokensExchangeAction(); } diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4fa1edea8b023b6914f8b26152b498c8a93d3bbf --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Rule\Model\Condition; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class CombineTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Rule\Model\Condition\Combine */ + protected $_combine; + + /** @var ObjectManagerHelper */ + protected $_objectManagerHelper; + + /** @var \Magento\Rule\Model\Condition\Context|\PHPUnit_Framework_MockObject_MockObject */ + protected $_contextMock; + + protected function setUp() + { + $this->_objectManagerHelper = new ObjectManagerHelper($this); + $this->_combine = $this->_objectManagerHelper->getObject('Magento\Rule\Model\Condition\Combine'); + } + + /** + * @covers \Magento\Rule\Model\Condition\AbstractCondition::getValueName + * @dataProvider optionValuesData + * @param string|array $value + * @param string $expectingData + */ + public function testGetValueName($value, $expectingData) + { + $this->_combine->setValueOption(array('option_key' => 'option_value'))->setValue($value); + $this->assertEquals($expectingData, $this->_combine->getValueName()); + } + + public function optionValuesData() + { + return array( + array('option_key', 'option_value'), + array('option_value', 'option_value'), + array(array('option_key'), 'option_value'), + array('', '...'), + ); + } + +} diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Items/AbstractItemsTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Items/AbstractItemsTest.php index f6441b8fe121733426348017b44eddc1b0ae1f6d..aa7edc862ade12ae73cd89bace59d55edadcd2c0 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Items/AbstractItemsTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Items/AbstractItemsTest.php @@ -23,8 +23,18 @@ */ namespace Magento\Sales\Block\Adminhtml\Items; +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + class AbstractItemsTest extends \PHPUnit_Framework_TestCase { + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + protected function setUp() + { + $this->objectManagerHelper = new ObjectManagerHelper($this); + } + public function testGetItemRenderer() { $layout = $this->getMock( @@ -34,44 +44,27 @@ class AbstractItemsTest extends \PHPUnit_Framework_TestCase '', false ); - $layout->expects( - $this->any() - )->method( - 'getChildName' - )->with( - null, - 'some-type' - )->will( - $this->returnValue('column_block-name') - ); - $layout->expects( - $this->any() - )->method( - 'getGroupChildNames' - )->with( - null, - 'column' - )->will( - $this->returnValue(array('column_block-name')) - ); + $layout->expects($this->any()) + ->method('getChildName') + ->with(null, 'some-type') + ->will($this->returnValue('column_block-name')); + $layout->expects($this->any()) + ->method('getGroupChildNames') + ->with(null, 'column') + ->will($this->returnValue(array('column_block-name'))); - $helper = new \Magento\TestFramework\Helper\ObjectManager($this); /** @var \Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer $renderer */ - $renderer = $helper->getObject('Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer'); + $renderer = $this->objectManagerHelper + ->getObject('Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer'); $renderer->setLayout($layout); - $layout->expects( - $this->any() - )->method( - 'getBlock' - )->with( - 'column_block-name' - )->will( - $this->returnValue($renderer) - ); + $layout->expects($this->any()) + ->method('getBlock') + ->with('column_block-name') + ->will($this->returnValue($renderer)); /** @var \Magento\Sales\Block\Adminhtml\Items\AbstractItems $block */ - $block = $helper->getObject('Magento\Sales\Block\Adminhtml\Items\AbstractItems'); + $block = $this->objectManagerHelper->getObject('Magento\Sales\Block\Adminhtml\Items\AbstractItems'); $block->setLayout($layout); $this->assertSame($renderer, $block->getItemRenderer('some-type')); @@ -92,32 +85,20 @@ class AbstractItemsTest extends \PHPUnit_Framework_TestCase '', false ); - $layout->expects( - $this->at(0) - )->method( - 'getChildName' - )->with( - null, - 'some-type' - )->will( - $this->returnValue('some-block-name') - ); - $layout->expects( - $this->at(1) - )->method( - 'getBlock' - )->with( - 'some-block-name' - )->will( - $this->returnValue($renderer) - ); + $layout->expects($this->at(0)) + ->method('getChildName') + ->with(null, 'some-type') + ->will($this->returnValue('some-block-name')); + $layout->expects($this->at(1)) + ->method('getBlock') + ->with('some-block-name') + ->will($this->returnValue($renderer)); /** @var $block \Magento\Sales\Block\Adminhtml\Items\AbstractItems */ - $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); - $block = $objectManager->getObject( + $block = $this->objectManagerHelper->getObject( 'Magento\Sales\Block\Adminhtml\Items\AbstractItems', array( - 'context' => $objectManager->getObject( + 'context' => $this->objectManagerHelper->getObject( 'Magento\Backend\Block\Template\Context', array('layout' => $layout) ) @@ -126,4 +107,174 @@ class AbstractItemsTest extends \PHPUnit_Framework_TestCase $block->getItemRenderer('some-type'); } + + /** + * @param bool $canReturnToStock + * @param array $itemConfig + * @param bool $result + * @dataProvider canReturnItemToStockDataProvider + */ + public function testCanReturnItemToStock($canReturnToStock, $itemConfig, $result) + { + $isItem = $itemConfig['is_item']; + $productId = isset($itemConfig['product_id']) ? $itemConfig['product_id'] : null; + $manageStock = isset($itemConfig['manage_stock']) ? $itemConfig['manage_stock'] : null; + $item = null; + + if ($isItem) { + $item = $this->getMock( + 'Magento\Sales\Model\Order\Creditmemo\Item', + ['hasCanReturnToStock', 'getOrderItem', 'setCanReturnToStock', 'getCanReturnToStock', '__wakeup'], + [], + '', + false + ); + $dependencies = $this->prepareServiceMockDependency( + $item, + $canReturnToStock, + $productId, + $manageStock, + $itemConfig + ); + } else { + $dependencies = $this->prepareScopeConfigMockDependency($canReturnToStock); + + } + + /** @var $block \Magento\Sales\Block\Adminhtml\Items\AbstractItems */ + $block = $this->objectManagerHelper->getObject( + 'Magento\Sales\Block\Adminhtml\Items\AbstractItems', + $dependencies + ); + $this->assertSame($result, $block->canReturnItemToStock($item)); + } + + /** + * @param bool $canReturnToStock + * @return array + */ + protected function prepareScopeConfigMockDependency($canReturnToStock) + { + $dependencies = []; + $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $scopeConfig->expects($this->once()) + ->method('getValue') + ->with( + $this->equalTo(\Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) + ->will($this->returnValue($canReturnToStock)); + + $dependencies['context'] = $this->objectManagerHelper->getObject( + 'Magento\Backend\Block\Template\Context', + array('scopeConfig' => $scopeConfig) + ); + return $dependencies; + } + + /** + * @param \PHPUnit_Framework_MockObject_MockObject $item + * @param bool $canReturnToStock + * @param int|null $productId + * @param bool $manageStock + * @param array $itemConfig + * @return array + */ + protected function prepareServiceMockDependency($item, $canReturnToStock, $productId, $manageStock, $itemConfig) + { + $dependencies = []; + $item->expects($this->once()) + ->method('hasCanReturnToStock') + ->will($this->returnValue($itemConfig['has_can_return_to_stock'])); + if (!$itemConfig['has_can_return_to_stock']) { + $orderItem = $this->getMock( + 'Magento\Sales\Model\Order\Item', + ['getProductId', '__wakeup'], + [], + '', + false + ); + $orderItem->expects($this->once()) + ->method('getProductId') + ->will($this->returnValue($productId)); + $item->expects($this->once()) + ->method('getOrderItem') + ->will($this->returnValue($orderItem)); + if ($productId) { + $stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); + $stockItemService->expects($this->once()) + ->method('getManageStock') + ->with($this->equalTo($productId)) + ->will($this->returnValue($manageStock)); + $dependencies['stockItemService'] = $stockItemService; + } + if ($productId && $manageStock) { + $canReturn = true; + } else { + $canReturn = false; + } + $item->expects($this->once()) + ->method('setCanReturnToStock') + ->with($this->equalTo($canReturn)) + ->will($this->returnSelf()); + } + $item->expects($this->once()) + ->method('getCanReturnToStock') + ->will($this->returnValue($canReturnToStock)); + + return $dependencies; + } + + /** + * @return array + */ + public function canReturnItemToStockDataProvider() + { + return [ + [true, ['is_item' => null], true], + [false, ['is_item' => null], false], + [ + true, + [ + 'is_item' => true, + 'has_can_return_to_stock' => true + ], + true + ], + [ + false, + [ + 'is_item' => true, + 'has_can_return_to_stock' => true + ], + false + ], + [ + false, + [ + 'is_item' => true, + 'has_can_return_to_stock' => false, + 'product_id' => 2, + 'manage_stock' => false + ], + false + ], + [ + true, + [ + 'is_item' => true, + 'has_can_return_to_stock' => false, + 'product_id' => 2, + 'manage_stock' => true + ], + true + ], + ]; + } } diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Items/GridTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Items/GridTest.php index 357f1771f052b6097b6acc047127f00317d6a0c0..b72f46f25625a59497b8688c72274eb3734bf94e 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Items/GridTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Items/GridTest.php @@ -28,64 +28,56 @@ class GridTest extends \PHPUnit_Framework_TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Block\Adminhtml\Order\Create\Items\Grid */ - protected $_block; + protected $block; + + /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Service\V1\StockItemService */ + protected $stockItemService; /** * Initialize required data */ protected function setUp() { - $orderCreateMock = $this->getMock( - 'Magento\Sales\Model\AdminOrder\Create', - array('__wakeup'), - array(), - '', - false - ); - + $orderCreateMock = $this->getMock('Magento\Sales\Model\AdminOrder\Create', ['__wakeup'], [], '', false); $taxData = $this->getMockBuilder('Magento\Tax\Helper\Data')->disableOriginalConstructor()->getMock(); - $coreData = $this->getMockBuilder('Magento\Core\Helper\Data')->disableOriginalConstructor()->getMock(); - - $sessionMock = $this->getMockBuilder( - 'Magento\Backend\Model\Session\Quote' - )->disableOriginalConstructor()->setMethods( - array('getQuote', '__wakeup') - )->getMock(); - - $quoteMock = $this->getMockBuilder( - 'Magento\Sales\Model\Quote' - )->disableOriginalConstructor()->setMethods( - array('getStore', '__wakeup') - )->getMock(); - - $storeMock = $this->getMockBuilder( - 'Magento\Store\Model\Store' - )->disableOriginalConstructor()->setMethods( - array('__wakeup', 'convertPrice') - )->getMock(); + $sessionMock = $this->getMockBuilder('Magento\Backend\Model\Session\Quote') + ->disableOriginalConstructor() + ->setMethods(array('getQuote', '__wakeup')) + ->getMock(); + + $quoteMock = $this->getMockBuilder('Magento\Sales\Model\Quote') + ->disableOriginalConstructor() + ->setMethods(array('getStore', '__wakeup')) + ->getMock(); + + $storeMock = $this->getMockBuilder('Magento\Store\Model\Store') + ->disableOriginalConstructor() + ->setMethods(array('__wakeup', 'convertPrice')) + ->getMock(); $storeMock->expects($this->any())->method('convertPrice')->will($this->returnArgument(0)); - $quoteMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); - $sessionMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); + $wishlistFactoryMock = $this->getMockBuilder('Magento\Wishlist\Model\WishlistFactory') + ->setMethods(array('methods', '__wakeup')) + ->getMock(); - $wishlistFactoryMock = $this->getMockBuilder( - 'Magento\Wishlist\Model\WishlistFactory' - )->setMethods( - array('methods', '__wakeup') - )->getMock(); - - $giftMessageSave = $this->getMockBuilder( - 'Magento\Giftmessage\Model\Save' - )->setMethods( - array('__wakeup') - )->disableOriginalConstructor()->getMock(); + $giftMessageSave = $this->getMockBuilder('Magento\Giftmessage\Model\Save') + ->setMethods(array('__wakeup')) + ->disableOriginalConstructor() + ->getMock(); $taxConfig = $this->getMockBuilder('Magento\Tax\Model\Config')->disableOriginalConstructor()->getMock(); + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); $helper = new \Magento\TestFramework\Helper\ObjectManager($this); - $this->_block = $helper->getObject( + $this->block = $helper->getObject( 'Magento\Sales\Block\Adminhtml\Order\Create\Items\Grid', array( 'wishlistFactory' => $wishlistFactoryMock, @@ -94,7 +86,8 @@ class GridTest extends \PHPUnit_Framework_TestCase 'taxData' => $taxData, 'sessionQuote' => $sessionMock, 'orderCreate' => $orderCreateMock, - 'coreData' => $coreData + 'coreData' => $coreData, + 'stockItemService' => $this->stockItemService ) ); } @@ -107,9 +100,8 @@ class GridTest extends \PHPUnit_Framework_TestCase */ public function testTierPriceInfo($itemData, $expectedMessage, $productType) { - $itemMock = $this->_prepareItem($itemData, $productType); - $result = $this->_block->getTierHtml($itemMock); - + $itemMock = $this->prepareItem($itemData, $productType); + $result = $this->block->getTierHtml($itemMock); $this->assertEquals($expectedMessage, $result); } @@ -128,7 +120,7 @@ class GridTest extends \PHPUnit_Framework_TestCase ), array( array(array('price' => 100, 'price_qty' => 1), array('price' => 200, 'price_qty' => 2)), - '1 with 100% discount each<br/>2 with 200% discount each', + '1 with 100% discount each<br />2 with 200% discount each', \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE ), array( @@ -138,7 +130,7 @@ class GridTest extends \PHPUnit_Framework_TestCase ), array( array(array('price' => 50, 'price_qty' => 2), array('price' => 150, 'price_qty' => 3)), - '2 for 50<br/>3 for 150', + '2 for 50<br />3 for 150', \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE ), array(0, '', \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) @@ -150,13 +142,12 @@ class GridTest extends \PHPUnit_Framework_TestCase * @param string $productType * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Model\Quote\Item */ - protected function _prepareItem($tierPrices, $productType) + protected function prepareItem($tierPrices, $productType) { - $product = $this->getMockBuilder( - 'Magento\Catalog\Model\Product' - )->disableOriginalConstructor()->setMethods( - array('getTierPrice', '__wakeup') - )->getMock(); + $product = $this->getMockBuilder('Magento\Catalog\Model\Product') + ->disableOriginalConstructor() + ->setMethods(array('getTierPrice', '__wakeup')) + ->getMock(); $product->expects($this->once())->method('getTierPrice')->will($this->returnValue($tierPrices)); $item = $this->getMock( 'Magento\Sales\Model\Quote\Item', @@ -177,30 +168,28 @@ class GridTest extends \PHPUnit_Framework_TestCase */ public function testGetItems() { - $layoutMock = $this->getMock('\Magento\Framework\View\LayoutInterface'); - $blockMock = $this->getMock( - '\Magento\Framework\View\Element\AbstractBlock', - array('getItems'), array(), '', false - ); - + $productId = 8; + $itemQty = 23; + $layoutMock = $this->getMock('Magento\Framework\View\LayoutInterface'); + $blockMock = $this->getMock('Magento\Framework\View\Element\AbstractBlock', ['getItems'], [], '', false); $itemMock = $this->getMock( - '\Magento\Sales\Model\Quote\Item', - array('getProduct', 'setHasError', 'setQty', 'getQty', '__sleep', '__wakeup'), array(), '', false + 'Magento\Sales\Model\Quote\Item', + array('getProduct', 'setHasError', 'setQty', 'getQty', '__sleep', '__wakeup'), + array(), + '', + false ); $productMock = $this->getMock( - '\Magento\Catalog\Model\Product', - array('getStockItem', 'getStatus', '__sleep', '__wakeup'), array(), '', false - ); - $stockItemMock = $this->getMock( - '\Magento\CatalogInventory\Model\Stock\Item', - array(), array(), '', false - ); - $checkMock = $this->getMock( - '\Magento\Framework\Object', - array('getMessage', 'getHasError'), array(), '', false + 'Magento\Catalog\Model\Product', + array('getStockItem', 'getID', '__sleep', '__wakeup'), + array(), + '', + false ); + $checkMock = $this->getMock('Magento\Framework\Object', ['getMessage', 'getHasError'], [], '', false); + $layoutMock->expects($this->once())->method('getParentName')->will($this->returnValue('parentBlock')); $layoutMock->expects($this->once())->method('getBlock')->with('parentBlock') ->will($this->returnValue($blockMock)); @@ -209,20 +198,28 @@ class GridTest extends \PHPUnit_Framework_TestCase $itemMock->expects($this->any())->method('getChildren')->will($this->returnValue(array($itemMock))); $itemMock->expects($this->any())->method('getProduct')->will($this->returnValue($productMock)); + $itemMock->expects($this->any())->method('getQty')->will($this->returnValue($itemQty)); - $productMock->expects($this->any())->method('getStockItem')->will($this->returnValue($stockItemMock)); + $productMock->expects($this->any())->method('getId')->will($this->returnValue($productId)); $productMock->expects($this->any())->method('getStatus') ->will($this->returnValue(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)); $checkMock->expects($this->any())->method('getMessage')->will($this->returnValue('Message')); $checkMock->expects($this->any())->method('getHasError')->will($this->returnValue(false)); - $stockItemMock->expects($this->once())->method('checkQuoteItemQty')->will($this->returnValue($checkMock)); + $this->stockItemService->expects($this->once()) + ->method('checkQuoteItemQty') + ->with( + $this->equalTo($productId), + $this->equalTo($itemQty), + $this->equalTo($itemQty) + ) + ->will($this->returnValue($checkMock)); - $this->_block->getQuote()->setIsSuperMode(true); - $items = $this->_block->setLayout($layoutMock)->getItems(); + $this->block->getQuote()->setIsSuperMode(true); + $items = $this->block->setLayout($layoutMock)->getItems(); $this->assertEquals('Message', $items[0]->getMessage()); - $this->assertEquals(true, $this->_block->getQuote()->getIsSuperMode()); + $this->assertEquals(true, $this->block->getQuote()->getIsSuperMode()); } } diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/ItemsTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/ItemsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e0953afda7a866c1ed42678c9821fb81d9e4ffb9 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/ItemsTest.php @@ -0,0 +1,160 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; + +class ItemsTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Items */ + protected $items; + + /** @var ObjectManagerHelper */ + protected $objectManagerHelper; + + /** @var \Magento\Backend\Block\Template\Context|\PHPUnit_Framework_MockObject_MockObject */ + protected $contextMock; + + /** @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */ + protected $stockItemMock; + + /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */ + protected $registryMock; + + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $scopeConfig; + + protected function setUp() + { + $this->contextMock = $this->getMock('Magento\Backend\Block\Template\Context', [], [], '', false); + $this->stockItemMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); + $this->registryMock = $this->getMock('Magento\Framework\Registry'); + $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'); + $this->contextMock->expects($this->once()) + ->method('getScopeConfig') + ->will($this->returnValue($this->scopeConfig)); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->items = $this->objectManagerHelper->getObject( + 'Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create\Items', + [ + 'context' => $this->contextMock, + 'stockItemService' => $this->stockItemMock, + 'registry' => $this->registryMock + ] + ); + } + + /** + * @param bool $canReturnToStock + * @param bool $manageStock + * @param bool $result + * @dataProvider canReturnItemsToStockDataProvider + */ + public function testCanReturnItemsToStock($canReturnToStock, $manageStock, $result) + { + $productId = 7; + $property = new \ReflectionProperty($this->items, '_canReturnToStock'); + $property->setAccessible(true); + $this->assertNull($property->getValue($this->items)); + $this->scopeConfig->expects($this->once()) + ->method('getValue') + ->with( + $this->equalTo(\Magento\CatalogInventory\Model\Stock\Item::XML_PATH_CAN_SUBTRACT), + $this->equalTo(\Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) + ->will($this->returnValue($canReturnToStock)); + + if ($canReturnToStock) { + $orderItem = $this->getMock('Magento\Sales\Model\Order\Item', ['getProductId', '__wakeup'], [], '', false); + $orderItem->expects($this->once()) + ->method('getProductId') + ->will($this->returnValue($productId)); + + $creditMemoItem = $this->getMock( + 'Magento\Sales\Model\Order\Creditmemo\Item', + ['setCanReturnToStock', 'getOrderItem', '__wakeup'], + [], + '', + false + ); + + $creditMemo = $this->getMock('Magento\Sales\Model\Order\Creditmemo', [], [], '', false); + $creditMemo->expects($this->once()) + ->method('getAllItems') + ->will($this->returnValue([$creditMemoItem])); + $creditMemoItem->expects($this->once()) + ->method('getOrderItem') + ->will($this->returnValue($orderItem)); + + $this->stockItemMock->expects($this->once()) + ->method('getManageStock') + ->with($this->equalTo($productId)) + ->will($this->returnValue($manageStock)); + + $creditMemoItem->expects($this->once()) + ->method('setCanReturnToStock') + ->with($this->equalTo($manageStock)) + ->will($this->returnSelf()); + + $order = $this->getMock('Magento\Sales\Model\Order', ['setCanReturnToStock', '__wakeup'], [], '', false); + $order->expects($this->once()) + ->method('setCanReturnToStock') + ->with($this->equalTo($manageStock)) + ->will($this->returnSelf()); + $creditMemo->expects($this->once()) + ->method('getOrder') + ->will($this->returnValue($order)); + + $this->registryMock->expects($this->any()) + ->method('registry') + ->with('current_creditmemo') + ->will($this->returnValue($creditMemo)); + } + + $this->assertSame($result, $this->items->canReturnItemsToStock()); + $this->assertSame($result, $property->getValue($this->items)); + // lazy load test + $this->assertSame($result, $this->items->canReturnItemsToStock()); + } + + /** + * @return array + */ + public function canReturnItemsToStockDataProvider() + { + return [ + 'cannot subtract by config' => [false, true, false], + 'manage stock is enabled' => [true, true, true], + 'manage stock is disabled' => [true, false, false], + ]; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Reorder/SidebarTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Reorder/SidebarTest.php index a5501c494a03cd4ff4ba6baf4c39d24dbf94facc..60644eb5717a51df87488c8945e6dd0571b858e7 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Block/Reorder/SidebarTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Reorder/SidebarTest.php @@ -65,6 +65,9 @@ class SidebarTest extends \PHPUnit_Framework_TestCase */ protected $orderCollection; + /** @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */ + protected $stockItemService; + /** * @var \Magento\TestFramework\Helper\ObjectManager */ @@ -73,14 +76,13 @@ class SidebarTest extends \PHPUnit_Framework_TestCase protected function setUp() { $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this); - $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false, false); - $this->httpContext = $this->getMock('Magento\Framework\App\Http\Context', ['getValue'], [], '', false, false); + $this->context = $this->getMock('Magento\Framework\View\Element\Template\Context', [], [], '', false); + $this->httpContext = $this->getMock('Magento\Framework\App\Http\Context', ['getValue'], [], '', false); $this->orderCollectionFactory = $this->getMock( 'Magento\Sales\Model\Resource\Order\CollectionFactory', ['create'], [], '', - false, false ); $this->customerSession = $this->getMock( @@ -88,7 +90,6 @@ class SidebarTest extends \PHPUnit_Framework_TestCase ['getCustomerId'], [], '', - false, false ); $this->orderConfig = $this->getMock( @@ -96,7 +97,6 @@ class SidebarTest extends \PHPUnit_Framework_TestCase ['getVisibleOnFrontStatuses'], [], '', - false, false ); $this->orderCollection = $this->getMock( @@ -109,7 +109,13 @@ class SidebarTest extends \PHPUnit_Framework_TestCase ], [], '', - false, + false + ); + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', false ); } @@ -119,6 +125,21 @@ class SidebarTest extends \PHPUnit_Framework_TestCase $this->block = null; } + protected function createBlockObject() + { + $this->block = $this->objectManagerHelper->getObject( + 'Magento\Sales\Block\Reorder\Sidebar', + [ + 'context' => $this->context, + 'orderCollectionFactory' => $this->orderCollectionFactory, + 'orderConfig' => $this->orderConfig, + 'customerSession' => $this->customerSession, + 'httpContext' => $this->httpContext, + 'stockItemService' => $this->stockItemService, + ] + ); + } + public function testGetIdentities() { $websiteId = 1; @@ -126,11 +147,12 @@ class SidebarTest extends \PHPUnit_Framework_TestCase $productTags = ['catalog_product_1']; $limit = 5; - $storeManager = $this->getMock('Magento\Store\Model\StoreManager', ['getStore'], [], '', false, false); + $storeManager = $this->getMock('Magento\Store\Model\StoreManager', ['getStore'], [], '', false); $this->context->expects($this->once()) ->method('getStoreManager') ->will($this->returnValue($storeManager)); - $store = $this->getMock('Magento\Store\Model', ['getWebsiteId'], [], '', false, false); + + $store = $this->getMock('Magento\Store\Model', ['getWebsiteId'], [], '', false); $store->expects($this->once()) ->method('getWebsiteId') ->will($this->returnValue($websiteId)); @@ -176,15 +198,8 @@ class SidebarTest extends \PHPUnit_Framework_TestCase ->with($this->equalTo($limit)) ->will($this->returnValue([$item])); - $this->block = new \Magento\Sales\Block\Reorder\Sidebar( - $this->context, - $this->orderCollectionFactory, - $this->orderConfig, - $this->customerSession, - $this->httpContext, - [] - ); - $this->block->setOrders([$order]); + $this->createBlockObject(); + $this->assertSame($this->block, $this->block->setOrders([$order])); $this->assertEquals($productTags, $this->block->getIdentities()); } @@ -230,15 +245,45 @@ class SidebarTest extends \PHPUnit_Framework_TestCase $this->orderCollectionFactory->expects($this->atLeastOnce()) ->method('create') ->will($this->returnValue($this->orderCollection)); - - $this->block = new \Magento\Sales\Block\Reorder\Sidebar( - $this->context, - $this->orderCollectionFactory, - $this->orderConfig, - $this->customerSession, - $this->httpContext, - [] - ); + $this->createBlockObject(); $this->assertEquals($this->orderCollection, $this->block->getOrders()); } + + /** + * @param int|bool $productId + * @param bool $result + * @dataProvider isItemAvailableForReorderDataProvider + */ + public function testIsItemAvailableForReorder($productId, $result) + { + if ($productId) { + $product = $this->getMock('Magento\Catalog\Model\Product', ['getId', '__wakeup'], [], '', false); + $product->expects($this->once()) + ->method('getId') + ->will($this->returnValue($productId)); + $this->stockItemService->expects($this->once()) + ->method('getIsInStock') + ->with($this->equalTo($productId)) + ->will($this->returnValue($result)); + } else { + $product = false; + } + $orderItem = $this->getMock('Magento\Sales\Model\Order\Item', [], [], '', false); + $orderItem->expects($this->any()) + ->method('getProduct') + ->will($this->returnValue($product)); + $this->createBlockObject(); + $this->assertSame($result, $this->block->isItemAvailableForReorder($orderItem)); + } + + /** + * @return array + */ + public function isItemAvailableForReorderDataProvider() + { + return [ + [false, false], + [4, true], + ]; + } } diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..07aa134b4af86def437ddb12ad9fd1ca5694385f --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php @@ -0,0 +1,223 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +namespace Magento\Sales\Model\AdminOrder\Product\Quote; + +/** + * Initializer test + */ +class InitializerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\TestFramework\Helper\ObjectManager + */ + protected $objectManager; + + /** + * @var \Magento\Sales\Model\Quote|\PHPUnit_Framework_MockObject_MockObject + */ + protected $quoteMock; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + /** + * @var \Magento\Framework\Object|\PHPUnit_Framework_MockObject_MockObject + */ + protected $configMock; + + /** + * @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemServiceMock; + + /** + * @var \Magento\Sales\Model\AdminOrder\Product\Quote\Initializer + */ + protected $model; + + protected function setUp() + { + $this->quoteMock = $this->getMock( + 'Magento\Sales\Model\Quote', + ['addProductAdvanced', '__wakeup'], + [], + '', + false + ); + + $this->productMock = $this->getMock( + 'Magento\Catalog\Model\Product', + ['getId', 'setIsQtyDecimal', 'setCartQty', '__wakeup'], + [], + '', + false + ); + + $this->configMock = $this->getMock( + 'Magento\Framework\Object', + ['getQty', 'setQty'], + [], + '', + false + ); + + $this->stockItemServiceMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + ['getStockItem', '__wakeup'], + [], + '', + false + ); + + $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this); + $this->model = $this->objectManager + ->getObject( + 'Magento\Sales\Model\AdminOrder\Product\Quote\Initializer', + ['stockItemService' => $this->stockItemServiceMock] + ); + } + + public function testInitWithDecimalQty() + { + $quoteItemMock = $this->getMock( + '\Magento\Sales\Model\Quote\Item', + ['getStockId', 'getIsQtyDecimal', '__wakeup'], + [], + '', + false + ); + + $this->stockItemServiceMock->expects($this->once()) + ->method('getStockItem') + ->will($this->returnValue($this->getStockItemDo(true))); + + $this->productMock->expects($this->once()) + ->method('getId') + ->will($this->returnSelf()); + + $this->productMock->expects($this->once()) + ->method('setIsQtyDecimal') + ->will($this->returnSelf()); + + $this->productMock->expects($this->once()) + ->method('setCartQty') + ->will($this->returnSelf()); + + $this->configMock->expects($this->once()) + ->method('getQty') + ->will($this->returnValue(20)); + + $this->configMock->expects($this->never()) + ->method('setQty'); + + $this->quoteMock->expects($this->once()) + ->method('addProductAdvanced') + ->will($this->returnValue($quoteItemMock)); + + $this->assertInstanceOf( + 'Magento\Sales\Model\Quote\Item', + $this->model->init( + $this->quoteMock, + $this->productMock, + $this->configMock + ) + ); + } + + public function testInitWithNonDecimalQty() + { + $quoteItemMock = $this->getMock( + '\Magento\Sales\Model\Quote\Item', + ['getStockId', 'getIsQtyDecimal', '__wakeup'], + [], + '', + false + ); + + $this->stockItemServiceMock->expects($this->once()) + ->method('getStockItem') + ->will($this->returnValue($this->getStockItemDo(false))); + + $this->productMock->expects($this->once()) + ->method('getId') + ->will($this->returnSelf()); + + $this->productMock->expects($this->never()) + ->method('setIsQtyDecimal'); + + $this->productMock->expects($this->once()) + ->method('setCartQty') + ->will($this->returnSelf()); + + $this->configMock->expects($this->exactly(2)) + ->method('getQty') + ->will($this->returnValue(10)); + + $this->configMock->expects($this->once()) + ->method('setQty') + ->will($this->returnSelf()); + + + $this->quoteMock->expects($this->once()) + ->method('addProductAdvanced') + ->will($this->returnValue($quoteItemMock)); + + $this->assertInstanceOf( + 'Magento\Sales\Model\Quote\Item', + $this->model->init( + $this->quoteMock, + $this->productMock, + $this->configMock + ) + ); + } + + /** + * @param bool $isQtyDecimal + * @return \Magento\CatalogInventory\Service\V1\Data\StockItem|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getStockItemDo($isQtyDecimal) + { + $stockItemDoMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\Data\StockItem', + ['getStockId', 'getIsQtyDecimal'], + [], + '', + false + ); + + $stockItemDoMock->expects($this->once()) + ->method('getStockId') + ->will($this->returnValue(5)); + + $stockItemDoMock->expects($this->once()) + ->method('getIsQtyDecimal') + ->will($this->returnValue($isQtyDecimal)); + + return $stockItemDoMock; + } +} diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/Total/SubtotalTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/Total/SubtotalTest.php index 08ba7473ac4eadcd1c0782c3baab7e794852b60c..4e05c179c9fe58fc3b402da71bc73a60eca26822 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/Total/SubtotalTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/Total/SubtotalTest.php @@ -63,8 +63,37 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase */ public function testCollect($price, $originalPrice, $itemHasParent, $expectedPrice, $expectedOriginalPrice) { + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDoMock */ + $stockItemDoMock = $this->getMock( + '\Magento\CatalogInventory\Service\V1\Data\StockItem', + ['getStockId'], + [], + '', + false + ); + + $stockItemDoMock->expects($this->any()) + ->method('getStockId') + ->will($this->returnValue(false)); + + /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemServiceMock */ + $stockItemServiceMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + ['getStockItem'], + [], + '', + false + ); + + $stockItemServiceMock->expects($this->any()) + ->method('getStockItem') + ->will($this->returnValue($stockItemDoMock)); + /** @var \Magento\Sales\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject $quoteItem */ - $quoteItem = $this->objectManager->getObject('Magento\Sales\Model\Quote\Item'); + $quoteItem = $this->objectManager->getObject( + 'Magento\Sales\Model\Quote\Item', + ['stockItemService' => $stockItemServiceMock] + ); /** @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject $address */ $address = $this->getMock( 'Magento\Sales\Model\Quote\Address', diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php index e4d2d5311fa05368b9cb3d20c34a840a518467b4..c679f53cb3c18f9574f509e3c941e465f0f9b276 100644 --- a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php +++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php @@ -65,6 +65,11 @@ class ItemTest extends \PHPUnit_Framework_TestCase */ protected $compareHelper; + /** + * @var \Magento\CatalogInventory\Service\V1\Data\StockItem + */ + protected $stockItemDoMock; + const PRODUCT_ID = 1; const PRODUCT_TYPE = 'simple'; const PRODUCT_SKU = '12345'; @@ -122,6 +127,28 @@ class ItemTest extends \PHPUnit_Framework_TestCase false ); + /** @var \Magento\CatalogInventory\Service\V1\Data\StockItem $stockItemDoMock */ + $this->stockItemDoMock = $this->getMock( + '\Magento\CatalogInventory\Service\V1\Data\StockItem', + ['getStockId', 'getIsQtyDecimal'], + [], + '', + false + ); + + /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemServiceMock */ + $stockItemServiceMock = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + ['getStockItem'], + [], + '', + false + ); + + $stockItemServiceMock->expects($this->any()) + ->method('getStockItem') + ->will($this->returnValue($this->stockItemDoMock)); + $this->model = $this->objectManagerHelper->getObject( '\Magento\Sales\Model\Quote\Item', [ @@ -129,7 +156,8 @@ class ItemTest extends \PHPUnit_Framework_TestCase 'context' => $this->modelContext, 'statusListFactory' => $statusListFactory, 'itemOptionFactory' => $this->itemOptionFactory, - 'compareHelper' => $this->compareHelper + 'compareHelper' => $this->compareHelper, + 'stockItemService' => $stockItemServiceMock ] ); } @@ -350,16 +378,12 @@ class ItemTest extends \PHPUnit_Framework_TestCase ->with('sales_quote_item_set_product', ['product' => $productMock, 'quote_item' => $this->model]); $isQtyDecimal = true; - $stockItemMock = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Item') - ->disableOriginalConstructor() - ->setMethods(['getIsQtyDecimal', '__wakeup']) - ->getMock(); - $stockItemMock->expects($this->once()) + $this->stockItemDoMock->expects($this->once()) + ->method('getStockId') + ->will($this->returnValue(99)); + $this->stockItemDoMock->expects($this->once()) ->method('getIsQtyDecimal') ->will($this->returnValue($isQtyDecimal)); - $productMock->expects($this->exactly(2)) - ->method('getStockItem') - ->will($this->returnValue($stockItemMock)); $storeId = 15; $customerGroupId = 11; @@ -415,7 +439,6 @@ class ItemTest extends \PHPUnit_Framework_TestCase 'getWeight', 'getTaxClassId', 'getCost', - 'getStockItem', 'setStoreId', 'setCustomerGroupId', 'getTypeInstance', diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Model/Carrier/AbstractCarrierOnlineTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Model/Carrier/AbstractCarrierOnlineTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ac5588b9f0adc8eb760dd1285a93a81ece2f785a --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Shipping/Model/Carrier/AbstractCarrierOnlineTest.php @@ -0,0 +1,117 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Shipping\Model\Carrier; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Sales\Model\Quote\Address\RateRequest; + +class AbstractCarrierOnlineTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test identification number of product + * + * @var int + */ + protected $productId = 1; + + /** + * @var AbstractCarrierOnline|\PHPUnit_Framework_MockObject_MockObject + */ + protected $carrier; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemService; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemData; + + protected function setUp() + { + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); + $this->stockItemData = $this->getMock('Magento\CatalogInventory\Service\V1\Data\StockItem', [], [], '', false); + $this->stockItemService->expects($this->any())->method('getStockItem') + ->will($this->returnValue($this->stockItemData)); + + $objectManagerHelper = new ObjectManagerHelper($this); + $carrierArgs = $objectManagerHelper->getConstructArguments( + 'Magento\Shipping\Model\Carrier\AbstractCarrierOnline', + ['stockItemService' => $this->stockItemService] + ); + $this->carrier = $this->getMockBuilder('Magento\Shipping\Model\Carrier\AbstractCarrierOnline') + ->setConstructorArgs($carrierArgs) + ->setMethods(['getConfigData', '_doShipmentRequest', 'collectRates']) + ->getMock(); + } + + /** + * @covers \Magento\Shipping\Model\Shipping::composePackagesForCarrier + */ + public function testComposePackages() + { + $this->carrier->expects($this->any())->method('getConfigData')->will($this->returnCallback(function ($key) { + $configData = [ + 'max_package_weight' => 10, + 'showmethod' => 1 + ]; + return isset($configData[$key]) ? $configData[$key] : 0; + })); + + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $product->expects($this->any())->method('getId')->will($this->returnValue($this->productId)); + + $item = $this->getMockBuilder('\Magento\Sales\Model\Quote\Item') + ->disableOriginalConstructor() + ->setMethods(['getProduct', 'getQty', 'getWeight', '__wakeup']) + ->getMock(); + $item->expects($this->any())->method('getProduct')->will($this->returnValue($product)); + + $request = new RateRequest(); + $request->setData('all_items', [$item]); + $request->setData('dest_postcode', 1); + + /** Testable service calls to CatalogInventory module */ + $this->stockItemService->expects($this->atLeastOnce())->method('getStockItem')->with($this->productId); + $this->stockItemService->expects($this->atLeastOnce())->method('getEnableQtyIncrements') + ->with($this->productId) + ->will($this->returnValue(true)); + $this->stockItemService->expects($this->atLeastOnce())->method('getQtyIncrements') + ->with($this->productId) + ->will($this->returnValue(5)); + $this->stockItemData->expects($this->atLeastOnce())->method('getIsQtyDecimal')->will($this->returnValue(true)); + $this->stockItemData->expects($this->atLeastOnce())->method('getIsDecimalDivided') + ->will($this->returnValue(true)); + + $this->carrier->proccessAdditionalValidation($request); + } +} diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Model/ShippingTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShippingTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6ad7a938156e531e5f5f5c912c58888faff889d3 --- /dev/null +++ b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShippingTest.php @@ -0,0 +1,119 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +namespace Magento\Shipping\Model; + +use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Sales\Model\Quote\Address\RateRequest; + +class ShippingTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test identification number of product + * + * @var int + */ + protected $productId = 1; + + /** + * @var Shipping + */ + protected $shipping; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Shipping\Model\Carrier\AbstractCarrier + */ + protected $carrier; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemService; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $stockItemData; + + protected function setUp() + { + $this->carrier = $this->getMock('Magento\Shipping\Model\Carrier\AbstractCarrier', [], [], '', false); + $this->carrier->expects($this->any())->method('getConfigData')->will($this->returnCallback(function ($key) { + $configData = [ + 'max_package_weight' => 10, + ]; + return isset($configData[$key]) ? $configData[$key] : 0; + })); + $this->stockItemService = $this->getMock( + 'Magento\CatalogInventory\Service\V1\StockItemService', + [], + [], + '', + false + ); + $this->stockItemData = $this->getMock('Magento\CatalogInventory\Service\V1\Data\StockItem', [], [], '', false); + $this->stockItemService->expects($this->any())->method('getStockItem') + ->will($this->returnValue($this->stockItemData)); + + $objectManagerHelper = new ObjectManagerHelper($this); + $this->shipping = $objectManagerHelper->getObject('Magento\Shipping\Model\Shipping', [ + 'stockItemService' => $this->stockItemService + ]); + } + + /** + * @covers \Magento\Shipping\Model\Shipping::composePackagesForCarrier + */ + public function testComposePackages() + { + $request = new RateRequest(); + /** \Magento\Catalog\Model\Product\Configuration\Item\ItemInterface */ + $item = $this->getMockBuilder('\Magento\Sales\Model\Quote\Item') + ->disableOriginalConstructor() + ->setMethods(['getQty', 'getIsQtyDecimal', 'getProductType', 'getProduct', 'getWeight', '__wakeup']) + ->getMock(); + $product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + + $item->expects($this->any())->method('getQty')->will($this->returnValue(1)); + $item->expects($this->any())->method('getWeight')->will($this->returnValue(10)); + $item->expects($this->any())->method('getIsQtyDecimal')->will($this->returnValue(true)); + $item->expects($this->any())->method('getProductType') + ->will($this->returnValue(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)); + $item->expects($this->any())->method('getProduct')->will($this->returnValue($product)); + $product->expects($this->any())->method('getId')->will($this->returnValue($this->productId)); + $request->setData('all_items', [$item]); + + $this->stockItemData->expects($this->any())->method('getIsDecimalDivided')->will($this->returnValue(true)); + + /** Testable service calls to CatalogInventory module */ + $this->stockItemService->expects($this->atLeastOnce())->method('getStockItem')->with($this->productId); + $this->stockItemService->expects($this->atLeastOnce()) + ->method('getEnableQtyIncrements') + ->with($this->productId) + ->will($this->returnValue(true)); + $this->stockItemService->expects($this->atLeastOnce())->method('getQtyIncrements')->with($this->productId) + ->will($this->returnValue(0.5)); + + $this->shipping->composePackagesForCarrier($this->carrier, $request); + } +} diff --git a/lib/internal/Magento/Framework/App/Http.php b/lib/internal/Magento/Framework/App/Http.php index 7048fd52ddfa223962e40d735ce2da124f1051d7..042a858d312669ea3c870930293bde9f951bee41 100644 --- a/lib/internal/Magento/Framework/App/Http.php +++ b/lib/internal/Magento/Framework/App/Http.php @@ -116,11 +116,8 @@ class Http implements \Magento\Framework\AppInterface $areaCode = $this->_areaList->getCodeByFrontName($this->_request->getFrontName()); $this->_state->setAreaCode($areaCode); $this->_objectManager->configure($this->_configLoader->load($areaCode)); - $this->_response = $this->_objectManager->get( - 'Magento\Framework\App\FrontControllerInterface' - )->dispatch( - $this->_request - ); + $this->_response = $this->_objectManager->get('Magento\Framework\App\FrontControllerInterface') + ->dispatch($this->_request); // This event gives possibility to launch something before sending output (allow cookie setting) $eventParams = array('request' => $this->_request, 'response' => $this->_response); $this->_eventManager->dispatch('controller_front_send_response_before', $eventParams); diff --git a/lib/internal/Magento/Framework/App/Response/Http.php b/lib/internal/Magento/Framework/App/Response/Http.php index 7d1a9d7b48cb78756dedc09ee64035c140533e74..71c0255665ca36424156fe425fc71fe96b5102ee 100644 --- a/lib/internal/Magento/Framework/App/Response/Http.php +++ b/lib/internal/Magento/Framework/App/Response/Http.php @@ -145,6 +145,18 @@ class Http extends \Zend_Controller_Response_Http implements HttpInterface $this->setHeader('expires', gmdate('D, d M Y H:i:s T', strtotime('-1 year')), true); } + /** + * Represents an HTTP response body in JSON format by sending appropriate header + * + * @param string $content String in JSON format + * @return \Magento\Framework\App\Response\Http + */ + public function representJson($content) + { + $this->setHeader('Content-Type', 'application/json', true); + return $this->setBody($content); + } + /** * @return string[] */ diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php index c1adafc34e5d63a888c371197efcffb50c21081f..690e06708c5c8c9d8d50165dac8feecabfac4df7 100644 --- a/lib/internal/Magento/Framework/AppInterface.php +++ b/lib/internal/Magento/Framework/AppInterface.php @@ -35,7 +35,7 @@ interface AppInterface /** * Magento version */ - const VERSION = '2.0.0.0-dev84'; + const VERSION = '2.0.0.0-dev85'; /** * Launch application