Help

Welcome!

This community is for professionals and enthusiasts of our products and services.
Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

0

How to get all invoice data for specific invoice with one request?

Avatar
Tim Thickhorn

Hello,

I hope this is the right place to be asking this…

I'm trying to get invoice data from Odoo with XMLRPC Client.

I was successful at getting invoice data by reading account.invoice with invoice id as parameter, but I soon noticed that I didn't get all the data I needed. For example payment term contained payment term id, not the actual days value. I know that I can get the payment term value by reading account.payment.term.line with payment term id as a parameter, but I was thinking if there is a way to get all the data with single request?

This is how I'm executing requests:

            $connecion = new xmlrpc_client('https://odoo.example.com'. '/xmlrpc/object');

            $c_msg = new xmlrpcmsg('execute');
            $c_msg->addParam(new xmlrpcval('database', "string"));
            $c_msg->addParam(new xmlrpcval('1234', "int"));
            $c_msg->addParam(new xmlrpcval('password', "string"));
            $c_msg->addParam(new xmlrpcval('account.invoice', "string"));
            $c_msg->addParam(new xmlrpcval('read', "string"));
            $c_msg->addParam(new xmlrpcval($response->value()->scalarval(), "array")); // Invoice Ids from previous request

            $c_response = $connecion->send($c_msg);


Thanks :)
Avatar
Discard
1 Answer
0
Avatar
David Tran
Best Answer

I don't know about xmlrpc_client library that you are using. But ripcord can make life easier.

Check this out: https://www.odoo.com/documentation/8.0/api_integration.html

Here is a simple class that I once wrote for a client a few months ago. I am sharing with you for your reference

<?php

/**
 * @category	Plugins
 * @package plg_odooconnector Odoo Connector Plugin
 * @copyright Copyright (C) 2015 T.V.T Marine Automation (aka TVTMA). All rights reserved.
 * @license http://www.gnu.org/licences GNU/GPL version 2 or later; see LICENSE.txt
 * @author url: http://ma.tvtmarine.com
 * @author TVTMA support@ma.tvtmarine.com
 */
// no direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Odoo object class which is used to call methods of odoo models via the execute_kw RPC function.
 *
 *
 * @since 1.0
 */
class OdooObj
{

        protected $conn = null;
        protected $obj_url = '';
        protected $common_url = '';
        protected $db = '';
        protected $username = '';
        protected $password = '';
        protected $uid = 0;

        /**
         *
         * @var OdooCommon
         */
        protected $odoocommon = null;

        /**
         * Store OdooObj instances
         * @var array
         */
        private static $instance = [];

        /**
         * Constructor
         *
         * @param string $obj_url the url to access Odoo. The value for version 8 is http(s)://odoodomain.com/xmlrpc/2/object where odoodomain.com is the domain of the Odoo system
         * @param string $common_url the url to access Odoo. The value for version 8 is http(s)://odoodomain.com/xmlrpc/2/common where odoodomain.com is the domain of the Odoo system
         * @param string $db the name of the Odoo database
         * @param string $username the name of the user to access the Odoo
         * @param string $password the password of the user to access the Odoo
         *
         * @return void
         *
         * @since 1.0
         */
        public function __construct($obj_url, $common_url, $db, $username, $password)
        {
                $this->obj_url = $obj_url;
                $this->common_url = $common_url;
                $this->db = $db;
                $this->username = $username;
                $this->password = $password;
                $this->conn = ripcord::client($this->obj_url);
                $this->odoocommon = OdooCommon::getInstance($this->common_url);

                $hash = JApplicationHelper::getHash($this->obj_url . $this->common_url . $this->db . $this->username . $this->password);
                static::$instance[$hash] = $this;
        }

        /**
         * Static method to get an OdooObj object. This method will return the previousely created object (instead of creating a new one) if the combination of $obj_url, $common_url, $db, $username, $password is unchanged.
         *
         * @param string $obj_url the url to access Odoo. The value for version 8 is http(s)://odoodomain.com/xmlrpc/2/object where odoodomain.com is the domain of the Odoo system
         * @param string $common_url the url to access Odoo. The value for version 8 is http(s)://odoodomain.com/xmlrpc/2/common where odoodomain.com is the domain of the Odoo system
         * @param string $db the name of the Odoo database
         * @param string $username the name of the user to access the Odoo
         * @param string $password the password of the user to access the Odoo
         *
         * @return OdooObj
         */
        public static function getInstance($obj_url, $common_url, $db, $username, $password)
        {
                $hash = JApplicationHelper::getHash($obj_url . $common_url . $db . $username . $password);

                if (!isset(static::$instance[$hash]))
                {
                        static::$instance[$hash] = new OdooObj($obj_url, $common_url, $db, $username, $password);
                }
                return static::$instance[$hash];
        }

        /**
         * The wrapper for Odoo's execute_kw method. This help avoid passing $db and $uid and $password everytime call the Odoo's execute_kw method
         *
         * @param mixed $arg arguments to pass to the func_get_args() inside the method
         *
         * @return mixed the return value of the callback, or FALSE on error
         *
         * @since 1.0
         */
        protected function execute_kw($arg)
        {
                $params = func_get_args($arg);
                array_unshift($params, $this->db, $this->getUid(), $this->password);
                return call_user_func_array([$this->conn, 'execute_kw'], $params);
        }

        /**
         * Method to check if the user has access rights to the model
         *
         * @param string $model the Odoo model to check (e.g. res.partner, account.invoice, etc)
         * @param string $operation an access operation to check, i.e. 'read' | 'write' | 'create' | unlink
         * @param $raise_exception pass false to get a true/false result rather than true/error. Otherwise pass true. Default value is false.
         *
         * @return boolean return true if the user has rights of $access_actions to the $model_to_check, otherwise return false
         *
         * @since 1.0
         */
        public function checkAccessRights($model, $operation, $raise_exception = false)
        {
                return $this->execute_kw($model, 'check_access_rights', [$operation], array('raise_exception' => $raise_exception));
        }

        /**
         * Method to list and filter records of the passed model
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param array $domain_filter default value is an empty array
         *
         * a sample input for instance:
         *
         *       array(
         *
         *            array('is_company', '=', true),
         *
         *            array('customer', '=', true)
         *
         *       )
         *
         * @param int $offset retrieve records starting from the passed offset
         * @param int $limit limit number of returned records
         *
         * @return array
         *
         * @since 1.0
         */
        public function search($model, $domain_filter = [], $offset = 0, $limit = 0)
        {
                $filter = [];
                if ($offset > 0)
                {
                        $filter['offset'] = $offset;
                }
                if ($limit > 0)
                {
                        $filter['limit'] = $limit;
                }
                return $this->execute_kw($model, 'search', [$domain_filter], $filter);
        }

        /**
         * Method to retrieve the number of records matching the query
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param array $domain_filter default value is an empty array
         *
         * a sample input for instance:
         *
         *       array(
         *
         *            array('is_company', '=', true),
         *
         *            array('customer', '=', true)
         *
         *       )
         *
         * @return int return number of records
         */
        public function count($model, $domain_filter = [])
        {
                return $this->execute_kw($model, 'search_count', [$domain_filter]);
        }

        /**
         * Method to retrive data of a model
         *
         * @param string $model e.g. res.partner, account.invoice, etc
         * @param int|array $ids the id(s) of the record to retrieve
         * @param array $fields an OPTIONAL list of fields to fetch. If not passed or empty, the method will fetch all the fields the current user can read, which tends to be a huge amount.
         *
         * @return array the list of associcated array records (each record is also in array format).
         *
         * NOTE: even if the id field is not requested, it is always returned
         *
         * @since 1.0
         */
        public function read($model, $ids, $fields = [])
        {
                if (!is_array($ids))
                {
                        $ids = (array) $ids;
                }

                if (!empty($fields))
                {
                        $fields = ['fields' => $fields];
                        return $this->execute_kw($model, 'read', [$ids], $fields);
                } else
                {
                        return $this->execute_kw($model, 'read', [$ids]);
                }
        }

        /**
         * Method to inspect a model’s fields and check which ones seem to be of interest
         *
         * NOTE: If no $attribute_filter is passed, this method returns a great amount of meta-information (it is also used by client programs) it should be filtered before printing, the most interesting items for a human user are string (the field’s label), help (a help text if available) and type (to know which values to expect, or to send when updating a record)
         *
         * @param string $model an OPTIONAL list of fields to inspect. If not passed or empty, the method will fetch all the available fields of the model
         * @param array $attribute_filter If passed, only these attributes will be returned within the field's metadata. Possible input is similar to array('string', 'help', 'type')
         *
         * @return array Return an array of fields (each field contains an array of attributes)
         *
         * @since 1.0
         */
        public function getFields($model, $attribute_filter = [])
        {
                if (!empty($attribute_filter))
                {
                        $attribute_filter = ['attributes' => $attribute_filter];
                }
                return $this->execute_kw($model, 'fields_get', [], $attribute_filter);
        }

        /**
         * This method is a shortcut which as its name notes is equivalent to a search() followed by a read(), but avoids having to perform two requests and keep ids around
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param array $domain_filter default value is an empty array
         *
         * a sample input for instance:
         *
         *       array(
         *
         *            array('is_company', '=', true),
         *
         *            array('customer', '=', true)
         *
         *       )
         *
         * @param array $fields an OPTIONAL list of fields to fetch. If not passed or empty, the method will fetch all the fields the current user can read, which tends to be a huge amount.
         * @param int $offset retrieve records starting from the passed offset
         * @param int $limit limit number of returned records
         *
         * @return array the list of associcated array records (each record is also in array format).
         *
         * NOTE: even if the id field is not requested, it is always returned
         *
         * @since 1.0
         */
        public function search_read($model, $domain_filter = [], $fields = [], $offset = 0, $limit = 0)
        {
                // array('fields'=>array('name', 'country_id', 'comment'), 'limit'=>5));
                $filter = [];
                if (!empty($fields))
                {
                        $filter['fields'] = $fields;
                }

                if ($offset > 0)
                {
                        $filter['offset'] = $offset;
                }
                if ($limit > 0)
                {
                        $filter['limit'] = $limit;
                }

                return $this->execute_kw($model, 'search_read', [$domain_filter], $filter);
        }

        /**
         * The method will create a single record and return its database identifier.
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param array $data mapping of fields to values, used to initialize the record. For any field which has a default value and is not set through the mapping argument, the default value will be used.
         *
         * NOTE: while most value types are what would be expected (integer for Integer, string for Char or Text),
         *
         * Date, Datetime and Binary fields use string values
         *
         * One2many and Many2many use a special command protocol detailed in the documentation to the write method.
         *
         * @return mixed Return the database identifier of the newly created record
         *
         * @tutorial https://www.odoo.com/documentation/8.0/api_integration.html
         * @tutorial https://www.odoo.com/documentation/8.0/reference/orm.html#openerp.models.Model.write
         *
         *
         * @since 1.0
         */
        public function create($model, $data)
        {
                return $this->execute_kw($model, 'create', [$data]);
        }

        /**
         * The method will update a single record or multiple records.
         *
         * NOTE: Multiple records can be updated simultanously, but they will all get the same values for the fields being set. It is not currently possible to perform “computed” updates (where the value being set depends on an existing value of a record).
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param array $data an array of array mapping of fields to values, used to initialize the record. For any field which has a default value and is not set through the mapping argument, the default value will be used.
         *
         * NOTE: while most value types are what would be expected (integer for Integer, string for Char or Text),
         *
         * Date, Datetime and Binary fields use string values
         *
         * One2many and Many2many use a special command protocol detailed in the documentation to the write method.
         *
         * @return boolean Description
         *
         * @example $data here is an example of possible value for the input $data: array(array($id), array('name'=>"Newer partner")));
         *
         * @since 1.0
         */
        public function write($model, $data)
        {
                return $this->execute_kw($model, 'write', $data);
        }

        /**
         * Method to delete a record
         *
         * @param string $model e.g. res.parner, account.invoice, etc
         * @param int|array $ids the id(s) of the record(s) to delete
         *
         * @return boolean True on success, otherwise return false
         *
         * @since 1.0
         */
        public function unlink($model, $ids)
        {
                if (!is_array($ids))
                {
                        $ids = (array) $ids;
                }

                return $this->execute_kw($model, 'unlink', [$ids]);
        }

        /**
         * Method to exec a work flow
         *
         * @param type $model
         * @param type $signal
         * @param type $id
         * @return type
         */
        public function exec_workflow($model, $signal, $id)
        {
                return $this->conn->exec_workflow($this->db, $this->getUid(), $this->password, $model, $signal, $id);
        }

        /**
         * Method to get the id of the current user
         *
         * @return int the id of the current user
         *
         * @since 1.0
         */
        public function getUid()
        {
                if (!$this->uid)
                {
                        $this->uid = $this->odoocommon->authenticate($this->db, $this->username, $this->password);
                }
                return $this->uid;
        }

        /**
         * Method to get Odoo's version info
         *
         * @return array return an array containing Odoo's version info
         *
         * [
         * server_serie => (string) 8.0,
         *
         * server_version_info => [(int) 8, (int) 0, (int) 0, (string) final, (int) 0],
         *
         * server_version => (string) 8.0,
         *
         * protocol_version => (int) 1
         * ]
         *
         * @since 1.0
         *
         */
        public function getVersion()
        {
                return $this->odoocommon->getVersion();
        }

}
Avatar
Discard

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!