0

Working on Magento 2.4.3

I am adding a product programmatically and so far it seems to work. The only thing what I am facing is, that Default Stock under Salable Quantity is not shown. See screenshot: enter image description here

If I open the product and just save it without changing something, "Default Stock: 30" is shown as it should.

So, something is missing in my code for creating a new product, but I do not know what.

I am using the classes: \Magento\Catalog\Model\Product $product, \Magento\Catalog\Model\Product\Copier $copier

Here the code I am using:

    $product = $this->product->load(143); // ein Biku termin kopieren
    $productcopy = $this->copier->copy($product);
    $productcopy->setSku($sku);
    $productcopy->setName($name);
    
    $productcopy->setStockData(
            array (
                    'use_config_manage_stock' => 0,
                    'manage_stock' => 1,
                    'is_in_stock'   => 1,
                    'qty'   => 30,
                    'stock_id' => 1
            )
        );
    
    $productcopy->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
    $productcopy->save();

Any idea what is missing?

Hi Mohit, yes, I can. Here is the full code. There is more in it, as I add as well a new swatch and assign it to the new product and make the link to the assosiated configurable product. This is all working fine, except of the "Default Stock" issue as shown before. There are a couple of injections in the class which are not needed at the end. THis is because I tried a couple of ways to do what I want. One more information: it is a controller called in the backend of Magento.

<?php
namespace JscDesign\Coupon\Controller\Adminhtml\EventList;

class Save extends \Magento\Backend\App\Action
{
    protected $eavConfig;
    protected $attributeOptionInterfaceFactory;
    protected $attributeOptionManagement;
    
    protected $customFactory;
 
    protected $adapterFactory;
    protected $uploader;
    protected $product;
    protected $copier;
    protected $productRepository;
    protected $productLinkFactory;
    protected $productFactory;
    protected $linkmanagement;
    protected $stockRegistryInterface;
    
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \JscDesign\Coupon\Model\CustomFactory $customFactory,
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $attributeOptionInterfaceFactory,
        \Magento\Catalog\Api\ProductAttributeOptionManagementInterface $attributeOptionManagement,
        \Magento\Catalog\Model\Product $product,
        \Magento\Catalog\Model\Product\Copier $copier,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Catalog\Model\ProductLink\LinkFactory $productLinkFactory,
        \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory,
        \Magento\ConfigurableProduct\Model\LinkManagement $linkmanagement,
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistryInterface
    ) {
        $this->customFactory = $customFactory;
        $this->eavConfig = $eavConfig;
        $this->attributeOptionInterfaceFactory = $attributeOptionInterfaceFactory;;
        $this->attributeOptionManagement = $attributeOptionManagement;
        $this->product = $product;
        $this->copier = $copier;
        $this->productRepository = $productRepository;
        $this->productLinkFactory = $productLinkFactory;
        $this->productFactory = $productFactory;
        $this->linkmanagement = $linkmanagement;
        $this->stockRegistryInterface= $stockRegistryInterface;
        parent::__construct($context);
    }
 
    public function execute()
    {
        $data = $this->getRequest()->getPostValue();
        
        try {
            $model = $this->customFactory->create();
            $model->addData([
                    "event_name" => $data['event_name'],
                    "event_date" => $data['event_date'],
            ]);
            
            $saveData = $model->save();
            
            if($saveData){
                $this->messageManager->addSuccess( __('Event erfolgreich hinzugefügt!') );
            }
            
        }catch (\Exception $e) {
            $this->messageManager->addError(__($e->getMessage()));
        }
        $newDate = date("d.m.Y",strtotime($data['event_date']));
        
        
        // Neuen Swatch in Atrribut termin eintragen
        // Hier das Datum des Events
        $this->processAttributes($newDate);


        // Frage ob BIKU oder BTAG
        if( strstr( $data['event_name'], 'Bierkulinarische') )
        {
            $product = $this->product->load(151); // ein Biku termin kopieren
            $productcopy = $this->copier->copy($product);
            $this->newProduct( $productcopy, 'ABIKUT-'.$newDate, 'Bierkulinarische Führung-'.$newDate, 30, $newDate);
            
            // Neues Produkt als Variation zum Produkt ABIKUT hinzufügen
            $this->linkmanagement->addChild('ABIKUT', 'ABIKUT-'.$newDate);
        }
        if( strstr( $data['event_name'], 'Brauer') )
        {
            $product = $this->product->load(156); // ein Biku termin kopieren
            $productcopy = $this->copier->copy($product);
            $this->newProduct( $productcopy, 'ABTAGT-'.$newDate, 'Brauer für einen Tag-'.$newDate, 30, $newDate);
            
            // Neues Produkt als Variation zum Produkt ABTAGT hinzufügen
            $this->linkmanagement->addChild('ABTAGT', 'ABTAGT-'.$newDate);
            
        }
        
        $this->_redirect('*/*/index');
        
    }

    public function processAttributes($newOption)
    {
        $attribute = $this->eavConfig->getAttribute('catalog_product', 'termin');
        $this->registerOption($attribute->getId(), $newOption);
    }
    
    private function registerOption($attributeCode, $label)
    {
        $option = $this->attributeOptionInterfaceFactory->create();
        $option->setLabel($label);
        $option->setValue($label);
        
        return $this->attributeOptionManagement->add(
                $attributeCode,
                $option
                );
    }
    public function newProduct( $product, $sku, $name, $qty, $newSwatch)
    {   
        $product->setSku($sku);
        $product->setName($name);

        $swatch = $newSwatch;
        $product_resource = $product->getResource();
        $swatch_attribute = $product_resource->getAttribute('termin');
        if ($swatch_attribute->usesSource()) {
            $swatch_option_id = $swatch_attribute->getSource()->getOptionId($newSwatch);
            if ($swatch_option_id != '') {
                $product->setData('termin', $swatch_option_id);
            }
        }    
        
        $product->setStockData(
                array (
                        'use_config_manage_stock' => 0,
                        'manage_stock' => 1,
                        'is_in_stock'   => 1,
                        'qty'   => 30,
                        'stock_id' => 1
                )
            );
        
        $product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
        $product->save();
        
    }
}
1
  • i have put your code in custom script it is working. So can you share me full code. Commented Jan 1, 2022 at 5:26

2 Answers 2

0

Found the answer to my question. Will share it here, maybe somebody needs it as well.

Ok, as Magento 2.4.3 is using MSI for inventory and stock management, the function $product->setStockData sets the values in the produkt, but it is not updating the stockItem stuff. This needs to be made additionally. I am using the following code:

    $sourceItems = [];

    $sourceItem = $this->sourceItem->create();
    $sourceItem->setSourceCode('default');
    $sourceItem->setQuantity(30);
    $sourceItem->setSku($sku);
    $sourceItem->setStatus(\Magento\InventoryApi\Api\Data\SourceItemInterface::STATUS_IN_STOCK);
    $sourceItems[] = $sourceItem;
    
    $this->sourceItemsSaveInterface->execute($sourceItems);

Of course, the accorindg classes have to be injected: \Magento\InventoryApi\Api\SourceItemsSaveInterface $sourceItemsSaveInterface, \Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory $sourceItem

WIth this it is working as expected. Default stock is shown.

0

What happens if you have MSI disabled and you can't inject those classes? How can you still add the stock item?

  • Adding a product through the backend (as an admin) with stock works.
  • Adding a product through a cli script with stock works.
  • Adding a product through the website, using an observer, fails to add the stock item - it's blank.
2
  • If MSI is disabled, it will not work of course. I do have no other solution to this. I am using MSI, so for me it's working
    – Chequille
    Commented Dec 15, 2022 at 21:21
  • I fixed it by adding a stockItem to the table programmatically. Thanks. ``` $stockItem = $this->stockItemFactory->create(); $stockItem->setProductId($product->getId()); $stockItem->setQty(0); $stockItem->setIsInStock(1); $stockItem->setUseConfigManageStock(1); $stockItem->setManageStock(0); $stockItem->setUseConfigMinSaleQty(0); $stockItem = $this->stockItemRepository->save($stockItem); ``` Commented Dec 15, 2022 at 22:30

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.