diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php
index 9ee191c2f30a4..4ff8a2c4e753a 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Value.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php
@@ -8,6 +8,7 @@
namespace Magento\Catalog\Model\Product\Option;
+use Magento\Catalog\Pricing\Price\BasePrice;
use Magento\Framework\Model\AbstractModel;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Option;
@@ -225,7 +226,7 @@ public function saveValues()
public function getPrice($flag = false)
{
if ($flag && $this->getPriceType() == self::TYPE_PERCENT) {
- $basePrice = $this->getOption()->getProduct()->getFinalPrice();
+ $basePrice = $this->getOption()->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue();
$price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
return $price;
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php
index 7fa5140884582..4a3b008ad4bb1 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/ValueTest.php
@@ -170,13 +170,30 @@ private function getMockedOption()
private function getMockedProduct()
{
$mockBuilder = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
- ->setMethods(['getFinalPrice', '__wakeup'])
+ ->setMethods(['getPriceInfo', '__wakeup'])
->disableOriginalConstructor();
$mock = $mockBuilder->getMock();
$mock->expects($this->any())
->method('getFinalPrice')
->will($this->returnValue(10));
+ $priceInfoMock = $this->getMockForAbstractClass(
+ \Magento\Framework\Pricing\PriceInfoInterface::class,
+ [],
+ '',
+ false,
+ false,
+ true,
+ ['getPrice']
+ );
+
+ $priceMock = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Price\PriceInterface::class);
+
+ $priceInfoMock->expects($this->any())->method('getPrice')->willReturn($priceMock);
+
+ $mock->expects($this->any())->method('getPriceInfo')->willReturn($priceInfoMock);
+
+ $priceMock->expects($this->any())->method('getValue')->willReturn(10);
return $mock;
}
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 09cbb678987e7..2406c9ad40afe 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -2643,7 +2643,12 @@ protected function checkUrlKeyDuplicates()
);
foreach ($urlKeyDuplicates as $entityData) {
$rowNum = $this->rowNumbers[$entityData['store_id']][$entityData['request_path']];
- $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum);
+ $message = sprintf(
+ $this->retrieveMessageTemplate(ValidatorInterface::ERROR_DUPLICATE_URL_KEY),
+ $entityData['request_path'],
+ $entityData['sku']
+ );
+ $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum, 'url_key', $message);
}
}
}
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
index 3b1e15bc3b9d6..bb3ea2c5a6eda 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
@@ -276,12 +276,12 @@ define([
var element;
_.each(this.disabledAttributes, function (attribute) {
- registry.get('index = ' + attribute).disabled(false);
+ registry.get('code = ' + attribute, 'index = ' + attribute).disabled(false);
});
this.disabledAttributes = [];
_.each(attributes, function (attribute) {
- element = registry.get('index = ' + attribute.code);
+ element = registry.get('code = ' + attribute.code, 'index = ' + attribute.code);
if (!_.isUndefined(element)) {
element.disabled(true);
this.disabledAttributes.push(attribute.code);
diff --git a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php
index b1c54a1f01260..3b67c0cc0694e 100644
--- a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php
+++ b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php
@@ -13,6 +13,8 @@
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\Exception\InputException;
+use Magento\Framework\App\ObjectManager;
+use Magento\Store\Model\ScopeInterface;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -61,6 +63,16 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf
*/
protected $extensionAttributesJoinProcessor;
+ /**
+ * @var \Magento\Directory\Model\AllowedCountries
+ */
+ private $allowedCountriesReader;
+
+ /**
+ * @var \Magento\Customer\Model\Config\Share
+ */
+ private $shareConfig;
+
/**
* @param \Magento\Customer\Model\AddressFactory $addressFactory
* @param \Magento\Customer\Model\AddressRegistry $addressRegistry
@@ -70,6 +82,10 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf
* @param \Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory
* @param \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressCollectionFactory
* @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
+ * @param \Magento\Directory\Model\AllowedCountries|null $allowedCountriesReader
+ * @param \Magento\Customer\Model\Config\Share|null $shareConfig
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Customer\Model\AddressFactory $addressFactory,
@@ -79,7 +95,9 @@ public function __construct(
\Magento\Directory\Helper\Data $directoryData,
\Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory,
\Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressCollectionFactory,
- \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor
+ \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor,
+ \Magento\Directory\Model\AllowedCountries $allowedCountriesReader = null,
+ \Magento\Customer\Model\Config\Share $shareConfig = null
) {
$this->addressFactory = $addressFactory;
$this->addressRegistry = $addressRegistry;
@@ -89,6 +107,10 @@ public function __construct(
$this->addressSearchResultsFactory = $addressSearchResultsFactory;
$this->addressCollectionFactory = $addressCollectionFactory;
$this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
+ $this->allowedCountriesReader = $allowedCountriesReader
+ ?: ObjectManager::getInstance()->get(\Magento\Directory\Model\AllowedCountries::class);
+ $this->shareConfig = $shareConfig
+ ?: ObjectManager::getInstance()->get(\Magento\Customer\Model\Config\Share::class);
}
/**
@@ -290,7 +312,7 @@ private function _validate(CustomerAddressModel $customerAddressModel)
$exception->addError(__('%fieldName is a required field.', ['fieldName' => 'countryId']));
} else {
//Checking if such country exists.
- if (!in_array($countryId, $this->directoryData->getCountryCollection()->getAllIds(), true)) {
+ if (!in_array($countryId, $this->getWebsiteAllowedCountries($customerAddressModel), true)) {
$exception->addError(
__(
'Invalid value of "%value" provided for the %fieldName field.',
@@ -334,4 +356,23 @@ private function _validate(CustomerAddressModel $customerAddressModel)
return $exception;
}
+
+ /**
+ * Return allowed counties per website.
+ *
+ * @param \Magento\Customer\Model\Address $customerAddressModel
+ * @return array
+ */
+ private function getWebsiteAllowedCountries(\Magento\Customer\Model\Address $customerAddressModel)
+ {
+ $websiteId = null;
+
+ if (!$this->shareConfig->isGlobalScope()) {
+ $websiteId = $customerAddressModel->getCustomer()
+ ? $customerAddressModel->getCustomer()->getWebsiteId()
+ : null;
+ }
+
+ return $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_WEBSITE, $websiteId);
+ }
}
diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php
index 8df72f96f93c7..338f6d1dffed5 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php
@@ -6,8 +6,8 @@
namespace Magento\Customer\Test\Unit\Model\ResourceModel;
use Magento\Customer\Api\Data\AddressInterface as AddressData;
-use Magento\Directory\Model\ResourceModel\Country\Collection as Countries;
use Magento\Framework\Exception\InputException;
+use Magento\Store\Model\ScopeInterface;
/**
* Unit test for Magento\Customer\Model\ResourceModel\AddressRepository
@@ -71,6 +71,16 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
*/
protected $repository;
+ /**
+ * @var \Magento\Directory\Model\AllowedCountries|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $allowedCountriesReaderMock;
+
+ /**
+ * @var \Magento\Customer\Model\Config\Share|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $shareConfigMock;
+
protected function setUp()
{
$this->addressFactory = $this->getMock(
@@ -137,6 +147,26 @@ protected function setUp()
false
);
+ $this->allowedCountriesReaderMock = $this->getMock(
+ \Magento\Directory\Model\AllowedCountries::class,
+ ['getAllowedCountries'],
+ [],
+ '',
+ false
+ );
+ $this->shareConfigMock = $this->getMock(
+ \Magento\Customer\Model\Config\Share::class,
+ ['isGlobalScope'],
+ [],
+ '',
+ false
+ );
+ $this->shareConfigMock->method('isGlobalScope')->willReturn(false);
+ $this->allowedCountriesReaderMock
+ ->method('getAllowedCountries')
+ ->with(ScopeInterface::SCOPE_WEBSITE, null)
+ ->willReturn(['1', '2']);
+
$this->repository = new \Magento\Customer\Model\ResourceModel\AddressRepository(
$this->addressFactory,
$this->addressRegistry,
@@ -145,7 +175,9 @@ protected function setUp()
$this->directoryData,
$this->addressSearchResultsFactory,
$this->addressCollectionFactory,
- $this->extensionAttributesJoinProcessor
+ $this->extensionAttributesJoinProcessor,
+ $this->allowedCountriesReaderMock,
+ $this->shareConfigMock
);
}
@@ -315,15 +347,6 @@ public function testSaveWithInvalidRegion()
->method('getRegion')
->willReturn('');
- /** @var \PHPUnit_Framework_MockObject_MockObject $countryCollection */
- $countryCollection = $this->getMockBuilder(Countries::class)
- ->disableOriginalConstructor()
- ->getMock();
- $countryCollection->expects($this->once())->method('getAllIds')->willReturn(['1', '2']);
- $this->directoryData->expects($this->once())
- ->method('getCountryCollection')
- ->willReturn($countryCollection);
-
$this->repository->save($customerAddress);
}
@@ -408,15 +431,6 @@ public function testSaveWithInvalidRegionId()
->method('getRegion')
->willReturn('');
- /** @var \PHPUnit_Framework_MockObject_MockObject $countryCollection */
- $countryCollection = $this->getMockBuilder(Countries::class)
- ->disableOriginalConstructor()
- ->getMock();
- $countryCollection->expects($this->once())->method('getAllIds')->willReturn(['1', '2']);
- $this->directoryData->expects($this->once())
- ->method('getCountryCollection')
- ->willReturn($countryCollection);
-
$this->repository->save($customerAddress);
}
@@ -714,15 +728,6 @@ private function prepareAddressData($countryId, $regionId)
$countryModel->expects($this->any())->method('getRegionCollection')->willReturn($regionCollection);
$regionCollection->expects($this->any())->method('getAllIds')->willReturn(['3', '4']);
- /** @var \PHPUnit_Framework_MockObject_MockObject $countryCollection */
- $countryCollection = $this->getMockBuilder(Countries::class)
- ->disableOriginalConstructor()
- ->getMock();
- $countryCollection->expects($this->once())->method('getAllIds')->willReturn(['1', '2']);
- $this->directoryData->expects($this->once())
- ->method('getCountryCollection')
- ->willReturn($countryCollection);
-
return $customerAddress;
}
}
diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml
index 241ab1451238a..4b041f4052e7e 100644
--- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml
@@ -32,7 +32,7 @@
@@ -51,12 +51,3 @@
-
diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
index c59c16ee3601c..516c5aa971ab8 100644
--- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml
@@ -134,7 +134,7 @@
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js b/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js
index fa62ebf5f9d48..9739fc1226917 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js
@@ -31,7 +31,7 @@ define(
/** Show login popup window */
showModal: function () {
- $(this.modalWindow).modal('openModal');
+ $(this.modalWindow).modal('openModal').trigger('contentUpdated');
}
}
}
diff --git a/app/code/Magento/Customer/view/frontend/web/js/trim-username.js b/app/code/Magento/Customer/view/frontend/web/js/trim-username.js
deleted file mode 100644
index 1b6aab6086853..0000000000000
--- a/app/code/Magento/Customer/view/frontend/web/js/trim-username.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-define([
- 'jquery'
-], function ($) {
- 'use strict';
-
- $.widget('mage.trimUsername', {
- options: {
- cache: {},
- formSelector: 'form',
- emailSelector: 'input[type="email"]'
- },
-
- /**
- * Widget initialization
- * @private
- */
- _create: function () {
- // We need to look outside the module for backward compatibility, since someone can already use the module.
- // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the
- // newsletter email field or any other "email" field.
- this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector);
- this._bind();
- },
-
- /**
- * Event binding, will monitor change, keyup and paste events.
- * @private
- */
- _bind: function () {
- if (this.options.cache.email.length) {
- this._on(this.options.cache.email, {
- 'change': this._trimUsername,
- 'keyup': this._trimUsername,
- 'paste': this._trimUsername
- });
- }
- },
-
- /**
- * Trim username
- * @private
- */
- _trimUsername: function () {
- var username = this._getUsername().trim();
-
- this.options.cache.email.val(username);
- },
-
- /**
- * Get username value
- * @returns {*}
- * @private
- */
- _getUsername: function () {
- return this.options.cache.email.val();
- }
- });
-
- return $.mage.trimUsername;
-});
diff --git a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
index 046cc38d39149..f412d3d15d11f 100644
--- a/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
+++ b/app/code/Magento/Customer/view/frontend/web/template/authentication-popup.html
@@ -60,6 +60,7 @@
id="email"
type="email"
class="input-text"
+ data-mage-init='{"mage/trim-input":{}}'
data-bind="attr: {autocomplete: autocomplete}"
data-validate="{required:true, 'validate-email':true}">
diff --git a/app/code/Magento/GiftMessage/view/frontend/web/template/gift-message-form.html b/app/code/Magento/GiftMessage/view/frontend/web/template/gift-message-form.html
index 20739f621ecff..15a36cc0e977a 100644
--- a/app/code/Magento/GiftMessage/view/frontend/web/template/gift-message-form.html
+++ b/app/code/Magento/GiftMessage/view/frontend/web/template/gift-message-form.html
@@ -12,26 +12,24 @@
-
diff --git a/app/code/Magento/ImportExport/Model/Import/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/AbstractEntity.php
index 8a95b2815eb85..fe7d1692c4a16 100644
--- a/app/code/Magento/ImportExport/Model/Import/AbstractEntity.php
+++ b/app/code/Magento/ImportExport/Model/Import/AbstractEntity.php
@@ -803,7 +803,7 @@ public function validateData()
if (!$this->isAttributeParticular($columnName)) {
if (trim($columnName) == '') {
$emptyHeaderColumns[] = $columnNumber;
- } elseif (!preg_match('/^[a-z][a-z0-9_]*$/', $columnName)) {
+ } elseif (!preg_match('/^[a-z][\w]*$/u', $columnName)) {
$invalidColumns[] = $columnName;
} elseif ($this->needColumnCheck && !in_array($columnName, $this->getValidColumnNames())) {
$invalidAttributes[] = $columnName;
diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php
index 47b0935e31470..3e9e239b3b05f 100644
--- a/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php
+++ b/app/code/Magento/ImportExport/Model/Import/Entity/AbstractEntity.php
@@ -769,7 +769,7 @@ public function validateData()
if (!$this->isAttributeParticular($columnName)) {
if (trim($columnName) == '') {
$emptyHeaderColumns[] = $columnNumber;
- } elseif (!preg_match('/^[a-z][a-z0-9_]*$/', $columnName)) {
+ } elseif (!preg_match('/^[a-z][\w]*$/u', $columnName)) {
$invalidColumns[] = $columnName;
} elseif ($this->needColumnCheck && !in_array($columnName, $this->getValidColumnNames())) {
$invalidAttributes[] = $columnName;
diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php
index 004677b899cd0..4e338c2d1df34 100644
--- a/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php
+++ b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php
@@ -32,6 +32,8 @@ public function execute()
}
}
- $this->getResponse()->setRedirect($this->_storeManager->getStore()->getBaseUrl());
+ $resultRedirect = $this->resultRedirectFactory->create();
+ $resultRedirect->setUrl($this->_storeManager->getStore()->getBaseUrl());
+ return $resultRedirect;
}
}
diff --git a/app/code/Magento/Paypal/view/frontend/web/order-review.js b/app/code/Magento/Paypal/view/frontend/web/order-review.js
index eb9319aa98cd2..524a604b6763d 100644
--- a/app/code/Magento/Paypal/view/frontend/web/order-review.js
+++ b/app/code/Magento/Paypal/view/frontend/web/order-review.js
@@ -88,7 +88,7 @@ define([
},
/**
- * trigger change for the update of shippping methods from server
+ * trigger change for the update of shipping methods from server
*/
_updateOrderHandler: function () {
$(this.options.shippingSelector).trigger('change');
@@ -246,7 +246,7 @@ define([
this._updateOrderSubmit(true);
this._toggleButton(this.options.updateOrderSelector, true);
- // form data and callBack updated based on the shippping Form element
+ // form data and callBack updated based on the shipping Form element
if (this.isShippingSubmitForm) {
formData = $(this.options.shippingSubmitFormSelector).serialize() + "&isAjax=true";
callBackResponseHandler = function (response) {
diff --git a/app/code/Magento/Quote/Model/ResourceModel/Quote.php b/app/code/Magento/Quote/Model/ResourceModel/Quote.php
index 7065e8bb51b40..afa76aba5366e 100644
--- a/app/code/Magento/Quote/Model/ResourceModel/Quote.php
+++ b/app/code/Magento/Quote/Model/ResourceModel/Quote.php
@@ -171,7 +171,7 @@ public function getReservedOrderId($quote)
{
return $this->sequenceManager->getSequence(
\Magento\Sales\Model\Order::ENTITY,
- $quote->getStore()->getGroup()->getDefaultStoreId()
+ $quote->getStoreId()
)
->getNextValue();
}
@@ -230,13 +230,24 @@ public function markQuotesRecollectOnCatalogRules()
return $this;
}
+ /**
+ * @param \Magento\Catalog\Model\Product $product
+ * @return Quote
+ * @deprecated
+ * @see subtractProductFromQuotes
+ */
+ public function substractProductFromQuotes($product)
+ {
+ return $this->subtractProductFromQuotes($product);
+ }
+
/**
* Subtract product from all quotes quantities
*
* @param \Magento\Catalog\Model\Product $product
* @return $this
*/
- public function substractProductFromQuotes($product)
+ public function subtractProductFromQuotes($product)
{
$productId = (int)$product->getId();
if (!$productId) {
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php
new file mode 100644
index 0000000000000..915241f5721e1
--- /dev/null
+++ b/app/code/Magento/Quote/Test/Unit/Model/ResourceModel/QuoteTest.php
@@ -0,0 +1,102 @@
+getMockBuilder(Context::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $snapshot = $this->getMockBuilder(Snapshot::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $relationComposite = $this->getMockBuilder(RelationComposite::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->quoteMock = $this->getMockBuilder(Quote::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->sequenceManagerMock = $this->getMockBuilder(Manager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->sequenceMock = $this->getMockBuilder(SequenceInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->quote = new \Magento\Quote\Model\ResourceModel\Quote(
+ $context,
+ $snapshot,
+ $relationComposite,
+ $this->sequenceManagerMock,
+ null
+ );
+ }
+
+ /**
+ * @param $entityType
+ * @param $storeId
+ * @param $reservedOrderId
+ * @dataProvider getReservedOrderIdDataProvider
+ */
+ public function testGetReservedOrderId($entityType, $storeId, $reservedOrderId)
+ {
+ $this->sequenceManagerMock->expects($this->once())
+ ->method('getSequence')
+ ->with($entityType, $storeId)
+ ->willReturn($this->sequenceMock);
+ $this->quoteMock->expects($this->once())
+ ->method('getStoreId')
+ ->willReturn($storeId);
+ $this->sequenceMock->expects($this->once())
+ ->method('getNextValue')
+ ->willReturn($reservedOrderId);
+ $this->assertEquals($reservedOrderId, $this->quote->getReservedOrderId($this->quoteMock));
+ }
+
+ /**
+ * @return array
+ */
+ public function getReservedOrderIdDataProvider()
+ {
+ return [
+ [\Magento\Sales\Model\Order::ENTITY, 1, '1000000001'],
+ [\Magento\Sales\Model\Order::ENTITY, 2, '2000000001'],
+ [\Magento\Sales\Model\Order::ENTITY, 3, '3000000001']
+ ];
+ }
+}
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals/Discount.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals/Discount.php
index cdeb596a54ac7..b28dbda5f3810 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals/Discount.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals/Discount.php
@@ -15,8 +15,6 @@
*/
class Discount extends \Magento\Sales\Block\Adminhtml\Order\Create\Totals\DefaultTotals
{
- //protected $_template = 'tax/checkout/subtotal.phtml';
-
/**
* Tax config
*
diff --git a/app/code/Magento/Sales/Model/ResourceModel/EntityAbstract.php b/app/code/Magento/Sales/Model/ResourceModel/EntityAbstract.php
index 8a8ee5e9c799f..2152ff7c84556 100644
--- a/app/code/Magento/Sales/Model/ResourceModel/EntityAbstract.php
+++ b/app/code/Magento/Sales/Model/ResourceModel/EntityAbstract.php
@@ -121,10 +121,15 @@ protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
{
/** @var \Magento\Sales\Model\AbstractModel $object */
if ($object instanceof EntityInterface && $object->getIncrementId() == null) {
+ $store = $object->getStore();
+ $storeId = $store->getId();
+ if ($storeId === null) {
+ $storeId = $store->getGroup()->getDefaultStoreId();
+ }
$object->setIncrementId(
$this->sequenceManager->getSequence(
$object->getEntityType(),
- $object->getStore()->getGroup()->getDefaultStoreId()
+ $storeId
)->getNextValue()
);
}
diff --git a/app/code/Magento/Sales/Observer/Backend/SubtractQtyFromQuotesObserver.php b/app/code/Magento/Sales/Observer/Backend/SubtractQtyFromQuotesObserver.php
index 775a7dab95cfe..cd8c705750d6c 100644
--- a/app/code/Magento/Sales/Observer/Backend/SubtractQtyFromQuotesObserver.php
+++ b/app/code/Magento/Sales/Observer/Backend/SubtractQtyFromQuotesObserver.php
@@ -31,6 +31,6 @@ public function __construct(\Magento\Quote\Model\ResourceModel\Quote $quote)
public function execute(\Magento\Framework\Event\Observer $observer)
{
$product = $observer->getEvent()->getProduct();
- $this->_quote->substractProductFromQuotes($product);
+ $this->_quote->subtractProductFromQuotes($product);
}
}
diff --git a/app/code/Magento/Sales/Test/Unit/Observer/Backend/SubtractQtyFromQuotesObserverTest.php b/app/code/Magento/Sales/Test/Unit/Observer/Backend/SubtractQtyFromQuotesObserverTest.php
index 1208e3a755543..8e2174775b117 100644
--- a/app/code/Magento/Sales/Test/Unit/Observer/Backend/SubtractQtyFromQuotesObserverTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Observer/Backend/SubtractQtyFromQuotesObserverTest.php
@@ -15,12 +15,12 @@ class SubtractQtyFromQuotesObserverTest extends \PHPUnit_Framework_TestCase
protected $_model;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Quote\Model\ResourceModel\Quote|\PHPUnit_Framework_MockObject_MockObject
*/
protected $_quoteMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject
*/
protected $_observerMock;
@@ -54,7 +54,7 @@ public function testSubtractQtyFromQuotes()
false
);
$this->_eventMock->expects($this->once())->method('getProduct')->will($this->returnValue($productMock));
- $this->_quoteMock->expects($this->once())->method('substractProductFromQuotes')->with($productMock);
+ $this->_quoteMock->expects($this->once())->method('subtractProductFromQuotes')->with($productMock);
$this->_model->execute($this->_observerMock);
}
}
diff --git a/app/code/Magento/Search/view/frontend/web/form-mini.js b/app/code/Magento/Search/view/frontend/web/form-mini.js
index 51398168c6e19..02a8f618a2298 100644
--- a/app/code/Magento/Search/view/frontend/web/form-mini.js
+++ b/app/code/Magento/Search/view/frontend/web/form-mini.js
@@ -207,6 +207,7 @@ define([
break;
case $.ui.keyCode.ENTER:
this.searchForm.trigger('submit');
+ e.preventDefault();
break;
case $.ui.keyCode.DOWN:
if (this.responseList.indexList) {
diff --git a/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml b/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml
index 32f692c32fccf..bb8ac51236d2c 100644
--- a/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml
+++ b/app/code/Magento/Tax/view/adminhtml/templates/class/page/edit.phtml
@@ -11,10 +11,10 @@
getSaveButtonHtml(); ?>
getRenameFormHtml(); ?>
-
+
\ No newline at end of file
diff --git a/app/code/Magento/Tax/view/adminhtml/web/js/validate.js b/app/code/Magento/Tax/view/adminhtml/web/js/validate.js
new file mode 100644
index 0000000000000..a49f199ba56b6
--- /dev/null
+++ b/app/code/Magento/Tax/view/adminhtml/web/js/validate.js
@@ -0,0 +1,15 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+ 'jquery',
+ 'mage/mage'
+], function (jQuery) {
+ 'use strict';
+
+ return function (data, element) {
+ jQuery(element).mage('form').mage('validation');
+ };
+});
diff --git a/app/code/Magento/Wishlist/CustomerData/Wishlist.php b/app/code/Magento/Wishlist/CustomerData/Wishlist.php
index ce04887732f6d..d7dd27874d365 100644
--- a/app/code/Magento/Wishlist/CustomerData/Wishlist.php
+++ b/app/code/Magento/Wishlist/CustomerData/Wishlist.php
@@ -147,6 +147,14 @@ protected function getItemData(\Magento\Wishlist\Model\Item $wishlistItem)
*/
protected function getImageData($product)
{
+ /*Set variant product if it is configurable product.
+ It will show variant product image in sidebar instead of configurable product image.*/
+ $simpleOption = $product->getCustomOption('simple_product');
+ if ($simpleOption !== null) {
+ $optionProduct = $simpleOption->getProduct();
+ $product = $optionProduct;
+ }
+
/** @var \Magento\Catalog\Helper\Image $helper */
$helper = $this->imageHelperFactory->create()
->init($product, 'wishlist_sidebar_block');
diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less
index e1d1851267afa..1576141fe0596 100644
--- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less
+++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less
@@ -494,6 +494,16 @@
}
}
+ //
+ // Category page 1 column layout
+ // ---------------------------------------------
+
+ .catalog-category-view.page-layout-1column {
+ .column.main {
+ min-height: inherit;
+ }
+ }
+
}
//
diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less
index c64efa65ae2f9..980e3367678f1 100644
--- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/_module.less
@@ -562,6 +562,16 @@
}
}
}
+
+ //
+ // Category page 1 column layout
+ // ---------------------------------------------
+
+ .catalog-category-view.page-layout-1column {
+ .column.main {
+ min-height: inherit;
+ }
+ }
}
//
diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
index 7acb082bdff65..84f116c2c9547 100644
--- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
+++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
@@ -425,7 +425,7 @@
.product-item {
margin-left: calc(~'(100% - 4 * 24.439%) / 3');
- padding: 0;
+ padding: 5px;
width: 24.439%;
&:nth-child(4n + 1) {
diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/Language/_files/bar/en_gb/1.csv b/dev/tests/integration/testsuite/Magento/Framework/App/Language/_files/bar/en_gb/1.csv
index 0c13b51b55287..235d18468b739 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/App/Language/_files/bar/en_gb/1.csv
+++ b/dev/tests/integration/testsuite/Magento/Framework/App/Language/_files/bar/en_gb/1.csv
@@ -1,2 +1,3 @@
four and 75/100,4.75
-four and 5/10,4.50
\ No newline at end of file
+four and 5/10,4.50
+
diff --git a/lib/internal/Magento/Framework/App/Language/Dictionary.php b/lib/internal/Magento/Framework/App/Language/Dictionary.php
index a8dc20d9465a3..02ee6ca2c9579 100644
--- a/lib/internal/Magento/Framework/App/Language/Dictionary.php
+++ b/lib/internal/Magento/Framework/App/Language/Dictionary.php
@@ -193,7 +193,9 @@ private function readPackCsv($vendor, $package)
foreach ($foundCsvFiles as $foundCsvFile) {
$file = $directoryRead->openFile($foundCsvFile);
while (($row = $file->readCsv()) !== false) {
- $result[$row[0]] = $row[1];
+ if (is_array($row) && count($row) > 1) {
+ $result[$row[0]] = $row[1];
+ }
}
}
}
diff --git a/lib/web/css/source/lib/_navigation.less b/lib/web/css/source/lib/_navigation.less
index 56aa2e7ef86b9..b2ed4352a334a 100644
--- a/lib/web/css/source/lib/_navigation.less
+++ b/lib/web/css/source/lib/_navigation.less
@@ -355,6 +355,25 @@
overflow: visible !important;
}
+ &.parent {
+ > .level-top {
+ padding-right: 20px;
+
+ > .ui-menu-icon {
+ position: absolute;
+ right: 0;
+
+ .lib-icon-font(
+ @icon-down,
+ @_icon-font-size: 12px,
+ @_icon-font-line-height: 20px,
+ @_icon-font-text-hide: true,
+ @_icon-font-position: after
+ );
+ }
+ }
+ }
+
.submenu {
.lib-css(background, @_submenu-background-color);
.lib-css(border, @_submenu-border-width @_submenu-border-style @_submenu-border-color);
@@ -414,6 +433,26 @@
left: auto !important;
right: 100%;
}
+
+ li {
+ margin: 0;
+ &.parent {
+ > a {
+ > .ui-menu-icon {
+ position: absolute;
+ right: 3px;
+
+ .lib-icon-font(
+ @icon-next,
+ @_icon-font-size: 12px,
+ @_icon-font-line-height: 20px,
+ @_icon-font-text-hide: true,
+ @_icon-font-position: after
+ );
+ }
+ }
+ }
+ }
}
&.more {
diff --git a/lib/web/mage/trim-input.js b/lib/web/mage/trim-input.js
new file mode 100644
index 0000000000000..678192dcf61ac
--- /dev/null
+++ b/lib/web/mage/trim-input.js
@@ -0,0 +1,60 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+ 'jquery'
+], function ($) {
+ 'use strict';
+
+ $.widget('mage.trimInput', {
+ options: {
+ cache: {}
+ },
+
+ /**
+ * Widget initialization
+ * @private
+ */
+ _create: function () {
+ this.options.cache.input = $(this.element);
+ this._bind();
+ },
+
+ /**
+ * Event binding, will monitor change, keyup and paste events.
+ * @private
+ */
+ _bind: function () {
+ if (this.options.cache.input.length) {
+ this._on(this.options.cache.input, {
+ 'change': this._trimInput,
+ 'keyup': this._trimInput,
+ 'paste': this._trimInput
+ });
+ }
+ },
+
+ /**
+ * Trim value
+ * @private
+ */
+ _trimInput: function () {
+ var input = this._getInputValue().trim();
+
+ this.options.cache.input.val(input);
+ },
+
+ /**
+ * Get input value
+ * @returns {*}
+ * @private
+ */
+ _getInputValue: function () {
+ return this.options.cache.input.val();
+ }
+ });
+
+ return $.mage.trimInput;
+});
diff --git a/lib/web/modernizr/modernizr.js b/lib/web/modernizr/modernizr.js
index 9b4f68aaaaaa9..0833cfb105cee 100644
--- a/lib/web/modernizr/modernizr.js
+++ b/lib/web/modernizr/modernizr.js
@@ -910,7 +910,7 @@ window.Modernizr = (function( window, document, undefined ) {
bool = inputElem.checkValidity && inputElem.checkValidity() === false;
} else {
- // If the upgraded input compontent rejects the :) text, we got a winner
+ // If the upgraded input component rejects the :) text, we got a winner
bool = inputElem.value != smile;
}
}
diff --git a/lib/web/tiny_mce/classes/Formatter.js b/lib/web/tiny_mce/classes/Formatter.js
index 0cbca75ec504b..5f05d3f3015ad 100644
--- a/lib/web/tiny_mce/classes/Formatter.js
+++ b/lib/web/tiny_mce/classes/Formatter.js
@@ -445,7 +445,7 @@
childCount = getChildCount(node);
// Remove empty nodes but only if there is multiple wrappers and they are not block
- // elements so never remove single since that would remove the currrent empty block element where the caret is at
+ // elements so never remove single since that would remove the current empty block element where the caret is at
if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) {
dom.remove(node, 1);
return;
diff --git a/lib/web/tiny_mce/classes/dom/DOMUtils.js b/lib/web/tiny_mce/classes/dom/DOMUtils.js
index 783dbea1cacb9..eb8b4b7ab5d78 100644
--- a/lib/web/tiny_mce/classes/dom/DOMUtils.js
+++ b/lib/web/tiny_mce/classes/dom/DOMUtils.js
@@ -1106,7 +1106,7 @@
/**
* Returns a unique id. This can be useful when generating elements on the fly.
- * This method will not check if the element allready exists.
+ * This method will not check if the element already exists.
*
* @method uniqueId
* @param {String} p Optional prefix to add infront of all ids defaults to "mce_".
diff --git a/lib/web/tiny_mce/tiny_mce_jquery_src.js b/lib/web/tiny_mce/tiny_mce_jquery_src.js
index 0c03d0d0ade44..8b474eee25796 100644
--- a/lib/web/tiny_mce/tiny_mce_jquery_src.js
+++ b/lib/web/tiny_mce/tiny_mce_jquery_src.js
@@ -14451,7 +14451,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
childCount = getChildCount(node);
// Remove empty nodes but only if there is multiple wrappers and they are not block
- // elements so never remove single since that would remove the currrent empty block element where the caret is at
+ // elements so never remove single since that would remove the current empty block element where the caret is at
if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) {
dom.remove(node, 1);
return;
diff --git a/lib/web/tiny_mce/tiny_mce_prototype_src.js b/lib/web/tiny_mce/tiny_mce_prototype_src.js
index 0eb43989cb919..b6f9a42b48e7e 100644
--- a/lib/web/tiny_mce/tiny_mce_prototype_src.js
+++ b/lib/web/tiny_mce/tiny_mce_prototype_src.js
@@ -15301,7 +15301,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
childCount = getChildCount(node);
// Remove empty nodes but only if there is multiple wrappers and they are not block
- // elements so never remove single since that would remove the currrent empty block element where the caret is at
+ // elements so never remove single since that would remove the current empty block element where the caret is at
if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) {
dom.remove(node, 1);
return;
diff --git a/lib/web/tiny_mce/tiny_mce_src.js b/lib/web/tiny_mce/tiny_mce_src.js
index 7189ca9e1592d..e64998971ef7f 100644
--- a/lib/web/tiny_mce/tiny_mce_src.js
+++ b/lib/web/tiny_mce/tiny_mce_src.js
@@ -15275,7 +15275,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
childCount = getChildCount(node);
// Remove empty nodes but only if there is multiple wrappers and they are not block
- // elements so never remove single since that would remove the currrent empty block element where the caret is at
+ // elements so never remove single since that would remove the current empty block element where the caret is at
if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) {
dom.remove(node, 1);
return;
diff --git a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php
index 9d8502feb27c9..4a7a55c70c4bf 100644
--- a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php
@@ -1,6 +1,6 @@
+ *
* {bool}
*
*