diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php index 3d73a5f0c205a..fae9903a845e1 100644 --- a/app/code/Magento/Checkout/Controller/Cart/Delete.php +++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php @@ -15,6 +15,10 @@ class Delete extends \Magento\Checkout\Controller\Cart */ public function execute() { + if (!$this->_formKeyValidator->validate($this->getRequest())) { + return $this->resultRedirectFactory->create()->setPath('*/*/'); + } + $id = (int)$this->getRequest()->getParam('id'); if ($id) { try { diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php index 2b512d5e30783..c23f79a3192c0 100644 --- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php +++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php @@ -265,6 +265,7 @@ public function getConfig() $output['isCustomerLoginRequired'] = $this->isCustomerLoginRequired(); $output['registerUrl'] = $this->getRegisterUrl(); $output['checkoutUrl'] = $this->getCheckoutUrl(); + $output['defaultSuccessPageUrl'] = $this->getDefaultSuccessPageUrl(); $output['pageNotFoundUrl'] = $this->pageNotFoundUrl(); $output['forgotPasswordUrl'] = $this->getForgotPasswordUrl(); $output['staticBaseUrl'] = $this->getStaticBaseUrl(); @@ -451,6 +452,17 @@ public function pageNotFoundUrl() return $this->urlBuilder->getUrl('checkout/noroute'); } + /** + * Retrieve default success page URL + * + * @return string + * @codeCoverageIgnore + */ + public function getDefaultSuccessPageUrl() + { + return $this->urlBuilder->getUrl('checkout/onepage/success/'); + } + /** * Retrieve selected shipping method * diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml index 39393518e7942..3015e63108993 100644 --- a/app/code/Magento/Checkout/etc/adminhtml/system.xml +++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml @@ -21,13 +21,6 @@ Magento\Config\Model\Config\Source\Yesno - - - Magento\Config\Model\Config\Source\Yesno - - 0 - - 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 5a459eed8af1b..8ddcc09f5efe3 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 @@ -41,7 +41,7 @@ Magento_Checkout/js/view/authentication authentication - + 0 Magento_Checkout/js/view/authentication-messages @@ -167,7 +167,7 @@ - + uiComponent before-shipping-method-form @@ -184,7 +184,7 @@ additional-fieldsets - + false @@ -310,6 +310,17 @@ checkout.steps.billing-step.payment.additional-payment-validators + + + uiComponent + before-place-order + before-place-order + checkoutProvider + + Magento_Checkout/payment/before-place-order + + + @@ -433,4 +444,4 @@ - + \ No newline at end of file diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml index 6ccdd1531ba37..dd4b81e3820b8 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml @@ -14,11 +14,11 @@ data-bind="scope: 'minicart_content'"> - + data-bind="css: { empty: !!getCartParam('summary_count') == false }, blockLoader: isLoading"> + - - + + diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js index e7dba81e18180..ad3ea77c0866e 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js @@ -7,9 +7,10 @@ define( [ 'Magento_Checkout/js/model/address-converter' ], - function(addressConverter) { - "use strict"; - return function(addressData) { + function (addressConverter) { + 'use strict'; + + return function (addressData) { return addressConverter.formAddressDataToQuoteAddress(addressData); }; } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js b/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js index 413065db54b2d..d600adf12d119 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js @@ -14,20 +14,27 @@ define( 'Magento_Checkout/js/model/totals' ], function ($, quote, resourceUrlManager, errorProcessor, storage, totals) { - "use strict"; + 'use strict'; + return function (callbacks, deferred) { deferred = deferred || $.Deferred(); totals.isLoading(true); + return storage.get( resourceUrlManager.getUrlForCartTotals(quote), false ).done( function (response) { - totals.isLoading(false); var proceed = true; - $.each(callbacks, function(index, callback) { - proceed = proceed && callback(); - }); + + totals.isLoading(false); + + if (callbacks.length > 0) { + $.each(callbacks, function (index, callback) { + proceed = proceed && callback(); + }); + } + if (proceed) { quote.setTotals(response); deferred.resolve(); @@ -47,4 +54,4 @@ define( }; } -); +); \ No newline at end of file diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js b/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js index 7e477c3b0a72a..f0c0bcce05fce 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js @@ -7,20 +7,17 @@ define( 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/url-builder', 'mage/storage', - 'mage/url', 'Magento_Checkout/js/model/error-processor', 'Magento_Customer/js/model/customer', 'Magento_Checkout/js/model/full-screen-loader' ], - function (quote, urlBuilder, storage, url, errorProcessor, customer, fullScreenLoader) { + function (quote, urlBuilder, storage, errorProcessor, customer, fullScreenLoader) { 'use strict'; - return function (paymentData, redirectOnSuccess, messageContainer) { + return function (paymentData, messageContainer) { var serviceUrl, payload; - redirectOnSuccess = redirectOnSuccess !== false; - /** Checkout for guest and registered customer. */ if (!customer.isLoggedIn()) { serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', { @@ -45,12 +42,6 @@ define( return storage.post( serviceUrl, JSON.stringify(payload) - ).done( - function () { - if (redirectOnSuccess) { - window.location.replace(url.build('checkout/onepage/success/')); - } - } ).fail( function (response) { errorProcessor.process(response, messageContainer); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/redirect-on-success.js b/app/code/Magento/Checkout/view/frontend/web/js/action/redirect-on-success.js new file mode 100644 index 0000000000000..e1411843d1db6 --- /dev/null +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/redirect-on-success.js @@ -0,0 +1,23 @@ +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define( + [ + 'mage/url' + ], + function (url) { + 'use strict'; + + return { + redirectUrl: window.checkoutConfig.defaultSuccessPageUrl, + + /** + * Provide redirect to page + */ + execute: function () { + window.location.replace(url.build(this.redirectUrl)); + } + }; + } +); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js index 79f6c5cb77d1f..cdb75877d2271 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js @@ -16,7 +16,7 @@ define( if (quote.shippingAddress() && billingAddress.getCacheKey() == quote.shippingAddress().getCacheKey()) { address = $.extend({}, billingAddress); - address.saveInAddressBook = false; + address.saveInAddressBook = null; } else { address = billingAddress; } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js index 101e3e6e74a9f..989d778eb6732 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/checkout-data-resolver.js @@ -7,182 +7,235 @@ /** * Checkout adapter for customer data storage */ -define([ - 'Magento_Customer/js/model/address-list', - 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/checkout-data', - 'Magento_Checkout/js/action/create-shipping-address', - 'Magento_Checkout/js/action/select-shipping-address', - 'Magento_Checkout/js/action/select-shipping-method', - 'Magento_Checkout/js/model/payment-service', - 'Magento_Checkout/js/action/select-payment-method', - 'Magento_Checkout/js/model/address-converter', - 'Magento_Checkout/js/action/select-billing-address', - 'Magento_Checkout/js/action/create-billing-address', - 'underscore' -], function ( - addressList, - quote, - checkoutData, - createShippingAddress, - selectShippingAddress, - selectShippingMethodAction, - paymentService, - selectPaymentMethodAction, - addressConverter, - selectBillingAddress, - createBillingAddress, - _ -) { - 'use strict'; - - return { - resolveEstimationAddress: function () { - if (checkoutData.getShippingAddressFromData()) { - var address = addressConverter.formAddressDataToQuoteAddress(checkoutData.getShippingAddressFromData()); - selectShippingAddress(address); - } else { - this.resolveShippingAddress(); - } - if (quote.isVirtual()) { - if (checkoutData.getBillingAddressFromData()) { - address = addressConverter.formAddressDataToQuoteAddress(checkoutData.getBillingAddressFromData()); - selectBillingAddress(address); - } else { - this.resolveBillingAddress(); - } - } +define( + [ + 'Magento_Customer/js/model/address-list', + 'Magento_Checkout/js/model/quote', + 'Magento_Checkout/js/checkout-data', + 'Magento_Checkout/js/action/create-shipping-address', + 'Magento_Checkout/js/action/select-shipping-address', + 'Magento_Checkout/js/action/select-shipping-method', + 'Magento_Checkout/js/model/payment-service', + 'Magento_Checkout/js/action/select-payment-method', + 'Magento_Checkout/js/model/address-converter', + 'Magento_Checkout/js/action/select-billing-address', + 'Magento_Checkout/js/action/create-billing-address', + 'underscore' + ], + function ( + addressList, + quote, + checkoutData, + createShippingAddress, + selectShippingAddress, + selectShippingMethodAction, + paymentService, + selectPaymentMethodAction, + addressConverter, + selectBillingAddress, + createBillingAddress, + _ + ) { + 'use strict'; - }, + return { - resolveShippingAddress: function () { - var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); - if (newCustomerShippingAddress) { - createShippingAddress(newCustomerShippingAddress); - } - this.applyShippingAddress(); - }, + /** + * Resolve estimation address. Used local storage + */ + resolveEstimationAddress: function () { + var address; - applyShippingAddress: function (isEstimatedAddress) { - if (addressList().length == 0) { - var address = addressConverter.formAddressDataToQuoteAddress(checkoutData.getShippingAddressFromData()); - selectShippingAddress(address); - } - var shippingAddress = quote.shippingAddress(), - isConvertAddress = isEstimatedAddress || false, - addressData; - if (!shippingAddress) { - var isShippingAddressInitialized = addressList.some(function (address) { - if (checkoutData.getSelectedShippingAddress() == address.getKey()) { - addressData = isConvertAddress - ? addressConverter.addressToEstimationAddress(address) - : address; - selectShippingAddress(addressData); - return true; + if (checkoutData.getShippingAddressFromData()) { + address = addressConverter.formAddressDataToQuoteAddress(checkoutData.getShippingAddressFromData()); + selectShippingAddress(address); + } else { + this.resolveShippingAddress(); + } + + if (quote.isVirtual()) { + if (checkoutData.getBillingAddressFromData()) { + address = addressConverter.formAddressDataToQuoteAddress( + checkoutData.getBillingAddressFromData() + ); + selectBillingAddress(address); + } else { + this.resolveBillingAddress(); } - return false; - }); - - if (!isShippingAddressInitialized) { - isShippingAddressInitialized = addressList.some(function (address) { - if (address.isDefaultShipping()) { - addressData = isConvertAddress - ? addressConverter.addressToEstimationAddress(address) - : address; + } + + }, + + /** + * Resolve shipping address. Used local storage + */ + resolveShippingAddress: function () { + var newCustomerShippingAddress = checkoutData.getNewCustomerShippingAddress(); + + if (newCustomerShippingAddress) { + createShippingAddress(newCustomerShippingAddress); + } + this.applyShippingAddress(); + }, + + /** + * Apply resolved estimated address to quote + * + * @param {Object} isEstimatedAddress + */ + applyShippingAddress: function (isEstimatedAddress) { + var address, + shippingAddress, + isConvertAddress, + addressData, + isShippingAddressInitialized; + + if (addressList().length == 0) { + address = addressConverter.formAddressDataToQuoteAddress( + checkoutData.getShippingAddressFromData() + ); + selectShippingAddress(address); + } + shippingAddress = quote.shippingAddress(); + isConvertAddress = isEstimatedAddress || false; + + if (!shippingAddress) { + isShippingAddressInitialized = addressList.some(function (addressFromList) { + if (checkoutData.getSelectedShippingAddress() == addressFromList.getKey()) { + addressData = isConvertAddress ? + addressConverter.addressToEstimationAddress(addressFromList) + : addressFromList; selectShippingAddress(addressData); + return true; } + return false; }); + + if (!isShippingAddressInitialized) { + isShippingAddressInitialized = addressList.some(function (address) { + if (address.isDefaultShipping()) { + addressData = isConvertAddress ? + addressConverter.addressToEstimationAddress(address) + : address; + selectShippingAddress(addressData); + + return true; + } + + return false; + }); + } + + if (!isShippingAddressInitialized && addressList().length == 1) { + addressData = isConvertAddress ? + addressConverter.addressToEstimationAddress(addressList()[0]) + : addressList()[0]; + selectShippingAddress(addressData); + } + } + }, + + /** + * @param {Object} ratesData + */ + resolveShippingRates: function (ratesData) { + var selectedShippingRate = checkoutData.getSelectedShippingRate(), + availableRate = false; + + if (ratesData.length == 1) { + //set shipping rate if we have only one available shipping rate + selectShippingMethodAction(ratesData[0]); + + return; + } + + if (quote.shippingMethod()) { + availableRate = _.find(ratesData, function (rate) { + return rate.carrier_code == quote.shippingMethod().carrier_code && + rate.method_code == quote.shippingMethod().method_code; + }); } - if (!isShippingAddressInitialized && addressList().length == 1) { - addressData = isConvertAddress - ? addressConverter.addressToEstimationAddress(addressList()[0]) - : addressList()[0]; - selectShippingAddress(addressData); + + if (!availableRate && selectedShippingRate) { + availableRate = _.find(ratesData, function (rate) { + return rate.carrier_code + '_' + rate.method_code === selectedShippingRate; + }); } - } - }, - resolveShippingRates: function (ratesData) { - var selectedShippingRate = checkoutData.getSelectedShippingRate(); - var availableRate = false; + if (!availableRate && window.checkoutConfig.selectedShippingMethod) { + availableRate = true; + selectShippingMethodAction(window.checkoutConfig.selectedShippingMethod); + } - if (ratesData.length == 1) { - //set shipping rate if we have only one available shipping rate - selectShippingMethodAction(ratesData[0]); - return; - } + //Unset selected shipping method if not available + if (!availableRate) { + selectShippingMethodAction(null); + } else { + selectShippingMethodAction(availableRate); + } + }, - if (quote.shippingMethod()) { - availableRate = _.find(ratesData, function (rate) { - return rate.carrier_code == quote.shippingMethod().carrier_code - && rate.method_code == quote.shippingMethod().method_code; - }); - } + /** + * Resolve payment method. Used local storage + */ + resolvePaymentMethod: function () { + var availablePaymentMethods = paymentService.getAvailablePaymentMethods(), + selectedPaymentMethod = checkoutData.getSelectedPaymentMethod(); - if (!availableRate && selectedShippingRate) { - availableRate = _.find(ratesData, function (rate) { - return rate.carrier_code + "_" + rate.method_code === selectedShippingRate; - }); - } + if (selectedPaymentMethod) { + availablePaymentMethods.some(function (payment) { + if (payment.method == selectedPaymentMethod) { + selectPaymentMethodAction(payment); + } + }); + } + }, - if (!availableRate && window.checkoutConfig.selectedShippingMethod) { - availableRate = true; - selectShippingMethodAction(window.checkoutConfig.selectedShippingMethod); - } + /** + * Resolve billing address. Used local storage + */ + resolveBillingAddress: function () { + var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), + newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(); - //Unset selected shipping method if not available - if (!availableRate) { - selectShippingMethodAction(null); - } else { - selectShippingMethodAction(availableRate); - } - }, - - resolvePaymentMethod: function () { - var availablePaymentMethods = paymentService.getAvailablePaymentMethods(); - var selectedPaymentMethod = checkoutData.getSelectedPaymentMethod(); - if (selectedPaymentMethod) { - availablePaymentMethods.some(function (payment) { - if (payment.method == selectedPaymentMethod) { - selectPaymentMethodAction(payment); + if (selectedBillingAddress) { + if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { + selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); + } else { + addressList.some(function (address) { + if (selectedBillingAddress == address.getKey()) { + selectBillingAddress(address); + } + }); } - }); - } - }, + } else { + this.applyBillingAddress(); + } + }, + + /** + * Apply resolved billing address to quote + */ + applyBillingAddress: function () { + var shippingAddress; - resolveBillingAddress: function () { - var selectedBillingAddress = checkoutData.getSelectedBillingAddress(), - newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress(), + if (quote.billingAddress()) { + selectBillingAddress(quote.billingAddress()); + + return; + } shippingAddress = quote.shippingAddress(); - if (selectedBillingAddress) { - if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { - selectBillingAddress(createBillingAddress(newCustomerBillingAddressData)); - } else { - addressList.some(function (address) { - if (selectedBillingAddress == address.getKey()) { - selectBillingAddress(address); - } - }); + if (shippingAddress && + shippingAddress.canUseForBilling() && + (shippingAddress.isDefaultShipping() || !quote.isVirtual()) + ) { + //set billing address same as shipping by default if it is not empty + selectBillingAddress(quote.shippingAddress()); } - } else { - this.applyBillingAddress() - } - }, - applyBillingAddress: function () { - if (quote.billingAddress()) { - selectBillingAddress(quote.billingAddress()); - return; - } - var shippingAddress = quote.shippingAddress(); - if (shippingAddress - && shippingAddress.canUseForBilling() - && (shippingAddress.isDefaultShipping() || !quote.isVirtual())) { - //set billing address same as shipping by default if it is not empty - selectBillingAddress(quote.shippingAddress()); } - } + }; } -}); +); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js index baa9c4b5ee54c..225742ef5c6df 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js @@ -10,23 +10,26 @@ define( 'Magento_Checkout/js/model/shipping-rate-processor/new-address', 'Magento_Checkout/js/model/shipping-rate-processor/customer-address' ], - function(quote, defaultProcessor, customerAddressProcessor) { - "use strict"; + function (quote, defaultProcessor, customerAddressProcessor) { + 'use strict'; + var processors = []; - processors['default'] = defaultProcessor; + + processors.default = defaultProcessor; processors['customer-address'] = customerAddressProcessor; quote.shippingAddress.subscribe(function () { var type = quote.shippingAddress().getType(); + if (processors[type]) { processors[type].getRates(quote.shippingAddress()); } else { - processors['default'].getRates(quote.shippingAddress()); + processors.default.getRates(quote.shippingAddress()); } }); return { - registerProcessor: function(type, processor) { + registerProcessor: function (type, processor) { processors[type] = processor; } } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js index e6eafeee848e5..170b29a9157d7 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js @@ -6,28 +6,32 @@ define( ['jquery'], function ($) { - "use strict"; - var ratesRules = {}; - var checkoutConfig = window.checkoutConfig; + 'use strict'; + + var ratesRules = {}, + checkoutConfig = window.checkoutConfig; + return { - registerRules: function(carrier, rules) { - if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) { + registerRules: function (carrier, rules) { + if (checkoutConfig.activeCarriers.indexOf(carrier) !== -1) { ratesRules[carrier] = rules.getRules(); } }, - getRules: function() { + getRules: function () { return ratesRules; }, - getObservableFields: function() { - var self = this; - var observableFields = []; - $.each(self.getRules(), function(carrier, fields) { - $.each(fields, function(field, rules) { - if (observableFields.indexOf(field) == -1) { + getObservableFields: function () { + var self = this, + observableFields = []; + + $.each(self.getRules(), function (carrier, fields) { + $.each(fields, function (field, rules) { + if (observableFields.indexOf(field) === -1) { observableFields.push(field); } }); }); + return observableFields; } }; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index 732f328ff7274..e28caf4706727 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -55,7 +55,7 @@ define( observableFields = shippingRatesValidationRules.getObservableFields(); $.each(elements, function (index, elem) { - if (elem && (observableFields.indexOf(elem.index) != -1 || force)) { + if (elem && (observableFields.indexOf(elem.index) !== -1 || force)) { if (elem.index !== 'postcode') { self.bindHandler(elem, delay); } @@ -75,9 +75,9 @@ define( bindHandler: function (element, delay) { var self = this; - delay = typeof delay === "undefined" ? self.validateDelay : delay; + delay = typeof delay === 'undefined' ? self.validateDelay : delay; - if (element.component.indexOf('/group') != -1) { + if (element.component.indexOf('/group') !== -1) { $.each(element.elems(), function (index, elem) { self.bindHandler(elem); }); @@ -110,6 +110,7 @@ define( if (!validationResult) { warnMessage = $t('Provided Zip/Postal Code seems to be invalid.'); + if (postcodeValidator.validatedPostCodeExample.length) { warnMessage += $t(' Example: ') + postcodeValidator.validatedPostCodeExample.join('; ') + '. '; } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 0b3290b3c3960..f98f921b31863 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -46,8 +46,9 @@ define( }, countryData = customerData.get('directory-data'), addressOptions = addressList().filter(function (address) { - return address.getType() == 'customer-address'; - }); + return address.getType() == 'customer-address'; + }); + addressOptions.push(newAddressOption); return Component.extend({ @@ -93,6 +94,8 @@ define( if (newAddress != null && newAddress.saveInAddressBook !== undefined) { this.saveInAddressBook(newAddress.saveInAddressBook); + } else { + this.saveInAddressBook(true); } this.isAddressDetailsVisible(true); }, this); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/estimation.js b/app/code/Magento/Checkout/view/frontend/web/js/view/estimation.js index f1f92feb37ad7..8b5ba4a8ac1ac 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/estimation.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/estimation.js @@ -12,21 +12,24 @@ define( ], function (Component, quote, priceUtils, totals, sidebarModel) { 'use strict'; + return Component.extend({ isLoading: totals.isLoading, - getQuantity: function() { + getQuantity: function () { if (totals.totals()) { - return parseFloat(totals.totals().items_qty); + return parseFloat(totals.totals()['items_qty']); } + return 0; }, - getPureValue: function() { + getPureValue: function () { if (totals.totals()) { return parseFloat(totals.getSegment('grand_total').value); } + return 0; }, - showSidebar: function() { + showSidebar: function () { sidebarModel.show(); }, getFormattedPrice: function (price) { diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js index 80da3cf1d6f68..5c43608d9e191 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js @@ -125,7 +125,7 @@ define([ loginForm.validation(); - if (focused === false) { + if (focused === false && !!this.email()) { return !!$(usernameSelector).valid(); } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 91d5d285a12c4..27b652d712813 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -7,8 +7,9 @@ define([ 'Magento_Customer/js/customer-data', 'jquery', 'ko', + 'underscore', 'sidebar' -], function (Component, customerData, $, ko) { +], function (Component, customerData, $, ko, _) { 'use strict'; var sidebarInitialized = false; @@ -69,20 +70,29 @@ define([ return Component.extend({ shoppingCartUrl: window.checkout.shoppingCartUrl, + cart: {}, + + /** + * @override + */ initialize: function () { - var self = this; - this._super(); - this.cart = customerData.get('cart'); - this.cart.subscribe(function () { + var self = this, + cartData = customerData.get('cart'); + + this.update(cartData()); + cartData.subscribe(function (updatedCart) { addToCartCalls--; this.isLoading(addToCartCalls > 0); sidebarInitialized = false; + this.update(updatedCart); initSidebar(); }, this); $('[data-block="minicart"]').on('contentLoading', function(event) { addToCartCalls++; self.isLoading(true); }); + + return this._super(); }, isLoading: ko.observable(false), initSidebar: initSidebar, @@ -96,6 +106,36 @@ define([ }, getItemRenderer: function (productType) { return this.itemRenderer[productType] || 'defaultRenderer'; + }, + + /** + * Update mini shopping cart content. + * + * @param {Object} updatedCart + * @returns void + */ + update: function (updatedCart) { + _.each(updatedCart, function (value, key) { + if (!this.cart.hasOwnProperty(key)) { + this.cart[key] = ko.observable(); + } + this.cart[key](value); + }, this); + }, + + /** + * Get cart param by name. + * @param {String} name + * @returns {*} + */ + getCartParam: function (name) { + if (!_.isUndefined(name)) { + if (!this.cart.hasOwnProperty(name)) { + this.cart[name] = ko.observable(); + } + } + + return this.cart[name](); } }); }); 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 4d80012fd1ffe..0d98eb3d6c149 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 @@ -17,7 +17,8 @@ define( 'uiRegistry', 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Ui/js/model/messages', - 'uiLayout' + 'uiLayout', + 'Magento_Checkout/js/action/redirect-on-success' ], function ( ko, @@ -33,46 +34,56 @@ define( registry, additionalValidators, Messages, - layout + layout, + redirectOnSuccessAction ) { 'use strict'; + return Component.extend({ redirectAfterPlaceOrder: true, + isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null), + /** * After place order callback */ afterPlaceOrder: function () { - // + // Override this function and put after place order logic here }, - isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null), + /** * Initialize view. * - * @returns {Component} Chainable. + * @return {exports} */ initialize: function () { + var billingAddressCode, + billingAddressData, + defaultAddressData; + this._super().initChildren(); - quote.billingAddress.subscribe(function(address) { - this.isPlaceOrderActionAllowed((address !== null)); + quote.billingAddress.subscribe(function (address) { + this.isPlaceOrderActionAllowed(address !== null); }, this); checkoutDataResolver.resolveBillingAddress(); - var billingAddressCode = 'billingAddress' + this.getCode(); + billingAddressCode = 'billingAddress' + this.getCode(); registry.async('checkoutProvider')(function (checkoutProvider) { - var defaultAddressData = checkoutProvider.get(billingAddressCode); + defaultAddressData = checkoutProvider.get(billingAddressCode); + if (defaultAddressData === undefined) { - // skip if payment does not have a billing address form + // Skip if payment does not have a billing address form return; } - var billingAddressData = checkoutData.getBillingAddressFromData(); + billingAddressData = checkoutData.getBillingAddressFromData(); + if (billingAddressData) { checkoutProvider.set( billingAddressCode, - $.extend({}, defaultAddressData, billingAddressData) + $.extend(true, {}, defaultAddressData, billingAddressData) ); } - checkoutProvider.on(billingAddressCode, function (billingAddressData) { - checkoutData.setBillingAddressFromData(billingAddressData); + checkoutProvider.on(billingAddressCode, function (providerBillingAddressData) { + checkoutData.setBillingAddressFromData(providerBillingAddressData); }, billingAddressCode); }); @@ -117,8 +128,7 @@ define( * Place order. */ placeOrder: function (data, event) { - var self = this, - placeOrder; + var self = this; if (event) { event.preventDefault(); @@ -126,19 +136,36 @@ define( if (this.validate() && additionalValidators.validate()) { this.isPlaceOrderActionAllowed(false); - placeOrder = placeOrderAction(this.getData(), this.redirectAfterPlaceOrder, this.messageContainer); - $.when(placeOrder).fail(function () { - self.isPlaceOrderActionAllowed(true); - }).done(this.afterPlaceOrder.bind(this)); + $.when( + placeOrderAction(this.getData(), this.messageContainer) + ).fail( + function () { + self.isPlaceOrderActionAllowed(true); + } + ).done( + function () { + self.afterPlaceOrder(); + + if (self.redirectAfterPlaceOrder) { + redirectOnSuccessAction.execute(); + } + } + ); + return true; } + return false; }, - selectPaymentMethod: function() { + /** + * @return {Boolean} + */ + selectPaymentMethod: function () { selectPaymentMethodAction(this.getData()); checkoutData.setSelectedPaymentMethod(this.item.method); + return true; }, @@ -153,11 +180,11 @@ define( /** * Get payment method data */ - getData: function() { + getData: function () { return { - "method": this.item.method, - "po_number": null, - "additional_data": null + 'method': this.item.method, + 'po_number': null, + 'additional_data': null }; }, @@ -175,17 +202,27 @@ define( return this.item.method; }, + /** + * @return {Boolean} + */ validate: function () { return true; }, - getBillingAddressFormName: function() { + /** + * @return {String} + */ + getBillingAddressFormName: function () { return 'billing-address-form-' + this.item.method; }, + /** + * Dispose billing address subscriptions + */ disposeSubscriptions: function () { // dispose all active subscriptions var billingAddressCode = 'billingAddress' + this.getCode(); + registry.async('checkoutProvider')(function (checkoutProvider) { checkoutProvider.off(billingAddressCode); }); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index e650f6269c910..6c8c87275fc5b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -6,7 +6,7 @@ define( [ 'jquery', - "underscore", + 'underscore', 'Magento_Ui/js/form/form', 'ko', 'Magento_Customer/js/model/customer', @@ -29,7 +29,7 @@ define( 'mage/translate', 'Magento_Checkout/js/model/shipping-rate-service' ], - function( + function ( $, _, Component, @@ -54,7 +54,9 @@ define( $t ) { 'use strict'; + var popUp = null; + return Component.extend({ defaults: { template: 'Magento_Checkout/shipping' @@ -68,9 +70,15 @@ define( saveInAddressBook: true, quoteIsVirtual: quote.isVirtual(), + /** + * @return {exports} + */ initialize: function () { - var self = this; + var self = this, + hasNewAddress; + this._super(); + if (!quote.isVirtual()) { stepNavigator.registerStep( 'shipping', @@ -82,7 +90,7 @@ define( } checkoutDataResolver.resolveShippingAddress(); - var hasNewAddress = addressList.some(function (address) { + hasNewAddress = addressList.some(function (address) { return address.getType() == 'new-customer-address'; }); @@ -94,12 +102,13 @@ define( } }); - quote.shippingMethod.subscribe(function (value) { + quote.shippingMethod.subscribe(function () { self.errorValidationMessage(false); }); registry.async('checkoutProvider')(function (checkoutProvider) { var shippingAddressData = checkoutData.getShippingAddressFromData(); + if (shippingAddressData) { checkoutProvider.set( 'shippingAddress', @@ -114,20 +123,31 @@ define( return this; }, + /** + * Load data from server for shipping step + */ navigate: function () { //load data from server for shipping step }, - initElement: function(element) { + /** + * @param {Object} element + */ + initElement: function (element) { if (element.index === 'shipping-address-fieldset') { shippingRatesValidator.bindChangeHandlers(element.elems(), false); } }, - getPopUp: function() { - var self = this; + /** + * @return {*} + */ + getPopUp: function () { + var self = this, + buttons; + if (!popUp) { - var buttons = this.popUpForm.options.buttons; + buttons = this.popUpForm.options.buttons; this.popUpForm.options.buttons = [ { text: buttons.save.text ? buttons.save.text : $t('Save Address'), @@ -135,38 +155,45 @@ define( click: self.saveNewAddress.bind(self) }, { - text: buttons.cancel.text ? buttons.cancel.text: $t('Cancel'), + text: buttons.cancel.text ? buttons.cancel.text : $t('Cancel'), class: buttons.cancel.class ? buttons.cancel.class : 'action secondary action-hide-popup', - click: function() { + click: function () { this.closeModal(); } } ]; - this.popUpForm.options.closed = function() { + this.popUpForm.options.closed = function () { self.isFormPopUpVisible(false); }; popUp = modal(this.popUpForm.options, $(this.popUpForm.element)); } + return popUp; }, - /** Show address form popup */ - showFormPopUp: function() { + /** + * Show address form popup + */ + showFormPopUp: function () { this.isFormPopUpVisible(true); }, + /** + * Save new shipping address + */ + saveNewAddress: function () { + var addressData, + newShippingAddress; - /** Save new shipping address */ - saveNewAddress: function() { this.source.set('params.invalid', false); this.source.trigger('shippingAddress.data.validate'); if (!this.source.get('params.invalid')) { - var addressData = this.source.get('shippingAddress'); + addressData = this.source.get('shippingAddress'); addressData.save_in_address_book = this.saveInAddressBook; // New address must be selected as a shipping address - var newShippingAddress = createShippingAddress(addressData); + newShippingAddress = createShippingAddress(addressData); selectShippingAddress(newShippingAddress); checkoutData.setSelectedShippingAddress(newShippingAddress.getKey()); checkoutData.setNewCustomerShippingAddress(addressData); @@ -175,32 +202,45 @@ define( } }, - /** Shipping Method View **/ + /** + * Shipping Method View + */ rates: shippingService.getShippingRates(), isLoading: shippingService.isLoading, isSelected: ko.computed(function () { - return quote.shippingMethod() - ? quote.shippingMethod().carrier_code + '_' + quote.shippingMethod().method_code + return quote.shippingMethod() ? + quote.shippingMethod().carrier_code + '_' + quote.shippingMethod().method_code : null; } ), - selectShippingMethod: function(shippingMethod) { + /** + * @param {Object} shippingMethod + * @return {Boolean} + */ + selectShippingMethod: function (shippingMethod) { selectShippingMethodAction(shippingMethod); checkoutData.setSelectedShippingRate(shippingMethod.carrier_code + '_' + shippingMethod.method_code); + return true; }, + /** + * Set shipping information handler + */ setShippingInformation: function () { if (this.validateShippingInformation()) { setShippingInformationAction().done( - function() { + function () { stepNavigator.next(); } ); } }, + /** + * @return {Boolean} + */ validateShippingInformation: function () { var shippingAddress, addressData, @@ -209,6 +249,7 @@ define( if (!quote.shippingMethod()) { this.errorValidationMessage('Please specify a shipping method'); + return false; } @@ -217,23 +258,22 @@ define( emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid()); } - if (!emailValidationResult) { - $(loginFormSelector + ' input[name=username]').focus(); - } - if (this.isFormInline) { this.source.set('params.invalid', false); this.source.trigger('shippingAddress.data.validate'); + if (this.source.get('shippingAddress.custom_attributes')) { this.source.trigger('shippingAddress.custom_attributes.data.validate'); - }; - if (this.source.get('params.invalid') - || !quote.shippingMethod().method_code - || !quote.shippingMethod().carrier_code - || !emailValidationResult + } + + if (this.source.get('params.invalid') || + !quote.shippingMethod().method_code || + !quote.shippingMethod().carrier_code || + !emailValidationResult ) { return false; } + shippingAddress = quote.shippingAddress(); addressData = addressConverter.formAddressDataToQuoteAddress( this.source.get('shippingAddress') @@ -241,9 +281,10 @@ define( //Copy form data to quote shipping address object for (var field in addressData) { - if (addressData.hasOwnProperty(field) - && shippingAddress.hasOwnProperty(field) - && typeof addressData[field] != 'function' + + if (addressData.hasOwnProperty(field) && + shippingAddress.hasOwnProperty(field) && + typeof addressData[field] != 'function' ) { shippingAddress[field] = addressData[field]; } @@ -254,6 +295,13 @@ define( } selectShippingAddress(shippingAddress); } + + if (!emailValidationResult) { + $(loginFormSelector + ' input[name=username]').focus(); + + return false; + } + return true; } }); diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html index 3cc77067a309b..501bfece9df21 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html @@ -9,9 +9,9 @@ - + @@ -25,18 +25,18 @@ - +
- - + + - +
- + @@ -46,7 +46,7 @@ - +
-
+
- +
-
    +
      @@ -73,12 +73,12 @@
- + - -

+ +

@@ -90,7 +90,7 @@ - +
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html index 3fdc88f0593ef..5a8d10ab80243 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/subtotal/totals.html @@ -5,5 +5,5 @@ */ -->
- +
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/payment/before-place-order.html b/app/code/Magento/Checkout/view/frontend/web/template/payment/before-place-order.html new file mode 100644 index 0000000000000..1b9c7bd977ece --- /dev/null +++ b/app/code/Magento/Checkout/view/frontend/web/template/payment/before-place-order.html @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file 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 da7dd9cbf7795..1c4b3991aeb7d 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,10 +22,15 @@ - Magento_CheckoutAgreements/js/view/checkout-agreements - before-place-order - checkoutAgreements - checkoutProvider + + + Magento_CheckoutAgreements/js/view/checkout-agreements + 100 + before-place-order + checkoutAgreements + checkoutProvider + + @@ -49,4 +54,4 @@ - + \ No newline at end of file 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 index ca8dfa8e26a8f..1f441779f79a1 100644 --- 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 @@ -9,25 +9,34 @@ define([ 'mage/utils/wrapper' ], 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, messageContainer) { + return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) { + var agreementForm, + agreementData, + agreementIds; + if (!agreementsConfig.isEnabled) { - return originalAction(paymentData, redirectOnSuccess, messageContainer); + return originalAction(paymentData, messageContainer); } - var agreementForm = $('.payment-method._active form[data-role=checkout-agreements]'), - agreementData = agreementForm.serializeArray(), - agreementIds = []; + agreementForm = $('.payment-method._active form[data-role=checkout-agreements]'); + agreementData = agreementForm.serializeArray(); + agreementIds = []; - agreementData.forEach(function(item) { + agreementData.forEach(function (item) { agreementIds.push(item.value); }); - paymentData.extension_attributes = {agreement_ids: agreementIds}; - return originalAction(paymentData, redirectOnSuccess, messageContainer); + paymentData.extension_attributes = { + agreement_ids: agreementIds + }; + + return originalAction(paymentData, messageContainer); }); }; }); diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js index bfec0bf920246..95aafb6a7ffba 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js +++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js @@ -11,80 +11,145 @@ define([ ], function ($, _, ko, sectionConfig) { 'use strict'; + var options, + storage, + storageInvalidation, + invalidateCacheBySessionTimeOut, + invalidateCacheByCloseCookieSession, + dataProvider, + buffer, + customerData; + //TODO: remove global change, in this case made for initNamespaceStorage - $.cookieStorage.setConf({path:'/'}); + $.cookieStorage.setConf({ + path: '/' + }); + + storage = $.initNamespaceStorage('mage-cache-storage').localStorage; + storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage; - var options; - var storage = $.initNamespaceStorage('mage-cache-storage').localStorage; - var storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage; + /** + * @param {Object} invalidateOptions + */ + invalidateCacheBySessionTimeOut = function (invalidateOptions) { + var date; - var invalidateCacheBySessionTimeOut = function(options) { if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) { storage.removeAll(); - var date = new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000); + date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000); $.localStorage.set('mage-cache-timeout', date); } }; - var invalidateCacheByCloseCookieSession = function() { + /** + * Invalidate Cache By Close Cookie Session + */ + invalidateCacheByCloseCookieSession = function () { if (!$.cookieStorage.isSet('mage-cache-sessid')) { $.cookieStorage.set('mage-cache-sessid', true); storage.removeAll(); } }; - var dataProvider = { + dataProvider = { + + /** + * @param {Object} sectionNames + * @return {Object} + */ getFromStorage: function (sectionNames) { var result = {}; + _.each(sectionNames, function (sectionName) { result[sectionName] = storage.get(sectionName); }); + return result; }, + + /** + * @param {Object} sectionNames + * @param {Number} updateSectionId + * @return {*} + */ getFromServer: function (sectionNames, updateSectionId) { + var parameters; + sectionNames = sectionConfig.filterClientSideSections(sectionNames); - var parameters = _.isArray(sectionNames) ? {sections: sectionNames.join(',')} : []; + parameters = _.isArray(sectionNames) ? { + sections: sectionNames.join(',') + } : []; parameters['update_section_id'] = updateSectionId; - return $.getJSON(options.sectionLoadUrl, parameters).fail(function(jqXHR) { + + return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) { throw new Error(jqXHR); }); } }; - - ko.extenders.disposableCustomerData = function(target, sectionName) { + /** + * @param {Function} target + * @param {String} sectionName + * @return {*} + */ + ko.extenders.disposableCustomerData = function (target, sectionName) { storage.remove(sectionName); - target.subscribe(function(newValue) { - setTimeout(function(){ + target.subscribe(function () { + setTimeout(function () { storage.remove(sectionName); }, 3000); }); + return target; }; - var buffer = { + buffer = { data: {}, + + /** + * @param {String} sectionName + */ bind: function (sectionName) { this.data[sectionName] = ko.observable({}); }, + + /** + * @param {String} sectionName + * @return {Object} + */ get: function (sectionName) { if (!this.data[sectionName]) { this.bind(sectionName); } + return this.data[sectionName]; }, + + /** + * @return {Array} + */ keys: function () { return _.keys(this.data); }, + + /** + * @param {String} sectionName + * @param {Object} sectionData + */ notify: function (sectionName, sectionData) { if (!this.data[sectionName]) { this.bind(sectionName); } this.data[sectionName](sectionData); }, + + /** + * @param {Object} sections + */ update: function (sections) { - var sectionId = 0; - var sectionDataIds = $.cookieStorage.get('section_data_ids') || {}; + var sectionId = 0, + sectionDataIds = $.cookieStorage.get('section_data_ids') || {}; + _.each(sections, function (sectionData, sectionName) { sectionId = sectionData['data_id']; sectionDataIds[sectionName] = sectionId; @@ -94,6 +159,10 @@ define([ }); $.cookieStorage.set('section_data_ids', sectionDataIds); }, + + /** + * @param {Object} sections + */ remove: function (sections) { _.each(sections, function (sectionName) { storage.remove(sectionName); @@ -102,8 +171,12 @@ define([ } }; - var customerData = { - init: function() { + customerData = { + + /** + * Customer data initialization + */ + init: function () { if (_.isEmpty(storage.keys())) { this.reload([], false); } else if (this.needReload()) { @@ -115,67 +188,119 @@ define([ _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) { buffer.notify(sectionName, sectionData); }); + if (!_.isEmpty(storageInvalidation.keys())) { this.reload(storageInvalidation.keys(), false); } } }, + + /** + * @return {Boolean} + */ needReload: function () { - var cookieSections = $.cookieStorage.get('section_data_ids'); + var cookieSections = $.cookieStorage.get('section_data_ids'), + storageVal, + name; + if (typeof cookieSections != 'object') { return true; } - var storageVal, name; + for (name in cookieSections) { - if (undefined !== name) { + if (name !== undefined) { storageVal = storage.get(name); - if (typeof storageVal == 'object' && cookieSections[name] > storageVal['data_id']) { + + if (typeof storageVal === 'undefined' || + typeof storageVal == 'object' && cookieSections[name] > storageVal['data_id'] + ) { return true; } } } + return false; }, - getExpiredKeys: function() { - var cookieSections = $.cookieStorage.get('section_data_ids'); + + /** + * + * @return {Array} + */ + getExpiredKeys: function () { + var cookieSections = $.cookieStorage.get('section_data_ids'), + storageVal, + name, + expiredKeys = []; if (typeof cookieSections != 'object') { return []; } - var storageVal, name, expiredKeys = []; + for (name in cookieSections) { storageVal = storage.get(name); - if (typeof storageVal == 'object' && cookieSections[name] != storage.get(name)['data_id']) { + + if (typeof storageVal === 'undefined' || + typeof storageVal == 'object' && cookieSections[name] != storage.get(name)['data_id'] + ) { expiredKeys.push(name); } } + return expiredKeys; }, + + /** + * @param {String} sectionName + * @return {*} + */ get: function (sectionName) { return buffer.get(sectionName); }, + + /** + * @param {String} sectionName + * @param {Object} sectionData + */ set: function (sectionName, sectionData) { var data = {}; + data[sectionName] = sectionData; buffer.update(data); }, + + /** + * @param {Array} sectionNames + * @param {Number} updateSectionId + * @return {*} + */ reload: function (sectionNames, updateSectionId) { return dataProvider.getFromServer(sectionNames, updateSectionId).done(function (sections) { buffer.update(sections); }); }, + + /** + * @param {Array} sectionNames + */ invalidate: function (sectionNames) { - var sectionDataIds; + var sectionDataIds, + sectionsNamesForInvalidation; - buffer.remove(_.contains(sectionNames, '*') ? buffer.keys() : sectionNames); + sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? buffer.keys() : sectionNames; + buffer.remove(sectionsNamesForInvalidation); sectionDataIds = $.cookieStorage.get('section_data_ids') || {}; // Invalidate section in cookie (increase version of section with 1000) - _.each(sectionNames, function (sectionName) { + _.each(sectionsNamesForInvalidation, function (sectionName) { sectionDataIds[sectionName] += 1000; }); $.cookieStorage.set('section_data_ids', sectionDataIds); }, + + /** + * @param {Object} settings + * @constructor + */ 'Magento_Customer/js/customer-data': function (settings) { options = settings; invalidateCacheBySessionTimeOut(settings); @@ -184,13 +309,16 @@ define([ } }; - /** Events listener **/ + /** + * Events listener + */ $(document).on('ajaxComplete', function (event, xhr, settings) { var sections, redirects; if (settings.type.match(/post|put/i)) { sections = sectionConfig.getAffectedSections(settings.url); + if (sections) { customerData.invalidate(sections); redirects = ['redirect', 'backUrl']; @@ -202,11 +330,16 @@ define([ } } }); + + /** + * Events listener + */ $(document).on('submit', function (event) { var sections; if (event.target.method.match(/post|put/i)) { sections = sectionConfig.getAffectedSections(event.target.action); + if (sections) { customerData.invalidate(sections); } diff --git a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js index 9f22914a8d29b..661fef20c7868 100644 --- a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js +++ b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js @@ -6,9 +6,10 @@ define( [], function () { - "use strict"; + 'use strict'; + return { - getRules: function() { + getRules: function () { return { 'postcode': { 'required': true diff --git a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js index 71dac1b92c10f..9ca57d5f168cd 100644 --- a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js @@ -7,19 +7,22 @@ define( [ 'jquery', 'mageUtils', - './shipping-rates-validation-rules', + 'Magento_Dhl/js/model/shipping-rates-validation-rules', 'mage/translate' ], function ($, utils, validationRules, $t) { - "use strict"; + 'use strict'; + return { validationErrors: [], - validate: function(address) { + validate: function (address) { var self = this; + this.validationErrors = []; - $.each(validationRules.getRules(), function(field, rule) { + $.each(validationRules.getRules(), function (field, rule) { if (rule.required && utils.isEmpty(address[field])) { var message = $t('Field ') + field + $t(' is required.'); + self.validationErrors.push(message); } }); diff --git a/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js index de18ca91237cd..50e0bda59bab8 100644 --- a/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js +++ b/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js @@ -9,8 +9,8 @@ define( 'uiComponent', 'Magento_Checkout/js/model/shipping-rates-validator', 'Magento_Checkout/js/model/shipping-rates-validation-rules', - '../model/shipping-rates-validator', - '../model/shipping-rates-validation-rules' + 'Magento_Dhl/js/model/shipping-rates-validator', + 'Magento_Dhl/js/model/shipping-rates-validation-rules' ], function ( Component, @@ -19,7 +19,8 @@ define( dhlShippingRatesValidator, dhlShippingRatesValidationRules ) { - "use strict"; + 'use strict'; + defaultShippingRatesValidator.registerValidator('dhl', dhlShippingRatesValidator); defaultShippingRatesValidationRules.registerRules('dhl', dhlShippingRatesValidationRules); return Component; diff --git a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js index 9f22914a8d29b..661fef20c7868 100644 --- a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js +++ b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js @@ -6,9 +6,10 @@ define( [], function () { - "use strict"; + 'use strict'; + return { - getRules: function() { + getRules: function () { return { 'postcode': { 'required': true diff --git a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js index 71dac1b92c10f..76c1ac89ad5fc 100644 --- a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js @@ -7,19 +7,21 @@ define( [ 'jquery', 'mageUtils', - './shipping-rates-validation-rules', + 'Magento_Fedex/js/model/shipping-rates-validation-rules', 'mage/translate' ], function ($, utils, validationRules, $t) { - "use strict"; + 'use strict'; + return { validationErrors: [], - validate: function(address) { + validate: function (address) { var self = this; this.validationErrors = []; - $.each(validationRules.getRules(), function(field, rule) { + $.each(validationRules.getRules(), function (field, rule) { if (rule.required && utils.isEmpty(address[field])) { var message = $t('Field ') + field + $t(' is required.'); + self.validationErrors.push(message); } }); diff --git a/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js index dc9bc66b93e5e..73470b8b881ea 100644 --- a/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js +++ b/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js @@ -9,8 +9,8 @@ define( 'uiComponent', 'Magento_Checkout/js/model/shipping-rates-validator', 'Magento_Checkout/js/model/shipping-rates-validation-rules', - '../model/shipping-rates-validator', - '../model/shipping-rates-validation-rules' + 'Magento_Fedex/js/model/shipping-rates-validator', + 'Magento_Fedex/js/model/shipping-rates-validation-rules' ], function ( Component, @@ -19,7 +19,7 @@ define( fedexShippingRatesValidator, fedexShippingRatesValidationRules ) { - "use strict"; + 'use strict'; defaultShippingRatesValidator.registerValidator('fedex', fedexShippingRatesValidator); defaultShippingRatesValidationRules.registerRules('fedex', fedexShippingRatesValidationRules); return Component; diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml index fc9624bde1016..0fcd0759c526d 100644 --- a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml +++ b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml @@ -29,11 +29,19 @@ $params = $block->getParams(); var require = window.top.require; require( [ + 'jquery', 'Magento_Checkout/js/model/quote', - 'Magento_Checkout/js/action/place-order' + 'Magento_Checkout/js/action/place-order', + 'Magento_Checkout/js/action/redirect-on-success' ], - function(quote, placeOrderAction) { - placeOrderAction({"method": quote.paymentMethod().method}, true); + function($, quote, placeOrderAction, redirectOnSuccessAction) { + $.when( + placeOrderAction({'method': quote.paymentMethod().method}) + ).done( + function () { + redirectOnSuccessAction.execute(); + } + ); } ); diff --git a/app/code/Magento/Paypal/etc/frontend/sections.xml b/app/code/Magento/Paypal/etc/frontend/sections.xml index 1a298d44576f9..2f4e672303e2d 100644 --- a/app/code/Magento/Paypal/etc/frontend/sections.xml +++ b/app/code/Magento/Paypal/etc/frontend/sections.xml @@ -11,4 +11,8 @@
+ +
+
+ diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js index 7820ef00544c2..10785fe7b2bbc 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js @@ -19,15 +19,24 @@ define( }, redirectAfterPlaceOrder: false, isInAction: iframe.isInAction, + + /** + * @return {exports} + */ initObservable: function () { this._super() .observe('paymentReady'); return this; }, + + /** + * @return {*} + */ isPaymentReady: function () { return this.paymentReady(); }, + /** * Get action url for payment method iframe. * @returns {String} @@ -35,25 +44,29 @@ define( getActionUrl: function () { return this.isInAction() ? window.checkoutConfig.payment.paypalIframe.actionUrl[this.getCode()] : ''; }, + /** * Places order in pending payment status. */ placePendingPaymentOrder: function () { - var self = this; - this.afterPlaceOrder = function () { - self.paymentReady(true); - }; if (this.placeOrder()) { this.isInAction(true); // capture all click events document.addEventListener('click', iframe.stopEventPropagation, true); } }, + + /** + * After place order callback + */ + afterPlaceOrder: function () { + this.paymentReady(true); + }, + /** * Hide loader when iframe is fully loaded. - * @returns {void} */ - iframeLoaded: function() { + iframeLoaded: function () { fullScreenLoader.stopLoader(); } }); diff --git a/app/code/Magento/Persistent/Model/Plugin/CustomerData.php b/app/code/Magento/Persistent/Model/Plugin/CustomerData.php new file mode 100644 index 0000000000000..31c22cf7b0f35 --- /dev/null +++ b/app/code/Magento/Persistent/Model/Plugin/CustomerData.php @@ -0,0 +1,71 @@ +persistentData = $persistentData; + $this->customerSession = $customerSession; + $this->persistentSession = $persistentSession; + } + + /** + * Reset quote reward point amount + * + * @param \Magento\Customer\CustomerData\Customer $subject + * @param \Closure $proceed + * + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundGetSectionData( + \Magento\Customer\CustomerData\Customer $subject, + \Closure $proceed + ) { + /** unset customer first name */ + if ( + !$this->customerSession->isLoggedIn() + && $this->persistentData->isEnabled() + && $this->persistentSession->isPersistent() + ) { + return []; + } + return $proceed(); + } +} diff --git a/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php b/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php index 1156568982f25..71a229aaeeff9 100644 --- a/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php +++ b/app/code/Magento/Persistent/Observer/EmulateCustomerObserver.php @@ -40,6 +40,11 @@ class EmulateCustomerObserver implements ObserverInterface */ protected $customerRepository; + /** + * @var \Magento\Customer\Api\AddressRepositoryInterface + */ + protected $addressRepository; + /** * Constructor * @@ -47,23 +52,28 @@ class EmulateCustomerObserver implements ObserverInterface * @param \Magento\Persistent\Helper\Data $persistentData * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository */ public function __construct( \Magento\Persistent\Helper\Session $persistentSession, \Magento\Persistent\Helper\Data $persistentData, \Magento\Customer\Model\Session $customerSession, - \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository + \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, + \Magento\Customer\Api\AddressRepositoryInterface $addressRepository ) { $this->_persistentSession = $persistentSession; $this->_persistentData = $persistentData; $this->_customerSession = $customerSession; $this->customerRepository = $customerRepository; + $this->addressRepository = $addressRepository; } /** * Set persistent data to customer session * * @param \Magento\Framework\Event\Observer $observer + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * * @return $this */ public function execute(\Magento\Framework\Event\Observer $observer) @@ -73,8 +83,37 @@ public function execute(\Magento\Framework\Event\Observer $observer) } if ($this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn()) { + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ $customer = $this->customerRepository->getById($this->_persistentSession->getSession()->getCustomerId()); - $this->_customerSession->setCustomerId($customer->getId())->setCustomerGroupId($customer->getGroupId()); + if ($defaultShipping = $customer->getDefaultShipping()) { + /** @var \Magento\Customer\Model\Data\Address $address */ + $address = $this->addressRepository->getById($defaultShipping); + if ($address) { + $this->_customerSession->setDefaultTaxShippingAddress( + [ + 'country_id' => $address->getCountryId(), + 'region_id' => $address->getRegion() + ? $address->getRegionId() + : null, + 'postcode' => $address->getPostcode(), + ] + ); + } + } + + if ($defaultBilling = $customer->getDefaultBilling()) { + $address = $this->addressRepository->getById($defaultBilling); + if ($address) { + $this->_customerSession->setDefaultTaxBillingAddress([ + 'country_id' => $address->getCountryId(), + 'region_id' => $address->getRegion() ? $address->getRegionId() : null, + 'postcode' => $address->getPostcode(), + ]); + } + } + $this->_customerSession + ->setCustomerId($customer->getId()) + ->setCustomerGroupId($customer->getGroupId()); } return $this; } diff --git a/app/code/Magento/Persistent/Test/Unit/Model/Checkout/ConfigProviderPluginTest.php b/app/code/Magento/Persistent/Test/Unit/Model/Checkout/ConfigProviderPluginTest.php new file mode 100644 index 0000000000000..31cde3ccbd9d6 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Unit/Model/Checkout/ConfigProviderPluginTest.php @@ -0,0 +1,125 @@ +persistentHelperMock = $this->getMock('Magento\Persistent\Helper\Data', [], [], '', false); + $this->persistentSessionMock = $this->getMock('Magento\Persistent\Helper\Session', [], [], '', false); + $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false); + $this->maskFactoryMock = $this->getMock( + 'Magento\Quote\Model\QuoteIdMaskFactory', + ['create', '__wakeup'], + [], + '', + false + ); + $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', [], [], '', false); + $this->subjectMock = $this->getMock('\Magento\Checkout\Model\DefaultConfigProvider', [], [], '', false); + + $this->plugin = new \Magento\Persistent\Model\Checkout\ConfigProviderPlugin( + $this->persistentHelperMock, + $this->persistentSessionMock, + $this->checkoutSessionMock, + $this->maskFactoryMock, + $this->customerSessionMock + ); + } + + /** + * @param bool $persitenceEnabled + * @param bool $isPersistent + * @param bool $isLoggedIn + * + * @dataProvider configDataProvider + */ + public function testAfterGetConfigNegative($persitenceEnabled, $isPersistent, $isLoggedIn) + { + $result = [40, 30, 50]; + + $this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn($persitenceEnabled); + $this->persistentSessionMock->expects($this->any())->method('isPersistent')->willReturn($isPersistent); + $this->customerSessionMock->expects($this->any())->method('isLoggedIn')->willReturn($isLoggedIn); + $this->maskFactoryMock->expects($this->never())->method('create'); + $this->assertEquals($result, $this->plugin->afterGetConfig($this->subjectMock, $result)); + } + + /** + * @return array + */ + public function configDataProvider() + { + return [ + [false, true, true], //disabled persistence case + [true, false, true], //persistence enabled but not persistent session + [true, true, true], //logged in user + ]; + } + + public function testAfterGetConfigPositive() + { + $maskedId = 3005; + $result = [40, 30, 50]; + $expectedResult = $result; + $expectedResult['quoteData']['entity_id'] = $maskedId; + + $this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(true); + $this->persistentSessionMock->expects($this->once())->method('isPersistent')->willReturn(true); + $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->willReturn(false); + + $quoteMaskMock = $this->getMock( + 'Magento\Quote\Model\QuoteIdMask', + ['load', 'getMaskedId'], + [], + '', + false + ); + $this->maskFactoryMock->expects($this->once())->method('create')->willReturn($quoteMaskMock); + $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false); + + $this->checkoutSessionMock->expects($this->once())->method('getQuote')->willReturn($quoteMock); + $quoteMaskMock->expects($this->once())->method('load')->willReturnSelf(); + $quoteMaskMock->expects($this->once())->method('getMaskedId')->willReturn($maskedId); + $this->assertEquals($expectedResult, $this->plugin->afterGetConfig($this->subjectMock, $result)); + } +} diff --git a/app/code/Magento/Persistent/Test/Unit/Model/Plugin/CustomerDataTest.php b/app/code/Magento/Persistent/Test/Unit/Model/Plugin/CustomerDataTest.php new file mode 100644 index 0000000000000..54a5a078d09d8 --- /dev/null +++ b/app/code/Magento/Persistent/Test/Unit/Model/Plugin/CustomerDataTest.php @@ -0,0 +1,77 @@ +helperMock = $this->getMock('Magento\Persistent\Helper\Data', [], [], '', false); + $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', [], [], '', false); + $this->persistentSessionMock = $this->getMock('Magento\Persistent\Helper\Session', [], [], '', false); + $this->subjectMock = $this->getMock('\Magento\Customer\CustomerData\Customer', [], [], '', false); + $this->plugin = new \Magento\Persistent\Model\Plugin\CustomerData( + $this->helperMock, + $this->customerSessionMock, + $this->persistentSessionMock + ); + } + + public function testAroundGetSectionDataForPersistentSession() + { + $result = 'result'; + $proceed = function () use ($result) { + return $result; + }; + + $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->willReturn(false); + $this->helperMock->expects($this->once())->method('isEnabled')->willReturn(true); + $this->persistentSessionMock->expects($this->once())->method('isPersistent')->willReturn(true); + + $this->assertEquals([], $this->plugin->aroundGetSectionData($this->subjectMock, $proceed)); + } + + + public function testAroundGetSectionData() + { + $result = 'result'; + $proceed = function () use ($result) { + return $result; + }; + + $this->customerSessionMock->expects($this->once())->method('isLoggedIn')->willReturn(false); + $this->helperMock->expects($this->once())->method('isEnabled')->willReturn(true); + $this->persistentSessionMock->expects($this->once())->method('isPersistent')->willReturn(false); + + $this->assertEquals($result, $this->plugin->aroundGetSectionData($this->subjectMock, $proceed)); + } +} diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php index fef80b1329ba4..f0164c8df8558 100644 --- a/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Observer/EmulateCustomerObserverTest.php @@ -39,6 +39,11 @@ class EmulateCustomerObserverTest extends \PHPUnit_Framework_TestCase */ protected $observerMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $addressRepositoryMock; + protected function setUp() { $this->customerRepositoryMock = $this->getMockForAbstractClass( @@ -47,15 +52,24 @@ protected function setUp() '', false ); - $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', [], [], '', false); + $methods = [ + 'setDefaultTaxShippingAddress', + 'setDefaultTaxBillingAddress', + 'setCustomerId', + 'setCustomerGroupId', + 'isLoggedIn' + ]; + $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', $methods, [], '', false); $this->sessionHelperMock = $this->getMock('Magento\Persistent\Helper\Session', [], [], '', false); $this->helperMock = $this->getMock('Magento\Persistent\Helper\Data', [], [], '', false); $this->observerMock = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false); + $this->addressRepositoryMock = $this->getMock('Magento\Customer\Api\AddressRepositoryInterface'); $this->model = new \Magento\Persistent\Observer\EmulateCustomerObserver( $this->sessionHelperMock, $this->helperMock, $this->customerSessionMock, - $this->customerRepositoryMock + $this->customerRepositoryMock, + $this->addressRepositoryMock ); } @@ -87,8 +101,51 @@ public function testExecuteWhenSessionPersistAndCustomerNotLoggedIn() { $customerId = 1; $customerGroupId = 2; - $sessionMock = $this->getMock('Magento\Persistent\Model\Session', ['getCustomerId', '__wakeUp'], [], '', false); - $customerMock = $this->getMock('\Magento\Customer\Api\Data\CustomerInterface', [], [], '', false); + $countryId = 3; + $regionId = 4; + $postcode = 90210; + $sessionMock = $this->getMock( + 'Magento\Persistent\Model\Session', + ['getCustomerId', '__wakeUp'], + [], + '', + false + ); + $methods = ['getCountryId', 'getRegion', 'getRegionId', 'getPostcode']; + $defaultShippingAddressMock = $this->getMock('Magento\Customer\Model\Address', $methods, [], '', false); + $defaultBillingAddressMock = $this->getMock('Magento\Customer\Model\Address', $methods, [], '', false); + $customerMock = $this->getMock('Magento\Customer\Api\Data\CustomerInterface'); + $customerMock + ->expects($this->once()) + ->method('getDefaultShipping') + ->willReturn('shippingId'); + $customerMock + ->expects($this->once()) + ->method('getDefaultBilling') + ->willReturn('billingId'); + $valueMap = [ + ['shippingId', $defaultShippingAddressMock], + ['billingId', $defaultBillingAddressMock] + ]; + $this->addressRepositoryMock->expects($this->any())->method('getById')->willReturnMap($valueMap); + $this->customerSessionMock + ->expects($this->once()) + ->method('setDefaultTaxShippingAddress') + ->with( + [ + 'country_id' => $countryId, + 'region_id' => $regionId, + 'postcode' => $postcode + ] + ); + $defaultBillingAddressMock->expects($this->once())->method('getCountryId')->willReturn($countryId); + $defaultBillingAddressMock->expects($this->once())->method('getRegion')->willReturn('California'); + $defaultBillingAddressMock->expects($this->once())->method('getRegionId')->willReturn($regionId); + $defaultBillingAddressMock->expects($this->once())->method('getPostcode')->willReturn($postcode); + $defaultShippingAddressMock->expects($this->once())->method('getCountryId')->willReturn($countryId); + $defaultShippingAddressMock->expects($this->once())->method('getRegion')->willReturn('California'); + $defaultShippingAddressMock->expects($this->once())->method('getRegionId')->willReturn($regionId); + $defaultShippingAddressMock->expects($this->once())->method('getPostcode')->willReturn($postcode); $this->helperMock ->expects($this->once()) ->method('canProcess') diff --git a/app/code/Magento/Persistent/etc/di.xml b/app/code/Magento/Persistent/etc/di.xml index 41f061292f040..a2a8dba823974 100644 --- a/app/code/Magento/Persistent/etc/di.xml +++ b/app/code/Magento/Persistent/etc/di.xml @@ -9,4 +9,7 @@ + + + diff --git a/app/code/Magento/Persistent/etc/persistent.xml b/app/code/Magento/Persistent/etc/persistent.xml index 5852621ae3518..8d2710252fc1d 100644 --- a/app/code/Magento/Persistent/etc/persistent.xml +++ b/app/code/Magento/Persistent/etc/persistent.xml @@ -8,6 +8,12 @@ + + header + Magento\Persistent\Model\Observer + emulateWelcomeBlock + Magento\Theme\Block\Html\Header + top.links Magento\Persistent\Model\Observer diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/minicart/subtotal/totals.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/minicart/subtotal/totals.html index 63afce061a333..cbff6b4a24496 100644 --- a/app/code/Magento/Tax/view/frontend/web/template/checkout/minicart/subtotal/totals.html +++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/minicart/subtotal/totals.html @@ -11,11 +11,11 @@ - + - + diff --git a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml index 668a435acdadd..60ca4067af2b7 100644 --- a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml @@ -14,7 +14,12 @@ $welcomeMessage = $block->getWelcome(); getShowPart()): case 'welcome': ?>
  • - + + + + + +