merge trunk
bzr revid: nicolas.vanhoren@openerp.com-20121123102100-6j5nf4mqypsz6u02 bzr revid: nicolas.vanhoren@openerp.com-20121126093747-6w88rmpbnlcsc2ls
This commit is contained in:
+59
-35
@@ -10,13 +10,25 @@ Installation from sources
|
||||
|
||||
.. _getting_started_installation_source-link:
|
||||
|
||||
Source code is hosted on Launchpad_. In order to get the sources, you will need Bazaar_ to pull the source from Launchpad. Bazaar is a version control system that helps you track project history over time and collaborate efficiently. You may have to create an account on Launchpad to be able to collaborate on OpenERP development. Please refer to the Launchpad and Bazaar documentation to install and setup your development environment.
|
||||
Source code is hosted on Launchpad_. In order to get the sources, you
|
||||
will need Bazaar_ to pull the source from Launchpad. Bazaar is a
|
||||
version control system that helps you track project history over time
|
||||
and collaborate efficiently. You may have to create an account on
|
||||
Launchpad to be able to collaborate on OpenERP development. Please
|
||||
refer to the Launchpad and Bazaar documentation to install and setup
|
||||
your development environment.
|
||||
|
||||
The running example of this section is based on an Ubuntu environment. You may have to adapt the steps according to your system. Once your working environment is ready, prepare a working directory that will contain the sources. For a ``source`` base directory, type::
|
||||
The running example of this section is based on an Ubuntu
|
||||
environment. You may have to adapt the steps according to your
|
||||
system. Once your working environment is ready, prepare a working
|
||||
directory that will contain the sources. For a ``source`` base
|
||||
directory, type::
|
||||
|
||||
mkdir source;cd source
|
||||
|
||||
OpenERP provides a setup script that automatizes the tasks of creating a shared repository and getting the source code. Get the setup script of OpenERP by typing::
|
||||
OpenERP provides a setup script that automatizes the tasks of creating
|
||||
a shared repository and getting the source code. Get the setup script
|
||||
of OpenERP by typing::
|
||||
|
||||
bzr cat -d lp:~openerp-dev/openerp-tools/trunk setup.sh | sh
|
||||
|
||||
@@ -29,27 +41,30 @@ If you want some help about the available options, please type::
|
||||
|
||||
make help
|
||||
|
||||
Next step is to initialize the shared repository and download the sources. Get the current trunk version of OpenERP by typing::
|
||||
Next step is to initialize the shared repository and download the
|
||||
sources. Get the current trunk version of OpenERP by typing::
|
||||
|
||||
make init-trunk
|
||||
|
||||
This will create the following structure inside your ``source`` directory, and fetch the latest source code from ``trunk``::
|
||||
This will create the following structure inside your ``source``
|
||||
directory, and fetch the latest source code from ``trunk``::
|
||||
|
||||
drwxrwxr-x 3 openerp openerp 4096 2012-04-17 11:10 addons
|
||||
drwxrwxr-x 3 openerp openerp 4096 2012-04-17 11:10 misc
|
||||
drwxrwxr-x 3 openerp openerp 4096 2012-04-17 11:10 server
|
||||
drwxrwxr-x 3 openerp openerp 4096 2012-04-17 11:10 web
|
||||
|
||||
Some dependencies are necessary to use OpenERP. Depending on your environment, you might have to install the following packages::
|
||||
Some dependencies are necessary to use OpenERP. Depending on your
|
||||
environment, you might have to install the following packages::
|
||||
|
||||
sudo apt-get install graphviz ghostscript postgresql-client
|
||||
|
||||
sudo apt-get install python-dateutil python-feedparser python-gdata
|
||||
python-ldap python-libxslt1 python-lxml python-mako, python-openid
|
||||
python-psycopg2 python-pybabel python-pychart python-pydot
|
||||
python-pyparsing python-reportlab python-simplejson python-tz
|
||||
python-vatnumber python-vobject python-webdav python-werkzeug python-xlwt
|
||||
python-yaml python-imaging python-matplotlib
|
||||
sudo apt-get install graphviz ghostscript postgresql-client \
|
||||
python-dateutil python-feedparser python-gdata \
|
||||
python-ldap python-libxslt1 python-lxml python-mako \
|
||||
python-openid python-psycopg2 python-pybabel python-pychart \
|
||||
python-pydot python-pyparsing python-reportlab python-simplejson \
|
||||
python-tz python-vatnumber python-vobject python-webdav \
|
||||
python-werkzeug python-xlwt python-yaml python-imaging \
|
||||
python-matplotlib
|
||||
|
||||
Next step is to initialize the database. This will create a new openerp role::
|
||||
|
||||
@@ -59,7 +74,8 @@ Finally, launch the OpenERP server::
|
||||
|
||||
make server
|
||||
|
||||
Testing your installation can be done on http://localhost:8069/ . You should see the OpenERP main login page.
|
||||
Testing your installation can be done on http://localhost:8069/. You
|
||||
should see the OpenERP main login page.
|
||||
|
||||
.. _Launchpad: https://launchpad.net/
|
||||
.. _Bazaar: http://bazaar.canonical.com/en/
|
||||
@@ -67,12 +83,12 @@ Testing your installation can be done on http://localhost:8069/ . You should see
|
||||
Command line options
|
||||
====================
|
||||
|
||||
.. program:: openerp-server
|
||||
|
||||
Using the command ::
|
||||
|
||||
./openerp-server --help
|
||||
|
||||
gives you the available command line options. For OpenERP server at revision 4133, an output example is given in the `Command line options example`_. Here are a few interesting command line options.
|
||||
|
||||
General Options
|
||||
+++++++++++++++
|
||||
|
||||
@@ -117,7 +133,8 @@ Database related options
|
||||
Internationalization options
|
||||
++++++++++++++++++++++++++++
|
||||
|
||||
Use these options to translate OpenERP to another language.See i18n section of the user manual. Option '-l' is mandatory.::
|
||||
Use these options to translate OpenERP to another language.See i18n
|
||||
section of the user manual. Option '-l' is mandatory.::
|
||||
|
||||
-l LANGUAGE, --language=LANGUAGE
|
||||
specify the language of the translation file. Use it
|
||||
@@ -134,8 +151,9 @@ Use these options to translate OpenERP to another language.See i18n section of t
|
||||
Options from previous versions
|
||||
++++++++++++++++++++++++++++++
|
||||
|
||||
Some options were removed in OpenERP version 6. For example, ``price_accuracy`` is now
|
||||
configured through the :ref:`decimal_accuracy` screen.
|
||||
Some options were removed in OpenERP version 6. For example,
|
||||
``price_accuracy`` is now configured through the
|
||||
:ref:`decimal_accuracy` screen.
|
||||
|
||||
Configuration
|
||||
==============
|
||||
@@ -147,7 +165,12 @@ Two configuration files are available:
|
||||
* one for the client: ``~/.openerprc``
|
||||
* one for the server: ``~/.openerp_serverrc``
|
||||
|
||||
If they are not found, the server and the client will start with a default configuration. Those files follow the convention used by python's ConfigParser module. Please note that lines beginning with "#" or ";" are comments. The client configuration file is automatically generated upon the first start. The sezrver configuration file can automatically be created using the command ::
|
||||
If they are not found, the server and the client will start with a
|
||||
default configuration. Those files follow the convention used by
|
||||
python's ConfigParser module. Please note that lines beginning with
|
||||
"#" or ";" are comments. The client configuration file is
|
||||
automatically generated upon the first start. The sezrver
|
||||
configuration file can automatically be created using the command ::
|
||||
|
||||
./openerp-server -s or ./openerp-server --save
|
||||
|
||||
@@ -156,19 +179,20 @@ You can specify alternate configuration files with ::
|
||||
-c CONFIG, --config=CONFIG specify alternate config file
|
||||
|
||||
Configure addons locations
|
||||
--------------------------
|
||||
++++++++++++++++++++++++++
|
||||
|
||||
By default, the only directory of addons known by the server is server/bin/addons.
|
||||
It is possible to add new addons by
|
||||
By default, the only directory of addons known by the server is
|
||||
server/bin/addons. It is possible to add new addons by
|
||||
|
||||
- copying them in server/bin/addons, or creating a symbolic link to each
|
||||
of them in this directory, or
|
||||
- specifying another directory containing addons to the server. The later
|
||||
can be accomplished either by running the server with the ``--addons-path=``
|
||||
option, or by configuring this option in the openerp_serverrc file,
|
||||
automatically generated under Linux in your home directory by the
|
||||
server when executed with the ``--save`` option. You can provide several
|
||||
addons to the ``addons_path`` = option, separating them using commas.
|
||||
- copying them in server/bin/addons, or creating a symbolic link to
|
||||
each of them in this directory, or
|
||||
- specifying another directory containing addons to the server. The
|
||||
later can be accomplished either by running the server with the
|
||||
``--addons-path=`` option, or by configuring this option in the
|
||||
openerp_serverrc file, automatically generated under Linux in your
|
||||
home directory by the server when executed with the ``--save``
|
||||
option. You can provide several addons to the ``addons_path`` =
|
||||
option, separating them using commas.
|
||||
|
||||
Start-up script
|
||||
===============
|
||||
@@ -176,9 +200,9 @@ Start-up script
|
||||
.. versionadded:: 6.1
|
||||
|
||||
To run the OpenERP server, the conventional approach is to use the
|
||||
`openerp-server` script. It loads the :ref:`openerp library`, sets a few
|
||||
configuration variables corresponding to command-line arguments, and starts to
|
||||
listen to incoming connections from clients.
|
||||
`openerp-server` script. It loads the :ref:`openerp library`, sets a
|
||||
few configuration variables corresponding to command-line arguments,
|
||||
and starts to listen to incoming connections from clients.
|
||||
|
||||
Depending on your deployment needs, you can write such a start-up script very
|
||||
easily. We also recommend you take a look at an alternative tool called
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _module-dev:
|
||||
|
||||
=======
|
||||
Modules
|
||||
=======
|
||||
|
||||
+12
-10
@@ -1,3 +1,5 @@
|
||||
.. _module-dev-structure:
|
||||
|
||||
Module structure
|
||||
================
|
||||
|
||||
@@ -124,11 +126,11 @@ But it is dangerous to write or read directly in the PostgreSQL database, as
|
||||
you will shortcut important steps like constraints checking or workflow
|
||||
modification.
|
||||
|
||||
.. figure:: images/pom_3_0_3.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/pom_3_0_3.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
*The Physical Objects Model of [OpenERP version 3.0.3]*
|
||||
.. *The Physical Objects Model of [OpenERP version 3.0.3]*
|
||||
|
||||
|
||||
XML Files
|
||||
@@ -311,9 +313,9 @@ When you open an invoice, here is the chain of operations followed by the client
|
||||
* The client asks (with XML-RPC) to the server what views are defined for the invoice object and what are the data it must show.
|
||||
* The client displays the form according to the view
|
||||
|
||||
.. figure:: images/arch_view_use.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/arch_view_use.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
To develop new objects
|
||||
//////////////////////
|
||||
@@ -342,9 +344,9 @@ The workflows describe these interactions with graphs. One or several workflows
|
||||
|
||||
Below is an example workflow used for sale orders. It must generate invoices and shipments according to certain conditions.
|
||||
|
||||
.. figure:: images/arch_workflow_sale.png
|
||||
:scale: 85
|
||||
:align: center
|
||||
.. .. figure:: images/arch_workflow_sale.png
|
||||
.. :scale: 85
|
||||
.. :align: center
|
||||
|
||||
|
||||
In this graph, the nodes represent the actions to be done:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _module-dev-api:
|
||||
|
||||
Objects, Fields and Methods
|
||||
===========================
|
||||
|
||||
|
||||
+32
-30
@@ -1,3 +1,5 @@
|
||||
.. _module-dev-views:
|
||||
|
||||
Views and Events
|
||||
================
|
||||
|
||||
@@ -45,26 +47,26 @@ The field disposition in a form view always follows the same principle. Fields a
|
||||
* Fields are placed on the screen from left to right, and from top to bottom, according to the order in which they are declared in the view.
|
||||
* Every screen is divided into 4 columns, each column being able to contain either a label, or an "edition" field. As every edition field is preceded (by default) by a label with its name, there will be two fields (and their respective labels) on each line of the screen. The green and red zones on the screen-shot below, illustrate those 4 columns. They designate respectively the labels and their corresponding fields.
|
||||
|
||||
.. figure:: images/sale_order.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/sale_order.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
|
||||
Views also support more advanced placement options:
|
||||
|
||||
* A view field can use several columns. For example, on the screen-shot below, the zone in the blue frame is, in fact, the only field of a "one to many". We will come back later on this note, but let's note that it uses the whole width of the screen and not only one column.
|
||||
|
||||
.. figure:: images/sale_order_sale_order_lines.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/sale_order_sale_order_lines.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
* We can also make the opposite operation: take a columns group and divide it in as many columns as desired. The surrounded green zones of the screen above are good examples. Precisely, the green framework up and on the right side takes the place of two columns, but contains 4 columns.
|
||||
|
||||
As we can see below in the purple zone of the screen, there is also a way to distribute the fields of an object on different tabs.
|
||||
|
||||
.. figure:: images/sale_order_notebook.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/sale_order_notebook.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
On Change
|
||||
+++++++++
|
||||
@@ -129,9 +131,9 @@ Tree views
|
||||
|
||||
These views are used when we work in list mode (in order to visualize several resources at once) and in the search screen. These views are simpler than the form views and thus have less options.
|
||||
|
||||
.. figure:: images/tree_view.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. figure:: images/tree_view.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
Search views
|
||||
--------------
|
||||
@@ -140,9 +142,9 @@ Search views are a new feature of OpenERP supported as of version 6.0
|
||||
It creates a customized search panel, and is declared quite similarly to a form view,
|
||||
except that the view type and root element change to ``search`` instead of ``form``.
|
||||
|
||||
.. image:: images/search.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. image:: images/search.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
Following is the list of new elements and features supported in search views.
|
||||
|
||||
@@ -300,9 +302,9 @@ combining them with AND/OR operators. It is also possible to save any search con
|
||||
of all currently applied domain and context values) as a personal filter, which can be recalled
|
||||
at any time. Filters can also be turned into Shortcuts directly available in the User's homepage.
|
||||
|
||||
.. image:: images/filter.png
|
||||
:scale: 50
|
||||
:align: center
|
||||
.. .. image:: images/filter.png
|
||||
.. :scale: 50
|
||||
.. :align: center
|
||||
|
||||
|
||||
In above screenshot we filter Partner where Salesman = Demo user and Country = Belgium,
|
||||
@@ -440,15 +442,15 @@ Screenshots
|
||||
|
||||
Month Calendar:
|
||||
|
||||
.. figure:: images/calendar_month.png
|
||||
:scale: 50%
|
||||
:align: center
|
||||
.. .. figure:: images/calendar_month.png
|
||||
.. :scale: 50%
|
||||
.. :align: center
|
||||
|
||||
Week Calendar:
|
||||
|
||||
.. figure:: images/calendar_week.png
|
||||
:scale: 50%
|
||||
:align: center
|
||||
.. .. figure:: images/calendar_week.png
|
||||
.. :scale: 50%
|
||||
.. :align: center
|
||||
|
||||
|
||||
Gantt Views
|
||||
@@ -556,9 +558,9 @@ end time can be changed by dragging right end of a bar.
|
||||
Screenshots
|
||||
+++++++++++
|
||||
|
||||
.. figure:: images/gantt.png
|
||||
:scale: 50%
|
||||
:align: center
|
||||
.. .. figure:: images/gantt.png
|
||||
.. :scale: 50%
|
||||
.. :align: center
|
||||
|
||||
|
||||
Design Elements
|
||||
@@ -1337,9 +1339,9 @@ The *view_id* method works very well for menus/actions, but how can you specify
|
||||
field, for example? When you have a one2many field, two views are used, a tree view (**in blue**), and a form view when
|
||||
you click on the add button (**in red**).
|
||||
|
||||
.. figure:: images/one2many_views.png
|
||||
:scale: 70%
|
||||
:align: center
|
||||
.. .. figure:: images/one2many_views.png
|
||||
.. :scale: 70%
|
||||
.. :align: center
|
||||
|
||||
When you add a one2many field in a form view, you do something like this :
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _module-dev-actions:
|
||||
|
||||
=================
|
||||
Menus and Actions
|
||||
=================
|
||||
@@ -207,9 +209,9 @@ They indicate at the user that he has to open a new window in a new 'tab'.
|
||||
|
||||
Administration > Custom > Low Level > Base > Action > Window Actions
|
||||
|
||||
.. figure:: images/module_base_action_window.png
|
||||
:scale: 85
|
||||
:align: center
|
||||
.. .. figure:: images/module_base_action_window.png
|
||||
.. :scale: 85
|
||||
.. :align: center
|
||||
|
||||
Examples of actions
|
||||
+++++++++++++++++++
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.. _module-dev-example:
|
||||
|
||||
==========================
|
||||
Example of module creation
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.. _module-dev-versioning:
|
||||
.. _module_versioning:
|
||||
|
||||
=================
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _security:
|
||||
|
||||
==================================
|
||||
Security in OpenERP: users, groups
|
||||
==================================
|
||||
|
||||
@@ -15,10 +15,159 @@
|
||||
Mr Demo</field>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/>
|
||||
<field name="image">/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
|
||||
ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e
|
||||
Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCACEAIQDASIA
|
||||
AhEBAxEB/8QAHQABAAICAwEBAAAAAAAAAAAAAAYIBQcBAgQDCf/EADcQAAEDAwIEBAMHBAIDAAAA
|
||||
AAECAwQABREGEgchMUETIlFhMnGBCBQVI0KRoTNSYsFD0bHw8f/EABoBAAIDAQEAAAAAAAAAAAAA
|
||||
AAAFAQMEBgL/xAAoEQACAgEDAwQBBQAAAAAAAAAAAQIDEQQSIQUxQRMiMlGBM2FxkbH/2gAMAwEA
|
||||
AhEDEQA/ALl0pSgBSlcKoAHr1rBuar0+3eHLO9dY7M9A3FhxW1ZHtnr9KjnEHidYtITFQp7gD20H
|
||||
ry5jp8/n1qnHEPXNw1frFUpc3x0bvyvERtDYPRGOqT9eveqbLdvbuaKqN/y7F7rZqC2Ti+hEttLj
|
||||
LhQpClYPqCB1wR/uu7l+s7aQtVxj7Scbg4MA+h9PrVF42pdTLaVERcXXmQhKPDcwpbRR0KV/EMZP
|
||||
fvXsm6kv/gJedf3SUc3SlQ/MSO59/nVMtVjsi+Ojz3Ze5lxDjYWhYUlQyCD1r6Cq18BeKw/FWLNc
|
||||
5YTBebUn81XNl0cxg+ihkexA9asihaVICgchQyCKvqsU45Ml1Trlg7ilBSrSsUpSgBSlKAFKUoAU
|
||||
pSgDhRqIcStbQtIWnxlbH5jh2ssBYCs46kHtUskLQ00t1xQShCSpSj0AHWqbcYNcQtZ6nkz2oq2r
|
||||
fHSpmMVfE7g48QgdAew9Kqts2LJfp6vUljwQjiPeL7rHUbtyuW0LOUjYrHlzyBx6dBUQRbpCHVJZ
|
||||
baKeXiBQyTz657GstbkPSpqlDdHWPhPYj3FSOFAUtK1OZz0K0JyKWyt55HEaOODCRorzriJTMxtu
|
||||
QjoR0Xj9Kx/uvRcELU63JaWqK5gFThG7w/UKH6k/6rPQbYJTgKPDCweRGMH51l29IzrgnwIrRKjy
|
||||
OByx6VmlcsmmOneDU97XOgXJLyEpYWFBeGj5DzyMe1bD4Ycc9Z6XuCROlv3e3PyPFfZeWCoDoUoJ
|
||||
+AdDj2rLz+FEpUFSZStqgnyAHOPatbX7SsqzKdQs7klIUnd3PPIqynVrsVX6J4yy/HDrWdq1xp9u
|
||||
82nxUNqJStpwYW2odQe1ScVR3gHxL1Bpq5N2O373YhdBVD8ML8bJ54OQUq64xV3IT6JMVqQgKCXU
|
||||
BYCk4UAR3HY03qs3oRXVOuR9qUFKtKRSlKAFKUoAUNKUAa94432TadFT2IicLkRXQtzaVbEYwenT
|
||||
OcZPIVS8MP3OwMxWwd4UduOWU56mrj/aOZdkcNZcZokFxadxGcbRzIOO2BVadB2hCr5b2F5WiRH8
|
||||
bB7Jzn+c0t1s2mOOnVpomHD/AIZLlaa8aW9tkq2lhahk7cd6zMfhdc3JJQ5IR4f95/6qfW55DDKG
|
||||
m8BpICRz7dqzTDpLfTpS1S3PkcSzH4kHtXDO3wcKdfU6rOfQVJodtiwGw1HQlPvisi6sq5ivg4o4
|
||||
5kVVL9iIOT7njnRW3mSCkE461q/Xmn25drmIQ0lTpQS3kd//AJW0nlr2nBxWBuDYVkGss5YkmjVF
|
||||
ZjgqyY70KaFtb2JaSNricghQ5jpV5+D2oDqfh1Z7s48XZC44RIJxnxU8lA49xVZOIemkMTlyIzZL
|
||||
b4Khj9JHYHt6/Ktg/ZUvT0O43HTspeGpCRJjg8sODksD6YOPY060GoTeG+4i6lp/bleCxIpXCOlc
|
||||
05EYpSlAClKUAKHpSlAEJ41x3ZHDy5IaSVYR5wOuzvVW9Mzhb9XPFxeAy2hpHoAAOQ/erk6lhidY
|
||||
LhDx/WjrQPmUnH81RbXDzkK7x7g2NoeUA4PRaeSh/GaXa2OXkbdOswsFgrVN3tJUTkHmKlFre8RA
|
||||
51rW2XNiJZUTJStjYaSr55HSuydV6hdjlVlsLgbI8rz52px64pPGLzkfNprBtNzuArka64TjzVp9
|
||||
HEV23ub7rNZ3A4WGzuGfpU307fhfLeqTGewg8gSOZqJTx4CNWVwerUGpYVsBbaiuTJBHJCKwcZvV
|
||||
N+P3lTMazxxzSlSty1/SopqpGobjdDFgvGCzglUhCRu5dOZ9/SuNDaO1GiCr8f1NOXJU4pSXUSSo
|
||||
7dxKQE4wPLgfSphFSg5NhKMoSUUvySC/W+S/bn4zq2lObSWlt5wFdjg9OdRzhJIWnVcGY6tTJU+2
|
||||
lYCefiBWFD2/3k1sFq1hhnap9b6sfEvqfesXpiBFs+pX0yWkmNJWmSyf7Hd2DVNVm2fB7upUo88l
|
||||
g0fDXNdGFbmkqHcZrvXXLlHEtYYpSlSQKUpQApSlAHVfvVNvtC6c/D9aToUZhQhufnN4HwqUCT/5
|
||||
xVylda11xX06h4KvrMZL7gYLD6FDIKf0n5jmM+9ZtVFuGfo3dPcfV2yeM/6aM0881M0XbJbyA4pD
|
||||
YG08xuAxzrzTrbf9Ub2X7j9wtwRhplLhSVH+5XqPas5aLY7BskrCAGUO+IgDmAFdvbBrI23Y/wAi
|
||||
Ej0z3pNzGSwdPCG6LizXMHQrVpgxba46J3gOlxTxGMnJ6nv1/gVsTS7yY7qEJ2jxDjCeQPblXS/q
|
||||
ZjtJDmVqVySkdKwku4IiFl5T6EcwQcgYNeLZucss1UUxhHaifFlkzMpQjPMK39BXraj4dAbUkewr
|
||||
FQVtToiXlyAtO0FzZz/mvs7KiBkgrUkIPlOfMD7VgllMuccEhcRtaBJ51i1QjLuMdTjoS1G3OFOM
|
||||
7lYwn9s16mHFOQ0nxN4xkK9ayej0Ic1JGS4gKSoK5H1AyKipb7VFeTLdP0qpT+jZNsChb2AoEKDa
|
||||
c569K9FcI6VzXaRWEkcLJ5bYpSlSQKUpQApSlAHBrz3CM3LhuxXk5bdQUq+Rr0d64IqGsgm08o0P
|
||||
e4CrTLnWyQT4hSpGSMeKnqFAd6glsmuMy0NE4AVirT3W2xLjHUxLZC0K+hH1qsPEWyyNNaofjrQo
|
||||
ICtzSz0Wk9D/AKpRrNO4RzE6XQa5XSxLhmQvkuO1EU8sEkJ9M9airkG23J9qRPaipCDyLmDjPpWa
|
||||
C7ZfdPORFuEKxhac4I9PfFRF3TcOJMQFsvOIz+t5Sh/JpdWs5UmO4yz37EwjXKxWxpTUeelLOPM2
|
||||
yrJUflWYjzzcmFRrVZHG9w/rSxhITjrjqflyrEWiNaoiAtuHFY6DagblGp9BkNOQkhISgKGAAK82
|
||||
enFPyXSdSXtWT4aUbmMWRDNxUlchAO5SU4B5+lSjRLZd1O1tHJptS1Y7dhUcnPCMyFBYyP0jvUr4
|
||||
TKS45NcUPO4lJBPXbzGK8aCvfqIirqVm3TzaNgp6VzXArmuuOOFKUoAUpSgBSlKAFKUoA6q61rzj
|
||||
zbLdK0Y5MlMbn2XEJacHxDccEe/yrYautVs4wcYrbetbzeG9tYC2oBBkTCr45CCCW0D0TnmT35dj
|
||||
XquEbJKMuzJU5Q90e5qS5SJlmn7sqCc+VzsoVmrJqZh4JS9hXPmK90thMhOxxCVpVywoZBrHSuHb
|
||||
0kfeLXIEdzGQlXwn/qqdX0FrMqnka6TrmMKxE1sUmPOc3AJ24OPSsxFmx0Jx4uFA4AzWvrNYNRW1
|
||||
wJlnwAeQXzKT+1TCDpxSm0OvSluFRzhPJIrl9RROqWJrB0dWrhbHMOT0PS37hIDMcOFGcK/xA96z
|
||||
k/VUzQ9pYvjDQeZbeabltf3NKVgkehGQa9FrhsR4u1ASMDBI71G+K62lcPLjGUQFvBDLYPdalpCQ
|
||||
PfNGkcoWxx9lGqirKpJ/RYy2S2J9vYmxlBTL7aXEH2IzXpqGcJZviaWZtzh/NhpCMeqe1TJJ5da6
|
||||
6UdrwcbnJzSlK8gKUpQApSlAClMio5r/AFrpnQ1k/F9TXRuDGKvDbGCpx5eCdqEDmo4BOAKAMdxq
|
||||
1vG4fcOrpqV7CnmWvDhtE/1ZC/K2n9yPpX5yaXushvXEK5Sny68/LJkuq6rU6SVK+qjmtifaY4uv
|
||||
cT9RsM25EqJYLeD91jPgBTjpyFPKAJ545JHYE+tafWjKcYHyqFLbJNeD0o8FuY0cPhG3BwnJPtUt
|
||||
060H4iFbTtTyPtVZuFPFJyyuos+qXFPWxXkRMOVORx/l3UntnqPftaTSK47traeivtvMPJDja0K3
|
||||
BST0OR1p5XfG2OV3MM63BmR2o2bdoKRywa6JisDKmB4RPUJ6ftX0UQFkAg+9EkNrznkexqLaYXLb
|
||||
NZJrunW8xeDyyj92aU466httIJUvGBgevpWqL3rHTt81fDQ/fYLFltjhcbU45gSH8YCz22pycZ78
|
||||
+wrL/aF1s1p3R33OK7i4XjdGjYIy23j8x36DkPciq120sLaKEbSrGACMgDtypHHpNFWo3Rf4HEuq
|
||||
3W07Gi7+k9RxLYE3xl377AXHUpZikOeIkDPkwcKPKpJpDjRwz1R4aLbquE0+58MeYTHcPyC8Z+ma
|
||||
pZwQ1fJ0rrIWt95Rs1wc2PNKVlLKzna6kdBz5K9QQe1YrjPp5WmdfzYraR9xnkzIh6jCz50/IK5/
|
||||
JQ9K16j3Lf8A2LocPB+k7TqHUBxpaVoPRSSCD9RXfIxnNfmXoziBq/SjyVaf1HcbcE4/KQ9vZx6e
|
||||
GrKf4rfvDz7Vlzafai64sjMtg8lTbcNjifdTROFe5SR7JrIpFziW4pWtLXx14VzoaZI1bFjbv+OU
|
||||
hbSx80kUqcojDNl0pSoIOqzjH/vavzX426zv+s+Id0nXyX4n3OZIhRGW8pajstulAShOTjO3Kj1J
|
||||
9gAFKlnpEBkHl4o5KGPrXZY5A0pXhns6KSDnPYZrbX2XtVXqHq9OkkSt9olNLe8FzzeCtJHNB/SD
|
||||
nmOY9hSlXadtTRVb2LQSiUqKQT5TgV5HnFrbbSTgKODj50pT5i8rF9qIrXxGUtTiyGWUMNIz5W0A
|
||||
ZwB7k5Prgela0t77jb6ClXUUpSm79U2Q+Jn2gHLJc7tgJlQHmlsqHQnOfMO45Vsnjc/+LcNLfdZL
|
||||
TaZMG6NMslsYAbdjhSkn2ycj5ClK9v4S/gjyjTYAU2CeoruwtQO3qPelKWmk96HnEpAStQHso0pS
|
||||
gk//2Q==</field>
|
||||
</record>
|
||||
|
||||
<record model="res.partner" id="base.partner_root">
|
||||
<field name="email">admin@example.com</field>
|
||||
<field name="image">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
|
||||
kALR5oiAU7jnCuj0RFIHQbIiKAf/2Q==</field>
|
||||
</record>
|
||||
|
||||
<!-- new rate for demo transactions in multi currency -->
|
||||
@@ -27,5 +176,6 @@ Mr Demo</field>
|
||||
<field name="currency_id" ref="USD"/>
|
||||
<field eval="time.strftime('%Y-06-06')" name="name"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
+5710
-5796
File diff suppressed because it is too large
Load Diff
+5753
-5812
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+6903
-6124
File diff suppressed because it is too large
Load Diff
+4942
-5069
File diff suppressed because it is too large
Load Diff
+6656
-6051
File diff suppressed because it is too large
Load Diff
+5798
-5819
File diff suppressed because it is too large
Load Diff
+6947
-6145
File diff suppressed because it is too large
Load Diff
+7413
-6238
File diff suppressed because it is too large
Load Diff
+5912
-5855
File diff suppressed because it is too large
Load Diff
+12242
-8491
File diff suppressed because it is too large
Load Diff
+6542
-6026
File diff suppressed because it is too large
Load Diff
+8534
-6808
File diff suppressed because it is too large
Load Diff
+10851
-7653
File diff suppressed because it is too large
Load Diff
+6256
-5970
File diff suppressed because it is too large
Load Diff
+7028
-6178
File diff suppressed because it is too large
Load Diff
+13954
-9362
File diff suppressed because it is too large
Load Diff
+7950
-6483
File diff suppressed because it is too large
Load Diff
+5719
-5798
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+6341
-5970
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+6528
-6051
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+7323
-6203
File diff suppressed because it is too large
Load Diff
+11036
-7945
File diff suppressed because it is too large
Load Diff
+6948
-6146
File diff suppressed because it is too large
Load Diff
+6069
-5888
File diff suppressed because it is too large
Load Diff
+6174
-5938
File diff suppressed because it is too large
Load Diff
+7059
-6162
File diff suppressed because it is too large
Load Diff
+7757
-6309
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+5740
-5804
File diff suppressed because it is too large
Load Diff
+5984
-5860
File diff suppressed because it is too large
Load Diff
+7082
-6188
File diff suppressed because it is too large
Load Diff
+13000
-8478
File diff suppressed because it is too large
Load Diff
+10349
-7629
File diff suppressed because it is too large
Load Diff
+5906
-5859
File diff suppressed because it is too large
Load Diff
+6317
-5929
File diff suppressed because it is too large
Load Diff
+6020
-5863
File diff suppressed because it is too large
Load Diff
+6568
-6031
File diff suppressed because it is too large
Load Diff
+5924
-5868
File diff suppressed because it is too large
Load Diff
+12407
-8439
File diff suppressed because it is too large
Load Diff
+6482
-6013
File diff suppressed because it is too large
Load Diff
+8357
-6579
File diff suppressed because it is too large
Load Diff
+5755
-5804
File diff suppressed because it is too large
Load Diff
+6855
-6114
File diff suppressed because it is too large
Load Diff
+7883
-6413
File diff suppressed because it is too large
Load Diff
+9752
-7267
File diff suppressed because it is too large
Load Diff
+13878
-9292
File diff suppressed because it is too large
Load Diff
+13095
-8883
File diff suppressed because it is too large
Load Diff
+6799
-6081
File diff suppressed because it is too large
Load Diff
+6988
-6142
File diff suppressed because it is too large
Load Diff
+5713
-5795
File diff suppressed because it is too large
Load Diff
+6655
-6052
File diff suppressed because it is too large
Load Diff
+10513
-7534
File diff suppressed because it is too large
Load Diff
+8304
-6698
File diff suppressed because it is too large
Load Diff
+5712
-5798
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+7496
-6244
File diff suppressed because it is too large
Load Diff
+6210
-5943
File diff suppressed because it is too large
Load Diff
+5710
-5796
File diff suppressed because it is too large
Load Diff
+6256
-5931
File diff suppressed because it is too large
Load Diff
+9945
-6840
File diff suppressed because it is too large
Load Diff
+5796
-5831
File diff suppressed because it is too large
Load Diff
+6544
-5998
File diff suppressed because it is too large
Load Diff
@@ -51,12 +51,14 @@ class ir_config_parameter(osv.osv):
|
||||
('key_uniq', 'unique (key)', 'Key must be unique.')
|
||||
]
|
||||
|
||||
def init(self, cr):
|
||||
def init(self, cr, force=False):
|
||||
"""
|
||||
Initializes the parameters listed in _default_parameters.
|
||||
It overrides existing parameters if force is ``True``.
|
||||
"""
|
||||
for key, func in _default_parameters.iteritems():
|
||||
ids = self.search(cr, SUPERUSER_ID, [('key','=',key)])
|
||||
# force=True skips search and always performs the 'if' body (because ids=False)
|
||||
ids = not force and self.search(cr, SUPERUSER_ID, [('key','=',key)])
|
||||
if not ids:
|
||||
self.set_param(cr, SUPERUSER_ID, key, func())
|
||||
|
||||
|
||||
@@ -73,7 +73,15 @@ class base_language_export(osv.osv_memory):
|
||||
self.write(cr, uid, ids, {'state': 'get',
|
||||
'data': out,
|
||||
'name':this.name}, context=context)
|
||||
return True
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'base.language.export',
|
||||
'view_mode': 'form',
|
||||
'view_type': 'form',
|
||||
'res_id': this.id,
|
||||
'views': [(False, 'form')],
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -127,7 +127,7 @@ class res_currency(osv.osv):
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
reads = self.read(cr, uid, ids, ['name','symbol'], context=context, load='_classic_write')
|
||||
return [(x['id'], tools.ustr(x['name']) + (x['symbol'] and (' (' + tools.ustr(x['symbol']) + ')') or '')) for x in reads]
|
||||
return [(x['id'], tools.ustr(x['name'])) for x in reads]
|
||||
|
||||
def round(self, cr, uid, currency, amount):
|
||||
"""Return ``amount`` rounded according to ``currency``'s
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<menuitem name="Sales"
|
||||
id="menu_base_partner"
|
||||
groups="base.group_sale_salesman"
|
||||
sequence="30"/>
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem id="base.menu_sales" parent="base.menu_base_partner" name="Sales" sequence="1" />
|
||||
<menuitem id="menu_base_config" parent="menu_base_partner" name="Configuration" sequence="30" groups="group_system"/>
|
||||
|
||||
@@ -398,10 +398,10 @@ class res_users(osv.osv):
|
||||
# prevent/delay login in that case. It will also have been logged
|
||||
# as a SQL error, if anyone cares.
|
||||
try:
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s FOR UPDATE NOWAIT", (user_id,))
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s FOR UPDATE NOWAIT", (user_id,), log_exceptions=False)
|
||||
cr.execute("UPDATE res_users SET login_date = now() AT TIME ZONE 'UTC' WHERE id=%s", (user_id,))
|
||||
except Exception, e:
|
||||
_logger.exception("Failed to update last_login for db:%s login:%s", db, login)
|
||||
except Exception:
|
||||
_logger.debug("Failed to update last_login for db:%s login:%s", db, login, exc_info=True)
|
||||
except openerp.exceptions.AccessDenied:
|
||||
_logger.info("Login failed for db:%s login:%s", db, login)
|
||||
user_id = False
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import test_base, test_expression, test_ir_values
|
||||
import test_base, test_expression, test_search, test_ir_values
|
||||
|
||||
checks = [
|
||||
test_base,
|
||||
test_expression,
|
||||
test_search,
|
||||
test_ir_values,
|
||||
]
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import unittest2
|
||||
|
||||
import openerp.tests.common as common
|
||||
|
||||
class test_expression(common.TransactionCase):
|
||||
|
||||
def test_search_order(self):
|
||||
|
||||
registry, cr, uid = self.registry, self.cr, self.uid
|
||||
|
||||
# Create 6 partners with a given name, and a given creation order to
|
||||
# ensure the order of their ID. Some are set as unactive to verify they
|
||||
# are by default excluded from the searches and to provide a second
|
||||
# `order` argument.
|
||||
|
||||
partners = registry('res.partner')
|
||||
c = partners.create(cr, uid, {'name': 'test_search_order_C'})
|
||||
d = partners.create(cr, uid, {'name': 'test_search_order_D', 'active': False})
|
||||
a = partners.create(cr, uid, {'name': 'test_search_order_A'})
|
||||
b = partners.create(cr, uid, {'name': 'test_search_order_B'})
|
||||
ab = partners.create(cr, uid, {'name': 'test_search_order_AB'})
|
||||
e = partners.create(cr, uid, {'name': 'test_search_order_E', 'active': False})
|
||||
|
||||
# The tests.
|
||||
|
||||
# The basic searches should exclude records that have active = False.
|
||||
# The order of the returned ids should be given by the `order`
|
||||
# parameter of search().
|
||||
|
||||
name_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="name asc")
|
||||
self.assertEqual([a, ab, b, c], name_asc, "Search with 'NAME ASC' order failed.")
|
||||
name_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="name desc")
|
||||
self.assertEqual([c, b, ab, a], name_desc, "Search with 'NAME DESC' order failed.")
|
||||
id_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="id asc")
|
||||
self.assertEqual([c, a, b, ab], id_asc, "Search with 'ID ASC' order failed.")
|
||||
id_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%')], order="id desc")
|
||||
self.assertEqual([ab, b, a, c], id_desc, "Search with 'ID DESC' order failed.")
|
||||
|
||||
# The inactive records shouldn't be excluded as soon as a condition on
|
||||
# that field is present in the domain. The `order` parameter of
|
||||
# search() should support any legal coma-separated values.
|
||||
|
||||
active_asc_id_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="active asc, id asc")
|
||||
self.assertEqual([d, e, c, a, b, ab], active_asc_id_asc, "Search with 'ACTIVE ASC, ID ASC' order failed.")
|
||||
active_desc_id_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="active desc, id asc")
|
||||
self.assertEqual([c, a, b, ab, d, e], active_desc_id_asc, "Search with 'ACTIVE DESC, ID ASC' order failed.")
|
||||
active_asc_id_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="active asc, id desc")
|
||||
self.assertEqual([e, d, ab, b, a, c], active_asc_id_desc, "Search with 'ACTIVE ASC, ID DESC' order failed.")
|
||||
active_desc_id_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="active desc, id desc")
|
||||
self.assertEqual([ab, b, a, c, e, d], active_desc_id_desc, "Search with 'ACTIVE DESC, ID DESC' order failed.")
|
||||
id_asc_active_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="id asc, active asc")
|
||||
self.assertEqual([c, d, a, b, ab, e], id_asc_active_asc, "Search with 'ID ASC, ACTIVE ASC' order failed.")
|
||||
id_asc_active_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="id asc, active desc")
|
||||
self.assertEqual([c, d, a, b, ab, e], id_asc_active_desc, "Search with 'ID ASC, ACTIVE DESC' order failed.")
|
||||
id_desc_active_asc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="id desc, active asc")
|
||||
self.assertEqual([e, ab, b, a, d, c], id_desc_active_asc, "Search with 'ID DESC, ACTIVE ASC' order failed.")
|
||||
id_desc_active_desc = partners.search(cr, uid, [('name', 'like', 'test_search_order%'), '|', ('active', '=', True), ('active', '=', False)], order="id desc, active desc")
|
||||
self.assertEqual([e, ab, b, a, d, c], id_desc_active_desc, "Search with 'ID DESC, ACTIVE DESC' order failed.")
|
||||
|
||||
|
||||
@@ -348,7 +348,8 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
||||
for (model, name) in cr.fetchall():
|
||||
model_obj = pool.get(model)
|
||||
if model_obj and not model_obj.is_transient():
|
||||
_logger.warning('Model %s (%s) has no access rules!', model, name)
|
||||
_logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,1,1,1',
|
||||
model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_'))
|
||||
|
||||
# Temporary warning while we remove access rights on osv_memory objects, as they have
|
||||
# been replaced by owner-only access rights
|
||||
|
||||
@@ -234,6 +234,8 @@ class html(text):
|
||||
_type = 'html'
|
||||
_symbol_c = '%s'
|
||||
def _symbol_f(x):
|
||||
if x is None or x == False:
|
||||
return None
|
||||
return html_sanitize(x)
|
||||
|
||||
_symbol_set = (_symbol_c, _symbol_f)
|
||||
|
||||
+4
-4
@@ -1603,7 +1603,7 @@ class BaseModel(object):
|
||||
if fld_def._type == 'many2many':
|
||||
obj = self.pool.get(fld_def._obj)
|
||||
field_value2 = []
|
||||
for i in range(len(field_value)):
|
||||
for i in range(len(field_value or [])):
|
||||
if not obj.search(cr, uid, [('id', '=',
|
||||
field_value[i])]):
|
||||
continue
|
||||
@@ -1612,7 +1612,7 @@ class BaseModel(object):
|
||||
if fld_def._type == 'one2many':
|
||||
obj = self.pool.get(fld_def._obj)
|
||||
field_value2 = []
|
||||
for i in range(len(field_value)):
|
||||
for i in range(len(field_value or [])):
|
||||
field_value2.append({})
|
||||
for field2 in field_value[i]:
|
||||
if field2 in obj._columns.keys() and obj._columns[field2]._type == 'many2one':
|
||||
@@ -1782,7 +1782,7 @@ class BaseModel(object):
|
||||
# TODO: find a way to remove this hack, by allow dynamic domains
|
||||
dom = []
|
||||
if column._domain and not isinstance(column._domain, basestring):
|
||||
dom = column._domain
|
||||
dom = list(column._domain)
|
||||
dom += eval(node.get('domain', '[]'), {'uid': user, 'time': time})
|
||||
search_context = dict(context)
|
||||
if column._context and not isinstance(column._context, basestring):
|
||||
@@ -4722,7 +4722,7 @@ class BaseModel(object):
|
||||
order_direction = order_split[1].strip() if len(order_split) == 2 else ''
|
||||
inner_clause = None
|
||||
if order_field == 'id':
|
||||
order_by_clause = '"%s"."%s"' % (self._table, order_field)
|
||||
order_by_elements.append('"%s"."id" %s' % (self._table, order_direction))
|
||||
elif order_field in self._columns:
|
||||
order_column = self._columns[order_field]
|
||||
if order_column._classic_read:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
'maintainer': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'data': ['view.xml'],
|
||||
'data': ['view.xml', 'ir.model.access.csv'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_test_exceptions_model,access_test_exceptions_model,model_test_exceptions_model,,1,1,1,1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
'maintainer': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'data': [],
|
||||
'data': ['ir.model.access.csv'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_export_boolean,access_export_boolean,model_export_boolean,,1,1,1,1
|
||||
access_export_integer,access_export_integer,model_export_integer,,1,1,1,1
|
||||
access_export_float,access_export_float,model_export_float,,1,1,1,1
|
||||
access_export_decimal,access_export_decimal,model_export_decimal,,1,1,1,1
|
||||
access_export_string_bounded,access_export_string_bounded,model_export_string_bounded,,1,1,1,1
|
||||
access_export_string_required,access_export_string_required,model_export_string_required,,1,1,1,1
|
||||
access_export_string,access_export_string,model_export_string,,1,1,1,1
|
||||
access_export_date,access_export_date,model_export_date,,1,1,1,1
|
||||
access_export_datetime,access_export_datetime,model_export_datetime,,1,1,1,1
|
||||
access_export_text,access_export_text,model_export_text,,1,1,1,1
|
||||
access_export_selection,access_export_selection,model_export_selection,,1,1,1,1
|
||||
access_export_selection_function,access_export_selection_function,model_export_selection_function,,1,1,1,1
|
||||
access_export_many2one,access_export_many2one,model_export_many2one,,1,1,1,1
|
||||
access_export_one2many,access_export_one2many,model_export_one2many,,1,1,1,1
|
||||
access_export_many2many,access_export_many2many,model_export_many2many,,1,1,1,1
|
||||
access_export_function,access_export_function,model_export_function,,1,1,1,1
|
||||
access_export_one2many_child,access_export_one2many_child,model_export_one2many_child,,1,1,1,1
|
||||
access_export_one2many_multiple,access_export_one2many_multiple,model_export_one2many_multiple,,1,1,1,1
|
||||
access_export_one2many_multiple_child,access_export_one2many_multiple_child,model_export_one2many_multiple_child,,1,1,1,1
|
||||
access_export_one2many_child_1,access_export_one2many_child_1,model_export_one2many_child_1,,1,1,1,1
|
||||
access_export_one2many_child_2,access_export_one2many_child_2,model_export_one2many_child_2,,1,1,1,1
|
||||
access_export_many2many_other,access_export_many2many_other,model_export_many2many_other,,1,1,1,1
|
||||
access_export_selection_withdefault,access_export_selection_withdefault,model_export_selection_withdefault,,1,1,1,1
|
||||
access_export_one2many_recursive,access_export_one2many_recursive,model_export_one2many_recursive,,1,1,1,1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
'maintainer': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'data': [],
|
||||
'data': ['ir.model.access.csv'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_test_limits_model,access_test_limits_model,model_test_limits_model,,1,1,1,1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
'maintainer': 'OpenERP SA',
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base'],
|
||||
'data': [],
|
||||
'data': ['ir.model.access.csv'],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_test_uninstall_model,access_test_uninstall_model,model_test_uninstall_model,,1,1,1,1
|
||||
|
@@ -9,8 +9,8 @@ import common
|
||||
DB = common.DB
|
||||
ADMIN_USER_ID = common.ADMIN_USER_ID
|
||||
|
||||
def cursor():
|
||||
return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
|
||||
def registry():
|
||||
return openerp.modules.registry.RegistryManager.get(DB)
|
||||
|
||||
|
||||
class test_cr_execute(unittest2.TestCase):
|
||||
@@ -21,12 +21,12 @@ class test_cr_execute(unittest2.TestCase):
|
||||
"""
|
||||
Try to use iterable but non-list or int params in query parameters.
|
||||
"""
|
||||
cr = cursor()
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE login=%s", 'admin')
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s", 1)
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s", '1')
|
||||
with registry().cursor(auto_commit=False) as cr:
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE login=%s", 'admin')
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s", 1)
|
||||
with self.assertRaises(ValueError):
|
||||
cr.execute("SELECT id FROM res_users WHERE id=%s", '1')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -173,6 +173,9 @@ class TestCleaner(unittest2.TestCase):
|
||||
new_html = html_email_clean(TEXT_TPL)
|
||||
self.assertNotIn('quote', new_html, 'html_email_cleaner did not remove correctly plaintext quotes')
|
||||
|
||||
# Test5: False boolean for text must return empty string
|
||||
new_html = html_email_clean(False)
|
||||
self.assertEqual(new_html, False, 'html_email_cleaner did change a False in an other value.')
|
||||
|
||||
class TestHtmlTools(unittest2.TestCase):
|
||||
""" Test some of our generic utility functions about html """
|
||||
|
||||
@@ -109,6 +109,7 @@ class TestInherits(common.TransactionCase):
|
||||
self.assertEqual(foo.name, 'Foo')
|
||||
self.assertEqual(foo.partner_id.id, par_id)
|
||||
|
||||
@mute_logger('openerp.osv.orm')
|
||||
def test_read(self):
|
||||
""" inherited fields should be read without any indirection """
|
||||
foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
|
||||
@@ -120,6 +121,7 @@ class TestInherits(common.TransactionCase):
|
||||
foo = self.user.browse(self.cr, UID, foo_id)
|
||||
self.assertEqual(foo.name, foo.partner_id.name)
|
||||
|
||||
@mute_logger('openerp.osv.orm')
|
||||
def test_copy(self):
|
||||
""" copying a user should automatically copy its partner, too """
|
||||
foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
|
||||
@@ -134,6 +136,7 @@ class TestInherits(common.TransactionCase):
|
||||
self.assertNotEqual(foo.id, bar.id)
|
||||
self.assertNotEqual(foo.partner_id.id, bar.partner_id.id)
|
||||
|
||||
@mute_logger('openerp.osv.orm')
|
||||
def test_copy_with_ancestor(self):
|
||||
""" copying a user with 'parent_id' in defaults should not duplicate the partner """
|
||||
foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
|
||||
|
||||
@@ -130,6 +130,9 @@ def html_email_clean(html):
|
||||
dest += source[idx:]
|
||||
return dest
|
||||
|
||||
if not html:
|
||||
return html
|
||||
|
||||
html = ustr(html)
|
||||
|
||||
# 1. <br[ /]> -> \n, because otherwise the tree is obfuscated
|
||||
|
||||
@@ -23,7 +23,6 @@ import codecs
|
||||
import csv
|
||||
import fnmatch
|
||||
import inspect
|
||||
import itertools
|
||||
import locale
|
||||
import os
|
||||
import openerp.pooler as pooler
|
||||
@@ -512,7 +511,7 @@ def trans_parse_rml(de):
|
||||
|
||||
def trans_parse_view(de):
|
||||
res = []
|
||||
if de.text and de.text.strip():
|
||||
if not isinstance(de, SKIPPED_ELEMENT_TYPES) and de.text and de.text.strip():
|
||||
res.append(de.text.strip().encode("utf8"))
|
||||
if de.tail and de.tail.strip():
|
||||
res.append(de.tail.strip().encode("utf8"))
|
||||
@@ -618,7 +617,12 @@ def trans_generate(lang, modules, cr):
|
||||
_to_translate = []
|
||||
def push_translation(module, type, name, id, source, comments=None):
|
||||
tuple = (module, source, name, id, type, comments or [])
|
||||
if source and tuple not in _to_translate:
|
||||
# empty and one-letter terms are ignored, they probably are not meant to be
|
||||
# translated, and would be very hard to translate anyway.
|
||||
if not source or len(source.strip()) <= 1:
|
||||
_logger.debug("Ignoring empty or 1-letter source term: %r", tuple)
|
||||
return
|
||||
if tuple not in _to_translate:
|
||||
_to_translate.append(tuple)
|
||||
|
||||
def encode(s):
|
||||
@@ -841,6 +845,8 @@ def trans_generate(lang, modules, cr):
|
||||
keywords=extract_keywords):
|
||||
push_translation(module, trans_type, display_path, lineno,
|
||||
encode(message), comments + extra_comments)
|
||||
except Exception:
|
||||
_logger.exception("Failed to extract terms from %s", fabsolutepath)
|
||||
finally:
|
||||
src_file.close()
|
||||
|
||||
@@ -856,7 +862,7 @@ def trans_generate(lang, modules, cr):
|
||||
for fname in fnmatch.filter(files, '*.js'):
|
||||
babel_extract_terms(fname, path, root, 'javascript',
|
||||
extra_comments=[WEB_TRANSLATION_COMMENT],
|
||||
extract_keywords={'_t': None})
|
||||
extract_keywords={'_t': None, '_lt': None})
|
||||
# QWeb template files
|
||||
if fnmatch.fnmatch(root, '*/static/src/xml*'):
|
||||
for fname in fnmatch.filter(files, '*.xml'):
|
||||
|
||||
Reference in New Issue
Block a user