How to get simple product id from selected configurable Attribute id and it's value in Magento 2?
-
24-02-2021 - |
문제
I have configure product id 2671
And selected attributes with value
- attributes id
280[color]
and selected value142[Black]
- attributes id
757[size]
and selected value181[M]
Based on these values how can I get simple product id of above selected attributes ids and values.
해결책
Magento provides function for that, by passing attributes in array format you can get simple product of those variants.
/magento/module-configurable-product/Model/Product/Type/Configurable.php
- product id
2671
And selected attributes with value
- attributes id
280[color]
and selected value142[Black]
- attributes id
757[size]
and selected value181[M]
Retrieve used product by attribute values
public function __construct(
\Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableProTypeModel,
\Magento\Catalog\Model\Product $product
) {
$this->_configurableProTypeModel = $configurableProTypeModel;
$this->_product = $product;
}
$product = $this->productRepository->getById($product_id);
// Valid format for attributes
//$attributesInfo = array( $attributeId => $attributeValue);
$attributesInfo = array( 280 => 145,757=>181);
$associateProduct = $this->_configurableProTypeModel->getProductByAttributes($attributesInfo, $product);
다른 팁
The following code works for me.
<script type="text/javascript">
require(['jquery','underscore'], function(jQuery,_){
var confProductId = jQuery('.price-box').attr('data-product-id');
jQuery(".product-options-wrapper select[id^='attribute']").on('change', function() {
var data = [];
var $el=jQuery(".product-options-wrapper select[id^='attribute']");
$el.each(function(){
data.push({selectedValue:jQuery(this).val(),selectedAttributeId:jQuery(this).attr('id').replace('attribute', '')});
});
jQuery.ajax({
url: "<?php echo $block->getBaseUrl();?>/getweekprice/index/index",
type: "POST",
data: { confProductId:confProductId,params: data },
showLoader: false,
cache: false,
success: function(response){
jQuery('#product-detail-week-prices').html(response).append("<span class='day-text week-text'>per week (ex.VAT)</span>");
}
});
});
});
Custom Module for handling ajax code.
class Index extends \Magento\Framework\App\Action\Action {
protected $resultPageFactory;
protected $jsonHelper;
protected $productObj;
protected $configurableProTypeModel;
protected $logger;
protected $currency;
/**
* Constructor
*
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\Json\Helper\Data $jsonHelper
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableProTypeModel,
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Magento\Framework\Json\Helper\Data $jsonHelper,
\Magento\Framework\Pricing\Helper\Data $currency,
\Confproducts\Weekpricesimpleprod\Logger\Logger $logger
) {
$this->resultPageFactory = $resultPageFactory;
$this->jsonHelper = $jsonHelper;
$this->configurableProTypeModel = $configurableProTypeModel;
$this->productObj = $productRepository;
$this->logger = $logger;
$this->currency = $currency;
parent::__construct($context);
}
/**
* Execute view action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
try {
$attributesInfo = array();
$getAjaxPostValues = $this->getRequest()->getPostValue();
$product = $this->productObj->getById( $getAjaxPostValues['confProductId'] );
foreach( $getAjaxPostValues['params'] as $attributeData ) {
if( empty( $attributeData['selectedValue'] ) )
{
return $this->jsonResponse( $this->currency->currency(0.00,true, false ) );
}
$attributesInfo[$attributeData['selectedAttributeId']] = $attributeData['selectedValue'];
}
$associateProduct = $this->configurableProTypeModel->getProductByAttributes($attributesInfo, $product);
$getWeekPrice = $associateProduct->getData('week_price');
$weekPrice = round( $getWeekPrice,2 );
$formattedWeekPrice = $this->currency->currency( $weekPrice,true,false);
// $this->logger->log(100,print_r($getAjaxPostValues,true));
return $this->jsonResponse( $formattedWeekPrice );
} catch (\Magento\Framework\Exception\LocalizedException $e) {
return $this->jsonResponse($e->getMessage());
} catch (\Exception $e) {
$this->logger->critical($e);
return $this->jsonResponse($e->getMessage());
}
}
/**
* Create json response
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function jsonResponse($response = '')
{
return $this->getResponse()->representJson(
$this->jsonHelper->jsonEncode($response)
);
}}
You can use this below code to get simple product id based on configurable product ID.
If you get value of selected configurable product id in js file, then you can pass value using ajax and call controller to get simple product id. If you want to get simple product id by compare value of selected attribute value, then you can use commented code also.
Add this below code in your controller :
<?php
namespace RH\Blog\Controller\Index;
class Test extends \Magento\Framework\App\Action\Action {
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
protected $productRepository;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* [__construct description]
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository [description]
* @param \Magento\Store\Model\StoreManagerInterface $storeManager [description]
*/
public function __construct(
....
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Store\Model\StoreManagerInterface $storeManager
....
) {
....
$this->productRepository = $productRepository;
$this->storeManager = $storeManager;
....
}
public function execute() {
$configurable_id = '2671';
$product = $this->productRepository->getById($configurable_id);
$storeId = $this->storeManager->getStore()->getId();
$productTypeInstance = $product->getTypeInstance();
$productTypeInstance->setStoreFilter($storeId, $product);
$usedProducts = $productTypeInstance->getUsedProducts($product);
foreach ($usedProducts as $child) {
echo "Simple Product ID : ".$child->getId() . "<br/>";
// $selected_option_val = $child->getAttributeText('color');
// if ($selected_option_val == 'your_selected_attr_val') {
// return $child->getId();
// }
}
}
}
Try this.
public function __construct(
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\ResourceModel\Eav\Attribute $eavAttribute,
\Magento\Catalog\Model\ProductRepository $productRepository
) {
$this->storeManager = $storeManager;
$this->eavAttribute = $eavAttribute;
$this->productRepository = $productRepository;
}
public function getSimpleProductId()
{
$simple_product_id = null;
$configurable_product_id = 2671;
$color_id = 280;
$size_id = 757;
$color_value = 142;
$size_value = 181;
$color_code = $this->eavAttribute->load($color_id)->getAttributeCode();
$size_code = $this->eavAttribute->load($size_id)->getAttributeCode();
$product = $this->getProductById($configurable_product_id);
$productTypeInstance = $product->getTypeInstance();
$simple_products = $productTypeInstance->getUsedProducts($product);
foreach ($simple_products as $simple)
{
if($simple->getData($color_code) == $color_value && $simple->getData($size_code) == $size_value)
{
$simple_product_id = $simple->getId();
}
}
return $simple_product_id;
}
public function getProductById($id)
{
return $this->productRepository->getById($id, false, $this->storeManager->getStore()->getId());
}