diff --git a/content/developer/reference/external_api.rst b/content/developer/reference/external_api.rst index 93355536f..af5787ada 100644 --- a/content/developer/reference/external_api.rst +++ b/content/developer/reference/external_api.rst @@ -72,6 +72,15 @@ If you already have an Odoo server installed, you can just use its parameters. username = "admin", password = ; + .. code-tab:: go + + var ( + url = + db = + username = "admin" + password = + ) + .. _api/external_api/keys: API Keys @@ -180,6 +189,27 @@ database: The examples do not include imports as these imports couldn't be pasted in the code. + .. group-tab:: Go + + .. code-block:: go + + client, err := xmlrpc.NewClient("https://demo.odoo.com/start", nil) + if err != nil { + log.Fatal(err) + } + info := map[string]string{} + client.Call("start", nil, &info) + url = info["host"].(string) + db = info["database"].(string) + username = info["user"].(string) + password = info["password"].(string) + + .. note:: + These examples use the `github.com/kolo/xmlrpc library `_. + + The examples do not include imports as these imports couldn't be + pasted in the code. + Logging in ---------- @@ -217,6 +247,17 @@ the login. common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url))); client.execute(common_config, "version", emptyList()); + .. code-tab:: go + + client, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/common", url), nil) + if err != nil { + log.Fatal(err) + } + common := map[string]any{} + if err := client.Call("version", nil, &common); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -247,6 +288,16 @@ Result: int uid = (int)client.execute(common_config, "authenticate", asList(db, username, password, emptyMap())); + .. code-tab:: go + + var uid int64 + if err := client.Call("authenticate", []any{ + db, username, password, + map[string]any{}, + }, &uid); err != nil { + log.Fatal(err) + } + .. _api/external_api/calling_methods: Calling methods @@ -303,6 +354,22 @@ Each call to ``execute_kw`` takes the following parameters: new HashMap() {{ put("raise_exception", false); }} )); + .. code-tab:: go + + models, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/object", url), nil) + if err != nil { + log.Fatal(err) + } + var result bool + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "check_access_rights", + []string{"read"}, + map[string]bool{"raise_exception": false}, + }, &result); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -345,6 +412,19 @@ database identifiers of all records matching the filter. asList("is_company", "=", true))) ))); + .. code-tab:: go + + var records []int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search", + []any{[]any{ + []any{"is_company", "=", true}, + }}, + }, &records); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -384,6 +464,20 @@ available to only retrieve a subset of all matched records. new HashMap() {{ put("offset", 10); put("limit", 5); }} ))); + .. code-tab:: go + + var records []int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search", + []any{[]any{ + []any{"is_company", "=", true}, + }}, + map[string]int64{"offset": 10, "limit": 5}, + }, &records); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -424,6 +518,19 @@ only the number of records matching the query. It takes the same asList("is_company", "=", true))) )); + .. code-tab:: go + + var counter int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search_count", + []any{[]any{ + []any{"is_company", "=", true}, + }}, + }, &counter); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -488,6 +595,30 @@ which tends to be a huge amount. // count the number of fields fetched by default record.size(); + .. code-tab:: go + + var ids []int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search", + []any{[]any{ + []any{"is_company", "=", true}, + }}, + map[string]int64{"limit": 1}, + }, &ids); err != nil { + log.Fatal(err) + } + var records []any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "read", + ids, + }, &records); err != nil { + log.Fatal(err) + } + // count the number of fields fetched by default + count := len(records) + Result: .. code-block:: json @@ -521,6 +652,20 @@ which tends to be a huge amount. }} ))); + .. code-tab:: go + + var recordFields []map[string]any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "read", + ids, + map[string][]string{ + "fields": {"name", "country_id", "comment"}, + }, + }, &recordFields); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -569,6 +714,20 @@ updating a record). }} )); + .. code-tab:: go + + recordFields := map[string]string{} + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "fields_get", + []any{}, + map[string][]string{ + "attributes": {"string", "help", "type"}, + }, + }, &recordFields); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -652,6 +811,23 @@ if that list is not provided it will fetch all fields of matched records). }} ))); + .. code-tab:: go + + var recordFields []map[string]any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search_read", + []any{[]any{ + []any{"is_company", "=", true}, + }}, + map[string]any{ + "fields": []string{"name", "country_id", "comment"}, + "limit": 5, + }, + }, &recordFields); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -723,6 +899,19 @@ set through the mapping argument, the default value will be used. asList(new HashMap() {{ put("name", "New Partner"); }}) )); + .. code-tab:: go + + var id int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "create", + []map[string]string{ + {"name": "New Partner"}, + }, + }, &id); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -792,6 +981,31 @@ a record). asList(asList(id)) ))); + .. code-tab:: go + + var result bool + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "write", + []any{ + []int64{id}, + map[string]string{"name": "Newer partner"}, + }, + }, &result); err != nil { + log.Fatal(err) + } + // get record name after having changed it + var record []any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "name_get", + []any{ + []int64{id}, + }, + }, &record); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -841,6 +1055,30 @@ Records can be deleted in bulk by providing their ids to asList(asList(asList("id", "=", 78))) ))); + .. code-tab:: go + + var result bool + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "unlink", + []any{ + []int64{id}, + }, + }, &result); err != nil { + log.Fatal(err) + } + // check if the deleted record is still in the database + var record []any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "res.partner", "search", + []any{[]any{ + []any{"id", "=", id}, + }}, + }, &record); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -953,6 +1191,34 @@ Provides information about Odoo models via its various fields. }} )); + .. code-tab:: go + + var id int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "ir.model", "create", + []map[string]string{ + { + "name": "Custom Model", + "model": "x_custom_model", + "state": "manual", + }, + }, + }, &id); err != nil { + log.Fatal(err) + } + recordFields := map[string]string{} + if err := models.Call("execute_kw", []any{ + db, uid, password, + "x_custom_model", "fields_get", + []any{}, + map[string][]string{ + "attributes": {"string", "help", "type"}, + }, + }, &recordFields); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json @@ -1118,6 +1384,57 @@ custom fields without using Python code. asList(asList(record_id)) )); + .. code-tab:: go + + var id int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "ir.model", "create", + []map[string]string{ + { + "name": "Custom Model", + "model": "x_custom", + "state": "manual", + }, + }, + }, &id); err != nil { + log.Fatal(err) + } + var fieldId int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "ir.model.fields", "create", + []map[string]any{ + { + "model_id": id, + "name": "x_name", + "ttype": "char", + "state": "manual", + "required": true, + }, + }, + }, &fieldId); err != nil { + log.Fatal(err) + } + var recordId int64 + if err := models.Call("execute_kw", []any{ + db, uid, password, + "x_custom", "create", + []map[string]string{ + {"x_name": "test record"}, + }, + }, &recordId); err != nil { + log.Fatal(err) + } + var recordFields []map[string]any + if err := models.Call("execute_kw", []any{ + db, uid, password, + "x_custom", "read", + [][]int64{{recordId}}, + }, recordFields); err != nil { + log.Fatal(err) + } + Result: .. code-block:: json