Skip to content

Commit

Permalink
Merge pull request magento#3934 from magento-tsg/2.2-develop-pr84
Browse files Browse the repository at this point in the history
[TSG] Backporting for 2.2 (pr84) (2.2-develop)
  • Loading branch information
Alexander Akimov authored Mar 25, 2019
2 parents d1190ce + c2ca0fe commit b83845a
Show file tree
Hide file tree
Showing 57 changed files with 1,061 additions and 187 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
<entity name="DefaultAllowCountriesConfig" type="allow_countries_config">
<requiredEntity type="allow_countries_config_default">DefaultAllowCountries</requiredEntity>
</entity>
<entity name="DefaultAllowCountries" type="allow_countries_config_default">
<data key="value">0</data>
</entity>

<entity name="SetAllowCountriesConfigUS" type="allow_countries_config">
<data key="value">US</data>
</entity>
</entities>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd">
<operation name="AllowCountriesConfig" dataType="allow_countries_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/general/" method="POST" successRegex="/messages-message-success/">
<object key="groups" dataType="allow_countries_config">
<object key="country" dataType="allow_countries_config">
<object key="fields" dataType="allow_countries_config">
<object key="allow" dataType="allow_countries_config">
<field key="value">string</field>
<object key="inherit" dataType="allow_countries_config_default">
<field key="value">integer</field>
</object>
</object>
</object>
</object>
</object>
</operation>
</operations>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Type as ProductTypes;

/**
* Build a product based on a request.
*/
class Builder
{
/**
Expand Down Expand Up @@ -92,6 +95,9 @@ public function build(RequestInterface $request)
if ($productId) {
try {
$product = $this->productRepository->getById($productId, true, $storeId);
if ($attributeSetId) {
$product->setAttributeSetId($attributeSetId);
}
} catch (\Exception $e) {
$product = $this->createEmptyProduct(ProductTypes::DEFAULT_TYPE, $attributeSetId, $storeId);
$this->logger->critical($e);
Expand All @@ -113,6 +119,8 @@ public function build(RequestInterface $request)
}

/**
* Create a product with the given properties
*
* @param int $typeId
* @param int $attributeSetId
* @param int $storeId
Expand Down
4 changes: 2 additions & 2 deletions app/code/Magento/Catalog/Model/CategoryList.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function getList(SearchCriteriaInterface $searchCriteria)
$this->collectionProcessor->process($searchCriteria, $collection);

$items = [];
foreach ($collection->getItems() as $category) {
$items[] = $this->categoryRepository->get($category->getId());
foreach ($collection->getAllIds() as $id) {
$items[] = $this->categoryRepository->get($id);
}

/** @var CategorySearchResultsInterface $searchResult */
Expand Down
128 changes: 128 additions & 0 deletions app/code/Magento/Catalog/Model/Product/Type/FrontSpecialPrice.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Model\Product\Type;

use Magento\Store\Model\Store;
use Magento\Catalog\Model\ResourceModel\Product\Price\SpecialPrice;
use Magento\Catalog\Api\Data\SpecialPriceInterface;
use Magento\Store\Api\Data\WebsiteInterface;

/**
* Product special price model.
*
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class FrontSpecialPrice extends Price
{
/**
* @var SpecialPrice
*/
private $specialPrice;

/**
* @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
* @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
* @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param SpecialPrice $specialPrice
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
\Magento\Customer\Model\Session $customerSession,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
\Magento\Customer\Api\GroupManagementInterface $groupManagement,
\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
SpecialPrice $specialPrice
) {
$this->specialPrice = $specialPrice;
parent::__construct(
$ruleFactory,
$storeManager,
$localeDate,
$customerSession,
$eventManager,
$priceCurrency,
$groupManagement,
$tierPriceFactory,
$config
);
}

/**
* @inheritdoc
*/
protected function _applySpecialPrice($product, $finalPrice)
{
if (!$product->getSpecialPrice()) {
return $finalPrice;
}

$specialPrices = $this->getSpecialPrices($product);
$specialPrice = !(empty($specialPrices)) ? min($specialPrices) : $product->getSpecialPrice();

$specialPrice = $this->calculateSpecialPrice(
$finalPrice,
$specialPrice,
$product->getSpecialFromDate(),
$product->getSpecialToDate(),
WebsiteInterface::ADMIN_CODE
);
$product->setData('special_price', $specialPrice);

return $specialPrice;
}

/**
* Get special prices.
*
* @param mixed $product
* @return array
*/
private function getSpecialPrices($product): array
{
$allSpecialPrices = $this->specialPrice->get([$product->getSku()]);
$specialPrices = [];
foreach ($allSpecialPrices as $price) {
if ($this->isSuitableSpecialPrice($product, $price)) {
$specialPrices[] = $price['value'];
}
}

return $specialPrices;
}

/**
* Price is suitable from default and current store + start and end date are equal.
*
* @param mixed $product
* @param array $price
* @return bool
*/
private function isSuitableSpecialPrice($product, array $price): bool
{
$priceStoreId = $price[Store::STORE_ID];
if (($priceStoreId == Store::DEFAULT_STORE_ID || $product->getStoreId() == $priceStoreId)
&& $price[SpecialPriceInterface::PRICE_FROM] == $product->getSpecialFromDate()
&& $price[SpecialPriceInterface::PRICE_TO] == $product->getSpecialToDate()) {
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<scrollToTopOfPage stepKey="initScrollToTopOfThePage"/>
<click selector="{{AdminProductFormSection.advancedPricingLink}}" stepKey="clickAdvancedPricingLink"/>
<waitForElementVisible selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="waitSpecialPrice"/>
<conditionalClick selector="{{AdminProductFormAdvancedPricingSection.useDefaultPrice}}" dependentSelector="{{AdminProductFormAdvancedPricingSection.useDefaultPrice}}" visible="true" stepKey="checkUseDefault"/>
<fillField userInput="{{price}}" selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="fillSpecialPrice"/>
<click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDone"/>
<waitForElementNotVisible selector="{{AdminProductFormAdvancedPricingSection.specialPrice}}" stepKey="waitForCloseModalWindow"/>
Expand Down Expand Up @@ -257,4 +258,15 @@
<click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton"/>
<see selector="{{AdminMessagesSection.success}}" userInput="You saved the product." stepKey="seeSaveProductMessage"/>
</actionGroup>

<actionGroup name="AdminChangeProductAttributeSet">
<arguments>
<argument name="attributeSet"/>
</arguments>
<scrollToTopOfPage stepKey="scrollToTop"/>
<click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttributeSet"/>
<fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{attributeSet.attribute_set_name}}" stepKey="searchForAttributeSet"/>
<waitForElementVisible selector="{{AdminProductFormSection.attributeSetFilterResultByName(attributeSet.attribute_set_name)}}" stepKey="waitForNewAttributeSetIsShown"/>
<click selector="{{AdminProductFormSection.attributeSetFilterResultByName(attributeSet.attribute_set_name)}}" stepKey="selectAttributeSet"/>
</actionGroup>
</actionGroups>
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,26 @@
<entity name="DefaultFlatCatalogProduct" type="flat_catalog_product">
<data key="value">0</data>
</entity>

<entity name="UseFlatCatalogCategoryAndProduct" type="catalog_storefront_config">
<requiredEntity type="flat_catalog_product">UseFlatCatalogProduct</requiredEntity>
<requiredEntity type="flat_catalog_category">UseFlatCatalogCategory</requiredEntity>
</entity>

<entity name="UseFlatCatalogProduct" type="flat_catalog_product">
<data key="value">1</data>
</entity>

<entity name="UseFlatCatalogCategory" type="flat_catalog_category">
<data key="value">1</data>
</entity>

<entity name="DefaultFlatCatalogCategoryAndProduct" type="catalog_storefront_config">
<requiredEntity type="flat_catalog_product">DefaultFlatCatalogProduct</requiredEntity>
<requiredEntity type="flat_catalog_category">DefaultFlatCatalogCategory</requiredEntity>
</entity>

<entity name="DefaultFlatCatalogCategory" type="flat_catalog_category">
<data key="value">0</data>
</entity>
</entities>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-->

<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd">
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
<entity name="productAttributeWithTwoOptions" type="ProductAttribute">
<data key="name" unique="suffix">ProductAttributeWithTwoOptions</data>
<data key="attribute_code" unique="suffix">attribute</data>
Expand Down Expand Up @@ -74,4 +74,7 @@
<data key="used_for_sort_by">true</data>
<requiredEntity type="FrontendLabel">ProductAttributeFrontendLabel</requiredEntity>
</entity>
<entity name="ProductAttributeText" extends="productAttributeWithTwoOptions">
<data key="frontend_input">text</data>
</entity>
</entities>
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
<element name="productTierPricePercentageError" type="text" selector="div[data-index='percentage_value'] label.admin__field-error" />
<element name="specialPrice" type="input" selector="input[name='product[special_price]']"/>
<element name="doneButton" type="button" selector=".product_form_product_form_advanced_pricing_modal button.action-primary" timeout="5"/>
<element name="useDefaultPrice" type="checkbox" selector="input[name='use_default[special_price]']"/>
</section>
</sections>
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<element name="requiredNameIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=name]&gt;.admin__field-label span'), ':after').getPropertyValue('content');"/>
<element name="requiredSkuIndicator" type="text" selector=" return window.getComputedStyle(document.querySelector('._required[data-index=sku]&gt;.admin__field-label span'), ':after').getPropertyValue('content');"/>
<element name="customAttributeDropdownField" type="select" selector="select[name='product[{{attributeCode}}]']" parameterized="true"/>
<element name="customAttributeInputField" type="select" selector="input[name='product[{{attributeCode}}]']" parameterized="true"/>
</section>
<section name="ProductInWebsitesSection">
<element name="sectionHeader" type="button" selector="div[data-index='websites']" timeout="30"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="AdminChangeProductAttributeSetTest">
<annotations>
<features value="Catalog"/>
<stories value="Update product"/>
<title value="Attributes from the selected attribute set should be shown"/>
<description value="Attributes from the selected attribute set should be shown"/>
<severity value="CRITICAL"/>
<testCaseId value="MC-15414"/>
<useCaseId value="MAGETWO-98380"/>
<group value="catalog"/>
</annotations>
<before>
<!--Create category product, attribute, attribute set-->
<createData entity="SimpleSubCategory" stepKey="createCategory"/>
<createData entity="_defaultProduct" stepKey="createSimpleProduct">
<requiredEntity createDataKey="createCategory"/>
</createData>
<createData entity="ProductAttributeText" stepKey="createProductAttribute"/>
<createData entity="CatalogAttributeSet" stepKey="createAttributeSet"/>

<actionGroup ref="LoginAsAdmin" stepKey="login"/>
<!--Assign attribute to attribute set-->
<amOnPage url="{{AdminProductAttributeSetEditPage.url($$createAttributeSet.attribute_set_id$$)}}" stepKey="openAttributeSetEdit"/>
<actionGroup ref="AssignAttributeToGroup" stepKey="assignAttributeToGroup">
<argument name="group" value="Product Details"/>
<argument name="attribute" value="$$createProductAttribute.attribute_code$$"/>
</actionGroup>
<actionGroup ref="SaveAttributeSet" stepKey="saveAttributeSet"/>
</before>
<after>
<!--Delete created entities-->
<deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/>
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
<deleteData createDataKey="createProductAttribute" stepKey="deleteProductAttribute"/>
<deleteData createDataKey="createAttributeSet" stepKey="deleteAttributeSet"/>

<actionGroup ref="logout" stepKey="logoutAdminUserAfterTest"/>
</after>
<!--Open created product-->
<amOnPage url="{{AdminProductEditPage.url($$createSimpleProduct.id$$)}}" stepKey="openProductEditPage"/>
<waitForPageLoad time="30" stepKey="waitForProductPageIsLoaded"/>
<dontSeeElement selector="{{AdminProductFormSection.customAttributeInputField($$createProductAttribute.attribute_code$$)}}" stepKey="dontSeeCreatedAttribute"/>
<!--Change product attribute set-->
<actionGroup ref="AdminChangeProductAttributeSet" stepKey="changeProductAttributeSet">
<argument name="attributeSet" value="$$createAttributeSet$$"/>
</actionGroup>
<!--Check new attribute is visible on product edit page-->
<seeElement selector="{{AdminProductFormSection.customAttributeInputField($$createProductAttribute.attribute_code$$)}}" stepKey="seeAttributeInForm"/>
</test>
</tests>
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,14 @@ public function testGetList()
$categoryIdSecond = 2;

$categoryFirst = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock();
$categoryFirst->expects($this->atLeastOnce())->method('getId')->willReturn($categoryIdFirst);
$categorySecond = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock();
$categorySecond->expects($this->atLeastOnce())->method('getId')->willReturn($categoryIdSecond);

/** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteria */
$searchCriteria = $this->createMock(SearchCriteriaInterface::class);

$collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock();
$collection->expects($this->once())->method('getSize')->willReturn($totalCount);
$collection->expects($this->once())->method('getItems')->willReturn([$categoryFirst, $categorySecond]);
$collection->expects($this->once())->method('getAllIds')->willReturn([$categoryIdFirst, $categoryIdSecond]);

$this->collectionProcessorMock->expects($this->once())
->method('process')
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/Catalog/etc/frontend/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@
<type name="Magento\Framework\App\Action\AbstractAction">
<plugin name="catalog_app_action_dispatch_controller_context_plugin" type="Magento\Catalog\Plugin\Framework\App\Action\ContextPlugin" />
</type>
<preference for="Magento\Catalog\Model\Product\Type\Price" type="Magento\Catalog\Model\Product\Type\FrontSpecialPrice" />
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

define([
'jquery',
'mage/mage'
'mage/mage',
'validation'
], function ($) {
'use strict';

return function (config, element) {

$(element).mage('form').mage('validation', {
$(element).mage('form').validation({
validationUrl: config.validationUrl
});
};
Expand Down
Loading

0 comments on commit b83845a

Please sign in to comment.