Documentation (and the inventory interface for individual products in admin) indicate that using a fulfillmentService for a product makes it impossible to track inventory of that same product in another location (like a physical store).
This is confusing to me because it seems natural to want to have some stock on hand in a physical store.
My client wants to prioritise manual fulfillment from stock that he already has in his physical store (location 1)
When products are not in stock in that location, he wishes that those products be automatically ordered via the fulfillment service (location 2).
So is it possible to prioritise my locations as follows:
1st priority : physical shop (location 1 - manual fulfillment)
2nd priority: supplier’s warehouse (location 2 - fully automatic fulfillmentService)
The fulfillmentService needs to automatically do the following (the usual stuff):
- fill the fulfillmentorders assigned to it automatically, immediately upon purchase.
- mark the fulfillmentorder as “fulfilled”
- recognise when the customer changes the location for a particular product line in an order and fulfill or cancel fulfillment via the fulfillmentService accordingly.
The following lines from Shopify Docs suggest that my envisaged fulfillmentService solution will conflict with managing inventories in two locations :
“If you use a third-party fulfillment service for a product, then you can't also stock the product in the locations that you manage.” (“If you use a third-party fulfillment service for a product, then you can't also stock the product i...)
“A fulfillment service always has its own location, and variants managed by the fulfillment service should always be fulfilled from that location.” (“A fulfillment service always has its own location, and variants managed by the fulfillment service ...)
... But, Confusingly, there is this mutation in Graphql reference documentation :
This suggests that FulfillmentServices CAN work with products also stocked in multiple locations!
Could anyone please clarify this and recommend a pathway to a solution?
Solved! Go to the solution
I can confirm that the behaviour you describe is currently expected. When the multi-location inventory features were implemented, it was designed so that when fulfillmentServices manage the inventory for a particular product, the inventory for that product can't also be managed by another location. I can't comment on exactly why it was designed this way, but our product teams design features which represent typical workflows used by merchants on the platform, so it's possible the current functionality is just more closely aligned with use-cases we typically see.
With regards to your question about the FulfillmentOrderMove mutation, this mutation is available because the fulfillmentOrder object is available to any app, not just apps that use FulfillmentService.
Since it seems like FulfillmentService won't work for this use-case, you can likely still achieve your desired functionality by creating a regular location to represent the warehouse. After setting the fulfillment priority in the admin, you can watch for orders coming in with FulfillmentOrders assigned to the new location, and action those accordingly. If you use webhooks, this will allow you to action fulfillmentOrders automatically as well. Just make sure your app has the
This is an accepted solution.
Thanks very much for your reply _JB.
Yes, I eventually realised that the fulfillmentOrder objects are accessible with out running a fulfillmentService, although the assigned location for these fulfillment orders doesn't appear in the webhook information for order/payment.
Instead, I have to take the orderId from the webhook payload and run a search of most recent fulfillmentOrders by orderId AND locationId.
If you're wondering why I don't use the query by locationId, it's because I found it not to work. The API returns fulfillmentOrders from all locations regardless.
I fulfill the relevent fulfillmentOrderLine items using fulfillmentCreate and I use fulfillmentOrderMove to split fufillmentOrders and send them to our local store so that stock on hand is used as much as possible.
The split basically leaves behind all fulfillmentOrderLine items that do NOT have a valid inventoryLevelId in the destination location. It is important to check this before doing the split, because if there is a line item in the fulfillmentOrder that we don't want to move, that DOES have a active inventoryLevelId in the destination location, this item WILL move, and this tends to create negative inventory levels which is a mess.
Unfortunately it's extremely confusing with all the documentation pointing towards fulfillmentService and with some of the more useful fulfillmentOrder calls, specifically fulfillmentCreate, no longer being displayed visibly in the GraphQL reference docs, although it does come up in the search.
Hope this will help someone out there!