Skip to content
Snippets Groups Projects
Commit 57f82445 authored by Susan Wright's avatar Susan Wright
Browse files

Merge remote-tracking branch 'mainline/develop' into MAGETWO-36298

parents 140b155a cc6ec2ba
No related merge requests found
Showing
with 931 additions and 177 deletions
...@@ -45,7 +45,7 @@ class InstallSchema implements InstallSchemaInterface ...@@ -45,7 +45,7 @@ class InstallSchema implements InstallSchemaInterface
'date_added', 'date_added',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null, null,
['nullable' => false], ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'Create date' 'Create date'
)->addColumn( )->addColumn(
'title', 'title',
...@@ -112,7 +112,7 @@ class InstallSchema implements InstallSchemaInterface ...@@ -112,7 +112,7 @@ class InstallSchema implements InstallSchemaInterface
'created_at', 'created_at',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null, null,
['nullable' => false], ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'Create date' 'Create date'
)->setComment( )->setComment(
'Admin System Messages' 'Admin System Messages'
......
...@@ -9,6 +9,24 @@ namespace Magento\Bundle\Api\Data; ...@@ -9,6 +9,24 @@ namespace Magento\Bundle\Api\Data;
interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{ {
const PRICE_TYPE_FIXED = 0;
const PRICE_TYPE_PERCENT = 1;
/**
* Get the identifier
*
* @return string|null
*/
public function getId();
/**
* Set id
*
* @param string $id
* @return $this
*/
public function setId($id);
/** /**
* Get linked product sku * Get linked product sku
* *
...@@ -69,21 +87,6 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface ...@@ -69,21 +87,6 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
*/ */
public function setPosition($position); public function setPosition($position);
/**
* Get is defined
*
* @return bool|null
*/
public function getIsDefined();
/**
* Set is defined
*
* @param bool $isDefined
* @return $this
*/
public function setIsDefined($isDefined);
/** /**
* Get is default * Get is default
* *
......
...@@ -11,12 +11,13 @@ interface ProductLinkManagementInterface ...@@ -11,12 +11,13 @@ interface ProductLinkManagementInterface
/** /**
* Get all children for Bundle product * Get all children for Bundle product
* *
* @param string $productId * @param string $productSku
* @param int $optionId
* @return \Magento\Bundle\Api\Data\LinkInterface[] * @return \Magento\Bundle\Api\Data\LinkInterface[]
* @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\InputException * @throws \Magento\Framework\Exception\InputException
*/ */
public function getChildren($productId); public function getChildren($productSku, $optionId = null);
/** /**
* Add child product to specified Bundle option by product sku * Add child product to specified Bundle option by product sku
...@@ -31,10 +32,23 @@ interface ProductLinkManagementInterface ...@@ -31,10 +32,23 @@ interface ProductLinkManagementInterface
*/ */
public function addChildByProductSku($sku, $optionId, \Magento\Bundle\Api\Data\LinkInterface $linkedProduct); public function addChildByProductSku($sku, $optionId, \Magento\Bundle\Api\Data\LinkInterface $linkedProduct);
/**
* @param string $sku
* @param \Magento\Bundle\Api\Data\LinkInterface $linkedProduct
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\CouldNotSaveException
* @throws \Magento\Framework\Exception\InputException
* @return bool
*/
public function saveChild(
$sku,
\Magento\Bundle\Api\Data\LinkInterface $linkedProduct
);
/** /**
* @param \Magento\Catalog\Api\Data\ProductInterface $product * @param \Magento\Catalog\Api\Data\ProductInterface $product
* @param int $optionId * @param int $optionId
* @param Data\LinkInterface $linkedProduct * @param \Magento\Bundle\Api\Data\LinkInterface $linkedProduct
* @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \Magento\Framework\Exception\CouldNotSaveException * @throws \Magento\Framework\Exception\CouldNotSaveException
* @throws \Magento\Framework\Exception\InputException * @throws \Magento\Framework\Exception\InputException
......
...@@ -16,17 +16,34 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements ...@@ -16,17 +16,34 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
/**#@+ /**#@+
* Constants * Constants
*/ */
const KEY_ID = 'id';
const KEY_SKU = 'sku'; const KEY_SKU = 'sku';
const KEY_OPTION_ID = 'option_id'; const KEY_OPTION_ID = 'option_id';
const KEY_QTY = 'qty'; const KEY_QTY = 'qty';
const KEY_POSITION = 'position'; const KEY_POSITION = 'position';
const KEY_IS_DEFINED = 'is_defined';
const KEY_IS_DEFAULT = 'is_default'; const KEY_IS_DEFAULT = 'is_default';
const KEY_PRICE = 'price'; const KEY_PRICE = 'price';
const KEY_PRICE_TYPE = 'price_type'; const KEY_PRICE_TYPE = 'price_type';
const KEY_CAN_CHANGE_QUANTITY = 'can_change_quantity'; const KEY_CAN_CHANGE_QUANTITY = 'selection_can_change_quantity';
/**#@-*/ /**#@-*/
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->getData(self::KEY_ID);
}
/**
* {@inheritdoc}
*/
public function setId($id)
{
return $this->setData(self::KEY_ID, $id);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -59,14 +76,6 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements ...@@ -59,14 +76,6 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
return $this->getData(self::KEY_POSITION); return $this->getData(self::KEY_POSITION);
} }
/**
* {@inheritdoc}
*/
public function getIsDefined()
{
return $this->getData(self::KEY_IS_DEFINED);
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -143,17 +152,6 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements ...@@ -143,17 +152,6 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
return $this->setData(self::KEY_POSITION, $position); return $this->setData(self::KEY_POSITION, $position);
} }
/**
* Set is defined
*
* @param bool $isDefined
* @return $this
*/
public function setIsDefined($isDefined)
{
return $this->setData(self::KEY_IS_DEFINED, $isDefined);
}
/** /**
* Set is default * Set is default
* *
......
...@@ -75,15 +75,18 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -75,15 +75,18 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getChildren($productId) public function getChildren($productSku, $optionId = null)
{ {
$product = $this->productRepository->get($productId); $product = $this->productRepository->get($productSku);
if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
throw new InputException(__('Only implemented for bundle product')); throw new InputException(__('Only implemented for bundle product'));
} }
$childrenList = []; $childrenList = [];
foreach ($this->getOptions($product) as $option) { foreach ($this->getOptions($product) as $option) {
if ($optionId !== null && $option->getOptionId() != $optionId) {
continue;
}
/** @var \Magento\Catalog\Model\Product $selection */ /** @var \Magento\Catalog\Model\Product $selection */
foreach ($option->getSelections() as $selection) { foreach ($option->getSelections() as $selection) {
$childrenList[] = $this->buildLink($selection, $product); $childrenList[] = $this->buildLink($selection, $product);
...@@ -107,6 +110,93 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -107,6 +110,93 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
* @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.NPathComplexity)
*/ */
public function saveChild(
$sku,
\Magento\Bundle\Api\Data\LinkInterface $linkedProduct
) {
$product = $this->productRepository->get($sku);
if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
throw new InputException(
__('Product with specified sku: "%1" is not a bundle product', [$product->getSku()])
);
}
/** @var \Magento\Catalog\Model\Product $linkProductModel */
$linkProductModel = $this->productRepository->get($linkedProduct->getSku());
if ($linkProductModel->isComposite()) {
throw new InputException(__('Bundle product could not contain another composite product'));
}
if (!$linkedProduct->getId()) {
throw new InputException(__('Id field of product link is required'));
}
/** @var \Magento\Bundle\Model\Selection $selectionModel */
$selectionModel = $this->bundleSelection->create();
$selectionModel->load($linkedProduct->getId());
if (!$selectionModel->getId()) {
throw new InputException(__('Can not find product link with id "%1"', [$linkedProduct->getId()]));
}
$selectionModel = $this->mapProductLinkToSelectionModel(
$selectionModel,
$linkedProduct,
$linkProductModel->getId(),
$product->getId()
);
try {
$selectionModel->save();
} catch (\Exception $e) {
throw new CouldNotSaveException(__('Could not save child: "%1"', $e->getMessage()), $e);
}
return true;
}
/**
* @param \Magento\Bundle\Model\Selection $selectionModel
* @param \Magento\Bundle\Api\Data\LinkInterface $productLink
* @param string $linkedProductId
* @param string $parentProductId
* @return \Magento\Bundle\Model\Selection
*/
protected function mapProductLinkToSelectionModel(
\Magento\Bundle\Model\Selection $selectionModel,
\Magento\Bundle\Api\Data\LinkInterface $productLink,
$linkedProductId,
$parentProductId
) {
$selectionModel->setProductId($linkedProductId);
$selectionModel->setParentProductId($parentProductId);
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());
}
return $selectionModel;
}
/**
* {@inheritdoc}
*/
public function addChild( public function addChild(
\Magento\Catalog\Api\Data\ProductInterface $product, \Magento\Catalog\Api\Data\ProductInterface $product,
$optionId, $optionId,
...@@ -119,17 +209,10 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -119,17 +209,10 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
} }
$options = $this->optionCollection->create(); $options = $this->optionCollection->create();
$options->setProductIdFilter($product->getId())->joinValues($this->storeManager->getStore()->getId()); $options->setIdFilter($optionId);
$isNewOption = true; $existingOption = $options->getFirstItem();
/** @var \Magento\Bundle\Model\Option $option */
foreach ($options as $option) {
if ($option->getOptionId() == $optionId) {
$isNewOption = false;
break;
}
}
if ($isNewOption) { if (!$existingOption->getId()) {
throw new InputException( throw new InputException(
__( __(
'Product with specified sku: "%1" does not contain option: "%2"', 'Product with specified sku: "%1" does not contain option: "%2"',
...@@ -161,16 +244,13 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -161,16 +244,13 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
} }
$selectionModel = $this->bundleSelection->create(); $selectionModel = $this->bundleSelection->create();
$selectionModel->setOptionId($optionId) $selectionModel = $this->mapProductLinkToSelectionModel(
->setPosition($linkedProduct->getPosition()) $selectionModel,
->setSelectionQty($linkedProduct->getQty()) $linkedProduct,
->setSelectionPriceType($linkedProduct->getPriceType()) $linkProductModel->getId(),
->setSelectionPriceValue($linkedProduct->getPrice()) $product->getId()
->setSelectionCanChangeQty($linkedProduct->getCanChangeQuantity()) );
->setProductId($linkProductModel->getId()) $selectionModel->setOptionId($optionId);
->setParentProductId($product->getId())
->setIsDefault($linkedProduct->getIsDefault())
->setWebsiteId($this->storeManager->getStore()->getWebsiteId());
try { try {
$selectionModel->save(); $selectionModel->save();
...@@ -242,8 +322,9 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -242,8 +322,9 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
'\Magento\Bundle\Api\Data\LinkInterface' '\Magento\Bundle\Api\Data\LinkInterface'
); );
$link->setIsDefault($selection->getIsDefault()) $link->setIsDefault($selection->getIsDefault())
->setId($selection->getSelectionId())
->setQty($selection->getSelectionQty()) ->setQty($selection->getSelectionQty())
->setIsDefined($selection->getSelectionCanChangeQty()) ->setCanChangeQuantity($selection->getSelectionCanChangeQty())
->setPrice($selectionPrice) ->setPrice($selectionPrice)
->setPriceType($selectionPriceType); ->setPriceType($selectionPriceType);
return $link; return $link;
...@@ -251,7 +332,7 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa ...@@ -251,7 +332,7 @@ class LinkManagement implements \Magento\Bundle\Api\ProductLinkManagementInterfa
/** /**
* @param \Magento\Catalog\Api\Data\ProductInterface $product * @param \Magento\Catalog\Api\Data\ProductInterface $product
* @return \Magento\Bundle\Api\Data\OptionTypeInterface[] * @return \Magento\Bundle\Api\Data\OptionInterface[]
*/ */
private function getOptions(\Magento\Catalog\Api\Data\ProductInterface $product) private function getOptions(\Magento\Catalog\Api\Data\ProductInterface $product)
{ {
......
...@@ -161,7 +161,6 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt ...@@ -161,7 +161,6 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt
/** /**
* {@inheritdoc} * {@inheritdoc}
* @SuppressWarnings(PHPMD.NPathComplexity)
*/ */
public function save( public function save(
\Magento\Catalog\Api\Data\ProductInterface $product, \Magento\Catalog\Api\Data\ProductInterface $product,
...@@ -170,35 +169,25 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt ...@@ -170,35 +169,25 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt
$option->setStoreId($this->storeManager->getStore()->getId()); $option->setStoreId($this->storeManager->getStore()->getId());
$option->setParentId($product->getId()); $option->setParentId($product->getId());
if (!$option->getOptionId()) { $optionId = $option->getOptionId();
$linksToAdd = [];
if (!$optionId) {
$option->setDefaultTitle($option->getTitle()); $option->setDefaultTitle($option->getTitle());
$linksToAdd = is_array($option->getProductLinks()) ? $option->getProductLinks() : []; if (is_array($option->getProductLinks())) {
$linksToAdd = $option->getProductLinks();
}
} else { } else {
$optionCollection = $this->type->getOptionsCollection($product); $optionCollection = $this->type->getOptionsCollection($product);
$optionCollection->setIdFilter($option->getOptionId());
/** @var \Magento\Bundle\Model\Option $existingOption */ /** @var \Magento\Bundle\Model\Option $existingOption */
$existingOption = $optionCollection->getFirstItem(); $existingOption = $optionCollection->getItemById($option->getOptionId());
if (!$existingOption->getOptionId()) { if (!isset($existingOption) || !$existingOption->getOptionId()) {
throw new NoSuchEntityException(__('Requested option doesn\'t exist')); throw new NoSuchEntityException(__('Requested option doesn\'t exist'));
} }
$option->setData(array_merge($existingOption->getData(), $option->getData())); $option->setData(array_merge($existingOption->getData(), $option->getData()));
$this->updateOptionSelection($product, $option);
/** @var \Magento\Bundle\Api\Data\LinkInterface[] $existingLinks */
$existingLinks = is_array($existingOption->getProductLinks()) ? $existingOption->getProductLinks() : [];
/** @var \Magento\Bundle\Api\Data\LinkInterface[] $newProductLinks */
$newProductLinks = is_array($option->getProductLinks()) ? $option->getProductLinks() : [];
/** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToDelete */
$linksToDelete = array_udiff($existingLinks, $newProductLinks, [$this, 'compareLinks']);
foreach ($linksToDelete as $link) {
$this->linkManagement->removeChild($product->getSku(), $option->getOptionId(), $link->getSku());
}
/** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToAdd */
$linksToAdd = array_udiff($newProductLinks, $existingLinks, [$this, 'compareLinks']);
} }
try { try {
...@@ -215,6 +204,50 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt ...@@ -215,6 +204,50 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt
return $option->getOptionId(); return $option->getOptionId();
} }
/**
* Update option selections
*
* @param \Magento\Catalog\Api\Data\ProductInterface $product
* @param \Magento\Bundle\Api\Data\OptionInterface $option
* @return $this
*/
protected function updateOptionSelection(
\Magento\Catalog\Api\Data\ProductInterface $product,
\Magento\Bundle\Api\Data\OptionInterface $option
) {
$optionId = $option->getOptionId();
$existingLinks = $this->linkManagement->getChildren($product->getSku(), $optionId);
$linksToAdd = [];
$linksToUpdate = [];
$linksToDelete = [];
if (is_array($option->getProductLinks())) {
$productLinks = $option->getProductLinks();
foreach ($productLinks as $productLink) {
if (!$productLink->getId()) {
$linksToAdd[] = $productLink;
} else {
$linksToUpdate[] = $productLink;
}
}
/** @var \Magento\Bundle\Api\Data\LinkInterface[] $linksToDelete */
$linksToDelete = array_udiff($existingLinks, $linksToUpdate, [$this, 'compareLinks']);
}
foreach ($linksToUpdate as $linkedProduct) {
$this->linkManagement->saveChild($product->getSku(), $linkedProduct);
}
foreach ($linksToDelete as $linkedProduct) {
$this->linkManagement->removeChild(
$product->getSku(),
$option->getOptionId(),
$linkedProduct->getSku()
);
}
foreach ($linksToAdd as $linkedProduct) {
$this->linkManagement->addChild($product, $option->getOptionId(), $linkedProduct);
}
return $this;
}
/** /**
* @param string $sku * @param string $sku
* @return \Magento\Catalog\Api\Data\ProductInterface * @return \Magento\Catalog\Api\Data\ProductInterface
...@@ -241,7 +274,7 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt ...@@ -241,7 +274,7 @@ class OptionRepository implements \Magento\Bundle\Api\ProductOptionRepositoryInt
\Magento\Bundle\Api\Data\LinkInterface $firstLink, \Magento\Bundle\Api\Data\LinkInterface $firstLink,
\Magento\Bundle\Api\Data\LinkInterface $secondLink \Magento\Bundle\Api\Data\LinkInterface $secondLink
) { ) {
if ($firstLink->getSku() == $secondLink->getSku()) { if ($firstLink->getId() == $secondLink->getId()) {
return 0; return 0;
} else { } else {
return 1; return 1;
......
...@@ -52,7 +52,10 @@ class BundleLoadOptions ...@@ -52,7 +52,10 @@ class BundleLoadOptions
return $product; return $product;
} }
$productExtension = $this->productExtensionFactory->create(); $productExtension = $product->getExtensionAttributes();
if ($productExtension === null) {
$productExtension = $this->productExtensionFactory->create();
}
$productExtension->setBundleProductOptions($this->productOptionList->getItems($product)); $productExtension->setBundleProductOptions($this->productOptionList->getItems($product));
$product->setExtensionAttributes($productExtension); $product->setExtensionAttributes($productExtension);
......
...@@ -17,8 +17,9 @@ class BundleSaveOptions ...@@ -17,8 +17,9 @@ class BundleSaveOptions
/** /**
* @param \Magento\Bundle\Api\ProductOptionRepositoryInterface $optionRepository * @param \Magento\Bundle\Api\ProductOptionRepositoryInterface $optionRepository
*/ */
public function __construct(\Magento\Bundle\Api\ProductOptionRepositoryInterface $optionRepository) public function __construct(
{ \Magento\Bundle\Api\ProductOptionRepositoryInterface $optionRepository
) {
$this->optionRepository = $optionRepository; $this->optionRepository = $optionRepository;
} }
...@@ -45,13 +46,37 @@ class BundleSaveOptions ...@@ -45,13 +46,37 @@ class BundleSaveOptions
} }
/* @var \Magento\Bundle\Api\Data\OptionInterface[] $options */ /* @var \Magento\Bundle\Api\Data\OptionInterface[] $options */
$bundleProductOptions = $product->getExtensionAttributes()->getBundleProductOptions(); $extendedAttributes = $product->getExtensionAttributes();
if ($extendedAttributes === null) {
return $result;
}
$bundleProductOptions = $extendedAttributes->getBundleProductOptions();
if ($bundleProductOptions == null) {
return $result;
}
if (is_array($bundleProductOptions)) { /** @var \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions */
foreach ($bundleProductOptions as $option) { $existingOptions = $this->optionRepository->getList($product->getSku());
$this->optionRepository->save($result, $option); $existingOptionsMap = [];
foreach ($existingOptions as $existingOption) {
$existingOptionsMap[$existingOption->getOptionId()] = $existingOption;
}
$updatedOptionIds = [];
foreach ($bundleProductOptions as $bundleOption) {
$optionId = $bundleOption->getOptionId();
if ($optionId) {
$updatedOptionIds[] = $optionId;
} }
} }
return $result; $optionIdsToDelete = array_diff(array_keys($existingOptionsMap), $updatedOptionIds);
//Handle new and existing options
foreach ($bundleProductOptions as $option) {
$this->optionRepository->save($result, $option);
}
//Delete options that are not in the list
foreach ($optionIdsToDelete as $optionId) {
$this->optionRepository->delete($existingOptionsMap[$optionId]);
}
return $subject->get($result->getSku(), false, $result->getStoreId(), true);
} }
} }
...@@ -61,8 +61,9 @@ class LinksList ...@@ -61,8 +61,9 @@ class LinksList
'\Magento\Bundle\Api\Data\LinkInterface' '\Magento\Bundle\Api\Data\LinkInterface'
); );
$productLink->setIsDefault($selection->getIsDefault()) $productLink->setIsDefault($selection->getIsDefault())
->setId($selection->getSelectionId())
->setQty($selection->getSelectionQty()) ->setQty($selection->getSelectionQty())
->setIsDefined($selection->getSelectionCanChangeQty()) ->setCanChangeQuantity($selection->getSelectionCanChangeQty())
->setPrice($selectionPrice) ->setPrice($selectionPrice)
->setPriceType($selectionPriceType); ->setPriceType($selectionPriceType);
$productLinks[] = $productLink; $productLinks[] = $productLink;
......
...@@ -8,6 +8,8 @@ namespace Magento\Bundle\Model; ...@@ -8,6 +8,8 @@ namespace Magento\Bundle\Model;
/** /**
* Bundle Selection Model * Bundle Selection Model
* *
* @method int getSelectionId()
* @method \Magento\Bundle\Model\Selection setSelectionId(int $value)
* @method int getOptionId() * @method int getOptionId()
* @method \Magento\Bundle\Model\Selection setOptionId(int $value) * @method \Magento\Bundle\Model\Selection setOptionId(int $value)
* @method int getParentProductId() * @method int getParentProductId()
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
*/ */
namespace Magento\Bundle\Model\Source\Option\Selection\Price; namespace Magento\Bundle\Model\Source\Option\Selection\Price;
use Magento\Bundle\Api\Data\LinkInterface;
/** /**
* Extended Attributes Source Model * Extended Attributes Source Model
* *
...@@ -17,6 +19,9 @@ class Type implements \Magento\Framework\Option\ArrayInterface ...@@ -17,6 +19,9 @@ class Type implements \Magento\Framework\Option\ArrayInterface
*/ */
public function toOptionArray() public function toOptionArray()
{ {
return [['value' => '0', 'label' => __('Fixed')], ['value' => '1', 'label' => __('Percent')]]; return [
['value' => LinkInterface::PRICE_TYPE_FIXED, 'label' => __('Fixed')],
['value' => LinkInterface::PRICE_TYPE_PERCENT, 'label' => __('Percent')]
];
} }
} }
...@@ -335,8 +335,9 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase ...@@ -335,8 +335,9 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
->willReturn($optCollectionMock); ->willReturn($optCollectionMock);
$existingOptionMock = $this->getMock('\Magento\Bundle\Model\Option', ['getOptionId'], [], '', false); $existingOptionMock = $this->getMock('\Magento\Bundle\Model\Option', ['getOptionId'], [], '', false);
$optCollectionMock->expects($this->once())->method('setIdFilter')->with($optionId)->willReturnSelf(); $optCollectionMock->expects($this->once())->method('getItemById')
$optCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($existingOptionMock); ->with($optionId)
->willReturn($existingOptionMock);
$existingOptionMock->expects($this->once())->method('getOptionId')->willReturn(null); $existingOptionMock->expects($this->once())->method('getOptionId')->willReturn(null);
$this->assertEquals($optionId, $this->model->save($productMock, $optionMock)); $this->assertEquals($optionId, $this->model->save($productMock, $optionMock));
...@@ -345,13 +346,16 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase ...@@ -345,13 +346,16 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
/** /**
* @SuppressWarnings(PHPMD.UnusedLocalVariable) * @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/ */
public function testUpdate() public function testSaveExistingOption()
{ {
$productId = 1; $productId = 1;
$productSku = 'bundle_sku';
$storeId = 2; $storeId = 2;
$optionId = 5; $optionId = 5;
$existingOptionId = 5; $existingOptionId = 5;
$existingOptionTitle = 'option_title'; $existingLinkToUpdateId = '23';
$existingLinkToDeleteId = '24';
$productSkuToDelete = 'simple2';
$storeMock = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false); $storeMock = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
$storeMock->expects($this->once())->method('getId')->willReturn($storeId); $storeMock->expects($this->once())->method('getId')->willReturn($storeId);
...@@ -359,6 +363,7 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase ...@@ -359,6 +363,7 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
$productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false); $productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
$productMock->expects($this->once())->method('getId')->willReturn($productId); $productMock->expects($this->once())->method('getId')->willReturn($productId);
$productMock->expects($this->any())->method('getSku')->willReturn($productSku);
$optionMock = $this->getMock( $optionMock = $this->getMock(
'\Magento\Bundle\Model\Option', '\Magento\Bundle\Model\Option',
[ [
...@@ -378,6 +383,17 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase ...@@ -378,6 +383,17 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
$optionMock->expects($this->once())->method('setParentId')->with($productId)->willReturnSelf(); $optionMock->expects($this->once())->method('setParentId')->with($productId)->willReturnSelf();
$optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId); $optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId);
$existingLinkToUpdate = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$existingLinkToUpdate->expects($this->any())->method('getId')->willReturn($existingLinkToUpdateId);
$existingLinkToDelete = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$existingLinkToDelete->expects($this->any())->method('getId')->willReturn($existingLinkToDeleteId);
$existingLinkToDelete->expects($this->once())->method('getSku')->willReturn($productSkuToDelete);
$existingLinks = [$existingLinkToUpdate, $existingLinkToDelete];
$this->linkManagementMock->expects($this->once())
->method('getChildren')
->with($productSku, $optionId)
->willReturn($existingLinks);
$optCollectionMock = $this->getMock('\Magento\Bundle\Model\Resource\Option\Collection', [], [], '', false); $optCollectionMock = $this->getMock('\Magento\Bundle\Model\Resource\Option\Collection', [], [], '', false);
$this->typeMock->expects($this->once()) $this->typeMock->expects($this->once())
->method('getOptionsCollection') ->method('getOptionsCollection')
...@@ -390,22 +406,183 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase ...@@ -390,22 +406,183 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
'', '',
false false
); );
$optCollectionMock->expects($this->once())->method('setIdFilter')->with($optionId)->willReturnSelf(); $optCollectionMock->expects($this->once())->method('getItemById')
$optCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($existingOptionMock); ->with($optionId)
->willReturn($existingOptionMock);
$existingOptionMock->expects($this->any())->method('getOptionId')->willReturn($existingOptionId); $existingOptionMock->expects($this->any())->method('getOptionId')->willReturn($existingOptionId);
$existingOptionMock->expects($this->once())->method('getProductLinks')->willReturn(null);
$linkedProductMock = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface'); $productLinkUpdate = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$optionMock->expects($this->exactly(2))->method('getProductLinks')->willReturn([$linkedProductMock]); $productLinkUpdate->expects($this->any())->method('getId')->willReturn($existingLinkToUpdateId);
$productLinkNew = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$productLinkNew->expects($this->any())->method('getId')->willReturn(null);
$optionMock->expects($this->exactly(2))
->method('getProductLinks')
->willReturn([$productLinkUpdate, $productLinkNew]);
$this->optionResourceMock->expects($this->once())->method('save')->with($optionMock)->willReturnSelf(); $this->optionResourceMock->expects($this->once())->method('save')->with($optionMock)->willReturnSelf();
$this->linkManagementMock->expects($this->once()) $this->linkManagementMock->expects($this->once())
->method('addChild') ->method('addChild')
->with($productMock, $optionId, $linkedProductMock) ->with($productMock, $optionId, $productLinkNew);
->willReturn(1); $this->linkManagementMock->expects($this->once())
->method('saveChild')
->with($productSku, $productLinkUpdate);
$this->linkManagementMock->expects($this->once())
->method('removeChild')
->with($productSku, $optionId, $productSkuToDelete);
$this->assertEquals($optionId, $this->model->save($productMock, $optionMock));
}
/**
* @expectedException \Magento\Framework\Exception\NoSuchEntityException
* @expectedExceptionMessage Requested option doesn't exist
*/
public function testSaveExistingOptionNoSuchOption()
{
$productId = 1;
$productSku = 'bundle_sku';
$storeId = 2;
$optionId = 5;
$storeMock = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
$productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
$productMock->expects($this->once())->method('getId')->willReturn($productId);
$productMock->expects($this->any())->method('getSku')->willReturn($productSku);
$optionMock = $this->getMock(
'\Magento\Bundle\Model\Option',
[
'setStoreId',
'setParentId',
'getOptionId',
],
[],
'',
false
);
$optionMock->expects($this->once())->method('setStoreId')->with($storeId)->willReturnSelf();
$optionMock->expects($this->once())->method('setParentId')->with($productId)->willReturnSelf();
$optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId);
$optCollectionMock = $this->getMock('\Magento\Bundle\Model\Resource\Option\Collection', [], [], '', false);
$this->typeMock->expects($this->once())
->method('getOptionsCollection')
->with($productMock)
->willReturn($optCollectionMock);
$existingOptionMock = $this->getMock(
'\Magento\Bundle\Model\Option',
['getOptionId', 'getTitle', 'getProductLinks'],
[],
'',
false
);
$optCollectionMock->expects($this->once())->method('getItemById')
->with($optionId)
->willReturn($existingOptionMock);
$existingOptionMock->expects($this->any())->method('getOptionId')->willReturn(null);
$this->model->save($productMock, $optionMock);
}
public function testSaveNewOption()
{
$productId = 1;
$productSku = 'bundle_sku';
$storeId = 2;
$optionId = 5;
$storeMock = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
$productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
$productMock->expects($this->once())->method('getId')->willReturn($productId);
$productMock->expects($this->any())->method('getSku')->willReturn($productSku);
$optionMock = $this->getMock(
'\Magento\Bundle\Model\Option',
[
'setStoreId',
'setParentId',
'getProductLinks',
'getOptionId',
'setOptionId',
'setDefaultTitle',
'getTitle'
],
[],
'',
false
);
$optionMock->expects($this->once())->method('setStoreId')->with($storeId)->willReturnSelf();
$optionMock->expects($this->once())->method('setParentId')->with($productId)->willReturnSelf();
$optionMock->method('getOptionId')
->will($this->onConsecutiveCalls(null, $optionId, $optionId, $optionId, $optionId));
$productLink1 = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$productLink2 = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$optionMock->expects($this->exactly(2))
->method('getProductLinks')
->willReturn([$productLink1, $productLink2]);
$this->optionResourceMock->expects($this->once())->method('save')->with($optionMock)->willReturnSelf();
$this->linkManagementMock->expects($this->at(0))
->method('addChild')
->with($productMock, $optionId, $productLink1);
$this->linkManagementMock->expects($this->at(1))
->method('addChild')
->with($productMock, $optionId, $productLink2);
$this->assertEquals($optionId, $this->model->save($productMock, $optionMock)); $this->assertEquals($optionId, $this->model->save($productMock, $optionMock));
} }
/**
* @expectedException \Magento\Framework\Exception\CouldNotSaveException
* @expectedExceptionMessage Could not save option
*/
public function testSaveCanNotSave()
{
$productId = 1;
$productSku = 'bundle_sku';
$storeId = 2;
$optionId = 5;
$storeMock = $this->getMock('\Magento\Store\Model\Store', ['getId'], [], '', false);
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
$productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
$productMock->expects($this->once())->method('getId')->willReturn($productId);
$productMock->expects($this->any())->method('getSku')->willReturn($productSku);
$optionMock = $this->getMock(
'\Magento\Bundle\Model\Option',
[
'setStoreId',
'setParentId',
'getProductLinks',
'getOptionId',
'setOptionId',
'setDefaultTitle',
'getTitle'
],
[],
'',
false
);
$optionMock->expects($this->once())->method('setStoreId')->with($storeId)->willReturnSelf();
$optionMock->expects($this->once())->method('setParentId')->with($productId)->willReturnSelf();
$optionMock->method('getOptionId')->will($this->onConsecutiveCalls(null, $optionId, $optionId, $optionId));
$productLink1 = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$productLink2 = $this->getMock('\Magento\Bundle\Api\Data\LinkInterface');
$optionMock->expects($this->exactly(2))
->method('getProductLinks')
->willReturn([$productLink1, $productLink2]);
$this->optionResourceMock->expects($this->once())->method('save')->with($optionMock)
->willThrowException($this->getMock('\Exception'));
$this->model->save($productMock, $optionMock);
}
public function testGetList() public function testGetList()
{ {
$productSku = 'simple'; $productSku = 'simple';
......
...@@ -60,7 +60,6 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -60,7 +60,6 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
public function testAroundLoad() public function testAroundLoad()
{ {
$this->markTestSkipped('MAGETWO-34577');
$productMock = $this->getMock( $productMock = $this->getMock(
'\Magento\Catalog\Model\Product', '\Magento\Catalog\Model\Product',
['getTypeId', 'setExtensionAttributes'], ['getTypeId', 'setExtensionAttributes'],
...@@ -82,6 +81,7 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -82,6 +81,7 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
->willReturn([$optionMock]); ->willReturn([$optionMock]);
$productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension') $productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
->disableOriginalConstructor() ->disableOriginalConstructor()
->setMethods(['setBundleProductOptions', 'getBundleProductOptions'])
->getMock(); ->getMock();
$this->productExtensionFactory->expects($this->once()) $this->productExtensionFactory->expects($this->once())
->method('create') ->method('create')
......
...@@ -43,6 +43,11 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -43,6 +43,11 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
*/ */
protected $productBundleOptionsMock; protected $productBundleOptionsMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
protected $productInterfaceFactoryMock;
/** /**
* @var \Closure * @var \Closure
*/ */
...@@ -54,7 +59,7 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -54,7 +59,7 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
$this->productOptionRepositoryMock = $this->getMock('Magento\Bundle\Api\ProductOptionRepositoryInterface'); $this->productOptionRepositoryMock = $this->getMock('Magento\Bundle\Api\ProductOptionRepositoryInterface');
$this->productMock = $this->getMock( $this->productMock = $this->getMock(
'Magento\Catalog\Model\Product', 'Magento\Catalog\Model\Product',
['getExtensionAttributes', 'getTypeId'], ['getExtensionAttributes', 'getTypeId', 'getSku', 'getStoreId'],
[], [],
'', '',
false false
...@@ -62,10 +67,12 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -62,10 +67,12 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
$this->closureMock = function () { $this->closureMock = function () {
return $this->productMock; return $this->productMock;
}; };
$this->plugin = new BundleSaveOptions($this->productOptionRepositoryMock); $this->plugin = new BundleSaveOptions(
$this->productOptionRepositoryMock
);
$this->productExtensionMock = $this->getMock( $this->productExtensionMock = $this->getMock(
'Magento\Catalog\Api\Data\ProductExtension', 'Magento\Catalog\Api\Data\ProductExtension',
['getBundleProductOptions'], ['getBundleProductOptions', 'setBundleProductOptions'],
[], [],
'', '',
false false
...@@ -98,7 +105,7 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -98,7 +105,7 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
->willReturn($this->productExtensionMock); ->willReturn($this->productExtensionMock);
$this->productExtensionMock->expects($this->once()) $this->productExtensionMock->expects($this->once())
->method('getBundleProductOptions') ->method('getBundleProductOptions')
->willReturn([]); ->willReturn(null);
$this->productOptionRepositoryMock->expects($this->never())->method('save'); $this->productOptionRepositoryMock->expects($this->never())->method('save');
...@@ -110,20 +117,105 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase ...@@ -110,20 +117,105 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
public function testAroundSaveWhenProductIsBundleWithOptions() public function testAroundSaveWhenProductIsBundleWithOptions()
{ {
$productSku = "bundle_sku";
$option = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
$this->productMock->expects($this->once())->method('getTypeId')->willReturn('bundle');
$this->productMock->expects($this->once())
->method('getExtensionAttributes')
->willReturn($this->productExtensionMock);
$this->productExtensionMock->expects($this->once())
->method('getBundleProductOptions')
->willReturn([$option]);
$this->productOptionRepositoryMock->expects($this->once())->method('save')->with($this->productMock, $option);
$this->productMock->expects($this->exactly(2))->method('getSku')
->will($this->returnValue($productSku));
$this->productOptionRepositoryMock->expects($this->once())
->method('getList')
->with($productSku)
->will($this->returnValue([]));
$newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
->disableOriginalConstructor()->getMock();
$this->productRepositoryMock->expects($this->once())
->method('get')
->with($productSku, false, null, true)
->willReturn($newProductMock);
$this->assertEquals(
$newProductMock,
$this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
);
}
/**
* Test the case where the product has existing options
*/
public function testAroundSaveWhenProductIsBundleWithOptionsAndExistingOptions()
{
$existOption1Id = 10;
$existOption2Id = 11;
$productSku = 'bundle_sku';
$existingOption1 = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
$existingOption1->expects($this->once())
->method('getOptionId')
->will($this->returnValue($existOption1Id));
$existingOption2 = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
$existingOption2->expects($this->once())
->method('getOptionId')
->will($this->returnValue($existOption2Id));
$bundleOptionExisting = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
$bundleOptionExisting->expects($this->once())
->method('getOptionId')
->will($this->returnValue($existOption1Id));
$bundleOptionNew = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
$bundleOptionNew->expects($this->once())
->method('getOptionId')
->will($this->returnValue(null));
$this->productMock->expects($this->once())->method('getTypeId')->willReturn('bundle'); $this->productMock->expects($this->once())->method('getTypeId')->willReturn('bundle');
$this->productMock->expects($this->once()) $this->productMock->expects($this->once())
->method('getExtensionAttributes') ->method('getExtensionAttributes')
->willReturn($this->productExtensionMock); ->willReturn($this->productExtensionMock);
$this->productExtensionMock->expects($this->once()) $this->productExtensionMock->expects($this->once())
->method('getBundleProductOptions') ->method('getBundleProductOptions')
->willReturn([$this->productBundleOptionsMock]); ->willReturn([$bundleOptionExisting, $bundleOptionNew]);
$this->productMock->expects($this->exactly(2))->method('getSku')
->will($this->returnValue($productSku));
$this->productOptionRepositoryMock->expects($this->once()) $this->productOptionRepositoryMock->expects($this->once())
->method('getList')
->with($productSku)
->will($this->returnValue([$existingOption1, $existingOption2]));
$this->productOptionRepositoryMock
->expects($this->at(1))
->method('save')
->with($this->productMock, $bundleOptionExisting);
$this->productOptionRepositoryMock
->expects($this->at(1))
->method('save') ->method('save')
->with($this->productMock, $this->productBundleOptionsMock); ->with($this->productMock, $bundleOptionNew);
$this->productOptionRepositoryMock
->expects($this->once())
->method('delete')
->with($existingOption2);
$newProductMock = $this->getMockBuilder('Magento\Catalog\Api\Data\ProductInterface')
->disableOriginalConstructor()->getMock();
$this->productRepositoryMock->expects($this->once())
->method('get')
->with($productSku, false, null, true)
->willReturn($newProductMock);
$this->assertEquals( $this->assertEquals(
$this->productMock, $newProductMock,
$this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock) $this->plugin->aroundSave($this->productRepositoryMock, $this->closureMock, $this->productMock)
); );
} }
......
...@@ -64,6 +64,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase ...@@ -64,6 +64,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase
'getIsDefault', 'getIsDefault',
'getSelectionQty', 'getSelectionQty',
'getSelectionCanChangeQty', 'getSelectionCanChangeQty',
'getSelectionId',
'__wakeup' '__wakeup'
], ],
[], [],
...@@ -89,6 +90,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase ...@@ -89,6 +90,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase
public function testLinksList() public function testLinksList()
{ {
$optionId = 665; $optionId = 665;
$selectionId = 1345;
$this->productTypeMock->expects($this->once()) $this->productTypeMock->expects($this->once())
->method('getSelectionsCollection') ->method('getSelectionsCollection')
->with([$optionId], $this->productMock) ->with([$optionId], $this->productMock)
...@@ -99,6 +101,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase ...@@ -99,6 +101,7 @@ class LinksListTest extends \PHPUnit_Framework_TestCase
->willReturn('selection_price_type'); ->willReturn('selection_price_type');
$this->selectionMock->expects($this->once())->method('getSelectionPriceValue')->willReturn(12); $this->selectionMock->expects($this->once())->method('getSelectionPriceValue')->willReturn(12);
$this->selectionMock->expects($this->once())->method('getData')->willReturn(['some data']); $this->selectionMock->expects($this->once())->method('getData')->willReturn(['some data']);
$this->selectionMock->expects($this->once())->method('getSelectionId')->willReturn($selectionId);
$this->selectionMock->expects($this->once())->method('getIsDefault')->willReturn(true); $this->selectionMock->expects($this->once())->method('getIsDefault')->willReturn(true);
$this->selectionMock->expects($this->once())->method('getSelectionQty')->willReturn(66); $this->selectionMock->expects($this->once())->method('getSelectionQty')->willReturn(66);
$this->selectionMock->expects($this->once())->method('getSelectionCanChangeQty')->willReturn(22); $this->selectionMock->expects($this->once())->method('getSelectionCanChangeQty')->willReturn(22);
...@@ -108,8 +111,9 @@ class LinksListTest extends \PHPUnit_Framework_TestCase ...@@ -108,8 +111,9 @@ class LinksListTest extends \PHPUnit_Framework_TestCase
->with($linkMock, ['some data'], '\Magento\Bundle\Api\Data\LinkInterface')->willReturnSelf(); ->with($linkMock, ['some data'], '\Magento\Bundle\Api\Data\LinkInterface')->willReturnSelf();
$linkMock->expects($this->once())->method('setIsDefault')->with(true)->willReturnSelf(); $linkMock->expects($this->once())->method('setIsDefault')->with(true)->willReturnSelf();
$linkMock->expects($this->once())->method('setQty')->with(66)->willReturnSelf(); $linkMock->expects($this->once())->method('setQty')->with(66)->willReturnSelf();
$linkMock->expects($this->once())->method('setIsDefined')->with(22)->willReturnSelf(); $linkMock->expects($this->once())->method('setCanChangeQuantity')->with(22)->willReturnSelf();
$linkMock->expects($this->once())->method('setPrice')->with(12)->willReturnSelf(); $linkMock->expects($this->once())->method('setPrice')->with(12)->willReturnSelf();
$linkMock->expects($this->once())->method('setId')->with($selectionId)->willReturnSelf();
$linkMock->expects($this->once()) $linkMock->expects($this->once())
->method('setPriceType')->with('selection_price_type')->willReturnSelf(); ->method('setPriceType')->with('selection_price_type')->willReturnSelf();
$this->linkFactoryMock->expects($this->once())->method('create')->willReturn($linkMock); $this->linkFactoryMock->expects($this->once())->method('create')->willReturn($linkMock);
......
...@@ -8,7 +8,5 @@ ...@@ -8,7 +8,5 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd"> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
<custom_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
<attribute code="bundle_product_options" type="Magento\Bundle\Api\Data\OptionInterface[]" /> <attribute code="bundle_product_options" type="Magento\Bundle\Api\Data\OptionInterface[]" />
<attribute code="price_type" type="integer" />
<attribute code="price_view" type="string" />
</custom_attributes> </custom_attributes>
</config> </config>
...@@ -13,7 +13,13 @@ ...@@ -13,7 +13,13 @@
<resource ref="Magento_Catalog::products"/> <resource ref="Magento_Catalog::products"/>
</resources> </resources>
</route> </route>
<route url="/V1/bundle-products/:productId/children" method="GET"> <route url="/V1/bundle-products/:sku/links/:id" method="PUT">
<service class="Magento\Bundle\Api\ProductLinkManagementInterface" method="saveChild"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
<route url="/V1/bundle-products/:productSku/children" method="GET">
<service class="Magento\Bundle\Api\ProductLinkManagementInterface" method="getChildren"/> <service class="Magento\Bundle\Api\ProductLinkManagementInterface" method="getChildren"/>
<resources> <resources>
<resource ref="Magento_Catalog::products"/> <resource ref="Magento_Catalog::products"/>
......
...@@ -27,10 +27,11 @@ interface ProductRepositoryInterface ...@@ -27,10 +27,11 @@ interface ProductRepositoryInterface
* @param string $sku * @param string $sku
* @param bool $editMode * @param bool $editMode
* @param null|int $storeId * @param null|int $storeId
* @param bool $forceReload
* @return \Magento\Catalog\Api\Data\ProductInterface * @return \Magento\Catalog\Api\Data\ProductInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\NoSuchEntityException
*/ */
public function get($sku, $editMode = false, $storeId = null); public function get($sku, $editMode = false, $storeId = null, $forceReload = false);
/** /**
* Get info about product by product id * Get info about product by product id
...@@ -38,10 +39,11 @@ interface ProductRepositoryInterface ...@@ -38,10 +39,11 @@ interface ProductRepositoryInterface
* @param int $productId * @param int $productId
* @param bool $editMode * @param bool $editMode
* @param null|int $storeId * @param null|int $storeId
* @param bool $forceReload
* @return \Magento\Catalog\Api\Data\ProductInterface * @return \Magento\Catalog\Api\Data\ProductInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\NoSuchEntityException
*/ */
public function getById($productId, $editMode = false, $storeId = null); public function getById($productId, $editMode = false, $storeId = null, $forceReload = false);
/** /**
* Delete product * Delete product
......
...@@ -64,6 +64,8 @@ class Helper ...@@ -64,6 +64,8 @@ class Helper
public function initialize(\Magento\Catalog\Model\Product $product) public function initialize(\Magento\Catalog\Model\Product $product)
{ {
$productData = $this->request->getPost('product'); $productData = $this->request->getPost('product');
unset($productData['custom_attributes']);
unset($productData['extension_attributes']);
if ($productData) { if ($productData) {
$stockData = isset($productData['stock_data']) ? $productData['stock_data'] : []; $stockData = isset($productData['stock_data']) ? $productData['stock_data'] : [];
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment