From 909a0e6b4c01c8fe3e6ffcf6d36bbb9df782334e Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Tue, 18 Aug 2015 11:27:15 +0300 Subject: [PATCH 01/26] MAGETWO-41597: Implement new terms and conditions creation flow --- .../Block/Adminhtml/Agreement/Edit/Form.php | 21 +++++++++ .../Model/AgreementModeOptions.php | 26 +++++++++++ .../Setup/UpgradeSchema.php | 45 +++++++++++++++++++ .../Magento/CheckoutAgreements/etc/module.xml | 2 +- 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CheckoutAgreements/Model/AgreementModeOptions.php create mode 100644 app/code/Magento/CheckoutAgreements/Setup/UpgradeSchema.php diff --git a/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit/Form.php b/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit/Form.php index c6cb28ad44859..2fffd98f23062 100644 --- a/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit/Form.php +++ b/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit/Form.php @@ -12,11 +12,17 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic */ protected $_systemStore; + /** + * @var \Magento\CheckoutAgreements\Model\AgreementModeOptions + */ + protected $agreementModeOptions; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Data\FormFactory $formFactory * @param \Magento\Store\Model\System\Store $systemStore + * @param \Magento\CheckoutAgreements\Model\AgreementModeOptions $agreementModeOptions * @param array $data */ public function __construct( @@ -24,9 +30,11 @@ public function __construct( \Magento\Framework\Registry $registry, \Magento\Framework\Data\FormFactory $formFactory, \Magento\Store\Model\System\Store $systemStore, + \Magento\CheckoutAgreements\Model\AgreementModeOptions $agreementModeOptions, array $data = [] ) { $this->_systemStore = $systemStore; + $this->agreementModeOptions = $agreementModeOptions; parent::__construct($context, $registry, $formFactory, $data); } @@ -98,6 +106,19 @@ protected function _prepareForm() ] ); + $fieldset->addField( + 'mode', + 'select', + [ + 'label' => __('Applied'), + 'title' => __('Applied'), + 'name' => 'mode', + 'required' => true, + 'note' => __('Applies to one-page checkout only'), + 'options' => $this->agreementModeOptions->getOptionsArray() + ] + ); + if (!$this->_storeManager->isSingleStoreMode()) { $field = $fieldset->addField( 'store_id', diff --git a/app/code/Magento/CheckoutAgreements/Model/AgreementModeOptions.php b/app/code/Magento/CheckoutAgreements/Model/AgreementModeOptions.php new file mode 100644 index 0000000000000..5b28fb3f9dee4 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementModeOptions.php @@ -0,0 +1,26 @@ + __('Automatically'), + self::MODE_MANUAL => __('Manually') + ]; + } +} diff --git a/app/code/Magento/CheckoutAgreements/Setup/UpgradeSchema.php b/app/code/Magento/CheckoutAgreements/Setup/UpgradeSchema.php new file mode 100644 index 0000000000000..d9e07a5fc25b4 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Setup/UpgradeSchema.php @@ -0,0 +1,45 @@ +getConnection(); + + if (version_compare($context->getVersion(), '2.0.0.1', '<')) { + $column = [ + 'type' => Table::TYPE_SMALLINT, + 'length' => 6, + 'nullable' => false, + 'comment' => 'Applied mode', + 'default' => '0' + ]; + $connection->addColumn($setup->getTable('checkout_agreement'), 'mode', $column); + } + } +} diff --git a/app/code/Magento/CheckoutAgreements/etc/module.xml b/app/code/Magento/CheckoutAgreements/etc/module.xml index 249c7b190e363..a0f9b5f01f299 100644 --- a/app/code/Magento/CheckoutAgreements/etc/module.xml +++ b/app/code/Magento/CheckoutAgreements/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + From f874881f31e35e2158dd6831df77c4d5e5d81400 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Tue, 18 Aug 2015 15:51:00 +0300 Subject: [PATCH 02/26] MAGETWO-41597: Implement new terms and conditions creation flow -- CR fixes --- .../Unit/Model/AgreementModeOptionsTest.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementModeOptionsTest.php diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementModeOptionsTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementModeOptionsTest.php new file mode 100644 index 0000000000000..e4bfcda185449 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementModeOptionsTest.php @@ -0,0 +1,31 @@ +model = $objectManager->getObject('Magento\CheckoutAgreements\Model\AgreementModeOptions'); + } + + public function testGetOptionsArray() + { + $expected = [ + AgreementModeOptions::MODE_AUTO => __('Automatically'), + AgreementModeOptions::MODE_MANUAL => __('Manually') + ];; + $this->assertEquals($expected, $this->model->getOptionsArray()); + } +} From 0f8aed1c173a1c8c7acc88c250cf953c40db3052 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Tue, 18 Aug 2015 16:06:34 +0300 Subject: [PATCH 03/26] MAGETWO-41598: Checkout ui rendering for terms and conditions modes --- .../Api/Data/AgreementInterface.php | 16 ++++++ .../Block/Checkout/LayoutProcessor.php | 55 ------------------ .../CheckoutAgreements/Model/Agreement.php | 16 ++++++ .../Model/AgreementsConfigProvider.php | 40 +++++++++++-- .../Model/Resource/Agreement.php | 13 ++--- .../Model/Resource/Agreement/Collection.php | 14 +++-- .../CheckoutAgreements/etc/frontend/di.xml | 7 --- .../frontend/layout/checkout_index_index.xml | 9 +-- .../frontend/web/js/model/agreements-modal.js | 37 ++++++++++++ .../web/js/view/checkout-agreements-link.js | 24 -------- .../web/js/view/checkout-agreements-modal.js | 56 ------------------ .../web/js/view/checkout-agreements.js | 57 +++++++++++++++++++ .../checkout/checkout-agreements.html | 30 ++++++++++ .../checkout/modal/agreements-modal.html | 15 ----- .../payment/checkout-agreements-link.html | 14 ----- 15 files changed, 205 insertions(+), 198 deletions(-) delete mode 100644 app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js delete mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js delete mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements.js create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html delete mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html delete mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html diff --git a/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php b/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php index 299e027ac248a..5b857daa56e82 100644 --- a/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php +++ b/app/code/Magento/CheckoutAgreements/Api/Data/AgreementInterface.php @@ -17,6 +17,7 @@ interface AgreementInterface extends \Magento\Framework\Api\ExtensibleDataInterf const CHECKBOX_TEXT = 'checkbox_text'; const IS_ACTIVE = 'is_active'; const IS_HTML = 'is_html'; + const MODE = 'mode'; /**#@-*/ /** @@ -129,6 +130,21 @@ public function getIsHtml(); */ public function setIsHtml($isHtml); + /** + * Returns the agreement applied mode. + * + * @return int + */ + public function getMode(); + + /** + * Sets the agreement applied mode. + * + * @param int $mode + * @return $this + */ + public function setMode($mode); + /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php b/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php deleted file mode 100644 index ad8bdfc822cd6..0000000000000 --- a/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php +++ /dev/null @@ -1,55 +0,0 @@ -checkoutAgreementsRepository = $checkoutAgreementsRepository; - $this->escaper = $escaper; - } - - /** - * {@inheritdoc} - */ - public function process($jsLayout) - { - $agreementConfiguration = []; - $agreementsList = $this->checkoutAgreementsRepository->getList(); - - foreach ($agreementsList as $agreement) { - $agreementConfiguration[] = [ - 'content' => $agreement->getIsHtml() - ? $agreement->getContent() - : nl2br($this->escaper->escapeHtml($agreement->getContent())), - 'height' => $agreement->getContentHeight(), - 'checkboxText' => $agreement->getCheckboxText() - ]; - } - $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment'] - ['children']['payments-list']['children']['before-place-order']['children']['checkout-agreements-modal'] - ['config']['agreementConfiguration'] = $agreementConfiguration; - - return $jsLayout; - } -} diff --git a/app/code/Magento/CheckoutAgreements/Model/Agreement.php b/app/code/Magento/CheckoutAgreements/Model/Agreement.php index 74d2fef6b5831..18e996990ec68 100644 --- a/app/code/Magento/CheckoutAgreements/Model/Agreement.php +++ b/app/code/Magento/CheckoutAgreements/Model/Agreement.php @@ -176,6 +176,22 @@ public function setIsHtml($isHtml) return $this->setData(self::IS_HTML, $isHtml); } + /** + * @inheritdoc + */ + public function getMode() + { + return $this->getData(self::MODE); + } + + /** + * @inheritdoc + */ + public function setMode($mode) + { + return $this->setData(self::MODE, $mode); + } + /** * {@inheritdoc} * diff --git a/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php index 4a16c276ce768..12a5c39e1ee16 100644 --- a/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php @@ -6,7 +6,6 @@ namespace Magento\CheckoutAgreements\Model; use Magento\Checkout\Model\ConfigProviderInterface; -use Magento\CheckoutAgreements\Model\AgreementsProvider; use Magento\Store\Model\ScopeInterface; /** @@ -24,16 +23,24 @@ class AgreementsConfigProvider implements ConfigProviderInterface */ protected $checkoutAgreementsRepository; + /** + * @var \Magento\Framework\Escaper + */ + protected $escaper; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration * @param \Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface $checkoutAgreementsRepository + * @param \Magento\Framework\Escaper $escaper */ public function __construct( \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration, - \Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface $checkoutAgreementsRepository + \Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface $checkoutAgreementsRepository, + \Magento\Framework\Escaper $escaper ) { $this->scopeConfiguration = $scopeConfiguration; $this->checkoutAgreementsRepository = $checkoutAgreementsRepository; + $this->escaper = $escaper; } /** @@ -41,14 +48,37 @@ public function __construct( */ public function getConfig() { + $agreements = []; + $agreements['checkoutAgreements'] = $this->getAgreementsConfig(); + return $agreements; + } + + /** + * Returns agreements config + * + * @return array + */ + protected function getAgreementsConfig() + { + $agreementConfiguration = []; $isAgreementsEnabled = $this->scopeConfiguration->isSetFlag( AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE ); - if ($isAgreementsEnabled && count($this->checkoutAgreementsRepository->getList()) > 0) { - return ['checkoutAgreementsEnabled' => true]; + $agreementsList = $this->checkoutAgreementsRepository->getList(); + $agreementConfiguration['isEnabled'] = (bool)($isAgreementsEnabled && count($agreementsList) > 0); + + foreach ($agreementsList as $agreement) { + $agreementConfiguration['agreements'][] = [ + 'content' => $agreement->getIsHtml() + ? $agreement->getContent() + : nl2br($this->escaper->escapeHtml($agreement->getContent())), + 'checkboxText' => $agreement->getCheckboxText(), + 'mode' => $agreement->getMode() + ]; } - return []; + + return $agreementConfiguration; } } diff --git a/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement.php b/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement.php index 2fdbdc6686a19..80b75c5e5348d 100644 --- a/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement.php +++ b/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement.php @@ -3,9 +3,6 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\CheckoutAgreements\Model\Resource; /** @@ -92,12 +89,10 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) */ protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object) { - $select = $this->getConnection()->select()->from( - $this->getTable('checkout_agreement_store'), - ['store_id'] - )->where( - 'agreement_id = :agreement_id' - ); + $select = $this->getConnection() + ->select() + ->from($this->getTable('checkout_agreement_store'), ['store_id']) + ->where('agreement_id = :agreement_id'); if ($stores = $this->getConnection()->fetchCol($select, [':agreement_id' => $object->getId()])) { $object->setData('store_id', $stores); diff --git a/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement/Collection.php b/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement/Collection.php index 163474a2c62d4..3ba768c713530 100644 --- a/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement/Collection.php +++ b/app/code/Magento/CheckoutAgreements/Model/Resource/Agreement/Collection.php @@ -3,9 +3,6 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\CheckoutAgreements\Model\Resource\Agreement; /** @@ -16,7 +13,11 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac /** * @var array */ - protected $_map = ['fields' => ['agreement_id' => 'main_table.agreement_id']]; + protected $_map = [ + 'fields' => [ + 'agreement_id' => 'main_table.agreement_id' + ] + ]; /** * Is store filter with admin store @@ -32,7 +33,10 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac */ protected function _construct() { - $this->_init('Magento\CheckoutAgreements\Model\Agreement', 'Magento\CheckoutAgreements\Model\Resource\Agreement'); + $this->_init( + 'Magento\CheckoutAgreements\Model\Agreement', + 'Magento\CheckoutAgreements\Model\Resource\Agreement' + ); } /** diff --git a/app/code/Magento/CheckoutAgreements/etc/frontend/di.xml b/app/code/Magento/CheckoutAgreements/etc/frontend/di.xml index f3e65ef5a342a..0fcced605585e 100644 --- a/app/code/Magento/CheckoutAgreements/etc/frontend/di.xml +++ b/app/code/Magento/CheckoutAgreements/etc/frontend/di.xml @@ -6,13 +6,6 @@ */ --> - - - - Magento\CheckoutAgreements\Block\Checkout\LayoutProcessor - - - diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml index 5f883201ee2dc..5c1a8612ee77f 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml +++ b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml @@ -22,17 +22,10 @@ - Magento_CheckoutAgreements/js/view/checkout-agreements-link + Magento_CheckoutAgreements/js/view/checkout-agreements before-place-order checkoutAgreements checkoutProvider - - - Magento_CheckoutAgreements/js/view/checkout-agreements-modal - checkoutAgreements - checkoutProvider - - diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js new file mode 100644 index 0000000000000..202da85a7eb47 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js @@ -0,0 +1,37 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +/*jshint browser:true jquery:true*/ +/*global alert*/ +define( + [ + 'jquery', + 'Magento_Ui/js/modal/modal' + ], + function ($, modal) { + 'use strict'; + return { + modalWindow: null, + + /** Create popUp window for provided element */ + createModal: function(element) { + this.modalWindow = element; + var options = { + 'type': 'popup', + 'modalClass': 'agreements-modal', + 'responsive': true, + 'innerScroll': true, + 'trigger': '.show-modal', + 'buttons': [] + }; + modal(options, $(this.modalWindow)); + }, + + /** Show login popup window */ + showModal: function() { + $(this.modalWindow).modal('openModal'); + } + } + } +); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js deleted file mode 100644 index 071602c254c40..0000000000000 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'ko', - 'uiComponent' - ], function (ko, Component) { - 'use strict'; - - return Component.extend({ - defaults: { - template: 'Magento_CheckoutAgreements/checkout/payment/checkout-agreements-link' - }, - isVisible: window.checkoutConfig.checkoutAgreementsEnabled, - /** - * Opens modal window with Terms&Conditions - */ - showAgreements: function () { - this.elems()[0].showAgreements(); - } - }); - } -); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js deleted file mode 100644 index e7762f7ea5b9f..0000000000000 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'ko', - 'uiComponent', - 'Magento_Ui/js/modal/modal' - ], function (ko, Component, modal) { - 'use strict'; - - /** - * Provides an empty div to force load template into. - * @todo MAGETWO-39170 Refactor this as soon as modal component is updated to support ko view models. - * @returns {HTMLElement} - */ - function createTemporayContainer() { - var temporaryDiv = document.createElement('div'); - temporaryDiv.style.display = 'none'; - document.body.appendChild(temporaryDiv); - - return temporaryDiv; - } - - return Component.extend({ - defaults: { - template: 'Magento_CheckoutAgreements/checkout/modal/agreements-modal' - }, - /** - * Initialize view and render it's template to temporary div. This will be refactored as soon as - * modal component is integrated with uiComponent. - * @returns {*} - */ - initialize: function () { - var temporaryContainer = createTemporayContainer(); - - this._super(); - ko.renderTemplate(this.template, this, {}, temporaryContainer); - temporaryContainer.parentNode.removeChild(temporaryContainer); - - return this; - }, - modal: modal({ - responsive: true, - innerScroll: true, - buttons: [] - }), - /** - * Show Terms&Conditions pop-up - */ - showAgreements: function () { - ko.renderTemplate(this.template, this, {}, this.modal.openModal(), 'replaceNode'); - } - }); - } -); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements.js new file mode 100644 index 0000000000000..4f2daa783ae03 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements.js @@ -0,0 +1,57 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define( + [ + 'ko', + 'jquery', + 'uiComponent', + 'Magento_CheckoutAgreements/js/model/agreements-modal' + ], + function (ko, $, Component, agreementsModal) { + 'use strict'; + var agreementsConfig = window.checkoutConfig.checkoutAgreements, + agreementManualMode = 1; + + return Component.extend({ + defaults: { + template: 'Magento_CheckoutAgreements/checkout/checkout-agreements' + }, + isVisible: agreementsConfig.isEnabled, + agreements: agreementsConfig.agreements, + modalTitle: ko.observable(null), + modalContent: ko.observable(null), + modalWindow: null, + + /** + * Checks if agreement required + * + * @param element + */ + isAgreementRequired: function(element) { + return element.mode == agreementManualMode; + }, + + /** + * Show agreement content in modal + * + * @param element + */ + showContent: function (element) { + this.modalTitle(element.checkboxText); + this.modalContent(element.content); + agreementsModal.showModal(); + }, + + /** + * Init modal window for rendered element + * + * @param element + */ + initModal: function(element) { + agreementsModal.createModal(element); + } + }); + } +); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html new file mode 100644 index 0000000000000..0285a538ebe6e --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -0,0 +1,30 @@ + +
+ + + + + + + + +
+ + +
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html deleted file mode 100644 index 0129cab3aebd3..0000000000000 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html +++ /dev/null @@ -1,15 +0,0 @@ - -
    - -
  1. -
    -
    -
  2. - -
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html deleted file mode 100644 index 364d060893812..0000000000000 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html +++ /dev/null @@ -1,14 +0,0 @@ - - -
- - - -
From 04cb334834194d0d8d98294e8d62bed6f85058e1 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Wed, 19 Aug 2015 13:49:21 +0300 Subject: [PATCH 04/26] MAGETWO-41598: Checkout ui rendering for terms and conditions modes --- .../authorizenet-directpost.js | 7 +- .../payment/authorizenet-directpost.html | 44 ++- .../web/template/payment/cc-form.html | 299 +++++++++--------- .../frontend/layout/checkout_index_index.xml | 11 +- .../js/model/payment/additional-validators.js | 51 +++ .../frontend/web/js/view/payment/default.js | 8 +- .../Model/AgreementsConfigProvider.php | 3 +- .../frontend/layout/checkout_index_index.xml | 7 + .../web/js/model/agreement-validator.js | 27 ++ .../frontend/web/js/model/agreements-modal.js | 15 +- .../web/js/view/agreement-validation.js | 16 + .../checkout/checkout-agreements.html | 54 ++-- .../template/payment/purchaseorder-form.html | 74 +++-- .../method-renderer/payflowpro-method.js | 7 +- .../paypal-express-abstract.js | 15 +- .../web/template/payment/payflowpro-form.html | 43 ++- .../paypal_billing_agreement-form.html | 30 +- 17 files changed, 423 insertions(+), 288 deletions(-) create mode 100644 app/code/Magento/Checkout/view/frontend/web/js/model/payment/additional-validators.js create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/agreement-validation.js diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js index 5e56746fbe50a..d163053292a0c 100644 --- a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js +++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js @@ -8,9 +8,10 @@ define( [ 'jquery', 'Magento_Payment/js/view/payment/iframe', - 'Magento_Checkout/js/action/set-payment-information' + 'Magento_Checkout/js/action/set-payment-information', + 'Magento_Checkout/js/model/payment/additional-validators' ], - function ($, Component, setPaymentInformationAction) { + function ($, Component, setPaymentInformationAction, additionalValidators) { 'use strict'; return Component.extend({ defaults: { @@ -45,7 +46,7 @@ define( placeOrder: function() { var self = this; - if (this.validateHandler()) { + if (this.validateHandler() && additionalValidators.validate()) { this.isPlaceOrderActionAllowed(false); $.when(setPaymentInformationAction()).done(function() { self.placeOrderHandler(); diff --git a/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html b/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html index 170de87cfd767..a053754095c61 100644 --- a/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html +++ b/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html @@ -40,31 +40,29 @@ 'cardFieldsMap': getCardFieldsMap(), 'nativeAction': getSaveOrderUrl() }, 'validation':[]}"> - + +
+ + + +
-
- - - -
- -
-
- -
+
+
+
- +
diff --git a/app/code/Magento/Braintree/view/frontend/web/template/payment/cc-form.html b/app/code/Magento/Braintree/view/frontend/web/template/payment/cc-form.html index 748133c319757..d50a5a3ec7c83 100644 --- a/app/code/Magento/Braintree/view/frontend/web/template/payment/cc-form.html +++ b/app/code/Magento/Braintree/view/frontend/web/template/payment/cc-form.html @@ -33,168 +33,168 @@ 'controller': getControllerName(), 'orderSaveUrl':getPlaceOrderUrl(), }, 'validation':[]}"> - -
- -
- - -
- -
- +
+ +
+ + +
+ +
+ +
-
-
 
- -
- -
- - - - -
    - -
  • - - +
     
    + +
    + +
    + + + + +
      + +
    • + + + +
    • - - -
    - - +
+ + +
-
-
- -
- +
+ +
+ +
-
-
- -
-
-
-
- +
+ +
+
+
+
+ +
-
-
-
- +
+
+ +
-
- -
- -
- -
- - - -
+ +
+ +
+ +
+ + + +
+
-
- - -
- -
- -
- -
+ + +
@@ -217,7 +217,6 @@
- \ No newline at end of file diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml index be5917f36ba62..b66d2d212eddd 100644 --- a/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml +++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml @@ -249,6 +249,12 @@ + + uiComponent + + + + Magento_Checkout/js/view/form/element/email customer-email @@ -291,7 +297,10 @@ Magento_Checkout/js/view/payment/list payment-methods-list - checkout.steps.billing-step.payment.renders + + checkout.steps.billing-step.payment.renders + checkout.steps.billing-step.payment.additional-payment-validators + diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/payment/additional-validators.js b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/additional-validators.js new file mode 100644 index 0000000000000..faad780f672ce --- /dev/null +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/additional-validators.js @@ -0,0 +1,51 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define( + [], + function() { + 'use strict'; + var validators = []; + return { + /** + * Register unique validator + * + * @param validator + */ + registerValidator: function(validator) { + validators.push(validator); + }, + + /** + * Returns array of registered validators + * + * @returns {Array} + */ + getValidators: function() { + return validators; + }, + + /** + * Process validators + * + * @returns {boolean} + */ + validate: function() { + var validationResult = true; + + if (validators.length <= 0) { + return validationResult; + } + + validators.forEach(function(item) { + if (item.validate() == false) { + validationResult = false; + return false; + } + }); + return validationResult; + } + }; + } +); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js index 972114b197300..3d909fa36aa14 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js @@ -14,7 +14,8 @@ define( 'Magento_Checkout/js/model/payment-service', 'Magento_Checkout/js/checkout-data', 'Magento_Checkout/js/model/checkout-data-resolver', - 'uiRegistry' + 'uiRegistry', + 'Magento_Checkout/js/model/payment/additional-validators' ], function ( ko, @@ -27,7 +28,8 @@ define( paymentService, checkoutData, checkoutDataResolver, - registry + registry, + additionalValidators ) { 'use strict'; return Component.extend({ @@ -97,7 +99,7 @@ define( $(loginFormSelector).validation(); emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid()); } - if (emailValidationResult && this.validate()) { + if (emailValidationResult && this.validate() && additionalValidators.validate()) { this.isPlaceOrderActionAllowed(false); placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder); diff --git a/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php index 12a5c39e1ee16..5538ec8865c85 100644 --- a/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsConfigProvider.php @@ -75,7 +75,8 @@ protected function getAgreementsConfig() ? $agreement->getContent() : nl2br($this->escaper->escapeHtml($agreement->getContent())), 'checkboxText' => $agreement->getCheckboxText(), - 'mode' => $agreement->getMode() + 'mode' => $agreement->getMode(), + 'agreementId' => $agreement->getAgreementId() ]; } diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml index 5c1a8612ee77f..ccf040f301602 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml +++ b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_index_index.xml @@ -29,6 +29,13 @@ + + + + Magento_CheckoutAgreements/js/view/agreement-validation + + + diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js new file mode 100644 index 0000000000000..91f6c83309b78 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js @@ -0,0 +1,27 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +/*jshint browser:true jquery:true*/ +/*global alert*/ +define( + [ + 'jquery', + 'mage/validation' + ], + function ($) { + 'use strict'; + return { + /** + * Validate checkout agreements + * + * @returns {boolean} + */ + validate: function() { + var form = $('.payment-method._active form[data-role=checkout-agreements]'); + form.validation(); + return form.validation('isValid'); + } + } + } +); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js index 202da85a7eb47..7fa26779ac0e2 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreements-modal.js @@ -7,9 +7,10 @@ define( [ 'jquery', - 'Magento_Ui/js/modal/modal' + 'Magento_Ui/js/modal/modal', + 'mage/translate' ], - function ($, modal) { + function ($, modal, $t) { 'use strict'; return { modalWindow: null, @@ -23,7 +24,15 @@ define( 'responsive': true, 'innerScroll': true, 'trigger': '.show-modal', - 'buttons': [] + 'buttons': [ + { + text: $t('Close'), + class: 'action secondary action-hide-popup', + click: function() { + this.closeModal(); + } + } + ] }; modal(options, $(this.modalWindow)); }, diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/agreement-validation.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/agreement-validation.js new file mode 100644 index 0000000000000..32e784b22b940 --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/agreement-validation.js @@ -0,0 +1,16 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define( + [ + 'uiComponent', + 'Magento_Checkout/js/model/payment/additional-validators', + 'Magento_CheckoutAgreements/js/model/agreement-validator' + ], + function (Component, additionalValidators, agreementValidator) { + 'use strict'; + additionalValidators.registerValidator(agreementValidator); + return Component.extend({}); + } +); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html index 0285a538ebe6e..8025c6867b099 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -4,27 +4,37 @@ * See COPYING.txt for license details. */ --> -
- - - - +
+
+ + +
+ + +
+ + +
+ +
+ - - - -
- - -
+
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html index 8154a87b26b98..4504a235f58bb 100644 --- a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html +++ b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html @@ -5,25 +5,23 @@ */ -->
-
+
+ + +
-
- - +
+
+ + +
- -
-
- - - -
- +
-
- - - -
-
-
- -
-
+ +
+ + + +
+
+
+ +
- +
\ No newline at end of file diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js index 81c41a741acb3..52c57e090c8b0 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js @@ -5,9 +5,10 @@ /*global define*/ define( [ - 'Magento_Payment/js/view/payment/iframe' + 'Magento_Payment/js/view/payment/iframe', + 'Magento_Checkout/js/model/payment/additional-validators' ], - function (Component) { + function (Component, additionalValidators) { 'use strict'; return Component.extend({ @@ -42,7 +43,7 @@ define( }, placeOrder: function() { - if (this.validateHandler()) { + if (this.validateHandler() && additionalValidators.validate()) { this.placeOrderHandler(); } } diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-abstract.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-abstract.js index f54caba0730c8..f3e75d46f2f3b 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-abstract.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-abstract.js @@ -8,9 +8,10 @@ define( [ 'jquery', 'Magento_Checkout/js/view/payment/default', - 'Magento_Paypal/js/action/set-payment-method' + 'Magento_Paypal/js/action/set-payment-method', + 'Magento_Checkout/js/model/payment/additional-validators' ], - function ($, Component, setPaymentMethodAction) { + function ($, Component, setPaymentMethodAction, additionalValidators) { 'use strict'; return Component.extend({ @@ -69,10 +70,12 @@ define( /** Redirect to paypal */ continueToPayPal: function () { - //update payment method information if additional data was changed - this.selectPaymentMethod(); - setPaymentMethodAction(); - return false; + if (additionalValidators.validate()) { + //update payment method information if additional data was changed + this.selectPaymentMethod(); + setPaymentMethodAction(); + return false; + } } }); } diff --git a/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html b/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html index df3fad1c4980e..8c986e7c1acc1 100644 --- a/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html +++ b/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html @@ -42,28 +42,27 @@ }, 'validation':[]}"> - -
- - - -
-
-
- -
-
+
+ + + +
+
+
+ +
+
diff --git a/app/code/Magento/Paypal/view/frontend/web/template/payment/paypal_billing_agreement-form.html b/app/code/Magento/Paypal/view/frontend/web/template/payment/paypal_billing_agreement-form.html index 724bd43648359..774c5d7ae9a1c 100644 --- a/app/code/Magento/Paypal/view/frontend/web/template/payment/paypal_billing_agreement-form.html +++ b/app/code/Magento/Paypal/view/frontend/web/template/payment/paypal_billing_agreement-form.html @@ -5,7 +5,6 @@ */ -->
-
-
- - - -
- - - + +
+ + + +
+ +
@@ -47,5 +52,4 @@
- From 00edc5ee6c03b5c2164742e11558fc60b66a6b9b Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Wed, 19 Aug 2015 17:54:28 +0300 Subject: [PATCH 05/26] MAGETWO-41596: Support terms and conditions validation on server side --- .../Checkout/Controller/Onepage/SaveOrder.php | 2 +- .../Model/AgreementsProvider.php | 1 - .../Model}/AgreementsProviderInterface.php | 2 +- .../Model}/AgreementsValidator.php | 2 +- .../Block/Checkout/LayoutProcessorTest.php | 102 ------------------ .../Unit/Model}/AgreementsValidatorTest.php | 11 +- .../Magento/CheckoutAgreements/etc/di.xml | 2 +- .../Controller/Checkout/OverviewPost.php | 2 +- .../Express/AbstractExpress/PlaceOrder.php | 2 +- .../Controller/Express/PlaceOrderTest.php | 2 +- .../Quote/Api/CartManagementInterface.php | 3 +- .../Api/GuestCartManagementInterface.php | 22 +--- .../Model/GuestCart/GuestCartManagement.php | 25 +---- .../Magento/Quote/Model/QuoteManagement.php | 12 +-- .../Test/Unit/Model/QuoteManagementTest.php | 16 +-- 15 files changed, 19 insertions(+), 187 deletions(-) rename app/code/Magento/{Checkout/Model/Agreements => CheckoutAgreements/Model}/AgreementsProviderInterface.php (88%) rename app/code/Magento/{Checkout/Model/Agreements => CheckoutAgreements/Model}/AgreementsValidator.php (95%) delete mode 100644 app/code/Magento/CheckoutAgreements/Test/Unit/Block/Checkout/LayoutProcessorTest.php rename app/code/Magento/{Checkout/Test/Unit/Model/Agreements => CheckoutAgreements/Test/Unit/Model}/AgreementsValidatorTest.php (82%) diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php index 5b6c8ca719aa4..6cc1a82963f5d 100644 --- a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php +++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php @@ -33,7 +33,7 @@ public function execute() $result = new DataObject(); try { - $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator'); + $agreementsValidator = $this->_objectManager->get('Magento\CheckoutAgreements\Model\AgreementsValidator'); if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) { $result->setData('success', false); $result->setData('error', true); diff --git a/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php index 43831218a53f1..b1fe46b8bd0f5 100644 --- a/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php @@ -5,7 +5,6 @@ */ namespace Magento\CheckoutAgreements\Model; -use Magento\Checkout\Model\Agreements\AgreementsProviderInterface; use Magento\Store\Model\ScopeInterface; /** diff --git a/app/code/Magento/Checkout/Model/Agreements/AgreementsProviderInterface.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsProviderInterface.php similarity index 88% rename from app/code/Magento/Checkout/Model/Agreements/AgreementsProviderInterface.php rename to app/code/Magento/CheckoutAgreements/Model/AgreementsProviderInterface.php index 89e96e0dc32d7..ef08ea2b930fc 100644 --- a/app/code/Magento/Checkout/Model/Agreements/AgreementsProviderInterface.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsProviderInterface.php @@ -3,7 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Checkout\Model\Agreements; +namespace Magento\CheckoutAgreements\Model; /** * Interface AgreementsProviderInterface diff --git a/app/code/Magento/Checkout/Model/Agreements/AgreementsValidator.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsValidator.php similarity index 95% rename from app/code/Magento/Checkout/Model/Agreements/AgreementsValidator.php rename to app/code/Magento/CheckoutAgreements/Model/AgreementsValidator.php index 42a8559260496..833cf6807b376 100644 --- a/app/code/Magento/Checkout/Model/Agreements/AgreementsValidator.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsValidator.php @@ -3,7 +3,7 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Checkout\Model\Agreements; +namespace Magento\CheckoutAgreements\Model; /** * Class AgreementsValidator diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Block/Checkout/LayoutProcessorTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Block/Checkout/LayoutProcessorTest.php deleted file mode 100644 index ba9f975139523..0000000000000 --- a/app/code/Magento/CheckoutAgreements/Test/Unit/Block/Checkout/LayoutProcessorTest.php +++ /dev/null @@ -1,102 +0,0 @@ -escaperMock = $this->getMock('\Magento\Framework\Escaper', [], [], '', false); - $this->agreementsRepositoryMock = $this->getMock( - '\Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface' - ); - - $this->model = $objectManager->getObject( - 'Magento\CheckoutAgreements\Block\Checkout\LayoutProcessor', - [ - 'escaper' => $this->escaperMock, - 'checkoutAgreementsRepository' => $this->agreementsRepositoryMock - ] - ); - } - - public function testProcessIfAgreementWithHtml() - { - $agreementData = [ - 'content' => 'content', - 'height' => '100', - 'checkboxText' => 'checkbox_text' - ]; - - $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment'] - ['children']['payments-list']['children']['before-place-order']['children']['checkout-agreements-modal'] - ['config']['agreementConfiguration'] = null; - - $expectedResult = $jsLayout; - $expectedResult['components']['checkout']['children']['steps']['children']['billing-step']['children'] - ['payment']['children']['payments-list']['children']['before-place-order']['children'] - ['checkout-agreements-modal']['config']['agreementConfiguration'][] = $agreementData; - - $agreementMock = $this->getMock('\Magento\CheckoutAgreements\Api\Data\AgreementInterface'); - $this->agreementsRepositoryMock->expects($this->once())->method('getList')->willReturn([$agreementMock]); - - $agreementMock->expects($this->once())->method('getIsHtml')->willReturn(true); - $agreementMock->expects($this->once())->method('getContent')->willReturn($agreementData['content']); - $agreementMock->expects($this->once())->method('getContentHeight')->willReturn($agreementData['height']); - $agreementMock->expects($this->once())->method('getCheckboxText')->willReturn($agreementData['checkboxText']); - - $this->assertEquals($expectedResult, $this->model->process($jsLayout)); - } - - public function testProcessIfAgreementRichText() - { - $agreementData = [ - 'content' => 'content', - 'height' => '100', - 'checkboxText' => 'checkbox_text' - ]; - - $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment'] - ['children']['payments-list']['children']['before-place-order']['children']['checkout-agreements-modal'] - ['config']['agreementConfiguration'] = null; - - $expectedResult = $jsLayout; - $expectedResult['components']['checkout']['children']['steps']['children']['billing-step']['children'] - ['payment']['children']['payments-list']['children']['before-place-order']['children'] - ['checkout-agreements-modal']['config']['agreementConfiguration'][] = $agreementData; - - $agreementMock = $this->getMock('\Magento\CheckoutAgreements\Api\Data\AgreementInterface'); - $this->agreementsRepositoryMock->expects($this->once())->method('getList')->willReturn([$agreementMock]); - - $this->escaperMock->expects($this->once())->method('escapeHtml') - ->with($agreementData['content']) - ->willReturn($agreementData['content']); - - $agreementMock->expects($this->once())->method('getIsHtml')->willReturn(false); - $agreementMock->expects($this->once())->method('getContent')->willReturn($agreementData['content']); - $agreementMock->expects($this->once())->method('getContentHeight')->willReturn($agreementData['height']); - $agreementMock->expects($this->once())->method('getCheckboxText')->willReturn($agreementData['checkboxText']); - - $this->assertEquals($expectedResult, $this->model->process($jsLayout)); - } -} diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Agreements/AgreementsValidatorTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsValidatorTest.php similarity index 82% rename from app/code/Magento/Checkout/Test/Unit/Model/Agreements/AgreementsValidatorTest.php rename to app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsValidatorTest.php index adec3e0c108ea..3eaaff3e539de 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/Agreements/AgreementsValidatorTest.php +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsValidatorTest.php @@ -3,10 +3,9 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Checkout\Test\Unit\Model\Agreements; - -use \Magento\Checkout\Model\Agreements\AgreementsValidator; +namespace Magento\CheckoutAgreements\Test\Unit\Model; +use Magento\CheckoutAgreements\Model\AgreementsValidator; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; class AgreementsValidatorTest extends \PHPUnit_Framework_TestCase @@ -41,7 +40,7 @@ public static function isValidDataProvider() public function testIsValid($data, $result) { $this->object = $this->objectManagerHelper->getObject( - 'Magento\Checkout\Model\Agreements\AgreementsValidator', + 'Magento\CheckoutAgreements\Model\AgreementsValidator', [] ); $this->assertEquals($result, $this->object->isValid($data)); @@ -69,13 +68,13 @@ public static function notIsValidDataProvider() */ public function testNotIsValid($data, $result) { - $provider = $this->getMockForAbstractClass('Magento\Checkout\Model\Agreements\AgreementsProviderInterface'); + $provider = $this->getMockForAbstractClass('\Magento\CheckoutAgreements\Model\AgreementsProviderInterface'); $provider->expects($this->once()) ->method('getRequiredAgreementIds') ->will($this->returnValue([1, 3, '4'])); $this->object = $this->objectManagerHelper->getObject( - 'Magento\Checkout\Model\Agreements\AgreementsValidator', + 'Magento\CheckoutAgreements\Model\AgreementsValidator', ['list' => [$provider]] ); $this->assertEquals($result, $this->object->isValid($data)); diff --git a/app/code/Magento/CheckoutAgreements/etc/di.xml b/app/code/Magento/CheckoutAgreements/etc/di.xml index 7469363193cb0..9bc9088e7d417 100644 --- a/app/code/Magento/CheckoutAgreements/etc/di.xml +++ b/app/code/Magento/CheckoutAgreements/etc/di.xml @@ -8,7 +8,7 @@ - + \Magento\CheckoutAgreements\Model\AgreementsProvider diff --git a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php index 8ab82a3d18a8e..137cc4fb6d5ea 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php @@ -68,7 +68,7 @@ public function execute() } try { - $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator'); + $agreementsValidator = $this->_objectManager->get('Magento\CheckoutAgreements\Model\AgreementsValidator'); if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) { $this->messageManager->addError( __('Please agree to all Terms and Conditions before placing the order.') diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php index 44cd56531af46..3f2c1d13acdb3 100644 --- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php +++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php @@ -19,7 +19,7 @@ class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress public function execute() { try { - $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator'); + $agreementsValidator = $this->_objectManager->get('Magento\CheckoutAgreements\Model\AgreementsValidator'); if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) { throw new \Magento\Framework\Exception\LocalizedException( __('Please agree to all the terms and conditions before placing the order.') diff --git a/app/code/Magento/Paypal/Test/Unit/Controller/Express/PlaceOrderTest.php b/app/code/Magento/Paypal/Test/Unit/Controller/Express/PlaceOrderTest.php index 5d1b82c55c509..314da0ad65216 100644 --- a/app/code/Magento/Paypal/Test/Unit/Controller/Express/PlaceOrderTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Controller/Express/PlaceOrderTest.php @@ -55,7 +55,7 @@ public function testExecuteProcessableException($code, $paymentAction = null) $oldCallback = &$this->objectManagerCallback; $this->objectManagerCallback = function ($className) use ($code, $oldCallback) { $instance = call_user_func($oldCallback, $className); - if ($className == 'Magento\Checkout\Model\Agreements\AgreementsValidator') { + if ($className == '\Magento\CheckoutAgreements\Model\AgreementsValidator') { $exception = $this->getMock( 'Magento\Paypal\Model\Api\ProcessableException', ['getUserMessage'], diff --git a/app/code/Magento/Quote/Api/CartManagementInterface.php b/app/code/Magento/Quote/Api/CartManagementInterface.php index 8828c66cacd74..a855004f7ccd8 100644 --- a/app/code/Magento/Quote/Api/CartManagementInterface.php +++ b/app/code/Magento/Quote/Api/CartManagementInterface.php @@ -58,10 +58,9 @@ public function assignCustomer($cartId, $customerId, $storeId); * Places an order for a specified cart. * * @param int $cartId The cart ID. - * @param int[]|null $agreements * @param PaymentInterface|null $paymentMethod * @throws \Magento\Framework\Exception\CouldNotSaveException * @return int Order ID. */ - public function placeOrder($cartId, $agreements = null, PaymentInterface $paymentMethod = null); + public function placeOrder($cartId, PaymentInterface $paymentMethod = null); } diff --git a/app/code/Magento/Quote/Api/GuestCartManagementInterface.php b/app/code/Magento/Quote/Api/GuestCartManagementInterface.php index 2ad5112ede8f0..5e82c4d532948 100644 --- a/app/code/Magento/Quote/Api/GuestCartManagementInterface.php +++ b/app/code/Magento/Quote/Api/GuestCartManagementInterface.php @@ -35,29 +35,9 @@ public function assignCustomer($cartId, $customerId, $storeId); * Place an order for a specified cart. * * @param string $cartId The cart ID. - * @param int[]|null $agreements * @param PaymentInterface|null $paymentMethod * @throws \Magento\Framework\Exception\CouldNotSaveException * @return int Order ID. */ - public function placeOrder($cartId, $agreements = null, PaymentInterface $paymentMethod = null); - - /** - * Registers a customer and places an order for the specified cart. - * - * @param string $cartId The cart ID. - * @param \Magento\Customer\Api\Data\CustomerInterface $customer - * @param string $password - * @param int[]|null $agreements - * @param PaymentInterface|null $paymentMethod - * @throws \Magento\Framework\Exception\CouldNotSaveException - * @return int Order ID. - */ - public function placeOrderCreatingAccount( - $cartId, - $customer, - $password, - $agreements = null, - PaymentInterface $paymentMethod = null - ); + public function placeOrder($cartId, PaymentInterface $paymentMethod = null); } diff --git a/app/code/Magento/Quote/Model/GuestCart/GuestCartManagement.php b/app/code/Magento/Quote/Model/GuestCart/GuestCartManagement.php index e64d5745d2b0c..231eda4e2da5d 100644 --- a/app/code/Magento/Quote/Model/GuestCart/GuestCartManagement.php +++ b/app/code/Magento/Quote/Model/GuestCart/GuestCartManagement.php @@ -78,33 +78,12 @@ public function assignCustomer($cartId, $customerId, $storeId) /** * {@inheritdoc} */ - public function placeOrder($cartId, $agreements = null, PaymentInterface $paymentMethod = null) + public function placeOrder($cartId, PaymentInterface $paymentMethod = null) { /** @var $quoteIdMask QuoteIdMask */ $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id'); $this->cartRepository->get($quoteIdMask->getQuoteId()) ->setCheckoutMethod(CartManagementInterface::METHOD_GUEST); - return $this->quoteManagement->placeOrder($quoteIdMask->getQuoteId(), $agreements, $paymentMethod); - } - - /** - * {@inheritdoc} - */ - public function placeOrderCreatingAccount( - $cartId, - $customer, - $password, - $agreements = null, - PaymentInterface $paymentMethod = null - ) { - /** @var $quoteIdMask QuoteIdMask */ - $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id'); - return $this->quoteManagement->placeOrderCreatingAccount( - $quoteIdMask->getQuoteId(), - $customer, - $password, - $agreements, - $paymentMethod - ); + return $this->quoteManagement->placeOrder($quoteIdMask->getQuoteId(), $paymentMethod); } } diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index ca139a975035c..cd128bc13d214 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -119,11 +119,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface */ protected $accountManagement; - /** - * @var \Magento\Checkout\Model\Agreements\AgreementsValidator $agreementsValidator - */ - protected $agreementsValidator; - /** * @param EventManager $eventManager * @param QuoteValidator $quoteValidator @@ -143,7 +138,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Api\AccountManagementInterface $accountManagement - * @param \Magento\Checkout\Model\Agreements\AgreementsValidator $agreementsValidator * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -164,8 +158,7 @@ public function __construct( StoreManagerInterface $storeManager, \Magento\Checkout\Model\Session $checkoutSession, \Magento\Customer\Model\Session $customerSession, - \Magento\Customer\Api\AccountManagementInterface $accountManagement, - \Magento\Checkout\Model\Agreements\AgreementsValidator $agreementsValidator + \Magento\Customer\Api\AccountManagementInterface $accountManagement ) { $this->eventManager = $eventManager; $this->quoteValidator = $quoteValidator; @@ -185,7 +178,6 @@ public function __construct( $this->checkoutSession = $checkoutSession; $this->accountManagement = $accountManagement; $this->customerSession = $customerSession; - $this->agreementsValidator = $agreementsValidator; } /** @@ -296,7 +288,7 @@ protected function createCustomerCart($customerId, $storeId) /** * {@inheritdoc} */ - public function placeOrder($cartId, $agreements = null, PaymentInterface $paymentMethod = null) + public function placeOrder($cartId, PaymentInterface $paymentMethod = null) { $quote = $this->quoteRepository->getActive($cartId); if ($paymentMethod) { diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php index b6a44c587386f..b316ad767ad7d 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php @@ -117,11 +117,6 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase */ protected $quoteMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $agreementsValidatorMock; - /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -224,13 +219,6 @@ protected function setUp() '', false ); - $this->agreementsValidatorMock = $this->getMock( - '\Magento\Checkout\Model\Agreements\AgreementsValidator', - [], - [], - '', - false - ); $this->model = $objectManager->getObject( 'Magento\Quote\Model\QuoteManagement', @@ -698,7 +686,6 @@ public function testPlaceOrderIfCustomerIsGuest() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'agreementsValidator' => $this->agreementsValidatorMock, ] ); $orderMock = $this->getMock( @@ -755,7 +742,6 @@ public function testPlaceOrder() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'agreementsValidator' => $this->agreementsValidatorMock, ] ); $orderMock = $this->getMock( @@ -805,7 +791,7 @@ public function testPlaceOrder() $paymentMethod->expects($this->once())->method('setChecks'); $paymentMethod->expects($this->once())->method('getData')->willReturn(['additional_data' => []]); - $this->assertEquals($orderId, $service->placeOrder($cartId, null, $paymentMethod)); + $this->assertEquals($orderId, $service->placeOrder($cartId, $paymentMethod)); } /** From 1b44f89c54cedd90367b1184a19e3868e84b8931 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov Date: Thu, 20 Aug 2015 17:27:53 +0300 Subject: [PATCH 06/26] MAGETWO-41596: Support terms and conditions validation on server side --- .../Model/AgreementsProvider.php | 1 + .../Model/Checkout/Plugin/Validation.php | 71 ++++++++++++ .../Model/AgreementsConfigProviderTest.php | 101 +++++++++++++----- .../Unit/Model/AgreementsProviderTest.php | 7 +- .../Model/Checkout/Plugin/ValidationTest.php | 89 +++++++++++++++ .../Magento/CheckoutAgreements/etc/di.xml | 4 +- .../etc/extension_attributes.xml | 13 +++ .../view/frontend/requirejs-config.js | 15 +++ .../web/js/model/agreement-validator.js | 5 + .../web/js/model/place-order-mixin.js | 33 ++++++ .../checkout/checkout-agreements.html | 6 +- 11 files changed, 317 insertions(+), 28 deletions(-) create mode 100644 app/code/Magento/CheckoutAgreements/Model/Checkout/Plugin/Validation.php create mode 100644 app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php create mode 100644 app/code/Magento/CheckoutAgreements/etc/extension_attributes.xml create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/requirejs-config.js create mode 100644 app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/place-order-mixin.js diff --git a/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php b/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php index b1fe46b8bd0f5..f5be0c9e2e2a1 100644 --- a/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php +++ b/app/code/Magento/CheckoutAgreements/Model/AgreementsProvider.php @@ -59,6 +59,7 @@ public function getRequiredAgreementIds() $agreementCollection = $this->agreementCollectionFactory->create(); $agreementCollection->addStoreFilter($this->storeManager->getStore()->getId()); $agreementCollection->addFieldToFilter('is_active', 1); + $agreementCollection->addFieldToFilter('mode', AgreementModeOptions::MODE_MANUAL); $agreementIds = $agreementCollection->getAllIds(); } return $agreementIds; diff --git a/app/code/Magento/CheckoutAgreements/Model/Checkout/Plugin/Validation.php b/app/code/Magento/CheckoutAgreements/Model/Checkout/Plugin/Validation.php new file mode 100644 index 0000000000000..7dfd0c37d630f --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Model/Checkout/Plugin/Validation.php @@ -0,0 +1,71 @@ +agreementsValidator = $agreementsValidator; + } + + /** + * @param \Magento\Checkout\Api\PaymentInformationManagementInterface $subject + * @param $cartId + * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod + * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeSavePaymentInformationAndPlaceOrder( + \Magento\Checkout\Api\PaymentInformationManagementInterface $subject, + $cartId, + \Magento\Quote\Api\Data\PaymentInterface $paymentMethod, + \Magento\Quote\Api\Data\AddressInterface $billingAddress + ) { + $this->validateAgreements($paymentMethod->getExtensionAttributes()->getAgreementIds()); + } + + /** + * @param \Magento\Checkout\Api\PaymentInformationManagementInterface $subject + * @param $cartId + * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod + * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeSavePaymentInformation( + \Magento\Checkout\Api\PaymentInformationManagementInterface $subject, + $cartId, + \Magento\Quote\Api\Data\PaymentInterface $paymentMethod, + \Magento\Quote\Api\Data\AddressInterface $billingAddress + ) { + $this->validateAgreements($paymentMethod->getExtensionAttributes()->getAgreementIds()); + } + + /** + * @param $agreements + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @return void + */ + protected function validateAgreements($agreements) + { + if (!$this->agreementsValidator->isValid($agreements)) { + throw new \Magento\Framework\Exception\CouldNotSaveException( + __('Please agree to all the terms and conditions before placing the order.') + ); + } + } +} diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsConfigProviderTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsConfigProviderTest.php index dc331b8f5adbf..7ece62e8f502e 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsConfigProviderTest.php +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsConfigProviderTest.php @@ -25,10 +25,13 @@ class AgreementsConfigProviderTest extends \PHPUnit_Framework_TestCase */ protected $agreementsRepositoryMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $escaperMock; + protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->scopeConfigMock = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface'); $this->agreementsRepositoryMock = $this->getMock( '\Magento\CheckoutAgreements\Api\CheckoutAgreementsRepositoryInterface', @@ -37,40 +40,88 @@ protected function setUp() '', false ); - $this->model = $objectManager->getObject( - 'Magento\CheckoutAgreements\Model\AgreementsConfigProvider', - [ - 'scopeConfiguration' => $this->scopeConfigMock, - 'checkoutAgreementsRepository' => $this->agreementsRepositoryMock - ] + $this->escaperMock = $this->getMock('\Magento\Framework\Escaper', [], [], '', false); + + $this->model = new \Magento\CheckoutAgreements\Model\AgreementsConfigProvider( + $this->scopeConfigMock, + $this->agreementsRepositoryMock, + $this->escaperMock ); } - /** - * @dataProvider getConfigDataProvider - * @param bool $isAgreementsEnabled - * @param array $agreements - * @param array $expectedResult - */ - public function testGetConfig($isAgreementsEnabled, $agreements, $expectedResult) + public function testGetConfigIfContentIsHtml() { + $content = 'content'; + $checkboxText = 'checkbox_text'; + $mode = \Magento\CheckoutAgreements\Model\AgreementModeOptions::MODE_AUTO; + $agreementId = 100; + $expectedResult = [ + 'checkoutAgreements' => [ + 'isEnabled' => 1, + 'agreements' => [ + [ + 'content' => $content, + 'checkboxText' => $checkboxText, + 'mode' => $mode, + 'agreementId' => $agreementId + ] + ] + ] + ]; + $this->scopeConfigMock->expects($this->once()) ->method('isSetFlag') ->with(AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE) - ->willReturn($isAgreementsEnabled); - $this->agreementsRepositoryMock->expects($this->any())->method('getList')->willReturn($agreements); + ->willReturn(true); + + $agreement = $this->getMock('\Magento\CheckoutAgreements\Api\Data\AgreementInterface'); + $this->agreementsRepositoryMock->expects($this->any())->method('getList')->willReturn([$agreement]); + + $agreement->expects($this->once())->method('getIsHtml')->willReturn(true); + $agreement->expects($this->once())->method('getContent')->willReturn($content); + $agreement->expects($this->once())->method('getCheckboxText')->willReturn($checkboxText); + $agreement->expects($this->once())->method('getMode')->willReturn($mode); + $agreement->expects($this->once())->method('getAgreementId')->willReturn($agreementId); + $this->assertEquals($expectedResult, $this->model->getConfig()); } - /** - * @return array - */ - public function getConfigDataProvider() + public function testGetConfigIfContentIsNotHtml() { - return [ - [true, ['agreement'], ['checkoutAgreementsEnabled' => true]], - [true, [], []], - [false, [], []] + $content = 'content'; + $escapedContent = 'escaped_content'; + $checkboxText = 'checkbox_text'; + $mode = \Magento\CheckoutAgreements\Model\AgreementModeOptions::MODE_AUTO; + $agreementId = 100; + $expectedResult = [ + 'checkoutAgreements' => [ + 'isEnabled' => 1, + 'agreements' => [ + [ + 'content' => $escapedContent, + 'checkboxText' => $checkboxText, + 'mode' => $mode, + 'agreementId' => $agreementId + ] + ] + ] ]; + + $this->scopeConfigMock->expects($this->once()) + ->method('isSetFlag') + ->with(AgreementsProvider::PATH_ENABLED, ScopeInterface::SCOPE_STORE) + ->willReturn(true); + + $agreement = $this->getMock('\Magento\CheckoutAgreements\Api\Data\AgreementInterface'); + $this->agreementsRepositoryMock->expects($this->any())->method('getList')->willReturn([$agreement]); + $this->escaperMock->expects($this->once())->method('escapeHtml')->with($content)->willReturn($escapedContent); + + $agreement->expects($this->once())->method('getIsHtml')->willReturn(false); + $agreement->expects($this->once())->method('getContent')->willReturn($content); + $agreement->expects($this->once())->method('getCheckboxText')->willReturn($checkboxText); + $agreement->expects($this->once())->method('getMode')->willReturn($mode); + $agreement->expects($this->once())->method('getAgreementId')->willReturn($agreementId); + + $this->assertEquals($expectedResult, $this->model->getConfig()); } } diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsProviderTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsProviderTest.php index 7334f4024a3f4..da0d0d82372ff 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsProviderTest.php +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/AgreementsProviderTest.php @@ -7,6 +7,7 @@ use Magento\Store\Model\ScopeInterface; use Magento\CheckoutAgreements\Model\AgreementsProvider; +use Magento\CheckoutAgreements\Model\AgreementModeOptions; class AgreementsProviderTest extends \PHPUnit_Framework_TestCase { @@ -77,10 +78,14 @@ public function testGetRequiredAgreementIdsIfAgreementsEnabled() $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock); $agreementCollection->expects($this->once())->method('addStoreFilter')->with($storeId)->willReturnSelf(); - $agreementCollection->expects($this->once()) + $agreementCollection->expects($this->at(1)) ->method('addFieldToFilter') ->with('is_active', 1) ->willReturnSelf(); + $agreementCollection->expects($this->at(2)) + ->method('addFieldToFilter') + ->with('mode', AgreementModeOptions::MODE_MANUAL) + ->willReturnSelf(); $agreementCollection->expects($this->once())->method('getAllIds')->willReturn($expectedResult); $this->assertEquals($expectedResult, $this->model->getRequiredAgreementIds()); diff --git a/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php new file mode 100644 index 0000000000000..f4f601d0ff5dd --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/Test/Unit/Model/Checkout/Plugin/ValidationTest.php @@ -0,0 +1,89 @@ +agreementsValidatorMock = $this->getMock( + '\Magento\CheckoutAgreements\Model\AgreementsValidator', + [], + [], + '', + false + ); + $this->model = new \Magento\CheckoutAgreements\Model\Checkout\Plugin\Validation( + $this->agreementsValidatorMock + ); + } + + public function testBeforeSavePaymentInformationAndPlaceOrder() + { + $cartId = 100; + $agreements = [1, 2, 3]; + $subjectMock = $this->getMock('\Magento\Checkout\Api\PaymentInformationManagementInterface'); + $paymentMock = $this->getMock('\Magento\Quote\Api\Data\PaymentInterface'); + $addressMock = $this->getMock('\Magento\Quote\Api\Data\AddressInterface'); + + $extensionAttributesMock = $this->getMock('\Magento\Quote\Api\Data\PaymentExtensionInterface'); + $extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements); + + $this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(true); + $paymentMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock); + + $this->model->beforeSavePaymentInformation($subjectMock, $cartId, $paymentMock, $addressMock); + } + + /** + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + * @expectedExceptionMessage Please agree to all the terms and conditions before placing the order. + */ + public function testBeforeSavePaymentInformationAndPlaceOrderIfAgreementsNotValid() + { + $cartId = 100; + $agreements = [1, 2, 3]; + $subjectMock = $this->getMock('\Magento\Checkout\Api\PaymentInformationManagementInterface'); + $paymentMock = $this->getMock('\Magento\Quote\Api\Data\PaymentInterface'); + $addressMock = $this->getMock('\Magento\Quote\Api\Data\AddressInterface'); + + $extensionAttributesMock = $this->getMock('\Magento\Quote\Api\Data\PaymentExtensionInterface'); + $extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements); + + $this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(false); + $paymentMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock); + + $this->model->beforeSavePaymentInformation($subjectMock, $cartId, $paymentMock, $addressMock); + } + + public function testBeforeSavePaymentInformation() + { + $cartId = 100; + $agreements = [1, 2, 3]; + + $extensionAttributesMock = $this->getMock('\Magento\Quote\Api\Data\PaymentExtensionInterface'); + $extensionAttributesMock->expects($this->once())->method('getAgreementIds')->willReturn($agreements); + + $subjectMock = $this->getMock('\Magento\Checkout\Api\PaymentInformationManagementInterface'); + $paymentMock = $this->getMock('\Magento\Quote\Api\Data\PaymentInterface'); + $addressMock = $this->getMock('\Magento\Quote\Api\Data\AddressInterface'); + + $this->agreementsValidatorMock->expects($this->once())->method('isValid')->with($agreements)->willReturn(true); + $paymentMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock); + + $this->model->beforeSavePaymentInformation($subjectMock, $cartId, $paymentMock, $addressMock); + } +} diff --git a/app/code/Magento/CheckoutAgreements/etc/di.xml b/app/code/Magento/CheckoutAgreements/etc/di.xml index 9bc9088e7d417..29566ec36db49 100644 --- a/app/code/Magento/CheckoutAgreements/etc/di.xml +++ b/app/code/Magento/CheckoutAgreements/etc/di.xml @@ -15,5 +15,7 @@ - + + + diff --git a/app/code/Magento/CheckoutAgreements/etc/extension_attributes.xml b/app/code/Magento/CheckoutAgreements/etc/extension_attributes.xml new file mode 100644 index 0000000000000..b6ae8360a260d --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/etc/extension_attributes.xml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/requirejs-config.js b/app/code/Magento/CheckoutAgreements/view/frontend/requirejs-config.js new file mode 100644 index 0000000000000..6d01efb6483ee --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/requirejs-config.js @@ -0,0 +1,15 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +/*jshint browser:true jquery:true*/ +/*global alert*/ +var config = { + config: { + mixins: { + 'Magento_Checkout/js/action/place-order': { + 'Magento_CheckoutAgreements/js/model/place-order-mixin': true + } + } + } +}; diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js index 91f6c83309b78..2ccbc0f43f70d 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/agreement-validator.js @@ -11,6 +11,7 @@ define( ], function ($) { 'use strict'; + var agreementsConfig = window.checkoutConfig.checkoutAgreements; return { /** * Validate checkout agreements @@ -18,6 +19,10 @@ define( * @returns {boolean} */ validate: function() { + if (!agreementsConfig.isEnabled) { + return true; + } + var form = $('.payment-method._active form[data-role=checkout-agreements]'); form.validation(); return form.validation('isValid'); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/place-order-mixin.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/place-order-mixin.js new file mode 100644 index 0000000000000..5407b96e2182d --- /dev/null +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/model/place-order-mixin.js @@ -0,0 +1,33 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +/*jshint browser:true jquery:true*/ +/*global alert*/ +define([ + 'jquery', + 'mage/utils/super' /** TODO: rename this dependency to 'mage/utils/wrapper' after Vanilla PR will merged */ +], function ($, wrapper) { + 'use strict'; + var agreementsConfig = window.checkoutConfig.checkoutAgreements; + + return function (placeOrderAction) { + /** Override default place order action and add agreement_ids to request */ + return wrapper.wrap(placeOrderAction, function(originalAction, paymentData, redirectOnSuccess) { + if (!agreementsConfig.isEnabled) { + return originalAction(paymentData, redirectOnSuccess); + } + + var agreementForm = $('.payment-method._active form[data-role=checkout-agreements]'), + agreementData = agreementForm.serializeArray(), + agreementIds = []; + + agreementData.forEach(function(item) { + agreementIds.push(item.value); + }); + + paymentData.extension_attributes = {agreement_ids: agreementIds}; + return originalAction(paymentData, redirectOnSuccess); + }); + }; +}); diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html index 8025c6867b099..3f0429aa0fca3 100644 --- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html +++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html @@ -10,7 +10,11 @@