0

I want to get all the location names from the Multi Source Inventory (MSI). How could I get a collection of all locations in my custom module?

Here I want to create a new multi-select product attribute name "place", which has the values of all source names as its attribute values.

i.e. if there are 3 sources "US, UK, IN" then attribute has the same values "US, UK, IN" in product form.

How could I achieve this functionality? Do anyone have an idea about it?

I have attribute script as below:

$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

    $eavSetup->addAttribute(Product::ENTITY, 'place',
        [
            'group' => 'General',
            'sort_order' => 30,
            'type' => 'text',
            'backend' => '\Module\Name\Model\Backend\Place',
            'frontend' => '',
            'class' => '',
            'label' => 'Place',
            'input' => 'multiselect',
            'source' => '',
            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => true,
            'user_defined' => false,
            'default' => '',
            'searchable' => true,
            'filterable' => true,
            'comparable' => false,
            'visible_on_front' => true,
            'used_in_product_listing' => true,
            'unique' => false
        ]
    );

Thanks in advance.

1

Try following way. Guess SR\MagentoStackExchange\Model\Backend\Place is your backend.


<?php
namespace SR\MagentoStackExchange\Model\Backend;

use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend;
use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SearchCriteriaBuilderFactory;
use Magento\Framework\App\RequestInterface;

class Place extends AbstractBackend
{
    /**
     * @var SourceRepositoryInterface
     */
    private $sourceRepository;

    /**
     * @var SearchCriteriaBuilderFactory
     */
    private $searchCriteriaBuilderFactory;

    /**
     * @var RequestInterface
     */
    private $request;

    /**
     * Place constructor.
     *
     * @param SourceRepositoryInterface $sourceRepository
     * @param SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory
     * @param RequestInterface $request
     */
    public function __construct(
        SourceRepositoryInterface $sourceRepository,
        SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
        RequestInterface $request
    ) {
        $this->sourceRepository = $sourceRepository;
        $this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
        $this->request = $request;
    }

    /**
     * @param Product $object
     * @return $this
     */
    public function beforeSave($object)
    {
        $sources = $this->request->getParam('sources', []);
        $assignedSources = $sources['assigned_sources'] ?? [];

        if (count($assignedSources) > 0) {
            $sourceCodes = [];
            foreach ($assignedSources as $assignedSource) {
                $sourceCodes[] = $assignedSource['source_code'];
            }

            if (count($sourceCodes) > 0) {
                /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
                $searchCriteriaBuilder = $this->searchCriteriaBuilderFactory->create();
                $searchCriteria = $searchCriteriaBuilder->addFilter('source_code', $sourceCodes, 'in')->create();
                $sources = $this->sourceRepository->getList($searchCriteria)->getItems();
                $countries = [];
                foreach ($sources as $source) {
                    $countries[] =  $source->getCountryId();
                }

                $countries = array_unique($countries);
                $object->setData('place', implode(',', $countries));
            }
        }
    }
}
  • Thanks for your help @Sohel Rana. But my question is if I use this code then each time of product save it will get source id different for each product place attribute, How can I solve that? The answer is helpful but needs some more clarification. – Utsav Gupta Feb 12 at 11:45
  • Without attribute, option id it is not working. it saves data in the database but filter is not working on the frontend. – Utsav Gupta Feb 12 at 12:45
  • Why are you looking option id when you save dynamic data? – Sohel Rana Feb 12 at 12:59
  • filter is not wokring on frontend – Utsav Gupta Feb 12 at 13:03
  • in table "catalog_product_entity_text" entry is there but no entry in "eav_attribute_option_value" thats why it is not working i think. – Utsav Gupta Feb 12 at 13:10

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.