4

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.

2

3 Answers 3

3

Try this, it's working for me.

global $objectManager;        

$sourceList = $objectManager->get('\Magento\Inventory\Model\ResourceModel\Source\Collection');
$sourceListArr = $sourceList->load();
$i=1;

$sourceList = array();
foreach ($sourceListArr as $sourceItemName) {
    $sourceCode = $sourceItemName->getSourceCode();
    $sourceName = $sourceItemName->getName();

    $sourceList['sourcecount'] = $i;
    $sourceList['sourceCode'] = $sourceCode;
    $sourceList['sourceName'] = $sourceName;

    $sourceAllList[] = $sourceList;

    $i++;
}

print_r($sourceAllList);

//Output will be

Array
(
    [0] => Array
        (
            [sourcecount] => 1
            [sourceCode] => default
            [sourceName] => Default Source
        )

    [1] => Array
        (
            [sourcecount] => 2
            [sourceCode] => CAN
            [sourceName] => Canada
        )

    [2] => Array
        (
            [sourcecount] => 3
            [sourceCode] => USA
            [sourceName] => United State
        )

)
3

Try this code. It worked for me.

use Magento\Framework\Api\SearchCriteriaBuilderFactory;
use Magento\InventoryApi\Api\SourceRepositoryInterface;

/**
* @var SourceRepositoryInterface
*/
private $sourceRepository;

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

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

/**
* {@inheritdoc}
* @codeCoverageIgnore
*/
public function getAllOptions()
{
  if (!$this->_options) {
      /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
      $searchCriteriaBuilder = $this->searchCriteriaBuilderFactory->create();
      $searchCriteria = $searchCriteriaBuilder->create();
      $sources = $this->sourceRepository->getList($searchCriteria)->getItems();
      foreach ($sources as $source) {
          $this->_options[] = [
            'value' => $source->getCountryId(),
            'label' => $source->getCountryId()
          ];
      }
  }
  return $this->_options;
}
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));
            }
        }
    }
}
7
  • 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. Feb 12, 2019 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. Feb 12, 2019 at 12:45
  • Why are you looking option id when you save dynamic data?
    – Sohel Rana
    Feb 12, 2019 at 12:59
  • filter is not wokring on frontend Feb 12, 2019 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. Feb 12, 2019 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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