Odoo の在庫モジュールを JSON-RPC で操作2
前回 の続きで、今回は Odoo の在庫モジュールを JSON-RPC で操作し在庫移動(顧客への出荷)を処理してみます。
ソースは http://github.com/fits/try_samples/tree/master/blog/20200112/
在庫管理
Odoo の画面では在庫移動(顧客への出荷等)を以下のように処理しているようでした。(ステータスは ドラフト -> 待機中 -> 準備完了 -> 完了
のように遷移)
- (1) stock.picking を create - 作成
- (2) action_confirm の実行 - 処理準備
- (3) action_assign の実行 - 利用可能準備(引当)
- (4) button_validate の実行
- (5) stock.immediate.transfer の process を実施
ただ、画面処理を前提としたような (4) 以降の処理を API として呼び出すには違和感があります。
そこで、button_validate
の処理等を参照して別の方法で処理できないか調べてみたところ、以下のようにしても実現できそうでした。
- (4') (1) で作られた stock.move.line の qty_done を更新
- (5') action_done の実行
よって、今回はこの両方を試してみます。
(c) 在庫移動1 - button_validate 実行
まずは、button_validate
を呼び出す方を試してみます。
(認証などの処理は前回と同じです)
sample3.js
const axios = require('axios') ・・・ const pickingTypeId = parseInt(process.argv[2]) const locationId = parseInt(process.argv[3]) const locationDestId = parseInt(process.argv[4]) const productId = parseInt(process.argv[5]) const qty = parseInt(process.argv[6]) const main = async () => { const auth = ・・・ const uid = auth.data.result // (1) 作成 const sp1 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'c2', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'create', { picking_type_id: pickingTypeId, location_id: locationId, location_dest_id: locationDestId, move_lines: [ [0, 0, { name: 'move', product_id: productId, product_uom: 1, product_uom_qty: qty }] ] }] } }) console.log(sp1.data) if (sp1.data.error) { return } const pid = sp1.data.result console.log(`id: ${pid}`) // (2) 処理準備 const sp2 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'c3', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'action_confirm', pid] } }) console.log(sp2.data) if (sp2.data.error) { return } // (3) 利用可能準備(引当) const sp3 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'c4', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'action_assign', pid] } }) console.log(sp3.data) if (sp3.data.error) { return } // (4) 検証(button_validate の実行) const sp4 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'c5', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'button_validate', pid] } }) console.log(sp4.data) if (sp4.data.error) { return } const vld = sp4.data.result // (5) stock.immediate.transfer の process を実行 const res = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'c7', params: { service: 'object', method: 'execute', args: [db, uid, password, vld.res_model, 'process', vld.res_id] } }) console.log(res.data) } main().catch(err => console.error(err))
上記を使って、ピッキングタイプ 2(Delivery Orders)
で在庫ロケーション 8(WH/Stock)
から顧客出荷用のロケーション 5(Partner Locations/Customers)
へ商品 19(Large Desk)
を 2個移動してみます。
実行
> node sample3.js 2 8 5 19 2 { jsonrpc: '2.0', id: 'c2', result: 70 } id: 70 { jsonrpc: '2.0', id: 'c3', result: true } { jsonrpc: '2.0', id: 'c4', result: true } { jsonrpc: '2.0', id: 'c5', result: { name: 'Immediate Transfer?', type: 'ir.actions.act_window', view_mode: 'form', res_model: 'stock.immediate.transfer', views: [ [Array] ], view_id: 477, target: 'new', res_id: 8, context: {} } } { jsonrpc: '2.0', id: 'c7', result: false }
在庫数を確認してみると 100個あった在庫が 98個となっているため、とりあえずは成功しているようです。
在庫数の確認
> node sample1.js 19 ・・・ [ { id: 19, name: 'Large Desk', product_tmpl_id: [ 13, '[E-COM09] Large Desk' ], qty_available: 98, virtual_available: 98 } ]
(d) 在庫移動2 - qty_done の更新
次に qty_done
を更新する方法も試してみます。
sample4.js
const axios = require('axios') ・・・ const pickingTypeId = parseInt(process.argv[2]) const locationId = parseInt(process.argv[3]) const locationDestId = parseInt(process.argv[4]) const productId = parseInt(process.argv[5]) const qty = parseInt(process.argv[6]) const main = async () => { ・・・ // (3) 利用可能準備(引当) const sp3 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'd4', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'action_assign', pid] } }) console.log(sp3.data) if (sp3.data.error) { return } // move_line_ids の取得 const pick = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'd5', params: { service: 'object', method: 'execute_kw', args: [db, uid, password, 'stock.picking', 'read', [pid], { fields: ['move_line_ids'] }] } }) console.log(pick.data) const lineIds = pick.data.result[0].move_line_ids console.log(`move line ids: ${lineIds}`) // (4') stock.move.line の qty_done(処理済み在庫数)を更新 const sml = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'd6', params: { service: 'object', method: 'execute_kw', args: [ db, uid, password, 'stock.move.line', 'write', [ lineIds, { qty_done: qty }], {} ] } }) console.log(sml.data) if (sml.data.error) { return } // (5') action_done の実行 const sp4 = await axios.post(url, { jsonrpc: '2.0', method: 'call', id: 'd7', params: { service: 'object', method: 'execute', args: [db, uid, password, 'stock.picking', 'action_done', pid] } }) console.log(sp4.data) } main().catch(err => console.error(err))
button_validate の時と同じようにピッキングタイプ 2(Delivery Orders)
で在庫ロケーション 8(WH/Stock)
から顧客出荷用のロケーション 5(Partner Locations/Customers)
へ商品 19(Large Desk)
を今度は 3個移動してみます。
実行
> node sample4.js 2 8 5 19 3 { jsonrpc: '2.0', id: 'd2', result: 71 } id: 71 { jsonrpc: '2.0', id: 'd3', result: true } { jsonrpc: '2.0', id: 'd4', result: true } { jsonrpc: '2.0', id: 'd5', result: [ { id: 71, move_line_ids: [Array] } ] } move line ids: 73 { jsonrpc: '2.0', id: 'd6', result: true } { jsonrpc: '2.0', id: 'd7', result: true }
98個あった在庫が 95個となっているので、こちらも一応は成功しているようです。
在庫確認
> node sample1.js 19 ・・・ [ { id: 19, name: 'Large Desk', product_tmpl_id: [ 13, '[E-COM09] Large Desk' ], qty_available: 95, virtual_available: 95 } ]