Skip to content

Commit 5dfe914

Browse files
authored
Merge pull request #2790 from magento-mpi/mpi-PR-0207
Fixed issues: - MAGETWO-90496: Countries from default website set when edit order address - MAGETWO-90999: Bundle Product not appears in catalog after import - MAGETWO-60573: [GITHUB] Custom option price field disallows negative values #7333
2 parents a021f0f + 2dcfd92 commit 5dfe914

File tree

39 files changed

+1030
-452
lines changed

39 files changed

+1030
-452
lines changed

app/code/Magento/BundleImportExport/Model/Import/Product/Type/Bundle.php

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
*/
99
namespace Magento\BundleImportExport\Model\Import\Product\Type;
1010

11-
use \Magento\Framework\App\ObjectManager;
12-
use \Magento\Bundle\Model\Product\Price as BundlePrice;
13-
use \Magento\Catalog\Model\Product\Type\AbstractType;
14-
use \Magento\CatalogImportExport\Model\Import\Product;
15-
use \Magento\Store\Model\StoreManagerInterface;
11+
use Magento\Framework\App\ObjectManager;
12+
use Magento\Bundle\Model\Product\Price as BundlePrice;
13+
use Magento\Catalog\Model\Product\Type\AbstractType;
14+
use Magento\CatalogImportExport\Model\Import\Product;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\Bundle\Model\ResourceModel\Bundle as BundleResourceModel;
1617

1718
/**
1819
* Class Bundle
@@ -148,6 +149,11 @@ class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\Abst
148149
*/
149150
private $storeCodeToId = [];
150151

152+
/**
153+
* @var BundleResourceModel
154+
*/
155+
private $bundleResourceModel;
156+
151157
/**
152158
* @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $attrSetColFac
153159
* @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $prodAttrColFac
@@ -156,8 +162,8 @@ class Bundle extends \Magento\CatalogImportExport\Model\Import\Product\Type\Abst
156162
* @param \Magento\Framework\EntityManager\MetadataPool|null $metadataPool
157163
* @param Bundle\RelationsDataSaver|null $relationsDataSaver
158164
* @param StoreManagerInterface $storeManager
165+
* @param BundleResourceModel $bundleResourceModel
159166
* @throws \Magento\Framework\Exception\LocalizedException
160-
* @throws \RuntimeException
161167
*/
162168
public function __construct(
163169
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $attrSetColFac,
@@ -166,13 +172,16 @@ public function __construct(
166172
array $params,
167173
\Magento\Framework\EntityManager\MetadataPool $metadataPool = null,
168174
Bundle\RelationsDataSaver $relationsDataSaver = null,
169-
StoreManagerInterface $storeManager = null
175+
StoreManagerInterface $storeManager = null,
176+
BundleResourceModel $bundleResourceModel = null
170177
) {
171178
parent::__construct($attrSetColFac, $prodAttrColFac, $resource, $params, $metadataPool);
172179
$this->relationsDataSaver = $relationsDataSaver
173180
?: ObjectManager::getInstance()->get(Bundle\RelationsDataSaver::class);
174181
$this->storeManager = $storeManager
175182
?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
183+
$this->bundleResourceModel = $bundleResourceModel
184+
?: ObjectManager::getInstance()->get(BundleResourceModel::class);
176185
}
177186

178187
/**
@@ -389,13 +398,15 @@ public function saveData()
389398
if ($this->_type != $productData['type_id']) {
390399
continue;
391400
}
392-
$this->parseSelections($rowData, $productData[$this->getProductEntityLinkField()]);
401+
$productId = $productData[$this->getProductEntityLinkField()];
402+
$this->parseSelections($rowData, $productId);
393403
}
394404
if (!empty($this->_cachedOptions)) {
395405
$this->retrieveProducsByCachedSkus();
396406
$this->populateExistingOptions();
397407
$this->insertOptions();
398408
$this->insertSelections();
409+
$this->insertProductRelations();
399410
$this->clear();
400411
}
401412
}
@@ -643,6 +654,29 @@ protected function insertSelections()
643654
return $this;
644655
}
645656

657+
/**
658+
* Insert product relations.
659+
*
660+
* @return void
661+
*/
662+
private function insertProductRelations()
663+
{
664+
foreach ($this->_cachedOptions as $productId => $options) {
665+
$childIds = [];
666+
foreach ($options as $option) {
667+
foreach ($option['selections'] as $selection) {
668+
if (isset($this->_cachedSkuToProducts[$selection['sku']])) {
669+
$childIds[] = $this->_cachedSkuToProducts[$selection['sku']];
670+
}
671+
}
672+
}
673+
if (!empty($childIds)) {
674+
$childIds = array_unique($childIds);
675+
$this->bundleResourceModel->saveProductRelations($productId, $childIds);
676+
}
677+
}
678+
}
679+
646680
/**
647681
* Initialize attributes parameters for all attributes' sets.
648682
*

app/code/Magento/Catalog/Model/Product/Option/Validator/DefaultValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ protected function validateOptionType(Option $option)
132132
*/
133133
protected function validateOptionValue(Option $option)
134134
{
135-
return $this->isInRange($option->getPriceType(), $this->priceTypes) && !$this->isNegative($option->getPrice());
135+
return $this->isInRange($option->getPriceType(), $this->priceTypes);
136136
}
137137

138138
/**

app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ protected function isValidOptionPrice($priceType, $price, $storeId)
8383
if (!$priceType && !$price) {
8484
return true;
8585
}
86-
if (!$this->isInRange($priceType, $this->priceTypes) || $this->isNegative($price)) {
86+
if (!$this->isInRange($priceType, $this->priceTypes)) {
8787
return false;
8888
}
8989

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/DefaultValidatorTest.php

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,30 @@ public function isValidTitleDataProvider()
6060
{
6161
$mess = ['option required fields' => 'Missed values for option required fields'];
6262
return [
63-
['option_title', 'name 1.1', 'fixed', 10, new \Magento\Framework\DataObject(['store_id' => 1]), [], true],
64-
['option_title', 'name 1.1', 'fixed', 10, new \Magento\Framework\DataObject(['store_id' => 0]), [], true],
65-
[null, 'name 1.1', 'fixed', 10, new \Magento\Framework\DataObject(['store_id' => 1]), [], true],
66-
[null, 'name 1.1', 'fixed', 10, new \Magento\Framework\DataObject(['store_id' => 0]), $mess, false],
63+
['option_title', 'name 1.1', 'fixed', new \Magento\Framework\DataObject(['store_id' => 1]), [], true],
64+
['option_title', 'name 1.1', 'fixed', new \Magento\Framework\DataObject(['store_id' => 0]), [], true],
65+
[null, 'name 1.1', 'fixed', new \Magento\Framework\DataObject(['store_id' => 1]), [], true],
66+
[null, 'name 1.1', 'fixed', new \Magento\Framework\DataObject(['store_id' => 0]), $mess, false],
6767
];
6868
}
6969

7070
/**
7171
* @param $title
7272
* @param $type
7373
* @param $priceType
74-
* @param $price
7574
* @param $product
7675
* @param $messages
7776
* @param $result
7877
* @dataProvider isValidTitleDataProvider
7978
*/
80-
public function testIsValidTitle($title, $type, $priceType, $price, $product, $messages, $result)
79+
public function testIsValidTitle($title, $type, $priceType, $product, $messages, $result)
8180
{
82-
$methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', '__wakeup', 'getProduct'];
81+
$methods = ['getTitle', 'getType', 'getPriceType', '__wakeup', 'getProduct'];
8382
$valueMock = $this->createPartialMock(\Magento\Catalog\Model\Product\Option::class, $methods);
8483
$valueMock->expects($this->once())->method('getTitle')->will($this->returnValue($title));
8584
$valueMock->expects($this->any())->method('getType')->will($this->returnValue($type));
8685
$valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue($priceType));
87-
$valueMock->expects($this->once())->method('getPrice')->will($this->returnValue($price));
86+
// $valueMock->expects($this->once())->method('getPrice')->will($this->returnValue($price));
8887
$valueMock->expects($this->once())->method('getProduct')->will($this->returnValue($product));
8988
$this->assertEquals($result, $this->validator->isValid($valueMock));
9089
$this->assertEquals($messages, $this->validator->getMessages());
@@ -124,41 +123,4 @@ public function testIsValidFail($product)
124123
$this->assertFalse($this->validator->isValid($valueMock));
125124
$this->assertEquals($messages, $this->validator->getMessages());
126125
}
127-
128-
/**
129-
* Data provider for testValidationNegativePrice
130-
* @return array
131-
*/
132-
public function validationNegativePriceDataProvider()
133-
{
134-
return [
135-
['option_title', 'name 1.1', 'fixed', -12, new \Magento\Framework\DataObject(['store_id' => 1])],
136-
['option_title', 'name 1.1', 'fixed', -12, new \Magento\Framework\DataObject(['store_id' => 0])],
137-
];
138-
}
139-
140-
/**
141-
* @param $title
142-
* @param $type
143-
* @param $priceType
144-
* @param $price
145-
* @param $product
146-
* @dataProvider validationNegativePriceDataProvider
147-
*/
148-
public function testValidationNegativePrice($title, $type, $priceType, $price, $product)
149-
{
150-
$methods = ['getTitle', 'getType', 'getPriceType', 'getPrice', '__wakeup', 'getProduct'];
151-
$valueMock = $this->createPartialMock(\Magento\Catalog\Model\Product\Option::class, $methods);
152-
$valueMock->expects($this->once())->method('getTitle')->will($this->returnValue($title));
153-
$valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue($type));
154-
$valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue($priceType));
155-
$valueMock->expects($this->once())->method('getPrice')->will($this->returnValue($price));
156-
$valueMock->expects($this->once())->method('getProduct')->will($this->returnValue($product));
157-
158-
$messages = [
159-
'option values' => 'Invalid option value',
160-
];
161-
$this->assertFalse($this->validator->isValid($valueMock));
162-
$this->assertEquals($messages, $this->validator->getMessages());
163-
}
164126
}

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/FileTest.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ public function testIsValidSuccess()
5858
{
5959
$this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title'));
6060
$this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1'));
61-
$this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed'));
62-
$this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10));
61+
$this->valueMock->method('getPriceType')
62+
->willReturn('fixed');
63+
$this->valueMock->method('getPrice')
64+
->willReturn(10);
6365
$this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(10));
6466
$this->valueMock->expects($this->once())->method('getImageSizeY')->will($this->returnValue(15));
6567
$this->assertEmpty($this->validator->getMessages());
@@ -70,8 +72,10 @@ public function testIsValidWithNegativeImageSize()
7072
{
7173
$this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title'));
7274
$this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1'));
73-
$this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed'));
74-
$this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10));
75+
$this->valueMock->method('getPriceType')
76+
->willReturn('fixed');
77+
$this->valueMock->method('getPrice')
78+
->willReturn(10);
7579
$this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(-10));
7680
$this->valueMock->expects($this->never())->method('getImageSizeY');
7781
$messages = [
@@ -85,8 +89,10 @@ public function testIsValidWithNegativeImageSizeY()
8589
{
8690
$this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title'));
8791
$this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1'));
88-
$this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed'));
89-
$this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10));
92+
$this->valueMock->method('getPriceType')
93+
->willReturn('fixed');
94+
$this->valueMock->method('getPrice')
95+
->willReturn(10);
9096
$this->valueMock->expects($this->once())->method('getImageSizeX')->will($this->returnValue(10));
9197
$this->valueMock->expects($this->once())->method('getImageSizeY')->will($this->returnValue(-10));
9298
$messages = [

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/SelectTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function isValidSuccessDataProvider()
9090
]
9191
],
9292
[
93-
false,
93+
true,
9494
[
9595
'title' => 'Some Title',
9696
'price_type' => 'fixed',
@@ -163,7 +163,6 @@ public function testIsValidateWithInvalidData($priceType, $price, $title)
163163
public function isValidateWithInvalidDataDataProvider()
164164
{
165165
return [
166-
'invalid_price' => ['fixed', -10, 'Title'],
167166
'invalid_price_type' => ['some_value', '10', 'Title'],
168167
'empty_title' => ['fixed', 10, null]
169168
];

app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Validator/TextTest.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ public function testIsValidSuccess()
5858
{
5959
$this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title'));
6060
$this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1'));
61-
$this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed'));
62-
$this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10));
61+
$this->valueMock->method('getPriceType')
62+
->willReturn('fixed');
63+
$this->valueMock->method('getPrice')
64+
->willReturn(10);
6365
$this->valueMock->expects($this->once())->method('getMaxCharacters')->will($this->returnValue(10));
6466
$this->assertTrue($this->validator->isValid($this->valueMock));
6567
$this->assertEmpty($this->validator->getMessages());
@@ -69,8 +71,10 @@ public function testIsValidWithNegativeMaxCharacters()
6971
{
7072
$this->valueMock->expects($this->once())->method('getTitle')->will($this->returnValue('option_title'));
7173
$this->valueMock->expects($this->exactly(2))->method('getType')->will($this->returnValue('name 1.1'));
72-
$this->valueMock->expects($this->once())->method('getPriceType')->will($this->returnValue('fixed'));
73-
$this->valueMock->expects($this->once())->method('getPrice')->will($this->returnValue(10));
74+
$this->valueMock->method('getPriceType')
75+
->willReturn('fixed');
76+
$this->valueMock->method('getPrice')
77+
->willReturn(10);
7478
$this->valueMock->expects($this->once())->method('getMaxCharacters')->will($this->returnValue(-10));
7579
$messages = [
7680
'option values' => 'Invalid option value',

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ protected function getPriceFieldConfig($sortOrder)
923923
'addbeforePool' => $this->productOptionsPrice->prefixesToOptionArray(),
924924
'sortOrder' => $sortOrder,
925925
'validation' => [
926-
'validate-zero-or-greater' => true
926+
'validate-number' => true
927927
],
928928
],
929929
],

app/code/Magento/Customer/Model/Address/AbstractAddress.php

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
use Magento\Customer\Api\Data\RegionInterfaceFactory;
1414
use Magento\Customer\Model\Data\Address as AddressData;
1515
use Magento\Framework\Model\AbstractExtensibleModel;
16-
use Magento\Framework\App\ObjectManager;
17-
use Magento\Store\Model\ScopeInterface;
1816

1917
/**
2018
* Address abstract model
@@ -121,16 +119,6 @@ class AbstractAddress extends AbstractExtensibleModel implements AddressModelInt
121119
*/
122120
protected $dataObjectHelper;
123121

124-
/**
125-
* @var \Magento\Directory\Model\AllowedCountries
126-
*/
127-
private $allowedCountriesReader;
128-
129-
/**
130-
* @var \Magento\Customer\Model\Config\Share
131-
*/
132-
private $shareConfig;
133-
134122
/**
135123
* @param \Magento\Framework\Model\Context $context
136124
* @param \Magento\Framework\Registry $registry
@@ -166,9 +154,7 @@ public function __construct(
166154
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
167155
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
168156
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
169-
array $data = [],
170-
\Magento\Directory\Model\AllowedCountries $allowedCountriesReader = null,
171-
\Magento\Customer\Model\Config\Share $shareConfig = null
157+
array $data = []
172158
) {
173159
$this->_directoryData = $directoryData;
174160
$data = $this->_implodeArrayField($data);
@@ -180,10 +166,6 @@ public function __construct(
180166
$this->addressDataFactory = $addressDataFactory;
181167
$this->regionDataFactory = $regionDataFactory;
182168
$this->dataObjectHelper = $dataObjectHelper;
183-
$this->allowedCountriesReader = $allowedCountriesReader
184-
?: ObjectManager::getInstance()->get(\Magento\Directory\Model\AllowedCountries::class);
185-
$this->shareConfig = $shareConfig
186-
?: ObjectManager::getInstance()->get(\Magento\Customer\Model\Config\Share::class);
187169
parent::__construct(
188170
$context,
189171
$registry,
@@ -641,7 +623,8 @@ public function validate()
641623
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'countryId']);
642624
} else {
643625
//Checking if such country exists.
644-
if (!in_array($countryId, $this->getWebsiteAllowedCountries(), true)) {
626+
$countryCollection = $this->_directoryData->getCountryCollection($this->getStoreId());
627+
if (!in_array($countryId, $countryCollection->getAllIds(), true)) {
645628
$errors[] = __(
646629
'Invalid value of "%value" provided for the %fieldName field.',
647630
[
@@ -685,22 +668,6 @@ public function validate()
685668
return $errors;
686669
}
687670

688-
/**
689-
* Return allowed counties per website.
690-
*
691-
* @return array
692-
*/
693-
private function getWebsiteAllowedCountries(): array
694-
{
695-
$websiteId = null;
696-
697-
if (!$this->shareConfig->isGlobalScope()) {
698-
$websiteId = $this->getCustomer() ? $this->getCustomer()->getWebsiteId() : null;
699-
}
700-
701-
return $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_WEBSITE, $websiteId);
702-
}
703-
704671
/**
705672
* @return \Magento\Directory\Model\Region
706673
*/

app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
namespace Magento\Customer\Model\ResourceModel;
99

10+
use Magento\Customer\Api\Data\AddressInterface;
1011
use Magento\Customer\Model\Address as CustomerAddressModel;
1112
use Magento\Customer\Model\Customer as CustomerModel;
1213
use Magento\Customer\Model\ResourceModel\Address\Collection;
@@ -123,6 +124,7 @@ public function save(\Magento\Customer\Api\Data\AddressInterface $address)
123124
} else {
124125
$addressModel->updateData($address);
125126
}
127+
$addressModel->setStoreId($customerModel->getStoreId());
126128

127129
$errors = $addressModel->validate();
128130
if ($errors !== true) {

0 commit comments

Comments
 (0)