[MERGE] merged with latest server
bzr revid: bde@tinyerp.com-20140212100909-rbfkncfa5i9gn7rv
This commit is contained in:
commit
6dca8bf3fb
|
@ -2,12 +2,11 @@ graft debian
|
|||
graft doc
|
||||
graft install
|
||||
graft openerp
|
||||
graft tests
|
||||
graft win32
|
||||
include README
|
||||
include LICENSE
|
||||
include MANIFEST.in
|
||||
include openerp-wsgi.py
|
||||
include openerp-server
|
||||
include openerp-*
|
||||
include oe*
|
||||
include setup*
|
||||
global-exclude *pyc *~ # Exclude possible garbage from previous graft.
|
||||
|
|
|
@ -172,40 +172,80 @@ is as follows:
|
|||
</data>
|
||||
</openerp>
|
||||
|
||||
Record Tag
|
||||
//////////
|
||||
``<record>``
|
||||
////////////
|
||||
|
||||
**Description**
|
||||
Defines a new record in a specified OpenERP model.
|
||||
|
||||
The addition of new data is made with the record tag. This one takes a
|
||||
mandatory attribute : model. Model is the object name where the insertion has
|
||||
to be done. The tag record can also take an optional attribute: id. If this
|
||||
attribute is given, a variable of this name can be used later on, in the same
|
||||
file, to make reference to the newly created resource ID.
|
||||
``@model`` (required)
|
||||
|
||||
A record tag may contain field tags. They indicate the record's fields value.
|
||||
If a field is not specified the default value will be used.
|
||||
Name of the model in which this record will be created/inserted.
|
||||
|
||||
The Record Field tag
|
||||
////////////////////
|
||||
``@id`` (optional)
|
||||
|
||||
The attributes for the field tag are the following:
|
||||
:term:`external ID` for the record, also allows referring to this record in
|
||||
the rest of this file or in other files (through ``field/@ref`` or the
|
||||
:py:func:`ref() <openerp.tools.convert._ref>` function)
|
||||
|
||||
name : mandatory
|
||||
the field name
|
||||
A record tag generally contains multiple ``field`` tags specifying the values
|
||||
set on the record's fields when creating it. Fields left out will be set to
|
||||
their default value unless required.
|
||||
|
||||
eval : optional
|
||||
python expression that indicating the value to add
|
||||
|
||||
ref
|
||||
reference to an id defined in this file
|
||||
``<field>``
|
||||
///////////
|
||||
|
||||
model
|
||||
model to be looked up in the search
|
||||
In its most basic use, the ``field`` tag will set its body (as a string) as
|
||||
the value of the corresponding ``record``'s ``@name`` field.
|
||||
|
||||
search
|
||||
a query
|
||||
Extra attributes can either preprocess the body or replace its use entirely:
|
||||
|
||||
``@name`` (mandatory)
|
||||
|
||||
Name of the field in the containing ``record``'s model
|
||||
|
||||
``@type`` (optional)
|
||||
|
||||
One of ``char``, ``int``, ``float``, ``list``, ``tuple``, ``xml`` or
|
||||
``html``, ``file`` or ``base64``. Converts the ``field``'s body to the
|
||||
specified type (or validates the body's content)
|
||||
|
||||
* ``xml`` will join multiple XML nodes under a single ``<data>`` root
|
||||
* in ``xml`` and ``html``, external ids can be referenced using
|
||||
``%(id_name)s``
|
||||
* ``list`` and ``tuple``'s element are specified using ``<value>``
|
||||
sub-nodes with the same attributes as ``field``.
|
||||
* ``file`` expects a module-local path and will save the path prefixed with
|
||||
the current module's name, separated by a ``,`` (comma). For use with
|
||||
:py:func:`~openerp.modules.module.get_module_resource`.
|
||||
* ``base64`` expects binary data, encodes it to base64 and sets it. Mostly
|
||||
useful with ``@file``
|
||||
|
||||
``@file``
|
||||
|
||||
Can be used with types ``char`` and ``base64``, sources the field's content
|
||||
from the specified file instead of the field's text body.
|
||||
|
||||
``@model``
|
||||
|
||||
Model used for ``@search``'s search, or registry object put in context for
|
||||
``@eval``. Required if ``@search`` but optional if ``@eval``.
|
||||
|
||||
``@eval`` (optional)
|
||||
|
||||
A Python expression evaluated to obtain the value to set on the record
|
||||
|
||||
``@ref`` (optional)
|
||||
|
||||
Links to an other record through its :term:`external id`. The module prefix
|
||||
may be ommitted to link to a record defined in the same module.
|
||||
|
||||
``@search`` (optional)
|
||||
|
||||
Search domain (evaluated Python expression) into ``@model`` to get the
|
||||
records to set on the field.
|
||||
|
||||
Sets all the matches found for m2m fields, the first id for other field
|
||||
types.
|
||||
|
||||
**Example**
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
.. _qweb:
|
||||
|
||||
====
|
||||
QWeb
|
||||
====
|
||||
|
||||
``t-field``
|
||||
===========
|
||||
|
||||
The server version of qweb includes a directive dedicated specifically to
|
||||
formatting and rendering field values from
|
||||
:class:`~openerp.osv.orm.browse_record` objects.
|
||||
|
||||
The directive is implemented through
|
||||
:meth:`~base.ir.ir_qweb.QWeb.render_tag_field` on the ``ir.qweb`` openerp
|
||||
object, and generally delegates to converters for rendering. These converters
|
||||
are obtained through :meth:`~base.ir.ir_qweb.QWeb.get_converter_for`.
|
||||
|
||||
By default, the key for obtaining a converter is the type of the field's
|
||||
column, but this can be overridden by providing a ``widget`` as field option.
|
||||
|
||||
Field options are specified through ``t-field-options``, which must be a JSON
|
||||
object (map). Custom widgets may define their own (possibly mandatory) options.
|
||||
|
||||
Global options
|
||||
--------------
|
||||
|
||||
A global option ``html-escape`` is provided. It defaults to ``True``, and for
|
||||
many (not all) fields it determines whether the field's output will be
|
||||
html-escaped before being output.
|
||||
|
||||
Date and datetime converters
|
||||
----------------------------
|
||||
|
||||
The default rendering for ``date`` and ``datetime`` fields. They render the
|
||||
field's value according to the current user's ``lang.date_format`` and
|
||||
``lang.time_format``. The ``datetime`` converter will also localize the value
|
||||
to the user's timezone (as defined by the ``tz`` context key, or the timezone
|
||||
in the user's profile if there is no ``tz`` key in the context).
|
||||
|
||||
A custom format can be provided to use a non-default rendering. The custom
|
||||
format uses the ``format`` options key, and uses the
|
||||
`ldml date format patterns`_ [#ldml]_.
|
||||
|
||||
For instance if one wanted a date field to be rendered as
|
||||
"(month) (day of month)" rather than whatever the default is, one could use:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<span t-field="object.datefield" t-field-options='{"format": "MMMM d"}'/>
|
||||
|
||||
Monetary converter (widget: ``monetary``)
|
||||
-----------------------------------------
|
||||
|
||||
Used to format and render monetary value, requires a ``display_currency``
|
||||
options value which is a path from the rendering context to a ``res.currency``
|
||||
object. This object is used to set the right currency symbol, and set it at the
|
||||
right position relative to the formatted value.
|
||||
|
||||
The field itself should be a float field.
|
||||
|
||||
Relative Datetime (widget: ``relative``)
|
||||
----------------------------------------
|
||||
|
||||
Used on a ``datetime`` field, formats it relatively to the current time
|
||||
(``datetime.now()``), e.g. if the field's value is 3 hours before now and the
|
||||
user's lang is english, it will render to *3 hours ago*.
|
||||
|
||||
.. note:: this field uses babel's ``format_timedelta`` more or less directly
|
||||
and will only display the biggest unit and round up at 85% e.g.
|
||||
1 hour 15 minutes will be rendered as *1 hour*, and 55 minutes will
|
||||
also be rendered as *1 hour*.
|
||||
|
||||
.. warning:: this converter *requires* babel 1.0 or more recent.
|
||||
|
||||
Duration (widget: ``duration``)
|
||||
-------------------------------
|
||||
|
||||
Renders a duration defined as a ``float`` to a human-readable localized string,
|
||||
e.g. ``1.5`` as hours in an english locale will be rendered to
|
||||
*1 hour 30 minutes*.
|
||||
|
||||
Requires a ``unit`` option which may be one of ``second``, ``minute``,
|
||||
``hour``, ``day``, ``week``, ``month`` or ``year``. This specifies the unit in
|
||||
which the value should be interpreted before formatting.
|
||||
|
||||
The duration must be a positive number, and no rounding is applied.
|
||||
|
||||
.. [#ldml] in part because `babel`_ is used for rendering, as ``strftime``
|
||||
would require altering the process's locale on the fly in order to
|
||||
get correctly localized date and time output. Babel uses the CLDR
|
||||
as its core and thus uses LDML date format patterns.
|
||||
|
||||
.. _babel: http://babel.pocoo.org
|
||||
|
||||
.. _ldml date format patterns:
|
||||
http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
|
||||
|
|
@ -11,3 +11,4 @@ Miscellanous
|
|||
06_misc_user_img_specs.rst
|
||||
06_misc_import.rst
|
||||
06_misc_auto_join.rst
|
||||
06_ir_qweb.rst
|
||||
|
|
|
@ -252,5 +252,4 @@ texinfo_documents = [
|
|||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {
|
||||
'python': ('http://docs.python.org/', None),
|
||||
'openerpweb': ('http://doc.openerp.com/trunk/developers/web', None),
|
||||
}
|
||||
|
|
|
@ -12,26 +12,20 @@ Server actions
|
|||
|
||||
.. currentmodule:: openerp.addons.base.ir.ir_actions
|
||||
|
||||
.. autoclass:: actions_server
|
||||
:noindex:
|
||||
.. autoclass:: ir_actions_server
|
||||
:members: run, _get_states
|
||||
|
||||
Adding a new sever action
|
||||
-------------------------
|
||||
|
||||
The ``state`` field holds the various available types of server action. In order
|
||||
to add a new server action, the first thing to do is to override the ``_get_states``
|
||||
to add a new server action, the first thing to do is to override the :meth:`~.ir_actions_server._get_states`
|
||||
method that returns the list of values available for the selection field.
|
||||
|
||||
.. automethod:: actions_server._get_states
|
||||
:noindex:
|
||||
|
||||
The method called when executing the server action is the ``run`` method. This
|
||||
The method called when executing the server action is the :meth:`~.ir_actions_server.run` method. This
|
||||
method calls ``run_action_<STATE>``. When adding a new server action type, you
|
||||
have to define the related method that will be called upon execution.
|
||||
|
||||
.. automethod:: actions_server.run
|
||||
:noindex:
|
||||
|
||||
Changelog
|
||||
---------
|
||||
|
||||
|
|
|
@ -19,17 +19,27 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
""" OpenERP core library..
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
""" OpenERP core library."""
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Running mode flags (gevent, prefork)
|
||||
#----------------------------------------------------------
|
||||
# Is the server running with gevent.
|
||||
import sys
|
||||
evented = False
|
||||
if sys.modules.get("gevent") is not None:
|
||||
evented = True
|
||||
|
||||
# Is the server running in pefork mode (e.g. behind Gunicorn).
|
||||
# If this is True, the processes have to communicate some events,
|
||||
# e.g. database update or cache invalidation. Each process has also
|
||||
# its own copy of the data structure and we don't need to care about
|
||||
# locks between threads.
|
||||
multi_process = False
|
||||
|
||||
#----------------------------------------------------------
|
||||
# libc UTC hack
|
||||
#----------------------------------------------------------
|
||||
# Make sure the OpenERP server runs in UTC. This is especially necessary
|
||||
# under Windows as under Linux it seems the real import of time is
|
||||
# sufficiently deferred so that setting the TZ environment variable
|
||||
|
@ -40,9 +50,22 @@ import time # ... *then* import time.
|
|||
del os
|
||||
del time
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Shortcuts
|
||||
#----------------------------------------------------------
|
||||
# The hard-coded super-user id (a.k.a. administrator, or root user).
|
||||
SUPERUSER_ID = 1
|
||||
|
||||
def registry(database_name):
|
||||
"""
|
||||
Return the model registry for the given database. If the registry does not
|
||||
exist yet, it is created on the fly.
|
||||
"""
|
||||
return modules.registry.RegistryManager.get(database_name)
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Imports
|
||||
#----------------------------------------------------------
|
||||
import addons
|
||||
import cli
|
||||
import conf
|
||||
|
@ -58,23 +81,6 @@ import service
|
|||
import sql_db
|
||||
import tools
|
||||
import workflow
|
||||
# backward compatilbility
|
||||
# TODO: This is for the web addons, can be removed later.
|
||||
wsgi = service
|
||||
wsgi.register_wsgi_handler = wsgi.wsgi_server.register_wsgi_handler
|
||||
# Is the server running in multi-process mode (e.g. behind Gunicorn).
|
||||
# If this is True, the processes have to communicate some events,
|
||||
# e.g. database update or cache invalidation. Each process has also
|
||||
# its own copy of the data structure and we don't need to care about
|
||||
# locks between threads.
|
||||
multi_process = False
|
||||
|
||||
def registry(database_name):
|
||||
"""
|
||||
Return the model registry for the given database. If the registry does not
|
||||
exist yet, it is created on the fly.
|
||||
"""
|
||||
return modules.registry.RegistryManager.get(database_name)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -34,7 +34,4 @@ Importing them from here is deprecated.
|
|||
|
||||
"""
|
||||
|
||||
# get_module_path is used only by base_module_quality
|
||||
from openerp.modules import get_module_resource, get_module_path
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -25,6 +25,7 @@ import module
|
|||
import res
|
||||
import report
|
||||
import test
|
||||
import tests
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -92,8 +92,6 @@ The kernel of OpenERP, needed for all installation.
|
|||
],
|
||||
'test': [
|
||||
'test/base_test.yml',
|
||||
'test/test_context.xml',
|
||||
'test/bug_lp541545.xml',
|
||||
'test/test_osv_expression.yml',
|
||||
'test/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules.
|
||||
],
|
||||
|
|
|
@ -112,18 +112,6 @@ CREATE TABLE ir_act_client (
|
|||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
|
||||
CREATE TABLE ir_ui_view (
|
||||
id serial NOT NULL,
|
||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
model varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
"type" varchar(64) DEFAULT 'form'::varchar NOT NULL,
|
||||
arch text NOT NULL,
|
||||
field_parent varchar(64),
|
||||
priority integer DEFAULT 5 NOT NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE ir_ui_menu (
|
||||
id serial NOT NULL,
|
||||
parent_id int references ir_ui_menu on delete set null,
|
||||
|
@ -409,4 +397,4 @@ insert into ir_model_data (name,module,model,noupdate,res_id) VALUES ('main_comp
|
|||
select setval('res_company_id_seq', 2);
|
||||
select setval('res_users_id_seq', 2);
|
||||
select setval('res_partner_id_seq', 2);
|
||||
select setval('res_currency_id_seq', 2);
|
||||
select setval('res_currency_id_seq', 2);
|
||||
|
|
|
@ -91,6 +91,25 @@ Administrator</field>
|
|||
<field eval="10" name="sequence"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
A group dedicated to the portal users, making groups
|
||||
restrictions more convenient.
|
||||
-->
|
||||
<record id="group_portal" model="res.groups">
|
||||
<field name="name">Portal</field>
|
||||
<field name="comment">Portal members have specific access rights (such as record rules and restricted menus).
|
||||
They usually do not belong to the usual OpenERP groups.</field>
|
||||
</record>
|
||||
<!--
|
||||
A group dedicated to the public user only, making groups
|
||||
restrictions more convenient.
|
||||
-->
|
||||
<record id="group_public" model="res.groups">
|
||||
<field name="name">Public</field>
|
||||
<field name="comment">Public users have specific access rights (such as record rules and restricted menus).
|
||||
They usually do not belong to the usual OpenERP groups.</field>
|
||||
</record>
|
||||
|
||||
<!-- Basic fonts family included in PDF standart, will always be in the font list -->
|
||||
<record model="res.font" id="base.font_helvetica">
|
||||
<field name="name">Helvetica</field>
|
||||
|
@ -111,5 +130,21 @@ Administrator</field>
|
|||
<field name="mode">all</field>
|
||||
</record>
|
||||
|
||||
<record id="public_partner" model="res.partner">
|
||||
<field name="name">Public user</field>
|
||||
<field name="active" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="public_user" model="res.users">
|
||||
<field name="name">Public user</field>
|
||||
<field name="login">public</field>
|
||||
<field name="password"></field>
|
||||
<!-- Avoid auto-including this demo user in any default group -->
|
||||
<field name="groups_id" eval="[(6,0,[ref('base.group_public')])]"/>
|
||||
<field name="image" type="base64" file="base/static/img/public_user-image.png"/>
|
||||
<field name="partner_id" ref="public_partner"/>
|
||||
<field name="active" eval="False"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,80 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="partner_demo" model="res.partner">
|
||||
<field name="name">Demo User</field>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
<field name="customer" eval="False"/>
|
||||
<field name="email">demo@example.com</field>
|
||||
<field name="email">demo@yourcompany.example.com</field>
|
||||
<field name="street">Avenue des Dessus-de-Lives, 2</field>
|
||||
<field name="city">Namur (Loyers)</field>
|
||||
<field name="zip">5101</field>
|
||||
<field name="country_id" ref="be"/>
|
||||
</record>
|
||||
|
||||
<record id="main_partner" model="res.partner">
|
||||
<field name="image">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
|
||||
BZrmED0AAAAASUVORK5CYII=
|
||||
</field>
|
||||
<field name="name">YourCompany</field>
|
||||
<field name="street">1725 Slough Ave.</field>
|
||||
<field name="city">Scranton</field>
|
||||
<field name="zip">18540</field>
|
||||
<field name="phone">+1 555 123 8069</field>
|
||||
<field name="email">info@yourcompany.example.com</field>
|
||||
<field name="website">www.example.com</field>
|
||||
<field name="image" type="base64" file="base/static/img/main_partner-image.png"/>
|
||||
</record>
|
||||
|
||||
<record id="main_company" model="res.company">
|
||||
<field name="name">YourCompany</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="user_demo" model="res.users">
|
||||
<field name="partner_id" ref="base.partner_demo"/>
|
||||
<field name="login">demo</field>
|
||||
|
@ -83,160 +37,13 @@ BZrmED0AAAAASUVORK5CYII=
|
|||
Mr Demo</field>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
<field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager')])]"/>
|
||||
<field name="image">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
|
||||
gk//2Q==</field>
|
||||
<field name="image" type="base64" file="base/static/img/user_demo-image.jpg"/>
|
||||
</record>
|
||||
|
||||
<record model="res.partner" id="base.partner_root">
|
||||
<field name="email">admin@example.com</field>
|
||||
<field name="email">admin@yourcompany.example.com</field>
|
||||
<field name="tz">Europe/Brussels</field>
|
||||
<field name="image">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
|
||||
kALR5oiAU7jnCuj0RFIHQbIiKAf/2Q==</field>
|
||||
<field name="image" type="base64" file="base/static/img/partner_root-image.jpg"/>
|
||||
</record>
|
||||
|
||||
<!-- new rate for demo transactions in multi currency -->
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -60,12 +60,12 @@ msgstr "Kyk na argitektuur"
|
|||
#. module: base
|
||||
#: model:ir.module.module,summary:base.module_sale_stock
|
||||
msgid "Quotation, Sale Orders, Delivery & Invoicing Control"
|
||||
msgstr ""
|
||||
msgstr "Kwotasie, Bestellins, Aflewerings en Faktuur beheer."
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.sequence,implementation:0
|
||||
msgid "No gap"
|
||||
msgstr ""
|
||||
msgstr "Geep Spasie"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -89,23 +89,24 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.module.module,summary:base.module_point_of_sale
|
||||
msgid "Touchscreen Interface for Shops"
|
||||
msgstr ""
|
||||
msgstr "Tasskerm koppelvlak vir Winkels"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
|
||||
msgid "Indian Payroll"
|
||||
msgstr ""
|
||||
msgstr "Indiese Betaalstaat"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.cron,model:0
|
||||
msgid ""
|
||||
"Model name on which the method to be called is located, e.g. 'res.partner'."
|
||||
msgstr ""
|
||||
"Model naam waarin die metode wat geroep word verskyn, bv. \"res.partner\"."
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
msgid "Created Views"
|
||||
msgstr ""
|
||||
msgstr "Geskepte Afbeelding"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_product_manufacturer
|
||||
|
@ -122,11 +123,24 @@ msgid ""
|
|||
" * Product Attributes\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"'n Module wat die vervaardegiers en eienskappe van die produk op die vorm "
|
||||
"byvoeg.\n"
|
||||
"===================================================================\n"
|
||||
"\n"
|
||||
"Jy behoort nu die volgende vir produkte te kan definieer:\n"
|
||||
"-----------------------------------------------------------------------------"
|
||||
"--\n"
|
||||
" * Vervaardiger\n"
|
||||
" * Vervaardiger Produk Naame\n"
|
||||
" * Vervaardiger Produk Kode\n"
|
||||
" * Produk Eienskappe\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.client,params:0
|
||||
msgid "Supplementary arguments"
|
||||
msgstr ""
|
||||
msgstr "Aanvullende argumente"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_google_base_account
|
||||
|
@ -135,11 +149,14 @@ msgid ""
|
|||
"The module adds google user in res user.\n"
|
||||
"========================================\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Hierdie module voeg google user bu res.user.\n"
|
||||
"=====================================\n"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner,employee:0
|
||||
msgid "Check this box if this contact is an Employee."
|
||||
msgstr ""
|
||||
msgstr "Selekteer hierdie block as die kontak 'n Verknemer is."
|
||||
|
||||
#. module: base
|
||||
#: help:ir.model.fields,domain:0
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -366,7 +366,7 @@ msgstr "አክቲቭ"
|
|||
#. module: base
|
||||
#: field:ir.actions.wizard,wiz_name:0
|
||||
msgid "Wizard Name"
|
||||
msgstr "የዊዘርዱ ስም"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_knowledge
|
||||
|
@ -481,7 +481,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"One of the records you are trying to modify has already been deleted "
|
||||
"(Document type: %s)."
|
||||
msgstr "ለማሻሻል የሞከሩት ሰነድ ከዚህ በፊት የተሰረዘ ሆኖ ተገኝትዋል (የሰነዱ አይነት፡ %s)።"
|
||||
msgstr ""
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.act_window,views:0
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-server\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2012-08-20 15:44+0000\n"
|
||||
"Last-Translator: Jiří Hajda <robie@centrum.cz>\n"
|
||||
"PO-Revision-Date: 2014-01-05 20:16+0000\n"
|
||||
"Last-Translator: Maros Tarbajovsky <openerp.cz@gmail.com>\n"
|
||||
"Language-Team: openerp-i18n-czech <openerp-i18n-czech@lists.launchpad.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Poedit-Language: Czech\n"
|
||||
|
||||
#. module: base
|
||||
|
@ -38,7 +38,7 @@ msgstr "Svatá Helena"
|
|||
#. module: base
|
||||
#: view:ir.actions.report.xml:0
|
||||
msgid "Other Configuration"
|
||||
msgstr "Další nastavení"
|
||||
msgstr "Ostatní nastavení"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.property,type:0
|
||||
|
@ -59,7 +59,7 @@ msgstr ""
|
|||
#: field:ir.ui.view,arch:0
|
||||
#: field:ir.ui.view.custom,arch:0
|
||||
msgid "View Architecture"
|
||||
msgstr "Architektura zobrazení"
|
||||
msgstr "Zobrazení architektury"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,summary:base.module_sale_stock
|
||||
|
@ -69,7 +69,7 @@ msgstr "Nabídky, zakázky, řízení dopravy a fakturace"
|
|||
#. module: base
|
||||
#: selection:ir.sequence,implementation:0
|
||||
msgid "No gap"
|
||||
msgstr "Bez mezer"
|
||||
msgstr "Bez mezery"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -769,8 +769,7 @@ msgstr "Server odchozí pošty"
|
|||
msgid ""
|
||||
"Context dictionary as Python expression, empty by default (Default: {})"
|
||||
msgstr ""
|
||||
"Kontextový slovník jako výraz Pythonu, výchozí hodnota je prázdný slovník "
|
||||
"(výchozí: {})"
|
||||
"Kontextový slovník jako výraz Pythonu, jako výchozí je prázdné (Výchozí: {})"
|
||||
|
||||
#. module: base
|
||||
#: field:res.company,logo_web:0
|
||||
|
@ -7554,7 +7553,7 @@ msgstr "Spojené království"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_pa
|
||||
msgid "Panama Localization Chart Account"
|
||||
msgstr ""
|
||||
msgstr "Panamská účtová osnova"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner.category,active:0
|
||||
|
@ -8390,7 +8389,7 @@ msgstr "Portál reklamací"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_pe
|
||||
msgid "Peru Localization Chart Account"
|
||||
msgstr ""
|
||||
msgstr "Peruánská účtová osnova"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_auth_oauth
|
||||
|
@ -8399,6 +8398,9 @@ msgid ""
|
|||
"Allow users to login through OAuth2 Provider.\n"
|
||||
"=============================================\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Povolit uživatelům přihlášení přes OAuth2 Provider.\n"
|
||||
"=============================================\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_model_fields
|
||||
|
@ -9333,7 +9335,7 @@ msgstr "Stránka dokumentu"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_ar
|
||||
msgid "Argentina Localization Chart Account"
|
||||
msgstr ""
|
||||
msgstr "Argentinská účtová osnova"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.module.module,description_html:0
|
||||
|
@ -9941,6 +9943,10 @@ msgid ""
|
|||
"=============================\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"OpenERP webové zobrazení Ganttova diagramu.\n"
|
||||
"===========================================\n"
|
||||
"\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_base_status
|
||||
|
@ -10216,6 +10222,15 @@ msgid ""
|
|||
"If set to true it allows user to cancel entries & invoices.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Umožňuje zrušení účetních zápisů.\n"
|
||||
"====================================\n"
|
||||
"\n"
|
||||
"Tento modul přidává pole \"Povolit zrušení položek\" na formuláři deník "
|
||||
"účtů.\n"
|
||||
"Pokud je nastaven na hodnotu true, umožňuje uživateli zrušit záznamy & "
|
||||
"faktury.\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_plugin
|
||||
|
@ -10378,6 +10393,10 @@ msgid ""
|
|||
"=========================\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Zobrazení Openerp Web Diagramu.\n"
|
||||
"=========================\n"
|
||||
"\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_l10n_ch
|
||||
|
@ -10776,6 +10795,11 @@ msgid ""
|
|||
"=======================\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"OpenERP Webová testovací sestava.\n"
|
||||
"\n"
|
||||
"==================================\n"
|
||||
"\n"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.model:0
|
||||
|
@ -10978,6 +11002,12 @@ msgid ""
|
|||
"This module gives the details of the goods traded between the countries of\n"
|
||||
"European Union."
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modul, který přidává výkazy pro Intrastat.\n"
|
||||
"=====================================\n"
|
||||
"\n"
|
||||
"Tento modul poskytuje údaje o zboží obchodovaného mezi zeměmi\n"
|
||||
"Evropské unie."
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.server,loop_action:0
|
||||
|
@ -11162,7 +11192,7 @@ msgstr "%A - Plný název dne v týdnu."
|
|||
#. module: base
|
||||
#: help:ir.values,user_id:0
|
||||
msgid "If set, action binding only applies for this user."
|
||||
msgstr ""
|
||||
msgstr "Je-li nastavena, závaznost akce platí pouze pro tohoto uživatele."
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.gw
|
||||
|
@ -11389,6 +11419,15 @@ msgid ""
|
|||
"associated to every resource. It also manages the leaves of every resource.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modul pro řízení zdrojů.\n"
|
||||
"===============================\n"
|
||||
"\n"
|
||||
"Zdroj představuje něco, co může být naplánováno (developer přiřazen k úkolu "
|
||||
"nebo\n"
|
||||
"středisko k výrobní zakázce). Tento modul spravuje kalendáře zdrojů\n"
|
||||
"spojené s každým prostředkem. Spravuje také absence každého zdroje.\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_followup
|
||||
|
@ -11883,7 +11922,7 @@ msgstr "pracovní postup"
|
|||
#. module: base
|
||||
#: view:ir.rule:0
|
||||
msgid "Read Access Right"
|
||||
msgstr ""
|
||||
msgstr "Přístupové právo ke čtení"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_analytic_user_function
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,8 +12,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:40+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Poedit-Country: GREECE\n"
|
||||
"X-Poedit-Language: Greek\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:46+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"Language: \n"
|
||||
|
||||
#. module: base
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -9,8 +9,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:44+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n"
|
||||
"X-Poedit-Language: Persian\n"
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:40+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -11393,7 +11393,7 @@ msgstr "Islande"
|
|||
#: model:ir.actions.act_window,name:base.ir_action_window
|
||||
#: model:ir.ui.menu,name:base.menu_ir_action_window
|
||||
msgid "Window Actions"
|
||||
msgstr "Actions de fênetres"
|
||||
msgstr "Actions de fenêtres"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_portal_project_issue
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:40+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:41+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:41+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:45+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
"Language: hr\n"
|
||||
|
||||
#. module: base
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:41+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -9,8 +9,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -58,7 +58,7 @@ msgstr ""
|
|||
#: field:ir.ui.view,arch:0
|
||||
#: field:ir.ui.view.custom,arch:0
|
||||
msgid "View Architecture"
|
||||
msgstr "Arsitektur View"
|
||||
msgstr "Lihat Arsitektur"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,summary:base.module_sale_stock
|
||||
|
@ -86,13 +86,13 @@ msgid ""
|
|||
"Helps you manage your projects and tasks by tracking them, generating "
|
||||
"plannings, etc..."
|
||||
msgstr ""
|
||||
"Memungkinkan Anda untuk mengelola proyek dan tugas dengan cara melacaknya, "
|
||||
"menghasilkan perencanaan dan lain sebagainya ..."
|
||||
"Membantu anda mengelola proyek dan tugas dengan cara melacak, menghasilkan "
|
||||
"perencanaan, dan lain sebagainya..."
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,summary:base.module_point_of_sale
|
||||
msgid "Touchscreen Interface for Shops"
|
||||
msgstr "Antarmuka layar sentuh untuk digunakan di toko"
|
||||
msgstr "Antarmuka Layar Sentuh untuk Toko"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
|
||||
|
@ -104,12 +104,12 @@ msgstr "Payroll untuk India"
|
|||
msgid ""
|
||||
"Model name on which the method to be called is located, e.g. 'res.partner'."
|
||||
msgstr ""
|
||||
"Sebutkan nama model yang mana metode ini akan dipanggil, misal 'res.partner'."
|
||||
"Nama model dimana terletak metode yang akan dipanggil, contoh 'res.partner'."
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
msgid "Created Views"
|
||||
msgstr "View yang diciptakan"
|
||||
msgstr "Tampilan yang Diciptakan"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_product_manufacturer
|
||||
|
@ -127,17 +127,17 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modul ini berfungsi untuk menambahkan nama produsen beserta atributnya pada "
|
||||
"Sebuah modul yang berfungsi menambahkan nama produsen dan keterangan pada "
|
||||
"formulir produk.\n"
|
||||
"============================================================================="
|
||||
"==\n"
|
||||
"=====\n"
|
||||
"\n"
|
||||
"Anda dapat mengisi data-data berikut pada produk:\n"
|
||||
"------------------------------------------------\n"
|
||||
"* Nama produsen\n"
|
||||
"* Nama produk produsen\n"
|
||||
"* Code produk produsen\n"
|
||||
"* Atribut produk\n"
|
||||
"Anda sekarang dapat menentukan data berikut untuk sebuah produk:\n"
|
||||
"-------------------------------------------------------------------\n"
|
||||
" * Produsen\n"
|
||||
" * Nama Produk Produsen\n"
|
||||
" * Kode Produk Produsen\n"
|
||||
" * Keterangan Produk\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
|
@ -153,8 +153,8 @@ msgid ""
|
|||
"========================================\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modul ini akan menambahkan google user dalam obyek res.user\n"
|
||||
"====================================================\n"
|
||||
"Modul ini menambahkan pengguna google dalam res user.\n"
|
||||
"======================================================\n"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner,employee:0
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:41+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -480,7 +480,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:ir.model.relation,name:0
|
||||
msgid "Relation Name"
|
||||
msgstr ""
|
||||
msgstr "リレーション名"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.rule:0
|
||||
|
@ -976,7 +976,7 @@ msgstr "ジンバブエ"
|
|||
#: help:ir.model.constraint,type:0
|
||||
msgid ""
|
||||
"Type of the constraint: `f` for a foreign key, `u` for other constraints."
|
||||
msgstr ""
|
||||
msgstr "制約のタイプ:`f`は外部キー、`u`は他の制約"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.report.xml:0
|
||||
|
@ -1105,7 +1105,7 @@ msgstr "アンドラ公国"
|
|||
#. module: base
|
||||
#: field:ir.rule,perm_read:0
|
||||
msgid "Apply for Read"
|
||||
msgstr ""
|
||||
msgstr "読み込みに適用"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.mn
|
||||
|
@ -1322,7 +1322,7 @@ msgstr "貢献者"
|
|||
#. module: base
|
||||
#: field:ir.rule,perm_unlink:0
|
||||
msgid "Apply for Delete"
|
||||
msgstr ""
|
||||
msgstr "削除に適用"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.property,type:0
|
||||
|
@ -1420,7 +1420,7 @@ msgstr "テスト"
|
|||
#. module: base
|
||||
#: field:ir.actions.report.xml,attachment:0
|
||||
msgid "Save as Attachment Prefix"
|
||||
msgstr ""
|
||||
msgstr "添付ファイルのプリフィックスとして保存"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.ui.view_sc,res_id:0
|
||||
|
@ -1718,7 +1718,7 @@ msgstr "見積り要求や仕入先請求書といった発注関係のプロセ
|
|||
#. module: base
|
||||
#: help:res.partner,website:0
|
||||
msgid "Website of Partner or Company"
|
||||
msgstr ""
|
||||
msgstr "取引先または会社のWebサイト"
|
||||
|
||||
#. module: base
|
||||
#: help:base.language.install,overwrite:0
|
||||
|
@ -1792,6 +1792,9 @@ msgid ""
|
|||
"Launch Manually Once: after having been launched manually, it sets "
|
||||
"automatically to Done."
|
||||
msgstr ""
|
||||
"手動:手動で起動します。\n"
|
||||
"自動:システムを再設定するたびに実行します。\n"
|
||||
"手動でいったん起動:手動で起動した後は自動に設定されます。"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner,image_small:0
|
||||
|
@ -1936,7 +1939,7 @@ msgstr "読み込みアクセス"
|
|||
#. module: base
|
||||
#: help:ir.attachment,res_id:0
|
||||
msgid "The record id this is attached to"
|
||||
msgstr ""
|
||||
msgstr "これに添付するレコードID"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_share
|
||||
|
@ -1969,7 +1972,7 @@ msgstr "企業の処理"
|
|||
msgid ""
|
||||
"Check this box if this contact is a supplier. If it's not checked, purchase "
|
||||
"people will not see it when encoding a purchase order."
|
||||
msgstr ""
|
||||
msgstr "連絡先が仕入先の場合はこのボックスをチェックします。チェックしない場合、発注書を作成する際に表示されません。"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_hr_evaluation
|
||||
|
@ -2255,7 +2258,7 @@ msgstr "バハマ"
|
|||
#. module: base
|
||||
#: field:ir.rule,perm_create:0
|
||||
msgid "Apply for Create"
|
||||
msgstr ""
|
||||
msgstr "作成に適用"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.category,name:base.module_category_tools
|
||||
|
@ -2277,7 +2280,7 @@ msgstr "アイルランド"
|
|||
msgid ""
|
||||
"Appears by default on the top right corner of your printed documents (report "
|
||||
"header)."
|
||||
msgstr ""
|
||||
msgstr "印刷された文書(レポートヘッダ)の右上隅にデフォルトで表示されます。"
|
||||
|
||||
#. module: base
|
||||
#: field:base.module.update,update:0
|
||||
|
@ -2509,7 +2512,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"View type: Tree type to use for the tree view, set to 'tree' for a "
|
||||
"hierarchical tree view, or 'form' for a regular list view"
|
||||
msgstr ""
|
||||
msgstr "ビュータイプ:ツリー表示に使用する型式、階層ツリー表示のための「ツリー」または通常のリスト表示のための「フォーム」に設定"
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:ir.ui.view_sc:0
|
||||
|
@ -3280,7 +3283,7 @@ msgstr "スウェーデン"
|
|||
#. module: base
|
||||
#: field:ir.actions.report.xml,report_file:0
|
||||
msgid "Report File"
|
||||
msgstr ""
|
||||
msgstr "レポートファイル"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.act_window.view,view_mode:0
|
||||
|
@ -3595,7 +3598,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:base.language.export,modules:0
|
||||
msgid "Modules To Export"
|
||||
msgstr ""
|
||||
msgstr "エクスポートするモジュール"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.mt
|
||||
|
@ -3855,7 +3858,7 @@ msgstr "トーゴ"
|
|||
#: field:ir.actions.act_window,res_model:0
|
||||
#: field:ir.actions.client,res_model:0
|
||||
msgid "Destination Model"
|
||||
msgstr ""
|
||||
msgstr "宛先モデル"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.sequence,implementation:0
|
||||
|
@ -4202,7 +4205,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.actions.server,name:base.action_run_ir_action_todo
|
||||
msgid "Run Remaining Action Todo"
|
||||
msgstr ""
|
||||
msgstr "Todoアクションの残りを実行"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner,ean13:0
|
||||
|
@ -4988,7 +4991,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: help:ir.attachment,res_model:0
|
||||
msgid "The database object this attachment will be attached to"
|
||||
msgstr ""
|
||||
msgstr "この添付ファイルに添付されるデータベースオブジェクト"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_fields.py:327
|
||||
|
@ -5122,7 +5125,7 @@ msgstr "保存"
|
|||
#. module: base
|
||||
#: field:ir.actions.report.xml,report_xml:0
|
||||
msgid "XML Path"
|
||||
msgstr ""
|
||||
msgstr "XMLパス"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.bj
|
||||
|
@ -5519,7 +5522,7 @@ msgstr "ブーベ島"
|
|||
#. module: base
|
||||
#: field:ir.model.constraint,type:0
|
||||
msgid "Constraint Type"
|
||||
msgstr ""
|
||||
msgstr "制約タイプ"
|
||||
|
||||
#. module: base
|
||||
#: field:res.company,child_ids:0
|
||||
|
@ -5658,7 +5661,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:res.groups,name:base.group_sale_salesman_all_leads
|
||||
msgid "See all Leads"
|
||||
msgstr ""
|
||||
msgstr "全ての見込み客を参照"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.ci
|
||||
|
@ -5684,7 +5687,7 @@ msgstr "リソース名"
|
|||
#. module: base
|
||||
#: model:ir.ui.menu,name:base.menu_ir_filters
|
||||
msgid "User-defined Filters"
|
||||
msgstr ""
|
||||
msgstr "ユーザ定義のフィルタ"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window_close,name:0
|
||||
|
@ -6074,6 +6077,8 @@ msgid ""
|
|||
"deleting it (if you delete a native record rule, it may be re-created when "
|
||||
"you reload the module."
|
||||
msgstr ""
|
||||
"アクティブなフィールドのチェックを外すと、レコードのルールを削除せずに無効化します(レコードのルールを削除すると、モジュールを再ロードするときに再作成され"
|
||||
"ます)。"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -6237,7 +6242,7 @@ msgstr ""
|
|||
#: help:res.country.state,name:0
|
||||
msgid ""
|
||||
"Administrative divisions of a country. E.g. Fed. State, Departement, Canton"
|
||||
msgstr ""
|
||||
msgstr "国の行政区画。たとえば連邦、省、州。"
|
||||
|
||||
#. module: base
|
||||
#: view:res.partner.bank:0
|
||||
|
@ -6257,12 +6262,12 @@ msgstr "このルールにより影響を受けたオブジェクト"
|
|||
#. module: base
|
||||
#: selection:ir.actions.act_window,target:0
|
||||
msgid "Inline View"
|
||||
msgstr ""
|
||||
msgstr "インラインビュー"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.filters,is_default:0
|
||||
msgid "Default filter"
|
||||
msgstr ""
|
||||
msgstr "デフォルトのフィルタ"
|
||||
|
||||
#. module: base
|
||||
#: report:ir.module.reference:0
|
||||
|
@ -6630,7 +6635,7 @@ msgstr "世紀なしの現在年: %(y)s"
|
|||
#: view:ir.config_parameter:0
|
||||
#: model:ir.ui.menu,name:base.ir_config_menu
|
||||
msgid "System Parameters"
|
||||
msgstr ""
|
||||
msgstr "システムパラメータ"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.client,tag:0
|
||||
|
@ -6805,7 +6810,7 @@ msgstr "ランドスケープレポート用RML内部ヘッダ"
|
|||
#. module: base
|
||||
#: model:res.groups,name:base.group_partner_manager
|
||||
msgid "Contact Creation"
|
||||
msgstr ""
|
||||
msgstr "連絡先作成"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
|
@ -7083,7 +7088,7 @@ msgstr "モジュールファイルのインポートが成功しました。"
|
|||
#: view:ir.model.constraint:0
|
||||
#: model:ir.ui.menu,name:base.ir_model_constraint_menu
|
||||
msgid "Model Constraints"
|
||||
msgstr ""
|
||||
msgstr "モデル制約"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_workflow_transition_form
|
||||
|
@ -7198,7 +7203,7 @@ msgstr "のコピー"
|
|||
#. module: base
|
||||
#: field:ir.model.data,display_name:0
|
||||
msgid "Record Name"
|
||||
msgstr ""
|
||||
msgstr "レコード名"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_client
|
||||
|
@ -7214,7 +7219,7 @@ msgstr "イギリス領インド洋地域"
|
|||
#. module: base
|
||||
#: model:ir.actions.server,name:base.action_server_module_immediate_install
|
||||
msgid "Module Immediate Install"
|
||||
msgstr ""
|
||||
msgstr "モジュール即時インストール"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.server:0
|
||||
|
@ -7565,6 +7570,8 @@ msgid ""
|
|||
"use the same timezone that is otherwise used to pick and render date and "
|
||||
"time values: your computer's timezone."
|
||||
msgstr ""
|
||||
"取引先のタイムゾーン。印刷するレポート内に適切な日付と時刻を出力するために使用します。このフィールドに値を設定することは重要です。日付と時刻を選択して表示"
|
||||
"するのでなければ、あなたのコンピュータと同じタイムゾーンを使用すべきです。"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_account_analytic_default
|
||||
|
@ -7633,7 +7640,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: view:ir.rule:0
|
||||
msgid "Rule Definition (Domain Filter)"
|
||||
msgstr ""
|
||||
msgstr "ルール定義(ドメインフィルタ)"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.act_url,target:0
|
||||
|
@ -8340,7 +8347,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: help:ir.model.relation,name:0
|
||||
msgid "PostgreSQL table name implementing a many2many relation."
|
||||
msgstr ""
|
||||
msgstr "多対多の関係を実装するPostgreSQLのテーブル名。"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_base
|
||||
|
@ -8441,7 +8448,7 @@ msgstr "常時検索可能"
|
|||
#. module: base
|
||||
#: help:res.country.state,code:0
|
||||
msgid "The state code in max. three chars."
|
||||
msgstr ""
|
||||
msgstr "最大3文字の州コード。"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.hk
|
||||
|
@ -8604,7 +8611,7 @@ msgstr "ドミニカ"
|
|||
#. module: base
|
||||
#: field:ir.translation,name:0
|
||||
msgid "Translated field"
|
||||
msgstr ""
|
||||
msgstr "翻訳フィールド"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_stock_location
|
||||
|
@ -8682,7 +8689,7 @@ msgstr "アクション結合"
|
|||
msgid ""
|
||||
"If the selected language is loaded in the system, all documents related to "
|
||||
"this contact will be printed in this language. If not, it will be English."
|
||||
msgstr ""
|
||||
msgstr "選択された言語がシステムにロードされている場合、この連絡先に関連するすべての文書はこの言語で印刷されます。そうでない場合は英語です。"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_hr_evaluation
|
||||
|
@ -8839,7 +8846,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"This field specifies whether the model is transient or not (i.e. if records "
|
||||
"are automatically deleted from the database or not)"
|
||||
msgstr ""
|
||||
msgstr "このフィールドはモデルが一時的かどうか(レコードがデータベースから自動的に削除されるかどうか)を指定します。"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_mail_server.py:445
|
||||
|
@ -9231,7 +9238,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.module.category,name:base.module_category_warehouse_management
|
||||
msgid "Warehouse"
|
||||
msgstr ""
|
||||
msgstr "倉庫"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.exports,resource:0
|
||||
|
@ -9568,7 +9575,7 @@ msgstr "%H - 時(24時間表示)[00,23]."
|
|||
#. module: base
|
||||
#: field:ir.model.fields,on_delete:0
|
||||
msgid "On Delete"
|
||||
msgstr ""
|
||||
msgstr "削除時"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_model.py:347
|
||||
|
@ -9825,7 +9832,7 @@ msgstr "通貨コードは会社ごとに固有でなければいけません。
|
|||
#: code:addons/base/module/wizard/base_export_language.py:39
|
||||
#, python-format
|
||||
msgid "New Language (Empty translation template)"
|
||||
msgstr ""
|
||||
msgstr "新しい言語 (空の翻訳テンプレート)"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.server,email:0
|
||||
|
@ -10296,7 +10303,7 @@ msgstr "ファイルの内容"
|
|||
#: view:ir.model.relation:0
|
||||
#: model:ir.ui.menu,name:base.ir_model_relation_menu
|
||||
msgid "ManyToMany Relations"
|
||||
msgstr ""
|
||||
msgstr "多対多の関係"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.pa
|
||||
|
@ -10400,7 +10407,7 @@ msgstr "OpenERPは自動的に次の番号に要求されているサイズに
|
|||
#. module: base
|
||||
#: help:ir.model.constraint,name:0
|
||||
msgid "PostgreSQL constraint or foreign key name."
|
||||
msgstr ""
|
||||
msgstr "PostgreSQLの制約や外部キーの名前。"
|
||||
|
||||
#. module: base
|
||||
#: view:res.company:0
|
||||
|
@ -10425,7 +10432,7 @@ msgstr "ギニアビサウ"
|
|||
#. module: base
|
||||
#: field:ir.actions.report.xml,header:0
|
||||
msgid "Add RML Header"
|
||||
msgstr ""
|
||||
msgstr "RMLヘッダを追加"
|
||||
|
||||
#. module: base
|
||||
#: help:res.company,rml_footer:0
|
||||
|
@ -10547,7 +10554,7 @@ msgstr "イタリア"
|
|||
#. module: base
|
||||
#: model:res.groups,name:base.group_sale_salesman
|
||||
msgid "See Own Leads"
|
||||
msgstr ""
|
||||
msgstr "自分の見込み客を参照"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.todo:0
|
||||
|
@ -11057,7 +11064,7 @@ msgstr "オフィス用品"
|
|||
#. module: base
|
||||
#: field:ir.attachment,res_model:0
|
||||
msgid "Resource Model"
|
||||
msgstr ""
|
||||
msgstr "リソースモデル"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/custom.py:555
|
||||
|
@ -11184,7 +11191,7 @@ msgstr ""
|
|||
#: model:ir.actions.act_window,name:base.action_inventory_form
|
||||
#: model:ir.ui.menu,name:base.menu_action_inventory_form
|
||||
msgid "Default Company per Object"
|
||||
msgstr ""
|
||||
msgstr "オブジェクトごとのデフォルト会社"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_web_hello
|
||||
|
@ -11229,7 +11236,7 @@ msgstr "州名"
|
|||
#. module: base
|
||||
#: help:ir.attachment,type:0
|
||||
msgid "Binary File or URL"
|
||||
msgstr ""
|
||||
msgstr "バイナリファイルまたはURL"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_fields.py:313
|
||||
|
@ -11374,7 +11381,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:workflow.transition,signal:0
|
||||
msgid "Signal (Button Name)"
|
||||
msgstr ""
|
||||
msgstr "シグナル(ボタン名)"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.act_window:0
|
||||
|
@ -11404,7 +11411,7 @@ msgstr "グレナダ"
|
|||
#. module: base
|
||||
#: help:res.partner,customer:0
|
||||
msgid "Check this box if this contact is a customer."
|
||||
msgstr ""
|
||||
msgstr "連絡先が顧客の場合はこのボックスをチェックします。"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.server:0
|
||||
|
@ -11439,7 +11446,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:res.users,partner_id:0
|
||||
msgid "Related Partner"
|
||||
msgstr ""
|
||||
msgstr "関連取引先"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/osv.py:172
|
||||
|
@ -11719,6 +11726,7 @@ msgid ""
|
|||
"(if you delete a native ACL, it will be re-created when you reload the "
|
||||
"module."
|
||||
msgstr ""
|
||||
"アクティブなフィールドのチェックを外すと、ACLを削除せずに無効化します(ACLを削除すると、モジュールを再ロードするときに再作成されます)。"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_fields_converter
|
||||
|
@ -12185,7 +12193,7 @@ msgstr "見積書、販売注文書、請求書の処理に役立ちます。"
|
|||
#. module: base
|
||||
#: field:res.users,login_date:0
|
||||
msgid "Latest connection"
|
||||
msgstr ""
|
||||
msgstr "最後の接続"
|
||||
|
||||
#. module: base
|
||||
#: field:res.groups,implied_ids:0
|
||||
|
@ -12349,7 +12357,7 @@ msgstr "デフォルト値、またはアクションへの参照"
|
|||
#. module: base
|
||||
#: field:ir.actions.report.xml,auto:0
|
||||
msgid "Custom Python Parser"
|
||||
msgstr ""
|
||||
msgstr "特注のPythonパーサ"
|
||||
|
||||
#. module: base
|
||||
#: sql_constraint:res.groups:0
|
||||
|
@ -12933,7 +12941,7 @@ msgstr "ニューカレドニア(フランス領)"
|
|||
#. module: base
|
||||
#: field:ir.model,osv_memory:0
|
||||
msgid "Transient Model"
|
||||
msgstr ""
|
||||
msgstr "過度的なモデル"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.cy
|
||||
|
@ -13073,7 +13081,7 @@ msgstr "送信メールサーバ"
|
|||
#. module: base
|
||||
#: model:ir.ui.menu,name:base.menu_custom
|
||||
msgid "Technical"
|
||||
msgstr ""
|
||||
msgstr "技術"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.cn
|
||||
|
@ -13290,7 +13298,7 @@ msgstr "起動するアクション"
|
|||
#: field:ir.model,modules:0
|
||||
#: field:ir.model.fields,modules:0
|
||||
msgid "In Modules"
|
||||
msgstr ""
|
||||
msgstr "モジュールリスト"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_contacts
|
||||
|
@ -13783,7 +13791,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"Check this to define the report footer manually. Otherwise it will be "
|
||||
"filled in automatically."
|
||||
msgstr ""
|
||||
msgstr "レポートフッタをマニュアルで定義する場合はチェックしてください。それ以外は自動で入力されます。"
|
||||
|
||||
#. module: base
|
||||
#: view:res.partner:0
|
||||
|
@ -13829,7 +13837,7 @@ msgstr "ソース"
|
|||
#: field:ir.model.constraint,date_init:0
|
||||
#: field:ir.model.relation,date_init:0
|
||||
msgid "Initialization Date"
|
||||
msgstr ""
|
||||
msgstr "初期化の日付"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.vu
|
||||
|
@ -13998,7 +14006,7 @@ msgstr "複数ドキュメントのアクション"
|
|||
#: model:ir.actions.act_window,name:base.action_partner_title_partner
|
||||
#: model:ir.ui.menu,name:base.menu_partner_title_partner
|
||||
msgid "Titles"
|
||||
msgstr ""
|
||||
msgstr "敬称"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_anonymization
|
||||
|
@ -14298,7 +14306,7 @@ msgstr "ヘルプデスク"
|
|||
#. module: base
|
||||
#: field:ir.rule,perm_write:0
|
||||
msgid "Apply for Write"
|
||||
msgstr ""
|
||||
msgstr "読み込みに適用"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.ui.menu,parent_left:0
|
||||
|
@ -14456,7 +14464,7 @@ msgstr "ペルシア語 / فارس"
|
|||
#. module: base
|
||||
#: view:base.language.export:0
|
||||
msgid "Export Settings"
|
||||
msgstr ""
|
||||
msgstr "エクスポート設定"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window,src_model:0
|
||||
|
@ -15333,7 +15341,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:ir.model.data,complete_name:0
|
||||
msgid "Complete ID"
|
||||
msgstr ""
|
||||
msgstr "完了ID"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_stock
|
||||
|
@ -15488,7 +15496,7 @@ msgstr "購買依頼"
|
|||
#. module: base
|
||||
#: selection:ir.actions.act_window,target:0
|
||||
msgid "Inline Edit"
|
||||
msgstr ""
|
||||
msgstr "インライン編集"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.cron,interval_type:0
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:40+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:43+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:43+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:43+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:43+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -14808,6 +14808,15 @@ msgid ""
|
|||
"automatically new claims based on incoming emails.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
"Захиалагчийн Гомдлын Менежмент.\n"
|
||||
"=======================\n"
|
||||
"Энэ аппликэйшн нь захиалагч/нийлүүлэгчийн гомдлыг хөтлөх боломжийг олгодог.\n"
|
||||
"\n"
|
||||
"Энэ модуль нь эмэйл үүдтэй бүрэн уялддаг тул ирж буй имэйлээс\n"
|
||||
"автоматаар гомдлыг үүсгэх боломжтой.\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_account_test
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:43+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:44+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:44+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:44+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -26,7 +26,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Modul pentru Bifeaza Scriere si Bifeaza Imprimare.\n"
|
||||
"================================================\n"
|
||||
"==================================================\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
|
@ -129,7 +129,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Un modul care adauga producatori si atribute la formularul produsului.\n"
|
||||
"====================================================================\n"
|
||||
"======================================================================\n"
|
||||
"\n"
|
||||
"Acum puteti defini urmatoarele pentru un produs:\n"
|
||||
"-----------------------------------------------\n"
|
||||
|
@ -153,7 +153,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Acest modul adauga utilizatorul google la utilizatorul res.\n"
|
||||
"========================================\n"
|
||||
"===========================================================\n"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner,employee:0
|
||||
|
@ -212,7 +212,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Generează Facturi din Cheltuieli, Înregistrări ale Fișelor de Pontaj.\n"
|
||||
"========================================================\n"
|
||||
"=====================================================================\n"
|
||||
"\n"
|
||||
"Modul pentru generarea facturilor pe baza costurilor (resurse umane, "
|
||||
"cheltuieli, ...).\n"
|
||||
|
@ -249,7 +249,7 @@ msgstr "Eroare constrângere"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_ui_view_custom
|
||||
msgid "ir.ui.view.custom"
|
||||
msgstr "ir.ui.vizualizare.personalizata"
|
||||
msgstr "ir.ui.view.custom"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_model.py:374
|
||||
|
@ -405,7 +405,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Programul de instalare Ascuns bazat pe cunostinte.\n"
|
||||
"=====================================\n"
|
||||
"==================================================\n"
|
||||
"\n"
|
||||
"Face Configuratia Aplicatiei Cunostinte disponibila, de unde puteti instala\n"
|
||||
"documente si Ascuns bazat pe Wiki.\n"
|
||||
|
@ -617,7 +617,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Modul pentru definirea obiectului contabilitatii analitice.\n"
|
||||
"===============================================\n"
|
||||
"=========================================================\n"
|
||||
"\n"
|
||||
"In OpenERP, conturile analitice sunt legate de conturile generale, dar sunt "
|
||||
"tratate\n"
|
||||
|
@ -650,7 +650,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Organizarea si gestionarea Evenimentelor.\n"
|
||||
"======================================\n"
|
||||
"=========================================\n"
|
||||
"\n"
|
||||
"Modulul eveniment va permite sa organizati eficient evenimente si toate "
|
||||
"sarcinile asociate lor: planificare, urmarirea inregistrarii,\n"
|
||||
|
@ -950,7 +950,7 @@ msgstr "Data urmatoarei executii planificate pentru aceasta sarcina."
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_ui_view
|
||||
msgid "ir.ui.view"
|
||||
msgstr "ir.ui.vizualizare"
|
||||
msgstr "ir.ui.view"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.er
|
||||
|
@ -975,7 +975,7 @@ msgstr "România - Contabilitate"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_config_settings
|
||||
msgid "res.config.settings"
|
||||
msgstr "res.configurare.setari"
|
||||
msgstr "res.config.settings"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner,image_small:0
|
||||
|
@ -996,8 +996,8 @@ msgid ""
|
|||
"the correct mobile number"
|
||||
msgstr ""
|
||||
"Furnizeaza campurile care sunt folosite pentru a cauta numarul de telefon "
|
||||
"mobil, de exemplu dumneavoastra selectati factura, atunci "
|
||||
"`obiect.factura_adresa_id.mobil` este campul care va da numarul corect de "
|
||||
"mobil, de exemplu dumneavoastra selectati factura, atunci "
|
||||
"`object.invoice_address_id.mobile` este campul care va da numarul corect de "
|
||||
"telefon mobil"
|
||||
|
||||
#. module: base
|
||||
|
@ -1932,7 +1932,7 @@ msgstr "Sfantul Martin (partea franceza)"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_exports
|
||||
msgid "ir.exports"
|
||||
msgstr "ir.exporturi"
|
||||
msgstr "ir.exports"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_l10n_lu
|
||||
|
@ -2056,7 +2056,7 @@ msgstr "Bancă"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_exports_line
|
||||
msgid "ir.exports.line"
|
||||
msgstr "ir.linie.exporturi"
|
||||
msgstr "ir.exports.line"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.category,description:base.module_category_purchase_management
|
||||
|
@ -2125,8 +2125,8 @@ msgid ""
|
|||
"Access all the fields related to the current object using expressions, i.e. "
|
||||
"object.partner_id.name "
|
||||
msgstr ""
|
||||
"Acceseaza toate fisierele asociate obiectului actual folosind expresii, de "
|
||||
"exemplu obiect.partener_id.nume "
|
||||
"Accesează toate câmpurile asociate obiectului actual folosind expresii, de "
|
||||
"exemplu object.partner_id.name "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_portal_project_issue
|
||||
|
@ -2169,7 +2169,7 @@ msgstr "Gestiunea depozitului"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_request_link
|
||||
msgid "res.request.link"
|
||||
msgstr "res.link.cerere"
|
||||
msgstr "res.request.link"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.wizard,name:0
|
||||
|
@ -2260,7 +2260,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Day: %(day)s"
|
||||
msgstr "Ziua: %(zi)s"
|
||||
msgstr "Ziua: %(day)s"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.category,description:base.module_category_point_of_sale
|
||||
|
@ -2299,7 +2299,7 @@ msgstr "Traducere în desfășurare"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_rule
|
||||
msgid "ir.rule"
|
||||
msgstr "ir.regula"
|
||||
msgstr "ir.rule"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.cron,interval_type:0
|
||||
|
@ -2456,7 +2456,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_model_access
|
||||
msgid "ir.model.access"
|
||||
msgstr "ir.model.acces"
|
||||
msgstr "ir.model.access"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_l10n_multilang
|
||||
|
@ -2987,7 +2987,7 @@ msgstr "Va fi șters"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_sequence
|
||||
msgid "ir.sequence"
|
||||
msgstr "ir.secventa"
|
||||
msgstr "ir.sequence"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.server,expression:0
|
||||
|
@ -2996,9 +2996,9 @@ msgid ""
|
|||
"order in Object, and you can have loop on the sales order line. Expression = "
|
||||
"`object.order_line`."
|
||||
msgstr ""
|
||||
"Introduceti campul/expresia care va genera lista. De exemplu, selectati "
|
||||
"comanda de vanzare in Obiect, si puteti parcurge in bucla pozitiile din "
|
||||
"comanda de vanzare. Expresie = `obiect.linie_comanda`."
|
||||
"Introduceți câmpul / expresia care sa genereze lista. De exemplu, selectând "
|
||||
"comanda de vânzare în Obiecte puteți parcurge în buclă pozițiile din "
|
||||
"comandă. Expresie = `object.order_line`."
|
||||
|
||||
#. module: base
|
||||
#: field:ir.mail_server,smtp_debug:0
|
||||
|
@ -3591,7 +3591,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_act_window_close
|
||||
msgid "ir.actions.act_window_close"
|
||||
msgstr "ir.actiuni.inchide_fereastra_act"
|
||||
msgstr "ir.actions.act_window_close"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.server.object.lines,col1:0
|
||||
|
@ -4878,7 +4878,7 @@ msgstr "Jersey"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_translation
|
||||
msgid "ir.translation"
|
||||
msgstr "ir.traducere"
|
||||
msgstr "ir.translation"
|
||||
|
||||
#. module: base
|
||||
#: view:res.lang:0
|
||||
|
@ -4954,7 +4954,7 @@ msgstr "Reg"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_property
|
||||
msgid "ir.property"
|
||||
msgstr "ir.proprietate"
|
||||
msgstr "ir.property"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.act_window,view_type:0
|
||||
|
@ -6083,9 +6083,9 @@ msgid ""
|
|||
"the same values as those available in the condition field, e.g. `Dear [[ "
|
||||
"object.partner_id.name ]]`"
|
||||
msgstr ""
|
||||
"Continuturile e-mail-urilor, pot sa contina expresii incluse in paranteze "
|
||||
"duble bazate pe aceleasi valori ca si cele disponibile in campul conditie, "
|
||||
"de exemplu: `Stimate [[ obiect.id_nume.partener ]]`"
|
||||
"Conținuturile e-mail-urilor, pot sa includă expresii incluse în paranteze "
|
||||
"duble bazate pe aceleași valori ca și cele disponibile în câmpul condiție, "
|
||||
"de exemplu: `Stimate [[ object.partner_id.name ]]`"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_workflow_form
|
||||
|
@ -6329,7 +6329,7 @@ msgstr "Nume de utilizator optional pentru autentificarea SMTP"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_actions
|
||||
msgid "ir.actions.actions"
|
||||
msgstr "ir.actiuni.actiuni"
|
||||
msgstr "ir.actions.actions"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.model.fields,select_level:0
|
||||
|
@ -6364,19 +6364,19 @@ msgid ""
|
|||
" \n"
|
||||
"%(country_code)s: the code of the country"
|
||||
msgstr ""
|
||||
"Aici puteti mentiona formatul obisnuit care va fi folosit pentru adresele "
|
||||
"care apartin acestei tari.\n"
|
||||
"Aici puteți menționa formatul obișnuit care va fi folosit pentru adresele "
|
||||
"acestei țări.\n"
|
||||
"\n"
|
||||
"Puteti folosi tiparul in sir stil python cu toate campurile adreselor (de "
|
||||
"exemplu, folositi '%(strada)s' pentru a afisa campul 'strada') plus\n"
|
||||
"Puteți folosi tiparul in sir stil python cu toate câmpurile adreselor (de "
|
||||
"exemplu, folosiți '%(street)s' pentru a afișa câmpul 'strada') plus\n"
|
||||
" \n"
|
||||
"%(nume_stat)s: numele statului\n"
|
||||
"%(state_name)s: numele statului (județului)\n"
|
||||
" \n"
|
||||
"%(cod_stat)s: codul statului\n"
|
||||
"%(state_code)s: codul statului (județului)\n"
|
||||
" \n"
|
||||
"%(nume_tara)s: numele tarii\n"
|
||||
"%(country_name)s: numele țării\n"
|
||||
" \n"
|
||||
"%(cod_tara)s: codul tarii"
|
||||
"%(country_code)s: codul țării"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.mu
|
||||
|
@ -7194,7 +7194,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_act_window_view
|
||||
msgid "ir.actions.act_window.view"
|
||||
msgstr "ir.actiuni.act_fereastra.vizualizare"
|
||||
msgstr "ir.actions.act_window.view"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_web
|
||||
|
@ -7278,7 +7278,7 @@ msgstr "Insulele Svalbard si Jan Mayen"
|
|||
#: model:ir.model,name:base.model_ir_actions_wizard
|
||||
#: selection:ir.ui.menu,action:0
|
||||
msgid "ir.actions.wizard"
|
||||
msgstr "ir.asistent.actiuni"
|
||||
msgstr "ir.actions.wizard"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_web_kanban
|
||||
|
@ -7567,7 +7567,7 @@ msgstr "Start Flux"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_partner_title
|
||||
msgid "res.partner.title"
|
||||
msgstr "res.partener.titlu"
|
||||
msgstr "res.partner.title"
|
||||
|
||||
#. module: base
|
||||
#: view:res.partner.bank:0
|
||||
|
@ -8097,7 +8097,7 @@ msgstr "Meniuri Create"
|
|||
#: view:ir.module.module:0
|
||||
#, python-format
|
||||
msgid "Uninstall"
|
||||
msgstr "Dezinstaleaza"
|
||||
msgstr "Dezinstalați"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_account_budget
|
||||
|
@ -8208,7 +8208,7 @@ msgstr "Curaçao"
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Current Year without Century: %(y)s"
|
||||
msgstr "Anul curent fara Secol: %(y)s"
|
||||
msgstr "Anul curent fără secol: %(y)s"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.ir_config_list_action
|
||||
|
@ -8490,7 +8490,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Week of the Year: %(woy)s"
|
||||
msgstr "Saptamana din An: %(sda)s"
|
||||
msgstr "Săptămâna din an: %(woy)s"
|
||||
|
||||
#. module: base
|
||||
#: field:res.users,id:0
|
||||
|
@ -8601,7 +8601,7 @@ msgstr "Filtre vizibile doar pentru un utilizator"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_attachment
|
||||
msgid "ir.attachment"
|
||||
msgstr "ir.atasament"
|
||||
msgstr "ir.attachment"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/orm.py:4348
|
||||
|
@ -9154,7 +9154,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_config_parameter
|
||||
msgid "ir.config_parameter"
|
||||
msgstr "ir.configurare_parametru"
|
||||
msgstr "ir.config_parameter"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_project_long_term
|
||||
|
@ -9243,7 +9243,7 @@ msgstr "Compania pentru care acest utilizator lucreaza in prezent."
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_wizard_ir_model_menu_create
|
||||
msgid "wizard.ir.model.menu.create"
|
||||
msgstr "wizard.ir.creeaza.model.meniu"
|
||||
msgstr "wizard.ir.model.menu.create"
|
||||
|
||||
#. module: base
|
||||
#: view:workflow.transition:0
|
||||
|
@ -9981,9 +9981,9 @@ msgid ""
|
|||
"the same values as those available in the condition field, e.g. `Hello [[ "
|
||||
"object.partner_id.name ]]`"
|
||||
msgstr ""
|
||||
"Subiectul e-mail-ului poate sa contina expresii intre paranteze duble, "
|
||||
"bazate pe aceleasi valori ca si cele disponibile in campul conditie, de ex. "
|
||||
"`Buna ziua [[obiect.partener_id.nume]]`"
|
||||
"Subiectul e-mail-ului poate să conțină expresii intre paranteze duble, "
|
||||
"bazate pe aceleași valori ca și cele disponibile în câmpul condiție, de ex. "
|
||||
"`Buna ziua [[ object.partner_id.name ]]`"
|
||||
|
||||
#. module: base
|
||||
#: help:res.partner,image:0
|
||||
|
@ -10209,7 +10209,7 @@ msgstr "Austria - Contabilitate"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_ui_menu
|
||||
msgid "ir.ui.menu"
|
||||
msgstr "ir.ui.meniu"
|
||||
msgstr "ir.ui.menu"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_project
|
||||
|
@ -10219,7 +10219,7 @@ msgstr "Managementul Proiectelor"
|
|||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
msgid "Cancel Uninstall"
|
||||
msgstr "Anulati dezinstalarea"
|
||||
msgstr "Anulați dezinstalarea"
|
||||
|
||||
#. module: base
|
||||
#: view:res.bank:0
|
||||
|
@ -10234,7 +10234,7 @@ msgstr "Contabilitate Analitica"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_model_constraint
|
||||
msgid "ir.model.constraint"
|
||||
msgstr "ir.restrictie.model"
|
||||
msgstr "ir.model.constraint"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_web_graph
|
||||
|
@ -10260,7 +10260,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_server_object_lines
|
||||
msgid "ir.server.object.lines"
|
||||
msgstr "ir.linii.obiect.server"
|
||||
msgstr "ir.server.object.lines"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_be
|
||||
|
@ -10889,7 +10889,7 @@ msgstr "Instalati Actualizare Modul"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_configuration_wizard
|
||||
msgid "ir.actions.configuration.wizard"
|
||||
msgstr "ir.wizard.configurare.actiuni"
|
||||
msgstr "ir.actions.configuration.wizard"
|
||||
|
||||
#. module: base
|
||||
#: view:res.lang:0
|
||||
|
@ -11835,7 +11835,7 @@ msgstr "Statele Unite - Plan de Conturi"
|
|||
#: view:res.users:0
|
||||
#: view:wizard.ir.model.menu.create:0
|
||||
msgid "Cancel"
|
||||
msgstr "Anulati"
|
||||
msgstr "Anulați"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/orm.py:1507
|
||||
|
@ -12119,9 +12119,9 @@ msgid ""
|
|||
"same values as for the condition field.\n"
|
||||
"Example: object.invoice_address_id.email, or 'me@example.com'"
|
||||
msgstr ""
|
||||
"Expresie care intoarce adresa de e-mail la trimite catre. Poate fi bazata pe "
|
||||
"aceleasi valori ca si pentru campul conditie.\n"
|
||||
"Exemplu: obiect.id_adresa_factura.e-mail, sau 'me@exemplu.com'"
|
||||
"Expresie care întoarce adresa de e-mail în câmpul trimite către. Poate fi "
|
||||
"bazată pe aceleași valori ca și pentru câmpul condiție.\n"
|
||||
"Exemplu: object.invoice_address_id.email, sau 'me@exemplu.com'"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_project_issue_sheet
|
||||
|
@ -12326,7 +12326,7 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<clasa p=\"creeaza_niciuncontinut_vizualizare_oe\">\n"
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" Faceti click pentru a adauga un contact in agenda "
|
||||
"dumneavoastra.\n"
|
||||
" </p><p>\n"
|
||||
|
@ -12389,7 +12389,7 @@ msgstr "Cod"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_config_installer
|
||||
msgid "res.config.installer"
|
||||
msgstr "res.config.program_de_instalare"
|
||||
msgstr "res.config.installer"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.mc
|
||||
|
@ -12452,7 +12452,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Current Year with Century: %(year)s"
|
||||
msgstr "Anul curent cu Secol: %(an)s"
|
||||
msgstr "Anul curent cu secol: %(year)s"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.exports,export_fields:0
|
||||
|
@ -12593,7 +12593,7 @@ msgstr "Chineza (TW) / 正體字"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_request
|
||||
msgid "res.request"
|
||||
msgstr "res.cerere"
|
||||
msgstr "res.request"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner,image_medium:0
|
||||
|
@ -13120,7 +13120,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_mail_server
|
||||
msgid "ir.mail_server"
|
||||
msgstr "ir.server_e-mail"
|
||||
msgstr "ir.mail_server"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -13689,7 +13689,7 @@ msgstr "Fus orar"
|
|||
#: model:ir.model,name:base.model_ir_actions_report_xml
|
||||
#: selection:ir.ui.menu,action:0
|
||||
msgid "ir.actions.report.xml"
|
||||
msgstr "ir.actiuni.raport.xml"
|
||||
msgstr "ir.actions.report.xml"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.ir_sequence_form
|
||||
|
@ -14248,7 +14248,7 @@ msgstr "Data trimiterii"
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Month: %(month)s"
|
||||
msgstr "Luna: %(luna)s"
|
||||
msgstr "Luna: %(month)s"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window.view,sequence:0
|
||||
|
@ -14285,7 +14285,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_fields_converter
|
||||
msgid "ir.fields.converter"
|
||||
msgstr "ir.convertor.campuri"
|
||||
msgstr "ir.fields.converter"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/res/res_partner.py:439
|
||||
|
@ -14308,12 +14308,12 @@ msgstr "Comore"
|
|||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
msgid "Cancel Install"
|
||||
msgstr "Anulati Instalarea"
|
||||
msgstr "Anulați Instalarea"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_model_relation
|
||||
msgid "ir.model.relation"
|
||||
msgstr "ir.model.relatie"
|
||||
msgstr "ir.model.relation"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_account_check_writing
|
||||
|
@ -14534,7 +14534,7 @@ msgstr "Planuri Analitice Multiple"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_default
|
||||
msgid "ir.default"
|
||||
msgstr "ir.implicit"
|
||||
msgstr "ir.default"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
|
@ -14633,9 +14633,9 @@ msgstr ""
|
|||
"*URL:** legatura dumneavoastra moodle, de exemplu: "
|
||||
"http://openerp.moodle.com\n"
|
||||
"\n"
|
||||
"**AUTENTIFICARE:** ${obiect.nume_de_utilizator_moodle}\n"
|
||||
"**AUTENTIFICARE:**${object.moodle_username}\n"
|
||||
" \n"
|
||||
"**PAROLA:** ${obiect.parola_utilizator_moodle}\n"
|
||||
"**PAROLA:** ${object.moodle_user_password}\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_uk
|
||||
|
@ -15423,7 +15423,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Retele Sociale orientate spre afaceri\n"
|
||||
"===================================\n"
|
||||
"=====================================\n"
|
||||
"Modulul Retele Sociale furnizeaza un strat de abstractizare unificat de "
|
||||
"retele sociale, permitand aplicatiilor sa afiseze un istoric\n"
|
||||
"complet al conversatiilor in documente cu un sistem complet integrat de "
|
||||
|
@ -15537,7 +15537,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_values
|
||||
msgid "ir.values"
|
||||
msgstr "ir.valori"
|
||||
msgstr "ir.values"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_base_module_update
|
||||
|
@ -16201,7 +16201,7 @@ msgstr "Agenda"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_sequence_type
|
||||
msgid "ir.sequence.type"
|
||||
msgstr "ir.tip.secventa"
|
||||
msgstr "ir.sequence.type"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_be_hr_payroll_account
|
||||
|
@ -16825,7 +16825,7 @@ msgstr "Nu pot exista doi utilizatori cu acelasi nume de autentificare !"
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_res_request_history
|
||||
msgid "res.request.history"
|
||||
msgstr "res.istoric.solicitari"
|
||||
msgstr "res.request.history"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_multi_company_default
|
||||
|
@ -17409,7 +17409,7 @@ msgstr "Uzbekistan"
|
|||
#: model:ir.model,name:base.model_ir_actions_act_window
|
||||
#: selection:ir.ui.menu,action:0
|
||||
msgid "ir.actions.act_window"
|
||||
msgstr "ir.actiuni.act_fereastra"
|
||||
msgstr "ir.actions.act_window"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.vi
|
||||
|
@ -17597,7 +17597,7 @@ msgstr "Germania - Contabilitate"
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Day of the Year: %(doy)s"
|
||||
msgstr "Ziua din An: %(doy)s"
|
||||
msgstr "Ziua din an: %(doy)s"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.ui.menu,web_icon:0
|
||||
|
@ -17642,7 +17642,7 @@ msgstr "Model sursa"
|
|||
#. module: base
|
||||
#: view:ir.sequence:0
|
||||
msgid "Day of the Week (0:Monday): %(weekday)s"
|
||||
msgstr "Ziua din Saptamana (0:Luni): %(weekday)s"
|
||||
msgstr "Ziua din saptămâna (0:Luni): %(weekday)s"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/module/wizard/base_module_upgrade.py:84
|
||||
|
@ -17936,7 +17936,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_model_data
|
||||
msgid "ir.model.data"
|
||||
msgstr "ir.date.model"
|
||||
msgstr "ir.model.data"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -18442,7 +18442,7 @@ msgstr "Grafic"
|
|||
#: model:ir.model,name:base.model_ir_actions_server
|
||||
#: selection:ir.ui.menu,action:0
|
||||
msgid "ir.actions.server"
|
||||
msgstr "ir.actiuni.server"
|
||||
msgstr "ir.actions.server"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_l10n_ca
|
||||
|
@ -18953,7 +18953,7 @@ msgstr "Note Interne"
|
|||
#: model:res.partner.title,name:base.res_partner_title_pvt_ltd
|
||||
#: model:res.partner.title,shortcut:base.res_partner_title_pvt_ltd
|
||||
msgid "Corp."
|
||||
msgstr "Corp."
|
||||
msgstr "SA"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_purchase_requisition
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:45+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -7386,7 +7386,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: selection:res.currency,position:0
|
||||
msgid "After Amount"
|
||||
msgstr "Сумма после налогов"
|
||||
msgstr "После суммы"
|
||||
|
||||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
|
@ -13474,7 +13474,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: selection:res.currency,position:0
|
||||
msgid "Before Amount"
|
||||
msgstr "Предварительный итог"
|
||||
msgstr "Перед суммой"
|
||||
|
||||
#. module: base
|
||||
#: field:res.request,act_from:0
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:45+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -25,6 +25,10 @@ msgid ""
|
|||
"================================================\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Modul pre vypisovanie a tlač šekov.\n"
|
||||
"================================================\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.sh
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:45+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:45+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:46+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:46+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:46+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:46+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -14,8 +14,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -13,8 +13,8 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-12-19 05:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16872)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-04 05:49+0000\n"
|
||||
"X-Generator: Launchpad (build 16916)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
|
|
@ -37,6 +37,7 @@ import ir_config_parameter
|
|||
import osv_memory_autovacuum
|
||||
import ir_mail_server
|
||||
import ir_fields
|
||||
import ir_qweb
|
||||
import ir_http
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2013 OpenERP S.A. <http://www.openerp.com>
|
||||
# Copyright (C) 2004-2014 OpenERP S.A. <http://www.openerp.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -417,7 +417,7 @@ class ir_actions_server(osv.osv):
|
|||
|
||||
def _select_objects(self, cr, uid, context=None):
|
||||
model_pool = self.pool.get('ir.model')
|
||||
ids = model_pool.search(cr, uid, [('name', 'not ilike', '.')])
|
||||
ids = model_pool.search(cr, uid, [], limit=None)
|
||||
res = model_pool.read(cr, uid, ids, ['model', 'name'])
|
||||
return [(r['model'], r['name']) for r in res] + [('', '')]
|
||||
|
||||
|
@ -910,11 +910,34 @@ class ir_actions_server(osv.osv):
|
|||
if action.link_new_record and action.link_field_id:
|
||||
self.pool[action.model_id.model].write(cr, uid, [context.get('active_id')], {action.link_field_id.name: res_id})
|
||||
|
||||
def _get_eval_context(self, cr, uid, action, context=None):
|
||||
""" Prepare the context used when evaluating python code, like the
|
||||
condition or code server actions.
|
||||
|
||||
:param action: the current server action
|
||||
:type action: browse record
|
||||
:returns: dict -- evaluation context given to (safe_)eval """
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
obj_pool = self.pool[action.model_id.model]
|
||||
obj = None
|
||||
if context.get('active_model') == action.model_id.model and context.get('active_id'):
|
||||
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
|
||||
return {
|
||||
'self': obj_pool,
|
||||
'object': obj,
|
||||
'obj': obj,
|
||||
'pool': self.pool,
|
||||
'time': time,
|
||||
'cr': cr,
|
||||
'uid': uid,
|
||||
'user': user,
|
||||
}
|
||||
|
||||
def run(self, cr, uid, ids, context=None):
|
||||
""" Run the server action. For each server action, the condition is
|
||||
checked. Note that A void (aka False) condition is considered as always
|
||||
""" Runs the server action. For each server action, the condition is
|
||||
checked. Note that a void (``False``) condition is considered as always
|
||||
valid. If it is verified, the run_action_<STATE> method is called. This
|
||||
allows easy inheritance of the server actions.
|
||||
allows easy overriding of the server actions.
|
||||
|
||||
:param dict context: context should contain following keys
|
||||
|
||||
|
@ -932,25 +955,9 @@ class ir_actions_server(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
res = False
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid)
|
||||
active_ids = context.get('active_ids', [context.get('active_id')])
|
||||
for action in self.browse(cr, uid, ids, context):
|
||||
obj_pool = self.pool[action.model_id.model]
|
||||
obj = None
|
||||
if context.get('active_model') == action.model_id.model and context.get('active_id'):
|
||||
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
|
||||
|
||||
# evaluation context for python strings to evaluate
|
||||
eval_context = {
|
||||
'self': obj_pool,
|
||||
'object': obj,
|
||||
'obj': obj,
|
||||
'pool': self.pool,
|
||||
'time': time,
|
||||
'cr': cr,
|
||||
'uid': uid,
|
||||
'user': user,
|
||||
}
|
||||
eval_context = self._get_eval_context(cr, uid, action, context=context)
|
||||
condition = action.condition
|
||||
if condition is False:
|
||||
# Void (aka False) conditions are considered as True
|
||||
|
|
|
@ -45,6 +45,7 @@ class ir_attachment(osv.osv):
|
|||
The default implementation is the file:dirname location that stores files
|
||||
on the local filesystem using name based on their sha1 hash
|
||||
"""
|
||||
_order = 'id desc'
|
||||
def _name_get_resname(self, cr, uid, ids, object, method, context):
|
||||
data = {}
|
||||
for attachment in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -242,7 +243,7 @@ class ir_attachment(osv.osv):
|
|||
# performed in batch as much as possible.
|
||||
ima = self.pool.get('ir.model.access')
|
||||
for model, targets in model_attachments.iteritems():
|
||||
if model not in self.pool:
|
||||
if not self.pool.get(model):
|
||||
continue
|
||||
if not ima.check(cr, uid, model, 'read', False):
|
||||
# remove all corresponding attachment ids
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import cStringIO
|
||||
import datetime
|
||||
import functools
|
||||
import operator
|
||||
|
@ -12,6 +13,7 @@ from openerp.osv import orm
|
|||
from openerp.tools.translate import _
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT,\
|
||||
DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.tools import html_sanitize
|
||||
|
||||
REFERENCING_FIELDS = set([None, 'id', '.id'])
|
||||
def only_ref_fields(record):
|
||||
|
@ -128,14 +130,17 @@ class ir_fields_converter(orm.Model):
|
|||
|
||||
:param column: column object to generate a value for
|
||||
:type column: :class:`fields._column`
|
||||
:param type fromtype: type to convert to something fitting for ``column``
|
||||
:param fromtype: type to convert to something fitting for ``column``
|
||||
:type fromtype: type | str
|
||||
:param context: openerp request context
|
||||
:return: a function (fromtype -> column.write_type), if a converter is found
|
||||
:rtype: Callable | None
|
||||
"""
|
||||
assert isinstance(fromtype, (type, str))
|
||||
# FIXME: return None
|
||||
typename = fromtype.__name__ if isinstance(fromtype, type) else fromtype
|
||||
converter = getattr(
|
||||
self, '_%s_to_%s' % (fromtype.__name__, column._type), None)
|
||||
self, '_%s_to_%s' % (typename, column._type), None)
|
||||
if not converter: return None
|
||||
|
||||
return functools.partial(
|
||||
|
@ -184,7 +189,7 @@ class ir_fields_converter(orm.Model):
|
|||
|
||||
def _str_id(self, cr, uid, model, column, value, context=None):
|
||||
return value, []
|
||||
_str_to_reference = _str_to_char = _str_to_text = _str_to_binary = _str_id
|
||||
_str_to_reference = _str_to_char = _str_to_text = _str_to_binary = _str_to_html = _str_id
|
||||
|
||||
def _str_to_date(self, cr, uid, model, column, value, context=None):
|
||||
try:
|
||||
|
|
|
@ -15,9 +15,7 @@ from openerp.osv import osv, orm
|
|||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# FIXME: replace by proxy on request.uid?
|
||||
_uid = object()
|
||||
UID_PLACEHOLDER = object()
|
||||
|
||||
class ModelConverter(werkzeug.routing.BaseConverter):
|
||||
|
||||
|
@ -29,7 +27,7 @@ class ModelConverter(werkzeug.routing.BaseConverter):
|
|||
def to_python(self, value):
|
||||
m = re.match(self.regex, value)
|
||||
return request.registry[self.model].browse(
|
||||
request.cr, _uid, int(m.group(1)), context=request.context)
|
||||
request.cr, UID_PLACEHOLDER, int(m.group(1)), context=request.context)
|
||||
|
||||
def to_url(self, value):
|
||||
return value.id
|
||||
|
@ -43,10 +41,7 @@ class ModelsConverter(werkzeug.routing.BaseConverter):
|
|||
self.regex = '([0-9,]+)'
|
||||
|
||||
def to_python(self, value):
|
||||
# TODO:
|
||||
# - raise routing.ValidationError() if no browse record can be createdm
|
||||
# - support slug
|
||||
return request.registry[self.model].browse(request.cr, _uid, [int(i) for i in value.split(',')], context=request.context)
|
||||
return request.registry[self.model].browse(request.cr, UID_PLACEHOLDER, [int(i) for i in value.split(',')], context=request.context)
|
||||
|
||||
def to_url(self, value):
|
||||
return ",".join(i.id for i in value)
|
||||
|
@ -66,15 +61,15 @@ class ir_http(osv.AbstractModel):
|
|||
if not request.uid:
|
||||
raise http.SessionExpiredException("Session expired")
|
||||
|
||||
def _auth_method_admin(self):
|
||||
if not request.db:
|
||||
raise http.SessionExpiredException("No valid database for request %s" % request.httprequest)
|
||||
request.uid = openerp.SUPERUSER_ID
|
||||
|
||||
def _auth_method_none(self):
|
||||
request.disable_db = True
|
||||
request.uid = None
|
||||
|
||||
def _auth_method_public(self):
|
||||
if not request.session.uid:
|
||||
dummy, request.uid = self.pool['ir.model.data'].get_object_reference(request.cr, openerp.SUPERUSER_ID, 'base', 'public_user')
|
||||
else:
|
||||
request.uid = request.session.uid
|
||||
|
||||
def _authenticate(self, auth_method='user'):
|
||||
if request.session.uid:
|
||||
try:
|
||||
|
@ -88,16 +83,8 @@ class ir_http(osv.AbstractModel):
|
|||
return auth_method
|
||||
|
||||
def _handle_exception(self, exception):
|
||||
if isinstance(exception, openerp.exceptions.AccessError):
|
||||
code = 403
|
||||
else:
|
||||
code = getattr(exception, 'code', 500)
|
||||
|
||||
fn = getattr(self, '_handle_%d' % code, self._handle_unknown_exception)
|
||||
return fn(exception)
|
||||
|
||||
def _handle_unknown_exception(self, exception):
|
||||
raise exception
|
||||
# If handle exception return something different than None, it will be used as a response
|
||||
raise
|
||||
|
||||
def _dispatch(self):
|
||||
# locate the controller method
|
||||
|
@ -108,17 +95,17 @@ class ir_http(osv.AbstractModel):
|
|||
|
||||
# check authentication level
|
||||
try:
|
||||
auth_method = self._authenticate(getattr(func, "auth", None))
|
||||
auth_method = self._authenticate(func.routing["auth"])
|
||||
except Exception:
|
||||
# force a Forbidden exception with the original traceback
|
||||
return self._handle_exception(
|
||||
convert_exception_to(
|
||||
werkzeug.exceptions.Forbidden))
|
||||
|
||||
# post process arg to set uid on browse records
|
||||
for arg in arguments.itervalues():
|
||||
if isinstance(arg, orm.browse_record) and arg._uid is _uid:
|
||||
arg._uid = request.uid
|
||||
processing = self._postprocess_args(arguments)
|
||||
if processing:
|
||||
return processing
|
||||
|
||||
|
||||
# set and execute handler
|
||||
try:
|
||||
|
@ -131,6 +118,16 @@ class ir_http(osv.AbstractModel):
|
|||
|
||||
return result
|
||||
|
||||
def _postprocess_args(self, arguments):
|
||||
""" post process arg to set uid on browse records """
|
||||
for arg in arguments.itervalues():
|
||||
if isinstance(arg, orm.browse_record) and arg._uid is UID_PLACEHOLDER:
|
||||
arg._uid = request.uid
|
||||
try:
|
||||
arg[arg._rec_name]
|
||||
except KeyError:
|
||||
return self._handle_exception(werkzeug.exceptions.NotFound())
|
||||
|
||||
def routing_map(self):
|
||||
if not hasattr(self, '_routing_map'):
|
||||
_logger.info("Generating routing map")
|
||||
|
@ -138,7 +135,7 @@ class ir_http(osv.AbstractModel):
|
|||
m = request.registry.get('ir.module.module')
|
||||
ids = m.search(cr, openerp.SUPERUSER_ID, [('state', '=', 'installed'), ('name', '!=', 'web')], context=request.context)
|
||||
installed = set(x['name'] for x in m.read(cr, 1, ids, ['name'], context=request.context))
|
||||
mods = ['', "web"] + sorted(installed)
|
||||
mods = [''] + openerp.conf.server_wide_modules + sorted(installed)
|
||||
self._routing_map = http.routing_map(mods, False, converters=self._get_converters())
|
||||
|
||||
return self._routing_map
|
||||
|
|
|
@ -411,6 +411,7 @@ class ir_mail_server(osv.osv):
|
|||
email_to = message['To']
|
||||
email_cc = message['Cc']
|
||||
email_bcc = message['Bcc']
|
||||
|
||||
smtp_to_list = filter(None, tools.flatten(map(extract_rfc2822_addresses,[email_to, email_cc, email_bcc])))
|
||||
assert smtp_to_list, "At least one valid recipient address should be specified for outgoing emails (To/Cc/Bcc)"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Business Applications
|
||||
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
|
||||
# Copyright (C) 2004-2014 OpenERP S.A. (<http://openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -29,7 +29,7 @@ import openerp.modules.registry
|
|||
from openerp import SUPERUSER_ID
|
||||
from openerp import tools
|
||||
from openerp.osv import fields,osv
|
||||
from openerp.osv.orm import Model
|
||||
from openerp.osv.orm import Model, browse_null
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.tools import config
|
||||
from openerp.tools.translate import _
|
||||
|
@ -737,7 +737,7 @@ class ir_model_access(osv.osv):
|
|||
msg_params = (model_name,)
|
||||
_logger.warning('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, uid, model_name)
|
||||
msg = '%s %s' % (msg_heads[mode], msg_tail)
|
||||
raise except_orm(_('Access Denied'), msg % msg_params)
|
||||
raise openerp.exceptions.AccessError(msg % msg_params)
|
||||
return r or False
|
||||
|
||||
__cache_clearing_methods = []
|
||||
|
@ -853,24 +853,58 @@ class ir_model_data(osv.osv):
|
|||
if not cr.fetchone():
|
||||
cr.execute('CREATE INDEX ir_model_data_module_name_index ON ir_model_data (module, name)')
|
||||
|
||||
@tools.ormcache()
|
||||
# NEW V8 API
|
||||
@tools.ormcache(skiparg=3)
|
||||
def xmlid_lookup(self, cr, uid, xmlid):
|
||||
"""Low level xmlid lookup
|
||||
Return (id, res_model, res_id) or raise ValueError if not found
|
||||
"""
|
||||
module, name = xmlid.split('.', 1)
|
||||
ids = self.search(cr, uid, [('module','=',module), ('name','=', name)])
|
||||
if not ids:
|
||||
raise ValueError('External ID not found in the system: %s' % (xmlid))
|
||||
# the sql constraints ensure us we have only one result
|
||||
res = self.read(cr, uid, ids[0], ['model', 'res_id'])
|
||||
if not res['res_id']:
|
||||
raise ValueError('External ID not found in the system: %s' % (xmlid))
|
||||
return ids[0], res['model'], res['res_id']
|
||||
|
||||
def xmlid_to_res_model_res_id(self, cr, uid, xmlid, raise_if_not_found=False):
|
||||
""" Return (res_model, res_id)"""
|
||||
try:
|
||||
return self.xmlid_lookup(cr, uid, xmlid)[1:3]
|
||||
except ValueError:
|
||||
if raise_if_not_found:
|
||||
raise
|
||||
return (False, False)
|
||||
|
||||
def xmlid_to_res_id(self, cr, uid, xmlid, raise_if_not_found=False):
|
||||
""" Returns res_id """
|
||||
return self.xmlid_to_res_model_res_id(cr, uid, xmlid, raise_if_not_found)[1]
|
||||
|
||||
def xmlid_to_object(self, cr, uid, xmlid, raise_if_not_found=False, context=None):
|
||||
""" Return a browse_record
|
||||
if not found and raise_if_not_found is True return the browse_null
|
||||
"""
|
||||
t = self.xmlid_to_res_model_res_id(cr, uid, xmlid, raise_if_not_found)
|
||||
res_model, res_id = t
|
||||
|
||||
if res_model and res_id:
|
||||
record = self.pool[res_model].browse(cr, uid, res_id, context=context)
|
||||
if record.exists():
|
||||
return record
|
||||
if raise_if_not_found:
|
||||
raise ValueError('No record found for unique ID %s. It may have been deleted.' % (xml_id))
|
||||
return browse_null()
|
||||
|
||||
# OLD API
|
||||
def _get_id(self, cr, uid, module, xml_id):
|
||||
"""Returns the id of the ir.model.data record corresponding to a given module and xml_id (cached) or raise a ValueError if not found"""
|
||||
ids = self.search(cr, uid, [('module','=',module), ('name','=', xml_id)])
|
||||
if not ids:
|
||||
raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
|
||||
# the sql constraints ensure us we have only one result
|
||||
return ids[0]
|
||||
return self.xmlid_lookup(cr, uid, "%s.%s" % (module, xml_id))[0]
|
||||
|
||||
@tools.ormcache()
|
||||
def get_object_reference(self, cr, uid, module, xml_id):
|
||||
"""Returns (model, res_id) corresponding to a given module and xml_id (cached) or raise ValueError if not found"""
|
||||
data_id = self._get_id(cr, uid, module, xml_id)
|
||||
#assuming data_id is not False, as it was checked upstream
|
||||
res = self.read(cr, uid, data_id, ['model', 'res_id'])
|
||||
if not res['res_id']:
|
||||
raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
|
||||
return res['model'], res['res_id']
|
||||
return self.xmlid_lookup(cr, uid, "%s.%s" % (module, xml_id))[1:3]
|
||||
|
||||
def check_object_reference(self, cr, uid, module, xml_id, raise_on_access_error=False):
|
||||
"""Returns (model, res_id) corresponding to a given module and xml_id (cached), if and only if the user has the necessary access rights
|
||||
|
@ -885,12 +919,11 @@ class ir_model_data(osv.osv):
|
|||
return model, False
|
||||
|
||||
def get_object(self, cr, uid, module, xml_id, context=None):
|
||||
"""Returns a browsable record for the given module name and xml_id or raise ValueError if not found"""
|
||||
res_model, res_id = self.get_object_reference(cr, uid, module, xml_id)
|
||||
result = self.pool[res_model].browse(cr, uid, res_id, context=context)
|
||||
if not result.exists():
|
||||
raise ValueError('No record found for unique ID %s.%s. It may have been deleted.' % (module, xml_id))
|
||||
return result
|
||||
""" Returns a browsable record for the given module name and xml_id.
|
||||
If not found, raise a ValueError or return a browse_null, depending
|
||||
on the value of `raise_exception`.
|
||||
"""
|
||||
return self.xmlid_to_object(cr, uid, "%s.%s" % (module, xml_id), raise_if_not_found=True, context=context)
|
||||
|
||||
def _update_dummy(self,cr, uid, model, module, xml_id=False, store=True):
|
||||
if not xml_id:
|
||||
|
@ -907,8 +940,7 @@ class ir_model_data(osv.osv):
|
|||
|
||||
:returns: itself
|
||||
"""
|
||||
self._get_id.clear_cache(self)
|
||||
self.get_object_reference.clear_cache(self)
|
||||
self.xmlid_lookup.clear_cache(self)
|
||||
return self
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
|
@ -929,15 +961,17 @@ class ir_model_data(osv.osv):
|
|||
return False
|
||||
action_id = False
|
||||
if xml_id:
|
||||
cr.execute('''SELECT imd.id, imd.res_id, md.id, imd.model
|
||||
cr.execute('''SELECT imd.id, imd.res_id, md.id, imd.model, imd.noupdate
|
||||
FROM ir_model_data imd LEFT JOIN %s md ON (imd.res_id = md.id)
|
||||
WHERE imd.module=%%s AND imd.name=%%s''' % model_obj._table,
|
||||
(module, xml_id))
|
||||
results = cr.fetchall()
|
||||
for imd_id2,res_id2,real_id2,real_model in results:
|
||||
for imd_id2,res_id2,real_id2,real_model,noupdate_imd in results:
|
||||
# In update mode, do not update a record if it's ir.model.data is flagged as noupdate
|
||||
if mode == 'update' and noupdate_imd:
|
||||
return res_id2
|
||||
if not real_id2:
|
||||
self._get_id.clear_cache(self, uid, module, xml_id)
|
||||
self.get_object_reference.clear_cache(self, uid, module, xml_id)
|
||||
self.clear_caches()
|
||||
cr.execute('delete from ir_model_data where id=%s', (imd_id2,))
|
||||
res_id = False
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,850 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import collections
|
||||
import cStringIO
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import re
|
||||
import sys
|
||||
import xml # FIXME use lxml and etree
|
||||
|
||||
import babel
|
||||
import babel.dates
|
||||
import werkzeug.utils
|
||||
from PIL import Image
|
||||
|
||||
import openerp.tools
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.osv import osv, orm, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# QWeb template engine
|
||||
#--------------------------------------------------------------------
|
||||
class QWebException(Exception):
|
||||
def __init__(self, message, **kw):
|
||||
Exception.__init__(self, message)
|
||||
self.qweb = dict(kw)
|
||||
|
||||
class QWebTemplateNotFound(QWebException):
|
||||
pass
|
||||
|
||||
def convert_to_qweb_exception(etype=None, **kw):
|
||||
if etype is None:
|
||||
etype = QWebException
|
||||
orig_type, original, tb = sys.exc_info()
|
||||
try:
|
||||
raise etype, original, tb
|
||||
except etype, e:
|
||||
for k, v in kw.items():
|
||||
e.qweb[k] = v
|
||||
# Will use `raise foo from bar` in python 3 and rename cause to __cause__
|
||||
e.qweb['cause'] = original
|
||||
return e
|
||||
|
||||
class QWebContext(dict):
|
||||
def __init__(self, cr, uid, data, loader=None, templates=None, context=None):
|
||||
self.cr = cr
|
||||
self.uid = uid
|
||||
self.loader = loader
|
||||
self.templates = templates or {}
|
||||
self.context = context
|
||||
dic = dict(data)
|
||||
super(QWebContext, self).__init__(dic)
|
||||
self['defined'] = lambda key: key in self
|
||||
|
||||
def safe_eval(self, expr):
|
||||
locals_dict = collections.defaultdict(lambda: None)
|
||||
locals_dict.update(self)
|
||||
locals_dict.pop('cr', None)
|
||||
locals_dict.pop('loader', None)
|
||||
return eval(expr, None, locals_dict, nocopy=True, locals_builtins=True)
|
||||
|
||||
def copy(self):
|
||||
return QWebContext(self.cr, self.uid, dict.copy(self),
|
||||
loader=self.loader,
|
||||
templates=self.templates,
|
||||
context=self.context)
|
||||
|
||||
def __copy__(self):
|
||||
return self.copy()
|
||||
|
||||
class QWeb(orm.AbstractModel):
|
||||
"""QWeb Xml templating engine
|
||||
|
||||
The templating engine use a very simple syntax based "magic" xml
|
||||
attributes, to produce textual output (even non-xml).
|
||||
|
||||
The core magic attributes are:
|
||||
|
||||
flow attributes:
|
||||
t-if t-foreach t-call
|
||||
|
||||
output attributes:
|
||||
t-att t-raw t-esc t-trim
|
||||
|
||||
assignation attribute:
|
||||
t-set
|
||||
|
||||
QWeb can be extended like any OpenERP model and new attributes can be
|
||||
added.
|
||||
|
||||
If you need to customize t-fields rendering, subclass the ir.qweb.field
|
||||
model (and its sub-models) then override :meth:`~.get_converter_for` to
|
||||
fetch the right field converters for your qweb model.
|
||||
|
||||
Beware that if you need extensions or alterations which could be
|
||||
incompatible with other subsystems, you should create a local object
|
||||
inheriting from ``ir.qweb`` and customize that.
|
||||
"""
|
||||
|
||||
_name = 'ir.qweb'
|
||||
|
||||
node = xml.dom.Node
|
||||
_void_elements = frozenset([
|
||||
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen',
|
||||
'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'])
|
||||
_format_regex = re.compile(
|
||||
'(?:'
|
||||
# ruby-style pattern
|
||||
'#\{(.+?)\}'
|
||||
')|(?:'
|
||||
# jinja-style pattern
|
||||
'\{\{(.+?)\}\}'
|
||||
')')
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
super(QWeb, self).__init__(pool, cr)
|
||||
|
||||
self._render_tag = self.prefixed_methods('render_tag_')
|
||||
self._render_att = self.prefixed_methods('render_att_')
|
||||
|
||||
def prefixed_methods(self, prefix):
|
||||
""" Extracts all methods prefixed by ``prefix``, and returns a mapping
|
||||
of (t-name, method) where the t-name is the method name with prefix
|
||||
removed and underscore converted to dashes
|
||||
|
||||
:param str prefix:
|
||||
:return: dict
|
||||
"""
|
||||
n_prefix = len(prefix)
|
||||
return dict(
|
||||
(name[n_prefix:].replace('_', '-'), getattr(type(self), name))
|
||||
for name in dir(self)
|
||||
if name.startswith(prefix)
|
||||
)
|
||||
|
||||
def register_tag(self, tag, func):
|
||||
self._render_tag[tag] = func
|
||||
|
||||
def add_template(self, qwebcontext, name, node):
|
||||
"""Add a parsed template in the context. Used to preprocess templates."""
|
||||
qwebcontext.templates[name] = node
|
||||
|
||||
def load_document(self, document, qwebcontext):
|
||||
"""
|
||||
Loads an XML document and installs any contained template in the engine
|
||||
"""
|
||||
if hasattr(document, 'documentElement'):
|
||||
dom = document
|
||||
elif document.startswith("<?xml"):
|
||||
dom = xml.dom.minidom.parseString(document)
|
||||
else:
|
||||
dom = xml.dom.minidom.parse(document)
|
||||
|
||||
for node in dom.documentElement.childNodes:
|
||||
if node.nodeType == self.node.ELEMENT_NODE and node.getAttribute('t-name'):
|
||||
name = str(node.getAttribute("t-name"))
|
||||
self.add_template(qwebcontext, name, node)
|
||||
|
||||
def get_template(self, name, qwebcontext):
|
||||
origin_template = qwebcontext.get('__caller__') or qwebcontext['__stack__'][0]
|
||||
if qwebcontext.loader and name not in qwebcontext.templates:
|
||||
try:
|
||||
xml_doc = qwebcontext.loader(name)
|
||||
except ValueError:
|
||||
raise convert_to_qweb_exception(QWebTemplateNotFound, message="Loader could not find template %r" % name, template=origin_template)
|
||||
self.load_document(xml_doc, qwebcontext=qwebcontext)
|
||||
|
||||
if name in qwebcontext.templates:
|
||||
return qwebcontext.templates[name]
|
||||
|
||||
raise QWebTemplateNotFound("Template %r not found" % name, template=origin_template)
|
||||
|
||||
def eval(self, expr, qwebcontext):
|
||||
try:
|
||||
return qwebcontext.safe_eval(expr)
|
||||
except Exception:
|
||||
template = qwebcontext.get('__template__')
|
||||
raise convert_to_qweb_exception(message="Could not evaluate expression %r" % expr, expression=expr, template=template)
|
||||
|
||||
def eval_object(self, expr, qwebcontext):
|
||||
return self.eval(expr, qwebcontext)
|
||||
|
||||
def eval_str(self, expr, qwebcontext):
|
||||
if expr == "0":
|
||||
return qwebcontext.get(0, '')
|
||||
val = self.eval(expr, qwebcontext)
|
||||
if isinstance(val, unicode):
|
||||
return val.encode("utf8")
|
||||
if val is False or val is None:
|
||||
return ''
|
||||
return str(val)
|
||||
|
||||
def eval_format(self, expr, qwebcontext):
|
||||
expr, replacements = self._format_regex.subn(
|
||||
lambda m: self.eval_str(m.group(1) or m.group(2), qwebcontext),
|
||||
expr
|
||||
)
|
||||
|
||||
if replacements:
|
||||
return expr
|
||||
|
||||
try:
|
||||
return str(expr % qwebcontext)
|
||||
except Exception:
|
||||
template = qwebcontext.get('__template__')
|
||||
raise convert_to_qweb_exception(message="Format error for expression %r" % expr, expression=expr, template=template)
|
||||
|
||||
def eval_bool(self, expr, qwebcontext):
|
||||
return int(bool(self.eval(expr, qwebcontext)))
|
||||
|
||||
def render(self, cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None):
|
||||
if qwebcontext is None:
|
||||
qwebcontext = {}
|
||||
|
||||
if not isinstance(qwebcontext, QWebContext):
|
||||
qwebcontext = QWebContext(cr, uid, qwebcontext, loader=loader, context=context)
|
||||
|
||||
qwebcontext['__template__'] = id_or_xml_id
|
||||
stack = qwebcontext.get('__stack__', [])
|
||||
if stack:
|
||||
qwebcontext['__caller__'] = stack[-1]
|
||||
stack.append(id_or_xml_id)
|
||||
qwebcontext['__stack__'] = stack
|
||||
qwebcontext['xmlid'] = str(stack[0]) # Temporary fix
|
||||
return self.render_node(self.get_template(id_or_xml_id, qwebcontext), qwebcontext)
|
||||
|
||||
def render_node(self, element, qwebcontext):
|
||||
result = ""
|
||||
if element.nodeType == self.node.TEXT_NODE or element.nodeType == self.node.CDATA_SECTION_NODE:
|
||||
result = element.data.encode("utf8")
|
||||
elif element.nodeType == self.node.ELEMENT_NODE:
|
||||
generated_attributes = ""
|
||||
t_render = None
|
||||
template_attributes = {}
|
||||
for (attribute_name, attribute_value) in element.attributes.items():
|
||||
attribute_name = str(attribute_name)
|
||||
if attribute_name == "groups":
|
||||
cr = qwebcontext.get('request') and qwebcontext['request'].cr or None
|
||||
uid = qwebcontext.get('request') and qwebcontext['request'].uid or None
|
||||
can_see = self.user_has_groups(cr, uid, groups=attribute_value)
|
||||
if not can_see:
|
||||
return ''
|
||||
continue
|
||||
|
||||
if isinstance(attribute_value, unicode):
|
||||
attribute_value = attribute_value.encode("utf8")
|
||||
else:
|
||||
attribute_value = attribute_value.nodeValue.encode("utf8")
|
||||
|
||||
if attribute_name.startswith("t-"):
|
||||
for attribute in self._render_att:
|
||||
if attribute_name[2:].startswith(attribute):
|
||||
att, val = self._render_att[attribute](self, element, attribute_name, attribute_value, qwebcontext)
|
||||
generated_attributes += val and ' %s="%s"' % (att, werkzeug.utils.escape(val)) or " "
|
||||
break
|
||||
else:
|
||||
if attribute_name[2:] in self._render_tag:
|
||||
t_render = attribute_name[2:]
|
||||
template_attributes[attribute_name[2:]] = attribute_value
|
||||
else:
|
||||
generated_attributes += ' %s="%s"' % (attribute_name, werkzeug.utils.escape(attribute_value))
|
||||
|
||||
if 'debug' in template_attributes:
|
||||
debugger = template_attributes.get('debug', 'pdb')
|
||||
__import__(debugger).set_trace() # pdb, ipdb, pudb, ...
|
||||
if t_render:
|
||||
result = self._render_tag[t_render](self, element, template_attributes, generated_attributes, qwebcontext)
|
||||
else:
|
||||
result = self.render_element(element, template_attributes, generated_attributes, qwebcontext)
|
||||
if isinstance(result, unicode):
|
||||
return result.encode('utf-8')
|
||||
return result
|
||||
|
||||
def render_element(self, element, template_attributes, generated_attributes, qwebcontext, inner=None):
|
||||
# element: element
|
||||
# template_attributes: t-* attributes
|
||||
# generated_attributes: generated attributes
|
||||
# qwebcontext: values
|
||||
# inner: optional innerXml
|
||||
if inner:
|
||||
g_inner = inner
|
||||
else:
|
||||
g_inner = []
|
||||
for current_node in element.childNodes:
|
||||
try:
|
||||
g_inner.append(self.render_node(current_node, qwebcontext))
|
||||
except QWebException:
|
||||
raise
|
||||
except Exception:
|
||||
template = qwebcontext.get('__template__')
|
||||
raise convert_to_qweb_exception(message="Could not render element %r" % element.nodeName, node=element, template=template)
|
||||
name = str(element.nodeName)
|
||||
inner = "".join(g_inner)
|
||||
trim = template_attributes.get("trim", 0)
|
||||
if trim == 0:
|
||||
pass
|
||||
elif trim == 'left':
|
||||
inner = inner.lstrip()
|
||||
elif trim == 'right':
|
||||
inner = inner.rstrip()
|
||||
elif trim == 'both':
|
||||
inner = inner.strip()
|
||||
if name == "t":
|
||||
return inner
|
||||
elif len(inner) or name not in self._void_elements:
|
||||
return "<%s%s>%s</%s>" % tuple(
|
||||
qwebcontext if isinstance(qwebcontext, str) else qwebcontext.encode('utf-8')
|
||||
for qwebcontext in (name, generated_attributes, inner, name)
|
||||
)
|
||||
else:
|
||||
return "<%s%s/>" % (name, generated_attributes)
|
||||
|
||||
# Attributes
|
||||
def render_att_att(self, element, attribute_name, attribute_value, qwebcontext):
|
||||
if attribute_name.startswith("t-attf-"):
|
||||
att, val = attribute_name[7:], self.eval_format(attribute_value, qwebcontext)
|
||||
elif attribute_name.startswith("t-att-"):
|
||||
att, val = attribute_name[6:], self.eval(attribute_value, qwebcontext)
|
||||
if isinstance(val, unicode):
|
||||
val = val.encode("utf8")
|
||||
else:
|
||||
att, val = self.eval_object(attribute_value, qwebcontext)
|
||||
return att, val
|
||||
|
||||
# Tags
|
||||
def render_tag_raw(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
inner = self.eval_str(template_attributes["raw"], qwebcontext)
|
||||
return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner)
|
||||
|
||||
def render_tag_esc(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
inner = werkzeug.utils.escape(self.eval_str(template_attributes["esc"], qwebcontext))
|
||||
return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner)
|
||||
|
||||
def render_tag_foreach(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
expr = template_attributes["foreach"]
|
||||
enum = self.eval_object(expr, qwebcontext)
|
||||
if enum is not None:
|
||||
var = template_attributes.get('as', expr).replace('.', '_')
|
||||
copy_qwebcontext = qwebcontext.copy()
|
||||
size = -1
|
||||
if isinstance(enum, (list, tuple)):
|
||||
size = len(enum)
|
||||
elif hasattr(enum, 'count'):
|
||||
size = enum.count()
|
||||
copy_qwebcontext["%s_size" % var] = size
|
||||
copy_qwebcontext["%s_all" % var] = enum
|
||||
index = 0
|
||||
ru = []
|
||||
for i in enum:
|
||||
copy_qwebcontext["%s_value" % var] = i
|
||||
copy_qwebcontext["%s_index" % var] = index
|
||||
copy_qwebcontext["%s_first" % var] = index == 0
|
||||
copy_qwebcontext["%s_even" % var] = index % 2
|
||||
copy_qwebcontext["%s_odd" % var] = (index + 1) % 2
|
||||
copy_qwebcontext["%s_last" % var] = index + 1 == size
|
||||
if index % 2:
|
||||
copy_qwebcontext["%s_parity" % var] = 'odd'
|
||||
else:
|
||||
copy_qwebcontext["%s_parity" % var] = 'even'
|
||||
if 'as' in template_attributes:
|
||||
copy_qwebcontext[var] = i
|
||||
elif isinstance(i, dict):
|
||||
copy_qwebcontext.update(i)
|
||||
ru.append(self.render_element(element, template_attributes, generated_attributes, copy_qwebcontext))
|
||||
index += 1
|
||||
return "".join(ru)
|
||||
else:
|
||||
template = qwebcontext.get('__template__')
|
||||
raise QWebException("foreach enumerator %r is not defined while rendering template %r" % (expr, template), template=template)
|
||||
|
||||
def render_tag_if(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
if self.eval_bool(template_attributes["if"], qwebcontext):
|
||||
return self.render_element(element, template_attributes, generated_attributes, qwebcontext)
|
||||
return ""
|
||||
|
||||
def render_tag_call(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
d = qwebcontext.copy()
|
||||
d[0] = self.render_element(element, template_attributes, generated_attributes, d)
|
||||
cr = d.get('request') and d['request'].cr or None
|
||||
uid = d.get('request') and d['request'].uid or None
|
||||
|
||||
return self.render(cr, uid, self.eval_format(template_attributes["call"], d), d)
|
||||
|
||||
def render_tag_set(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
if "value" in template_attributes:
|
||||
qwebcontext[template_attributes["set"]] = self.eval_object(template_attributes["value"], qwebcontext)
|
||||
elif "valuef" in template_attributes:
|
||||
qwebcontext[template_attributes["set"]] = self.eval_format(template_attributes["valuef"], qwebcontext)
|
||||
else:
|
||||
qwebcontext[template_attributes["set"]] = self.render_element(element, template_attributes, generated_attributes, qwebcontext)
|
||||
return ""
|
||||
|
||||
def render_tag_field(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
""" eg: <span t-record="browse_record(res.partner, 1)" t-field="phone">+1 555 555 8069</span>"""
|
||||
node_name = element.nodeName
|
||||
assert node_name not in ("table", "tbody", "thead", "tfoot", "tr", "td",
|
||||
"li", "ul", "ol", "dl", "dt", "dd"),\
|
||||
"RTE widgets do not work correctly on %r elements" % node_name
|
||||
assert node_name != 't',\
|
||||
"t-field can not be used on a t element, provide an actual HTML node"
|
||||
|
||||
record, field_name = template_attributes["field"].rsplit('.', 1)
|
||||
record = self.eval_object(record, qwebcontext)
|
||||
|
||||
column = record._model._all_columns[field_name].column
|
||||
options = json.loads(template_attributes.get('field-options') or '{}')
|
||||
field_type = get_field_type(column, options)
|
||||
|
||||
converter = self.get_converter_for(field_type)
|
||||
|
||||
return converter.to_html(qwebcontext.cr, qwebcontext.uid, field_name, record, options,
|
||||
element, template_attributes, generated_attributes, qwebcontext, context=qwebcontext.context)
|
||||
|
||||
def get_converter_for(self, field_type):
|
||||
return self.pool.get('ir.qweb.field.' + field_type,
|
||||
self.pool['ir.qweb.field'])
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# QWeb Fields converters
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
class FieldConverter(osv.AbstractModel):
|
||||
""" Used to convert a t-field specification into an output HTML field.
|
||||
|
||||
:meth:`~.to_html` is the entry point of this conversion from QWeb, it:
|
||||
|
||||
* converts the record value to html using :meth:`~.record_to_html`
|
||||
* generates the metadata attributes (``data-oe-``) to set on the root
|
||||
result node
|
||||
* generates the root result node itself through :meth:`~.render_element`
|
||||
"""
|
||||
_name = 'ir.qweb.field'
|
||||
|
||||
def attributes(self, cr, uid, field_name, record, options,
|
||||
source_element, g_att, t_att, qweb_context,
|
||||
context=None):
|
||||
"""
|
||||
Generates the metadata attributes (prefixed by ``data-oe-`` for the
|
||||
root node of the field conversion. Attribute values are escaped by the
|
||||
parent using ``werkzeug.utils.escape``.
|
||||
|
||||
The default attributes are:
|
||||
|
||||
* ``model``, the name of the record's model
|
||||
* ``id`` the id of the record to which the field belongs
|
||||
* ``field`` the name of the converted field
|
||||
* ``type`` the logical field type (widget, may not match the column's
|
||||
``type``, may not be any _column subclass name)
|
||||
* ``translate``, a boolean flag (``0`` or ``1``) denoting whether the
|
||||
column is translatable
|
||||
* ``expression``, the original expression
|
||||
|
||||
:returns: iterable of (attribute name, attribute value) pairs.
|
||||
"""
|
||||
column = record._model._all_columns[field_name].column
|
||||
field_type = get_field_type(column, options)
|
||||
return [
|
||||
('data-oe-model', record._model._name),
|
||||
('data-oe-id', record.id),
|
||||
('data-oe-field', field_name),
|
||||
('data-oe-type', field_type),
|
||||
('data-oe-expression', t_att['field']),
|
||||
]
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
""" Converts a single value to its HTML version/output
|
||||
"""
|
||||
if not value: return ''
|
||||
return value
|
||||
|
||||
def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None):
|
||||
""" Converts the specified field of the browse_record ``record`` to
|
||||
HTML
|
||||
"""
|
||||
return self.value_to_html(
|
||||
cr, uid, record[field_name], column, options=options, context=context)
|
||||
|
||||
def to_html(self, cr, uid, field_name, record, options,
|
||||
source_element, t_att, g_att, qweb_context, context=None):
|
||||
""" Converts a ``t-field`` to its HTML output. A ``t-field`` may be
|
||||
extended by a ``t-field-options``, which is a JSON-serialized mapping
|
||||
of configuration values.
|
||||
|
||||
A default configuration key is ``widget`` which can override the
|
||||
field's own ``_type``.
|
||||
"""
|
||||
content = None
|
||||
try:
|
||||
content = self.record_to_html(
|
||||
cr, uid, field_name, record,
|
||||
record._model._all_columns[field_name].column,
|
||||
options, context=context)
|
||||
if options.get('html-escape', True):
|
||||
content = werkzeug.utils.escape(content)
|
||||
elif hasattr(content, '__html__'):
|
||||
content = content.__html__()
|
||||
except Exception:
|
||||
_logger.warning("Could not get field %s for model %s",
|
||||
field_name, record._model._name, exc_info=True)
|
||||
content = None
|
||||
|
||||
g_att += ''.join(
|
||||
' %s="%s"' % (name, werkzeug.utils.escape(value))
|
||||
for name, value in self.attributes(
|
||||
cr, uid, field_name, record, options,
|
||||
source_element, g_att, t_att, qweb_context)
|
||||
)
|
||||
|
||||
return self.render_element(cr, uid, source_element, t_att, g_att,
|
||||
qweb_context, content)
|
||||
|
||||
def qweb_object(self):
|
||||
return self.pool['ir.qweb']
|
||||
|
||||
def render_element(self, cr, uid, source_element, t_att, g_att,
|
||||
qweb_context, content):
|
||||
""" Final rendering hook, by default just calls ir.qweb's ``render_element``
|
||||
"""
|
||||
return self.qweb_object().render_element(
|
||||
source_element, t_att, g_att, qweb_context, content or '')
|
||||
|
||||
def user_lang(self, cr, uid, context):
|
||||
"""
|
||||
Fetches the res.lang object corresponding to the language code stored
|
||||
in the user's context. Fallbacks to en_US if no lang is present in the
|
||||
context *or the language code is not valid*.
|
||||
|
||||
:returns: res.lang browse_record
|
||||
"""
|
||||
if context is None: context = {}
|
||||
|
||||
lang_code = context.get('lang') or 'en_US'
|
||||
Lang = self.pool['res.lang']
|
||||
|
||||
lang_ids = Lang.search(cr, uid, [('code', '=', lang_code)], context=context) \
|
||||
or Lang.search(cr, uid, [('code', '=', 'en_US')], context=context)
|
||||
|
||||
return Lang.browse(cr, uid, lang_ids[0], context=context)
|
||||
|
||||
class FloatConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.float'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def precision(self, cr, uid, column, options=None, context=None):
|
||||
_, precision = column.digits or (None, None)
|
||||
return precision
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
precision = self.precision(cr, uid, column, options=options, context=context)
|
||||
fmt = '%f' if precision is None else '%.{precision}f'
|
||||
|
||||
lang_code = context.get('lang') or 'en_US'
|
||||
lang = self.pool['res.lang']
|
||||
formatted = lang.format(cr, uid, [lang_code], fmt.format(precision=precision), value, grouping=True)
|
||||
|
||||
# %f does not strip trailing zeroes. %g does but its precision causes
|
||||
# it to switch to scientific notation starting at a million *and* to
|
||||
# strip decimals. So use %f and if no precision was specified manually
|
||||
# strip trailing 0.
|
||||
if not precision:
|
||||
formatted = re.sub(r'(?:(0|\d+?)0+)$', r'\1', formatted)
|
||||
return formatted
|
||||
|
||||
class DateConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.date'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
if not value: return ''
|
||||
lang = self.user_lang(cr, uid, context=context)
|
||||
locale = babel.Locale.parse(lang.code)
|
||||
|
||||
if isinstance(value, basestring):
|
||||
value = datetime.datetime.strptime(
|
||||
value, openerp.tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
if options and 'format' in options:
|
||||
pattern = options['format']
|
||||
else:
|
||||
strftime_pattern = lang.date_format
|
||||
pattern = openerp.tools.posix_to_ldml(strftime_pattern, locale=locale)
|
||||
|
||||
return babel.dates.format_datetime(
|
||||
value, format=pattern,
|
||||
locale=locale)
|
||||
|
||||
class DateTimeConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.datetime'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
if not value: return ''
|
||||
lang = self.user_lang(cr, uid, context=context)
|
||||
locale = babel.Locale.parse(lang.code)
|
||||
|
||||
if isinstance(value, basestring):
|
||||
value = datetime.datetime.strptime(
|
||||
value, openerp.tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
value = column.context_timestamp(
|
||||
cr, uid, timestamp=value, context=context)
|
||||
|
||||
if options and 'format' in options:
|
||||
pattern = options['format']
|
||||
else:
|
||||
strftime_pattern = (u"%s %s" % (lang.date_format, lang.time_format))
|
||||
pattern = openerp.tools.posix_to_ldml(strftime_pattern, locale=locale)
|
||||
|
||||
return babel.dates.format_datetime(value, format=pattern, locale=locale)
|
||||
|
||||
class TextConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.text'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
"""
|
||||
Escapes the value and converts newlines to br. This is bullshit.
|
||||
"""
|
||||
if not value: return ''
|
||||
|
||||
return nl2br(value, options=options)
|
||||
|
||||
class SelectionConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.selection'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None):
|
||||
value = record[field_name]
|
||||
if not value: return ''
|
||||
selection = dict(fields.selection.reify(
|
||||
cr, uid, record._model, column))
|
||||
return self.value_to_html(
|
||||
cr, uid, selection[value], column, options=options)
|
||||
|
||||
class ManyToOneConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.many2one'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None):
|
||||
[read] = record.read([field_name])
|
||||
if not read[field_name]: return ''
|
||||
_, value = read[field_name]
|
||||
return nl2br(value, options=options)
|
||||
|
||||
class HTMLConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.html'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
return HTMLSafe(value or '')
|
||||
|
||||
class ImageConverter(osv.AbstractModel):
|
||||
""" ``image`` widget rendering, inserts a data:uri-using image tag in the
|
||||
document. May be overridden by e.g. the website module to generate links
|
||||
instead.
|
||||
|
||||
.. todo:: what happens if different output need different converters? e.g.
|
||||
reports may need embedded images or FS links whereas website
|
||||
needs website-aware
|
||||
"""
|
||||
_name = 'ir.qweb.field.image'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
try:
|
||||
image = Image.open(cStringIO.StringIO(value.decode('base64')))
|
||||
image.verify()
|
||||
except IOError:
|
||||
raise ValueError("Non-image binary fields can not be converted to HTML")
|
||||
except: # image.verify() throws "suitable exceptions", I have no idea what they are
|
||||
raise ValueError("Invalid image content")
|
||||
|
||||
return HTMLSafe('<img src="data:%s;base64,%s">' % (Image.MIME[image.format], value))
|
||||
|
||||
class MonetaryConverter(osv.AbstractModel):
|
||||
""" ``monetary`` converter, has a mandatory option
|
||||
``display_currency``.
|
||||
|
||||
The currency is used for formatting *and rounding* of the float value. It
|
||||
is assumed that the linked res_currency has a non-empty rounding value and
|
||||
res.currency's ``round`` method is used to perform rounding.
|
||||
|
||||
.. note:: the monetary converter internally adds the qweb context to its
|
||||
options mapping, so that the context is available to callees.
|
||||
It's set under the ``_qweb_context`` key.
|
||||
"""
|
||||
_name = 'ir.qweb.field.monetary'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def to_html(self, cr, uid, field_name, record, options,
|
||||
source_element, t_att, g_att, qweb_context, context=None):
|
||||
options['_qweb_context'] = qweb_context
|
||||
return super(MonetaryConverter, self).to_html(
|
||||
cr, uid, field_name, record, options,
|
||||
source_element, t_att, g_att, qweb_context, context=context)
|
||||
|
||||
def record_to_html(self, cr, uid, field_name, record, column, options, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
Currency = self.pool['res.currency']
|
||||
display = self.display_currency(cr, uid, options)
|
||||
|
||||
# lang.format mandates a sprintf-style format. These formats are non-
|
||||
# minimal (they have a default fixed precision instead), and
|
||||
# lang.format will not set one by default. currency.round will not
|
||||
# provide one either. So we need to generate a precision value
|
||||
# (integer > 0) from the currency's rounding (a float generally < 1.0).
|
||||
#
|
||||
# The log10 of the rounding should be the number of digits involved if
|
||||
# negative, if positive clamp to 0 digits and call it a day.
|
||||
# nb: int() ~ floor(), we want nearest rounding instead
|
||||
precision = int(round(math.log10(display.rounding)))
|
||||
fmt = "%.{0}f".format(-precision if precision < 0 else 0)
|
||||
|
||||
lang_code = context.get('lang') or 'en_US'
|
||||
lang = self.pool['res.lang']
|
||||
formatted_amount = lang.format(cr, uid, [lang_code],
|
||||
fmt, Currency.round(cr, uid, display, record[field_name]),
|
||||
grouping=True, monetary=True)
|
||||
|
||||
pre = post = u''
|
||||
if display.position == 'before':
|
||||
pre = u'{symbol} '
|
||||
else:
|
||||
post = u' {symbol}'
|
||||
|
||||
return HTMLSafe(u'{pre}<span class="oe_currency_value">{0}</span>{post}'.format(
|
||||
formatted_amount,
|
||||
pre=pre, post=post,
|
||||
).format(
|
||||
symbol=display.symbol,
|
||||
))
|
||||
|
||||
def display_currency(self, cr, uid, options):
|
||||
return self.qweb_object().eval_object(
|
||||
options['display_currency'], options['_qweb_context'])
|
||||
|
||||
TIMEDELTA_UNITS = (
|
||||
('year', 3600 * 24 * 365),
|
||||
('month', 3600 * 24 * 30),
|
||||
('week', 3600 * 24 * 7),
|
||||
('day', 3600 * 24),
|
||||
('hour', 3600),
|
||||
('minute', 60),
|
||||
('second', 1)
|
||||
)
|
||||
class DurationConverter(osv.AbstractModel):
|
||||
""" ``duration`` converter, to display integral or fractional values as
|
||||
human-readable time spans (e.g. 1.5 as "1 hour 30 minutes").
|
||||
|
||||
Can be used on any numerical field.
|
||||
|
||||
Has a mandatory option ``unit`` which can be one of ``second``, ``minute``,
|
||||
``hour``, ``day``, ``week`` or ``year``, used to interpret the numerical
|
||||
field value before converting it.
|
||||
|
||||
Sub-second values will be ignored.
|
||||
"""
|
||||
_name = 'ir.qweb.field.duration'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
units = dict(TIMEDELTA_UNITS)
|
||||
if value < 0:
|
||||
raise ValueError(_("Durations can't be negative"))
|
||||
if not options or options.get('unit') not in units:
|
||||
raise ValueError(_("A unit must be provided to duration widgets"))
|
||||
|
||||
locale = babel.Locale.parse(
|
||||
self.user_lang(cr, uid, context=context).code)
|
||||
factor = units[options['unit']]
|
||||
|
||||
sections = []
|
||||
r = value * factor
|
||||
for unit, secs_per_unit in TIMEDELTA_UNITS:
|
||||
v, r = divmod(r, secs_per_unit)
|
||||
if not v: continue
|
||||
section = babel.dates.format_timedelta(
|
||||
v*secs_per_unit, threshold=1, locale=locale)
|
||||
if section:
|
||||
sections.append(section)
|
||||
return u' '.join(sections)
|
||||
|
||||
class RelativeDatetimeConverter(osv.AbstractModel):
|
||||
_name = 'ir.qweb.field.relative'
|
||||
_inherit = 'ir.qweb.field'
|
||||
|
||||
def value_to_html(self, cr, uid, value, column, options=None, context=None):
|
||||
parse_format = openerp.tools.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
locale = babel.Locale.parse(
|
||||
self.user_lang(cr, uid, context=context).code)
|
||||
|
||||
if isinstance(value, basestring):
|
||||
value = datetime.datetime.strptime(value, parse_format)
|
||||
|
||||
# value should be a naive datetime in UTC. So is fields.datetime.now()
|
||||
reference = datetime.datetime.strptime(column.now(), parse_format)
|
||||
|
||||
return babel.dates.format_timedelta(
|
||||
value - reference, add_direction=True, locale=locale)
|
||||
|
||||
class HTMLSafe(object):
|
||||
""" HTMLSafe string wrapper, Werkzeug's escape() has special handling for
|
||||
objects with a ``__html__`` methods but AFAIK does not provide any such
|
||||
object.
|
||||
|
||||
Wrapping a string in HTML will prevent its escaping
|
||||
"""
|
||||
__slots__ = ['string']
|
||||
def __init__(self, string):
|
||||
self.string = string
|
||||
def __html__(self):
|
||||
return self.string
|
||||
def __str__(self):
|
||||
s = self.string
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf-8')
|
||||
return s
|
||||
def __unicode__(self):
|
||||
s = self.string
|
||||
if isinstance(s, str):
|
||||
return s.decode('utf-8')
|
||||
return s
|
||||
|
||||
def nl2br(string, options=None):
|
||||
""" Converts newlines to HTML linebreaks in ``string``. Automatically
|
||||
escapes content unless options['html-escape'] is set to False, and returns
|
||||
the result wrapped in an HTMLSafe object.
|
||||
|
||||
:param str string:
|
||||
:param dict options:
|
||||
:rtype: HTMLSafe
|
||||
"""
|
||||
if options is None: options = {}
|
||||
|
||||
if options.get('html-escape', True):
|
||||
string = werkzeug.utils.escape(string)
|
||||
return HTMLSafe(string.replace('\n', '<br>\n'))
|
||||
|
||||
def get_field_type(column, options):
|
||||
""" Gets a t-field's effective type from the field's column and its options
|
||||
"""
|
||||
return options.get('widget', column._type)
|
||||
|
||||
# vim:et:
|
|
@ -268,13 +268,8 @@ class ir_translation(osv.osv):
|
|||
return translations
|
||||
|
||||
def _set_ids(self, cr, uid, name, tt, lang, ids, value, src=None):
|
||||
# clear the caches
|
||||
tr = self._get_ids(cr, uid, name, tt, lang, ids)
|
||||
for res_id in tr:
|
||||
if tr[res_id]:
|
||||
self._get_source.clear_cache(self, uid, name, tt, lang, tr[res_id])
|
||||
self._get_ids.clear_cache(self, uid, name, tt, lang, res_id)
|
||||
self._get_source.clear_cache(self, uid, name, tt, lang)
|
||||
self._get_ids.clear_cache(self)
|
||||
self._get_source.clear_cache(self)
|
||||
|
||||
cr.execute('delete from ir_translation '
|
||||
'where lang=%s '
|
||||
|
@ -294,7 +289,7 @@ class ir_translation(osv.osv):
|
|||
return len(ids)
|
||||
|
||||
@tools.ormcache(skiparg=3)
|
||||
def _get_source(self, cr, uid, name, types, lang, source=None):
|
||||
def _get_source(self, cr, uid, name, types, lang, source=None, res_id=None):
|
||||
"""
|
||||
Returns the translation for the given combination of name, type, language
|
||||
and source. All values passed to this method should be unicode (not byte strings),
|
||||
|
@ -304,6 +299,7 @@ class ir_translation(osv.osv):
|
|||
:param types: single string defining type of term to translate (see ``type`` field on ir.translation), or sequence of allowed types (strings)
|
||||
:param lang: language code of the desired translation
|
||||
:param source: optional source term to translate (should be unicode)
|
||||
:param res_id: optional resource id to translate (if used, ``source`` should be set)
|
||||
:rtype: unicode
|
||||
:return: the request translation, or an empty unicode string if no translation was
|
||||
found and `source` was not passed
|
||||
|
@ -321,6 +317,9 @@ class ir_translation(osv.osv):
|
|||
AND type in %s
|
||||
AND src=%s"""
|
||||
params = (lang or '', types, tools.ustr(source))
|
||||
if res_id:
|
||||
query += "AND res_id=%s"
|
||||
params += (res_id,)
|
||||
if name:
|
||||
query += " AND name=%s"
|
||||
params += (tools.ustr(name),)
|
||||
|
@ -342,8 +341,9 @@ class ir_translation(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
ids = super(ir_translation, self).create(cr, uid, vals, context=context)
|
||||
self._get_source.clear_cache(self, uid, vals.get('name',0), vals.get('type',0), vals.get('lang',0), vals.get('src',0))
|
||||
self._get_ids.clear_cache(self, uid, vals.get('name',0), vals.get('type',0), vals.get('lang',0), vals.get('res_id',0))
|
||||
self._get_source.clear_cache(self)
|
||||
self._get_ids.clear_cache(self)
|
||||
self.pool['ir.ui.view'].clear_cache()
|
||||
return ids
|
||||
|
||||
def write(self, cursor, user, ids, vals, context=None):
|
||||
|
@ -356,9 +356,9 @@ class ir_translation(osv.osv):
|
|||
if vals.get('value'):
|
||||
vals.update({'state':'translated'})
|
||||
result = super(ir_translation, self).write(cursor, user, ids, vals, context=context)
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
|
||||
self._get_source.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['src'])
|
||||
self._get_ids.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['res_id'])
|
||||
self._get_source.clear_cache(self)
|
||||
self._get_ids.clear_cache(self)
|
||||
self.pool['ir.ui.view'].clear_cache()
|
||||
return result
|
||||
|
||||
def unlink(self, cursor, user, ids, context=None):
|
||||
|
@ -366,9 +366,9 @@ class ir_translation(osv.osv):
|
|||
context = {}
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
|
||||
self._get_source.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['src'])
|
||||
self._get_ids.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['res_id'])
|
||||
|
||||
self._get_source.clear_cache(self)
|
||||
self._get_ids.clear_cache(self)
|
||||
result = super(ir_translation, self).unlink(cursor, user, ids, context=context)
|
||||
return result
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
domain="[('comments', 'like', 'openerp-web')]"/>
|
||||
<field name="name" operator="="/>
|
||||
<field name="lang"/>
|
||||
<field name="source"/>
|
||||
<field name="src"/>
|
||||
<field name="value"/>
|
||||
</search>
|
||||
</field>
|
||||
|
|
|
@ -18,20 +18,43 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import collections
|
||||
import copy
|
||||
import fnmatch
|
||||
import logging
|
||||
from lxml import etree
|
||||
from operator import itemgetter
|
||||
import os
|
||||
import simplejson
|
||||
import werkzeug
|
||||
|
||||
import HTMLParser
|
||||
|
||||
import openerp
|
||||
from openerp import tools
|
||||
from openerp.osv import fields,osv
|
||||
from openerp.tools import graph
|
||||
from openerp.http import request
|
||||
from openerp.osv import fields, osv, orm
|
||||
from openerp.tools import graph, SKIPPED_ELEMENT_TYPES
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from openerp.tools.view_validation import valid_view
|
||||
from openerp.tools import misc
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
MOVABLE_BRANDING = ['data-oe-model', 'data-oe-id', 'data-oe-field', 'data-oe-xpath']
|
||||
|
||||
def keep_query(*args, **kw):
|
||||
if not args and not kw:
|
||||
args = ('*',)
|
||||
params = kw.copy()
|
||||
query_params = frozenset(werkzeug.url_decode(request.httprequest.query_string).keys())
|
||||
for keep_param in args:
|
||||
for param in fnmatch.filter(query_params, keep_param):
|
||||
if param not in params and param in request.params:
|
||||
params[param] = request.params[param]
|
||||
return werkzeug.urls.url_encode(params)
|
||||
|
||||
class view_custom(osv.osv):
|
||||
_name = 'ir.ui.view.custom'
|
||||
_order = 'create_date desc' # search(limit=1) should return the last customization
|
||||
|
@ -50,59 +73,45 @@ class view_custom(osv.osv):
|
|||
class view(osv.osv):
|
||||
_name = 'ir.ui.view'
|
||||
|
||||
def _type_field(self, cr, uid, ids, name, args, context=None):
|
||||
result = {}
|
||||
for record in self.browse(cr, uid, ids, context):
|
||||
# Get the type from the inherited view if any.
|
||||
if record.inherit_id:
|
||||
result[record.id] = record.inherit_id.type
|
||||
else:
|
||||
result[record.id] = etree.fromstring(record.arch.encode('utf8')).tag
|
||||
def _get_model_data(self, cr, uid, ids, *args, **kwargs):
|
||||
ir_model_data = self.pool.get('ir.model.data')
|
||||
data_ids = ir_model_data.search(cr, uid, [('model', '=', self._name), ('res_id', 'in', ids)])
|
||||
result = dict(zip(ids, data_ids))
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('View Name', required=True),
|
||||
'model': fields.char('Object', size=64, required=True, select=True),
|
||||
'model': fields.char('Object', select=True),
|
||||
'priority': fields.integer('Sequence', required=True),
|
||||
'type': fields.function(_type_field, type='selection', selection=[
|
||||
'type': fields.selection([
|
||||
('tree','Tree'),
|
||||
('form','Form'),
|
||||
('mdx','mdx'),
|
||||
('graph', 'Graph'),
|
||||
('calendar', 'Calendar'),
|
||||
('diagram','Diagram'),
|
||||
('gantt', 'Gantt'),
|
||||
('kanban', 'Kanban'),
|
||||
('search','Search')], string='View Type', required=True, select=True, store=True),
|
||||
('search','Search'),
|
||||
('qweb', 'QWeb')], string='View Type'),
|
||||
'arch': fields.text('View Architecture', required=True),
|
||||
'inherit_id': fields.many2one('ir.ui.view', 'Inherited View', ondelete='cascade', select=True),
|
||||
'field_parent': fields.char('Child Field',size=64),
|
||||
'inherit_children_ids': fields.one2many('ir.ui.view','inherit_id', 'Inherit Views'),
|
||||
'field_parent': fields.char('Child Field'),
|
||||
'model_data_id': fields.function(_get_model_data, type='many2one', relation='ir.model.data', string="Model Data", store=True),
|
||||
'xml_id': fields.function(osv.osv.get_xml_id, type='char', size=128, string="External ID",
|
||||
help="ID of the view defined in xml file"),
|
||||
'groups_id': fields.many2many('res.groups', 'ir_ui_view_group_rel', 'view_id', 'group_id',
|
||||
string='Groups', help="If this field is empty, the view applies to all users. Otherwise, the view applies to the users of those groups only."),
|
||||
'model_ids': fields.one2many('ir.model.data', 'res_id', domain=[('model','=','ir.ui.view')], auto_join=True),
|
||||
}
|
||||
_defaults = {
|
||||
'arch': '<?xml version="1.0"?>\n<tree string="My view">\n\t<field name="name"/>\n</tree>',
|
||||
'priority': 16,
|
||||
'type': 'tree',
|
||||
}
|
||||
_order = "priority,name"
|
||||
|
||||
# Holds the RNG schema
|
||||
_relaxng_validator = None
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if 'type' in values:
|
||||
_logger.warning("Setting the `type` field is deprecated in the `ir.ui.view` model.")
|
||||
if not values.get('name'):
|
||||
if values.get('inherit_id'):
|
||||
inferred_type = self.browse(cr, uid, values['inherit_id'], context).type
|
||||
else:
|
||||
inferred_type = etree.fromstring(values['arch'].encode('utf8')).tag
|
||||
values['name'] = "%s %s" % (values['model'], inferred_type)
|
||||
return super(view, self).create(cr, uid, values, context)
|
||||
|
||||
def _relaxng(self):
|
||||
if not self._relaxng_validator:
|
||||
frng = tools.file_open(os.path.join('base','rng','view.rng'))
|
||||
|
@ -115,59 +124,37 @@ class view(osv.osv):
|
|||
frng.close()
|
||||
return self._relaxng_validator
|
||||
|
||||
def _check_render_view(self, cr, uid, view, context=None):
|
||||
"""Verify that the given view's hierarchy is valid for rendering, along with all the changes applied by
|
||||
its inherited views, by rendering it using ``fields_view_get()``.
|
||||
|
||||
@param browse_record view: view to validate
|
||||
@return: the rendered definition (arch) of the view, always utf-8 bytestring (legacy convention)
|
||||
if no error occurred, else False.
|
||||
"""
|
||||
if view.model not in self.pool:
|
||||
return False
|
||||
try:
|
||||
fvg = self.pool[view.model].fields_view_get(cr, uid, view_id=view.id, view_type=view.type, context=context)
|
||||
return fvg['arch']
|
||||
except Exception:
|
||||
_logger.exception('cannot render view %s', view.xml_id)
|
||||
return False
|
||||
|
||||
def _check_xml(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
context['check_view_ids'] = ids
|
||||
context = dict(context, check_view_ids=ids)
|
||||
|
||||
# Sanity checks: the view should not break anything upon rendering!
|
||||
# Any exception raised below will cause a transaction rollback.
|
||||
for view in self.browse(cr, uid, ids, context):
|
||||
# Sanity check: the view should not break anything upon rendering!
|
||||
view_arch_utf8 = self._check_render_view(cr, uid, view, context=context)
|
||||
# always utf-8 bytestring - legacy convention
|
||||
if not view_arch_utf8: return False
|
||||
|
||||
# RNG-based validation is not possible anymore with 7.0 forms
|
||||
# TODO 7.0: provide alternative assertion-based validation of view_arch_utf8
|
||||
view_docs = [etree.fromstring(view_arch_utf8)]
|
||||
if view_docs[0].tag == 'data':
|
||||
# A <data> element is a wrapper for multiple root nodes
|
||||
view_docs = view_docs[0]
|
||||
validator = self._relaxng()
|
||||
for view_arch in view_docs:
|
||||
if (view_arch.get('version') < '7.0') and validator and not validator.validate(view_arch):
|
||||
for error in validator.error_log:
|
||||
_logger.error(tools.ustr(error))
|
||||
return False
|
||||
if not valid_view(view_arch):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _check_model(self, cr, uid, ids, context=None):
|
||||
for view in self.browse(cr, uid, ids, context):
|
||||
if view.model not in self.pool:
|
||||
return False
|
||||
view_def = self.read_combined(cr, uid, view.id, None, context=context)
|
||||
view_arch_utf8 = view_def['arch']
|
||||
if view.type != 'qweb':
|
||||
view_doc = etree.fromstring(view_arch_utf8)
|
||||
# verify that all fields used are valid, etc.
|
||||
self.postprocess_and_fields(cr, uid, view.model, view_doc, view.id, context=context)
|
||||
# RNG-based validation is not possible anymore with 7.0 forms
|
||||
view_docs = [view_doc]
|
||||
if view_docs[0].tag == 'data':
|
||||
# A <data> element is a wrapper for multiple root nodes
|
||||
view_docs = view_docs[0]
|
||||
validator = self._relaxng()
|
||||
for view_arch in view_docs:
|
||||
if (view_arch.get('version') < '7.0') and validator and not validator.validate(view_arch):
|
||||
for error in validator.error_log:
|
||||
_logger.error(tools.ustr(error))
|
||||
return False
|
||||
if not valid_view(view_arch):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_model, 'The model name does not exist.', ['model']),
|
||||
(_check_xml, 'The model name does not exist or the view architecture cannot be rendered.', ['arch', 'model']),
|
||||
(_check_xml, 'Invalid view definition', ['arch'])
|
||||
]
|
||||
|
||||
def _auto_init(self, cr, context=None):
|
||||
|
@ -176,6 +163,73 @@ class view(osv.osv):
|
|||
if not cr.fetchone():
|
||||
cr.execute('CREATE INDEX ir_ui_view_model_type_inherit_id ON ir_ui_view (model, inherit_id)')
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if 'type' not in values:
|
||||
if values.get('inherit_id'):
|
||||
values['type'] = self.browse(cr, uid, values['inherit_id'], context).type
|
||||
else:
|
||||
values['type'] = etree.fromstring(values['arch']).tag
|
||||
|
||||
if not values.get('name'):
|
||||
values['name'] = "%s %s" % (values['model'], values['type'])
|
||||
|
||||
self.read_template.clear_cache(self)
|
||||
return super(view, self).create(cr, uid, values, context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if not isinstance(ids, (list, tuple)):
|
||||
ids = [ids]
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
# drop the corresponding view customizations (used for dashboards for example), otherwise
|
||||
# not all users would see the updated views
|
||||
custom_view_ids = self.pool.get('ir.ui.view.custom').search(cr, uid, [('ref_id', 'in', ids)])
|
||||
if custom_view_ids:
|
||||
self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids)
|
||||
|
||||
self.read_template.clear_cache(self)
|
||||
ret = super(view, self).write(cr, uid, ids, vals, context)
|
||||
|
||||
# if arch is modified views become noupdatable
|
||||
if 'arch' in vals and not context.get('install_mode', False):
|
||||
# TODO: should be doable in a read and a write
|
||||
for view_ in self.browse(cr, uid, ids, context=context):
|
||||
if view_.model_data_id:
|
||||
self.pool.get('ir.model.data').write(cr, openerp.SUPERUSER_ID, view_.model_data_id.id, {'noupdate': True})
|
||||
return ret
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if not default:
|
||||
default = {}
|
||||
default.update({
|
||||
'model_ids': [],
|
||||
})
|
||||
return super(view, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
# default view selection
|
||||
def default_view(self, cr, uid, model, view_type, context=None):
|
||||
""" Fetches the default view for the provided (model, view_type) pair:
|
||||
view with no parent (inherit_id=Fase) with the lowest priority.
|
||||
|
||||
:param str model:
|
||||
:param int view_type:
|
||||
:return: id of the default view of False if none found
|
||||
:rtype: int
|
||||
"""
|
||||
domain = [
|
||||
['model', '=', model],
|
||||
['type', '=', view_type],
|
||||
['inherit_id', '=', False],
|
||||
]
|
||||
ids = self.search(cr, uid, domain, limit=1, order='priority', context=context)
|
||||
if not ids:
|
||||
return False
|
||||
return ids[0]
|
||||
|
||||
#------------------------------------------------------
|
||||
# Inheritance mecanism
|
||||
#------------------------------------------------------
|
||||
def get_inheriting_views_arch(self, cr, uid, view_id, model, context=None):
|
||||
"""Retrieves the architecture of views that inherit from the given view, from the sets of
|
||||
views that should currently be used in the system. During the module upgrade phase it
|
||||
|
@ -185,43 +239,605 @@ class view(osv.osv):
|
|||
after the module initialization phase is completely finished.
|
||||
|
||||
:param int view_id: id of the view whose inheriting views should be retrieved
|
||||
:param str model: model identifier of the view's related model (for double-checking)
|
||||
:param str model: model identifier of the inheriting views.
|
||||
:rtype: list of tuples
|
||||
:return: [(view_arch,view_id), ...]
|
||||
"""
|
||||
|
||||
user_groups = frozenset(self.pool.get('res.users').browse(cr, 1, uid, context).groups_id)
|
||||
|
||||
check_view_ids = context and context.get('check_view_ids') or (0,)
|
||||
conditions = [['inherit_id', '=', view_id], ['model', '=', model]]
|
||||
if self.pool._init:
|
||||
# Module init currently in progress, only consider views from modules whose code was already loaded
|
||||
check_view_ids = context and context.get('check_view_ids') or (0,)
|
||||
query = """SELECT v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id)
|
||||
WHERE v.inherit_id=%s AND v.model=%s AND (md.module in %s OR v.id in %s)
|
||||
ORDER BY priority"""
|
||||
query_params = (view_id, model, tuple(self.pool._init_modules), tuple(check_view_ids))
|
||||
else:
|
||||
# Modules fully loaded, consider all views
|
||||
query = """SELECT v.id FROM ir_ui_view v
|
||||
WHERE v.inherit_id=%s AND v.model=%s
|
||||
ORDER BY priority"""
|
||||
query_params = (view_id, model)
|
||||
cr.execute(query, query_params)
|
||||
view_ids = [v[0] for v in cr.fetchall()]
|
||||
# filter views based on user groups
|
||||
# Module init currently in progress, only consider views from
|
||||
# modules whose code is already loaded
|
||||
conditions.extend([
|
||||
'|',
|
||||
['model_ids.module', 'in', tuple(self.pool._init_modules)],
|
||||
['id', 'in', check_view_ids],
|
||||
])
|
||||
view_ids = self.search(cr, uid, conditions, context=context)
|
||||
|
||||
return [(view.arch, view.id)
|
||||
for view in self.browse(cr, 1, view_ids, context)
|
||||
if not (view.groups_id and user_groups.isdisjoint(view.groups_id))]
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if not isinstance(ids, (list, tuple)):
|
||||
ids = [ids]
|
||||
def raise_view_error(self, cr, uid, message, view_id, context=None):
|
||||
view = self.browse(cr, uid, view_id, context)
|
||||
not_avail = _('n/a')
|
||||
message = ("%(msg)s\n\n" +
|
||||
_("Error context:\nView `%(view_name)s`") +
|
||||
"\n[view_id: %(viewid)s, xml_id: %(xmlid)s, "
|
||||
"model: %(model)s, parent_id: %(parent)s]") % \
|
||||
{
|
||||
'view_name': view.name or not_avail,
|
||||
'viewid': view_id or not_avail,
|
||||
'xmlid': view.xml_id or not_avail,
|
||||
'model': view.model or not_avail,
|
||||
'parent': view.inherit_id.id or not_avail,
|
||||
'msg': message,
|
||||
}
|
||||
_logger.error(message)
|
||||
raise AttributeError(message)
|
||||
|
||||
# drop the corresponding view customizations (used for dashboards for example), otherwise
|
||||
# not all users would see the updated views
|
||||
custom_view_ids = self.pool.get('ir.ui.view.custom').search(cr, uid, [('ref_id','in',ids)])
|
||||
if custom_view_ids:
|
||||
self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids)
|
||||
def locate_node(self, arch, spec):
|
||||
""" Locate a node in a source (parent) architecture.
|
||||
|
||||
return super(view, self).write(cr, uid, ids, vals, context)
|
||||
Given a complete source (parent) architecture (i.e. the field
|
||||
`arch` in a view), and a 'spec' node (a node in an inheriting
|
||||
view that specifies the location in the source view of what
|
||||
should be changed), return (if it exists) the node in the
|
||||
source view matching the specification.
|
||||
|
||||
:param arch: a parent architecture to modify
|
||||
:param spec: a modifying node in an inheriting view
|
||||
:return: a node in the source matching the spec
|
||||
"""
|
||||
if spec.tag == 'xpath':
|
||||
nodes = arch.xpath(spec.get('expr'))
|
||||
return nodes[0] if nodes else None
|
||||
elif spec.tag == 'field':
|
||||
# Only compare the field name: a field can be only once in a given view
|
||||
# at a given level (and for multilevel expressions, we should use xpath
|
||||
# inheritance spec anyway).
|
||||
for node in arch.iter('field'):
|
||||
if node.get('name') == spec.get('name'):
|
||||
return node
|
||||
return None
|
||||
|
||||
for node in arch.iter(spec.tag):
|
||||
if isinstance(node, SKIPPED_ELEMENT_TYPES):
|
||||
continue
|
||||
if all(node.get(attr) == spec.get(attr) for attr in spec.attrib
|
||||
if attr not in ('position','version')):
|
||||
# Version spec should match parent's root element's version
|
||||
if spec.get('version') and spec.get('version') != arch.get('version'):
|
||||
return None
|
||||
return node
|
||||
return None
|
||||
|
||||
def inherit_branding(self, specs_tree, view_id, source_id):
|
||||
for node in specs_tree.iterchildren(tag=etree.Element):
|
||||
xpath = node.getroottree().getpath(node)
|
||||
if node.tag == 'data' or node.tag == 'xpath':
|
||||
self.inherit_branding(node, view_id, source_id)
|
||||
else:
|
||||
node.set('data-oe-id', str(view_id))
|
||||
node.set('data-oe-source-id', str(source_id))
|
||||
node.set('data-oe-xpath', xpath)
|
||||
node.set('data-oe-model', 'ir.ui.view')
|
||||
node.set('data-oe-field', 'arch')
|
||||
|
||||
return specs_tree
|
||||
|
||||
def apply_inheritance_specs(self, cr, uid, source, specs_tree, inherit_id, context=None):
|
||||
""" Apply an inheriting view (a descendant of the base view)
|
||||
|
||||
Apply to a source architecture all the spec nodes (i.e. nodes
|
||||
describing where and what changes to apply to some parent
|
||||
architecture) given by an inheriting view.
|
||||
|
||||
:param Element source: a parent architecture to modify
|
||||
:param Elepect specs_tree: a modifying architecture in an inheriting view
|
||||
:param inherit_id: the database id of specs_arch
|
||||
:return: a modified source where the specs are applied
|
||||
:rtype: Element
|
||||
"""
|
||||
# Queue of specification nodes (i.e. nodes describing where and
|
||||
# changes to apply to some parent architecture).
|
||||
specs = [specs_tree]
|
||||
|
||||
while len(specs):
|
||||
spec = specs.pop(0)
|
||||
if isinstance(spec, SKIPPED_ELEMENT_TYPES):
|
||||
continue
|
||||
if spec.tag == 'data':
|
||||
specs += [c for c in spec]
|
||||
continue
|
||||
node = self.locate_node(source, spec)
|
||||
if node is not None:
|
||||
pos = spec.get('position', 'inside')
|
||||
if pos == 'replace':
|
||||
if node.getparent() is None:
|
||||
source = copy.deepcopy(spec[0])
|
||||
else:
|
||||
for child in spec:
|
||||
node.addprevious(child)
|
||||
node.getparent().remove(node)
|
||||
elif pos == 'attributes':
|
||||
for child in spec.getiterator('attribute'):
|
||||
attribute = (child.get('name'), child.text and child.text.encode('utf8') or None)
|
||||
if attribute[1]:
|
||||
node.set(attribute[0], attribute[1])
|
||||
elif attribute[0] in node.attrib:
|
||||
del node.attrib[attribute[0]]
|
||||
else:
|
||||
sib = node.getnext()
|
||||
for child in spec:
|
||||
if pos == 'inside':
|
||||
node.append(child)
|
||||
elif pos == 'after':
|
||||
if sib is None:
|
||||
node.addnext(child)
|
||||
node = child
|
||||
else:
|
||||
sib.addprevious(child)
|
||||
elif pos == 'before':
|
||||
node.addprevious(child)
|
||||
else:
|
||||
self.raise_view_error(cr, uid, _("Invalid position attribute: '%s'") % pos, inherit_id, context=context)
|
||||
else:
|
||||
attrs = ''.join([
|
||||
' %s="%s"' % (attr, spec.get(attr))
|
||||
for attr in spec.attrib
|
||||
if attr != 'position'
|
||||
])
|
||||
tag = "<%s%s>" % (spec.tag, attrs)
|
||||
self.raise_view_error(cr, uid, _("Element '%s' cannot be located in parent view") % tag, inherit_id, context=context)
|
||||
|
||||
return source
|
||||
|
||||
def apply_view_inheritance(self, cr, uid, source, source_id, model, context=None):
|
||||
""" Apply all the (directly and indirectly) inheriting views.
|
||||
|
||||
:param source: a parent architecture to modify (with parent modifications already applied)
|
||||
:param source_id: the database view_id of the parent view
|
||||
:param model: the original model for which we create a view (not
|
||||
necessarily the same as the source's model); only the inheriting
|
||||
views with that specific model will be applied.
|
||||
:return: a modified source where all the modifying architecture are applied
|
||||
"""
|
||||
if context is None: context = {}
|
||||
sql_inherit = self.pool.get('ir.ui.view').get_inheriting_views_arch(cr, uid, source_id, model, context=context)
|
||||
for (specs, view_id) in sql_inherit:
|
||||
specs_tree = etree.fromstring(specs.encode('utf-8'))
|
||||
if context.get('inherit_branding'):
|
||||
self.inherit_branding(specs_tree, view_id, source_id)
|
||||
source = self.apply_inheritance_specs(cr, uid, source, specs_tree, view_id, context=context)
|
||||
source = self.apply_view_inheritance(cr, uid, source, view_id, model, context=context)
|
||||
return source
|
||||
|
||||
def read_combined(self, cr, uid, view_id, fields=None, context=None):
|
||||
"""
|
||||
Utility function to get a view combined with its inherited views.
|
||||
|
||||
* Gets the top of the view tree if a sub-view is requested
|
||||
* Applies all inherited archs on the root view
|
||||
* Returns the view with all requested fields
|
||||
.. note:: ``arch`` is always added to the fields list even if not
|
||||
requested (similar to ``id``)
|
||||
"""
|
||||
if context is None: context = {}
|
||||
|
||||
# if view_id is not a root view, climb back to the top.
|
||||
base = v = self.browse(cr, uid, view_id, context=context)
|
||||
while v.inherit_id:
|
||||
v = v.inherit_id
|
||||
root_id = v.id
|
||||
|
||||
# arch and model fields are always returned
|
||||
if fields:
|
||||
fields = list(set(fields) | set(['arch', 'model']))
|
||||
|
||||
# read the view arch
|
||||
[view] = self.read(cr, uid, [root_id], fields=fields, context=context)
|
||||
arch_tree = etree.fromstring(view['arch'].encode('utf-8'))
|
||||
|
||||
if context.get('inherit_branding'):
|
||||
arch_tree.attrib.update({
|
||||
'data-oe-model': 'ir.ui.view',
|
||||
'data-oe-id': str(root_id),
|
||||
'data-oe-field': 'arch',
|
||||
})
|
||||
|
||||
# and apply inheritance
|
||||
arch = self.apply_view_inheritance(
|
||||
cr, uid, arch_tree, root_id, base.model, context=context)
|
||||
|
||||
return dict(view, arch=etree.tostring(arch, encoding='utf-8'))
|
||||
|
||||
#------------------------------------------------------
|
||||
# Postprocessing: translation, groups and modifiers
|
||||
#------------------------------------------------------
|
||||
# TODO:
|
||||
# - split postprocess so that it can be used instead of translate_qweb
|
||||
# - remove group processing from ir_qweb
|
||||
#------------------------------------------------------
|
||||
def postprocess(self, cr, user, model, node, view_id, in_tree_view, model_fields, context=None):
|
||||
"""Return the description of the fields in the node.
|
||||
|
||||
In a normal call to this method, node is a complete view architecture
|
||||
but it is actually possible to give some sub-node (this is used so
|
||||
that the method can call itself recursively).
|
||||
|
||||
Originally, the field descriptions are drawn from the node itself.
|
||||
But there is now some code calling fields_get() in order to merge some
|
||||
of those information in the architecture.
|
||||
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
result = False
|
||||
fields = {}
|
||||
children = True
|
||||
|
||||
modifiers = {}
|
||||
Model = self.pool.get(model)
|
||||
if not Model:
|
||||
self.raise_view_error(cr, user, _('Model not found: %(model)s') % dict(model=model),
|
||||
view_id, context)
|
||||
|
||||
def encode(s):
|
||||
if isinstance(s, unicode):
|
||||
return s.encode('utf8')
|
||||
return s
|
||||
|
||||
def check_group(node):
|
||||
"""Apply group restrictions, may be set at view level or model level::
|
||||
* at view level this means the element should be made invisible to
|
||||
people who are not members
|
||||
* at model level (exclusively for fields, obviously), this means
|
||||
the field should be completely removed from the view, as it is
|
||||
completely unavailable for non-members
|
||||
|
||||
:return: True if field should be included in the result of fields_view_get
|
||||
"""
|
||||
if node.tag == 'field' and node.get('name') in Model._all_columns:
|
||||
column = Model._all_columns[node.get('name')].column
|
||||
if column.groups and not self.user_has_groups(
|
||||
cr, user, groups=column.groups, context=context):
|
||||
node.getparent().remove(node)
|
||||
fields.pop(node.get('name'), None)
|
||||
# no point processing view-level ``groups`` anymore, return
|
||||
return False
|
||||
if node.get('groups'):
|
||||
can_see = self.user_has_groups(
|
||||
cr, user, groups=node.get('groups'), context=context)
|
||||
if not can_see:
|
||||
node.set('invisible', '1')
|
||||
modifiers['invisible'] = True
|
||||
if 'attrs' in node.attrib:
|
||||
del(node.attrib['attrs']) #avoid making field visible later
|
||||
del(node.attrib['groups'])
|
||||
return True
|
||||
|
||||
if node.tag in ('field', 'node', 'arrow'):
|
||||
if node.get('object'):
|
||||
attrs = {}
|
||||
views = {}
|
||||
xml = "<form>"
|
||||
for f in node:
|
||||
if f.tag == 'field':
|
||||
xml += etree.tostring(f, encoding="utf-8")
|
||||
xml += "</form>"
|
||||
new_xml = etree.fromstring(encode(xml))
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = model
|
||||
xarch, xfields = self.postprocess_and_fields(cr, user, node.get('object'), new_xml, view_id, ctx)
|
||||
views['form'] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
fields = xfields
|
||||
if node.get('name'):
|
||||
attrs = {}
|
||||
try:
|
||||
if node.get('name') in Model._columns:
|
||||
column = Model._columns[node.get('name')]
|
||||
else:
|
||||
column = Model._inherit_fields[node.get('name')][2]
|
||||
except Exception:
|
||||
column = False
|
||||
|
||||
if column:
|
||||
children = False
|
||||
views = {}
|
||||
for f in node:
|
||||
if f.tag in ('form', 'tree', 'graph', 'kanban', 'calendar'):
|
||||
node.remove(f)
|
||||
ctx = context.copy()
|
||||
ctx['base_model_name'] = model
|
||||
xarch, xfields = self.postprocess_and_fields(cr, user, column._obj or None, f, view_id, ctx)
|
||||
views[str(f.tag)] = {
|
||||
'arch': xarch,
|
||||
'fields': xfields
|
||||
}
|
||||
attrs = {'views': views}
|
||||
fields[node.get('name')] = attrs
|
||||
|
||||
field = model_fields.get(node.get('name'))
|
||||
if field:
|
||||
orm.transfer_field_to_modifiers(field, modifiers)
|
||||
|
||||
elif node.tag in ('form', 'tree'):
|
||||
result = Model.view_header_get(cr, user, False, node.tag, context)
|
||||
if result:
|
||||
node.set('string', result)
|
||||
in_tree_view = node.tag == 'tree'
|
||||
|
||||
elif node.tag == 'calendar':
|
||||
for additional_field in ('date_start', 'date_delay', 'date_stop', 'color', 'all_day', 'attendee'):
|
||||
if node.get(additional_field):
|
||||
fields[node.get(additional_field)] = {}
|
||||
|
||||
if not check_group(node):
|
||||
# node must be removed, no need to proceed further with its children
|
||||
return fields
|
||||
|
||||
# The view architeture overrides the python model.
|
||||
# Get the attrs before they are (possibly) deleted by check_group below
|
||||
orm.transfer_node_to_modifiers(node, modifiers, context, in_tree_view)
|
||||
|
||||
# TODO remove attrs counterpart in modifiers when invisible is true ?
|
||||
|
||||
# translate view
|
||||
if 'lang' in context:
|
||||
Translations = self.pool['ir.translation']
|
||||
if node.text and node.text.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.text.strip())
|
||||
if trans:
|
||||
node.text = node.text.replace(node.text.strip(), trans)
|
||||
if node.tail and node.tail.strip():
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.tail.strip())
|
||||
if trans:
|
||||
node.tail = node.tail.replace(node.tail.strip(), trans)
|
||||
|
||||
if node.get('string') and not result:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], node.get('string'))
|
||||
if trans == node.get('string') and ('base_model_name' in context):
|
||||
# If translation is same as source, perhaps we'd have more luck with the alternative model name
|
||||
# (in case we are in a mixed situation, such as an inherited view where parent_view.model != model
|
||||
trans = Translations._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.get('string'))
|
||||
if trans:
|
||||
node.set('string', trans)
|
||||
|
||||
for attr_name in ('confirm', 'sum', 'avg', 'help', 'placeholder'):
|
||||
attr_value = node.get(attr_name)
|
||||
if attr_value:
|
||||
trans = Translations._get_source(cr, user, model, 'view', context['lang'], attr_value)
|
||||
if trans:
|
||||
node.set(attr_name, trans)
|
||||
|
||||
for f in node:
|
||||
if children or (node.tag == 'field' and f.tag in ('filter','separator')):
|
||||
fields.update(self.postprocess(cr, user, model, f, view_id, in_tree_view, model_fields, context))
|
||||
|
||||
orm.transfer_modifiers_to_node(modifiers, node)
|
||||
return fields
|
||||
|
||||
def _disable_workflow_buttons(self, cr, user, model, node):
|
||||
""" Set the buttons in node to readonly if the user can't activate them. """
|
||||
if model is None or user == 1:
|
||||
# admin user can always activate workflow buttons
|
||||
return node
|
||||
|
||||
# TODO handle the case of more than one workflow for a model or multiple
|
||||
# transitions with different groups and same signal
|
||||
usersobj = self.pool.get('res.users')
|
||||
buttons = (n for n in node.getiterator('button') if n.get('type') != 'object')
|
||||
for button in buttons:
|
||||
user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id']
|
||||
cr.execute("""SELECT DISTINCT t.group_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
AND t.group_id is NOT NULL
|
||||
""", (model, button.get('name')))
|
||||
group_ids = [x[0] for x in cr.fetchall() if x[0]]
|
||||
can_click = not group_ids or bool(set(user_groups).intersection(group_ids))
|
||||
button.set('readonly', str(int(not can_click)))
|
||||
return node
|
||||
|
||||
def postprocess_and_fields(self, cr, user, model, node, view_id, context=None):
|
||||
""" Return an architecture and a description of all the fields.
|
||||
|
||||
The field description combines the result of fields_get() and
|
||||
postprocess().
|
||||
|
||||
:param node: the architecture as as an etree
|
||||
:return: a tuple (arch, fields) where arch is the given node as a
|
||||
string and fields is the description of all the fields.
|
||||
|
||||
"""
|
||||
fields = {}
|
||||
Model = self.pool.get(model)
|
||||
if not Model:
|
||||
self.raise_view_error(cr, user, _('Model not found: %(model)s') % dict(model=model), view_id, context)
|
||||
|
||||
if node.tag == 'diagram':
|
||||
if node.getchildren()[0].tag == 'node':
|
||||
node_model = self.pool[node.getchildren()[0].get('object')]
|
||||
node_fields = node_model.fields_get(cr, user, None, context)
|
||||
fields.update(node_fields)
|
||||
if not node.get("create") and not node_model.check_access_rights(cr, user, 'create', raise_exception=False):
|
||||
node.set("create", 'false')
|
||||
if node.getchildren()[1].tag == 'arrow':
|
||||
arrow_fields = self.pool[node.getchildren()[1].get('object')].fields_get(cr, user, None, context)
|
||||
fields.update(arrow_fields)
|
||||
else:
|
||||
fields = Model.fields_get(cr, user, None, context)
|
||||
|
||||
fields_def = self.postprocess(cr, user, model, node, view_id, False, fields, context=context)
|
||||
node = self._disable_workflow_buttons(cr, user, model, node)
|
||||
if node.tag in ('kanban', 'tree', 'form', 'gantt'):
|
||||
for action, operation in (('create', 'create'), ('delete', 'unlink'), ('edit', 'write')):
|
||||
if not node.get(action) and not Model.check_access_rights(cr, user, operation, raise_exception=False):
|
||||
node.set(action, 'false')
|
||||
arch = etree.tostring(node, encoding="utf-8").replace('\t', '')
|
||||
for k in fields.keys():
|
||||
if k not in fields_def:
|
||||
del fields[k]
|
||||
for field in fields_def:
|
||||
if field == 'id':
|
||||
# sometime, the view may contain the (invisible) field 'id' needed for a domain (when 2 objects have cross references)
|
||||
fields['id'] = {'readonly': True, 'type': 'integer', 'string': 'ID'}
|
||||
elif field in fields:
|
||||
fields[field].update(fields_def[field])
|
||||
else:
|
||||
message = _("Field `%(field_name)s` does not exist") % \
|
||||
dict(field_name=field)
|
||||
self.raise_view_error(cr, user, message, view_id, context)
|
||||
return arch, fields
|
||||
|
||||
#------------------------------------------------------
|
||||
# QWeb template views
|
||||
#------------------------------------------------------
|
||||
@tools.ormcache_context(accepted_keys=('lang','inherit_branding', 'editable', 'translatable'))
|
||||
def read_template(self, cr, uid, xml_id, context=None):
|
||||
if '.' not in xml_id:
|
||||
raise ValueError('Invalid template id: %r' % (xml_id,))
|
||||
|
||||
view_id = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
|
||||
arch = self.read_combined(cr, uid, view_id, fields=['arch'], context=context)['arch']
|
||||
arch_tree = etree.fromstring(arch)
|
||||
|
||||
if 'lang' in context:
|
||||
arch_tree = self.translate_qweb(cr, uid, view_id, arch_tree, context['lang'], context)
|
||||
|
||||
self.distribute_branding(arch_tree)
|
||||
root = etree.Element('templates')
|
||||
root.append(arch_tree)
|
||||
arch = etree.tostring(root, encoding='utf-8', xml_declaration=True)
|
||||
return arch
|
||||
|
||||
def clear_cache(self):
|
||||
self.read_template.clear_cache(self)
|
||||
|
||||
def distribute_branding(self, e, branding=None, parent_xpath='',
|
||||
index_map=misc.ConstantMapping(1)):
|
||||
if e.get('t-ignore') or e.tag == 'head':
|
||||
# TODO: find a better name and check if we have a string to boolean helper
|
||||
return
|
||||
|
||||
node_path = e.get('data-oe-xpath')
|
||||
if node_path is None:
|
||||
node_path = "%s/%s[%d]" % (parent_xpath, e.tag, index_map[e.tag])
|
||||
if branding and not (e.get('data-oe-model') or e.get('t-field')):
|
||||
e.attrib.update(branding)
|
||||
e.set('data-oe-xpath', node_path)
|
||||
if not e.get('data-oe-model'): return
|
||||
|
||||
# if a branded element contains branded elements distribute own
|
||||
# branding to children unless it's t-raw, then just remove branding
|
||||
# on current element
|
||||
if e.tag == 't' or 't-raw' in e.attrib or \
|
||||
any(self.is_node_branded(child) for child in e.iterdescendants()):
|
||||
distributed_branding = dict(
|
||||
(attribute, e.attrib.pop(attribute))
|
||||
for attribute in MOVABLE_BRANDING
|
||||
if e.get(attribute))
|
||||
|
||||
if 't-raw' not in e.attrib:
|
||||
# TODO: collections.Counter if remove p2.6 compat
|
||||
# running index by tag type, for XPath query generation
|
||||
indexes = collections.defaultdict(lambda: 0)
|
||||
for child in e.iterchildren(tag=etree.Element):
|
||||
indexes[child.tag] += 1
|
||||
self.distribute_branding(child, distributed_branding,
|
||||
parent_xpath=node_path,
|
||||
index_map=indexes)
|
||||
|
||||
def is_node_branded(self, node):
|
||||
""" Finds out whether a node is branded or qweb-active (bears a
|
||||
@data-oe-model or a @t-* *which is not t-field* as t-field does not
|
||||
section out views)
|
||||
|
||||
:param node: an etree-compatible element to test
|
||||
:type node: etree._Element
|
||||
:rtype: boolean
|
||||
"""
|
||||
return any(
|
||||
(attr == 'data-oe-model' or (attr != 't-field' and attr.startswith('t-')))
|
||||
for attr in node.attrib
|
||||
)
|
||||
|
||||
def translate_qweb(self, cr, uid, id_, arch, lang, context=None):
|
||||
# TODO: this should be moved in a place before inheritance is applied
|
||||
# but process() is only called on fields_view_get()
|
||||
Translations = self.pool['ir.translation']
|
||||
h = HTMLParser.HTMLParser()
|
||||
def get_trans(text):
|
||||
if not text or not text.strip():
|
||||
return None
|
||||
text = h.unescape(text.strip())
|
||||
if len(text) < 2 or (text.startswith('<!') and text.endswith('>')):
|
||||
return None
|
||||
return Translations._get_source(cr, uid, 'website', 'view', lang, text, id_)
|
||||
|
||||
if arch.tag not in ['script']:
|
||||
text = get_trans(arch.text)
|
||||
if text:
|
||||
arch.text = arch.text.replace(arch.text.strip(), text)
|
||||
tail = get_trans(arch.tail)
|
||||
if tail:
|
||||
arch.tail = arch.tail.replace(arch.tail.strip(), tail)
|
||||
|
||||
for attr_name in ('title', 'alt', 'placeholder'):
|
||||
attr = get_trans(arch.get(attr_name))
|
||||
if attr:
|
||||
arch.set(attr_name, attr)
|
||||
for node in arch.iterchildren("*"):
|
||||
self.translate_qweb(cr, uid, id_, node, lang, context)
|
||||
return arch
|
||||
|
||||
@openerp.tools.ormcache()
|
||||
def get_view_xmlid(self, cr, uid, id):
|
||||
imd = self.pool['ir.model.data']
|
||||
domain = [('model', '=', 'ir.ui.view'), ('res_id', '=', id)]
|
||||
xmlid = imd.search_read(cr, uid, domain, ['module', 'name'])[0]
|
||||
return '%s.%s' % (xmlid['module'], xmlid['name'])
|
||||
|
||||
def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None):
|
||||
if isinstance(id_or_xml_id, list):
|
||||
id_or_xml_id = id_or_xml_id[0]
|
||||
tname = id_or_xml_id
|
||||
if isinstance(tname, (int, long)):
|
||||
tname = self.get_view_xmlid(cr, uid, tname)
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
if values is None:
|
||||
values = dict()
|
||||
qcontext = dict(
|
||||
keep_query=keep_query,
|
||||
request=request,
|
||||
json=simplejson,
|
||||
quote_plus=werkzeug.url_quote_plus,
|
||||
)
|
||||
qcontext.update(values)
|
||||
|
||||
def loader(name):
|
||||
return self.read_template(cr, uid, name, context=context)
|
||||
|
||||
return self.pool[engine].render(cr, uid, tname, qcontext, loader=loader, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Misc
|
||||
#------------------------------------------------------
|
||||
|
||||
def graph_get(self, cr, uid, id, model, node_obj, conn_obj, src_node, des_node, label, scale, context=None):
|
||||
nodes=[]
|
||||
|
@ -305,5 +921,4 @@ class view(osv.osv):
|
|||
ids = map(itemgetter(0), cr.fetchall())
|
||||
return self._check_xml(cr, uid, ids)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:et:
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<group>
|
||||
<field name="field_parent"/>
|
||||
<field name="inherit_id"/>
|
||||
<field name="model_data_id"/>
|
||||
<field name="xml_id"/>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -49,17 +50,19 @@
|
|||
<field name="model">ir.ui.view</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Views">
|
||||
<field name="name" filter_domain="['|', ('name','ilike',self), ('model','ilike',self)]" string="View"/>
|
||||
<field name="name" filter_domain="['|', '|', ('name','ilike',self), ('model','ilike',self), ('model_data_id','ilike',self)]" string="View"/>
|
||||
<filter string="Form" domain="[('type', '=','form')]"/>
|
||||
<filter string="Tree" domain="[('type', '=', 'tree')]"/>
|
||||
<filter string="Kanban" domain="[('type', '=', 'kanban')]"/>
|
||||
<filter string="Search" domain="[('type', '=', 'search')]"/>
|
||||
<filter string="QWeb" domain="[('type', '=', 'qweb')]"/>
|
||||
<field name="model"/>
|
||||
<field name="inherit_id"/>
|
||||
<field name="type"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model'}"/>
|
||||
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
|
||||
<filter string="Object" domain="[]" context="{'group_by':'model'}"/>
|
||||
<filter string="Type" domain="[]" context="{'group_by':'type'}"/>
|
||||
<filter string="Inherit" domain="[]" context="{'group_by':'inherit_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
|
|
@ -41,8 +41,9 @@ except ImportError:
|
|||
from StringIO import StringIO # NOQA
|
||||
|
||||
import openerp
|
||||
from openerp import modules, tools, addons
|
||||
from openerp import modules, tools
|
||||
from openerp.modules.db import create_categories
|
||||
from openerp.modules import get_module_resource
|
||||
from openerp.tools.parse_version import parse_version
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv import fields, osv, orm
|
||||
|
@ -154,7 +155,7 @@ class module(osv.osv):
|
|||
def _get_desc(self, cr, uid, ids, field_name=None, arg=None, context=None):
|
||||
res = dict.fromkeys(ids, '')
|
||||
for module in self.browse(cr, uid, ids, context=context):
|
||||
path = addons.get_module_resource(module.name, 'static/description/index.html')
|
||||
path = get_module_resource(module.name, 'static/description/index.html')
|
||||
if path:
|
||||
with tools.file_open(path, 'rb') as desc_file:
|
||||
doc = desc_file.read()
|
||||
|
@ -233,7 +234,7 @@ class module(osv.osv):
|
|||
def _get_icon_image(self, cr, uid, ids, field_name=None, arg=None, context=None):
|
||||
res = dict.fromkeys(ids, '')
|
||||
for module in self.browse(cr, uid, ids, context=context):
|
||||
path = addons.get_module_resource(module.name, 'static', 'description', 'icon.png')
|
||||
path = get_module_resource(module.name, 'static', 'description', 'icon.png')
|
||||
if path:
|
||||
image_file = tools.file_open(path, 'rb')
|
||||
try:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<field name="visible" eval="0" />
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.module.category" id="module_category_localization">
|
||||
<field name="name">Localization</field>
|
||||
<field name="visible" eval="0" />
|
||||
|
@ -113,6 +114,11 @@
|
|||
<field name="sequence">15</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.module.category" id="module_category_website">
|
||||
<field name="name">Website</field>
|
||||
<field name="sequence">16</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.module.category" id="module_category_administration">
|
||||
<field name="name">Administration</field>
|
||||
<field name="sequence">100</field>
|
||||
|
|
|
@ -141,8 +141,8 @@ class res_company(osv.osv):
|
|||
'state_id': fields.function(_get_address_data, fnct_inv=_set_address_data, type='many2one', relation='res.country.state', string="Fed. State", multi='address'),
|
||||
'bank_ids': fields.one2many('res.partner.bank','company_id', 'Bank Accounts', help='Bank accounts related to this company'),
|
||||
'country_id': fields.function(_get_address_data, fnct_inv=_set_address_data, type='many2one', relation='res.country', string="Country", multi='address'),
|
||||
'email': fields.function(_get_address_data, fnct_inv=_set_address_data, size=64, type='char', string="Email", multi='address'),
|
||||
'phone': fields.function(_get_address_data, fnct_inv=_set_address_data, size=64, type='char', string="Phone", multi='address'),
|
||||
'email': fields.related('partner_id', 'email', size=64, type='char', string="Email", store=True),
|
||||
'phone': fields.related('partner_id', 'phone', size=64, type='char', string="Phone", store=True),
|
||||
'fax': fields.function(_get_address_data, fnct_inv=_set_address_data, size=64, type='char', string="Fax", multi='address'),
|
||||
'website': fields.related('partner_id', 'website', string="Website", type="char", size=64),
|
||||
'vat': fields.related('partner_id', 'vat', string="Tax ID", type="char", size=32),
|
||||
|
|
|
@ -415,6 +415,7 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
* 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.
|
||||
The attribute 'group' may contain several xml ids, separated by commas.
|
||||
|
||||
* For a boolean field like 'module_XXX', ``execute`` triggers the immediate
|
||||
installation of the module named 'XXX' if the field has value ``True``.
|
||||
|
@ -437,7 +438,7 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
""" return a dictionary with the fields classified by category::
|
||||
|
||||
{ 'default': [('default_foo', 'model', 'foo'), ...],
|
||||
'group': [('group_bar', browse_group, browse_implied_group), ...],
|
||||
'group': [('group_bar', [browse_group], browse_implied_group), ...],
|
||||
'module': [('module_baz', browse_module), ...],
|
||||
'other': ['other_field', ...],
|
||||
}
|
||||
|
@ -446,15 +447,15 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
ir_module = self.pool['ir.module.module']
|
||||
def ref(xml_id):
|
||||
mod, xml = xml_id.split('.', 1)
|
||||
return ir_model_data.get_object(cr, uid, mod, xml, context)
|
||||
return ir_model_data.get_object(cr, uid, mod, xml, context=context)
|
||||
|
||||
defaults, groups, modules, others = [], [], [], []
|
||||
for name, field in self._columns.items():
|
||||
if name.startswith('default_') and hasattr(field, 'default_model'):
|
||||
defaults.append((name, field.default_model, name[8:]))
|
||||
elif name.startswith('group_') and isinstance(field, fields.boolean) and hasattr(field, 'implied_group'):
|
||||
field_group = getattr(field, 'group', 'base.group_user')
|
||||
groups.append((name, ref(field_group), ref(field.implied_group)))
|
||||
field_groups = getattr(field, 'group', 'base.group_user').split(',')
|
||||
groups.append((name, map(ref, field_groups), ref(field.implied_group)))
|
||||
elif name.startswith('module_') and isinstance(field, fields.boolean):
|
||||
mod_ids = ir_module.search(cr, uid, [('name', '=', name[7:])])
|
||||
record = ir_module.browse(cr, uid, mod_ids[0], context) if mod_ids else None
|
||||
|
@ -477,8 +478,8 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
res[name] = value
|
||||
|
||||
# groups: which groups are implied by the group Employee
|
||||
for name, group, implied_group in classified['group']:
|
||||
res[name] = implied_group in group.implied_ids
|
||||
for name, groups, implied_group in classified['group']:
|
||||
res[name] = all(implied_group in group.implied_ids for group in groups)
|
||||
|
||||
# modules: which modules are installed/to install
|
||||
for name, module in classified['module']:
|
||||
|
@ -497,6 +498,7 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
|
||||
ir_values = self.pool['ir.values']
|
||||
ir_module = self.pool['ir.module.module']
|
||||
res_groups = self.pool['res.groups']
|
||||
|
||||
classified = self._get_classified_fields(cr, uid, context)
|
||||
|
||||
|
@ -507,12 +509,16 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin):
|
|||
ir_values.set_default(cr, SUPERUSER_ID, model, field, config[name])
|
||||
|
||||
# group fields: modify group / implied groups
|
||||
for name, group, implied_group in classified['group']:
|
||||
for name, groups, implied_group in classified['group']:
|
||||
gids = map(int, groups)
|
||||
if config[name]:
|
||||
group.write({'implied_ids': [(4, implied_group.id)]})
|
||||
res_groups.write(cr, uid, gids, {'implied_ids': [(4, implied_group.id)]}, context=context)
|
||||
else:
|
||||
group.write({'implied_ids': [(3, implied_group.id)]})
|
||||
implied_group.write({'users': [(3, u.id) for u in group.users]})
|
||||
res_groups.write(cr, uid, gids, {'implied_ids': [(3, implied_group.id)]}, context=context)
|
||||
uids = set()
|
||||
for group in groups:
|
||||
uids.update(map(int, group.users))
|
||||
implied_group.write({'users': [(3, u) for u in uids]})
|
||||
|
||||
# other fields: execute all methods that start with 'set_'
|
||||
for method in dir(self):
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue