shopify-admin-fulfillment-location-routing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePurpose
用途
Queries open fulfillment orders assigned to a source location and moves them to a destination location. Used when a warehouse is at capacity, a location is closing, or regional routing rules change. Replaces manual reassignment in Shopify Admin — this skill handles bulk location transfers for any number of open orders in a single workflow.
查询分配给源地址的未完成履约订单,并将其转移到目标地址。适用于仓库满负荷、站点关闭或区域路由规则变更的场景。可替代Shopify Admin中的手动重新分配操作——该skill可在单个工作流中完成任意数量未结订单的批量地址转移。
Prerequisites
前置要求
- Authenticated Shopify CLI session:
shopify store auth --store <domain> --scopes read_orders,write_fulfillments - API scopes: ,
read_orderswrite_fulfillments - Both source and destination locations must be active fulfillment locations in Shopify
- 已完成身份验证的Shopify CLI会话:
shopify store auth --store <domain> --scopes read_orders,write_fulfillments - API权限范围:、
read_orderswrite_fulfillments - 源地址和目标地址都必须是Shopify中处于激活状态的履约地点
Parameters
参数
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| source_location_id | string | yes | — | GID of the location to move orders FROM |
| destination_location_id | string | yes | — | GID of the location to move orders TO |
| order_filter | string | no | — | Optional order name filter (e.g., "#1001,#1002") |
| dry_run | bool | no | true | Preview moves without executing mutations |
| format | string | no | human | Output format: |
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| store | string | 是 | — | 店铺域名(例如:mystore.myshopify.com) |
| source_location_id | string | 是 | — | 要转出订单的地址的GID |
| destination_location_id | string | 是 | — | 要转入订单的地址的GID |
| order_filter | string | 否 | — | 可选的订单名称筛选条件(例如:"#1001,#1002") |
| dry_run | bool | 否 | true | 试运行模式,仅预览转移操作而不实际执行变更 |
| format | string | 否 | human | 输出格式: |
Safety
安全提示
⚠️reassigns fulfillment responsibility. This affects which warehouse picks and ships the order. Verify destination location has sufficient stock for all products before moving. Run withfulfillmentOrderMoveto confirm the order list and destination before committing.dry_run: true
⚠️会重新分配履约责任,这将决定由哪个仓库拣货并发货。转移前请确认目标地址有足够的库存支撑所有商品。正式执行前请先设置fulfillmentOrderMove运行,确认订单列表和目标地址无误。dry_run: true
Workflow Steps
工作流步骤
-
OPERATION:— query Inputs:
fulfillmentOrders,assignedLocationId: <source_location_id>,status: OPEN, pagination cursor Expected output: List of open fulfillment orders; paginate untilfirst: 250hasNextPage: false -
OPERATION:— mutation Inputs:
fulfillmentOrderMove,id: <fulfillment_order_id>Expected output:newLocationId: <destination_location_id>,movedFulfillmentOrder { id, assignedLocation { name } }userErrors
-
操作:— 查询 输入:
fulfillmentOrders、assignedLocationId: <source_location_id>、status: OPEN、分页游标 预期输出: 未结履约订单列表;分页查询直到first: 250hasNextPage: false -
操作:— mutation 输入:
fulfillmentOrderMove、id: <fulfillment_order_id>预期输出:newLocationId: <destination_location_id>、movedFulfillmentOrder { id, assignedLocation { name } }userErrors
GraphQL Operations
GraphQL操作
graphql
undefinedgraphql
undefinedfulfillmentOrders:query — validated against api_version 2025-01
fulfillmentOrders:query — validated against api_version 2025-01
query FulfillmentOrdersByLocation($locationId: ID!, $after: String) {
fulfillmentOrders(
assignedLocationId: $locationId
first: 250
after: $after
query: "status:open"
) {
edges {
node {
id
status
order {
id
name
}
assignedLocation {
location {
id
name
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
```graphqlquery FulfillmentOrdersByLocation($locationId: ID!, $after: String) {
fulfillmentOrders(
assignedLocationId: $locationId
first: 250
after: $after
query: "status:open"
) {
edges {
node {
id
status
order {
id
name
}
assignedLocation {
location {
id
name
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
```graphqlfulfillmentOrderMove:mutation — validated against api_version 2025-01
fulfillmentOrderMove:mutation — validated against api_version 2025-01
mutation FulfillmentOrderMove($id: ID!, $newLocationId: ID!) {
fulfillmentOrderMove(id: $id, newLocationId: $newLocationId) {
movedFulfillmentOrder {
id
assignedLocation {
location {
id
name
}
}
}
originalFulfillmentOrder {
id
status
}
remainingFulfillmentOrder {
id
status
}
userErrors {
field
message
}
}
}
undefinedmutation FulfillmentOrderMove($id: ID!, $newLocationId: ID!) {
fulfillmentOrderMove(id: $id, newLocationId: $newLocationId) {
movedFulfillmentOrder {
id
assignedLocation {
location {
id
name
}
}
}
originalFulfillmentOrder {
id
status
}
remainingFulfillmentOrder {
id
status
}
userErrors {
field
message
}
}
}
undefinedSession Tracking
会话追踪
Claude MUST emit the following output at each stage. This is mandatory.
On start, emit:
╔══════════════════════════════════════════════╗
║ SKILL: Fulfillment Location Routing ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝After each step, emit:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>If , prefix every mutation step with and do not execute it.
dry_run: true[DRY RUN]On completion, emit:
For (default):
format: human══════════════════════════════════════════════
OUTCOME SUMMARY
Orders at source location: <n>
Orders moved: <n>
Errors: <n>
Output: routing_log_<date>.csv
══════════════════════════════════════════════For , emit:
format: jsonjson
{
"skill": "fulfillment-location-routing",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": true,
"outcome": {
"orders_at_source": 0,
"orders_moved": 0,
"errors": 0,
"output_file": "routing_log_<date>.csv"
}
}Claude在每个阶段必须输出以下内容,这是强制要求。
启动时输出:
╔══════════════════════════════════════════════╗
║ SKILL: Fulfillment Location Routing ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝每步执行完成后输出:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <关键输入的简要说明>
→ Result: <数量或执行结果>如果,每个mutation步骤前要加前缀,且不实际执行操作。
dry_run: true[DRY RUN]执行完成后输出:
format: human══════════════════════════════════════════════
OUTCOME SUMMARY
Orders at source location: <n>
Orders moved: <n>
Errors: <n>
Output: routing_log_<date>.csv
══════════════════════════════════════════════format: jsonjson
{
"skill": "fulfillment-location-routing",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": true,
"outcome": {
"orders_at_source": 0,
"orders_moved": 0,
"errors": 0,
"output_file": "routing_log_<date>.csv"
}
}Output Format
输出格式
CSV file with columns:
, , , ,
routing_log_<YYYY-MM-DD>.csvorder_namefulfillment_order_idsource_locationdestination_locationstatusCSV文件,包含以下列:
、、、、
routing_log_<YYYY-MM-DD>.csvorder_namefulfillment_order_idsource_locationdestination_locationstatusError Handling
错误处理
| Error | Cause | Recovery |
|---|---|---|
| API rate limit exceeded | Wait 2 seconds, retry up to 3 times |
| Order already fulfilled or location inactive | Log error, skip order, continue |
| Destination location not stocked | Insufficient inventory at destination | Log warning per SKU, continue move |
| No open orders at source | Source has no pending work | Exit with summary: 0 orders found |
| 错误 | 原因 | 解决方法 |
|---|---|---|
| API请求超出频率限制 | 等待2秒,最多重试3次 |
fulfillmentOrderMove返回 | 订单已完成履约或地址未激活 | 记录错误,跳过该订单,继续执行后续操作 |
| 目标地址无库存 | 目标地址库存不足 | 按SKU记录警告,继续执行转移操作 |
| 源地址无未结订单 | 源地址没有待处理的订单 | 输出摘要后退出:共找到0个订单 |
Best Practices
最佳实践
- Always run with first — moving a fulfillment order does not move inventory; verify destination stock levels separately using the
dry_run: trueskill.multi-location-inventory-audit - Use to move specific high-priority orders first rather than the entire queue.
order_filter - For location closures, run this skill before the location is deactivated in Shopify Admin.
- 始终先以模式运行——转移履约订单不会转移库存;请使用
dry_run: trueskill单独确认目标地址的库存水平。multi-location-inventory-audit - 优先使用转移特定高优先级订单,而不是一次性转移整个队列。
order_filter - 如果要关闭站点,请在Shopify Admin中停用该站点前先运行本skill。