Magento 2: Aggiornamento programmatico dell'inventario


12

Nel seguente codice, sono in grado di memorizzare tutte le informazioni con l'esclusione dei dati di borsa. Qualcosa è cambiato in Magento 2?

public function __construct(
    ScopeConfigInterface $scopeConfig, CollectionFactory $product,
    Magento\Catalog\Api\ProductRepositoryInterface $productRepository
) {
    $this->scopeConfig = $scopeConfig;
    $this->product = $product;
    $this->productRepository = $productRepository;
}

public function update(\XXXXXX\XXXXXX\Api\Data\InventoryCollectionInterface $data) {
    foreach ($data['list'] as $d) {
        $product = $this->productRepository->getById($d['entity_id']);
        $product->setStatus(($d['quantity'] > 0 ? 1 : 0));
        $product->setUpc($d['upc']);
        $product->setStockData(array(
            'qty' => $d['quantity'],
            'is_in_stock' => ($d['quantity'] > 0 ? 1 : 0)
        ));

        $this->productRepository->save($product);
    }

    return "Done";
}

1
Questo potrebbe essere d'aiuto: github.com/magento/magento2/issues/5771
Mukesh Chapagain

Risposte:


34

Questo funziona per me:

$item = ['qty' => 11]; // For example
$product->setStockData(['qty' => $item['qty'], 'is_in_stock' => $item['qty'] > 0]);
$product->save();

Modifica :

Questo non è più il modo corretto di gestirlo, perché $product->save()è obsoleto da Magento 2.1. Il modo corretto per farlo è utilizzando StockRegistryInterface:

/**
 * @var StockRegistryInterface
 */
protected $stockRegistry;

/**
 * Inventory constructor.
 * @param StockRegistryInterface $stockRegistry
 */
public function __construct(
    StockRegistryInterface $stockRegistry
)
{
    $this->stockRegistry = $stockRegistry;
    parent::__construct();
}

Con il codice sopra, è possibile utilizzare quanto segue:

$sku = 'ABC123';
$qty = 10;
$stockItem = $this->stockRegistry->getStockItemBySku($sku);
$stockItem->setQty($qty);
$this->stockRegistry->updateStockItemBySku($sku, $stockItem);

Usa i gestori il più possibile. Tieni i tuoi moduli disaccoppiati l'uno dall'altro.

È The Magento Way ™


setStockData è ciò che è richiesto. Non è necessario chiamare -> setQuantityAndStockStatuses, anche se sembra non fare alcun male.
Robert Egginton,

9
Funziona alla grande per un prodotto. Tuttavia, quando leggi un file CSV con SKU 5k le prestazioni sono piuttosto scarse. Qualcuno ha lo stesso problema?
medina,

+1 per l'aggiornamento del tuo post alla versione magento 2.1.
ZFNerd,

+1 per le migliori pratiche (e aggiornamento della risposta)
Akif

Apprezzo molto il metodo aggiornato! Magento sta migliorando per tutti noi grazie ai membri della community come te che fanno post come questo! Strada da percorrere
JustinP

16

Se si utilizza la soluzione @ giel-berkers, potrebbe essere necessario impostare anche isInStock, poiché non verrà impostato automaticamente. Quindi, il seguente codice mi è stato utile:

public function __construct(
    \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
)
{
    $this->stockRegistry = $stockRegistry;
    parent::__construct();
}

public function yourMethod() {
    $sku = 'ABC123';
    $qty = 10;
    $stockItem = $this->stockRegistry->getStockItemBySku($sku);
    $stockItem->setQty($qty);
    $stockItem->setIsInStock((bool)$qty); // this line
    $this->stockRegistry->updateStockItemBySku($sku, $stockItem);
}

come posso usare questa risposta per aggiornare il qty store saggio in magento 2?
Mujahidh,

@Mujahidh puoi provare a passare scopeId come secondo parametro al getStockItemBySku()metodo
spiil

1
grazie, qty si sta aggiornando ma non è un punto di vista del negozio, per entrambi i negozi aggiornano la stessa quantità.
Mujahidh,

8

Una cosa che manca alle altre risposte è che, se tu setQty($qty), applicherà il valore esatto che fornisci. Ma se fosse stata effettuata una vendita per quel prodotto un momento prima del salvataggio, la quantità originale avrebbe potuto essere modificata. Quindi quello che vuoi davvero fare è dire a Magento la differenza che vuoi applicare alla quantità.

Fortunatamente, Magento 2 fornisce un bel meccanismo per questo. Dai un'occhiata a Magento\CatalogInventory\Model\ResourceModel\Stock\Item:

protected function _prepareDataForTable(\Magento\Framework\DataObject $object, $table)
{
    $data = parent::_prepareDataForTable($object, $table);
    $ifNullSql = $this->getConnection()->getIfNullSql('qty');
    if (!$object->isObjectNew() && $object->getQtyCorrection()) {
        if ($object->getQty() === null) {
            $data['qty'] = null;
        } elseif ($object->getQtyCorrection() < 0) {
            $data['qty'] = new \Zend_Db_Expr($ifNullSql . '-' . abs($object->getQtyCorrection()));
        } else {
            $data['qty'] = new \Zend_Db_Expr($ifNullSql . '+' . $object->getQtyCorrection());
        }
    }
    return $data;
}

Qui vediamo che se imposti il qty_correctionvalore, applicherà la differenza in modo incrementale invece di applicare un importo esatto.

Quindi il mio suggerimento per un salvataggio più sicuro è questo:

/**
 * @var \Magento\CatalogInventory\Api\StockRegistryInterface
 */
protected $stockRegistry;

public function __construct(StockRegistryInterface $stockRegistry)
{
    $this->stockRegistry = $stockRegistry;
}

/**
* Set the quantity in stock for a product
*
*/
public function applyNewQty($sku, $newQty)
{
    $stockItem = $this->stockRegistry->getStockItemBySku($sku);
    $origQty = $stockItem->getQty();
    $difference = $newQty - $origQty;
    $stockItem->setQtyCorrection($difference);
    $this->stockRegistry->updateStockItemBySku($sku, $stockItem);

    // note that at this point, $stockItem->getQty() is incorrect, so you'll need to reload if you need that value
}

7

Ho lottato con questo stesso problema. Durante il debug ho scoperto che i dati del prodotto hanno un array Quantity_and_stock_status, quindi ho provato a impostarlo con:

$product->setQuantityAndStockStatus(['qty' => $quantity, 'is_in_stock' => 1]);

e ha iniziato a funzionare per me. Sto ancora impostando anche $ product-> setStockData se modifichi un prodotto e controlli l'elemento sui campi, vedrai che ha entrambi, uno è nella scheda generale, l'altro nei campi avanzati dell'inventario. Non ho studiato a fondo perché ce ne sono 2.


ordinata e semplice, ottima soluzione !!! funziona per me +1
Manthan Dave,

Soluzione preferita, poiché funziona e richiede molto meno editing rispetto agli altri +1
leedch

Quando il prodotto è disabilitato, la quantità non si aggiorna; altrimenti in abilita lo stato funziona correttamente. Potete aiutarmi per questo. Il mio sito è in 2.1.9
Anil,

2
$objectManager = $bootstrap->getObjectManager();
$stockRegistry = $objectManager->create('Magento\CatalogInventory\Api\StockRegistryInterface');

$stockItem = $stockRegistry->getStockItemBySku($sku);
$stockItem->setQty($qty);
$stockItem->setIsInStock((bool)$qty);
$stockRegistry->updateStockItemBySku($sku, $stockItem);

1

Di seguito il codice funziona bene per me per aggiornare la quantità di prodotto,

public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory
) {
    $this->productFactory = $productFactory;
}

public function updateQty(){
    $sku = '24-mb01';
    $product = $this->productFactory->create();
    $productId = $product->getIdBySku($sku);
    if($productId){
        $product->load($productId);
    }

    $product->setStockData(
        array(
            'use_config_manage_stock' => 0,
            'manage_stock' => 1,
            'is_in_stock' => 1,
            'qty' => 10
        )
    );

    try {
        $product->save(); 
        echo $sku.' updated. '; 
    } catch (Exception $e) {
        echo $e->getException();
    }
}

Quando lo stato del prodotto è disabilitato, la quantità non si aggiorna nel mio caso. Potete aiutarmi per risolverlo.
Anil,

0

Prova a impostare StoreId su $ product prima di tutto e magari sostituiscilo:

$product->setStockData(...) per $product->setData('stock_data', '...') // A Paranoid Recommendation

A proposito, se si guarda il ActionController Salva nel backend M2 utilizza un filtro per preparare stock_data è possibile trovare quel filtro in:

Magento \ Catalog \ Controller \ Adminhtml \ prodotto \ inizializzazione \ StockDataFilter


Apprezzo la risposta, ma questa opzione non ha funzionato. Grazie per l'aiuto.
Stephen Malenshek,

0

Prova questo, risparmiando il prodotto in amministrazione, hanno salvato i dati di inventario utilizzando evento catalog_product_save_after in Magento_CatalogInventoryosservatore modulo

Magento \ CatalogInventory \ Observer \ SaveInventoryDataObserver


0

Ho avuto lo stesso problema con Magento 2.0.9 e nel mio caso funziona il codice seguente

$productStock = $this->_productRepository->getById($item->getMageproductId());
$productStock->setQuantityAndStockStatus(['qty' => 12, 'is_in_stock' => 1]);
$res = $productStock->save();

0

Magento2 presenta anche la funzionalità Multi stock in modo da poter aggiornare su una particolare fonte stock è possibile seguire questa soluzione

https://magento.stackexchange.com/questions/272296/how-to-set-qty-to-product-on-msi-magento-2-3
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.