Skip to content

Commit 0c35c6b

Browse files
author
Volodymyr Kublytskyi
committed
Merge magento-partners/magento2ce/2.1-develop
2 parents d684743 + 78e72eb commit 0c35c6b

File tree

115 files changed

+4763
-1062
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+4763
-1062
lines changed

app/code/Magento/Braintree/view/frontend/web/template/payment/form.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@
140140
type="submit"
141141
data-bind="
142142
click: placeOrderClick,
143-
attr: {title: $t('Place Order')}
144-
">
143+
attr: {title: $t('Place Order')},
144+
css: {disabled: !isPlaceOrderActionAllowed()},
145+
enable: isActive()
146+
"
147+
disabled>
145148
<span data-bind="i18n: 'Place Order'"></span>
146149
</button>
147150
</div>

app/code/Magento/Bundle/Pricing/Price/BundleSelectionPrice.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public function getValue()
124124
$value = $product->getData('final_price') * ($selectionPriceValue / 100);
125125
} else {
126126
// calculate price for selection type fixed
127-
$value = $this->priceCurrency->convert($selectionPriceValue) * $this->quantity;
127+
$value = $this->priceCurrency->convert($selectionPriceValue);
128128
}
129129
}
130130
if (!$this->useRegularPrice) {

app/code/Magento/Bundle/Test/Unit/Pricing/Price/BundleSelectionPriceTest.php

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,63 +66,58 @@ class BundleSelectionPriceTest extends \PHPUnit_Framework_TestCase
6666
*/
6767
protected $priceCurrencyMock;
6868

69-
/**
70-
* @var float
71-
*/
72-
protected $quantity;
73-
7469
/**
7570
* Test setUp
7671
*/
7772
protected function setUp()
7873
{
7974
$this->productMock = $this->getMock(
80-
'Magento\Catalog\Model\Product',
75+
\Magento\Catalog\Model\Product::class,
8176
['__wakeup', 'getPriceInfo', 'getSelectionPriceType', 'getSelectionPriceValue'],
8277
[],
8378
'',
8479
false
8580
);
8681

8782
$this->bundleMock = $this->getMock(
88-
'Magento\Catalog\Model\Product',
83+
\Magento\Catalog\Model\Product::class,
8984
['__wakeup', 'getPriceType', 'getPriceInfo', 'setFinalPrice', 'getData'],
9085
[],
9186
'',
9287
false
9388
);
94-
$this->calculatorMock = $this->getMockBuilder('Magento\Framework\Pricing\Adjustment\CalculatorInterface')
89+
$this->calculatorMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\CalculatorInterface::class)
9590
->getMockForAbstractClass();
9691
$this->eventManagerMock = $this->getMock(
97-
'Magento\Framework\Event\Manager',
92+
\Magento\Framework\Event\Manager::class,
9893
['dispatch'],
9994
[],
10095
'',
10196
false
10297
);
10398
$this->priceInfoMock = $this->getMock(
104-
'Magento\Framework\Pricing\PriceInfo\Base',
99+
\Magento\Framework\Pricing\PriceInfo\Base::class,
105100
['getPrice'],
106101
[],
107102
'',
108103
false
109104
);
110105
$this->discountCalculatorMock = $this->getMock(
111-
'Magento\Bundle\Pricing\Price\DiscountCalculator',
106+
\Magento\Bundle\Pricing\Price\DiscountCalculator::class,
112107
[],
113108
[],
114109
'',
115110
false
116111
);
117112
$this->finalPriceMock = $this->getMock(
118-
'Magento\Catalog\Pricing\Price\FinalPrice',
113+
\Magento\Catalog\Pricing\Price\FinalPrice::class,
119114
[],
120115
[],
121116
'',
122117
false
123118
);
124119
$this->regularPriceMock = $this->getMock(
125-
'Magento\Catalog\Pricing\Price\RegularPrice',
120+
\Magento\Catalog\Pricing\Price\RegularPrice::class,
126121
[],
127122
[],
128123
'',
@@ -132,18 +127,16 @@ protected function setUp()
132127
->method('getPriceInfo')
133128
->will($this->returnValue($this->priceInfoMock));
134129

135-
$this->priceCurrencyMock = $this->getMock('\Magento\Framework\Pricing\PriceCurrencyInterface');
136-
137-
$this->quantity = 1;
130+
$this->priceCurrencyMock = $this->getMock(\Magento\Framework\Pricing\PriceCurrencyInterface::class);
138131

139132
$this->setupSelectionPrice();
140133
}
141134

142-
protected function setupSelectionPrice($useRegularPrice = false)
135+
protected function setupSelectionPrice($useRegularPrice = false, $qty = 1)
143136
{
144137
$this->selectionPrice = new \Magento\Bundle\Pricing\Price\BundleSelectionPrice(
145138
$this->productMock,
146-
$this->quantity,
139+
$qty,
147140
$this->calculatorMock,
148141
$this->priceCurrencyMock,
149142
$this->bundleMock,
@@ -313,6 +306,58 @@ public function testGetValueTypeFixedWithoutSelectionPriceType($useRegularPrice)
313306
$this->assertEquals($expectedPrice, $this->selectionPrice->getValue());
314307
}
315308

309+
/**
310+
* Test for method getValue with type Fixed and selectionPriceType is empty or zero.
311+
*
312+
* @param bool $useRegularPrice
313+
* @return void
314+
*
315+
* @dataProvider useRegularPriceDataProvider
316+
*/
317+
public function testFixedPriceWithMultipleQty($useRegularPrice)
318+
{
319+
$qty = 2;
320+
321+
$this->setupSelectionPrice($useRegularPrice, $qty);
322+
$regularPrice = 100.125;
323+
$discountedPrice = 70.453;
324+
$convertedValue = 100.247;
325+
$actualPrice = $useRegularPrice ? $convertedValue : $discountedPrice;
326+
$expectedPrice = $useRegularPrice ? round($convertedValue, 2) : round($discountedPrice, 2);
327+
328+
$this->bundleMock->expects($this->once())
329+
->method('getPriceType')
330+
->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
331+
$this->productMock->expects($this->once())
332+
->method('getSelectionPriceType')
333+
->will($this->returnValue(false));
334+
$this->productMock->expects($this->any())
335+
->method('getSelectionPriceValue')
336+
->will($this->returnValue($regularPrice));
337+
338+
$this->priceCurrencyMock->expects($this->once())
339+
->method('convert')
340+
->with($regularPrice)
341+
->will($this->returnValue($convertedValue));
342+
343+
if (!$useRegularPrice) {
344+
$this->discountCalculatorMock->expects($this->once())
345+
->method('calculateDiscount')
346+
->with(
347+
$this->equalTo($this->bundleMock),
348+
$this->equalTo($convertedValue)
349+
)
350+
->will($this->returnValue($discountedPrice));
351+
}
352+
353+
$this->priceCurrencyMock->expects($this->once())
354+
->method('round')
355+
->with($actualPrice)
356+
->will($this->returnValue($expectedPrice));
357+
358+
$this->assertEquals($expectedPrice, $this->selectionPrice->getValue());
359+
}
360+
316361
public function useRegularPriceDataProvider()
317362
{
318363
return [

app/code/Magento/Bundle/view/base/web/js/price-bundle.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ define([
5555
this._setOption('priceFormat', priceBox.priceBox('option').priceConfig.priceFormat);
5656
priceBox.priceBox('setDefault', this.options.optionConfig.prices);
5757
}
58-
this._applyQtyFix();
5958
this._applyOptionNodeFix(options);
6059

6160
options.on('change', this._onBundleOptionChanged.bind(this));

app/code/Magento/Catalog/Cron/DeleteOutdatedPriceValues.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
/**
1515
* Cron operation is responsible for deleting all product prices on WEBSITE level
16-
* in case 'Catalog Price Scope' configuratoin parameter is set to GLOBAL.
16+
* in case 'Catalog Price Scope' configuration parameter is set to GLOBAL.
1717
*/
1818
class DeleteOutdatedPriceValues
1919
{
@@ -48,27 +48,46 @@ public function __construct(
4848
}
4949

5050
/**
51-
* Delete all price values for non-admin stores if PRICE_SCOPE is global
51+
* Delete all price values for non-admin stores if PRICE_SCOPE is set to global.
5252
*
5353
* @return void
5454
*/
5555
public function execute()
5656
{
57-
$priceScope = $this->scopeConfig->getValue(Store::XML_PATH_PRICE_SCOPE);
58-
if ($priceScope == Store::PRICE_SCOPE_GLOBAL) {
59-
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $priceAttribute */
60-
$priceAttribute = $this->attributeRepository
61-
->get(ProductAttributeInterface::ENTITY_TYPE_CODE, ProductAttributeInterface::CODE_PRICE);
62-
$connection = $this->resource->getConnection();
63-
$conditions = [
64-
$connection->quoteInto('attribute_id = ?', $priceAttribute->getId()),
65-
$connection->quoteInto('store_id != ?', Store::DEFAULT_STORE_ID),
66-
];
57+
if ($this->isPriceScopeSetToGlobal() === false) {
58+
return;
59+
}
60+
61+
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $priceAttribute */
62+
$priceAttribute = $this->attributeRepository
63+
->get(ProductAttributeInterface::ENTITY_TYPE_CODE, ProductAttributeInterface::CODE_PRICE);
64+
$connection = $this->resource->getConnection();
65+
$conditions = [
66+
$connection->quoteInto('attribute_id = ?', $priceAttribute->getId()),
67+
$connection->quoteInto('store_id != ?', Store::DEFAULT_STORE_ID),
68+
];
6769

68-
$connection->delete(
69-
$priceAttribute->getBackend()->getTable(),
70-
$conditions
71-
);
70+
$connection->delete(
71+
$priceAttribute->getBackend()->getTable(),
72+
$conditions
73+
);
74+
}
75+
76+
/**
77+
* Checks if price scope config option explicitly equal to global value.
78+
*
79+
* Such strict comparision is required to prevent price deleting when
80+
* price scope config option is null for some reason.
81+
*
82+
* @return bool
83+
*/
84+
private function isPriceScopeSetToGlobal()
85+
{
86+
$priceScope = $this->scopeConfig->getValue(Store::XML_PATH_PRICE_SCOPE);
87+
if ($priceScope === null) {
88+
return false;
7289
}
90+
91+
return (int)$priceScope === Store::PRICE_SCOPE_GLOBAL;
7392
}
7493
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ public function build($productId)
9898
->limit(1);
9999
$priceSelect = $this->baseSelectProcessor->process($priceSelect);
100100

101-
$priceSelectDefault = clone $priceSelect;
102-
$priceSelectDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
103-
$select[] = $priceSelectDefault;
104-
105101
if (!$this->catalogHelper->isPriceGlobal()) {
106-
$priceSelect->where('t.store_id = ?', $this->storeManager->getStore()->getId());
107-
$select[] = $priceSelect;
102+
$priceSelectStore = clone $priceSelect;
103+
$priceSelectStore->where('t.store_id = ?', $this->storeManager->getStore()->getId());
104+
$selects[] = $priceSelectStore;
108105
}
109106

110-
return $select;
107+
$priceSelect->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
108+
$selects[] = $priceSelect;
109+
110+
return $selects;
111111
}
112112
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,15 @@ public function build($productId)
142142
->limit(1);
143143
$specialPrice = $this->baseSelectProcessor->process($specialPrice);
144144

145-
$specialPriceDefault = clone $specialPrice;
146-
$specialPriceDefault->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
147-
$select[] = $specialPriceDefault;
148-
149145
if (!$this->catalogHelper->isPriceGlobal()) {
150-
$specialPrice->where('t.store_id = ?', $this->storeManager->getStore()->getId());
151-
$select[] = $specialPrice;
146+
$priceSelectStore = clone $specialPrice;
147+
$priceSelectStore->where('t.store_id = ?', $this->storeManager->getStore()->getId());
148+
$selects[] = $priceSelectStore;
152149
}
153150

154-
return $select;
151+
$specialPrice->where('t.store_id = ?', Store::DEFAULT_STORE_ID);
152+
$selects[] = $specialPrice;
153+
154+
return $selects;
155155
}
156156
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,15 @@ public function build($productId)
100100
->limit(1);
101101
$priceSelect = $this->baseSelectProcessor->process($priceSelect);
102102

103-
$priceSelectDefault = clone $priceSelect;
104-
$priceSelectDefault->where('t.website_id = ?', self::DEFAULT_WEBSITE_ID);
105-
$select[] = $priceSelectDefault;
106-
107103
if (!$this->catalogHelper->isPriceGlobal()) {
108-
$priceSelect->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId());
109-
$select[] = $priceSelect;
104+
$priceSelectStore = clone $priceSelect;
105+
$priceSelectStore->where('t.website_id = ?', $this->storeManager->getStore()->getWebsiteId());
106+
$selects[] = $priceSelectStore;
110107
}
111108

112-
return $select;
109+
$priceSelect->where('t.website_id = ?', self::DEFAULT_WEBSITE_ID);
110+
$selects[] = $priceSelect;
111+
112+
return $selects;
113113
}
114114
}

app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderComposite.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public function __construct($linkedProductSelectBuilder)
2626
*/
2727
public function build($productId)
2828
{
29-
$select = [];
29+
$selects = [];
3030
foreach ($this->linkedProductSelectBuilder as $productSelectBuilder) {
31-
$select = array_merge($select, $productSelectBuilder->build($productId));
31+
$selects = array_merge($selects, $productSelectBuilder->build($productId));
3232
}
3333

34-
return $select;
34+
return $selects;
3535
}
3636
}

0 commit comments

Comments
 (0)