Inventory IMPEX ベストプラクティス
Inventory Impex API を使用すると、Omnichannel Inventory (OCI) の在庫入手可能性のインポートとエクスポートを管理できます。このドキュメントは、OCI サービスの使用を実装する際にいくつかのベストプラクティスに従えるようにサポートし、またサービス自体に関する情報を提供することを目的としています。
-
高パフォーマンスのインポートプロセスを常時使用してください。従来のインポートプロセスは使用できなくなり、廃止される予定です。新しい 方法ははるかに高パフォーマンスで、インポートの実行には最適な方法です。高パフォーマンスへの変更の詳細については、Inventory Impex ドキュメントの「インポートファイルのレイアウト - 高パフォーマンス」を参照してください。
-
ロケーショングラフの変更の進行中は、在庫データのインポートを実行しないでください。さもないと、グループとそのグループに含まれるロケーション間で在庫の不一致が発生する可能性があります。スケジュール済みのインポートを実行している場合は、ロケーショングラフの変更中にインポートが実行されていないこと、あるいはロケーショングラフの変更が完了するまでインポートが一時停止されていることを確認してください。これにより、ロケーションやグループ全体でシステム内の在庫を正確に把握できます。
-
小さなバッチデータを更新する場合は、完全なインポートを実行するのではなく、
batchInventoryUpdate
API 呼び出しの使用が推奨されています。バッチあたり 100 SKU という制限がありますが、これはファイル経由でデータをロードするよりも高速です。 -
batchInventoryUpdate
API 呼び出しを使用している際に、API への複数の呼び出しを通じて 1000 を超える SKU を更新していることが判明した場合は、この時点で切り替えて、在庫ファイルのインポートプロセスを使用してください。 -
最高のパフォーマンスを得るには、完全なデータインポートではなく、変更点のみを更新する 差分 データインポートを使用します。完全なデータのインポートは時間がかかるため、必要な場合以外は行わないでください。
-
データインポートのスケジュールは 非常に注意して 実行してください。完全なデータのインポートには、十分な時間を確保してください。インポートのスケジュールをあまりにも密に設定したために (たとえば間が 1 分ほどの場合)、困難な状況に直面した顧客もいます。このようなサービスの誤用からの復旧は困難であり、稼働計画や実装計画に問題が起きる可能性があります。
-
大量のインポートデータを処理する場合、データを複数のファイルに分割して個別に送信できます。ただし、OCI サービスとインフラストラクチャ内にはレートと同時実行に関する制限があります。このため、在庫インポートは、多数の小さなファイルではなく、より少ない数のファイルにグループ化して行うことが最善です。
- インポートファイル内の最上位のエントリは、コンマではなく改行で区切ります。ファイルの各エントリは単一の行であることが必要です。
- モードは常時
UPDATE
であるとみなされます。 - 各在庫レコードエントリのリクエストには、一意の べき等性 のある recordId があります。ベストプラクティスとして、この場合は UUID を使用します。レコード ID により、重複データのインポートが防止されます。
- インポートされる各在庫レコードには、
effectiveDate
エントリが必要です。 - インポートされる将来の各在庫レコードには、ゼロ以外の数量と
expectedDate
が必要です。 - システムでは、データに含まれているエントリの作成または更新のみが行われます。含まれていないエントリが削除されることはありません。ただし、含まれるエントリに空の値がある場合、その値は無視され、エラーとして報告されます。
- 初期の実装期間中に過剰販売が発生するのを避けるため、安全在庫レベルを定義することを推奨します。
商品の入手可能性レコードをインポートする場合、以下のエンドポイントをこの順番で使用する必要があります。
-
インポート POST URI への呼び出しによってインポートを開始します。
https://{shortCode}.api.commercecloud.salesforce.com/inventory/impex/v1/organizations/{organizationId}/availability-records/imports
在庫入手可能性データの Omnichannel Inventory への読み込みを開始するには、入手可能性レコードインポート POST エンドポイントを使用します。インポートするデータの詳細は、POST リクエストのボディに記載されています。
-
手順 1 のレスポンスボディから uploadLink を使用し、POST 呼び出しを使用して、データストリーム/ファイルを OCI にアップロードします。
https://{shortCode}.api.commercecloud.salesforce.com/inventory/impex/v1/organizations/{organizationId}/availability-records/imports/uploadlink/{uploadLinkId}
呼び出しの開始で返されるレスポンスボディには、実際のインポートデータストリーム/ファイルを送信するためのリンクが含まれています。システムにアップロードされるファイルが 100MB を超える場合、そのファイルは gzip で圧縮する 必要があります 。
-
ファイルが OCI にアップロードされた後、手順 1 の呼び出し開始に対してレスポンスボディで提供された importStatusLink への GET 呼び出しを使用して、インポートデータの処理ステータスを確認できます。
https://{shortCode}.api.commercecloud.salesforce.com/inventory/impex/v1/organizations/{organizationId}/availability-records/imports/{importId}/status
ファイルが OCI システムに正常にアップロードされた後、入手可能性レコードインポートステータスエンドポイントを呼び出して、インポートのステータスを確認できます。このエンドポイントをファイルアップロードで使用された importId と組み合わせて使用すると、インポート処理が完了したかどうかを確認できます。
-
手順 3 から返されるレスポンスボディのステータスフィールドが COMPLETED (完了) になった後、OCI への入手可能性レコードデータのインポートが完了します。ステータスレスポンスには、完了したインポート処理の詳細を取得するための URI をもつ fullResults href フィールドが含まれています。この情報は、提供された URI への GET 呼び出しで取得されます。
https://{shortCode}.api.commercecloud.salesforce.com/inventory/impex/v1/organizations/{organizationId}/availability-records/imports/{importId}/file-content
ファイルが OCI によって正常に処理されると、レスポンスボディに COMPLETED (完了) のステータスが含められます。インポートに関する他のメトリクスも含まれており、ステータス 呼び出しのドキュメントに記載されています。
また、COMPLETED ステータスには、fullResults href が含まれています。この URI を使用することで、完了したインポート処理の詳細な結果を取得できます。
この順番でエンドポイントを指定すると、入手可能性レコードを OCI に正常にインポートできます。
これは推奨されるインポートファイルのレイアウトです。
mode
は、現在唯一サポートされている UPDATE
とみなされます。
{"recordId":"0a87539d-f3dd-47bc-91c7-9c752e39dbe0","onHand":10,"sku":"sku1","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"wickenburg"}
{"recordId":"3127e2ad-748b-459a-917c-78bef741602c","onHand":10,"sku":"sku1","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"prescott"}
{"recordId":"b709e7a8-7d4f-4458-be0c-a88f1e594f1d","onHand":10,"sku":"sku2","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"wickenburg"}
{"recordId":"b34c99ea-e659-40f7-bcb4-2a3fdc4a80b0","onHand":10,"sku":"sku2","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"prescott"}
{"recordId":"4bf7b40b-c965-485c-afa0-cc56a8ea70eb","onHand":10,"sku":"sku3","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"wickenburg"}
{"recordId":"539d41b7-5f05-4908-831b-3dd0461794fc","onHand":10,"sku":"sku3","effectiveDate":"2020-04-08T14:05:22.790896-07:00","futures":[{"quantity":1,"expectedDate":"2020-04-18T14:05:22.781-07:00"}],"safetyStockCount":0,"locationId":"prescott"}
高パフォーマンスレイアウトを使用していることを示す要件は、この他にはありません。ファイルがシステムに読み込まれると、処理方法は自動的に決定されます。
フィールドのコンテンツについては、後述の「インポートフィールドの定義」のセクションを参照してください。
ロケーションヘッダー:
フィールド | 説明 | 必須フィールド |
---|---|---|
location | 在庫が保管されている物理的な場所 | TRUE |
mode | 実行するシステムオペレーションのタイプ。現時点では、UPDATE のみがサポートされています。 | TRUE |
ロケーション在庫:
フィールド | 説明 | 必須フィールド |
---|---|---|
recordId | 在庫レコードの一意の識別子。 | TRUE |
sku | 商品の一意の識別子。 | TRUE |
onHand | 現在の手持在庫数量。 | FALSE |
effectiveDate | onHand の有効日 (ISO フォーマット)。 | FALSE 、詳細については後述の追加説明を参照してください。 |
futures | 商品の将来の数量に関する情報のコレクション。(後述の「将来の数量」を参照してください。)注: Inventory Availability API は、futures を futureStock というコレクションで参照しています。これらは同じものです。 | FALSE 。指定されている場合は、後述の必須フィールドを参照してください。 |
safetyStockCount | 安全在庫数。 | FALSE |
将来の数量:
フィールド | 説明 | 必須フィールド |
---|---|---|
quantity | 将来到着する予定の数量。値は 0 より大きくなければなりません。 | TRUE |
expectedDate | 将来の数量が到着すると予想される日付 (ISO フォーマット)。 | TRUE |
入手可能性の有効日:
effectiveDate
フィールドは、物理的な場所における onHand
の値の正確な時間を表します。このフィールドは、予約フルフィルメントフィールドの fulfillmentTime
と連動して、onHand
を物理的な場所と同期させるために使用します。たとえば、ロケーションレコードに effectiveDate
が指定されている場合、システムはオプションとして、予約フルフィルメントのときに onHand
の値をデクリメントします。予約フルフィルメントの仕組みの詳細については、Inventory Reservation APIを参照してください。
例:
SKU abc
がロケーション 123
でインポートされた場合、onHand
の値では、OCI でまだ処理されていない予約フルフィルメントが考慮されます。
JSON はここではフォーマットされた状態で表示されていますが、実際のインポートファイルでは、すべて 1 行になっていなければ なりません 。
予約フルフィルメントのリクエストは、SKU abc
がロケーション 123
でインポートされた後に行われます。
システムで、effectiveDate
と fulfillmentTime
の値が比較されます。fulfillmentTime
は effectiveDate
より 小さい ため、onHand
の値はデクリメント されません 。予約フルフィルメントが先に行われた場合、onHand
がデクリメントされます (ただし effectiveDate
の前の値が fulfillmentTime
より小さいことが前提)。次に、在庫インポートが実行されると、前の値は onHand
の値で置き換えられます。
結果ファイルは、ステータス行のレコードで始まります。
{"status": "COMPLETED_WITHOUT_ERRORS"}
結果ステータス | 説明 |
---|---|
COMPLETED_WITHOUT_ERRORS | インポートがエラーなしで完了しました。 |
COMPLETED_WITH_PARTIAL_FAILURES | 一部のレコードを読み込みませんでした。 |
FAILED | レコードを読み込めませんでした。 |
ステータス行に続く各行は、エラーレコードを表します。
{"recordId": "2a3e769c-c981-4d96-ba6a-e0b821a5bbbb","locationId":"location1","sku": "sku1", "message": "Unknown"}
フィールド | 説明 | 必須フィールド |
---|---|---|
recordId | インポートファイルで送信される在庫レコードの一意の識別子。 | TRUE |
locationId | ロケーションの識別子。 | TRUE |
sku | 商品の一意の識別子。 | TRUE |
message | 失敗の詳細が記載されているメッセージ。 | TRUE |
すべてのエンドポイントには、同じ sku/locationGroup の組み合わせに対して 1 秒あたり約 50 件のリクエストという理論上の制限があります。このため、フラッシュセールなどで最適なパフォーマンスを確保することが難しくなります。個々の SKU/locationGroup に対して多数のリクエストを行う場合は、可能であれば、入手可能性、予約、転送、フルフィルメントなどのリクエストを 1 つに結合またはバッチ処理することを推奨します。この方法は、実装全体でパフォーマンスを最適な状態に保つのに役立ちます。
現在、コンシューマーがリクエストとともに ExternalRefId
を送信できる場所はいくつかあります。これは、コンシューマーが、リクエストとともにユーザー生成データを他の外部システムデータへのリンクとして送信できるようにするためです。たとえば、注文 ID をもつ注文からデータを引き出す場合、その注文 ID を externalRefId
として予約リクエストとともに送信できます。このようにすると、予約に問題が発生した場合に、エラーや問題が発生した外部システムの注文と簡単に関連付けることができます。これを、Salesforce Core やその他のサービスで使用されている externalRefId
と混同してはなりません。この用途は OCI 限定で、他では使用されません。
OCI での操作の追跡を容易にするために、顧客は correlation-id
という名前のヘッダーに情報を入力する必要があります。この情報は、CDN から OCI にリクエストを送信するために使用されます。このヘッダーは、Salesforce のサービスを通じてリクエストを容易に追跡できるようにします。
一部のサービスではヘッダー x-correlation-id
が使用されます。このヘッダーを OCI で使用すると、CDN によって新しい値で上書きされるため、ヘッダーの当初の目的は達成されません。一貫した結果を得るには、代わりに correlation-id
を使用してください。