Skip to content

Commit bcd8dc1

Browse files
merge magento/2.3-develop into magento-trigger/MC-31567
2 parents e64331c + e71e92e commit bcd8dc1

File tree

29 files changed

+1102
-138
lines changed

29 files changed

+1102
-138
lines changed

app/code/Magento/Braintree/view/frontend/web/js/view/payment/3d-secure.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ define([
117117
options.bin = context.paymentPayload.details.bin;
118118
}
119119

120-
if (shippingAddress) {
120+
if (shippingAddress && this.isValidShippingAddress(shippingAddress)) {
121121
options.additionalInformation = {
122122
shippingGivenName: shippingAddress.firstname,
123123
shippingSurname: shippingAddress.lastname,
@@ -206,6 +206,25 @@ define([
206206
}
207207

208208
return false;
209+
},
210+
211+
/**
212+
* Validate shipping address
213+
*
214+
* @param {Object} shippingAddress
215+
* @return {Boolean}
216+
*/
217+
isValidShippingAddress: function (shippingAddress) {
218+
var isValid = false;
219+
220+
// check that required fields are not empty
221+
if (shippingAddress.firstname && shippingAddress.lastname && shippingAddress.telephone &&
222+
shippingAddress.street && shippingAddress.city && shippingAddress.regionCode &&
223+
shippingAddress.postcode && shippingAddress.countryId) {
224+
isValid = true;
225+
}
226+
227+
return isValid;
209228
}
210229
};
211230
});

app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ define(
9292
})
9393
.then(function (hostedFieldsInstance) {
9494
self.hostedFieldsInstance = hostedFieldsInstance;
95-
self.isPlaceOrderActionAllowed(true);
95+
self.isPlaceOrderActionAllowed(false);
9696
self.initFormValidationEvents(hostedFieldsInstance);
9797

9898
return self.hostedFieldsInstance;

app/code/Magento/Catalog/Test/Mftf/Test/CheckTierPricingOfProductsTest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<createData entity="Simple_US_Customer" stepKey="customer"/>
3737
<!--Login as admin-->
3838
<actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/>
39+
<createData entity="CustomerAccountSharingGlobal" stepKey="setConfigCustomerAccountToGlobal"/>
3940
</before>
4041

4142
<!--Create website, Sore adn Store View-->
@@ -328,6 +329,7 @@
328329
<actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="DeleteWebsite">
329330
<argument name="websiteName" value="secondWebsite"/>
330331
</actionGroup>
332+
<createData entity="CustomerAccountSharingDefault" stepKey="setConfigCustomerAccountDefault"/>
331333
<actionGroup ref="logout" stepKey="logout"/>
332334

333335
<!--Do reindex and flush cache-->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AssertStorefrontCheckoutCartEstimateShippingAndTaxAddressActionGroup">
12+
<annotations>
13+
<description>Check address data in Estimate Shipping And Tax section of shopping cart on storefront</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="country" type="string" defaultValue="{{US_Address_TX.country}}"/>
17+
<argument name="state" type="string" defaultValue="{{US_Address_TX.state}}"/>
18+
<argument name="postcode" type="string" defaultValue="{{US_Address_TX.postcode}}"/>
19+
</arguments>
20+
21+
<waitForElementVisible selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="waitForSubtotalVisible"/>
22+
<conditionalClick selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" dependentSelector="{{CheckoutCartSummarySection.country}}" visible="false" stepKey="expandEstimateShippingAndTaxIfNeeded" />
23+
<seeOptionIsSelected selector="{{CheckoutCartSummarySection.country}}" userInput="{{country}}" stepKey="checkCountry"/>
24+
<seeOptionIsSelected selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="{{state}}" stepKey="checkState" />
25+
<grabValueFrom selector="{{CheckoutCartSummarySection.postcode}}" stepKey="grabPostCodeText"/>
26+
<assertEquals message="Address postcode is invalid" stepKey="checkPostcode">
27+
<expectedResult type="string">{{postcode}}</expectedResult>
28+
<actualResult type="variable">grabPostCodeText</actualResult>
29+
</assertEquals>
30+
</actionGroup>
31+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontCheckoutCartFillEstimateShippingAndTaxActionGroup">
12+
<annotations>
13+
<description>Fill address data in Estimate Shipping And Tax section of shopping cart on storefront</description>
14+
</annotations>
15+
<arguments>
16+
<argument name="country" type="string" defaultValue="{{US_Address_TX.country}}"/>
17+
<argument name="state" type="string" defaultValue="{{US_Address_TX.state}}"/>
18+
<argument name="postcode" type="string" defaultValue="{{US_Address_TX.postcode}}"/>
19+
</arguments>
20+
21+
<conditionalClick selector="{{CheckoutCartSummarySection.estimateShippingAndTax}}" dependentSelector="{{CheckoutCartSummarySection.estimateShippingAndTaxSummary}}" visible="false" stepKey="openEestimateShippingAndTaxSection"/>
22+
<selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="{{country}}" stepKey="selectCountry"/>
23+
<selectOption selector="{{CheckoutCartSummarySection.stateProvince}}" userInput="{{state}}" stepKey="selectState"/>
24+
<waitForElementVisible selector="{{CheckoutCartSummarySection.postcode}}" stepKey="waitForPostCodeVisible"/>
25+
<fillField selector="{{CheckoutCartSummarySection.postcode}}" userInput="{{postcode}}" stepKey="selectPostCode"/>
26+
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDiappear"/>
27+
</actionGroup>
28+
</actionGroups>

app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,13 @@ public function execute()
320320
['customer' => $customer, 'request' => $this->getRequest()]
321321
);
322322

323-
if (isset($customerData['sendemail_store_id'])) {
323+
if (isset($customerData['sendemail_store_id']) && $customerData['sendemail_store_id'] !== false) {
324324
$customer->setStoreId($customerData['sendemail_store_id']);
325325
}
326326

327327
// Save customer
328328
if ($customerId) {
329+
$this->customerAccountManagement->validateCustomerStoreIdByWebsiteId($customer);
329330
$this->_customerRepository->save($customer);
330331

331332
$this->getEmailNotification()->credentialsChanged($customer, $currentCustomer->getEmail());

app/code/Magento/Customer/Model/AccountManagement.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,6 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash
872872
if ($customer->getId()) {
873873
$customer = $this->customerRepository->get($customer->getEmail());
874874
$websiteId = $customer->getWebsiteId();
875-
876875
if ($this->isCustomerInStore($websiteId, $customer->getStoreId())) {
877876
throw new InputException(__('This customer already exists in this store.'));
878877
}
@@ -896,13 +895,10 @@ public function createAccountWithPasswordHash(CustomerInterface $customer, $hash
896895
$customer->setWebsiteId($websiteId);
897896
}
898897

898+
$this->validateCustomerStoreIdByWebsiteId($customer);
899+
899900
// Update 'created_in' value with actual store name
900901
if ($customer->getId() === null) {
901-
$websiteId = $customer->getWebsiteId();
902-
if ($websiteId && !$this->isCustomerInStore($websiteId, $customer->getStoreId())) {
903-
throw new LocalizedException(__('The store view is not in the associated website.'));
904-
}
905-
906902
$storeName = $this->storeManager->getStore($customer->getStoreId())->getName();
907903
$customer->setCreatedIn($storeName);
908904
}
@@ -1144,6 +1140,22 @@ public function isCustomerInStore($customerWebsiteId, $storeId)
11441140
return in_array($storeId, $ids);
11451141
}
11461142

1143+
/**
1144+
* Validate customer store id by customer website id.
1145+
*
1146+
* @param CustomerInterface $customer
1147+
* @return bool
1148+
* @throws LocalizedException
1149+
*/
1150+
public function validateCustomerStoreIdByWebsiteId(CustomerInterface $customer)
1151+
{
1152+
if (!$this->isCustomerInStore($customer->getWebsiteId(), $customer->getStoreId())) {
1153+
throw new LocalizedException(__('The store view is not in the associated website.'));
1154+
}
1155+
1156+
return true;
1157+
}
1158+
11471159
/**
11481160
* Validate the Reset Password Token for a customer.
11491161
*

app/code/Magento/Customer/Model/Address/Validator/General.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Customer\Model\Address\Validator;
77

8+
use Magento\Customer\Api\AddressMetadataInterface;
89
use Magento\Customer\Model\Address\AbstractAddress;
910
use Magento\Customer\Model\Address\ValidatorInterface;
1011

@@ -87,6 +88,7 @@ private function checkRequiredFields(AbstractAddress $address)
8788
*/
8889
private function checkOptionalFields(AbstractAddress $address)
8990
{
91+
$this->reloadAddressAttributes($address);
9092
$errors = [];
9193
if ($this->isTelephoneRequired()
9294
&& !\Zend_Validate::is($address->getTelephone(), 'NotEmpty')
@@ -148,4 +150,17 @@ private function isFaxRequired()
148150
{
149151
return $this->eavConfig->getAttribute('customer_address', 'fax')->getIsRequired();
150152
}
153+
154+
/**
155+
* Reload address attributes for the certain store
156+
*
157+
* @param AbstractAddress $address
158+
* @return void
159+
*/
160+
private function reloadAddressAttributes(AbstractAddress $address): void
161+
{
162+
$attributeSetId = $address->getAttributeSetId() ?: AddressMetadataInterface::ATTRIBUTE_SET_ID_ADDRESS;
163+
$address->setData('attribute_set_id', $attributeSetId);
164+
$this->eavConfig->getEntityAttributes(AddressMetadataInterface::ENTITY_TYPE_ADDRESS, $address);
165+
}
151166
}

app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ protected function setUp()
231231
->getMock();
232232
$this->managementMock = $this->getMockBuilder(\Magento\Customer\Model\AccountManagement::class)
233233
->disableOriginalConstructor()
234-
->setMethods(['createAccount'])
234+
->setMethods(['createAccount', 'validateCustomerStoreIdByWebsiteId'])
235235
->getMock();
236236
$this->addressDataFactoryMock = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterfaceFactory::class)
237237
->disableOriginalConstructor()
@@ -501,6 +501,9 @@ public function testExecuteWithExistentCustomer()
501501
->with('customer/*/edit', ['id' => $customerId, '_current' => true])
502502
->willReturn(true);
503503

504+
$this->managementMock->method('validateCustomerStoreIdByWebsiteId')
505+
->willReturn(true);
506+
504507
$this->assertEquals($redirectMock, $this->model->execute());
505508
}
506509

0 commit comments

Comments
 (0)