Note, this file used in tests, so it may contain additional test related logic.
# import extensions first (they modify Session and Client classes)
from openerp_proxy.ext.all import HField
# Enable module_utils plugin
import openerp_proxy.plugins.module_utils
# Import Client and Session classes
from openerp_proxy import (Client,
Session)
For connection to Odoo Client class is used. Below is example of it's usage.
cl = Client('localhost') # connect to local instance of server
cl
login | None |
---|---|
Host | localhost |
Protocol | xml-rpc |
Port | 8069 |
Database | None |
Next we should check if our database is present on server. For this purpose we should use Odoo's database service, which could be accessed via Client.services.db. And if database does not exists, we can create it.
# check if our demo database exists
if 'openerp_proxy_test_db' not in cl.services.db:
# create demo database
cl.services.db.create_db('admin', 'openerp_proxy_test_db', demo=True, lang='en_US')
And now we can login to our database.
ldb = cl.login('openerp_proxy_test_db', 'admin', 'admin') # all this arguments could be passed directly to Client constructor.
# and let's look how it is displayed in IPython
ldb
login | admin |
---|---|
Host | localhost |
Protocol | xml-rpc |
Port | 8069 |
Database | openerp_proxy_test_db |
Note, that ldb
is new instance of Client class, but with login credential. it can be used to interact with object service (models, documents, logic, ...)
If You often need to connect to same databases, there are a Session class, which automaticaly save, most of your connections, made via Session.connect method in specified file.
# create session instance
session = Session('~/.openerp_proxy.local.json') # default file path is '~/.openerp_proxy.json'
And there are option You may be interested in. It is 'store_passwords', which automaticaly saves password You have used for connection.
session.option('store_passwords', True)
True
We used openerp_proxy.Client
class to create connection to database, so our session does not know anything about it. Let's add our connection to our session:
session.add_db(ldb)
session
Index | URL | Aliases |
---|---|---|
1 | xml-rpc://admin@localhost:8069/openerp_proxy_test_db | ldb |
And now we can get this connection from session by index, or by URL (look at the table above). But to simplify next connections, we may add aliase to this connection
session.aliase('ldb', ldb)
session
Index | URL | Aliases |
---|---|---|
1 | xml-rpc://admin@localhost:8069/openerp_proxy_test_db | ldb |
So, now, to get connection again we could just type session.ldb
.
Ok. initialization is done, and now we could save it.
session.save()
Let's now create new instance of session, and connect to created above database
session = Session('~/.openerp_proxy.local.json') # default file path is '~/.openerp_proxy.json'
ldb = session.ldb
ldb
login | admin |
---|---|
Host | localhost |
Protocol | xml-rpc |
Port | 8069 |
Database | openerp_proxy_test_db |
Our database is clean, for next code, we need to install sale
addon. For this, we have module_utils
plugin, out-of-the box, which simplyfies work with modules. To enable this plugin, we just need to import it, and then we will have it in ldb.plugins
property. This plugin was imported above.
This plugin extends ir.module.module
model from client side, adding simple methods: install
and upgrade
to it for shorter syntax. If You're interested for code, look here, it is very simple!
Also this plugin allows to acces any module registered in database, as attribute of plugin. All module attributes are prefixed with m_
. So to get access to sale
module we can use folowing syntax: ldb.plugins.module_utils.m_sale
.
So now, let's install sale
module. (Note that in most cases, IPython autocompletition work's fine)
ldb.plugins.module_utils.m_sale.install()
{'tag': 'reload', 'type': 'ir.actions.client'}
Congratulation! module was installed!
One more interesting method of this plugins is module_utils.update_module_list
method, which updates list of Odoo addons registered in database.
ldb.plugins.module_utils.update_module_list()
[58, 0]
To get list of registered models, just use registered_objects proerty of Client instance. It returns list of all registered models in database. For example:
ldb.registered_objects
Name | System Name | Description |
---|---|---|
Account | account.account | False |
Templates for Accounts | account.account.template | False |
Account Type | account.account.type | False |
account.addtmpl.wizard | account.addtmpl.wizard | Add one more account from the template. With the 'nocreate' option, some accounts may not be created. Use this to add them later. |
Account Aged Trial balance Report | account.aged.trial.balance | False |
Analytic Account | account.analytic.account | False |
Account Analytic Balance | account.analytic.balance | False |
Account Analytic Chart | account.analytic.chart | False |
Account Analytic Cost Ledger | account.analytic.cost.ledger | False |
Account Analytic Cost Ledger For Journal Report | account.analytic.cost.ledger.journal.report | False |
Account Analytic Inverted Balance | account.analytic.inverted.balance | False |
Analytic Journal | account.analytic.journal | False |
Account Analytic Journal | account.analytic.journal.report | False |
Analytic Line | account.analytic.line | False |
Automatic Reconcile | account.automatic.reconcile | False |
Trial Balance Report | account.balance.report | False |
account.bank.accounts.wizard | account.bank.accounts.wizard | False |
Bank Statement | account.bank.statement | False |
Bank Statement Line | account.bank.statement.line | False |
CashBox Line | account.cashbox.line | Cash Box Details |
Account Central Journal | account.central.journal | False |
Change Currency | account.change.currency | False |
Account chart | account.chart | For Chart of Accounts |
Templates for Account Chart | account.chart.template | False |
Account Common Account Report | account.common.account.report | False |
Account Common Journal Report | account.common.journal.report | False |
Account Common Partner Report | account.common.partner.report | False |
Account Common Report | account.common.report | False |
account.config.settings | account.config.settings | False |
Journal Items Analysis | account.entries.report | False |
Account Report | account.financial.report | False |
Fiscal Position | account.fiscal.position | False |
Accounts Fiscal Position | account.fiscal.position.account | False |
Template Account Fiscal Mapping | account.fiscal.position.account.template | False |
Taxes Fiscal Position | account.fiscal.position.tax | False |
Template Tax Fiscal Position | account.fiscal.position.tax.template | False |
Template for Fiscal Position | account.fiscal.position.template | False |
Fiscal Year | account.fiscalyear | False |
Fiscalyear Close | account.fiscalyear.close | Closes Account Fiscalyear and Generate Opening entries for New Fiscalyear |
Fiscalyear Close state | account.fiscalyear.close.state | Closes Account Fiscalyear |
Account General Journal | account.general.journal | False |
Accounting Report | accounting.report | False |
account.installer | account.installer | False |
Invoice | account.invoice | False |
Cancel the Selected Invoices | account.invoice.cancel | This wizard will cancel the all the selected invoices. If in the journal, the option allow cancelling entry is not selected then it will give warning message. |
Confirm the selected invoices | account.invoice.confirm | This wizard will confirm the all the selected draft invoices |
Invoice Line | account.invoice.line | False |
Invoice Refund | account.invoice.refund | Refunds invoice |
Invoices Statistics | account.invoice.report | False |
Invoice Tax | account.invoice.tax | False |
Journal | account.journal | False |
account.journal.cashbox.line | account.journal.cashbox.line | False |
Journal Period | account.journal.period | False |
Account Journal Select | account.journal.select | Account Journal Select |
Account Model | account.model | False |
Account Model Entries | account.model.line | False |
Account Entry | account.move | False |
Move bank reconcile | account.move.bank.reconcile | Bank Reconciliation |
Journal Items | account.move.line | False |
Account move line reconcile | account.move.line.reconcile | Account move line reconcile wizard, it checks for the write off the reconcile entry or directly reconcile. |
Move line reconcile select | account.move.line.reconcile.select | False |
Account move line reconcile (writeoff) | account.move.line.reconcile.writeoff | It opens the write off wizard form, in that user can define the journal, account, analytic account for reconcile |
Unreconciliation | account.move.line.unreconcile.select | False |
Account Reconciliation | account.move.reconcile | False |
Choose Fiscal Year | account.open.closed.fiscalyear | False |
Print Account Partner Balance | account.partner.balance | False |
Account Partner Ledger | account.partner.ledger | False |
Reconcilation Process partner by partner | account.partner.reconcile.process | False |
Payment Term | account.payment.term | False |
Payment Term Line | account.payment.term.line | False |
Account period | account.period | False |
period close | account.period.close | close period |
Account Print Journal | account.print.journal | False |
General Ledger Report | account.report.general.ledger | False |
account.sequence.fiscalyear | account.sequence.fiscalyear | False |
Entries by Statement from Invoices | account.statement.from.invoice.lines | Generate Entries by Statement from Invoices |
Account State Open | account.state.open | False |
Account Subscription | account.subscription | False |
Subscription Compute | account.subscription.generate | False |
Account Subscription Line | account.subscription.line | False |
Tax | account.tax | A tax object. Type: percent, fixed, none, code PERCENT: tax = price * amount FIXED: tax = price + amount NONE: no tax line CODE: execute python code. localcontext = {'price_unit':pu} return result in the context Ex: result=round(price_unit*0.21,4) |
Account tax chart | account.tax.chart | For Chart of taxes |
Tax Code | account.tax.code | A code for the tax object. This code is used for some tax declarations. |
Tax Code Template | account.tax.code.template | False |
Templates for Taxes | account.tax.template | False |
Treasury Analysis | account.treasury.report | False |
Account Unreconcile | account.unreconcile | False |
Account Unreconcile Reconcile | account.unreconcile.reconcile | False |
Use model | account.use.model | False |
Account Vat Declaration | account.vat.declaration | False |
Accounting Voucher | account.voucher | False |
Voucher Lines | account.voucher.line | False |
Analytic Entries Statistics | analytic.entries.report | False |
base.config.settings | base.config.settings | False |
base_import.import | base_import.import | False |
base_import.tests.models.char | base_import.tests.models.char | False |
base_import.tests.models.char.noreadonly | base_import.tests.models.char.noreadonly | False |
base_import.tests.models.char.readonly | base_import.tests.models.char.readonly | False |
base_import.tests.models.char.required | base_import.tests.models.char.required | False |
base_import.tests.models.char.states | base_import.tests.models.char.states | False |
base_import.tests.models.char.stillreadonly | base_import.tests.models.char.stillreadonly | False |
base_import.tests.models.m2o | base_import.tests.models.m2o | False |
base_import.tests.models.m2o.related | base_import.tests.models.m2o.related | False |
base_import.tests.models.m2o.required | base_import.tests.models.m2o.required | False |
base_import.tests.models.m2o.required.related | base_import.tests.models.m2o.required.related | False |
base_import.tests.models.o2m | base_import.tests.models.o2m | False |
base_import.tests.models.o2m.child | base_import.tests.models.o2m.child | False |
base_import.tests.models.preview | base_import.tests.models.preview | False |
base.language.export | base.language.export | False |
Language Import | base.language.import | Language Import |
Install Language | base.language.install | Install Language |
base.module.configuration | base.module.configuration | False |
Import Module | base.module.import | Import Module |
Update Module | base.module.update | Update Module |
Module Upgrade | base.module.upgrade | Module Upgrade |
base.setup.terminology | base.setup.terminology | False |
base.update.translations | base.update.translations | False |
Board | board.board | False |
Board Creation | board.create | False |
cash.box.in | cash.box.in | False |
cash.box.out | cash.box.out | False |
Change Password Wizard User | change.password.user | A model to configure users in the change password wizard |
Change Password Wizard | change.password.wizard | A wizard to manage the change of users' passwords |
decimal.precision | decimal.precision | False |
EDI Subsystem | edi.edi | False |
Email Templates | email.template | Templates for sending email |
Email Template Preview | email_template.preview | False |
fetchmail.config.settings | fetchmail.config.settings | This wizard can be inherited in conjunction with 'res.config.settings', in order to
define fields that configure a fetchmail server.
It relies on the following convention on the object::
class my_config_settings(osv.osv_memory):
_name = 'my.settings'
_inherit = ['res.config.settings', 'fetchmail.config.settings']
_columns = {
'fetchmail_stuff': fields.boolean(...,
fetchmail_model='my.stuff', fetchmail_name='Incoming Stuff'),
}
def configure_fetchmail_stuff(self, cr, uid, ids, context=None):
return self.configure_fetchmail(cr, uid, 'fetchmail_stuff', context)
and in the form view::
|
POP/IMAP Server | fetchmail.server | Incoming POP/IMAP mail server account |
ir.actions.actions | ir.actions.actions | False |
ir.actions.act_url | ir.actions.act_url | False |
ir.actions.act_window | ir.actions.act_window | False |
ir.actions.act_window_close | ir.actions.act_window_close | False |
ir.actions.act_window.view | ir.actions.act_window.view | False |
ir.actions.client | ir.actions.client | False |
ir.actions.configuration.wizard | ir.actions.configuration.wizard | False |
ir.actions.report.xml | ir.actions.report.xml | False |
ir.actions.server | ir.actions.server | False |
Configuration Wizards | ir.actions.todo | Configuration Wizards |
ir.actions.wizard | ir.actions.wizard | False |
ir.attachment | ir.attachment | Attachments are used to link binary files or url to any openerp document. External attachment storage --------------------------- The 'data' function field (_data_get,data_set) is implemented using _file_read, _file_write and _file_delete which can be overridden to implement other storage engines, shuch methods should check for other location pseudo uri (example: hdfs://hadoppserver) The default implementation is the file:dirname location that stores files on the local filesystem using name based on their sha1 hash |
ir.config_parameter | ir.config_parameter | Per-database storage of configuration key-value pairs. |
ir.cron | ir.cron | Model describing cron jobs (also called actions or tasks). |
ir.default | ir.default | False |
ir.exports | ir.exports | False |
ir.exports.line | ir.exports.line | False |
ir.fields.converter | ir.fields.converter | False |
Filters | ir.filters | False |
ir.mail_server | ir.mail_server | Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities. |
Models | ir.model | False |
ir.model.access | ir.model.access | False |
ir.model.constraint | ir.model.constraint | This model tracks PostgreSQL foreign keys and constraints used by OpenERP models. |
ir.model.data | ir.model.data | Holds external identifier keys for records in the database. This has two main uses: * allows easy data integration with third-party systems, making import/export/sync of data possible, as records can be uniquely identified across multiple systems * allows tracking the origin of data installed by OpenERP modules themselves, thus making it possible to later update them seamlessly. |
Fields | ir.model.fields | False |
ir.model.relation | ir.model.relation | This model tracks PostgreSQL tables used to implement OpenERP many2many relations. |
Application | ir.module.category | False |
Module | ir.module.module | False |
Module dependency | ir.module.module.dependency | False |
ir.needaction_mixin | ir.needaction_mixin | Mixin class for objects using the need action feature. Need action feature can be used by models that have to be able to signal that an action is required on a particular record. If in the business logic an action must be performed by somebody, for instance validation by a manager, this mechanism allows to set a list of users asked to perform an action. Models using the 'need_action' feature should override the ``_needaction_domain_get`` method. This method returns a domain to filter records requiring an action for a specific user. This class also offers several global services: - ``_needaction_count``: returns the number of actions uid has to perform |
ir.property | ir.property | False |
ir.rule | ir.rule | False |
ir.sequence | ir.sequence | Sequence model. The sequence model allows to define and use so-called sequence objects. Such objects are used to generate unique identifiers in a transaction-safe way. |
ir.sequence.type | ir.sequence.type | False |
ir.server.object.lines | ir.server.object.lines | False |
ir.translation | ir.translation | False |
ir.ui.menu | ir.ui.menu | False |
ir.ui.view | ir.ui.view | False |
ir.ui.view.custom | ir.ui.view.custom | False |
ir.ui.view_sc | ir.ui.view_sc | False |
ir.values | ir.values | Holds internal model-specific action bindings and user-defined default field values. definitions. This is a legacy internal model, mixing two different concepts, and will likely be updated or replaced in a future version by cleaner, separate models. You should not depend explicitly on it. The purpose of each ``ir.values`` entry depends on its type, defined by the ``key`` column: * 'default': user-defined default values, used when creating new records of this model: * 'action': binding of an action to a particular *action slot* of this model, making the action easily available in the user interface for this model. The ``key2`` column acts as a qualifier, further refining the type of the entry. The possible values are: * for 'default' entries: an optional condition restricting the cases where this particular default value will be applicable, or ``False`` for no condition * for 'action' entries: the ``key2`` qualifier is one of the available action slots, defining how this action can be invoked: * ``'client_print_multi'`` for report printing actions that will be available on views displaying items from this model * ``'client_action_multi'`` for assistants (wizards) actions that will be available in views displaying objects of this model * ``'client_action_relate'`` for links towards related documents that should be available in views displaying objects of this model * ``'tree_but_open'`` for actions that will be triggered when double-clicking an item from this model in a hierarchical tree view Each entry is specific to a model (``model`` column), and for ``'actions'`` type, may even be made specific to a given record of that model when the ``res_id`` column contains a record ID (``False`` means it's global for all records). The content of the entry is defined by the ``value`` column, which may either contain an arbitrary value, or a reference string defining the action that should be executed. .. rubric:: Usage: default values The ``'default'`` entries are usually defined manually by the users, and set by their UI clients calling :meth:`~.set_default`. These default values are then automatically used by the ORM every time a new record is about to be created, i.e. when :meth:`~openerp.osv.osv.osv.default_get` or :meth:`~openerp.osv.osv.osv.create` are called. .. rubric:: Usage: action bindings Business applications will usually bind their actions during installation, and OpenERP UI clients will apply them as defined, based on the list of actions included in the result of :meth:`~openerp.osv.osv.osv.fields_view_get`, or directly returned by explicit calls to :meth:`~.get_actions`. |
Email Aliases | mail.alias | A Mail Alias is a mapping of an email address with a given OpenERP Document model. It is used by OpenERP's mail gateway when processing incoming emails sent to the system. If the recipient address (To) of the message matches a Mail Alias, the message will be either processed following the rules of that alias. If the message is a reply it will be attached to the existing discussion on the corresponding record, otherwise a new record of the corresponding model will be created. This is meant to be used in combination with a catch-all email configuration on the company's mail server, so that as soon as a new mail.alias is created, it becomes immediately usable and OpenERP will accept email for it. |
Email composition wizard | mail.compose.message | False |
Document Followers | mail.followers | mail_followers holds the data related to the follow mechanism inside OpenERP. Partners can choose to follow documents (records) of any kind that inherits from mail.thread. Following documents allow to receive notifications for new messages. A subscription is characterized by: :param: res_model: model of the followed objects :param: res_id: ID of resource (may be 0 for every objects) |
Discussion group | mail.group | False |
Outgoing Mails | mail.mail | Model holding RFC2822 email messages to send. This model also provides facilities to queue and send new email messages. |
Message | mail.message | False |
Message subtypes | mail.message.subtype | Class holding subtype definition for messages. Subtypes allow to tune the follower subscription, allowing only some subtypes to be pushed on the Wall. |
Notifications | mail.notification | Class holding notifications pushed to partners. Followers and partners added in 'contacts to notify' receive notifications. |
Email Thread | mail.thread | mail_thread model is meant to be inherited by any model that needs to act as a discussion topic on which messages can be attached. Public methods are prefixed with ``message_`` in order to avoid name collisions with methods of the models that will inherit from this class. ``mail.thread`` defines fields used to handle and display the communication history. ``mail.thread`` also manages followers of inheriting classes. All features and expected behavior are managed by mail.thread. Widgets has been designed for the 7.0 and following versions of OpenERP. Inheriting classes are not required to implement any method, as the default implementation will work for any model. However it is common to override at least the ``message_new`` and ``message_update`` methods (calling ``super``) to add model-specific behavior at creation and update of a thread when processing incoming emails. Options: - _mail_flat_thread: if set to True, all messages without parent_id are automatically attached to the first message posted on the ressource. If set to False, the display of Chatter is done using threads, and no parent_id is automatically set. |
Invite wizard | mail.wizard.invite | Wizard to invite partners and make them followers. |
Default multi company | multi_company.default | Manage multi company default value |
osv_memory.autovacuum | osv_memory.autovacuum | Expose the osv_memory.vacuum() method to the cron jobs mechanism. |
Online Payment Acquirer | portal.payment.acquirer | False |
Portal Access Management | portal.wizard | A wizard to manage the creation/removal of portal users. |
Portal User Config | portal.wizard.user | A model to configure users in the portal wizard. |
pricelist.partnerinfo | pricelist.partnerinfo | False |
Condition | process.condition | False |
Process Node | process.node | False |
Process | process.process | False |
Process Transition | process.transition | False |
Process Transitions Actions | process.transition.action | False |
Product Category | product.category | False |
Packaging | product.packaging | False |
Pricelist | product.pricelist | False |
Price List | product.price_list | False |
Pricelist item | product.pricelist.item | False |
Pricelist Type | product.pricelist.type | False |
Pricelist Version | product.pricelist.version | False |
Price Type | product.price.type | The price type is used to points which field in the product form is a price and in which currency is this price expressed. When a field is a price, you can use it in pricelists to base sale and purchase prices based on some fields of the product. |
Product | product.product | False |
Information about a product supplier | product.supplierinfo | False |
Product Template | product.template | False |
Shipping Unit | product.ul | False |
Product Unit of Measure | product.uom | False |
Product uom categ | product.uom.categ | False |
Analytic Entries by line | project.account.analytic.line | False |
publisher_warranty.contract | publisher_warranty.contract | False |
Receivable accounts | report.account.receivable | False |
Report of the Sales by Account | report.account.sales | False |
Report of the Sales by Account Type | report.account_type.sales | False |
Aged Receivable Till Today | report.aged.receivable | False |
Report of Invoices Created within Last 15 days | report.invoice.created | False |
Bank | res.bank | False |
Companies | res.company | False |
res.config | res.config | Base classes for new-style configuration items Configuration items should inherit from this class, implement the execute method (and optionally the cancel one) and have their view inherit from the related res_config_view_base view. |
res.config.installer | res.config.installer | False |
res.config.settings | res.config.settings | Base configuration wizard for application settings. It provides support for setting default values, assigning groups to employee users, and installing modules. To make such a 'settings' wizard, define a model like:: class my_config_wizard(osv.osv_memory): _name = 'my.settings' _inherit = 'res.config.settings' _columns = { 'default_foo': fields.type(..., default_model='my.model'), 'group_bar': fields.boolean(..., group='base.group_user', implied_group='my.group'), 'module_baz': fields.boolean(...), 'other_field': fields.type(...), } The method ``execute`` provides some support based on a naming convention: * For a field like 'default_XXX', ``execute`` sets the (global) default value of the field 'XXX' in the model named by ``default_model`` to the field's value. * For a boolean field like 'group_XXX', ``execute`` adds/removes 'implied_group' to/from the implied groups of 'group', depending on the field's value. By default 'group' is the group Employee. Groups are given by their xml id. * For a boolean field like 'module_XXX', ``execute`` triggers the immediate installation of the module named 'XXX' if the field has value ``True``. * For the other fields, the method ``execute`` invokes all methods with a name that starts with 'set_'; such methods can be defined to implement the effect of those fields. The method ``default_get`` retrieves values that reflect the current status of the fields like 'default_XXX', 'group_XXX' and 'module_XXX'. It also invokes all methods with a name that starts with 'get_default_'; such methods can be defined to provide current values for other fields. |
Country | res.country | False |
Country state | res.country.state | False |
Currency | res.currency | False |
Currency Rate | res.currency.rate | False |
Currency Rate Type | res.currency.rate.type | False |
Access Groups | res.groups | False |
Languages | res.lang | False |
Partner | res.partner | False |
Bank Accounts | res.partner.bank | Bank Accounts |
Bank Account Type | res.partner.bank.type | False |
Bank type fields | res.partner.bank.type.field | False |
Partner Categories | res.partner.category | False |
res.partner.title | res.partner.title | False |
res.request | res.request | False |
res.request.history | res.request.history | False |
res.request.link | res.request.link | False |
Users | res.users | False |
Sales Advance Payment Invoice | sale.advance.payment.inv | False |
sale.config.settings | sale.config.settings | False |
Sales Make Invoice | sale.make.invoice | False |
Sales Order | sale.order | False |
Sales Order Line | sale.order.line | False |
Sale OrderLine Make_invoice | sale.order.line.make.invoice | False |
Sales Receipt Statistics | sale.receipt.report | False |
Sales Orders Statistics | sale.report | False |
Sales Shop | sale.shop | False |
Share Wizard | share.wizard | False |
share.wizard.result.line | share.wizard.result.line | False |
A Temporary table used for Dashboard view | temp.range | False |
Validate Account Move | validate.account.move | False |
Validate Account Move Lines | validate.account.move.lines | False |
wizard.ir.model.menu.create | wizard.ir.model.menu.create | False |
wizard.multi.charts.accounts | wizard.multi.charts.accounts | False |
workflow | workflow | False |
workflow.activity | workflow.activity | False |
workflow.instance | workflow.instance | False |
workflow.transition | workflow.transition | False |
workflow.triggers | workflow.triggers | False |
workflow.workitem | workflow.workitem | False |
ldb here represents database connection (Client class instance) As told in help message above .get_obj method allows to get instance of specified Object proxy, where Object means model, document.
so = ldb.get_obj('sale.order')
so
Model | sale.order |
---|---|
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
Name | Sales Order |
Record count | 8 |
Also it is posible to use shorter (dictionary style) syntax:
so = ldb['sale.order']
so
Model | sale.order |
---|---|
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
Name | Sales Order |
Record count | 8 |
And as result of using openerp_proxy.ext.sugar extension (which is automaticaly imported in 'openerp_proxy.ext.all') there are attribute-style access (which also support's IPython auto-completition):
so = ldb._sale_order
so
Model | sale.order |
---|---|
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
Name | Sales Order |
Record count | 8 |
so.columns_info
Name | Disp. Name | Type | Required | Help |
---|---|---|---|---|
amount_tax | Taxes | float | None | The tax amount. |
amount_total | Total | float | None | The total amount. |
amount_untaxed | Untaxed Amount | float | None | The amount without tax. |
client_order_ref | Customer Reference | char | None | None |
company_id | Company | many2one | None | None |
create_date | Creation Date | datetime | None | Date on which sales order is created. |
currency_id | Currency | many2one | True | None |
date_confirm | Confirmation Date | date | None | Date on which sales order is confirmed. |
date_order | Date | date | True | None |
fiscal_position | Fiscal Position | many2one | None | None |
invoice_exists | Invoiced | boolean | None | It indicates that sales order has at least one invoice. |
invoice_ids | Invoices | many2many | None | This is the list of invoices that have been generated for this sales order. The same sales order may have been invoiced in several times (by line for example). |
invoice_quantity | Invoice on | selection | True | The sales order will automatically create the invoice proposition (draft invoice). |
invoiced | Paid | boolean | None | It indicates that an invoice has been paid. |
invoiced_rate | Invoiced Ratio | float | None | None |
message_follower_ids | Followers | many2many | None | None |
message_ids | Messages | one2many | None | Messages and communication history |
message_is_follower | Is a Follower | boolean | None | None |
message_summary | Summary | text | None | Holds the Chatter summary (number of messages, ...). This summary is directly in html format in order to be inserted in kanban views. |
message_unread | Unread Messages | boolean | None | If checked new messages require your attention. |
name | Order Reference | char | True | None |
note | Terms and conditions | text | None | None |
order_line | Order Lines | one2many | None | None |
order_policy | Create Invoice | selection | True | This field controls how invoice and delivery operations are synchronized. |
origin | Source Document | char | None | Reference of the document that generated this sales order request. |
partner_id | Customer | many2one | True | None |
partner_invoice_id | Invoice Address | many2one | True | Invoice address for current sales order. |
partner_shipping_id | Delivery Address | many2one | True | Delivery address for current sales order. |
payment_term | Payment Term | many2one | None | None |
paypal_url | Paypal Url | char | None | None |
portal_payment_options | Portal Payment Options | html | None | None |
pricelist_id | Pricelist | many2one | True | Pricelist for current sales order. |
project_id | Contract / Analytic | many2one | None | The analytic account related to a sales order. |
shop_id | Shop | many2one | True | None |
state | Status | selection | None | Gives the status of the quotation or sales order. The exception status is automatically set when a cancel operation occurs in the processing of a document linked to the sales order. The 'Waiting Schedule' status is set when the invoice is confirmed but waiting for the scheduler to run on the order date. |
user_id | Salesperson | many2one | None | None |
# Standard search .search_records(domain)
so_list = so.search_records([])
so_list
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
---|---|
Object | Object ('sale.order') |
Record count | 8 |
Also there are shorter syntax provided by openerp_proxy.ext.sugar extension:
so_list = so([])
so_list
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
---|---|
Object | Object ('sale.order') |
Record count | 8 |
It is posible to represent RecordList as HTML table, with ability to highlight rows by specified conditions. Also, when building result table, it is posible to display values of related fields, and even method calls. This functionality is implemented in openerp_proxy.ext.repr module
# High light rows by condition
highlighters = {
'#99FF99': lambda x: x.state == 'done',
'#9999FF': lambda x: x.state == 'draft',
'#FFFF99': lambda x: x.state == 'progress',
}
# Display as table.
# Note that prefetch method is used to fetch some set of fields with less RPC call.
# on big datasets it may speed up performance signifiantly.
# Each RecordList instance have related cache, which reduce need of reading data on each field get.
so_list.prefetch('id', 'name', 'partner_id', 'partner_id.email', 'state')
so_table = so_list.as_html_table(
'id',
'name',
# _name attribute provides result of *name_search method:
HField('partner_id._name', name='Partner name'),
# silent=True means, if field cannot be found, not throw error
HField('partner_id.email', name='Partner email', silent=True),
# Also it is posible to display result of method calls
# 'as_html_list()' is method of RecordList.
('order_line.as_html_list', 'Order lines'),
'state',
highlighters=highlighters,
)
so_table
id | name | Partner name | Partner email | Order lines | state |
---|---|---|---|---|---|
8 | SO008 | Millennium Industries | False |
|
draft |
7 | SO007 | Luminous Technologies | False |
|
manual |
6 | SO006 | Think Big Systems | info@thinkbig.com |
|
draft |
5 | SO005 | Agrolait | info@agrolait.com |
|
draft |
4 | SO004 | Millennium Industries | False |
|
draft |
3 | SO003 | Chamber Works | info@chamberworks.com |
|
draft |
2 | SO002 | Bank Wealthy and sons | email@wealthyandsons.com |
|
draft |
1 | SO001 | Agrolait | info@agrolait.com |
|
sent |
There also available to_csv method, which allow to represent table in csv format
so_table.to_csv()
This app has experimental integration with Anyfield library. For example it is posible to use Anyfield expressions in RecordList.filter method.
Ususaly You use lambdas to filter some records. Something like this:
partners = ldb._res_partner() # find all partners in database
filtered_partners_l = partners.filter(lambda x: x.sale_order_ids.length >= 1)
filtered_partners_l
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
---|---|
Object | Object ('res.partner') |
Record count | 6 |
from anyfield import F
# Imagine that F is record in partners recordlist. and pass expression based on this to filter method.
# It will automaticaly be converted to filter function
filtered_partners_f = partners.filter(F.sale_order_ids.length >= 1)
filtered_partners_f
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
---|---|
Object | Object ('res.partner') |
Record count | 6 |
To check that resultes are same, let's just compare them:
assert sorted(filtered_partners_f.ids) == sorted(filtered_partners_l.ids), \
"Filtered partners must be same in both cases"
Also it is posible to display nested html tables. For example, lets list partners with sale orders related to them Here anyfield.F expression is used too.
filtered_partners_l.as_html_table(
'id',
'name',
'parent_id',
HField(F.sale_order_ids.as_html_table('id',
'_name',
'date_order',
'amount_total',
'state'),
'Sale orders'),
)
id | name | parent_id | Sale orders | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6 | Agrolait | False |
|
|||||||||||||||
11 | Bank Wealthy and sons | False |
|
|||||||||||||||
18 | Chamber Works | False |
|
|||||||||||||||
15 | Luminous Technologies | False |
|
|||||||||||||||
19 | Millennium Industries | False |
|
|||||||||||||||
22 | Think Big Systems | False |
|
Recordlist supports access to containing elements via indexes
so_list[0]
Client | xml-rpc://admin@localhost:8069/openerp_proxy_test_db |
---|---|
Object | Object ('sale.order') |
ID | 8 |
Name | SO008 |
so_list[0].as_html('name',
'origin',
# Will display Reacord instance representing partner related to this sale order
('partner_id', 'Partner'),
# Will display result of 'name_get' called on partner
('partner_id._name', 'Partner name'),
# Display how many sale orders have this partner
('partner_id.sale_order_ids.length', 'Sales QTY'),
)
Field name | System name | Value |
---|---|---|
name | name | SO008 |
origin | origin | False |
Partner | partner_id | R(res.partner, 19)[Millennium Industries] |
Partner name | partner_id._name | Millennium Industries |
Sales QTY | partner_id.sale_order_ids.length | 2 |
so_list[0].as_html() # Display all fields for firest sale order record
Field name | System name | Value |
---|---|---|
Confirmation Date | date_confirm | False |
Contract / Analytic | project_id | False |
Create Invoice | order_policy | manual |
Creation Date | create_date | 2016-03-22 15:29:15 |
Customer | partner_id | R(res.partner, 19)[Millennium Industries] |
Customer Reference | client_order_ref | False |
Date | date_order | 2016-03-22 |
Delivery Address | partner_shipping_id | R(res.partner, 52)[Millennium Industries, Jacob Taylor] |
Fiscal Position | fiscal_position | False |
Invoice Address | partner_invoice_id | R(res.partner, 52)[Millennium Industries, Jacob Taylor] |
Invoice on | invoice_quantity | order |
Invoices | invoice_ids | RecordList(account.invoice): length=0 |
Messages | message_ids | RecordList(mail.message): length=2 |
Order Lines | order_line | RecordList(sale.order.line): length=2 |
Order Reference | name | SO008 |
Payment Term | payment_term | False |
Pricelist | pricelist_id | R(product.pricelist, 1)[Public Pricelist (EUR)] |
Salesperson | user_id | R(res.users, 3)[Demo User] |
Shop | shop_id | R(sale.shop, 1)[Your Company] |
Source Document | origin | False |
Status | state | draft |
Terms and conditions | note | False |
*Odoo 11.0 Note*: in Odoo 11.0 report service was completely removed.
All reports now handled by model ir.actions.report
.
So to get generated report, just call render
method of this model and get generated report.
There is reports
service available in Odoo (before 11.0), which allows to print reports.
Example below is *deprecated*, use ir.actions.report
model directly
from pkg_resources import parse_version as V
if ldb.server_version < V('11.0'):
if 'sale.report_saleorder' in ldb.services.report:
report_name = 'sale.report_saleorder' # Odoo version >= 8.0
elif 'sale.order' in ldb.services.report:
report_name = 'sale.order' # Odoo version 7.0
else:
raise Exception("Cannot find sale report") # no such report registered on server
report = ldb.services.report[report_name]
else:
report = None
if report:
report_result = report.generate(so_list)
report_result