ThinkPHP调用odoo8.0Web服务,以下代码:
namespace Home\Controller;
use Think\Controller;
use Org\Ripcord\Ripcord;//https://code.google.com/p/ripcord/
class ApiController extends Controller {
public $url;
public $db;
public $username;
public $password;
public $models;
public $common;
function __construct() {
self::_initialize ();
}
function _initialize() {
// $url = 'https://demo.odoo.com';
// $db = 'test';
// $username = "admin";
// $password = "admin";
// 从官方获取一个测试账号与数据库
$info = Ripcord::client ( 'https://demo.odoo.com/start' )->start ();
list ( $this->url, $this->db, $this->username, $this->password ) = array (
$info ['host'],
$info ['database'],
$info ['user'],
$info ['password']
);
$this->common = Ripcord::client ( "$this->url/xmlrpc/2/common" );
// Logging in
$uid = $this->common->authenticate ( $this->db, $this->username, $this->password, array () );
define ( UID, $uid );
$this->models = Ripcord::client ( "$this->url/xmlrpc/2/object" );
}
/**
* 获取版本
*/
public function version() {
$data = $common->version ();
dump ( $common );
dump ( $data );
}
/**
* 检测权限
*/
public function check_access_rights() {
// 检测对象是否有权限
$data = self::execute_kw ( 'res.partner', 'check_access_rights', array (
'read'
), array (
'raise_exception' => false
) );
dump ( $data );
}
public function search() {
// List records
$data = self::execute_kw ( 'res.partner', 'search', array (
array (
array (
'is_company',
'=',
true
),
array (
'customer',
'=',
true
)
)
) );
dump ( $data );
}
public function search_page() {
// Pagination
$data = self::execute_kw ( 'res.partner', 'search', array (
array (
array (
'is_company',
'=',
true
),
array (
'customer',
'=',
true
)
)
), array (
'offset' => 10,
'limit' => 5
) );
dump ( $data );
}
public function search_count() {
// Count records
$data = self::execute_kw ( 'res.partner', 'search_count', array (
array (
array (
'is_company',
'=',
true
),
array (
'customer',
'=',
true
)
)
) );
dump ( $data );
}
public function read_records() {
// Read records
$ids = self::execute_kw ( 'res.partner', 'search', array (
array (
array (
'is_company',
'=',
true
),
array (
'customer',
'=',
true
)
)
), array (
'limit' => 1
) );
$records = self::execute_kw ( 'res.partner', 'read', array (
$ids
) );
// count the number of fields fetched by default
$data = count ( $records [0] );
dump ( $data );
}
public function read_field() {
// 只显示需要的字段
$data = self::execute_kw ( 'res.partner', 'read', array (
$ids
), array (
'fields' => array (
'name',
'country_id',
'comment'
)
) );
dump ( $data );
}
public function record_attr() {
// Listing record fields
$data = self::execute_kw ( 'res.partner', 'fields_get', array (), array (
'attributes' => array (
'string',
'help',
'type'
)
) );
dump ( $data );
}
public function search_read() {
// Search and read
$data = self::execute_kw ( 'res.partner', 'search_read', array (
array (
array (
'is_company',
'=',
true
),
array (
'customer',
'=',
true
)
)
), array (
'fields' => array (
'name',
'country_id',
'comment'
),
'limit' => 5
) );
dump ( $data );
}
public function create() {
// Create records
$id = self::execute_kw ( 'res.partner', 'create', array (
array (
'name' => "New Partner"
)
) );
dump ( $id );
}
/**
* 更新记录
*
* @param unknown $id
*/
public function update($id) {
// Update records
self::execute_kw ( 'res.partner', 'write', array (
array (
$id
),
array (
'name' => "Newer partner"
)
) );
}
public function name_get($id) {
// get record name after having changed it
$data = self::execute_kw ( 'res.partner', 'name_get', array (
array (
$id
)
) );
dump ( $data );
}
public function delete($id) {
// Delete records
self::execute_kw ( 'res.partner', 'unlink', array (
array (
$id
)
) );
// check if the deleted record is still in the database
$data = self::execute_kw ( 'res.partner', 'search', array (
array (
array (
'id',
'=',
$id
)
)
) );
dump ( $data );
}
/**
* Available reports can be listed by searching the ir.actions.report.xml model, fields of interest being
* model
* the model on which the report applies, can be used to look for available reports on a specific model
* name
* human-readable report name
* report_name
* the technical name of the report, used to print it
* Reports can be printed over RPC with the following information:
* the name of the report (report_name)
* the ids of the records to include in the report
*/
public function report() {
header ( "Pragma: public" ); // required
header ( "Expires: 0" );
header ( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header ( "Cache-Control: private", false ); // required for certain browsers
header ( "Content-Type: application/pdf" );
// header("Content-Disposition: attachment; filename=\"".basename($fullPath)."\";" );
header ( "Content-Transfer-Encoding: binary" );
// header("Content-Length: ".$fsize);
// Report printing
$invoice_ids = self::execute_kw ( 'account.invoice', 'search', array (
array (
array (
'type',
'=',
'out_invoice'
),
array (
'state',
'=',
'open'
)
)
) );
$report = ripcord::client ( "$this->url/xmlrpc/2/report" );
$result = $report->render_report ( $this->db, UID, $this->password, 'account.report_invoice', $invoice_ids );
$report_data = base64_decode ( $result ['result'] );
echo $report_data;
}
/**
* While we previously used fields_get() to query a model’s and have been using an arbitrary model from the start, Odoo stores most model metadata inside a few meta-models which allow both querying the system and altering models and fields (with some limitations) on the fly over XML-RPC.
* ir.model
*
* Provides informations about Odoo models themselves via its various fields
* name
* a human-readable description of the model
* model
* the name of each model in the system
* state
* whether the model was generated in Python code (base) or by creating an ir.model record (manual)
* field_id
* list of the model’s fields through a One2many to ir.model.fields
* view_ids
* One2many to the Views defined for the model
* access_ids
* One2many relation to the Access Control set on the model
* ir.model can be used to
* query the system for installed models (as a precondition to operations on the model or to explore the system’s content)
* get information about a specific model (generally by listing the fields associated with it)
* create new models dynamically over RPC
* Warning
* “custom” model names must start with x_
* the state must be provided and manual, otherwise the model will not be loaded
* it is not possible to add new methods to a custom model, only fields
*/
public function inspection() {
// Inspection and introspection
self::execute_kw ( 'ir.model', 'create', array (
array (
'name' => "Custom Model",
'model' => 'x_custom_model',
'state' => 'manual'
)
) );
$data = self::execute_kw ( 'x_custom_model', 'fields_get', array (), array (
'attributes' => array (
'string',
'help',
'type'
)
) );
dump ( $data );
}
/**
* ir.model.fields
*
* Provides informations about the fields of Odoo models and allows adding custom fields without using Python code
* model_id
* Many2one to ir.model to which the field belongs
* name
* the field’s technical name (used in read or write)
* field_description
* the field’s user-readable label (e.g. string in fields_get)
* ttype
* the type of field to create
* state
* whether the field was created via Python code (base) or via ir.model.fields (manual)
* required, readonly, translate
* enables the corresponding flag on the field
* groups
* field-level access control, a Many2many to res.groups
* selection, size, on_delete, relation, relation_field, domain
* type-specific properties and customizations, see the fields documentation for details
* Like custom models, only new fields created with state="manual" are activated as actual fields on the model.
* computed fields can not be added via ir.model.fields, some field meta-information (defaults, onchange) can not be set either
*/
public function custom_model() {
//
$id = self::execute_kw ( 'ir.model', 'create', array (
array (
'name' => "Custom Model",
'model' => 'x_custom',
'state' => 'manual'
)
) );
self::execute_kw ( 'ir.model.fields', 'create', array (
array (
'model_id' => $id,
'name' => 'x_name',
'ttype' => 'char',
'state' => 'manual',
'required' => true
)
) );
$record_id = self::execute_kw ( 'x_custom', 'create', array (
array (
'x_name' => "test record"
)
) );
$data = self::execute_kw ( 'x_custom', 'read', array (
array (
$record_id
)
) );
dump ( $data );
}
/**
* Workflows can be moved along by sending them signals.
* Instead of using the top-level execute_kw,
* signals are sent using exec_workflow.Signals are sent to a specific record,
* and possibly trigger a transition on the workflow instance associated with the record.
*/
public function workflow() {
// Workflow manipulations
$client = self::execute_kw ( 'res.partner', 'search_read', array (
array (
array (
'customer',
'=',
true
)
)
), array (
'limit' => 1,
'fields' => array (
'property_account_receivable',
'property_payment_term',
'property_account_position'
)
) )[0];
$invoice_id = self::execute_kw ( 'account.invoice', 'create', array (
array (
'partner_id' => $client ['id'],
'account_id' => $client ['property_account_receivable'] [0],
'invoice_line' => array (
array (
0,
false,
array (
'name' => "AAA"
)
)
)
)
) );
$this->models->exec_workflow ( $this->db, $this->uid, $this->password, 'account.invoice', 'invoice_open', $invoice_id );
}
public function index() {
dump ( $this );
}
public function execute_kw($objName, $cmd, $args) {
$data = $this->models->execute_kw ( $this->db, UID, $this->password, $objName, $cmd, $args );
return $data;
}
}