16

What would be the latest best practice to load Order using increment ID (instead of Order ID) using OrderRepository

  • 2
    Not a duplicate - the linked answer is about retrieving the order by order id, not by increment id – Fabian Schmengler Oct 12 '16 at 18:45
  • ekk! Is there a way to undo the mark as duplicate? I meant to mark the answer below as the answer to the solution. – frostshoxx Oct 12 '16 at 20:53
  • 1
    Too late, now that it is already closed. But I nominated the question to be reopened. – Fabian Schmengler Oct 12 '16 at 20:58
31

Magento 2 uses Service Contracts for retrieving and saving objects. In Magento this layer is formed by Repositories, which are managers with get() and save() methods. This keeps user code away from Model calls. Don't call model methods (like load() or save() or loadByIncrementId()) directly, they are being deprecated as custom code should use the Service Contracts. Also, don't use the API from within Magento like Khoa is suggesting, it does not make sense. The API is for connecting Magento with other systems.

Inject OrderRepository and SearchCriteriaBuilder in your constructor:

private $orderRepository;
private $searchCriteriaBuilder;

public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Sales\Model\OrderRepository $orderRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
){
$this->orderRepository = $orderRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
parent::__construct($context);
}

And in your function:

$searchCriteria = $this->searchCriteriaBuilder
    ->addFilter('increment_id', '000000001', 'eq')->create();
$orderList = $this->orderRepository->getList($searchCriteria)->getItems();

// $orderList is now an array of Orders with this incrementId, which is just one order obviously

/** @var \Magento\Sales\Model\Order $order */
$order = $orderList[0];
// Your logic here
$order = $this->orderRepository->save($order);

Official Magento PHP Developer guide on magento.com

Code by Mulderea on github

  • I am getting error like : Cannot use object of type Magento\Sales\Model\ResourceModel\Order\Collection as array at $order = $orderList[0]; – Ashish Raj Feb 13 '17 at 14:26
  • That's odd, I got an array. Which version are you on? But with a collection you can just replace $order = $orderList[0] with $order = $orderList->getFirstItem() to get the first (and only) item from the collection. – Jacco Amersfoort Feb 14 '17 at 8:42
  • I am in version 2.1.3. and I need to load order object for load payment object .. I have done $order = $orderList->getFirstItem(); $payment = $order->getPayment(); But getting nothing in $payment Please check my problem here magento.stackexchange.com/questions/158935/… – Ashish Raj Feb 14 '17 at 9:20
  • 1
    I had a bug with the accepted answer. This solved it. Thanks for the good solution – CompactCode Aug 31 '18 at 2:44
20

As far as I know, we should use \Magento\Sales\Api\Data\OrderInterface.

/** @var \Magento\Sales\Api\Data\OrderInterface $order **/

protected $order;

public function __construct(
    \Magento\Sales\Api\Data\OrderInterface $order,
    ......
) {
    $this->order = $order;

}

Load order object by increment id:

$this->order->loadByIncrementId('00001952-42');

[EDIT] should try with service contracts. Try Jacco's answer.

  • 3
    Please don't use underscores in your variable names. PHP has had access modifiers since PHP 5, which is now 12 years old. You should use modern programming practices, especially in answers here. – Jacco Amersfoort Jan 18 '17 at 11:18
  • 1
    This method should not be used even if it "works". One: the di injection is a shared object unless it is specified to not be; anytime you insert OrderInterface in you'll be using the exact same object. If you really want to go this route use OrderInterfaceFactory and then call create(). Second, you should be using the service contracts as in Jacco's answer. – Ian Jul 18 '17 at 22:03
  • 2
    version 2.2.2, use \Magento\Sales\Api\OrderRepositoryInterface and its get() method – LucScu Mar 6 '18 at 14:41
  • 2
    service contracts must be taken in consideration. – Thiago Lima Jul 2 '18 at 10:25
  • 1
    @ThiagoLima yes, I agreed with you! I also voted the service contracts answer. – Khoa TruongDinh Jul 3 '18 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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