用途
该技能用于在两个 Shopify 地点之间转移指定数量的库存,方式是成对的库存调整:扣减源地点、增加目标地点。它适用于仓库间库存再平衡、促销前提前布货,或地点变更后重新分配库存。其定位是替代在 Shopify Admin 中进行的手动库存转移。
前提条件
- 已认证的 Shopify CLI 会话:shopify store auth --store <domain> --scopes read_products,write_inventory,read_inventory
- API 权限:read_products、read_inventory、write_inventory
- 源地点与目标地点均须为有效的活跃 Shopify 地点
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| store | string | 是 | — | 商店域名(例如 mystore.myshopify.com) |
| source_location_id | string | 是 | — | 要移出库存的地点 GID |
| destination_location_id | string | 是 | — | 要移入库存的地点 GID |
| transfers | array | 是 | — | 要转移的 {sku, quantity} 对象列表 |
| dry_run | bool | 否 | true | 预览调整而不执行变更 |
| format | string | 否 | human | 输出格式:human 或 json |
安全提示
inventoryAdjustQuantities 会直接修改库存水平。如果数量超过可用库存,源地点有可能被扣减为负数——该技能会发出警告,但 Shopify 不会阻止负数调整。建议先以 dry_run: true 运行,在执行前核验源地点的可用数量。该操作不会在 Shopify 中创建转移单记录,它是一次直接调整。
工作流程步骤
- OPERATION: locations — 查询。输入:first: 50。预期输出:所有地点的 id、name,用于验证源地点与目标地点 ID 是否存在。
- OPERATION: inventoryItems — 查询。输入:按 SKU 批量查询,以获取每个转移 SKU 的 inventoryItem.id。预期输出:库存项目及其在源地点的当前数量。
- 校验:对每个 SKU,确认源地点可用数量 >= 转移数量。若不满足则警告,但在 dry_run: false 时仍继续执行。
- OPERATION: inventoryAdjustQuantities — 变更。输入:每个 SKU 两项变更:{ inventoryItemId, locationId: source, delta: -quantity, reason: "correction" } 与 { inventoryItemId, locationId: destination, delta: +quantity, reason: "correction" }。预期输出:inventoryAdjustmentGroup { changes { delta, location } }、userErrors。
GraphQL 操作
locations:query — 已针对 api_version 2025-01 验证
query ActiveLocations { locations(first: 50, includeInactive: false) { edges { node { id name isActive fulfillsOnlineOrders } } } }
inventoryItems:query — 已针对 api_version 2025-01 验证
query InventoryLevelsAtLocation($ids: [ID!]!) { nodes(ids: $ids) { ... on InventoryItem { id sku inventoryLevels(first: 20) { edges { node { location { id name } quantities(names: ["available", "on_hand"]) { name quantity } } } } } } }
inventoryAdjustQuantities:mutation — 已针对 api_version 2025-01 验证
mutation InventoryAdjustQuantities($input: InventoryAdjustQuantitiesInput!) { inventoryAdjustQuantities(input: $input) { inventoryAdjustmentGroup { createdAt reason changes { delta quantityAfterChange item { id sku } location { id name } } } userErrors { field message } } }
会话追踪
在每个阶段必须输出以下内容:
启动时输出:
╔══════════════════════════════════════════════╗ ║ SKILL: Inventory Transfer Between Locations ║ ║ Store: <store domain> ║ ║ Started: <YYYY-MM-DD HH:MM UTC> ║ ╚══════════════════════════════════════════════╝
每一步之后输出:
[N/TOTAL] <QUERY|MUTATION> <OperationName> → Params: <brief summary of key inputs> → Result: <count or outcome>
如果 dry_run: true,则在每个变更步骤前加上 [DRY RUN],且不执行该步骤。
完成时输出:
对于 format: human(默认):
══════════════════════════════════════════════ OUTCOME SUMMARY SKUs transferred: <n> Total units moved: <n> Warnings (low stock): <n> Errors: <n> Output: inventory_transfer_<date>.csv ══════════════════════════════════════════════
对于 format: json,输出:
{ "skill": "inventory-transfer-between-locations", "store": "<domain>", "started_at": "<ISO8601>", "dry_run": true, "source_location": "<name>", "destination_location": "<name>", "outcome": { "skus_transferred": 0, "units_moved": 0, "warnings": 0, "errors": 0, "output_file": "inventory_transfer_<date>.csv" } }
输出格式
CSV 文件 inventory_transfer_<YYYY-MM-DD>.csv,包含列:sku, product_title, inventory_item_id, source_location, destination_location, quantity_transferred, source_qty_before, source_qty_after, destination_qty_before, destination_qty_after
错误处理
| 错误 | 原因 | 恢复方式 |
|---|---|---|
| THROTTLED | 超过 API 速率限制 | 等待 2 秒,最多重试 3 次 |
| SKU not found | SKU 不在目录中 | 记录警告,跳过该 SKU 的转移 |
| adjustment 上的 userErrors | 地点未备有该商品 | 记录错误,跳过该 SKU,继续执行 |
| 数量将变为负数 | 转移数量超过可用数量 | 记录警告;若 dry_run: false 则中止该 SKU |
最佳实践
- 始终先以 dry_run: true 运行——该技能会核验可用数量,并展示将要发生的具体变化。
- 这会创建原始库存调整,而非转移单。出于审计目的,可在 reason 字段中添加备注,并单独记录转移。
- 对于大批量转移(50+ SKU),建议在非高峰时段运行,以避免干扰店面实时库存读取。
- 可搭配 multi-location-inventory-audit 使用,在决定转移数量前识别哪些地点有超额库存。