Skip to content

Commit

Permalink
Merge pull request #377 from magento-south/BUGS2.0.11
Browse files Browse the repository at this point in the history
[South] Bugfixes backports to 2.0.11

- MAGETWO-57000 [Backport] Simple child product without a special price still shown as "was (original price)" #4442 #5097 - for 2.0
- MAGETWO-58058 [Backport] - [GitHub] Unable to add more than 1 product to a cart from Wishlist #5282 - for 2.0
- MAGETWO-57491 [Backport] - Maximum error count when importing because issue URL key for specified store already exists - for 2.0
- MAGETWO-57004 [Backport] - Scope selector on product page does not display all related websites for restricted user - for 2.0
- MAGETWO-58192 [Backport] - [GITHUB] Prices of related products on PDP changes according to product custom options. #4588 - for 2.0
- MAGETWO-57331 [Backport] - Changing Swatch attribute's property doesn't affect storefront - for 2.0
- MAGETWO-56859 [Backport] Attribute for Send Welcome Email From shows wrong store ID - for 2.0
  • Loading branch information
slavvka authored Sep 13, 2016
2 parents c7a4cb4 + 89684bb commit 5c2f645
Show file tree
Hide file tree
Showing 20 changed files with 658 additions and 27 deletions.
6 changes: 1 addition & 5 deletions app/code/Magento/Backend/Block/Store/Switcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,7 @@ public function getWebsites()
{
$websites = $this->_storeManager->getWebsites();
if ($websiteIds = $this->getWebsiteIds()) {
foreach (array_keys($websites) as $websiteId) {
if (!in_array($websiteId, $websiteIds)) {
unset($websites[$websiteId]);
}
}
$websites = array_intersect_key($websites, array_flip($websiteIds));
}
return $websites;
}
Expand Down
53 changes: 53 additions & 0 deletions app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento\Backend\Test\Unit\Block\Store;

class SwitcherTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Magento\Backend\Block\Store\Switcher
*/
private $switcherBlock;

private $storeManagerMock;

protected function setUp()
{
$this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class);
$objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
$context = $objectHelper->getObject(
\Magento\Backend\Block\Template\Context::class,
[
'storeManager' => $this->storeManagerMock,
]
);

$this->switcherBlock = $objectHelper->getObject(
\Magento\Backend\Block\Store\Switcher::class,
['context' => $context]
);
}

public function testGetWebsites()
{
$websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false);
$websites = [0 => $websiteMock, 1 => $websiteMock];
$this->storeManagerMock->expects($this->once())->method('getWebsites')->will($this->returnValue($websites));
$this->assertEquals($websites, $this->switcherBlock->getWebsites());
}

public function testGetWebsitesIfSetWebsiteIds()
{
$websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false);
$websites = [0 => $websiteMock, 1 => $websiteMock];
$this->storeManagerMock->expects($this->once())->method('getWebsites')->will($this->returnValue($websites));

$this->switcherBlock->setWebsiteIds([1]);
$expected = [1 => $websiteMock];
$this->assertEquals($expected, $this->switcherBlock->getWebsites());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
<script>
require([
'jquery',
'Magento_Catalog/js/price-box'
'priceBox'
], function($){
var priceBoxes = $('[data-role=priceBox]');
var dataPriceBoxSelector = '[data-role=priceBox]',
dataProductIdSelector = '[data-product-id=<?php echo $block->escapeHtml($_product->getId())?>]',
priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector);

priceBoxes = priceBoxes.filter(function(index, elem){
return !$(elem).find('.price-from').length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
?>

<?php $_options = $block->decorateArray($block->getOptions()) ?>
<?php $_productId = $block->getProduct()->getId() ?>
<?php if (count($_options)):?>
<script type="text/x-magento-init">
{
"#product_addtocart_form": {
"priceOptions": {
"optionConfig": <?php /* @escapeNotVerified */ echo $block->getJsonConfig()?>,
"controlContainer": ".field",
"priceHolderSelector": "[data-role=priceBox]"
"priceHolderSelector": "[data-product-id='<?php echo $block->escapeHtml($_productId)?>'][data-role=priceBox]"
}
}
}
Expand Down
42 changes: 38 additions & 4 deletions app/code/Magento/CatalogImportExport/Model/Import/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -1248,23 +1248,57 @@ protected function _saveProductEntity(array $entityRowsIn, array $entityRowsUp)
if ($entityRowsIn) {
$this->_connection->insertMultiple($entityTable, $entityRowsIn);

$newProducts = $this->_connection->fetchPairs(
$newProducts = $this->_connection->fetchAll(
$this->_connection->select()->from(
$entityTable,
['sku', 'entity_id']
array_merge(['sku', 'entity_id'], $this->getOldSkuFieldsForSelect())
)->where(
'sku IN (?)',
array_keys($entityRowsIn)
)
);
foreach ($newProducts as $sku => $newId) {
foreach ($newProducts as $product) {
// fill up entity_id for new products
$this->skuProcessor->setNewSkuData($sku, 'entity_id', $newId);
$this->skuProcessor->setNewSkuData($product['sku'], 'entity_id', $product['entity_id']);
}

$this->updateOldSku($newProducts);
}
return $this;
}

/**
* Return additional data, needed to select.
* @return array
*/
private function getOldSkuFieldsForSelect()
{
return ['type_id', 'attribute_set_id'];
}

/**
* Adds newly created products to _oldSku
* @param array $newProducts
* @return void
*/
private function updateOldSku(array $newProducts)
{
$oldSkus = [];
foreach ($newProducts as $info) {
$typeId = $info['type_id'];
$sku = $info['sku'];
$oldSkus[$sku] = [
'type_id' => $typeId,
'attr_set_id' => $info['attribute_set_id'],
'supported_type' => isset($this->_productTypeModels[$typeId]),
'entity_id' => $info['entity_id']
];
}

$this->_oldSku = array_replace($this->_oldSku, $oldSkus);
}


/**
* Retrieving images from all columns and rows
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\ConfigurableProduct\Pricing\Render;

use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\Catalog\Pricing\Price\RegularPrice;
use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
use Magento\Framework\Pricing\Price\PriceInterface;
use Magento\Framework\Pricing\Render\RendererPool;
use Magento\Framework\Pricing\SaleableInterface;
use Magento\Framework\View\Element\Template\Context;

class FinalPriceBox extends \Magento\Catalog\Pricing\Render\FinalPriceBox
{
/**
* @var ConfigurableOptionsProviderInterface
*/
private $configurableOptionsProvider;

/**
* @param Context $context
* @param SaleableInterface $saleableItem
* @param PriceInterface $price
* @param RendererPool $rendererPool
* @param ConfigurableOptionsProviderInterface $configurableOptionsProvider
* @param array $data
*/
public function __construct(
Context $context,
SaleableInterface $saleableItem,
PriceInterface $price,
RendererPool $rendererPool,
ConfigurableOptionsProviderInterface $configurableOptionsProvider,
array $data = []
) {
$this->configurableOptionsProvider = $configurableOptionsProvider;
parent::__construct($context, $saleableItem, $price, $rendererPool, $data);
}

/**
* Define if the special price should be shown
*
* @return bool
*/
public function hasSpecialPrice()
{
$product = $this->getSaleableItem();
foreach ($this->configurableOptionsProvider->getProducts($product) as $subProduct) {
$regularPrice = $subProduct->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getValue();
$finalPrice = $subProduct->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
if ($finalPrice < $regularPrice) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Render;

use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\Catalog\Pricing\Price\RegularPrice;
use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface;
use Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox;

class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
*/
private $context;

/**
* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
*/
private $saleableItem;

/**
* @var \Magento\Framework\Pricing\Price\PriceInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $price;

/**
* @var \Magento\Framework\Pricing\Render\RendererPool|\PHPUnit_Framework_MockObject_MockObject
*/
private $rendererPool;

/**
* @var ConfigurableOptionsProviderInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $configurableOptionsProvider;

/**
* @var FinalPriceBox
*/
private $model;

protected function setUp()
{
$this->context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class)
->disableOriginalConstructor()
->getMock();

$this->saleableItem = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
->disableOriginalConstructor()
->getMock();

$this->price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
->getMockForAbstractClass();

$this->rendererPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class)
->disableOriginalConstructor()
->getMock();

$this->configurableOptionsProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class)
->getMockForAbstractClass();

$this->model = new FinalPriceBox(
$this->context,
$this->saleableItem,
$this->price,
$this->rendererPool,
$this->configurableOptionsProvider
);
}

/**
* @param float $regularPrice
* @param float $finalPrice
* @param bool $expected
* @dataProvider hasSpecialPriceDataProvider
*/
public function testHasSpecialPrice(
$regularPrice,
$finalPrice,
$expected
) {
$priceMockOne = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
->getMockForAbstractClass();

$priceMockOne->expects($this->once())
->method('getValue')
->willReturn($regularPrice);

$priceMockTwo = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
->getMockForAbstractClass();

$priceMockTwo->expects($this->once())
->method('getValue')
->willReturn($finalPrice);

$priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class)
->disableOriginalConstructor()
->getMock();

$priceInfoMock->expects($this->exactly(2))
->method('getPrice')
->willReturnMap([
[RegularPrice::PRICE_CODE, $priceMockOne],
[FinalPrice::PRICE_CODE, $priceMockTwo],
]);

$productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class)
->setMethods(['getPriceInfo'])
->getMockForAbstractClass();

$productMock->expects($this->exactly(2))
->method('getPriceInfo')
->willReturn($priceInfoMock);

$this->configurableOptionsProvider->expects($this->once())
->method('getProducts')
->with($this->saleableItem)
->willReturn([$productMock]);

$this->assertEquals($expected, $this->model->hasSpecialPrice());
}

/**
* @return array
*/
public function hasSpecialPriceDataProvider()
{
return [
[10., 20., false],
[10., 10., false],
[20., 10., true],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<referenceBlock name="render.product.prices">
<arguments>
<argument name="configurable" xsi:type="array">
<item name="prices" xsi:type="array">
<item name="final_price" xsi:type="array">
<item name="render_class" xsi:type="string">Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox</item>
<item name="render_template" xsi:type="string">Magento_ConfigurableProduct::product/price/final_price.phtml</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</layout>
Loading

0 comments on commit 5c2f645

Please sign in to comment.