Metadata-Version: 2.2
Name: proteus
Version: 6.2.0
Summary: Library to access Tryton server as a client
Home-page: http://www.tryton.org/
Download-URL: http://downloads.tryton.org/6.2/
Author: Tryton
Author-email: bugs@tryton.org
License: LGPL-3
Project-URL: Bug Tracker, https://bugs.tryton.org/
Project-URL: Documentation, https://docs.tryton.org/
Project-URL: Forum, https://www.tryton.org/forum
Project-URL: Source Code, https://hg.tryton.org/proteus
Keywords: tryton library cli
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Plugins
Classifier: Framework :: Tryton
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Legal Industry
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Office/Business
Requires-Python: >=3.6
License-File: LICENSE
Requires-Dist: python-dateutil
Provides-Extra: trytond
Requires-Dist: trytond<6.3,>=6.2; extra == "trytond"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: download-url
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: platform
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

=======================
Tryton Scripting Client
=======================

A library to access Tryton's models like a client.

Example of usage
----------------

    >>> from proteus import config, Model, Wizard, Report

Configuration
~~~~~~~~~~~~~

Configuration to connect to a sqlite memory database using trytond as module.

    >>> config = config.set_trytond('sqlite:///:memory:')

There is also the `config.set_xmlrpc` method which can be used to connect using
a URL, and the `config.set_xmlrpc_session` method (when used as a context
manager) which connects for a session.

Activating a module
~~~~~~~~~~~~~~~~~~~

Find the module, call the activate button and run the upgrade wizard.

    >>> Module = Model.get('ir.module')
    >>> party_module, = Module.find([('name', '=', 'party')])
    >>> party_module.click('activate')
    >>> Wizard('ir.module.activate_upgrade').execute('upgrade')

Creating a party
~~~~~~~~~~~~~~~~

First instanciate a new Party:

    >>> Party = Model.get('party.party')
    >>> party = Party()
    >>> party.id < 0
    True

Fill the fields:

    >>> party.name = 'ham'

Save the instance into the server:

    >>> party.save()
    >>> party.name
    'ham'
    >>> party.id > 0
    True

Setting the language of the party
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The language on party is a `Many2One` relation field. So it requires to get a
`Model` instance as value.

    >>> Lang = Model.get('ir.lang')
    >>> en, = Lang.find([('code', '=', 'en')])
    >>> party.lang = en
    >>> party.save()
    >>> party.lang.code
    'en'

Creating an address for the party
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Addresses are store on party with a `One2Many` field. So the new address just
needs to be appended to the list `addresses`.

    >>> address = party.addresses.new(postal_code='42')
    >>> party.save()
    >>> party.addresses #doctest: +ELLIPSIS
    [proteus.Model.get('party.address')(...)]

Adding category to the party
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Categories are linked to party with a `Many2Many` field.

So first create a category

    >>> Category = Model.get('party.category')
    >>> category = Category()
    >>> category.name = 'spam'
    >>> category.save()

Append it to categories of the party

    >>> party.categories.append(category)
    >>> party.save()
    >>> party.categories #doctest: +ELLIPSIS
    [proteus.Model.get('party.category')(...)]

Print party label
~~~~~~~~~~~~~~~~~

There is a label report on `Party`.

    >>> label = Report('party.label')

The report is executed with a list of records and some extra data.

    >>> type_, data, print_, name = label.execute([party], {})

Sorting addresses and register order
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Addresses are ordered by sequence which means they can be stored following a
specific order. The `set_sequence` method stores the current order.

    >>> address = party.addresses.new(postal_code='69')
    >>> party.save()
    >>> address = party.addresses.new(postal_code='23')
    >>> party.save()

Now changing the order.

    >>> reversed_addresses = list(reversed(party.addresses))
    >>> while party.addresses:
    ...     _ = party.addresses.pop()
    >>> party.addresses.extend(reversed_addresses)
    >>> party.addresses.set_sequence()
    >>> party.save()
    >>> party.addresses == reversed_addresses
    True

Setting context
~~~~~~~~~~~~~~~

Make French translatable:

    >>> Language = Model.get('ir.lang')
    >>> french, = Language.find([('code', '=', 'fr')])
    >>> french.translatable = True
    >>> french.save()

Create a category in English:

    >>> Category = Model.get('party.category')
    >>> with config.set_context(language='en'):
    ...     category = Category(name="Category")
    ...     category.save()

Translate in French:

    >>> with config.set_context(language='fr'):
    ...     category_fr = Category(category.id)
    ...     category_fr.name = "Categorie"
    ...     category_fr.save()

Read in English:

    >>> category.reload()
    >>> category.name
    'Category'

Read in French:

    >>> category_fr.reload()
    >>> category_fr.name
    'Categorie'
