Skip to content

Commit

Permalink
#12584: Bundle Item price cannot differ per website.
Browse files Browse the repository at this point in the history
  • Loading branch information
engcom-Foxtrot committed Nov 19, 2020
1 parent ed0f987 commit ac37ae1
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 16 deletions.
68 changes: 59 additions & 9 deletions app/code/Magento/Bundle/Model/LinkManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\StoreManagerInterface;

Expand Down Expand Up @@ -174,11 +174,12 @@ public function saveChild(
);
}
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
$selectionModel = $this->mapProductLinkToSelectionModel(
$selectionModel = $this->mapProductLinkToBundleSelectionModel(
$selectionModel,
$linkedProduct,
$linkProductModel->getId(),
$product->getData($linkField)
$product,
(int)$linkProductModel->getId(),
$linkField
);

try {
Expand All @@ -202,6 +203,7 @@ public function saveChild(
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @deprecated use mapProductLinkToBundleSelectionModel
*/
protected function mapProductLinkToSelectionModel(
Selection $selectionModel,
Expand Down Expand Up @@ -235,9 +237,55 @@ protected function mapProductLinkToSelectionModel(
if ($productLink->getIsDefault() !== null) {
$selectionModel->setIsDefault($productLink->getIsDefault());
}
if ($productLink->getWebsiteId() !== null) {
$selectionModel->setWebsiteId($productLink->getWebsiteId());

return $selectionModel;
}

/**
* Fill selection model with product link data.
*
* @param Selection $selectionModel
* @param LinkInterface $productLink
* @param ProductInterface $parentProduct
* @param int $linkedProductId
* @param string $linkField
* @return Selection
* @throws NoSuchEntityException
*/
private function mapProductLinkToBundleSelectionModel(
Selection $selectionModel,
LinkInterface $productLink,
ProductInterface $parentProduct,
int $linkedProductId,
string $linkField
): Selection {
$selectionModel->setProductId($linkedProductId);
$selectionModel->setParentProductId($parentProduct->getData($linkField));
if ($productLink->getSelectionId() !== null) {
$selectionModel->setSelectionId($productLink->getSelectionId());
}
if ($productLink->getOptionId() !== null) {
$selectionModel->setOptionId($productLink->getOptionId());
}
if ($productLink->getPosition() !== null) {
$selectionModel->setPosition($productLink->getPosition());
}
if ($productLink->getQty() !== null) {
$selectionModel->setSelectionQty($productLink->getQty());
}
if ($productLink->getPriceType() !== null) {
$selectionModel->setSelectionPriceType($productLink->getPriceType());
}
if ($productLink->getPrice() !== null) {
$selectionModel->setSelectionPriceValue($productLink->getPrice());
}
if ($productLink->getCanChangeQuantity() !== null) {
$selectionModel->setSelectionCanChangeQty($productLink->getCanChangeQuantity());
}
if ($productLink->getIsDefault() !== null) {
$selectionModel->setIsDefault($productLink->getIsDefault());
}
$selectionModel->setWebsiteId((int)$this->storeManager->getStore($parentProduct->getStoreId())->getWebsiteId());

return $selectionModel;
}
Expand Down Expand Up @@ -305,12 +353,14 @@ public function addChild(
}

$selectionModel = $this->bundleSelection->create();
$selectionModel = $this->mapProductLinkToSelectionModel(
$selectionModel = $this->mapProductLinkToBundleSelectionModel(
$selectionModel,
$linkedProduct,
$linkProductModel->getEntityId(),
$product->getData($linkField)
$product,
(int)$linkProductModel->getEntityId(),
$linkField
);

$selectionModel->setOptionId($optionId);

try {
Expand Down
4 changes: 2 additions & 2 deletions app/code/Magento/Bundle/Model/Option/SaveAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Bundle\Model\Product\Type;
use Magento\Bundle\Api\ProductLinkManagementInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\StoreManagerInterface;

/**
Expand Down Expand Up @@ -105,7 +106,7 @@ public function save(ProductInterface $bundleProduct, OptionInterface $option)
}
} else {
if (!$existingOption->getOptionId()) {
throw new \Magento\Framework\Exception\NoSuchEntityException(
throw new NoSuchEntityException(
__("The option that was requested doesn't exist. Verify the entity and try again.")
);
}
Expand Down Expand Up @@ -147,7 +148,6 @@ private function updateOptionSelection(ProductInterface $product, OptionInterfac
if (is_array($option->getProductLinks())) {
$productLinks = $option->getProductLinks();
foreach ($productLinks as $productLink) {
$productLink->setWebsiteId($this->storeManager->getStore($product->getStoreId())->getWebsiteId());
if (!$productLink->getId() && !$productLink->getSelectionId()) {
$linksToAdd[] = $productLink;
} else {
Expand Down
31 changes: 26 additions & 5 deletions app/code/Magento/Bundle/Test/Unit/Model/LinkManagementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Api\Data\WebsiteInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
Expand Down Expand Up @@ -139,6 +140,11 @@ class LinkManagementTest extends TestCase
*/
private $linkField = 'product_id';

/**
* @var WebsiteInterface|MockObject
*/
private $websiteMock;

/**
* @inheritDoc
*/
Expand Down Expand Up @@ -203,6 +209,9 @@ protected function setUp(): void
$this->dataObjectHelperMock = $this->getMockBuilder(DataObjectHelper::class)
->disableOriginalConstructor()
->getMock();

$this->websiteMock = $this->getMockForAbstractClass( WebsiteInterface::class);

$this->model = $helper->getObject(
LinkManagement::class,
[
Expand Down Expand Up @@ -539,7 +548,9 @@ public function testAddChildCouldNotSave()
$productLink->method('getSku')->willReturn('linked_product_sku');
$productLink->method('getOptionId')->willReturn(1);
$productLink->method('getSelectionId')->willReturn(1);
$productLink->method('getWebSiteId')->willReturn(100);
$store = $this->createMock(Store::class);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn(100);

$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
$productMock = $this->createMock(Product::class);
Expand Down Expand Up @@ -617,7 +628,9 @@ public function testAddChild()
$productLink->method('getSku')->willReturn('linked_product_sku');
$productLink->method('getOptionId')->willReturn(1);
$productLink->method('getSelectionId')->willReturn(1);
$productLink->method('getWebSiteId')->willReturn(100);
$store = $this->createMock(Store::class);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn(100);

$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
$productMock = $this->createMock(Product::class);
Expand Down Expand Up @@ -705,7 +718,9 @@ public function testSaveChild()
->willReturn($canChangeQuantity);
$productLink->method('getIsDefault')->willReturn($isDefault);
$productLink->method('getSelectionId')->willReturn($optionId);
$productLink->method('getWebSiteId')->willReturn($websiteId);
$store = $this->createMock(Store::class);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);

$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
$productMock = $this->createMock(Product::class);
Expand Down Expand Up @@ -785,16 +800,22 @@ public function testSaveChildFailedToSave()
$productLink->method('getSku')->willReturn('linked_product_sku');
$productLink->method('getId')->willReturn($id);
$productLink->method('getSelectionId')->willReturn(1);
$productLink->method('getWebsiteId')->willReturn($websiteId);
$store = $this->createMock(Store::class);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn($websiteId);

$bundleProductSku = 'bundleProductSku';

$this->metadataMock->expects($this->once())->method('getLinkField')->willReturn($this->linkField);
$productMock = $this->createMock(Product::class);
$productMock->expects($this->once())
->method('getTypeId')
->willReturn(Type::TYPE_BUNDLE);
$productMock->method('getId')
->willReturn($parentProductId);
$productMock
->method('getData')
->with($this->linkField)
->willReturn($parentProductId);

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

0 comments on commit ac37ae1

Please sign in to comment.