flux-se/odoo-api-client

Odoo API 客户端库(消费 JSON 或 XML-RPC API)

v1.1.1 2024-06-08 16:27 UTC

This package is auto-updated.

Last update: 2024-08-27 15:04:53 UTC


README

Latest Version on Packagist Software License Build Status Quality Score

Odoo API 客户端

Odoo(原 OpenERP)是比利时的一款企业管理软件套件(PGI):[https://www.odoo.com/](https://www.odoo.com/).

此库允许通过 Odoo JSON-RPC 或 XML-RPC API 进行通信。有关文档,请参阅此处(对于 XML-RPC,没有 JSON-RPC):https://www.odoo.com/documentation/master/developer/reference/external_api.html

此库将允许您

  • 根据您自己的 Odoo 数据库中的信息生成 PHP 模型类,以简化对 API 的调用
  • 通过 JSON-RPC 或 XML-RPC API 向您的 Odoo 实例发送请求
  • 发送类似于 Ripcord 的原始请求,但使用更新的库,例如
    • php-http/httplug 用于进行 HTTP 请求
    • symfony/serializer 用于处理 JSON/XML-RPC 格式,并将结果数组转换为专用对象类。

安装

Composer

使用 Composer 安装

composer require \
  flux-se/odoo-api-client \
  php-http/guzzle7-adapter \
  http-interop/http-factory-guzzle

php-http/guzzle7-adapterhttp-interop/http-factory-guzzle 是 2 个可选要求,可从 php-http/client-implementationpsr/http-factory-implementation 中选择

对象模型生成

首先收集所需的凭证和数据库信息,详情请参阅此处.

根据您的 Odoo 实例,可用的对象模型将不同,这就是为什么此库允许您使用此 CLI 命令生成模型类

此命令使用环境变量来猜测凭证和数据库信息,您可以使用这些环境变量来全局设置凭证

  • ODOO_API_HOST
  • ODOO_API_DATABASE
  • ODOO_API_USERNAME
  • ODOO_API_PASSWORD
#> vendor/bin/odoo-model-classes-generator --help
Usage:
  vendor/bin/odoo-model-classes-generator [options] [--] <basePath> <baseNamespace>

Arguments:
  basePath                             The path where classes will be generated (ex: ./src/OdooModel/Object)
  baseNamespace                        The base namespace of the generated classes (ex: "App\OdooModel\Object")

Options:
      --host[=HOST]                    Your Odoo base host (default: http://localhost:8069) [default: "http://localhost:8069"]
      --database[=DATABASE]            Your Odoo database name (default: odoo-master) [default: "odoo-master"]
      --username[=USERNAME]            Your Odoo account username. (default: admin) [default: "admin"]
      --password[=PASSWORD]            Your Odoo account password or API key (since Odoo v14, default: admin) [default: "admin"]
      --only-model[=ONLY-MODEL]        Filter the model list with the model you will set in this option. (multiple values allowed)
      --exclude-model[=EXCLUDE-MODEL]  Filter the model list excluding the model you will set in this option. (multiple values allowed)
  -h, --help                           Display help for the given command. When no command is given display help for the vendor/bin/odoo-model-classes-generator command
  -q, --quiet                          Do not output any message
  -V, --version                        Display this application version
      --ansi                           Force ANSI output
      --no-ansi                        Disable ANSI output
  -n, --no-interaction                 Do not ask any interactive question
  -v|vv|vvv, --verbose                 Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Example :
  ./vendor/bin/odoo-model-classes-generator \
      --host http://localhost:8069 \
      --database odoo-master \
      --username admin \
      --password admin \
      ./src/OdooModel/Object \
      "App\\OdooModel\\Object"

简介

本章将描述两个 Odoo API 的工作原理。

JSON-RPC(点击此处查看详细信息)

JSON-RPC

Odoo JSON-RPC API 提供了 1 个主要端点 /jsonrpc。请求体的负载是一个包含特定数据的 JSON 对象

{
     "jsonrpc": "2.0",
     "method": 'call',
     "params": {
        {
           "service": 'common',
           "method": 'login',
           "args": [
              'database',
              'username',
              'password'
           ]
        }
     },
     "id": 123456890
 }

服务参数可以设置为以下 3 个值

  • db 允许管理 PostgreSQL 数据库
  • common 允许验证用户或获取有关 Odoo 安装的信息
  • object 允许操作所有公开的 API 模型

此库帮助您使用这些端点,使用 ext-jsonHttPlug,**它还允许您使用所有已安装的 Odoo 模型的 PHP 类表示形式来消费 Odoo API**。

XML-RPC(点击此处查看详细信息)

XML-RPC

Odoo XML-RPC API 提供了 3 个主要端点

  • /xmlrpc/2/db 允许管理 PostgreSQL 数据库
  • /xmlrpc/2/common 允许验证用户或获取有关 Odoo 安装的信息
  • /xmlrpc/2/object 允许操作所有公开的 API 模型

此库帮助您使用这些端点,使用 ext-xmlrpcHttPlug,**它还允许您使用所有已安装的 Odoo 模型的 PHP 类表示形式来消费 Odoo API**。

认证不是标准的(与其他API相比),您的用户名和密码将在调用/xmlrpc/2/common时使用XML-RPC方法authenticate(或login)来返回您的Odoo用户ID(uid)。此uid、您的密码以及您的Odoo数据库名称是调用/xmlrpc/2/object端点时每个请求调用的必需项。

使用示例

使用此库,您将能够使用两种方式来消费Odoo XML-RPC API

  1. 使用数组
  2. 使用对象模型类

使用数组

列出您的第一个合作伙伴(联系人)

$loader = require_once( __DIR__.'/vendor/autoload.php');

use FluxSE\OdooApiClient\Builder\OdooApiClientBuilder;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\Options\SearchReadOptions;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\RecordListOperations;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\Arguments\Criterion;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\Arguments\SearchDomains;

$host = 'https://myapp.odoo.com';
$database = 'myapp';
$username = 'myemail@mydomain.tld';
$password = 'myOdooUserApiKey';

// 1 - instantiate the Odoo API client builder
$odooApiClientBuilder = new OdooApiClientBuilder($host);

// 2 - service allowing to query Odoo API using `execute_kw` method
$recordListOperations = $odooApiClientBuilder->buildExecuteKwOperations(
    RecordListOperations::class,
    $database,
    $username,
    $password
);

// 3.1 - Helper class to set parameters to your request
$searchDomains = new SearchDomains();
$searchDomains->addCriterion(Criterion::equal('is_company', true));
// will be translated to : [['is_company', '=', true]]

// 3.2 - Helper class to set options to your request
$searchReadOptions = new SearchReadOptions();
$searchReadOptions->setLimit(1);
$searchReadOptions->addField('name');

// 3.3 - Search for the first Partner being a company and only return its name 
$partners = $recordListOperations->search_read('res.partner', $searchDomains, $searchReadOptions);

dump($partners);

/**

array:1 [
  0 => array:2 [
    "id" => 1
    "name" => "My Partner"
  ]
]

**/

默认情况下,将使用JSON-RPC API,如果您想使用XML-RPC,请创建一个类似这样的Odoo Api客户端构建器

use FluxSE\OdooApiClient\Api\OdooApiRequestMakerInterface;
use FluxSE\OdooApiClient\Builder\OdooApiClientBuilder;

$odooApiClientBuilder = new OdooApiClientBuilder(
  $host,
  OdooApiRequestMakerInterface::BASE_XMLRPC_PATH
);

使用对象模型

首先,您可以根据您拥有的Odoo实例生成类,例如

bin/odoo-model-classes-generator \
      "./src/Odoo/Model/Object" \
      "App\\Odoo\\Model\\Object" \
      --only-model=res.partner

💡 在这里我们只生成一个类,但您也可以生成所有类,排除其中一些(请参见此处的信息)。

$loader = require_once( __DIR__.'/vendor/autoload.php');

use App\Odoo\Model\Object\Res\Partner;
use FluxSE\OdooApiClient\Builder\OdooApiClientBuilder;
use FluxSE\OdooApiClient\Manager\ModelListManager;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\RecordListOperations;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\Arguments\Criterion;
use FluxSE\OdooApiClient\Operations\Object\ExecuteKw\Arguments\SearchDomains;

$host = 'https://myapp.odoo.com';
$database = 'myapp';
$username = 'myemail@mydomain.tld';
$password = 'myOdooUserApiKey';

// 1 - Instantiate the Odoo API client builder 
$odooApiClientBuilder = new OdooApiClientBuilder($host);

// 2 - Service allowing to query Odoo API using `execute_kw` method
$recordListOperations = $odooApiClientBuilder->buildExecuteKwOperations(
    RecordListOperations::class,
    $database,
    $username,
    $password
);

// 3 - Service allowing to return object instead of raw array data
$modelListManager = new ModelListManager(
    $odooApiClientBuilder->buildSerializer(),
    $recordListOperations
);

// 4.1- Helper class to set parameters to your request
$searchDomains = new SearchDomains();
$searchDomains->addCriterion(Criterion::equal('is_company', true));
// will be translated to : [['is_company', '=', true]]

// 4.2 - Search for the first Partner being a company 
$partner = $modelListManager->findOneBy(Partner::class, $searchDomains);

dump($partner);

/**
App\Odoo\Model\Object\Res\Partner
{#1234
  #name: "My test company"
  #date: DateTimeImmutable @1577880060 {#1234
    date: 2020-01-01 12:01:00.123456 UTC (+00:00)
  }
  #is_company: true

  ...
  
  #id: 1
  #display_name: "My test company"
  #__last_update: DateTimeImmutable @1577923260 {#5678
    date: 2020-01-02 00:01:00.123456 UTC (+00:00)
  }
}
**/

已知问题

  • 由于Odoo v16,一些新字段可能会产生500错误,我在遇到错误时尝试创建相关的问题,您可以在此处找到相关的问题。

开发

使用Docker

docker run -d -p 5432:5432 -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres
docker run --rm --pull always -p 8069:8069 --name odoo -e "HOST=host.docker.internal" -t odoo:14 -- --database odoo-master --init "l10n_fr,account_accountant"

当出现此日志行时,服务器已完全准备好使用(Odoo v13可能需要比上一个版本更长的时间才能到达此行)

2030-01-01 00:00:00,000 1 INFO odoo-master odoo.modules.loading: Modules loaded.

根据Docker Odoo实例生成模型类

此脚本将使用环境变量来收集有关您要针对的Odoo实例的信息(请参见此处的信息)。

bin/odoo-model-classes-generator \
      "./tests/TestModel/Object" \
      "Tests\\FluxSE\\OdooApiClient\\TestModel\\Object"

使用您自己的Odoo实例生成的类测试代码

vendor/bin/ecs check tests
vendor/bin/psalm
vendor/bin/phpunit