Square APIを使って、在庫数の取得ができるようになったので、在庫数の一覧を作ってみます。
Square APIを使ってみる(在庫数の取得) - Qiita
商品リストをシンプルにする
CatalogApiのlistCatalogで取得できるカタログオブジェクトから、在庫表を作るのに必要そうなデータだけを抜き出して、解析しやすくします。
// カタログオブジェクトをシンプルにするfunctionsimplifyCatalogObjects(catalogObjects){letresultObjects=[];catalogObjects.forEach(obj=>{constresultObj={};if(!obj.is_deleted){resultObj.id=obj.id;resultObj.item_data={"name":obj.item_data.name,};//バリエーションif(obj.item_data.variations){letvariations=[];obj.item_data.variations.forEach(variation=>{if(!variation.is_deleted){variations.push({"id":variation.id,"item_variation_data":{"name":variation.item_variation_data.name,"sku":variation.item_variation_data.sku,},});}});resultObj.item_data.variations=variations;}resultObjects.push(resultObj);}});returnresultObjects;}// Square APIへアクセスconstSquareConnect=require('square-connect');constdefaultClient=SquareConnect.ApiClient.instance;constoauth2=defaultClient.authentications['oauth2'];oauth2.accessToken='YOUR ACCESS TOKEN';// カタログリスト取得constapiInstance=newSquareConnect.CatalogApi();constopts={'types':'ITEM'// String | An optional case-insensitive, comma-separated list of object types to retrieve, for example `ITEM,ITEM_VARIATION,CATEGORY,IMAGE`. The legal values are taken from the CatalogObjectType enum: `ITEM`, `ITEM_VARIATION`, `CATEGORY`, `DISCOUNT`, `TAX`, `MODIFIER`, `MODIFIER_LIST`, or `IMAGE`.};apiInstance.listCatalog(opts).then(function(data){console.log('API called successfully. Returned data: ');constlistObj=simplifyCatalogObjects(data.objects);console.log(JSON.stringify(listObj,null,2));},function(error){console.error(error);});
以下のようなオブジェクトになります。
{"id":"5PH23FJXUXRA762XBNMIWXOP","item_data":{"name":"龍童子","variations":[{"id":"YFUAKFPQFKZGLDVDAC7BAEZM","item_variation_data":{"name":"亀","sku":""}},{"id":"GKG5AJSJGPGWBKKCPDXVTYYL","item_variation_data":{"name":"龍","sku":""}}]}},{"id":"GHUUZGRZR4RLKU5CORONQGCE","item_data":{"name":"獅子毛毬","variations":[{"id":"XLYCP3R5HKYGBZGXXYMR4FRG","item_variation_data":{"name":"カラフル","sku":""}}]}},{"id":"SGT6ELC5BRESKTIDJ4OV2AF5","item_data":{"name":"たまねぎ屋","variations":[{"id":"6I4VBILOEURJCZHDA5KXF3YS","item_variation_data":{"name":"定価","sku":""}}]}},
シンプルにしてみて気づいたのですが、Squareの商品管理画面では、バリエーションがないように見える商品も必ず「定価」とか「販売価格」といったバリエーションができるようです。
在庫数を問い合わせる
どの商品にも必ずバリエーションが1つはあることがわかったので、全てのバリエーションのidで在庫数を問い合わせれば良さそうです。
id一つ一つ問い合わせればいいかと思ったのですが、一度に取得出来そうです。
複数の商品の在庫数を問い合わせるには、InventoryApiのbatchRetrieveInventoryCountsを使います。
問い合わせるidを配列に入れて指定することもできるようですが、今回は全ての在庫数を取得してみます。
varSquareConnect=require('square-connect');vardefaultClient=SquareConnect.ApiClient.instance;// Configure OAuth2 access token for authorization: oauth2varoauth2=defaultClient.authentications['oauth2'];oauth2.accessToken='YOUR ACCESS TOKEN';varapiInstance=newSquareConnect.InventoryApi();varbody=newSquareConnect.BatchRetrieveInventoryCountsRequest();// BatchRetrieveInventoryCountsRequest | An object containing the fields to POST for the request. See the corresponding object definition for field details.apiInstance.batchRetrieveInventoryCounts(body).then(function(data){console.log('API called successfully. Returned data: ');console.log(JSON.stringify(data,null,2));},function(error){console.error(error);});
在庫データが以下のような感じで取得できます。
{"counts":[{"catalog_object_id":"CQZIEPDLFE64WVKMCQDLW7D3","catalog_object_type":"ITEM_VARIATION","state":"IN_STOCK","location_id":"454ACGR0V7GPA","quantity":"1","calculated_at":"2020-01-25T03:15:12.1253Z"},{"catalog_object_id":"Q4QA5OQ6EY5ZQR6LC7K22RT6","catalog_object_type":"ITEM_VARIATION","state":"IN_STOCK","location_id":"454ACGR0V7GPA","quantity":"0","calculated_at":"2020-02-03T04:27:25.234Z"},{"catalog_object_id":"52EALZY6VCSEZEHAJPGFJB5R","catalog_object_type":"ITEM_VARIATION","state":"IN_STOCK","location_id":"454ACGR0V7GPA","quantity":"0","calculated_at":"2019-11-03T09:50:46.1139Z"},{"catalog_object_id":"LEGPUO52IVTP7RLT2A5NRD6T","catalog_object_type":"ITEM_VARIATION","state":"IN_STOCK","location_id":"454ACGR0V7GPA","quantity":"2","calculated_at":"2019-11-03T09:50:16.1139Z"},
※後でわかったのですが、1度に取得できる件数が100アイテム分のようで、返ってきたオブジェクトにcursor
プロパティがあった場合は、このカーソルプロパティの値をパラメーターに使って、追加でbatchRetrieveInventoryCountsを呼び出す必要があります。
在庫データを連想配列にする
使いやすいように、idをキーにした連想配列に変換します。
// 全在庫数データを連想配列にするfunctionarrayInventoryCounts(inventoryCounts){letresultArray=[];inventoryCounts.forEach(obj=>{resultArray[obj.catalog_object_id]=obj.quantity;});returnresultArray;}
以下のような感じの連想配列になります。
[CQZIEPDLFE64WVKMCQDLW7D3:'1',Q4QA5OQ6EY5ZQR6LC7K22RT6:'0','52EALZY6VCSEZEHAJPGFJB5R':'0',LEGPUO52IVTP7RLT2A5NRD6T:'2',JE3HZYQEKDXDEPQJYYDGMWDV:'0',X7EGVDUYAVVWKWHHZPMDS53E:'0',THTWJQPEEAXU4S75DKUBSF6V:'0',Y7KFYSA33DQ22JY3QJVPBTRG:'0',K46BVOXXYN7IESVTNTKOQNLY:'0',ZZTLDYJAIXNCLWS3MV3NQTRX:'0','3TUHUDMXKKS3RDLLGAJGTMPM':'0',F3Z6XGJPU7XKXCVLKQ5BBTDB:'0',
※こちらも後で分かったのですが、stateプロパティがIN_STOCK
以外のものも入るようなので、stateプロパティがIN_STOCK
のものだけを使うようにする必要があります。
在庫数の一覧を作る
batchRetrieveInventoryCountsのページネーションや、在庫データの種類の問題を解決して結局以下のようなプログラムで在庫一覧のデータを作成できました。
// 在庫数リスト取得サンプルconstSquareConnect=require('square-connect');// 全在庫数データを連想配列にするfunctionarrayInventoryCounts(inventoryCounts){letresultArray=[];inventoryCounts.forEach(obj=>{if(obj.state=="IN_STOCK"){if(resultArray[obj.catalog_object_id]){// console.log(obj.catalog_object_id);}resultArray[obj.catalog_object_id]=obj.quantity;}});returnresultArray;}// 全在庫数リストを作成functionlistInventoryCount(catalogObjects,inventoryCounts){letresultObjects=[];constarrayCounts=arrayInventoryCounts(inventoryCounts);catalogObjects.forEach(obj=>{constresultObj={};if(!obj.is_deleted){resultObj.id=obj.id;resultObj.item_data={"name":obj.item_data.name,};//バリエーションif(obj.item_data.variations){letvariations=[];obj.item_data.variations.forEach(variation=>{if(!variation.is_deleted){variations.push({"id":variation.id,"item_variation_data":{"name":variation.item_variation_data.name,"sku":variation.item_variation_data.sku,"stock":arrayCounts[variation.id]},});}});resultObj.item_data.variations=variations;}resultObjects.push(resultObj);}});returnresultObjects;}//商品カタログ取得asyncfunctionlistCatalog(){constapiInstance=newSquareConnect.CatalogApi();constopts={'types':'ITEM'};constdata=awaitapiInstance.listCatalog(opts);returndata;}// 全在庫数データ取得asyncfunctionbatchRetrieveInventoryCounts(){constapiInstance=newSquareConnect.InventoryApi();letbody={"cursor":""};letdata={"counts":[]};do{constdt=awaitapiInstance.batchRetrieveInventoryCounts(body);data.counts=data.counts.concat(dt.counts);body.cursor=dt.cursor||null;}while(body.cursor);returndata;}// Square APIへアクセスconstdefaultClient=SquareConnect.ApiClient.instance;constoauth2=defaultClient.authentications['oauth2'];oauth2.accessToken='YOUR ACCESS TOKEN';(async()=>{try{//カタログデータと在庫データを並列で問い合わせconstlistCatalogPromise=listCatalog();console.log("listCatalog()");constinventoryCountsPromise=batchRetrieveInventoryCounts();console.log("batchRetrieveInventoryCounts()");//問い合わせ処理の終了待ちcatalogObjs=awaitlistCatalogPromise;inventoryCounts=awaitinventoryCountsPromise;console.log('問い合わせ終了');//在庫リスト作成constdata=listInventoryCount(catalogObjs.objects,inventoryCounts.counts);console.log(JSON.stringify(data,null,2));}catch(error){console.error(error);}})();
取得できるデータは以下のよう感じです。
{"id":"KEGDS5AB55HZXNKDVU2KMR54","item_data":{"name":"T ベージュ","variations":[{"id":"L3AMBR4VKPEKACZM42W5XSSR","item_variation_data":{"name":"XS","sku":"","stock":"1"}},{"id":"H6SZNXOHR5AODKVYXSF5LQUJ","item_variation_data":{"name":"S","sku":"","stock":"0"}},{"id":"IEU5P2IX25NYGMTTNP6MJHZE","item_variation_data":{"name":"M","sku":"","stock":"0"}},{"id":"OV2UHORNF7NMC6KJHUXQTOPR","item_variation_data":{"name":"L","sku":"","stock":"2"}},{"id":"L22LMUV37MNPRZMA2SX3G3AI","item_variation_data":{"name":"Kids","sku":""}}]}},{"id":"YKWBCEXWXMQHJ3OJNSUTZ532","item_data":{"name":"T オレンジ","variations":[{"id":"ZXAY4RQ56TCXJQXWGJDKSBRP","item_variation_data":{"name":"XS","sku":"","stock":"2"}},{"id":"MY7KQ7RUBDQG3LCWARXPZZCN","item_variation_data":{"name":"S","sku":"","stock":"0"}},{"id":"RO4SSMLWPQ7IQ75G6HVFMXNH","item_variation_data":{"name":"M","sku":"","stock":"0"}},{"id":"QLSRDXB52BKDFXLZ3XRAEQO4","item_variation_data":{"name":"KIDS","sku":"","stock":"-1"}}]}},
stock
が在庫数になります。
stock
プロパティがないものがありますが、これは在庫データを全く入力していない状況だとデータがないので、このようになります。
在庫数=0とは別の状況です。
stock
がマイナスのものは、在庫補充時に在庫データを変更しなかったので、売れた分マイナスになっていっている状況です。