diff --git a/app/code/Magento/Bundle/Model/Product/Price.php b/app/code/Magento/Bundle/Model/Product/Price.php index 83bfcbbabc2536ab0ee2f84525dcb4cca12aa883..d0aee24945f9d21df7c3d73350093206065b0429 100644 --- a/app/code/Magento/Bundle/Model/Product/Price.php +++ b/app/code/Magento/Bundle/Model/Product/Price.php @@ -533,6 +533,10 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price $prevGroup = $allCustomersGroupId; foreach ($prices as $price) { + if (empty($price['percentage_value'])) { + // can use only percentage tier price + continue; + } if ($price['cust_group'] != $custGroup && $price['cust_group'] != $allCustomersGroupId) { // tier not for current customer group nor is for all groups continue; @@ -553,8 +557,8 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price continue; } - if ($price['website_price'] > $prevPrice) { - $prevPrice = $price['website_price']; + if ($price['percentage_value'] > $prevPrice) { + $prevPrice = $price['percentage_value']; $prevQty = $price['price_qty']; $prevGroup = $price['cust_group']; } diff --git a/app/code/Magento/Bundle/Pricing/Price/TierPrice.php b/app/code/Magento/Bundle/Pricing/Price/TierPrice.php index cbbf45e2dbb5f01187760b73f96c251fae49c1c5..fab49292d9bdea9f2ee02e1762385b979e15bdb0 100644 --- a/app/code/Magento/Bundle/Pricing/Price/TierPrice.php +++ b/app/code/Magento/Bundle/Pricing/Price/TierPrice.php @@ -8,6 +8,7 @@ namespace Magento\Bundle\Pricing\Price; use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\PriceInfoInterface; /** * Bundle tier prices model @@ -32,8 +33,25 @@ class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice implements Disc public function getDiscountPercent() { if ($this->percent === null) { - $percent = parent::getValue(); - $this->percent = ($percent) ? max(0, min(100, 100 - $percent)) : null; + $prices = $this->getStoredTierPrices(); + $prevQty = PriceInfoInterface::PRODUCT_QUANTITY_DEFAULT; + $this->value = $prevPrice = false; + $priceGroup = $this->groupManagement->getAllCustomersGroup()->getId(); + + foreach ($prices as $price) { + if (!$this->canApplyTierPrice($price, $priceGroup, $prevQty) + || !isset($price['percentage_value']) + || !is_numeric($price['percentage_value']) + ) { + continue; + } + if (false === $prevPrice || $this->isFirstPriceBetter($price['website_price'], $prevPrice)) { + $prevPrice = $price['website_price']; + $prevQty = $price['price_qty']; + $priceGroup = $price['cust_group']; + $this->percent = max(0, min(100, 100 - $price['percentage_value'])); + } + } } return $this->percent; } @@ -90,13 +108,4 @@ class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice implements Disc { return true; } - - /** - * @param AmountInterface $amount - * @return float - */ - public function getSavePercent(AmountInterface $amount) - { - return round($amount->getBaseAmount()); - } } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php index e97f0bbc1558dc3c63e02ef2c894b0d4423a61b2..9f7952e7ae8c882a5b747f9fd24855feea7c380e 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/PriceTest.php @@ -90,7 +90,6 @@ class PriceTest extends \PHPUnit_Framework_TestCase false ); $scopeConfig = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $objectManagerHelper = new ObjectManagerHelper($this); $this->model = $objectManagerHelper->getObject( \Magento\Bundle\Model\Product\Price::class, @@ -191,7 +190,6 @@ class PriceTest extends \PHPUnit_Framework_TestCase $dataObjectMock->expects($this->once()) ->method('getValue') ->willReturn($value); - $this->assertEquals(0, $this->model->getTotalBundleItemsPrice($productMock)); } @@ -245,7 +243,6 @@ class PriceTest extends \PHPUnit_Framework_TestCase $dataObjectMock->expects($this->once()) ->method('getValue') ->willReturn('a:1:{i:0;s:1:"1";}'); - $productTypeMock->expects($this->once()) ->method('getSelectionsByIds') ->with([1], $productMock) diff --git a/app/code/Magento/Bundle/Test/Unit/Pricing/Price/TierPriceTest.php b/app/code/Magento/Bundle/Test/Unit/Pricing/Price/TierPriceTest.php index 7b1f6181bb6f8ddc5951ce69e7564b7e2d1b1536..15bc06c2c6437d450ca480479b08a2cf1900d0de 100644 --- a/app/code/Magento/Bundle/Test/Unit/Pricing/Price/TierPriceTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Pricing/Price/TierPriceTest.php @@ -188,9 +188,17 @@ class TierPriceTest extends \PHPUnit_Framework_TestCase */ public function testGetSavePercent($baseAmount, $savePercent) { + $basePrice = 10.; $amount = $this->getMockForAbstractClass(\Magento\Framework\Pricing\Amount\AmountInterface::class); $amount->expects($this->once())->method('getBaseAmount')->willReturn($baseAmount); + $price = $this->getMock(\Magento\Framework\Pricing\Price\PriceInterface::class); + $price->expects($this->any()) + ->method('getValue') + ->will($this->returnValue($basePrice)); + $this->priceInfo->expects($this->any()) + ->method('getPrice') + ->will($this->returnValue($price)); $this->assertEquals($savePercent, $this->model->getSavePercent($amount)); } @@ -200,10 +208,8 @@ class TierPriceTest extends \PHPUnit_Framework_TestCase public function providerForTestGetSavePercent() { return [ - 'no fraction' => [10.0000, 10], - 'lower half' => [10.1234, 10], - 'half way' => [10.5000, 11], - 'upper half' => [10.6789, 11], + 'no fraction' => [9.0000, 10], + 'lower half' => [9.1234, 9], ]; } } diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index 538c80d9b1cf27af4ba14c911b0d0a6913c403c7..4012af357e2c50e31c1052adae15ee1b1a4931bf 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -14,6 +14,8 @@ use Magento\Ui\Component\Container; use Magento\Ui\Component\DynamicRows; use Magento\Ui\Component\Form; use Magento\Ui\Component\Modal; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; /** * Create Ship Bundle Items and Affect Bundle Product Selections fields @@ -73,6 +75,7 @@ class BundlePanel extends AbstractModifier */ public function modifyMeta(array $meta) { + $meta = $this->removeFixedTierPrice($meta); $path = $this->arrayManager->findPath(static::CODE_BUNDLE_DATA, $meta, null, 'children'); $meta = $this->arrayManager->merge( @@ -178,6 +181,43 @@ class BundlePanel extends AbstractModifier return $meta; } + /** + * Remove option with fixed tier price from config. + * + * @param array $meta + * @return array + */ + private function removeFixedTierPrice(array $meta) + { + $tierPricePath = $this->arrayManager->findPath( + ProductAttributeInterface::CODE_TIER_PRICE, + $meta, + null, + 'children' + ); + $pricePath = $this->arrayManager->findPath( + ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE, + $meta, + $tierPricePath + ); + $pricePath = $this->arrayManager->slicePath($pricePath, 0, -1) . '/value_type/arguments/data/options'; + + $price = $this->arrayManager->get($pricePath, $meta); + $meta = $this->arrayManager->remove($pricePath, $meta); + foreach ($price as $key => $item) { + if ($item['value'] == ProductPriceOptionsInterface::VALUE_FIXED) { + unset($price[$key]); + } + } + $meta = $this->arrayManager->merge( + $this->arrayManager->slicePath($pricePath, 0, -1), + $meta, + ['options' => $price] + ); + + return $meta; + } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Bundle/etc/adminhtml/di.xml b/app/code/Magento/Bundle/etc/adminhtml/di.xml index ca93dd5365160fd84372425a11fd5aff32972851..19b683027dfa14062883d4d80430f68a7c6ce49e 100644 --- a/app/code/Magento/Bundle/etc/adminhtml/di.xml +++ b/app/code/Magento/Bundle/etc/adminhtml/di.xml @@ -27,11 +27,11 @@ <argument name="modifiers" xsi:type="array"> <item name="bundle" xsi:type="array"> <item name="class" xsi:type="string">Magento\Bundle\Ui\DataProvider\Product\Form\Modifier\Composite</item> - <item name="sortOrder" xsi:type="number">125</item> + <item name="sortOrder" xsi:type="number">180</item> </item> <item name="bundle_stock_data" xsi:type="array"> <item name="class" xsi:type="string">Magento\Bundle\Ui\DataProvider\Product\Form\Modifier\StockData</item> - <item name="sortOrder" xsi:type="number">126</item> + <item name="sortOrder" xsi:type="number">190</item> </item> </argument> </arguments> diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml index 2d3913d72e579302ac9cd1f0e23d6b235f9c6b23..3425b9323ed4d4e18fd8be5342a4139be87291f3 100644 --- a/app/code/Magento/Bundle/etc/di.xml +++ b/app/code/Magento/Bundle/etc/di.xml @@ -130,4 +130,5 @@ </argument> </arguments> </type> + </config> diff --git a/app/code/Magento/Bundle/view/base/templates/product/price/tier_prices.phtml b/app/code/Magento/Bundle/view/base/templates/product/price/tier_prices.phtml index 3285603c431a219f76698b9e5e8d41571b285c11..63f090acf34dfb477521f992b2ee0f8d1eb6ff17 100644 --- a/app/code/Magento/Bundle/view/base/templates/product/price/tier_prices.phtml +++ b/app/code/Magento/Bundle/view/base/templates/product/price/tier_prices.phtml @@ -22,7 +22,7 @@ $tierPrices = $tierPriceModel->getTierPriceList(); <?php /* @escapeNotVerified */ echo __( 'Buy %1 with %2 discount each', $price['price_qty'], - '<strong class="benefit">' . $tierPriceModel->getSavePercent($price['price']) . '%</strong>' + '<strong class="benefit">' . round($price['percentage_value']) . '%</strong>' ); ?> </li> <?php endforeach; ?> diff --git a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php index b994c787bee7aa76f8a4baa3648bcbb2c0e4ee27..5e518df37db1a574f25fe008510e75742cdffa9c 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php +++ b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php @@ -23,7 +23,7 @@ class Price implements ProductPriceOptionsInterface { return [ ['value' => self::VALUE_FIXED, 'label' => __('Fixed')], - ['value' => self::VALUE_PERCENT, 'label' => __('Percent')], + ['value' => self::VALUE_PERCENT, 'label' => __('Discount')], ]; } } diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php index 480f8e8942e87f200ce3829641ea026d351b1967..460204a478d9d75ac86dbaa4e8d3684ea26b8812 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -157,6 +157,7 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr $data = parent::modifyPriceData($object, $data); foreach ($data as $key => $tierPrice) { if ($this->getPercentage($tierPrice)) { + $data[$key]['price'] = $object->getPrice() * (1 - $this->getPercentage($tierPrice) / 100); $data[$key]['website_price'] = $object->getPrice() * (1 - $this->getPercentage($tierPrice) / 100); } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index ac511edcf2e5338eba6b83c60cf38a749406cf89..9b382464e8e2392fb07d81c070bae66cce7c203f 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -109,6 +109,7 @@ class TierPrice extends AbstractModifier 'label' => __('Price'), 'enableLabel' => true, 'dataScope' => '', + 'additionalClasses' => 'control-grouped', 'sortOrder' => isset($priceMeta['arguments']['data']['config']['sortOrder']) ? $priceMeta['arguments']['data']['config']['sortOrder'] : 40, ], diff --git a/app/code/Magento/Persistent/Model/Observer.php b/app/code/Magento/Persistent/Model/Observer.php index 283d7bb45a5e832b0f4450a7633f6d27056d85ca..392d88a29a58137c04209a91107a4a4cc2f7001d 100644 --- a/app/code/Magento/Persistent/Model/Observer.php +++ b/app/code/Magento/Persistent/Model/Observer.php @@ -121,6 +121,13 @@ class Observer public function emulateTopLinks($block) { $this->_applyAccountLinksPersistentData(); - $block->removeLinkByUrl($this->_url->getUrl('customer/account/login')); + /** @var \Magento\Framework\View\Element\Html\Link[] $links */ + $links = $block->getLinks(); + $removeLink = $this->_url->getUrl('customer/account/login'); + foreach ($links as $link) { + if ($link->getHref() == $removeLink) { + $this->_layout->unsetChild($block->getNameInLayout(), $link->getNameInLayout()); + } + } } } diff --git a/app/design/adminhtml/Magento/backend/Magento_Catalog/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Catalog/web/css/source/_module.less index 304f895a85b969dfe95acd4e3dddb0607940432f..77a769d8f5a36cc4788031b5efa4d57c85481106 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Catalog/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Catalog/web/css/source/_module.less @@ -78,3 +78,19 @@ margin-top: -@indent__base; } } + +// +// Advanced Price panel +// --------------------------------------------- + +.admin__control-fields { + .control-grouped { + .lib-vendor-prefix-display(inline-flex); + .lib-vendor-prefix-flex-direction(row); + + .admin__field + .admin__field { + margin-left: @indent__s; + margin-top: 0; + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php index 1bc689d8e1b1e3009bbf2f3fc563b3aa51ccc3c7..f8266026b3927798fa2a04128deb65a70254188e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductTierPriceInCart.php @@ -110,7 +110,7 @@ class AssertProductTierPriceInCart extends AbstractConstraint { $tierPrice = $product->getDataFieldConfig('tier_price')['source']->getData()[0]; - if ($tierPrice['value_type'] === "Percent") { + if ($tierPrice['value_type'] === "Discount") { $this->fixtureActualPrice = $this->fixturePrice * (1 - $tierPrice['percentage_value'] / 100); } else { $this->fixtureActualPrice = $tierPrice['price']; diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml index 2f517f4d6cf3cc03020abc575d4e91cd7f7188da..9581427d16ec6f9e597e420dcee0329c2dddee32 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml @@ -92,7 +92,7 @@ <dataset name="custom_with_percentage_discount"> <field name="0" xsi:type="array"> - <item name="value_type" xsi:type="string">Percent</item> + <item name="value_type" xsi:type="string">Discount</item> <item name="percentage_value" xsi:type="string">3</item> <item name="website" xsi:type="string">All Websites [USD]</item> <item name="price_qty" xsi:type="string">10</item> diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/DynamicBundleWithTierPriceCalculatorTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/DynamicBundleWithTierPriceCalculatorTest.php index 0be5adcb304f772218e588795f3f6ef26ce0721c..c2c62aa2ce093e3b52502ec5c234d3932cdbe3b4 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/DynamicBundleWithTierPriceCalculatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/DynamicBundleWithTierPriceCalculatorTest.php @@ -201,7 +201,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -239,7 +240,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -281,7 +283,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -323,7 +326,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -365,7 +369,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -422,7 +427,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -479,7 +485,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -536,7 +543,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -578,7 +586,8 @@ class DynamicBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; $tierPriceSimpleProductData = [ diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundleWithTierPriceCalculatorTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundleWithTierPriceCalculatorTest.php index bd148080631aea892cccb0fab6fd0321d08c231b..aa020fe1f5a2b89e6d1e1eb922c0dee8412f4de7 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundleWithTierPriceCalculatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundleWithTierPriceCalculatorTest.php @@ -495,7 +495,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -544,7 +545,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -601,7 +603,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -664,7 +667,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -727,7 +731,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -790,7 +795,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ @@ -872,7 +878,8 @@ class FixedBundleWithTierPriceCalculatorTest extends BundlePriceAbstract $tierPriceData = [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 1, - 'value' => 50 + 'value' => 50, + 'extension_attributes' => new \Magento\Framework\DataObject(['percentage_value' => 50]) ]; return [ diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing.php index 6d6d10ce4d220fc45047d140621a784ea44413c6..9574948dae900e292e38d55a306d4a7fe8706955 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_tier_pricing.php @@ -41,18 +41,21 @@ $product->setTypeId('bundle') 'cust_group' => \Magento\Customer\Model\GroupManagement::CUST_GROUP_ALL, 'price_qty' => 2, 'price' => 8, + 'percentage_value' => 8 ], [ 'website_id' => 0, 'cust_group' => \Magento\Customer\Model\GroupManagement::CUST_GROUP_ALL, 'price_qty' => 5, 'price' => 30, + 'percentage_value' => 30 ], [ 'website_id' => 0, 'cust_group' => \Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID, 'price_qty' => 3, 'price' => 20, + 'percentage_value' => 20 ], ] ) diff --git a/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php index 5617eca9a0e7e24694c151d508ed09a4cd547999..1bdffb253ae1f06f24647cf7efbc85d0801286f9 100644 --- a/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php @@ -16,12 +16,27 @@ class AttributeSetsFixture extends Fixture */ protected $priority = 25; + /** + * Cache for attribute IDs. + * + * @var array + */ + private $attributeIdsCache = []; + + /** + * Quantity of unique attributes to generate. Zero means infinity. + * + * @var int + */ + protected $uniqueAttributesQuantity = 0; + /** * {@inheritdoc} */ public function execute() { - $attributeSets = $this->fixtureModel->getValue('attribute_sets', null); + $this->populateUniqueAttributesQuantity(); + $attributeSets = $this->getAttributeSetsFixtureValue(); if ($attributeSets === null) { return; } @@ -71,37 +86,81 @@ class AttributeSetsFixture extends Fixture $attributesData = array_key_exists(0, $attributeSetData['attributes']['attribute']) ? $attributeSetData['attributes']['attribute'] : [$attributeSetData['attributes']['attribute']]; foreach ($attributesData as $attributeData) { - //Create Attribute - /** @var \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory $attributeFactory */ - $attributeFactory = $this->fixtureModel->getObjectManager()->create( - \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class - ); - - $optionsData = array_key_exists(0, $attributeData['options']['option']) - ? $attributeData['options']['option'] : [$attributeData['options']['option']]; - $options = []; - foreach ($optionsData as $optionData) { - /** @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory */ - $optionFactory = $this->fixtureModel->getObjectManager()->create( - \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class + if ($this->uniqueAttributesQuantity === 0 + || (count($this->attributeIdsCache) < $this->uniqueAttributesQuantity)) { + //Create Attribute + /** @var \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory $attributeFactory */ + $attributeFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class ); - $option = $optionFactory->create(['data' => $optionData]); - $options[] = $option; - } - $attribute = $attributeFactory->create(['data' => $attributeData]); - $attribute->setOptions($options); + $optionsData = array_key_exists(0, $attributeData['options']['option']) + ? $attributeData['options']['option'] : [$attributeData['options']['option']]; + $options = []; + foreach ($optionsData as $optionData) { + /** @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory */ + $optionFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class + ); + $option = $optionFactory->create(['data' => $optionData]); + $options[] = $option; + } - $result = $attributeRepository->save($attribute); - $attributeId = $result->getAttributeId(); + $attribute = $attributeFactory->create(['data' => $attributeData]); + $attribute->setOptions($options); + $result = $attributeRepository->save($attribute); + $attributeId = $result->getAttributeId(); + $this->fillAttributeIdsCache($attributeId); + } else { + $attributeId = $this->getAttributeIdFromCache(); + } //Associate Attribute to Attribute Set $sortOrder = 3; + $attributeManagement->assign($attributeSetId, $attributeGroupId, $attributeId, $sortOrder); } } } + /** + * Get attribute ID from cache. + * + * @return int + */ + private function getAttributeIdFromCache() + { + $attributeId = next($this->attributeIdsCache); + if ($attributeId === false) { + $attributeId = reset($this->attributeIdsCache); + } + + return $attributeId; + } + + /** + * Fill attribute IDs cache. + * + * @param int $attributeId + * @return void + */ + private function fillAttributeIdsCache($attributeId) + { + if ($this->uniqueAttributesQuantity !== 0) { + $this->attributeIdsCache[] = $attributeId; + } + } + + /** + * Populate quantity of unique attributes to generate. + * + * @return void + */ + protected function populateUniqueAttributesQuantity() + { + $this->uniqueAttributesQuantity = $this->fixtureModel->getValue('unique_attributes_quantity', 0); + } + /** * {@inheritdoc} */ @@ -119,4 +178,14 @@ class AttributeSetsFixture extends Fixture 'attribute_sets' => 'Attribute Sets' ]; } + + /** + * Get attribute sets fixture value. + * + * @return array|null + */ + protected function getAttributeSetsFixtureValue() + { + return $this->fixtureModel->getValue('attribute_sets', null); + } } diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php index 2340de71cf78363ed00fd9248577e7479b6dc012..9e84578281c5d65b8a84b384aab699b266c7286b 100644 --- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php @@ -25,6 +25,13 @@ class ConfigurableProductsFixture extends SimpleProductsFixture */ protected $searchConfig; + /** + * Variations count. + * + * @var int + */ + protected $variationsCount; + //@codingStandardsIgnoreStart /** * Get CSV template headers @@ -169,7 +176,7 @@ class ConfigurableProductsFixture extends SimpleProductsFixture ) { return [ - 'sku' => 'Configurable Product %s' . $suffix, + 'sku' => $this->getConfigurableProductSkuPattern() . $suffix, 'store_view_code' => '', 'attribute_set_code' => $attributeSetClosure, 'additional_attributes' => $additionalAttributesClosure, @@ -225,8 +232,8 @@ class ConfigurableProductsFixture extends SimpleProductsFixture 'updated_at' => '2013-10-25 15:12:39', 'upsell_tgtr_position_behavior' => '', 'upsell_tgtr_position_limit' => '', - 'url_key' => "configurable-product-%s{$suffix}", - 'url_path' => "configurable-product-%s{$suffix}", + 'url_key' => $this->getUrlKeyPrefix() . "{$suffix}", + 'url_path' => $this->getUrlKeyPrefix() . "{$suffix}", 'visibility' => 'Catalog, Search', 'weight' => '', 'qty' => 333, @@ -305,7 +312,7 @@ class ConfigurableProductsFixture extends SimpleProductsFixture $data = []; for ($i = 1; $i <= $optionsNumber; $i++) { $productData = [ - 'sku' => "Configurable Product %s-option {$i}{$suffix}", + 'sku' => $this->getConfigurableOptionSkuPattern() . "{$i}{$suffix}", 'store_view_code' => '', 'attribute_set_code' => $attributeSetClosure, 'additional_attributes' => $additionalAttributesClosure, @@ -361,8 +368,8 @@ class ConfigurableProductsFixture extends SimpleProductsFixture 'updated_at' => '2013-10-25 15:12:32', 'upsell_tgtr_position_behavior' => '', 'upsell_tgtr_position_limit' => '', - 'url_key' => "simple-of-configurable-product-{$suffix}-%s-option-{$i}", - 'url_path' => "simple-of-configurable-product-{$suffix}-%s-option-{$i}", + 'url_key' => $this->getOptionUrlKeyPrefix() . "-{$suffix}-%s-option-{$i}", + 'url_path' => $this->getOptionUrlKeyPrefix() . "-{$suffix}-%s-option-{$i}", 'variations' => '', 'variations_1382710717' => '', 'variations_1382710773' => '', @@ -431,7 +438,7 @@ class ConfigurableProductsFixture extends SimpleProductsFixture */ public function execute() { - $configurableProductsCount = $this->fixtureModel->getValue('configurable_products', 0); + $configurableProductsCount = $this->getConfigurableProductsValue(); if (!$configurableProductsCount) { return; } @@ -440,170 +447,147 @@ class ConfigurableProductsFixture extends SimpleProductsFixture $maxAmountOfWordsShortDescription = $this->getSearchConfigValue('max_amount_of_words_short_description'); $minAmountOfWordsDescription = $this->getSearchConfigValue('min_amount_of_words_description'); $minAmountOfWordsShortDescription = $this->getSearchConfigValue('min_amount_of_words_short_description'); + $configurableProductsWithAttributes = []; - $attributes = $this->getAttributes(); - $searchTerms = $this->getSearchTerms(); - $this->fixtureModel->resetObjectManager(); - $result = $this->getCategoriesAndWebsites(); - $variationCount = $this->fixtureModel->getValue('configurable_products_variation', 3); - $result = array_values($result); - $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv')); - - $productWebsiteClosure = function ($index) use ($result) { - return $result[$index % count($result)][0]; - }; - $productCategoryClosure = function ($index) use ($result) { - return $result[$index % count($result)][2] . '/' . $result[$index % count($result)][1]; - }; - $shortDescriptionClosure = function ($index) - use ( - $searchTerms, - $simpleProductsCount, - $configurableProductsCount, - $dataGenerator, - $maxAmountOfWordsShortDescription, - $minAmountOfWordsShortDescription - ) - { - $count = $searchTerms === null - ? 0 - : round( - $searchTerms[$index % count($searchTerms)]['count'] * ( - $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) - ) - ); - mt_srand($index); - return $dataGenerator->generate( - $minAmountOfWordsShortDescription, - $maxAmountOfWordsShortDescription, - 'shortDescription-' . $index - ) . ($index <= ($count * count($searchTerms)) ? ' ' - . $searchTerms[$index % count($searchTerms)]['term'] : ''); - }; - $descriptionClosure = function ($index) - use ( - $searchTerms, - $simpleProductsCount, - $configurableProductsCount, - $dataGenerator, - $maxAmountOfWordsDescription, - $minAmountOfWordsDescription - ) - { - $count = $searchTerms === null - ? 0 - : round( - $searchTerms[$index % count($searchTerms)]['count'] * ( - $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) - ) - ); - mt_srand($index); - return $dataGenerator->generate( - $minAmountOfWordsDescription, - $maxAmountOfWordsDescription, - 'description-' . $index - ) . ($index <= ($count * count($searchTerms)) - ? ' ' . $searchTerms[$index % count($searchTerms)]['term'] : ''); - }; - $priceClosure = function($index) { - mt_srand($index); - switch (mt_rand(0,3)) { - case 0: return 9.99; - case 1: return 5; - case 2: return 1; - case 3: return mt_rand(1,10000)/10; - } - }; - $attributeSetClosure = function($index) use ($attributes, $result) { - mt_srand($index); - $attributeSet = (count(array_keys($attributes)) > (($index - 1) % count($result)) - ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); - return $attributeSet; - }; - $variationClosure = function($index, $variationIndex) use ($attributes, $result, $variationCount) { - mt_srand($index); - $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) - ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); - $skus = []; - for ($i=1; $i <= $variationCount; $i++) { - $skus[] = 'sku=Configurable Product ' . $index . '-option ' . $i; - } - $values = []; - if ($attributeSetCode == 'Default') { - for ($i=1; $i <= $variationCount; $i++) { - $values[] = 'configurable_variation=option ' . $i; - } + if ($this->getAdditionalConfigurableProductsVariations() === null) { + $configurableProductsWithAttributes[$configurableProductsCount] + = $this->getConfigurableProductsVariationsValue(); + } else { + if (strpos($this->getAdditionalConfigurableProductsVariations(), ',')) { + $variations = explode(',', $this->getAdditionalConfigurableProductsVariations()); } else { - for ($i=$variationCount; $i > 0; $i--) { - $attributeValues = ''; - foreach ($attributes[$attributeSetCode] as $attribute) { - $attributeValues = $attributeValues . $attribute['name'] . "=" . - $attribute['values'][($variationIndex - $i) % count($attribute['values'])] . ","; - } - $values [] = $attributeValues; - } + $variations = [$this->getAdditionalConfigurableProductsVariations()]; } - $variations = []; - for ($i=0; $i < $variationCount; $i++) { - $variations[] = trim(implode(",",[$skus[$i],$values[$i]]), ","); + + foreach ($variations as $variation) { + $value = explode(':', $variation); + $configurableProductsWithAttributes[$value[0]] = $value[1]; } - return implode("|",$variations); - }; - $additionalAttributesClosure = function($index, $variationIndex) use ($attributes, $result) { - $attributeValues = ''; - mt_srand($index); - $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) - ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); - if ($attributeSetCode !== 'Default' ) { - foreach ($attributes[$attributeSetCode] as $attribute) { - $attributeValues = $attributeValues . $attribute['name'] . "=" . - $attribute['values'][$variationIndex % count($attribute['values'])] . ","; + } + + foreach ($configurableProductsWithAttributes as $productsCount => $variationsCount) { + $this->variationsCount = $variationsCount; + $configurableProductsCount = $productsCount; + $attributes = $this->getAttributes(); + $searchTerms = $this->getSearchTerms(); + $this->fixtureModel->resetObjectManager(); + $result = $this->getCategoriesAndWebsites(); + $result = array_values($result); + $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv')); + + $productWebsiteClosure = function ($index) use ($result) { + return $result[$index % count($result)][0]; + }; + $productCategoryClosure = function ($index) use ($result) { + return $result[$index % count($result)][2] . '/' . $result[$index % count($result)][1]; + }; + $shortDescriptionClosure = function ($index) + use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsShortDescription, + $minAmountOfWordsShortDescription + ) { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + mt_srand($index); + return $dataGenerator->generate( + $minAmountOfWordsShortDescription, + $maxAmountOfWordsShortDescription, + 'shortDescription-' . $index + ) . ($index <= ($count * count($searchTerms)) ? ' ' + . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $descriptionClosure = function ($index) + use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsDescription, + $minAmountOfWordsDescription + ) { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + mt_srand($index); + return $dataGenerator->generate( + $minAmountOfWordsDescription, + $maxAmountOfWordsDescription, + 'description-' . $index + ) . ($index <= ($count * count($searchTerms)) + ? ' ' . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $priceClosure = function ($index) { + mt_srand($index); + switch (mt_rand(0, 3)) { + case 0: + return 9.99; + case 1: + return 5; + case 2: + return 1; + case 3: + return mt_rand(1, 10000) / 10; } - } - return trim($attributeValues, ","); - }; - /** - * Create configurable products - */ - $pattern = new Pattern(); - $pattern->setHeaders($this->getHeaders()); - $pattern->setRowsSet( - $this->getRows( - $productCategoryClosure, - $productWebsiteClosure, - $shortDescriptionClosure, - $descriptionClosure, - $priceClosure, - $attributeSetClosure, - $additionalAttributesClosure, - $variationClosure, - $variationCount - ) - ); + }; + $attributeSetClosure = $this->getAttributeSetClosure($attributes, $result); + $variationClosure = $this->getVariationsClosure($attributes, $result, $variationsCount); + $additionalAttributesClosure = $this->getAdditionalAttributesClosure($attributes, $result); + /** + * Create configurable products + */ + $pattern = new Pattern(); + $pattern->setHeaders($this->getHeaders()); + $pattern->setRowsSet( + $this->getRows( + $productCategoryClosure, + $productWebsiteClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure, + $variationClosure, + $variationsCount + ) + ); - /** @var \Magento\ImportExport\Model\Import $import */ - $import = $this->fixtureModel->getObjectManager()->create( - \Magento\ImportExport\Model\Import::class, - [ - 'data' => [ - 'entity' => 'catalog_product', - 'behavior' => 'append', - 'validation_strategy' => 'validation-stop-on-errors', - ], - ] - ); + /** @var \Magento\ImportExport\Model\Import $import */ + $import = $this->fixtureModel->getObjectManager()->create( + \Magento\ImportExport\Model\Import::class, + [ + 'data' => [ + 'entity' => 'catalog_product', + 'behavior' => 'append', + 'validation_strategy' => 'validation-stop-on-errors', + ], + ] + ); - $source = $this->fixtureModel->getObjectManager()->create( - Generator::class, - ['rowPattern' => $pattern, 'count' => $configurableProductsCount] - ); - // it is not obvious, but the validateSource() will actually save import queue data to DB - if (!$import->validateSource($source)) { - throw new \Exception($import->getFormatedLogTrace()); - } - // this converts import queue into actual entities - if (!$import->importSource()) { - throw new \Exception($import->getFormatedLogTrace()); + $source = $this->fixtureModel->getObjectManager()->create( + Generator::class, + ['rowPattern' => $pattern, 'count' => $configurableProductsCount] + ); + // it is not obvious, but the validateSource() will actually save import queue data to DB + if (!$import->validateSource($source)) { + throw new \Exception($import->getFormatedLogTrace()); + } + // this converts import queue into actual entities + if (!$import->importSource()) { + throw new \Exception($import->getFormatedLogTrace()); + } } } // @codingStandardsIgnoreEnd @@ -674,4 +658,166 @@ class ConfigurableProductsFixture extends SimpleProductsFixture } return $result; } + + /** + * Get configurable products value. + * + * @return int + */ + protected function getConfigurableProductsValue() + { + return $this->fixtureModel->getValue('configurable_products', 0); + } + + /** + * Get configurable products variations value. + * + * @return int + */ + protected function getConfigurableProductsVariationsValue() + { + return $this->fixtureModel->getValue('configurable_products_variation', 3); + } + + /** + * Get attribute set closure + * + * @param array $attributes + * @param array $result + * @return \Closure + */ + protected function getAttributeSetClosure(array $attributes, array $result) + { + return function ($index) use ($attributes, $result) { + mt_srand($index); + $attributeSet = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + return $attributeSet; + }; + } + + /** + * Get additional attributes closure. + * + * @param array $attributes + * @param array $result + * @return \Closure + */ + protected function getAdditionalAttributesClosure(array $attributes, array $result) + { + return function ($index, $variationIndex) use ($attributes, $result) { + $attributeValues = ''; + mt_srand($index); + $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + if ($attributeSetCode !== 'Default') { + foreach ($attributes[$attributeSetCode] as $attribute) { + $attributeValues = $attributeValues . $attribute['name'] . "=" . + $attribute['values'][$variationIndex % count($attribute['values'])] . ","; + } + } + return trim($attributeValues, ","); + }; + } + + /** + * Get variations closure. + * + * @param array $attributes + * @param array $result + * @param int $variationCount + * @return \Closure + */ + protected function getVariationsClosure(array $attributes, array $result, $variationCount) + { + return function ($index, $variationIndex) use ($attributes, $result, $variationCount) { + mt_srand($index); + $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + $skus = []; + for ($i = 1; $i <= $variationCount; $i++) { + $skus[] = 'sku=' . sprintf($this->getConfigurableOptionSkuPattern(), $index) . $i; + } + $values = []; + if ($attributeSetCode == 'Default') { + for ($i = 1; $i <= $variationCount; $i++) { + $values[] = 'configurable_variation=option ' . $i; + } + } else { + for ($i = $variationCount; $i > 0; $i--) { + $attributeValues = ''; + foreach ($attributes[$attributeSetCode] as $attribute) { + $attributeValues = $attributeValues . $attribute['name'] . "=" . + $attribute['values'][($variationIndex - $i) % count($attribute['values'])] . ","; + } + $values [] = $attributeValues; + } + } + $variations = []; + for ($i = 0; $i < $variationCount; $i++) { + $variations[] = trim(implode(",", [$skus[$i], $values[$i]]), ","); + } + return implode("|", $variations); + }; + } + + /** + * Get configurable product sku pattern. + * + * @return string + */ + private function getConfigurableProductSkuPattern() + { + return 'Configurable Product ' . $this->getConfigurableProductPrefix() . ' %s'; + } + + /** + * Get configurable option sku pattern. + * + * @return string + */ + protected function getConfigurableOptionSkuPattern() + { + return 'Configurable Product ' . $this->getConfigurableProductPrefix() . '%s-option'; + } + + /** + * Get url key prefix. + * + * @return string + */ + private function getUrlKeyPrefix() + { + return 'configurable-product' . $this->getConfigurableProductPrefix() . '-%s'; + } + + /** + * Get option url key prefix. + * + * @return string + */ + private function getOptionUrlKeyPrefix() + { + return 'simple-of-configurable-product' . $this->getConfigurableProductPrefix(); + } + + /** + * Get additional configurations for configurable products. + * + * @return string|null + */ + private function getAdditionalConfigurableProductsVariations() + { + return $this->fixtureModel->getValue('configurable_products_variations', null); + } + + /** + * Get configurable product prefix. + * + * @return string + */ + protected function getConfigurableProductPrefix() + { + return ''; + } } diff --git a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php index fbb28d35269b177762410e8da7560612dd64db9c..43270676cb94f0a16729d7c16dab4913247f105c 100644 --- a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php @@ -235,7 +235,7 @@ class SimpleProductsFixture extends Fixture */ protected function getAttributes() { - $attributeSets = $this->fixtureModel->getValue('attribute_sets', null); + $attributeSets = $this->getAttributeSets(); $attributes = []; if ($attributeSets !== null && array_key_exists('attribute_set', $attributeSets)) { @@ -337,4 +337,14 @@ class SimpleProductsFixture extends Fixture } return $searchTerms; } + + /** + * Get attribute sets. + * + * @return array|null + */ + private function getAttributeSets() + { + return $this->fixtureModel->getValue('attribute_sets', null); + } } diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php index 674f444fbde10666b75aa5dadfef3719e3177152..2192f4e84e26e7d39e5fa09b2e5ee752eb659b10 100644 --- a/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php @@ -202,7 +202,7 @@ class AttributeSetsFixtureTest extends \PHPUnit_Framework_TestCase ->willReturn($optionFactoryMock); $this->fixtureModelMock - ->expects($this->once()) + ->expects($this->any()) ->method('getValue') ->willReturn($attributeSets); @@ -267,7 +267,7 @@ class AttributeSetsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getObjectManager') ->will($this->returnValue($objectManagerMock)); $this->fixtureModelMock - ->expects($this->once()) + ->expects($this->any()) ->method('getValue') ->willReturn(null);