How to Get Shipment item collection by order item id Magento 2?

You can retrieve partial shipment items collection by Order item id using Magento 2 with the search criteria Builder interface.

This is the rare condition where you need to fetch the list of shipment items from the Order item id.

This situation will be needed when the order item id has multiple quantities placed and partial shipment for a separate quantity of each item.

Let’s take an example You have placed an order with SKU “24-MB01” product with 5 quantities and you are doing a partial shipment for SKU 5 times. (1 quantity at a time in each shipment)

Shipment items entry generated in the sales_shipment_item table.

When you check the shipment items in the sales_shipment_item table, You can see 5 different entries for each partial shipment.

API Interface used to fetch shipment items:
Magento\Sales\Api\ShipmentItemRepositoryInterface

Now you can get the collection of each shipment item using the below code snippet,

<?php
namespace Jesadiya\ShipmentItems\Model;

use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Sales\Api\Data\ShipmentItemInterface;
use Magento\Sales\Api\ShipmentItemRepositoryInterface;

class PartialShipment
{
   /**
     * @var SearchCriteriaBuilder
     */
    protected $searchCriteriaBuilder;

    /**
     * @var ShipmentItemRepositoryInterface
     */
    protected $shipmentItem;

    /**
     * @var LoggerInterface
     */
    protected $logger;

    public function __construct(
        SearchCriteriaBuilder $searchCriteriaBuilder,
        ShipmentItemRepositoryInterface $shipmentItem,
        LoggerInterface $logger
    ) {
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->shipmentItem = $shipmentItem;
        $this->logger = $logger;
    }

    /**
     * Get Shipment Item Repository collection
     *
     * @param int $id
     * @return ShipmentItemInterface[]|null
     */
    public function getShipmentItem(int $orderItemId): ?array
    {
        $searchCriteria = $this->searchCriteriaBuilder->addFilter('order_item_id', $orderItemId)->create();

        $shipmentItems = null;
        try {
            $shipment = $this->shipmentItem->getList($searchCriteria);
            if ($shipment->getTotalCount()) {
                $shipmentItems = $shipment->getItems();
            }
        } catch (Exception $exception)  {
            $this->logger->critical($exception->getMessage());
        }

        return $shipmentItems;
    }
}

Call from a template or PHP class,
Here Don’t confuse  Order Item id with Order Id. Take Order_item_id only.

$orderItemId = "1"; //Order item id.
$shipmentItems = $this->getShipmentItem($orderItemId);
foreach ($shipmentItems as $shipment) {
    $qty = (int)$shipment->getQty();
    $price = (float)$shipment->getPrice();
}

Iterate over a $shipmentItem to get the list of available shipment items for a specific order item id.