Node.js Interfacing dengan Odoo REST API
Menggunakan Axios untuk access Odoo MUK REST API

MUK REST API adalah salah satu addon REST API buatan Mukit.at yang cukup lumayan lengkap, flexible dan secure, karena authentication nya pakai token based Oauth1 dan Oauth2. 

Addon nya bisa dicari di apps.odoo.com dengan keyword muk_rest. Untuk keperluan belajar bisa hubungi kami untuk mendapatkan addon ini.

Dokumentasinya cukup detail tapi agak susah diikuti oleh newbie.

https://app.swaggerhub.com/apis/keshrath/muk_rest/3.0.0

Mudah2an artikel ini bisa agak membumikan dokumentasi tersebut menjadi real application.

INSTALASI DAN PENGGUNAAN

Step1: Install muk_rest addons di server

Step2: Add API configuration di Odoo

  • Menu Settings - Rest API - configuration - Oauth2 - Create...

  • Oauth type: Password credentials

  • Security: Basic Access Control 

Copy Client Key dan Client Secret untuk digunakan pada nodejs atau mobile apps 


Step3: Develop client app dengan Client Key dan Client Secret untuk Authorization ke odoo menggunakan username dan password yang existing di odoo 

 

Cara Kerja

Client app harus request access_token ke Odoo menggunakan Client Key dan Client Secret, username dan password user Odoo

Internally cara me-request access_token adalah dengan mengirimkan HTTP Header berikut:

Authorization: Basic <encrypted>

dimana <encrypted> adalah encrypt dan encoded dari Client Key menggunakan Client Secret. Hal Ini sudah dihandle di dalam library axios-oauth-client

Setelah dapat access_token, simpan ke local variable global di apps.

Gunakan access_token untuk setiap request ke API pada HTTP header:

Authorization: Bearer <access_token>

CONTOH

Berikut ini contoh script Node JS untuk login, search, create, update data partner.


class TestOdooAPI {

/**********************************************************************
* setup class
*********************************************************************/
constructor(url, client_id, client_secret, redirect_uri, username, password){
this.url = url;
this.client_id = client_id;
this.client_secret = client_secret;
this.redirect_uri = redirect_uri;
this.username = username;
this.password = password;

this.access_token='----';
}
/**********************************************************************
* login to Odoo using Oauth2
* Create object oauth.client() dan axios.client() dengan parameter:
* url: alamat API authentication Odoo
* grant_type: password , sesuai yang di setting di ODoo
* client_id: client key yang didapat dari Odoo
* client_secret: client Secret yang didapat dari Odoo
* redirect_uri: optional url redirect setelah berhasil dapat token
* username: user odoo
* password: password user odoo
* scope: all=Basic Access Control sesuai yang ditentukan di Odoo
*********************************************************************/
async loginRequest() {
const getAuthorizationCode = oauth.client(axios.create(), {
url: this.url + '/api/authentication/oauth2/token',
grant_type: 'password',
client_id: this.client_id,
client_secret: this.client_secret,
redirect_uri: this.redirect_uri,
username: this.username,
password: this.password,
scope: 'all',
});
let auth = await getAuthorizationCode();
console.log("----- auth response -----")
console.log(auth)
this.access_token=auth.access_token
}

/**********************************************************************
* get logged user information setelah berhasil login
*
* Parameter:
* method: get
* url: /api/user
* HTTP Header: Authorization: 'Bearer ' + this.access_token
*********************************************************************/
async getUserInfo(){
const config = {
method: 'get',
url: this.url + '/api/user',
headers: { Authorization: 'Bearer ' + this.access_token }
}
let res = await axios(config)
console.log("----- user info -----")
console.log(res.data);
}

/**********************************************************************
* request call any methods on a model
* memanggil method apapun yang ada di dalam model
*
* Parameter:
* model = nama model Odoo, misalnya "res.partner", "account.invoice", dll
* method = nama method, misalnya "create", "write", "unlink", atau custom method
*
* Named parameter:
* ids = id database jika method ini perlu ID parameter dalam bentuk string of list, misalnya "[2,3,4]"
* args= argument yang diminta oleh method dalam bentuk string , misalnya "[ [('name','=','Indonesia')] ]", "[1,2,3]", dan sebagainya
* kwargs = named argument yang diminta oleh method dalam bentuk string
*********************************************************************/
async call(model, method,{ids, context, args, kwargs}){
const config = {
method: 'post',
url: this.url + '/api/call/'+model+'/'+method+'?' + qs.stringify({
ids: ids,
context: context,
args: args,
kwargs: kwargs }),
headers: {
Authorization: 'Bearer ' + this.access_token,
'Content-Type': 'multipart/form-data' }
}
let call = await axios(config)
.catch( (err)=>{
console.log("----- error -----")
console.log(err.response.data)
})

if (call){
console.log("----- success -----")
console.log(call.data);
}
}

/**********************************************************************
* call search method
* mencari record di odoo dan return berupa list of ID record-record tersebut
*
* Parameter:
* model = nama model Odoo, misalnya "res.partner", "account.invoice", dll
* domain = format domain dalam bentuk string, misalnya "[('name','=','Indonesia')]"
*
* Named parameter:
* context = context varible yang ingin dikirimkan ke dalam method, dalam bentuk string of dictionary, misalnya "{'languange':'en'}"
* count = jumlah record hasil search
* limit = batasan record
* offset = mulai dari record ke berapa
* order = sortir berdasarkan field misalnya "date desc, id asc"
*********************************************************************/
async search(model, domain, {context, count, limit, offset, order}){
const config = {
method: 'get',
url: this.url + '/api/search/'+model+'?' + qs.stringify({
domain: domain,
context: context,
count: count,
limit: limit,
offset:offset,
order:order
}),
headers: {
Authorization: 'Bearer ' + this.access_token,
'Content-Type': 'multipart/form-data' }
}
let res = await axios(config)
.catch( (err)=>{
console.log("----- error -----")
console.log(err.response.data)
})
if (res){
console.log("----- search -----")
console.log(res.data);
}
}

/**********************************************************************
* call search_read method
* mencari record di odoo dan return berupa list of data lengkap record-record tersebut
*
* Parameter:
* model = nama model Odoo, misalnya "res.partner", "account.invoice", dll
* domain = format domain dalam bentuk string, misalnya "[('name','=','Indonesia')]"
*
* Named parameter:
* fields = nama-nama field yang di select , berupa string of list of fieldnames, misalnya '["name","street","country_id"]'
* context = context varible yang ingin dikirimkan ke dalam method, dalam bentuk string of dictionary, misalnya "{'languange':'en'}"
* count = jumlah record hasil search
* limit = batasan record
* offset = mulai dari record ke berapa
* order = sortir berdasarkan field misalnya "date desc, id asc"
*********************************************************************/
async search_read(model, domain, {fields, context, count, limit, offset, order}){
const config = {
method: 'get',
url: this.url + '/api/search_read/'+model+'?' + qs.stringify({
domain: domain,
fields: fields,
context: context,
count: count,
limit: limit,
offset:offset,
order:order
}),
headers: {
Authorization: 'Bearer ' + this.access_token,
'Content-Type': 'multipart/form-data' }
}
let res = await axios(config)
.catch( (err)=>{
console.log("----- error -----")
console.log(err.response.data)
})
if (res){
console.log("----- search_read -----")
console.log(res.data);
}
}
/**********************************************************************
* call create record method
* menginsert record baru
*
* Parameter:
* model = nama model Odoo
* values = nama field dan values nya, berupa string of dictionary misalnya
* "{'name':'test create partner', 'street':'Sudirman 23', 'city':'Jakarta'}"
*********************************************************************/
async create(model, values){
const config = {
method: 'post',
url: this.url + '/api/create/'+model+'?' + qs.stringify({
values: values
}),
headers: {
Authorization: 'Bearer ' + this.access_token,
'Content-Type': 'multipart/form-data' }
}
let res = await axios(config)
.catch( (err)=>{
console.log("----- error -----")
console.log(err.response.data)
})
if (res){
console.log("----- create -----")
console.log(res.data);
}
}

/**********************************************************************
* call update record method
* mengupdate record
*
* Parameter:
* model = nama model Odoo
* ids = ID database record yang akan diupdate
* values = nama field dan values nya, berupa string of dictionary misalnya
* "{'name':'test create partner', 'street':'Sudirman 23', 'city':'Jakarta'}"
* context = context varible yang ingin dikirimkan ke dalam method, dalam bentuk string of dictionary, misalnya "{'languange':'en'}"
*********************************************************************/
async update(model, ids, values, {context}){
const config = {
method: 'put',
url: this.url + '/api/write/'+model+'?' + qs.stringify({
ids:ids,
values: values,
context: context
}),
headers: {
Authorization: 'Bearer ' + this.access_token,
'Content-Type': 'multipart/form-data' }
}
let res = await axios(config)
.catch( (err)=>{
console.log("----- error -----")
console.log(err.response.data)
})
if (res){
console.log("----- update -----")
console.log(res.data);
}
}



}


const url = 'https://demo0101.1toucherp.com'
const client_id = '**************************'
const client_secret ='************************'
const username = 'admin'
const password = '12345'
const redirect_uri='http://demo0101.1toucherp.com'


testOdoo = new TestOdooAPI(url, client_id, client_secret, redirect_uri, username, password)
testOdoo.loginRequest().then(()=>{
testOdoo.getUserInfo()
testOdoo.call('res.partner','search', {args:"[ [('name','ilike','admin')] ]"})
testOdoo.search('res.partner', "[('name','ilike','admin')]", {})
testOdoo.search_read('res.partner', "[('name','ilike','admin')]", {fields:'["name","street","country_id"]'})
testOdoo.create('res.partner', "{'name':'test create partner'}" )
testOdoo.update('res.partner', 14, "{'name':'updated name'}", {})
})



Klik http://udemy.com/user/akhmaddaniel untuk trik lainnya seputar odoo dan interfacing.

 DO NOT CLICK THIS https://bit.ly/3biXWMc

Videos fill be uploaded regularly, so subscribe our youtube Channel.

Visit YouTube Channel http://youtube.com/odooindonesia

Untuk trik Odoo lainnya bisa cek Udemy courses http://udemy.com/user/akhmaddaniel

Visit official site http://vitraining.com

One Touch and Go Live with Odoo http://1toucherp.com

Twitter http://Twitter.com/akhdaniel 

Check our blog: http://indonesia.odoo.com


Node.js Interfacing dengan Odoo REST API
vitraining, odoo indonesia
15 May, 2020
Share this post
Archive
Sign in to leave a comment
BAGAIMANA MENGECEK SALAH SATU ELEMENT LIST ADA DI SUATU LIST YANG LAIN
DENGAN CARA CEPAT PYTHON