[MERGE] trunk
bzr revid: al@openerp.com-20140227161819-p9chmskfifo0rygs
This commit is contained in:
commit
38d1ca1ff2
|
@ -16,6 +16,7 @@ Depends:
|
|||
python,
|
||||
postgresql-client,
|
||||
python-dateutil,
|
||||
python-decorator,
|
||||
python-docutils,
|
||||
python-feedparser,
|
||||
python-gdata,
|
||||
|
|
|
@ -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
|
||||
---------
|
||||
|
||||
|
|
3
oe
3
oe
|
@ -1,5 +1,8 @@
|
|||
#! /usr/bin/env python2
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if sys.argv[1] == 'run-tests':
|
||||
sys.exit(0)
|
||||
import openerpcommand.main
|
||||
openerpcommand.main.run()
|
||||
|
|
|
@ -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,17 +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="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>
|
||||
|
@ -24,7 +41,7 @@ Mr Demo</field>
|
|||
</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" type="base64" file="base/static/img/partner_root-image.jpg"/>
|
||||
</record>
|
||||
|
|
|
@ -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: 2014-01-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:16+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-16 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16901)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:16+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:16+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-06 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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
|
||||
|
@ -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
|
||||
|
@ -9335,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
|
||||
|
@ -10393,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
|
||||
|
|
|
@ -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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:18+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:16+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -25,7 +25,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Moduuli Šekkien kirjoittamisen ja tulostamiseen.\n"
|
||||
"Moduuli Shekkien kirjoittamisen ja tulostamiseen.\n"
|
||||
"===========================================\n"
|
||||
" "
|
||||
|
||||
|
@ -129,7 +129,7 @@ msgstr ""
|
|||
"Moduuli joka lisää valmistajat ja ominaisuudet tuotelomakkeelle.\n"
|
||||
"=========================================================\n"
|
||||
"\n"
|
||||
"Voit net määritellä tuotteelle seuraavat tiedot:\n"
|
||||
"Voit nyt määritellä tuotteelle seuraavat tiedot:\n"
|
||||
"---------------------------------------------------------\n"
|
||||
" * Valmistaja\n"
|
||||
" * Valmistajan tuotenimi\n"
|
||||
|
@ -688,7 +688,7 @@ msgstr "Palau"
|
|||
#. module: base
|
||||
#: view:res.partner:0
|
||||
msgid "Sales & Purchases"
|
||||
msgstr "Myynti ja hankinta"
|
||||
msgstr "Myynnit & Ostot"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.translation:0
|
||||
|
@ -3836,7 +3836,7 @@ msgstr "Raportointi"
|
|||
#: field:res.partner,title:0
|
||||
#: field:res.partner.title,name:0
|
||||
msgid "Title"
|
||||
msgstr "Yhtiömuoto"
|
||||
msgstr "Titteli"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.property,res_id:0
|
||||
|
@ -10138,7 +10138,7 @@ msgstr ""
|
|||
#: view:res.groups:0
|
||||
#: field:res.partner,comment:0
|
||||
msgid "Notes"
|
||||
msgstr "Huomautukset"
|
||||
msgstr "Muistiinpanot"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.config_parameter,value:0
|
||||
|
@ -13158,7 +13158,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:res.company,company_registry:0
|
||||
msgid "Company Registry"
|
||||
msgstr "Yritysrekisteri"
|
||||
msgstr "Y-tunnus"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.actions.report.xml:0
|
||||
|
@ -13471,7 +13471,7 @@ msgstr "Riippuvuudet:"
|
|||
#. module: base
|
||||
#: field:res.company,vat:0
|
||||
msgid "Tax ID"
|
||||
msgstr "Vero ID"
|
||||
msgstr "VAT-numero"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_account_bank_statement_extensions
|
||||
|
@ -13821,7 +13821,7 @@ msgstr "Marokko - Kirjanpito"
|
|||
#: field:res.bank,bic:0
|
||||
#: field:res.partner.bank,bank_bic:0
|
||||
msgid "Bank Identifier Code"
|
||||
msgstr "BIC koodi"
|
||||
msgstr "BIC-koodi"
|
||||
|
||||
#. module: base
|
||||
#: view:base.language.export:0
|
||||
|
@ -15482,7 +15482,7 @@ msgstr "Matkapuhelinnumero"
|
|||
#: model:ir.model,name:base.model_res_partner_category
|
||||
#: view:res.partner.category:0
|
||||
msgid "Partner Categories"
|
||||
msgstr "Kumppanien ryhmät"
|
||||
msgstr "Kumppaniryhmät"
|
||||
|
||||
#. module: base
|
||||
#: view:base.module.upgrade:0
|
||||
|
@ -15690,7 +15690,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: view:res.partner:0
|
||||
msgid "Internal Notes"
|
||||
msgstr "Sisäiset huomautukset"
|
||||
msgstr "Sisäiset muistiinpanot"
|
||||
|
||||
#. module: base
|
||||
#: model:res.partner.title,name:base.res_partner_title_pvt_ltd
|
||||
|
|
|
@ -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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:18+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:18+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:18+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:18+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:16+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:27+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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
|
||||
|
@ -2292,7 +2295,7 @@ msgstr "メソッド"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_auth_crypt
|
||||
msgid "Password Encryption"
|
||||
msgstr ""
|
||||
msgstr "パスワード暗号化"
|
||||
|
||||
#. module: base
|
||||
#: view:workflow.activity: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
|
||||
|
@ -8009,6 +8016,12 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" クリックしてアドレス帳に連絡先を追加してください。\n"
|
||||
" </p><p>\n"
|
||||
" OpenERPは顧客、ディスカッション、商機の履歴、文書など関連するすべての活動の追跡を容易にします。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.bank_account_update
|
||||
|
@ -8340,7 +8353,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 +8454,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 +8617,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 +8695,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 +8852,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 +9244,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 +9581,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
|
||||
|
@ -9782,7 +9795,7 @@ msgstr "ドイツ"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_auth_oauth
|
||||
msgid "OAuth2 Authentication"
|
||||
msgstr ""
|
||||
msgstr "OAuth2認証"
|
||||
|
||||
#. module: base
|
||||
#: view:workflow:0
|
||||
|
@ -9825,7 +9838,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
|
||||
|
@ -10025,6 +10038,12 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" クリックしてアドレス帳に連絡先を追加してください。\n"
|
||||
" </p><p>\n"
|
||||
" OpenERPは仕入先、ディスカッション、購入の履歴、文書など関連するすべての活動の追跡を容易にします。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.lr
|
||||
|
@ -10296,7 +10315,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 +10419,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 +10444,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 +10566,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 +11076,7 @@ msgstr "オフィス用品"
|
|||
#. module: base
|
||||
#: field:ir.attachment,res_model:0
|
||||
msgid "Resource Model"
|
||||
msgstr ""
|
||||
msgstr "リソースモデル"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/custom.py:555
|
||||
|
@ -11184,7 +11203,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 +11248,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 +11393,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 +11423,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 +11458,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: field:res.users,partner_id:0
|
||||
msgid "Related Partner"
|
||||
msgstr ""
|
||||
msgstr "関連取引先"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/osv.py:172
|
||||
|
@ -11719,6 +11738,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 +12205,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 +12369,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 +12953,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 +13093,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 +13310,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 +13803,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 +13849,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 +14018,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 +14318,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 +14476,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 +15353,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 +15508,7 @@ msgstr "購買依頼"
|
|||
#. module: base
|
||||
#: selection:ir.actions.act_window,target:0
|
||||
msgid "Inline Edit"
|
||||
msgstr ""
|
||||
msgstr "インライン編集"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.cron,interval_type:0
|
||||
|
@ -15555,6 +15575,12 @@ msgid ""
|
|||
" </p>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<p class=\"oe_view_nocontent_create\">\n"
|
||||
" クリックしてアドレス帳に連絡先を追加してください。\n"
|
||||
" </p><p>\n"
|
||||
" OpenERPは顧客、ディスカッション、商機の履歴、文書など関連するすべての活動の追跡を容易にします。\n"
|
||||
" </p>\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: model:res.partner.category,name:base.res_partner_category_2
|
||||
|
|
|
@ -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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:28+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -16519,3 +16519,10 @@ msgstr ""
|
|||
#~ msgstr ""
|
||||
#~ "Nevar izveidot dokumentu (%s) ! Pārbaudiet, vai lietotājs pieder kādai no "
|
||||
#~ "šīm grupām: %s."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "\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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -3094,7 +3094,7 @@ msgstr "Моделийн Тойм"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_product_margin
|
||||
msgid "Margins by Products"
|
||||
msgstr "Захалбар Бараагаар"
|
||||
msgstr "Бохир ашиг Бараагаар"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.ui.menu,name:base.menu_invoiced
|
||||
|
@ -5214,7 +5214,7 @@ msgstr ""
|
|||
" * Дагавар\n"
|
||||
" * Дараагийн Дугаар\n"
|
||||
" * Нэмэгдэх Тоо\n"
|
||||
" * Гүйцээлтийн тоо\n"
|
||||
" * Дугаарлалтын гүйцээлт\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
|
@ -7400,7 +7400,7 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Энэ модуль нь борлуулалтын захиалга дээр 'Тодотгол' нэмдэг.\n"
|
||||
"Энэ модуль нь борлуулалтын захиалга дээр 'Бохир ашиг' нэмдэг.\n"
|
||||
"=============================================\n"
|
||||
"\n"
|
||||
"Нэгж үнэ, Өртөг үнийг харьцуулан бохир ашгийг харуулдаг.\n"
|
||||
|
@ -11017,7 +11017,7 @@ msgstr "Өөриймшүүлсэн"
|
|||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_sale_margin
|
||||
msgid "Margins in Sales Orders"
|
||||
msgstr "Борлуулалтын захиалгын зөрүү"
|
||||
msgstr "Борлуулалтын захиалгын бохир ашиг"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,shortdesc:base.module_purchase
|
||||
|
@ -12353,7 +12353,7 @@ msgid ""
|
|||
"you need.\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Бараанд борлуулалт, худалдан авалт, тохируулалт зэрэг олон сонирхолтой "
|
||||
"Бараанд борлуулалт, худалдан авалт, бохир ашиг зэрэг олон сонирхолтой "
|
||||
"үзүүлэлтийг тооцолох тайлангийн менюг нэмдэг.\n"
|
||||
"============================================================================="
|
||||
"================================================\n"
|
||||
|
@ -13178,7 +13178,7 @@ msgstr "Гүйцэтгэх дараагийн огноо"
|
|||
#. module: base
|
||||
#: field:ir.sequence,padding:0
|
||||
msgid "Number Padding"
|
||||
msgstr "Тоон дугаарын гүйцээлт"
|
||||
msgstr "Дугаарын гүйцээлт"
|
||||
|
||||
#. module: base
|
||||
#: help:multi_company.default,field_id:0
|
||||
|
@ -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
|
||||
|
@ -18259,9 +18268,6 @@ msgstr "Бүртгүүлэх"
|
|||
#~ msgid "View Ordering"
|
||||
#~ msgstr "Дэлгэц эрэмблэлт"
|
||||
|
||||
#~ msgid "Number padding"
|
||||
#~ msgstr "Тоон дугаарын урт"
|
||||
|
||||
#~ msgid "Object Identifiers"
|
||||
#~ msgstr "Обьект бүрдүүлбэр"
|
||||
|
||||
|
@ -24122,3 +24128,6 @@ msgstr "Бүртгүүлэх"
|
|||
|
||||
#~ msgid "Retro-Planning on Events"
|
||||
#~ msgstr "Үйл явдлын хойноос урагшаа төлөвлөлт"
|
||||
|
||||
#~ msgid "Number padding"
|
||||
#~ msgstr "Тоон дугаарын гүйцээлт"
|
||||
|
|
|
@ -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: 2014-01-01 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:29+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:17+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -1625,7 +1625,7 @@ msgstr ""
|
|||
#: model:ir.module.category,name:base.module_category_purchase_management
|
||||
#: model:ir.ui.menu,name:base.menu_purchase_root
|
||||
msgid "Purchases"
|
||||
msgstr "Inkoop"
|
||||
msgstr "Inkopen"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.md
|
||||
|
|
|
@ -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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:30+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:24+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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"
|
||||
|
@ -431,7 +431,8 @@ msgstr ""
|
|||
"\n"
|
||||
"Va permite sa adaugati metode de livrare la comenzile de vanzare si "
|
||||
"ridicare.\n"
|
||||
"==============================================================\n"
|
||||
"============================================================================="
|
||||
"\n"
|
||||
"\n"
|
||||
"Va puteti defini propriile grile de preturi pentru transport si livrare. "
|
||||
"Atunci cand creati \n"
|
||||
|
@ -617,7 +618,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 +651,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"
|
||||
|
@ -855,7 +856,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Contabilitate si Management Financiar.\n"
|
||||
"====================================\n"
|
||||
"======================================\n"
|
||||
"\n"
|
||||
"Modulul Finante si contabilitate acopera:\n"
|
||||
"--------------------------------------------\n"
|
||||
|
@ -899,7 +900,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Meniul pentru Marketing.\n"
|
||||
"=======================\n"
|
||||
"========================\n"
|
||||
"\n"
|
||||
"Contine programul de instalare pentru modulele legate de marketing.\n"
|
||||
" "
|
||||
|
@ -915,7 +916,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Modulul OpenERP Web LinkedIn.\n"
|
||||
"============================\n"
|
||||
"=============================\n"
|
||||
"Acest modul asigura Integrarea lui LinkedIn in OpenERP.\n"
|
||||
" "
|
||||
|
||||
|
@ -950,7 +951,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 +976,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 +997,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
|
||||
|
@ -1072,7 +1073,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Gestioneaza concediile si cererile de alocare\n"
|
||||
"=====================================\n"
|
||||
"=============================================\n"
|
||||
"\n"
|
||||
"Aceasta aplicatie controleaza programul de concedii al companiei "
|
||||
"dumneavoastra. Le permite angajatilor sa solicite concedii. Astfel, "
|
||||
|
@ -1331,7 +1332,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Managementul general OpenERP al Relatiilor cu Clientii\n"
|
||||
" ====================================================\n"
|
||||
"======================================================\n"
|
||||
" \n"
|
||||
"Aceasta aplicatie permite unui grup de oameni sa gestioneze in mod "
|
||||
"inteligent si eficient piste, oportunitati, intalniri si apeluri "
|
||||
|
@ -1356,7 +1357,7 @@ msgstr ""
|
|||
" \n"
|
||||
"\n"
|
||||
"Tabloul de bord pentru MRC va include:\n"
|
||||
" -------------------------------\n"
|
||||
"--------------------------------------\n"
|
||||
" * Veniturile Planificate dupa Etapa si Utilizator (grafic)\n"
|
||||
" * Oportunitati dupa Etapa (grafic)\n"
|
||||
|
||||
|
@ -1932,7 +1933,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
|
||||
|
@ -2011,7 +2012,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Modulul de baza pentru gestionarea pranzului.\n"
|
||||
"================================\n"
|
||||
"=============================================\n"
|
||||
"\n"
|
||||
"Multe companii comanda sandwich-uri, pizza si alte mancaruri de la "
|
||||
"furnizorii obisnuiti, pentru angajatii lor pentru a le oferi mai multe "
|
||||
|
@ -2056,7 +2057,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 +2126,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 +2170,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
|
||||
|
@ -2250,7 +2251,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Drepturi de acces contabile\n"
|
||||
"========================\n"
|
||||
"===========================\n"
|
||||
"Ii ofera utilizatorului Administrator acces la toate caracteristicile "
|
||||
"contabile, precum elemente ale jurnalului si planul de conturi.\n"
|
||||
"\n"
|
||||
|
@ -2260,7 +2261,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 +2300,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
|
||||
|
@ -2444,7 +2445,8 @@ msgstr ""
|
|||
"\n"
|
||||
"Sincronizarea inregistrarilor sarcinilor proiectului cu inregistrarile fisei "
|
||||
"de pontaj.\n"
|
||||
"====================================================================\n"
|
||||
"============================================================================="
|
||||
"==========\n"
|
||||
"\n"
|
||||
"Acest modul va permite sa transferati inregistrarile sub sarcini definite "
|
||||
"pentru Managementul\n"
|
||||
|
@ -2456,7 +2458,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
|
||||
|
@ -2778,7 +2780,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Inregistreaza si valideaza fisele de pontaj si prezenta cu usurinta\n"
|
||||
"=====================================================\n"
|
||||
"===================================================================\n"
|
||||
"\n"
|
||||
"Aceasta aplicatie ofera un ecran nou care va permite sa gestionati atat "
|
||||
"prezenta (La intrare/La iesire) cat si inregistrare muncii (fisa de pontaj) "
|
||||
|
@ -2874,7 +2876,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Permite anonimilor sa Acceseze Portalul.\n"
|
||||
"=================================\n"
|
||||
"========================================\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
|
@ -2987,7 +2989,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 +2998,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
|
||||
|
@ -3021,7 +3023,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Managementul Serviciului de asistenta tehnica.\n"
|
||||
"===================================\n"
|
||||
"==============================================\n"
|
||||
"\n"
|
||||
"La fel ca si inregistrarea si prelucrarea reclamatiilor, Serviciul de "
|
||||
"Asistenta tehnica este un instrument\n"
|
||||
|
@ -3095,7 +3097,8 @@ msgstr ""
|
|||
"\n"
|
||||
"Acesta este modulul de baza pentru gestionarea produselor si a listelor de "
|
||||
"preturi in OpenERP.\n"
|
||||
"========================================================================\n"
|
||||
"============================================================================="
|
||||
"=================\n"
|
||||
"\n"
|
||||
"Produsele accepta variante, diferite metode de stabilire a pretului, "
|
||||
"informatii referitoare la furnizori,\n"
|
||||
|
@ -3103,7 +3106,7 @@ msgstr ""
|
|||
"proprietati.\n"
|
||||
"\n"
|
||||
"Listele de preturi accepta:\n"
|
||||
"--------------------\n"
|
||||
"---------------------------\n"
|
||||
" * Niveluri multiple de reducere (dupa produs, categorie, cantitati)\n"
|
||||
" * Calculeaza pretul pe baza unor criterii diferite:\n"
|
||||
" * Alte liste de preturi\n"
|
||||
|
@ -3134,11 +3137,10 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Configureaza valorile implicite pentru conturile dumneavoastra analitice.\n"
|
||||
"==============================================\n"
|
||||
"=========================================================================\n"
|
||||
"\n"
|
||||
"Permite selectarea automata a conturilor analitice pe baza criteriilor:\n"
|
||||
"-----------------------------------------------------------------------------"
|
||||
"------\n"
|
||||
"-----------------------------------------------------------------------\n"
|
||||
" * Produs \n"
|
||||
" * Partener\n"
|
||||
" * Utilizator\n"
|
||||
|
@ -3216,7 +3218,8 @@ msgstr ""
|
|||
"\n"
|
||||
"Modulul de baza pentru gestionarea distribuirii analitice si a comenzilor de "
|
||||
"vanzare.\n"
|
||||
"==========================================================================\n"
|
||||
"============================================================================="
|
||||
"========\n"
|
||||
"\n"
|
||||
"Folosind acest modul veti putea lega conturile analitice de comenzile de "
|
||||
"vanzare.\n"
|
||||
|
@ -3292,7 +3295,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Acesta este un sistem complet de gestionare a documentelor.\n"
|
||||
"==============================================\n"
|
||||
"===========================================================\n"
|
||||
" * Autentificare Utilizator\n"
|
||||
" * Indexare Documente:- fisierele .pptx si .docx nu sunt acceptate in "
|
||||
"platforma Windows.\n"
|
||||
|
@ -3351,8 +3354,8 @@ msgid ""
|
|||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Gestiunea cotarilor si a comenzilor de vanzare\n"
|
||||
" ==================================\n"
|
||||
"Gestionare cotațiilor și a comenzilor de vânzare\n"
|
||||
"================================================\n"
|
||||
"\n"
|
||||
"Aceasta aplicatie va permite sa va gestionati obiectivele de vanzari intr-un "
|
||||
"mod efectiv si eficient, tinand evidenta tuturor comenzilor de vanzare si "
|
||||
|
@ -3363,7 +3366,7 @@ msgstr ""
|
|||
"* **Cotare** -> **Comanda de vanzare** -> **Factura**\n"
|
||||
"\n"
|
||||
"Preferinte (numai daca este instalat si modulul Gestionarea Depozitului)\n"
|
||||
"-----------------------------------------------------\n"
|
||||
"------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
"Daca ati instalat si Gestionarea Depozitului, puteti efectua urmatoarele:\n"
|
||||
"\n"
|
||||
|
@ -3382,7 +3385,7 @@ msgstr ""
|
|||
"\n"
|
||||
"\n"
|
||||
"Tabloul de bord pentru Managerul de Vanzari va include\n"
|
||||
"------------------------------------------------\n"
|
||||
"------------------------------------------------------\n"
|
||||
"* Cotatiile mele\n"
|
||||
"* Cifra de afaceri lunara (Grafic)\n"
|
||||
" "
|
||||
|
@ -3414,7 +3417,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"\n"
|
||||
"Modul pentru atasarea unui document google oricarui model.\n"
|
||||
"================================================\n"
|
||||
"==========================================================\n"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_fields.py:333
|
||||
|
@ -3591,7 +3594,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 +4881,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 +4957,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 +6086,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 +6332,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 +6367,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 +7197,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 +7281,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 +7570,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 +8100,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 +8211,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 +8493,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 +8604,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 +9157,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 +9246,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 +9984,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 +10212,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 +10222,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 +10237,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 +10263,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 +10892,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 +11838,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 +12122,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 +12329,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 +12392,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 +12455,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 +12596,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 +13123,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 +13692,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 +14251,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 +14288,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 +14311,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 +14537,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 +14636,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 +15426,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 +15540,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 +16204,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 +16828,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 +17412,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 +17600,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 +17645,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 +17939,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 +18445,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 +18956,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: 2014-01-01 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:32+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:21+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:31+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:26+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:22+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.module.module,description:base.module_account_check_writing
|
||||
|
@ -25,6 +25,9 @@ msgid ""
|
|||
"================================================\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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: 2014-01-01 05:25+0000\n"
|
||||
"X-Generator: Launchpad (build 16877)\n"
|
||||
"X-Launchpad-Export-Date: 2014-02-22 06:37+0000\n"
|
||||
"X-Generator: Launchpad (build 16926)\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:
|
||||
|
|
|
@ -24,6 +24,8 @@ import logging
|
|||
import operator
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import dateutil
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
|
@ -268,7 +270,7 @@ class ir_actions_act_window(osv.osv):
|
|||
'filter': fields.boolean('Filter'),
|
||||
'auto_search':fields.boolean('Auto Search'),
|
||||
'search_view' : fields.function(_search_view, type='text', string='Search View'),
|
||||
'multi': fields.boolean('Action on Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view"),
|
||||
'multi': fields.boolean('Restrict to lists', help="If checked and the action is bound to a model, it will only appear in the More menu on list views"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -550,6 +552,7 @@ class ir_actions_server(osv.osv):
|
|||
# - uid: current user id
|
||||
# - context: current context
|
||||
# - time: Python time module
|
||||
# - workflow: Workflow engine
|
||||
# If you plan to return an action, assign: action = {...}""",
|
||||
'use_relational_model': 'base',
|
||||
'use_create': 'new',
|
||||
|
@ -910,11 +913,38 @@ 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,
|
||||
'datetime': datetime,
|
||||
'dateutil': dateutil,
|
||||
'cr': cr,
|
||||
'uid': uid,
|
||||
'user': user,
|
||||
'context': context,
|
||||
'workflow': workflow
|
||||
}
|
||||
|
||||
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,33 +962,14 @@ 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
|
||||
condition = True
|
||||
if hasattr(self, 'run_action_%s_multi' % action.state):
|
||||
# set active_ids in context only needed if one active_id
|
||||
run_context = dict(context, active_ids=active_ids)
|
||||
eval_context["context"] = run_context
|
||||
run_context = eval_context['context']
|
||||
expr = eval(str(condition), eval_context)
|
||||
if not expr:
|
||||
continue
|
||||
|
@ -968,6 +979,8 @@ class ir_actions_server(osv.osv):
|
|||
|
||||
elif hasattr(self, 'run_action_%s' % action.state):
|
||||
func = getattr(self, 'run_action_%s' % action.state)
|
||||
active_id = context.get('active_id')
|
||||
active_ids = context.get('active_ids', [active_id] if active_id else [])
|
||||
for active_id in active_ids:
|
||||
# run context dedicated to a particular active_id
|
||||
run_context = dict(context, active_ids=[active_id], active_id=active_id)
|
||||
|
|
|
@ -180,6 +180,7 @@
|
|||
<field name="auto_refresh"/>
|
||||
<field name="auto_search"/>
|
||||
<field name="filter"/>
|
||||
<field name="multi"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Help">
|
||||
|
@ -411,6 +412,7 @@
|
|||
<li>cr: database cursor</li>
|
||||
<li>uid: current user id</li>
|
||||
<li>context: current context</li>
|
||||
<li>workflow: Workflow engine</li>
|
||||
</ul>
|
||||
<div>
|
||||
<p>Example of condition expression using Python</p>
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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,9 @@ 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)
|
||||
if openerp.tools.config['test_enable']:
|
||||
installed.add(openerp.modules.module.current_test)
|
||||
mods = [''] + openerp.conf.server_wide_modules + sorted(installed)
|
||||
self._routing_map = http.routing_map(mods, False, converters=self._get_converters())
|
||||
|
||||
return self._routing_map
|
||||
|
|
|
@ -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,611 @@ 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, root_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, root_id)
|
||||
else:
|
||||
node.set('data-oe-id', str(view_id))
|
||||
node.set('data-oe-source-id', str(root_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, root_id=None, 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 = {}
|
||||
if root_id is None:
|
||||
root_id = source_id
|
||||
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, root_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, root_id=root_id, 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):
|
||||
if child.get('data-oe-xpath'):
|
||||
# injected by view inheritance, skip otherwise
|
||||
# generated xpath is incorrect
|
||||
continue
|
||||
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 +927,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>
|
||||
|
|
|
@ -394,17 +394,16 @@ class ir_values(osv.osv):
|
|||
for action in cr.dictfetchall():
|
||||
if not action['value']:
|
||||
continue # skip if undefined
|
||||
action_model,id = action['value'].split(',')
|
||||
fields = [
|
||||
field
|
||||
for field in self.pool[action_model]._all_columns
|
||||
if field not in EXCLUDED_FIELDS]
|
||||
action_model_name, action_id = action['value'].split(',')
|
||||
action_model = self.pool.get(action_model_name)
|
||||
if not action_model:
|
||||
continue # unknow model? skip it
|
||||
fields = [field for field in action_model._all_columns if field not in EXCLUDED_FIELDS]
|
||||
# FIXME: needs cleanup
|
||||
try:
|
||||
action_def = self.pool[action_model].read(cr, uid, int(id), fields, context)
|
||||
action_def = action_model.read(cr, uid, int(action_id), fields, context)
|
||||
if action_def:
|
||||
if action_model in ('ir.actions.report.xml','ir.actions.act_window',
|
||||
'ir.actions.wizard'):
|
||||
if action_model_name in ('ir.actions.report.xml', 'ir.actions.act_window'):
|
||||
groups = action_def.get('groups_id')
|
||||
if groups:
|
||||
cr.execute('SELECT 1 FROM res_groups_users_rel WHERE gid IN %s AND uid=%s',
|
||||
|
|
|
@ -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>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue