What would be the latest best practice to load Order using increment ID (instead of Order ID) using OrderRepository
-
2Not 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
-
1Too late, now that it is already closed. But I nominated the question to be reopened. – Fabian Schmengler Oct 12 '16 at 20:58
2 Answers
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 = reset($orderList);
// Your logic here
$order = $this->orderRepository->save($order);
- 1,935
- 16
- 39
- 1,026
- 10
- 21
-
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. – Jacques Feb 14 '17 at 08: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$paymentPlease check my problem here http://magento.stackexchange.com/questions/158935/magento-2-unable-to-set-payment-transaction-id-after-successful-payment-process
– Ashish Raj Feb 14 '17 at 09:20 -
1I had a bug with the accepted answer. This solved it. Thanks for the good solution – CompactCode Aug 31 '18 at 02:44
-
In Magento 2.3.x I need to get the order this way:
$order = $orderList['000000001'];– phse Sep 19 '19 at 16:06 -
1@ph.dev
$order = end($orderList)would be better since'000000001'here is order ID which you probably don't know. – Krzysztof Wołowski Nov 18 '19 at 11:59 -
@KrzysztofWołowski Upvote and you are right.
$order = reset($orderList)could be used too, and maybe more semantic. – Key Shang Sep 17 '20 at 09:54
As far as I know, we should use \Magento\Sales\Api\Data\OrderInterface.
/** @var \Magento\Sales\Api\Data\OrderInterfaceFactory $order **/
protected $orderFactory;
public function __construct(
\Magento\Sales\Api\Data\OrderInterfaceFactory $orderFactory,
......
) {
$this->orderFactory = $orderFactory;
}
Load order object by increment id:
$this->orderFactory->create()->loadByIncrementId('00001952-42');
[EDIT] should try with service contracts. Try Jacco's answer.
- 32,054
- 11
- 88
- 155
-
3Please 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. – Jacques Jan 18 '17 at 11:18
-
@JaccoAmersfoort Thanks your input. However, I also took a look your answer below. I need to check and confirm. – Khoa TruongDinh Jan 18 '17 at 12:46
-
-
@AshishRaj you can show me your controller? You should open new question. I will take a look. – Khoa TruongDinh Feb 14 '17 at 09:27
-
yes but its little big in lines... so will not come inside the comment box... but i m doing the same thing .. loading as above in constructor and using as like
$order = $this->order->loadByIncrementId('00001952-42');and then doing$payment = $order->getPayment();But getting nothing in$paymentPlease check my problem here http://magento.stackexchange.com/questions/158935/magento-2-unable-to-set-payment-transaction-id-after-successful-payment-process – Ashish Raj Feb 14 '17 at 09:32 -
-
1This 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
-
@Ian I agreed with you that we should use service contracts. I also voted up Jacco's answer. – Khoa TruongDinh Jul 19 '17 at 01:15
-
2version 2.2.2, use
\Magento\Sales\Api\OrderRepositoryInterfaceand itsget()method – LucScu Mar 06 '18 at 14:41 -
2
-
1@ThiagoLima yes, I agreed with you! I also voted the service contracts answer. – Khoa TruongDinh Jul 03 '18 at 01:15