Skip to content

Commit ac37ae1

Browse files
#12584: Bundle Item price cannot differ per website.
1 parent ed0f987 commit ac37ae1

File tree

3 files changed

+87
-16
lines changed

3 files changed

+87
-16
lines changed

app/code/Magento/Bundle/Model/LinkManagement.php

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
use Magento\Catalog\Api\ProductRepositoryInterface;
2020
use Magento\Catalog\Model\Product;
2121
use Magento\Framework\Api\DataObjectHelper;
22+
use Magento\Framework\EntityManager\MetadataPool;
2223
use Magento\Framework\Exception\CouldNotSaveException;
2324
use Magento\Framework\Exception\InputException;
24-
use Magento\Framework\EntityManager\MetadataPool;
2525
use Magento\Framework\Exception\NoSuchEntityException;
2626
use Magento\Store\Model\StoreManagerInterface;
2727

@@ -174,11 +174,12 @@ public function saveChild(
174174
);
175175
}
176176
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
177-
$selectionModel = $this->mapProductLinkToSelectionModel(
177+
$selectionModel = $this->mapProductLinkToBundleSelectionModel(
178178
$selectionModel,
179179
$linkedProduct,
180-
$linkProductModel->getId(),
181-
$product->getData($linkField)
180+
$product,
181+
(int)$linkProductModel->getId(),
182+
$linkField
182183
);
183184

184185
try {
@@ -202,6 +203,7 @@ public function saveChild(
202203
*
203204
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
204205
* @SuppressWarnings(PHPMD.NPathComplexity)
206+
* @deprecated use mapProductLinkToBundleSelectionModel
205207
*/
206208
protected function mapProductLinkToSelectionModel(
207209
Selection $selectionModel,
@@ -235,9 +237,55 @@ protected function mapProductLinkToSelectionModel(
235237
if ($productLink->getIsDefault() !== null) {
236238
$selectionModel->setIsDefault($productLink->getIsDefault());
237239
}
238-
if ($productLink->getWebsiteId() !== null) {
239-
$selectionModel->setWebsiteId($productLink->getWebsiteId());
240+
241+
return $selectionModel;
242+
}
243+
244+
/**
245+
* Fill selection model with product link data.
246+
*
247+
* @param Selection $selectionModel
248+
* @param LinkInterface $productLink
249+
* @param ProductInterface $parentProduct
250+
* @param int $linkedProductId
251+
* @param string $linkField
252+
* @return Selection
253+
* @throws NoSuchEntityException
254+
*/
255+
private function mapProductLinkToBundleSelectionModel(
256+
Selection $selectionModel,
257+
LinkInterface $productLink,
258+
ProductInterface $parentProduct,
259+
int $linkedProductId,
260+
string $linkField
261+
): Selection {
262+
$selectionModel->setProductId($linkedProductId);
263+
$selectionModel->setParentProductId($parentProduct->getData($linkField));
264+
if ($productLink->getSelectionId() !== null) {
265+
$selectionModel->setSelectionId($productLink->getSelectionId());
266+
}
267+
if ($productLink->getOptionId() !== null) {
268+
$selectionModel->setOptionId($productLink->getOptionId());
240269
}
270+
if ($productLink->getPosition() !== null) {
271+
$selectionModel->setPosition($productLink->getPosition());
272+
}
273+
if ($productLink->getQty() !== null) {
274+
$selectionModel->setSelectionQty($productLink->getQty());
275+
}
276+
if ($productLink->getPriceType() !== null) {
277+
$selectionModel->setSelectionPriceType($productLink->getPriceType());
278+
}
279+
if ($productLink->getPrice() !== null) {
280+
$selectionModel->setSelectionPriceValue($productLink->getPrice());
281+
}
282+
if ($productLink->getCanChangeQuantity() !== null) {
283+
$selectionModel->setSelectionCanChangeQty($productLink->getCanChangeQuantity());
284+
}
285+
if ($productLink->getIsDefault() !== null) {
286+
$selectionModel->setIsDefault($productLink->getIsDefault());
287+
}
288+
$selectionModel->setWebsiteId((int)$this->storeManager->getStore($parentProduct->getStoreId())->getWebsiteId());
241289

242290
return $selectionModel;
243291
}
@@ -305,12 +353,14 @@ public function addChild(
305353
}
306354

307355
$selectionModel = $this->bundleSelection->create();
308-
$selectionModel = $this->mapProductLinkToSelectionModel(
356+
$selectionModel = $this->mapProductLinkToBundleSelectionModel(
309357
$selectionModel,
310358
$linkedProduct,
311-
$linkProductModel->getEntityId(),
312-
$product->getData($linkField)
359+
$product,
360+
(int)$linkProductModel->getEntityId(),
361+
$linkField
313362
);
363+
314364
$selectionModel->setOptionId($optionId);
315365

316366
try {

app/code/Magento/Bundle/Model/Option/SaveAction.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Magento\Framework\Exception\CouldNotSaveException;
1717
use Magento\Bundle\Model\Product\Type;
1818
use Magento\Bundle\Api\ProductLinkManagementInterface;
19+
use Magento\Framework\Exception\NoSuchEntityException;
1920
use Magento\Store\Model\StoreManagerInterface;
2021

2122
/**
@@ -105,7 +106,7 @@ public function save(ProductInterface $bundleProduct, OptionInterface $option)
105106
}
106107
} else {
107108
if (!$existingOption->getOptionId()) {
108-
throw new \Magento\Framework\Exception\NoSuchEntityException(
109+
throw new NoSuchEntityException(
109110
__("The option that was requested doesn't exist. Verify the entity and try again.")
110111
);
111112
}
@@ -147,7 +148,6 @@ private function updateOptionSelection(ProductInterface $product, OptionInterfac
147148
if (is_array($option->getProductLinks())) {
148149
$productLinks = $option->getProductLinks();
149150
foreach ($productLinks as $productLink) {
150-
$productLink->setWebsiteId($this->storeManager->getStore($product->getStoreId())->getWebsiteId());
151151
if (!$productLink->getId() && !$productLink->getSelectionId()) {
152152
$linksToAdd[] = $productLink;
153153
} else {

app/code/Magento/Bundle/Test/Unit/Model/LinkManagementTest.php

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use Magento\Framework\Exception\InputException;
3232
use Magento\Framework\Exception\NoSuchEntityException;
3333
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
34+
use Magento\Store\Api\Data\WebsiteInterface;
3435
use Magento\Store\Model\Store;
3536
use Magento\Store\Model\StoreManagerInterface;
3637
use PHPUnit\Framework\MockObject\MockObject;
@@ -139,6 +140,11 @@ class LinkManagementTest extends TestCase
139140
*/
140141
private $linkField = 'product_id';
141142

143+
/**
144+
* @var WebsiteInterface|MockObject
145+
*/
146+
private $websiteMock;
147+
142148
/**
143149
* @inheritDoc
144150
*/
@@ -203,6 +209,9 @@ protected function setUp(): void
203209
$this->dataObjectHelperMock = $this->getMockBuilder(DataObjectHelper::class)
204210
->disableOriginalConstructor()
205211
->getMock();
212+
213+
$this->websiteMock = $this->getMockForAbstractClass( WebsiteInterface::class);
214+
206215
$this->model = $helper->getObject(
207216
LinkManagement::class,
208217
[
@@ -539,7 +548,9 @@ public function testAddChildCouldNotSave()
539548
$productLink->method('getSku')->willReturn('linked_product_sku');
540549
$productLink->method('getOptionId')->willReturn(1);
541550
$productLink->method('getSelectionId')->willReturn(1);
542-
$productLink->method('getWebSiteId')->willReturn(100);
551+
$store = $this->createMock(Store::class);
552+
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
553+
$store->expects($this->once())->method('getWebsiteId')->willReturn(100);
543554

544555
$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
545556
$productMock = $this->createMock(Product::class);
@@ -617,7 +628,9 @@ public function testAddChild()
617628
$productLink->method('getSku')->willReturn('linked_product_sku');
618629
$productLink->method('getOptionId')->willReturn(1);
619630
$productLink->method('getSelectionId')->willReturn(1);
620-
$productLink->method('getWebSiteId')->willReturn(100);
631+
$store = $this->createMock(Store::class);
632+
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
633+
$store->expects($this->once())->method('getWebsiteId')->willReturn(100);
621634

622635
$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
623636
$productMock = $this->createMock(Product::class);
@@ -705,7 +718,9 @@ public function testSaveChild()
705718
->willReturn($canChangeQuantity);
706719
$productLink->method('getIsDefault')->willReturn($isDefault);
707720
$productLink->method('getSelectionId')->willReturn($optionId);
708-
$productLink->method('getWebSiteId')->willReturn($websiteId);
721+
$store = $this->createMock(Store::class);
722+
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
723+
$store->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);
709724

710725
$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
711726
$productMock = $this->createMock(Product::class);
@@ -785,16 +800,22 @@ public function testSaveChildFailedToSave()
785800
$productLink->method('getSku')->willReturn('linked_product_sku');
786801
$productLink->method('getId')->willReturn($id);
787802
$productLink->method('getSelectionId')->willReturn(1);
788-
$productLink->method('getWebsiteId')->willReturn($websiteId);
803+
$store = $this->createMock(Store::class);
804+
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
805+
$store->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);
789806

790807
$bundleProductSku = 'bundleProductSku';
791-
808+
$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
792809
$productMock = $this->createMock(Product::class);
793810
$productMock->expects($this->once())
794811
->method('getTypeId')
795812
->willReturn(Type::TYPE_BUNDLE);
796813
$productMock->method('getId')
797814
->willReturn($parentProductId);
815+
$productMock
816+
->method('getData')
817+
->with($this->linkField)
818+
->willReturn($parentProductId);
798819

799820
$linkedProductMock = $this->createMock(Product::class);
800821
$linkedProductMock->method('getId')->willReturn($linkProductId);

0 commit comments

Comments
 (0)