Magento 2: Lập trình cập nhật hàng tồn kho


11

Trong đoạn mã sau, tôi có thể lưu trữ tất cả thông tin với việc loại trừ dữ liệu chứng khoán. Có điều gì đó đã thay đổi trong 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";
}

Câu trả lời:


32

Điều này làm việc cho tôi:

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

Chỉnh sửa :

Đây không còn là cách chính xác để xử lý việc này, vì $product->save()bị phản đối kể từ Magento 2.1. Cách chính xác để làm điều này là bằng cách sử dụng StockRegistryInterface:

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

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

Với đoạn mã trên, bạn có thể sử dụng như sau:

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

Sử dụng người quản lý càng nhiều càng tốt. Giữ các mô-đun của bạn tách rời nhau.

Đó là Magento Way ™


setStockData là những gì được yêu cầu. Không cần phải gọi -> setQuantityAndStockStatuses, mặc dù nó dường như không có hại.
Robert Egginton

9
Nó hoạt động tuyệt vời cho một sản phẩm. Tuy nhiên, khi bạn đọc tệp CSV có 5k SKU thì hiệu suất khá tệ. Có ai có cùng vấn đề không?
medina

+1 để cập nhật bài viết của bạn lên phiên bản magento 2.1.
ZFNerd

+1 cho các thực tiễn tốt nhất (và cập nhật câu trả lời)
Akif

Thực sự đánh giá cao Phương pháp cập nhật! Magento đang trở nên tốt hơn cho tất cả chúng ta vì các thành viên cộng đồng như bạn đang làm những bài đăng như thế này! Con đường để đi
JustinP

16

Nếu bạn đang sử dụng giải pháp @ giel-berkers, bạn cũng có thể cần phải đặt isInStock, vì nó sẽ không được đặt tự động. Vì vậy, đoạn mã sau rất hữu ích cho tôi:

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);
}

Làm thế nào tôi có thể sử dụng câu trả lời này để cập nhật qty store khôn ngoan trong magento 2?
Mujahidh

@Mujahidh bạn có thể thử truyền scopeId làm tham số thứ hai cho getStockItemBySku()phương thức
spiil 23/03/19

1
cảm ơn, qty đang cập nhật nhưng không lưu trữ thông minh, vì cả hai cửa hàng đều cập nhật cùng một qty.
Mujahidh

8

Một điều mà các câu trả lời khác bị bỏ lỡ là nếu bạn setQty($qty), nó sẽ áp dụng giá trị chính xác mà bạn cung cấp. Nhưng nếu việc bán hàng được thực hiện cho sản phẩm đó một lúc trước khi bạn tiết kiệm, số lượng ban đầu có thể đã thay đổi. Vì vậy, những gì bạn thực sự muốn làm là nói với Magento sự khác biệt bạn muốn áp dụng cho qty.

May mắn thay, Magento 2 cung cấp một cơ chế tốt cho việc này. Hãy xem 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;
}

Ở đây chúng tôi thấy rằng nếu bạn đặt qty_correctiongiá trị, nó sẽ áp dụng chênh lệch tăng dần thay vì áp dụng một số tiền chính xác.

Vì vậy, đề nghị của tôi cho một tiết kiệm qty an toàn hơn là:

/**
 * @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

Tôi vật lộn với vấn đề tương tự. Trong khi gỡ lỗi, tôi thấy rằng dữ liệu sản phẩm có mảng quant_and_stock_status, vì vậy tôi đã thử đặt nó với:

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

và nó bắt đầu làm việc cho tôi. Tôi vẫn đang thiết lập $ sản phẩm-> setStockData nếu bạn chỉnh sửa một sản phẩm và kiểm tra phần tử trên các trường bạn sẽ thấy nó có cả hai, một cái nằm trên tab chung, cái kia trên các trường hàng tồn kho nâng cao. Tôi chưa điều tra đầy đủ tại sao có 2 người trong số họ.


sắp xếp và đơn giản, giải pháp rất tốt !!! làm việc cho tôi +1
Manthan Dave

Giải pháp ưa thích, vì cách này hiệu quả và ít chỉnh sửa hơn các cách khác +1
leedch

Khi sản phẩm bị vô hiệu hóa thì số lượng không cập nhật; khác trong trạng thái cho phép làm việc đúng. Bạn có thể giúp tôi cho nó Trang web của tôi là trong 2.1.9
Anil

1

Mã bên dưới đang hoạt động tốt để tôi cập nhật sản phẩm qty,

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();
    }
}

Khi trạng thái sản phẩm bị vô hiệu hóa thì số lượng không cập nhật trong trường hợp của tôi. Bạn có thể giúp tôi giải quyết nó
Anil

1
$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);

0

Hãy thử đặt StoreId thành $ sản phẩm trước tất cả và có thể thay thế:

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

BTW Nếu bạn xem Save ActionContoder tại phần phụ trợ M2 sử dụng bộ lọc để chuẩn bị stock_data, bạn có thể tìm thấy bộ lọc đó trong:

Magento \ Catalog \ Trình điều khiển \ adminhtml \ Sản phẩm \ Khởi tạo \ StockDataFilter


Tôi đánh giá cao phản hồi, nhưng tùy chọn đó không hoạt động. Cảm ơn đã giúp đỡ.
Stephen Malenshek

0

Hãy thử điều này, trong khi lưu sản phẩm trong quản trị viên, họ đã lưu dữ liệu hàng tồn kho bằng cách sử dụng danh mục sự kiện_product_save_after trong trình Magento_CatalogInventoryquan sát mô-đun

Magento \ CatalogInventory \ Observer \ SaveInventoryDataObserver


0

Tôi gặp vấn đề tương tự với magento 2.0.9 và mã sau đang hoạt động trong trường hợp của tôi

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

0

Magento2 cũng đưa ra tính năng Multi stock để cập nhật trên nguồn chứng khoán cụ thể, bạn có thể làm theo giải pháp này

https://magento.stackexchange.com/questions/272296/how-to-set-qty-to-product-on-msi-magento-2-3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.