M2 REST API: Creating shipment with products from MSI source
-
15-04-2021 - |
Question
I am using MSI.
When trying to create a shipment with a source code, the shipment uses the "default source" instead of the one I'm providing.
My Request: [POST] /rest/default/V1/order/5/ship
{
"items": [
{
"order_item_id": 14,
"qty": 1
}
],
"extension_attributes" : {
"source_code" : "3"
}
}
I've used this documentation to create my request: https://devdocs.magento.com/swagger/index_23.html#/salesShipmentRepositoryV1/salesShipmentRepositoryV1SavePost
The source "3" has sufficient stock, so this shouldn't be the issue
When "default source" has stock, the shipment is created uses stock from "default source"
When "default source" has no stock, I get the following:
Shipment Document Validation Error(s):\nThe order does not allow a shipment to be created.\nYou can't create a shipment without products.
So it definitely tries to use the default source, which is what I don't want.
My question: How can I tell Magento to use my source code? Do I need to provide the source code in a different way?
Solution 2
The issue lies in the JSON structure. You should use arguments.extension_attributes.source_code
, instead of extension_attributes.source_code
as shown below:
{
"items": [
{
"order_item_id": 14,
"qty": 1
}
],
"arguments": {
"extension_attributes" : {
"source_code" : "3"
}
}
}
Then, it will create the shipment (using the specified source) and return the shipment_id
as the response.
I have tested this in Magento 2.3.2-p2
OTHER TIPS
I think you pass the wrong source code.
"source_code" : "3"
If you open the following class:
vendor/magento/module-inventory-shipping/Plugin/Sales/Shipment/AssignSourceCodeToShipmentPlugin.php
Following code snippet resolve correct source:
if (empty($sourceCode)) {
$websiteId = $order->getStore()->getWebsiteId();
$stockId = $this->stockByWebsiteIdResolver->execute((int)$websiteId)->getStockId();
$sources = $this->getSourcesAssignedToStockOrderedByPriority->execute((int)$stockId);
//TODO: need ro rebuild this logic | create separate service
if (!empty($sources) && count($sources) == 1) {
$sourceCode = $sources[0]->getSourceCode();
} else {
$sourceCode = $this->defaultSourceProvider->getCode();
}
}
So following code returns nothing and tried from the default source.
$sources = $this->getSourcesAssignedToStockOrderedByPriority->execute((int)$stockId);
This post is in top searches for the following error:
Shipment Document Validation Error(s):
The order does not allow a shipment to be created.
You can't create a shipment without products.
So I'll add my experience which in my case was because, Magento 2 has a designed flaw (in my humble opinion).
I needed to be able to push partial-shipping
and I was going crazy by trying to push the simple product Id (logically thinking - I don't see how there can be any other option).
But, every time I was getting the same upper error.
I was creating the shipment by submitting the data to following url (POST) (magento wiki):
https://www.{domain.co.uk}/index.php/rest/{store_code}/V1/order/{order_id}/ship
This was the submitted data:
{
"appendComment": 1,
"comment": {
"comment": "Shipment created via API",
"is_visible_on_front": 1
},
"items": [
{
"order_item_id": 369,
"qty": 1
}
],
"notify": 1,
"tracks": [
{
"track_number": "54149997365",
"title": "Shipment 1300000010",
"carrier_code": "DHL"
}
]
}
This line was the one creating all the trouble:
"order_item_id": 369,
369
- is the Item_ID for simple product
while Magento is waiting the configurable
Item_id which in my case was:
368
So, magento is expecting the configurable
order item id and NOT the simple product
item id.
I just have one question: why Magento? WHYY??
Never-mind the fact you force in URL to use the internal order_id
and not the incremental_id
but using the configurable instead of simple product
:( ?!?
P.S. Another reason for the same error is: if the shipment already exists.