有人将ODOO与Android集成吗?

问题描述 投票:0回答:4

我目前正在为坚持使用 Odoo API 的客户开发一个 Android 应用程序。我对此没有任何想法。即使参考了这个link我也没有得到它。它们提供 URL、数据库名称、用户名和密码。如果有人以前用Android做过Odoo,你能给一些建议吗?

android odoo xml-rpc odoo-mobile
4个回答
6
投票

有很多方法可以将 Android 连接到 Odoo。他们在这里:

  1. Json-RPC
  2. XML-RPC(尤其是aXMLRPC,这就是我正在使用的)
  3. 还有一个名为 Odoo Mobile Framework 的框架。我已经尝试过,但发现了很多问题,并且无法使其正常工作。您可以在此处找到文档。

Odoo 有一个Web 服务 API,可用于 Python、Ruby、PHP 和 Java。我强烈推荐去看一看。

对于我的情况,我克隆了 aXMLRPC git 存储库,在我的项目中创建了一个包并调整了原始包名称。但最近我在 Stack Overflow 上发现了this,解释了如何使用 Gradle 将 aXMLRPC 添加到 Android 项目(我还没有尝试过)。

Odoo 提供了三个端点:

  1. xmlrpc/2/db
    获取服务器上可用数据库的列表,不需要进行身份验证;
  2. xmlrpc/2/common
    登录服务器,不需要认证;
  3. xmlrpc/2/object
    ,用于通过
    execute_kw
    RPC 函数调用 odoo 模型的方法。

     public class OdooConnect {
        String url;
        private XMLRPCClient client;
    
        public OdooConnect(String serverAddress, String path) {
            url = serverAddress + "/xmlrpc/2/" + path;
            client = new XMLRPCClient(url);
        }
    
        public Object login(String db, String username, String password) {
            Object object;
            try {
                object = client.call("login", db, username, password);
                return object;
            } catch (XMLRPCException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public Object checkServer() {
            Object object;
            try {
                object = client.call("list", new Object[]{});
                return object;
            } catch (XMLRPCException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

在此类中,构造函数作为参数提供服务器地址(可以是

http(s)://your_ip_address:the_port_number
)和
path ('db', 'common' or 'object')

checkServer 方法返回一个对象,该对象实际上是一个包含可用数据库列表的数组。

登录方法返回一个 Integer,它是经过身份验证的用户的 Id。

对于 Odoo CRUD 方法(search_read、search_count、search、write、create、unlink),您可以查看 Odoo Web 服务 API 与您想要的方法匹配的 Java 代码。

这是 search_read 方法的示例。我假设您有一个名为 client 的 XMLRPCClient。

public Object search_read(String db, int user_id, String password, String object, List conditions, Map<String, List> fields) {
    Object result = null;
    try {
        result = client.call("execute_kw", db, user_id, password, object, "search_read", conditions, fields);
    } catch (XMLRPCException e) {
        e.printStackTrace();
    }
    return result;
}

哪里

  1. 对象是一个 Odoo 模型,例如
    "res.partner"
  2. 条件是域(过滤器),如下所示:
    Collections.singletonList(Collections.singletonList(Arrays.asList("supplier", "=", true)));
  3. fields,你想要获取的字段,

    fields = new HashMap() {{put("fields", Arrays.asList("id","name","is_company","street")); }};

您必须将该方法的结果转换为 Object[],这将为您提供一个包含对象列表的数组,每个对象代表一条记录。

Object[] objects = (Object[]) result;
if (objects.length > 0) {
    for (Object object : objects) {
        String name= OdooUtil.getString((Map<String, Object>) object, "name");
        boolean is_company= OdooUtil.getBoolean((Map<String, Object>) object, "is_company");
        String street = OdooUtil.getString((Map<String, Object>) object, "street");  
        int id= OdooUtil.getInteger((Map<String, Object>) object, "id");
    }
}

这里是 OdooUtil 类

public class OdooUtil {

    public static String getString(Map<String, Object> map, String fieldName) {
        String res = "";
        if (map.get(fieldName) instanceof String) {
            res = (String) map.get(fieldName);
        }
        return res;
    }

    public static Integer getInteger(Map<String, Object> map, String fieldName) {
        Integer res = 0;
        if (map.get(fieldName) instanceof Integer) {
            res = (Integer) map.get(fieldName);
        }
        return res;
    }

    public static Double getDouble(Map<String, Object> map, String fieldName) {
        Double res = 0.0;
        if (map.get(fieldName) instanceof Double) {
            res = (Double) map.get(fieldName);
        }
        return res;
    }

    public static Boolean getBoolean(Map<String, Object> map, String fieldName) {
        Boolean res = false;
        if (map.get(fieldName) instanceof Boolean) {
            res = (Boolean) map.get(fieldName);
        }
        return res;
    }


    public static Float getFloat(Map<String, Object> map, String fieldName) {
        Float res = 0f;
        if (map.get(fieldName) instanceof Float) {
            res = (Float) map.get(fieldName);
        }
        return res;
    }
}

如果您有一个 Many2one 字段,您只能访问相关记录的 ID 和名称。您可以使用以下类来获取many2one记录的id和名称。

public class Many2One {
    private int id;
    private String name;

    public Many2One() {
    }

    public static Many2One getMany2One(Map<String, Object> stringObjectMap, String fieldName) {
        Integer fieldId = 0;
        String fieldValue = "";

        Many2One res = new Many2One();
        if (stringObjectMap.get(fieldName) instanceof Object[]) {
            Object[] field = (Object[]) stringObjectMap.get(fieldName);

            if (field.length > 0) {
                fieldId = (Integer) field[0];
                fieldValue = (String) field[1];
            }
        }

        res.id = fieldId;
        res.name = fieldValue;

        return res;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

Many2One 类的使用示例

    String partner_name= Many2One.getMany2One((Map<String, Object>) object, "partner_id").getName();
    int partner_id= Many2One.getMany2One((Map<String, Object>) object, "partner_id").getId();

对于其他剩余的 CRUD 方法,您可以通过阅读 Odoo Web Service API 文档轻松找到它们的工作方式。

我希望这能给你一些见解。


2
投票

这只是从 odoo 访问联系人/合作伙伴的示例:

#!/usr/bin/env python

import csv
from xmlrpclib import ServerProxy

SERVER = 'http://localhost:8069'
DATABASE = 'testcompany'
USERNAME = 'admin'
PASSWORD = 'password'

FILE_PATH = 'ODOO_clientsMain2_test.csv'

server = ServerProxy('http://localhost:8069/xmlrpc/common')
user_id = server.login(DATABASE, USERNAME, PASSWORD)

server = ServerProxy('http://localhost:8069/xmlrpc/object')

def search(list, key):
    for item in list:
        return item[key]

reader = csv.reader(open(FILE_PATH,'rb'))

for row in reader:
    #print row
    partner_template = {
        'name': row[0],
        #'company_id': row[1],
    }
    if row[2] is not None and row[2]<>'':
        partner_template.update({'email': row[2]})
    if row[5] is not None and row[5]<>'':
        partner_template.update({'tin': row[5]})
    if row[6] is not None and row[6]<>'':
        partner_template.update({'ref': row[6]})
    if row[8] is not None and row[8]<>'':
        partner_template.update({'phone': row[8]})
    if row[9] is not None and row[9]<>'':
        partner_template.update({'mobile': row[9]})

    print partner_template

    partner_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'create', [partner_template])

    #create External ID

    external_ids = {
       'model': 'res.partner',
       'name': row[11],
       'res_id': partner_id,
    }
    external_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'ir.model.data', 'create', [external_ids])

    # update related fields

    if row[7] is not None and row[7]<>'':
        #look up and update payment term

        payment_term_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'account.payment.term', 'search_read', [[['name','=',row[7]],['active', '=', True]]],{'fields': ['id'], 'limit': 1})
        if payment_term_id is not None:
            id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'write', [[partner_id],{'property_payment_term': search(payment_term_id,'id')}])

    if row[10] is not None and row[10]<>'':
        #look up and update pricelist

        pricelist_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'product.pricelist', 'search_read', [[['name','=',row[10]],['active', '=', True]]],{'fields': ['id'], 'limit': 1})

        if pricelist_id is not None:
            id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'write', [[partner_id],{'property_product_pricelist': search(pricelist_id,'id')}])

1
投票

如果您从stretch创建应用程序并且Odoo只需要Android API,这里是开源APIhttps://github.com/oogbox/odoo-mobile-api(Odoo android api)

要在android中使用,首先将以下依赖项添加到您的应用程序级别

build.gradle

compile 'com.oogbox.api:odoo:1.0.0'

文档:https://github.com/oogbox/odoo-mobile-api#getting-started

谢谢


0
投票

我当然愿意! 根据 OdooExternal Api wep page,按照以下步骤操作: 1-实现 XML-RPC 库

//odoo connect
    implementation("org.apache.xmlrpc:xmlrpc-client:3.1.2")

2- 通过验证您的登录来获取“uid”,如下所示:

private void Login() {
        String username = "admin",
                password = "admin",
                url="https://yourCompany.odoo.com",
                db="db_name";
        try {
            common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
            ExecutorService service = Executors.newSingleThreadExecutor();
            Handler handler = new Handler(Looper.getMainLooper());
            service.execute(() -> {
                try {
                    //client.execute(common_config, "version", Collections.emptyList()); // test connection
                    
                    int uid = client.execute(common_config, "authenticate",
                            asList(db, username, password, emptyMap()));
                    // HERE WE HAVE uid 
                } catch (XmlRpcException e) {
                    handler.post(() -> {
                        // show data on layout here
                    });
                }
            });
        } catch (MalformedURLException e) {
            // url error
        }

    }

3- 在调用方法时使用获取的“uid”,例如

try {
            final XmlRpcClient models = new XmlRpcClient() {{
                setConfig(new XmlRpcClientConfigImpl() {{
                    setServerURL(new URL(String.format("%s/xmlrpc/2/object", url)));
                }});
            }};
            ExecutorService service = Executors.newSingleThreadExecutor();
            Handler handler = new Handler(Looper.getMainLooper());
            service.execute(() -> {
                try {
                    List s = asList((Object[]) models.execute("execute_kw", asList(
                            db, uid, password,
                            var, "search_read",
                            emptyList(),
                            new HashMap() {{
                                put("fields", asList(
                                        "subscriber_id", "meter_number", "prev_reading"));
                               
                             put("limit", 5);
                            }}
                    )));
                } catch (Exception e) {
                    //
                }
            });
        } catch (MalformedURLException e) {
            // invalid url
        }

现在看看其他方法! 这里

© www.soinside.com 2019 - 2024. All rights reserved.