diff options
232 files changed, 26329 insertions, 6977 deletions
diff --git a/MANIFEST.in b/MANIFEST.in index 6cd10b511cf..70715f18bc2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,18 +1,12 @@ -include rpminstall_sh.txt # TODO do we need this file ? include README include LICENSE include MANIFEST.in include setup.nsi include setup.cfg -#include openerp/server.cert -#include openerp/server.pkey -#include openerp/gpl.txt -include man/openerp-server.1 -include man/openerp_serverrc.5 -recursive-include pixmaps *bmp *ico *png +include setup_rpm.sh recursive-include win32 *.py *.bat -recursive-include openerp *css *csv *html *png *po *pot -recursive-include openerp *rml *rng *sql *sxw *xml *xsl *yml +recursive-include openerp *css *csv *html *png *po *pot *rml *rng *sql *sxw *xml *xsl *yml +graft install graft debian graft doc global-exclude *pyc *~ # Exclude possible garbage from previous graft. @@ -1,17 +1,138 @@ -About OpenERP
----------------
-
-OpenERP is a free Enterprise Resource Planning and Customer Relationship
-Management software. It is mainly developed to meet changing needs.
-
-The main functional features are: CRM & SRM, analytic and financial accounting,
-double-entry stock management, sales and purchases management, tasks automation,
-help desk, marketing campaign, ... and vertical modules for very specific
-businesses.
-
-Technical features include a distributed server, flexible workflows, an object
-database, dynamic GUIs, customizable reports, NET-RPC and XML-RPC interfaces, ...
-
-For more information, please visit:
-http://www.openerp.com
-
+About OpenERP +------------- + +OpenERP is a free Enterprise Resource Planning and Customer Relationship +Management software. It is mainly developed to meet changing needs. + +The main functional features are: CRM & SRM, analytic and financial accounting, +double-entry stock management, sales and purchases management, tasks automation, +help desk, marketing campaign, ... and vertical modules for very specific +businesses. + +Technical features include a distributed server, flexible workflows, an object +database, dynamic GUIs, customizable reports, NET-RPC and XML-RPC interfaces, ... + +For more information, please visit: +http://www.openerp.com + +OpenERP Quick Installation Guide +--------------------------------- + +This file contains a quick guide to configure and install the OpenERP server. + +Required dependencies: +--------------------- + +You need the following software installed: + + * Python 2.5 or 2.6 + * Postgresql 8.2 or above + * Psycopg2 python module + * Reportlab pdf generation library for python + * lxml python module + * pytz python module + * PyYaml python module (install with: easy_install PyYaml) + +Some dependencies are only required for specific purposes: + +for rendering workflows graphs, you need: + * graphviz + * pyparsing + +For Luxembourg localization, you also need: + * pdftk (http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/) + +for generating reports using non .jpg images, you need: + * Python Imaging Library for python + +For Debian-based distributions, the required packages can be installed with the +following command: + + #> apt-get install -y postgresql graphviz python-psycopg2 python-lxml python-tz python-imaging + +For Fedora +if they are not installed, install: +python and postgresql + +uses yum or you can recover required packages on fedora web site in "core" or "extra" repository : +postgresql-python +python-lxml +python-imaging +python-psycopg2 +python-reportlab +graphviz +You can find pyparsing at http://pyparsing.sourceforge.net/ + +1. Check that all the required dependencies are installed. + +2. Launch the program "python ./bin/openerp-server.py -r db_user -w db_password --db_host 127.0.0.1". +See the man page for more information about options. + +3. Connect to the server using the GUI client. And follow the instructions to create a new database. + +Installation Steps +------------------ + +1. Check that all the required dependencies are installed. + +2. Create a postgresql database. + +The default database name is "terp". If you want to use another name, you +will need to provide it when launching the server (by using the commandline +option --database). + +To create a postgresql database named "terp" using the following command: + $ createdb --encoding=UNICODE terp + +If it is the first time you use postgresql you might need to create a new user +to the postgres system using the following commands (where myusername is your +unix user name): + + $ su - + # su - postgres + $ createuser openerp + Shall the new user be allowed to create databases? (y/n) y + Shall the new user be allowed to create more new users? (y/n) y + CREATE USER + $ logout + # logout + +3. Launch service daemon by "service openerp-server start". + +The first time it is run, the server will initialise the database with all the default values. + +4. Connect to the server using the GUI client. + +There are two accounts by default: + * login: admin, password:admin + * login: demo, password:demo + +Some instructions to use setup.py for a user-install. +This file should/will be moved on a proper documentation place later. + + +- Possibly clean any left-over of the previous build. + > rm -rf dist openerp_server.egg-info + +- Possibly copy the addons in the server if we want them to be packaged + together: + > rsync -av --delete \ + --exclude .bzr/ \ + --exclude .bzrignore \ + --exclude /__init__.py \ + --exclude /base \ + --exclude /base_quality_interrogation.py \ + <path-to-addons> openerp/addons + +- Create the user-local directory where we want the package to be installed: + > mkdir -p /home/openerp/openerp-tmp/lib/python2.6/site-packages/ + +- Use --prefix to specify where the package is installed and include that + place in PYTHONPATH: + > PYTHONPATH=/home/openerp/openerp-tmp/lib/python2.6/site-packages/ \ + python setup.py install --prefix=/home/openerp/openerp-tmp + +- Run the main script, again specifying the PYTHONPATH: + > PYTHONPATH=/home/openerp/openerp-tmp/lib/python2.6/site-packages/ \ + /home/openerp/openerp-tmp/bin/openerp-server + diff --git a/debian/README.source b/debian/README.source deleted file mode 100644 index 18b6b245bf0..00000000000 --- a/debian/README.source +++ /dev/null @@ -1,37 +0,0 @@ -Package Repositories --------------------- - -Backports for the current stable debian distribution as well as snapshots of -unreleased versions may be available in repositories listed on the maintainers -homepage. The current URL of the maintainer homepage can be seen in -debian/copyright. - - -Source Access -------------- - -You can obtain the sources of this package with: - - $ apt-get source ${PACKAGE} - -whereas '${PACKAGE}' has to be replaced with the actual name of the package. - -This package is maintained with the Git version control system. The current git -source tree can be obtained with: - - $ git clone ${GIT_URI} - -whereas '${GIT_URI}' has to be replaced with the actual URI for the Git -repository. The current Git URI can be seen in debian/control in the extracted -package sources. - -More information about Git can be found in the git-core package. - -This package may use the Quilt patch system to manage all modifications to the -upstream source. Changes, if any, are stored in the source package as diffs in -debian/diff and are applied during the build. Current modifications can be -applied to the source tree with: - - $ QUILT_PATCHES=debian/patches quilt push -a - -More information about Quilt can be found in the quilt package. diff --git a/debian/changelog b/debian/changelog index f9a2355cf62..0ee8e0e3295 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openerp (6.1-1) testing; urgency=low + + * New major version, new packaging. + + -- Antony Lesuisse <al@openerp.com> Sat, 01 Oct 2011 12:31:00 +0100 + openerp-server (6.0.2-1) testing; urgency=low * Using upstream version 6.0.2 diff --git a/debian/control b/debian/control index 11c98536526..3165879fa3f 100644 --- a/debian/control +++ b/debian/control @@ -1,40 +1,49 @@ -Source: openerp-server +Source: openerp Section: net Priority: optional -Maintainer: OpenERP SA. <xrg@openerp.com> -Uploaders: Xrg <xrg@openerp.com> -Build-Depends: debhelper (>= 7.0.50~), python -Build-Depends-Indep: - python-libxslt1, python-lxml, python-pychart, python-pydot, python-psycopg2, - python-reportlab +Maintainer: OpenERP SA <al@openerp.com> +Build-Depends: debhelper (>= 7.0.50~), python, rsync Standards-Version: 3.9.1 Homepage: http://www.openerp.com/ -Vcs-Browser: http://git.hellug.gr/?p=xrg/openobject-server;a=summary -Vcs-Git: http://members.hellug.gr/xrg/repos/openobject-server -Vcs-Bzr: https://code.launchpad.net/openobject-server +Vcs-Bzr: https://launchpad.net/openobject -Package: openerp-server +Package: openerp Section: net Architecture: all Depends: - ${misc:Depends}, adduser, python, python-dateutil, python-libxslt1, - python-lxml, python-psycopg2, python-pydot, python-pychart, python-reportlab, - python-tz, python-pyparsing, python-yaml, python-mako, - postgresql-client (>=8.2) -Conflicts: tinyerp-server -Replaces: tinyerp-server + ${misc:Depends}, + adduser, + python, + postgresql-client, + python-dateutil, + python-gdata, + python-ldap, + python-libxslt1, + python-lxml, + python-mako, + python-openid, + python-psycopg2, + python-pybabel, + python-pychart, + python-pydot, + python-pyparsing, + python-reportlab, + python-simplejson, + python-tz, + python-vobject, + python-webdav, + python-werkzeug, + python-yaml, + python-zsi +Conflicts: tinyerp-server, openerp-server, openerp-web +Replaces: tinyerp-server, openerp-server, openerp-web Recommends: - graphviz, ghostscript, postgresql, python-imaging, - python-matplotlib -Suggests: openerp-client -Description: Enterprise Resource Management (server) - Open ERP, previously known as TinyERP, is a complete ERP and CRM. The main + graphviz, ghostscript, postgresql, python-imaging, python-matplotlib +Description: OpenERP Enterprise Resource Management + OpenERP, previously known as TinyERP, is a complete ERP and CRM. The main features are accounting (analytic and financial), stock management, sales and purchases management, tasks automation, marketing campaigns, help desk, POS, etc. Technical features include a distributed server, flexible workflows, an object database, a dynamic GUI, customizable reports, and NET-RPC and XML-RPC interfaces. - . - This package contains the Open ERP server, install openerp-client package for - the client. diff --git a/debian/local/openerp-server.conf b/debian/local/openerp-server.conf deleted file mode 100644 index ffb6ed49db3..00000000000 --- a/debian/local/openerp-server.conf +++ /dev/null @@ -1,55 +0,0 @@ -# /etc/openerp-server.conf(5) - configuration file for openerp-server(1) - -[options] -# Enable the debugging mode (default False). -verbose = False -debug_mode = False - -# The file where the server pid will be stored (default False). -#pidfile = /var/run/openerp.pid - -# The file where the server log will be stored (default False). -logfile = /var/log/openerp-server.log - -# The unix account on behalf openerp is running. -process_user = openerp - -# The IP address on which the server will bind. -# If empty, it will bind on all interfaces (default empty). -interface = localhost - -# The TCP port on which the server will listen (default 8069). -#port = 8070 - -# Enable debug mode (default False). -debug_mode = False - -# Launch server over https instead of http (default False). -secure = False - -# Specify the SMTP server for sending email (default localhost). -smtp_server = localhost - -# Specify the SMTP user for sending email (default False). -smtp_user = False - -# Specify the SMTP password for sending email (default False). -smtp_password = False - -# Specify the database name. -#db_name = openerp - -# Specify the database user name (default None). -db_user = openerp - -# Specify the database password for db_user (default None). -db_password = - -# Specify the database host (default localhost). -db_host = - -# Specify the database port (default None). -db_port = 5432 - -# Specify the price accuracy. -#price_accuracy = diff --git a/debian/openerp-server.config b/debian/openerp-server.config deleted file mode 100644 index cf081ab3861..00000000000 --- a/debian/openerp-server.config +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -set -e - -. /usr/share/debconf/confmodule - -db_input low openerp-server/username || true -db_go - -db_stop diff --git a/debian/openerp-server.docs b/debian/openerp-server.docs deleted file mode 100644 index d5ad552bfce..00000000000 --- a/debian/openerp-server.docs +++ /dev/null @@ -1,2 +0,0 @@ -doc/migrate -doc/tests diff --git a/debian/openerp-server.examples b/debian/openerp-server.examples deleted file mode 100644 index c7f075ec127..00000000000 --- a/debian/openerp-server.examples +++ /dev/null @@ -1 +0,0 @@ -debian/openerp-server.preseed diff --git a/debian/openerp-server.install b/debian/openerp-server.install deleted file mode 100644 index 78a4a648a06..00000000000 --- a/debian/openerp-server.install +++ /dev/null @@ -1 +0,0 @@ -doc/openerp-server.conf /etc diff --git a/debian/openerp-server.links b/debian/openerp-server.links deleted file mode 100644 index 67620d22397..00000000000 --- a/debian/openerp-server.links +++ /dev/null @@ -1,2 +0,0 @@ -/usr/share/man/man5/openerp_serverrc.5.gz /usr/share/man/man5/openerp-server.conf.5.gz -/var/lib/openerp-server/filestore /usr/lib/openerp-server/filestore diff --git a/debian/openerp-server.lintian-overrides b/debian/openerp-server.lintian-overrides deleted file mode 100644 index 25b1165c4be..00000000000 --- a/debian/openerp-server.lintian-overrides +++ /dev/null @@ -1,7 +0,0 @@ -# Add-on directories needs data directories, and sometimes they are -# (intentionally) empty, hence overriting the lintian warning. -openerp-server: package-contains-empty-directory -# Add-on directoires contain images sometimes, but it's nothing that is -# worthwile to be splittet out to /usr/share as it's all manual work for each -# release. -openerp-server: image-file-in-usr-lib diff --git a/debian/openerp-server.postinst b/debian/openerp-server.postinst deleted file mode 100644 index a1e5317b8fc..00000000000 --- a/debian/openerp-server.postinst +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -set -e - -. /usr/share/debconf/confmodule - -CONFFILE="/etc/openerp-server.conf" -LOGFILE="/var/log/openerp-server.log" - -case "${1}" in - configure) - db_version 2.0 - - db_get openerp-server/username - _USERNAME="${RET:-openerp}" - - db_stop - - if ! getent passwd | grep -q "^${_USERNAME}" - then - adduser --system --no-create-home --quiet --gecos 'Open ERP server' --group ${_USERNAME} - else - echo "Open ERP user (${_USERNAME}) already exists, doing nothing." - fi - - sed -i -e "s|^process_user.*$|process_user = ${_USERNAME}|" ${CONFFILE} - - # Creating log file - touch ${LOGFILE} - chown ${_USERNAME}:adm ${LOGFILE} - chmod 0640 ${LOGFILE} - - # Creating local storage directory - mkdir -p /var/lib/openerp-server/filestore - - # Setting ownership and permissions - chmod 0640 ${CONFFILE} - chown ${_USERNAME}:${_USERNAME} ${CONFFILE} - chown ${_USERNAME}:${_USERNAME} /var/lib/openerp-server -R - - echo - echo "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" - echo "* Open ERP uses a PostgreSQL database to store its data. With the first *" - echo "* generation of packages, you have to setup this database manually. *" - echo "* Please read /usr/share/doc/openerp-server/README.Debian how to do it. *" - echo "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" - echo - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - - ;; - - *) - echo "postinst called with unknown argument \`{$1}'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/openerp-server.postrm b/debian/openerp-server.postrm deleted file mode 100644 index 02b3d0a6817..00000000000 --- a/debian/openerp-server.postrm +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -set -e - -case "${1}" in - remove) - _USERNAME="openerp" - _GROUPNAME="openerp" - - if [ -x /usr/sbin/deluser ] - then - deluser --quiet --system ${_USERNAME} - fi - - if [ -x /usr/sbin/delgroup ] - then - delgroup --quiet --system --only-if-empty ${_GROUPNAME} || true - fi - - rm -f /usr/lib/openerp-server/addons/__init__.pyc - rmdir --ignore-fail-on-non-empty /usr/lib/openerp-server/addons || true - rmdir --ignore-fail-on-non-empty /usr/lib/openerp-server || true - ;; - - purge) - rm -rf /var/lib/openerp-server - ;; - - upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - - ;; - - *) - echo "postrm called with unknown argument \`${1}'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/openerp-server.preseed b/debian/openerp-server.preseed deleted file mode 100644 index 66d1a4ab95d..00000000000 --- a/debian/openerp-server.preseed +++ /dev/null @@ -1,5 +0,0 @@ -################################################################################ -## openerp-server - -#openerp-server openerp-server/username string openerp -################################################################################ diff --git a/debian/openerp-server.templates b/debian/openerp-server.templates deleted file mode 100644 index 985bd24abd9..00000000000 --- a/debian/openerp-server.templates +++ /dev/null @@ -1,9 +0,0 @@ -Template: openerp-server/username -Type: string -Default: openerp -_Description: Dedicated system account for the Open ERP server: - The Open ERP server must use a dedicated account for its operation so that - the system's security is not compromised by running it with superuser - privileges. - . - Please choose that account's username. diff --git a/debian/openerp-server.README.Debian b/debian/openerp.README.Debian index af298134af8..af298134af8 100644 --- a/debian/openerp-server.README.Debian +++ b/debian/openerp.README.Debian diff --git a/debian/openerp-server.init b/debian/openerp.init index ad8cbecb07c..6abb6f10ed6 100644 --- a/debian/openerp-server.init +++ b/debian/openerp.init @@ -16,7 +16,7 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/bin/openerp-server NAME=openerp-server DESC=openerp-server -CONFIG=/etc/openerp-server.conf +CONFIG=/etc/openerp/openerp-server.conf LOGFILE=/var/log/openerp-server.log USER=openerp diff --git a/debian/openerp.install b/debian/openerp.install new file mode 100644 index 00000000000..511075fb7c9 --- /dev/null +++ b/debian/openerp.install @@ -0,0 +1 @@ +install/openerp-server.conf /etc/openerp diff --git a/debian/openerp.postinst b/debian/openerp.postinst new file mode 100644 index 00000000000..362741bb7e9 --- /dev/null +++ b/debian/openerp.postinst @@ -0,0 +1,28 @@ +#!/bin/sh + +set -e + +case "${1}" in + configure) + if ! getent passwd | grep -q "^openerp"; then + adduser --system --no-create-home --quiet --gecos 'OpenERP' --group openerp + fi + # Register "openerp" as a postgres superuser + su - postgres -c "createuser -s openerp" 2> /dev/null || true + chown openerp:openerp /etc/openerp/openerp-server.conf + chmod 0640 /etc/openerp/openerp-server.conf + # Creating log file + touch /var/log/openerp.log + chown openerp:openerp /var/log/openerp.log + chmod 0640 /var/log/openerp.log + # Creating local storage directory + mkdir -p /var/lib/openerp/filestore + chown openerp:openerp -R /var/lib/openerp + ;; + *) + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/openerp.postrm b/debian/openerp.postrm new file mode 100644 index 00000000000..0e5014dc9c8 --- /dev/null +++ b/debian/openerp.postrm @@ -0,0 +1,26 @@ +#!/bin/sh + +set -e + +case "${1}" in + remove) + deluser --quiet --system "openerp" || true + delgroup --quiet --system --only-if-empty "openerp" || true + ;; + + purge) + rm -rf /var/lib/openerp-server + ;; + + upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`${1}'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules index 30ce14141e4..7d8b210d1ba 100755 --- a/debian/rules +++ b/debian/rules @@ -1,12 +1,18 @@ #!/usr/bin/make -f -EXTRA_MODULES_PATH ?= ../addons - %: dh ${@} -override_dh_installchangelogs: - dh_installchangelogs doc/Changelog +override_dh_pysupport: + echo "rsync" + sh -c "[ -d debian/openerp/usr/lib/python2.6 ] && rsync -av openerp/ debian/openerp/usr/lib/python2.6/dist-packages/openerp/" || true + sh -c "[ -d debian/openerp/usr/lib/python2.7 ] && rsync -av openerp/ debian/openerp/usr/lib/python2.7/dist-packages/openerp/" || true + rm -Rf debian/openerp/usr/openerp debian/openerp/usr/lib/python2.6/dist-packages/tests debian/openerp/usr/lib/python2.7/dist-packages/tests + dh_pysupport + rm -Rf debian/openerp/usr/lib + + override_dh_installinit: dh_installinit --update-rcd-params='defaults 21' + diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index d3827e75a5c..00000000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/doc/openerp-server.conf b/doc/openerp-server.conf deleted file mode 100644 index 4f13c8a45c2..00000000000 --- a/doc/openerp-server.conf +++ /dev/null @@ -1,34 +0,0 @@ -[options] -without_demo = True -; This is the password that allows database operations: -; admin_passwd = admin -upgrade = False -verbose = False -netrpc = True -; netrpc_interface = -; netrpc_port = -xmlrpc = True -; xmlrpc_interface = -xmlrpc_port = 8069 -db_host = False -db_port = False -; Please uncomment the following line *after* you have created the -; database. It activates the auto module check on startup. -; db_name = terp -db_user = openerp -db_password = False -; Uncomment these for xml-rpc over SSL -; secure = True -; secure_cert_file = /etc/openerp/server.cert -; secure_pkey_file = /etc/openerp/server.key -root_path = None -soap = False -translate_modules = ['all'] -demo = {} -addons_path = None -reportgz = False - -; Static http parameters -static_http_enable = False -static_http_document_root = /var/www/html -static_http_url_prefix = /
\ No newline at end of file diff --git a/gunicorn.conf.py b/gunicorn.conf.py new file mode 100644 index 00000000000..7b117c040f6 --- /dev/null +++ b/gunicorn.conf.py @@ -0,0 +1,17 @@ +import openerp +# Standard OpenERP XML-RPC port. +bind = '127.0.0.1:8069' +pidfile = '.gunicorn.pid' +# This is the big TODO: safely use more than a single worker. +workers = 1 +# Some application-wide initialization is needed. +on_starting = openerp.wsgi.on_starting +when_ready = openerp.wsgi.when_ready +timeout = 240 # openerp request-response cycle can be quite long + +# Setting openerp.conf.xxx will be better than setting +# openerp.tools.config['xxx'] +conf = openerp.tools.config +conf['addons_path'] = '/home/openerp/repos/addons/trunk-xmlrpc' +conf['static_http_document_root'] = '/tmp' +#conf['log_level'] = 10 # 10 is DEBUG diff --git a/doc/Changelog b/history/Changelog index 3c63a7ee22d..3c63a7ee22d 100644 --- a/doc/Changelog +++ b/history/Changelog diff --git a/doc/Changelog-4.x b/history/Changelog-4.x index d884fe8d391..d884fe8d391 100644 --- a/doc/Changelog-4.x +++ b/history/Changelog-4.x diff --git a/doc/Changelog-6.x b/history/Changelog-6.x index 05b5f58217e..05b5f58217e 100644 --- a/doc/Changelog-6.x +++ b/history/Changelog-6.x diff --git a/doc/INSTALL b/history/INSTALL index 254b7e7b5a0..254b7e7b5a0 100644 --- a/doc/INSTALL +++ b/history/INSTALL diff --git a/doc/README.urpmi b/history/README.urpmi index ce8fb706703..ce8fb706703 100644 --- a/doc/README.urpmi +++ b/history/README.urpmi diff --git a/doc/README.userchange b/history/README.userchange index f6cc0ab0666..f6cc0ab0666 100644 --- a/doc/README.userchange +++ b/history/README.userchange diff --git a/tools/change-loglevel.sh b/history/change-loglevel.sh index 88c8c1d0fe0..88c8c1d0fe0 100755 --- a/tools/change-loglevel.sh +++ b/history/change-loglevel.sh diff --git a/doc/tests/check_profile_l10n_all.py b/history/check_profile_l10n_all.py index 719d5ce051b..719d5ce051b 100644 --- a/doc/tests/check_profile_l10n_all.py +++ b/history/check_profile_l10n_all.py diff --git a/sql/clean-model.sql b/history/clean-model.sql index 59b492aab2d..59b492aab2d 100644 --- a/sql/clean-model.sql +++ b/history/clean-model.sql diff --git a/tools/gen_graph.sh b/history/gen_graph.sh index b052528eef4..b052528eef4 100755 --- a/tools/gen_graph.sh +++ b/history/gen_graph.sh diff --git a/tools/get-srvstats.sh b/history/get-srvstats.sh index 931d575858a..931d575858a 100755 --- a/tools/get-srvstats.sh +++ b/history/get-srvstats.sh diff --git a/tools/list-services.sh b/history/list-services.sh index a90e58479d5..a90e58479d5 100755 --- a/tools/list-services.sh +++ b/history/list-services.sh diff --git a/doc/migrate/3.3.0-3.4.0/README b/history/migrate/3.3.0-3.4.0/README index 10cf834af0e..10cf834af0e 100644 --- a/doc/migrate/3.3.0-3.4.0/README +++ b/history/migrate/3.3.0-3.4.0/README diff --git a/doc/migrate/3.3.0-3.4.0/post.py b/history/migrate/3.3.0-3.4.0/post.py index bdbd719116b..bdbd719116b 100644 --- a/doc/migrate/3.3.0-3.4.0/post.py +++ b/history/migrate/3.3.0-3.4.0/post.py diff --git a/doc/migrate/3.3.0-3.4.0/pre.py b/history/migrate/3.3.0-3.4.0/pre.py index db8ec6ddfcc..db8ec6ddfcc 100644 --- a/doc/migrate/3.3.0-3.4.0/pre.py +++ b/history/migrate/3.3.0-3.4.0/pre.py diff --git a/doc/migrate/3.4.0-4.0.0/README b/history/migrate/3.4.0-4.0.0/README index 6f8d73d9520..6f8d73d9520 100644 --- a/doc/migrate/3.4.0-4.0.0/README +++ b/history/migrate/3.4.0-4.0.0/README diff --git a/doc/migrate/3.4.0-4.0.0/post-tiny.py b/history/migrate/3.4.0-4.0.0/post-tiny.py index f4d299f3763..f4d299f3763 100644 --- a/doc/migrate/3.4.0-4.0.0/post-tiny.py +++ b/history/migrate/3.4.0-4.0.0/post-tiny.py diff --git a/doc/migrate/3.4.0-4.0.0/post.py b/history/migrate/3.4.0-4.0.0/post.py index 2abb06dd6f9..2abb06dd6f9 100644 --- a/doc/migrate/3.4.0-4.0.0/post.py +++ b/history/migrate/3.4.0-4.0.0/post.py diff --git a/doc/migrate/3.4.0-4.0.0/pre-tiny.py b/history/migrate/3.4.0-4.0.0/pre-tiny.py index 1001957e719..1001957e719 100644 --- a/doc/migrate/3.4.0-4.0.0/pre-tiny.py +++ b/history/migrate/3.4.0-4.0.0/pre-tiny.py diff --git a/doc/migrate/3.4.0-4.0.0/pre.py b/history/migrate/3.4.0-4.0.0/pre.py index 3e9f2bbf2d4..3e9f2bbf2d4 100644 --- a/doc/migrate/3.4.0-4.0.0/pre.py +++ b/history/migrate/3.4.0-4.0.0/pre.py diff --git a/doc/migrate/4.0.0-4.2.0/pre.py b/history/migrate/4.0.0-4.2.0/pre.py index a8080ee9a2a..a8080ee9a2a 100644 --- a/doc/migrate/4.0.0-4.2.0/pre.py +++ b/history/migrate/4.0.0-4.2.0/pre.py diff --git a/doc/migrate/4.0.0-4.2.0/tiny/README b/history/migrate/4.0.0-4.2.0/tiny/README index 36f129050d0..36f129050d0 100644 --- a/doc/migrate/4.0.0-4.2.0/tiny/README +++ b/history/migrate/4.0.0-4.2.0/tiny/README diff --git a/doc/migrate/4.0.0-4.2.0/tiny/pre-tiny.py b/history/migrate/4.0.0-4.2.0/tiny/pre-tiny.py index f2485a24100..f2485a24100 100644 --- a/doc/migrate/4.0.0-4.2.0/tiny/pre-tiny.py +++ b/history/migrate/4.0.0-4.2.0/tiny/pre-tiny.py diff --git a/doc/migrate/4.2.0-4.4.0/pre.py b/history/migrate/4.2.0-4.4.0/pre.py index 5c4598274e5..5c4598274e5 100644 --- a/doc/migrate/4.2.0-4.4.0/pre.py +++ b/history/migrate/4.2.0-4.4.0/pre.py diff --git a/tools/module_graph.py b/history/module_graph.py index b29bd316e2f..b29bd316e2f 100755 --- a/tools/module_graph.py +++ b/history/module_graph.py diff --git a/tools/xml2yml.py b/history/xml2yml.py index e926ddf5f94..e926ddf5f94 100755 --- a/tools/xml2yml.py +++ b/history/xml2yml.py diff --git a/pixmaps/openerp-header.bmp b/install/openerp-header.bmp Binary files differindex 61226b99ad7..61226b99ad7 100644 --- a/pixmaps/openerp-header.bmp +++ b/install/openerp-header.bmp diff --git a/pixmaps/openerp-header.png b/install/openerp-header.png Binary files differindex 22c1df45aee..22c1df45aee 100644 --- a/pixmaps/openerp-header.png +++ b/install/openerp-header.png diff --git a/pixmaps/openerp-icon.ico b/install/openerp-icon.ico Binary files differindex 89ed393f7cc..89ed393f7cc 100644 --- a/pixmaps/openerp-icon.ico +++ b/install/openerp-icon.ico diff --git a/pixmaps/openerp-icon.png b/install/openerp-icon.png Binary files differindex 9057d12d51e..9057d12d51e 100644 --- a/pixmaps/openerp-icon.png +++ b/install/openerp-icon.png diff --git a/man/openerp-server.1 b/install/openerp-server.1 index 58ac6f324f1..58ac6f324f1 100644 --- a/man/openerp-server.1 +++ b/install/openerp-server.1 diff --git a/install/openerp-server.conf b/install/openerp-server.conf new file mode 100644 index 00000000000..ead261e5218 --- /dev/null +++ b/install/openerp-server.conf @@ -0,0 +1,7 @@ +[options] +; This is the password that allows database operations: +; admin_passwd = admin +db_host = False +db_port = False +db_user = openerp +db_password = False diff --git a/doc/openerp-server.init b/install/openerp-server.init index 41efb5c35ce..41efb5c35ce 100644 --- a/doc/openerp-server.init +++ b/install/openerp-server.init diff --git a/doc/openerp-server.logrotate b/install/openerp-server.logrotate index e1f7f803a7d..e1f7f803a7d 100644 --- a/doc/openerp-server.logrotate +++ b/install/openerp-server.logrotate diff --git a/pixmaps/openerp.ico b/install/openerp.ico Binary files differindex cde3e961e79..cde3e961e79 100644 --- a/pixmaps/openerp.ico +++ b/install/openerp.ico diff --git a/pixmaps/openerp.png b/install/openerp.png Binary files differindex 20da496413b..20da496413b 100644 --- a/pixmaps/openerp.png +++ b/install/openerp.png diff --git a/man/openerp_serverrc.5 b/install/openerp_serverrc.5 index e43f9b5a668..e43f9b5a668 100644 --- a/man/openerp_serverrc.5 +++ b/install/openerp_serverrc.5 diff --git a/ssl-cert.cfg b/install/ssl-cert.cfg index 08ca7b5757e..08ca7b5757e 100644 --- a/ssl-cert.cfg +++ b/install/ssl-cert.cfg diff --git a/openerp-server b/openerp-server index dbae1c31884..52ad49104b1 100755 --- a/openerp-server +++ b/openerp-server @@ -27,7 +27,7 @@ OpenERP is an ERP+CRM program for small and medium businesses. The whole source code is distributed under the terms of the GNU Public Licence. -(c) 2003-TODAY, Fabien Pinckaers - OpenERP s.a. +(c) 2003-TODAY, Fabien Pinckaers - OpenERP SA """ import logging @@ -88,19 +88,27 @@ def setup_pid_file(): def preload_registry(dbname): """ Preload a registry, and start the cron.""" - db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) - pool.get('ir.cron').restart(db.dbname) + try: + db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) + + # jobs will start to be processed later, when openerp.cron.start_master_thread() is called by openerp.service.start_services() + registry.schedule_cron_jobs() + except Exception: + logging.exception('Failed to initialize database `%s`.', dbname) def run_test_file(dbname, test_file): """ Preload a registry, possibly run a test file, and start the cron.""" - db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) + try: + db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False) + cr = db.cursor() + logger = logging.getLogger('server') + logger.info('loading test file %s', test_file) + openerp.tools.convert_yaml_import(cr, 'base', file(test_file), {}, 'test', True) + cr.rollback() + cr.close() + except Exception: + logging.exception('Failed to initialize database `%s` and run test file `%s`.', dbname, test_file) - cr = db.cursor() - logger = logging.getLogger('server') - logger.info('loading test file %s', test_file) - openerp.tools.convert_yaml_import(cr, 'base', file(test_file), {}, 'test', True) - cr.rollback() - cr.close() def export_translation(): config = openerp.tools.config @@ -136,27 +144,6 @@ def import_translation(): cr.commit() cr.close() -def start_services(): - http_server = openerp.service.http_server - netrpc_server = openerp.service.netrpc_server - - # Instantiate local services (this is a legacy design). - openerp.osv.osv.start_object_proxy() - # Export (for RPC) services. - openerp.service.web_services.start_web_services() - - # Initialize the HTTP stack. - http_server.init_servers() - http_server.init_xmlrpc() - http_server.init_static_http() - netrpc_server.init_servers() - - # Start the main cron thread. - openerp.netsvc.start_agent() - - # Start the top-level servers threads (normally HTTP, HTTPS, and NETRPC). - openerp.netsvc.Server.startAll() - # Variable keeping track of the number of calls to the signal handler defined # below. This variable is monitored by ``quit_on_signals()``. quit_signals_received = 0 @@ -208,30 +195,16 @@ def quit_on_signals(): while quit_signals_received == 0: time.sleep(60) - openerp.netsvc.Agent.quit() - openerp.netsvc.Server.quitAll() - config = openerp.tools.config if config['pidfile']: os.unlink(config['pidfile']) - logger = logging.getLogger('server') - logger.info("Initiating shutdown") - logger.info("Hit CTRL-C again or send a second signal to force the sutdown.") - logging.shutdown() - - # manually join() all threads before calling sys.exit() to allow a second signal - # to trigger _force_quit() in case some non-daemon threads won't exit cleanly. - # threading.Thread.join() should not mask signals (at least in python 2.5) - for thread in threading.enumerate(): - if thread != threading.currentThread() and not thread.isDaemon(): - while thread.isAlive(): - # need a busyloop here as thread.join() masks signals - # and would present the forced shutdown - thread.join(0.05) - time.sleep(0.05) + + openerp.service.stop_services() sys.exit(0) if __name__ == "__main__": + os.environ["TZ"] = "UTC" + check_root_user() openerp.tools.config.parse_config(sys.argv[1:]) check_postgres_user() @@ -240,6 +213,8 @@ if __name__ == "__main__": config = openerp.tools.config + setup_signal_handlers() + if config["test_file"]: run_test_file(config['db_name'], config['test_file']) sys.exit(0) @@ -255,7 +230,7 @@ if __name__ == "__main__": if not config["stop_after_init"]: # Some module register themselves when they are loaded so we need the # services to be running before loading any registry. - start_services() + openerp.service.start_services() if config['db_name']: for dbname in config['db_name'].split(','): @@ -264,8 +239,17 @@ if __name__ == "__main__": if config["stop_after_init"]: sys.exit(0) + for m in openerp.conf.server_wide_modules: + try: + __import__(m) + # Call any post_load hook. + info = openerp.modules.module.load_information_from_description_file(m) + if info['post_load']: + getattr(sys.modules[m], info['post_load'])() + except Exception: + logging.exception('Failed to load server-wide module `%s`', m) + setup_pid_file() - setup_signal_handlers() logger = logging.getLogger('server') logger.info('OpenERP server is running, waiting for connections...') quit_on_signals() diff --git a/openerp/__init__.py b/openerp/__init__.py index b7b5fc1b533..7e723c41f9d 100644 --- a/openerp/__init__.py +++ b/openerp/__init__.py @@ -22,6 +22,8 @@ """ OpenERP core library. """ +# The hard-coded super-user id (a.k.a. administrator, or root user). +SUPERUSER_ID = 1 import addons import conf @@ -41,6 +43,7 @@ import tiny_socket import tools import wizard import workflow +import wsgi # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/__init__.py b/openerp/addons/__init__.py index 88a0d113151..1f863eca509 100644 --- a/openerp/addons/__init__.py +++ b/openerp/addons/__init__.py @@ -22,10 +22,15 @@ """ Addons module. -This module only serves to contain OpenERP addons. For the code to -manage those addons, see openerp.modules. This module conveniently -reexports some symbols from openerp.modules. Importing them from here -is deprecated. +This module serves to contain all OpenERP addons, across all configured addons +paths. For the code to manage those addons, see openerp.modules. + +Addons are made available here (i.e. under openerp.addons) after +openerp.tools.config.parse_config() is called (so that the addons paths +are known). + +This module also conveniently reexports some symbols from openerp.modules. +Importing them from here is deprecated. """ diff --git a/openerp/addons/base/__init__.py b/openerp/addons/base/__init__.py index 847bef71f8c..16a61521fb4 100644 --- a/openerp/addons/base/__init__.py +++ b/openerp/addons/base/__init__.py @@ -24,6 +24,7 @@ import module import res import publisher_warranty import report +import test # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index 37f26edc177..e436a0a6005 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -67,7 +67,7 @@ 'res/res_currency_view.xml', 'res/res_partner_event_view.xml', 'res/wizard/partner_sms_send_view.xml', - 'res/wizard/partner_wizard_spam_view.xml', + 'res/wizard/partner_wizard_massmail_view.xml', 'res/wizard/partner_clear_ids_view.xml', 'res/wizard/partner_wizard_ean_check_view.xml', 'res/res_partner_data.xml', @@ -92,6 +92,10 @@ 'test/test_osv_expression.yml', 'test/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules. 'test/test_ir_values.yml', + # Commented because this takes some time. + # This must be (un)commented with the corresponding import statement + # in test/__init__.py. + # 'test/test_ir_cron.yml', # <-- These tests perform a roolback. ], 'installable': True, 'active': True, diff --git a/openerp/addons/base/base.sql b/openerp/addons/base/base.sql index 54dcc3a55ae..55c4d41aba5 100644 --- a/openerp/addons/base/base.sql +++ b/openerp/addons/base/base.sql @@ -290,6 +290,7 @@ CREATE TABLE ir_module_module ( state character varying(16), latest_version character varying(64), shortdesc character varying(256), + complexity character varying(32), category_id integer REFERENCES ir_module_category ON DELETE SET NULL, certificate character varying(64), description text, diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml index 00fb83a0796..feaac206723 100644 --- a/openerp/addons/base/base_data.xml +++ b/openerp/addons/base/base_data.xml @@ -1002,7 +1002,7 @@ </record> <record id="main_partner" model="res.partner"> - <field name="name">OpenERP S.A.</field> + <field name="name">Your Company</field> <!-- Address and Company ID will be set later --> <field name="address" eval="[]"/> <field name="company_id" eval="None"/> @@ -1010,14 +1010,7 @@ </record> <record id="main_address" model="res.partner.address"> <field name="partner_id" ref="main_partner"/> - <field name="name">Fabien Pinckaers</field> - <field name="street">Chaussee de Namur 40</field> - <field name="zip">1367</field> - <field name="city">Gerompont</field> - <field name="phone">(+32).81.81.37.00</field> <field name="type">default</field> - <field model="res.country" name="country_id" ref="be"/> - <!-- Company ID will be set later --> <field name="company_id" eval="None"/> </record> @@ -1038,19 +1031,14 @@ <!-- Basic Company --> <record id="main_company" model="res.company"> - <field name="name">OpenERP S.A.</field> + <field name="name">Your Company</field> <field name="partner_id" ref="main_partner"/> - <field name="rml_header1">Free Business Solutions</field> - <field name="rml_footer1">Web: http://www.openerp.com - Tel: (+32).81.81.37.00 - Bank: CPH 126-2013269-07</field> - <field name="rml_footer2">IBAN: BE74 1262 0132 6907 - SWIFT: CPHBBE75 - VAT: BE0477.472.701</field> + <field name="rml_header1">Company business slogan</field> + <field name="rml_footer1">Web: www.companyname.com - Tel: +1-212-555-12345</field> + <field name="rml_footer2">IBAN: XX12 3456 7890 1234 5678 - SWIFT: SWIFTCODE - VAT: Company vat number</field> <field name="currency_id" ref="base.EUR"/> </record> - <assert id="main_company" model="res.company"> - <test expr="currency_id.name == 'eur'.upper()"/> - <test expr="name">OpenERP S.A.</test> - </assert> - <record model="res.users" id="base.user_root"> <field name="signature">Administrator</field> <field name="company_id" ref="main_company"/> @@ -1086,16 +1074,17 @@ <field eval="time.strftime('%Y-01-01')" name="name"/> </record> - <record id="VEB" model="res.currency"> - <field name="name">VEB</field> - <field name="symbol">Bs</field> - <field name="rounding">2.95</field> + <!-- VEF was previously VEB --> + <record id="VEF" model="res.currency"> + <field name="name">VEF</field> + <field name="symbol">Bs.F</field> + <field name="rounding">0.0001</field> <field name="accuracy">4</field> <field name="company_id" ref="main_company"/> </record> - <record id="rateVEB" model="res.currency.rate"> - <field name="rate">2768.45</field> - <field name="currency_id" ref="VEB"/> + <record id="rateVEF" model="res.currency.rate"> + <field name="rate">5.864</field> + <field name="currency_id" ref="VEF"/> <field eval="time.strftime('%Y-01-01')" name="name"/> </record> @@ -1599,12 +1588,20 @@ <field name="rounding">0.01</field> <field name="accuracy">4</field> <field name="symbol">¢</field> + <field name="company_id" ref="main_company"/> </record> <record id="rateCRC" model="res.currency.rate"> <field name="rate">691.3153</field> <field name="currency_id" ref="CRC"/> <field eval="time.strftime('%Y-01-01')" name="name"/> - </record> + </record> + + <record id="ir_mail_server_localhost0" model="ir.mail_server"> + <field name="name">localhost</field> + <field name="smtp_host">localhost</field> + <field eval="25" name="smtp_port"/> + <field eval="10" name="priority"/> + </record> <record id="MUR" model="res.currency"> <field name="name">MUR</field> diff --git a/openerp/addons/base/base_update.xml b/openerp/addons/base/base_update.xml index b87c0ef4382..26f971b8334 100644 --- a/openerp/addons/base/base_update.xml +++ b/openerp/addons/base/base_update.xml @@ -75,29 +75,29 @@ --> <record id="view_users_form_simple_modif" model="ir.ui.view"> - <field name="name">res.users.form.modif</field> + <field name="name">res.users.preferences.form</field> <field name="model">res.users</field> <field name="type">form</field> <field eval="18" name="priority"/> <field name="arch" type="xml"> <form string="Users"> - <field name="name"/> + <field name="name" readonly="1"/> <newline/> <group colspan="2" col="2"> <separator string="Preferences" colspan="2"/> - <field name="view"/> - <field name="context_lang"/> - <field name="context_tz"/> - <field name="menu_tips"/> + <field name="view" readonly="0"/> + <field name="context_lang" readonly="0"/> + <field name="context_tz" readonly="0"/> + <field name="menu_tips" readonly="0"/> </group> <group name="default_filters" colspan="2" col="2"> <separator string="Default Filters" colspan="2"/> - <field name="company_id" widget="selection" + <field name="company_id" widget="selection" readonly="0" groups="base.group_multi_company" on_change="on_change_company_id(company_id)"/> </group> <separator string="Email Preferences" colspan="4"/> - <field colspan="4" name="user_email" widget="email"/> - <field colspan="4" name="signature"/> + <field colspan="4" name="user_email" widget="email" readonly="0"/> + <field colspan="4" name="signature" readonly="0"/> </form> </field> </record> @@ -147,7 +147,7 @@ <page string="Access Rights"> <field nolabel="1" name="groups_id"/> </page> - <page string="Companies" groups="base.group_multi_company"> + <page string="Allowed Companies" groups="base.group_multi_company"> <field colspan="4" nolabel="1" name="company_ids" select="1"/> </page> </notebook> @@ -196,7 +196,7 @@ <field name="view_type">form</field> <field name="view_mode">tree,form</field> <field name="context" eval="{'default_partner_id':ref('base.main_partner'), 'company_hide':False, 'default_company_id':ref('base.main_company'), 'search_default_my_bank':1}"/> - <field name="help">Configure your company's bank account and select those that must appear on the report footer. You can drag & drop bank in the list view to reorder bank accounts. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data.</field> + <field name="help">Configure your company's bank account and select those that must appear on the report footer. You can reorder bank accounts from the list view. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data.</field> </record> @@ -209,7 +209,7 @@ <group colspan="4" col="6"> <group colspan="4" col="4"> <field name="name"/> - <field name="partner_id" readonly="1" required="0"/> + <field name="partner_id" readonly="1" required="0" groups="base.group_extended"/> <field name="parent_id" groups="base.group_multi_company"/> </group> <group colspan="2" col="2"> @@ -225,18 +225,17 @@ <field name="city"/> <field name="country_id"/> <field name="state_id"/> - <field name="phone"/> - <field name="email"/> - <field name="fax"/> - <field name="website"/> - <field name="vat"/> - <field name="company_registry"/> + <field name="phone" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="email" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="fax" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="website" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="vat" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> + <field name="company_registry" on_change="on_change_header(phone, email, fax, website, vat, company_registry)"/> <separator string="Header/Footer of Reports" colspan="4"/> <group colspan="4" col="3"> <field name="rml_header1" colspan="3"/> <newline/> - <field name="rml_footer1" colspan="2"/> - <button name="generate_header" string="Generate" type="object" icon="gtk-go-forward"/> + <field name="rml_footer1" colspan="3" groups="base.group_extended"/> <newline/> <field name="rml_footer2" colspan="2"/> <button name="%(bank_account_update)d" string="Set Bank Accounts" type="action" icon="gtk-go-forward"/> @@ -245,10 +244,10 @@ <button name="%(preview_report)d" string="Preview Header" type="action" icon="gtk-print"/> </group> </page> - <page string="External Template" groups="base.group_extended"> + <page string="Header/Footer" groups="base.group_extended"> <field colspan="4" name="rml_header" nolabel="1"/> </page> - <page string="Internal Template" groups="base.group_extended"> + <page string="Internal Header/Footer" groups="base.group_extended"> <separator string="Portrait" colspan="2"/> <separator string="Landscape" colspan="2"/> <field colspan="2" name="rml_header2" nolabel="1"/> diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po index 72547d34bc1..3c5d2fb0117 100644 --- a/openerp/addons/base/i18n/af.po +++ b/openerp/addons/base/i18n/af.po @@ -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: 2011-09-01 04:38+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:00+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po index 7fa923c0660..3e4289b0e47 100644 --- a/openerp/addons/base/i18n/am.po +++ b/openerp/addons/base/i18n/am.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:00+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po index b50c02ca98d..d11ff8d8dea 100644 --- a/openerp/addons/base/i18n/ar.po +++ b/openerp/addons/base/i18n/ar.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5430,7 +5430,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/base.pot b/openerp/addons/base/i18n/base.pot index 9484a376151..55c648f89af 100644 --- a/openerp/addons/base/i18n/base.pot +++ b/openerp/addons/base/i18n/base.pot @@ -5217,7 +5217,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po index 02da984c8b3..faaa8231ca2 100644 --- a/openerp/addons/base/i18n/bg.po +++ b/openerp/addons/base/i18n/bg.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-16 08:59+0000\n" +"PO-Revision-Date: 2011-09-30 20:32+0000\n" "Last-Translator: Boris <boris.t.ivanov@gmail.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5572,7 +5572,7 @@ msgstr "Преводи" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Брой на остъпката" #. module: base @@ -9421,3 +9421,6 @@ msgstr "Шри Ланка" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "руски / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Брой на остъпката" diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po index 80691631cf8..8ac67468fac 100644 --- a/openerp/addons/base/i18n/bs.po +++ b/openerp/addons/base/i18n/bs.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5439,7 +5439,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po index 58c927285eb..a0ff5259435 100644 --- a/openerp/addons/base/i18n/ca.po +++ b/openerp/addons/base/i18n/ca.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-25 10:50+0000\n" -"Last-Translator: Esther Xaus (Zikzakmedia) <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:08+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5709,7 +5709,7 @@ msgstr "Traduccions" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Omplenat del número" #. module: base @@ -9665,3 +9665,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Rus / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Omplenat del número" diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po index 5161c860eb2..160cf68e8eb 100644 --- a/openerp/addons/base/i18n/cs.po +++ b/openerp/addons/base/i18n/cs.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-08-13 17:34+0000\n" +"PO-Revision-Date: 2011-09-30 21:07+0000\n" "Last-Translator: Jiří Hajda <robie@centrum.cz>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" "X-Poedit-Language: Czech\n" #. module: base @@ -174,7 +174,7 @@ msgstr "ir.ui.view.custom" #. module: base #: model:res.country,name:base.sz msgid "Swaziland" -msgstr "Švýcarsko" +msgstr "Svazijsko" #. module: base #: code:addons/orm.py:1993 @@ -885,7 +885,7 @@ msgstr "Znak" #: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form #: model:ir.ui.menu,name:base.menu_publisher_warranty_contract msgid "Contracts" -msgstr "Kontakty" +msgstr "Smlouvy" #. module: base #: selection:base.language.install,lang:0 @@ -1876,7 +1876,7 @@ msgstr "Slovinsko" #. module: base #: model:res.country,name:base.pk msgid "Pakistan" -msgstr "Pakistán" +msgstr "Pákistán" #. module: base #: code:addons/orm.py:1350 @@ -3532,7 +3532,7 @@ msgstr "Pobřeží slonoviny (Cote D'Ivoire)" #. module: base #: model:res.country,name:base.kz msgid "Kazakhstan" -msgstr "Kazakstán" +msgstr "Kazachstán" #. module: base #: view:res.lang:0 @@ -3812,7 +3812,7 @@ msgstr "" #. module: base #: view:publisher_warranty.contract.wizard:0 msgid "Please enter the serial key provided in your contract document:" -msgstr "Prosíme zadejte sériové číslo poskytnuté ve dokumentu vaší smlouvy:" +msgstr "Prosíme zadejte sériové číslo poskytnuté v dokumentu vaší smlouvy:" #. module: base #: view:workflow.activity:0 @@ -3896,7 +3896,7 @@ msgstr "Měsíc" #. module: base #: model:res.country,name:base.my msgid "Malaysia" -msgstr "Malaysie" +msgstr "Malajsie" #. module: base #: view:base.language.install:0 @@ -3971,7 +3971,7 @@ msgstr "Neplatné ID pro záznam procházení, máme %r, očekáván integer." #: model:ir.actions.act_window,name:base.action_partner_addess_tree #: view:res.partner:0 msgid "Partner Contacts" -msgstr "Kontakty společníka" +msgstr "Kontakty partnera" #. module: base #: field:base.module.update,add:0 @@ -4059,7 +4059,7 @@ msgstr "Pravidlo musí mít alespoň jedno aktivní přístupové právo !" #. module: base #: model:res.country,name:base.fj msgid "Fiji" -msgstr "Fiji" +msgstr "Fidži" #. module: base #: field:ir.model.fields,size:0 @@ -4069,7 +4069,7 @@ msgstr "Velikost" #. module: base #: model:res.country,name:base.sd msgid "Sudan" -msgstr "Sudan" +msgstr "Súdán" #. module: base #: model:res.country,name:base.fm @@ -4118,7 +4118,7 @@ msgstr "Formát času" #. module: base #: view:ir.module.module:0 msgid "Defined Reports" -msgstr "Definoavné výkazy" +msgstr "Definované výkazy" #. module: base #: view:ir.actions.report.xml:0 @@ -4617,7 +4617,7 @@ msgstr "Přístup k nabídce" #. module: base #: model:res.country,name:base.na msgid "Namibia" -msgstr "Nambie" +msgstr "Namibie" #. module: base #: model:res.country,name:base.mn @@ -4800,7 +4800,7 @@ msgstr "Adresy" #. module: base #: model:res.country,name:base.mm msgid "Myanmar" -msgstr "Barma" +msgstr "Myanmar" #. module: base #: selection:base.language.install,lang:0 @@ -5476,12 +5476,12 @@ msgstr "Globální" #. module: base #: model:res.country,name:base.mp msgid "Northern Mariana Islands" -msgstr "Severní Mariánské ostrovy" +msgstr "Severní Mariany" #. module: base #: model:res.country,name:base.sb msgid "Solomon Islands" -msgstr "Šalamounovy Ostrovy" +msgstr "Šalamounovy ostrovy" #. module: base #: code:addons/base/ir/ir_model.py:490 @@ -5529,7 +5529,7 @@ msgstr "Překlady" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Zarovnání čísla" #. module: base @@ -5682,7 +5682,7 @@ msgstr "Jazyk" #. module: base #: model:res.country,name:base.gm msgid "Gambia" -msgstr "Gambia" +msgstr "Gambie" #. module: base #: model:ir.actions.act_window,name:base.action_res_company_form @@ -6443,7 +6443,7 @@ msgstr "Mongolština / монгол" #. module: base #: model:res.country,name:base.mr msgid "Mauritania" -msgstr "Mauretánie" +msgstr "Mauritánie" #. module: base #: model:ir.model,name:base.model_ir_translation @@ -7379,7 +7379,7 @@ msgstr "Typ výkazu" #: field:workflow.instance,state:0 #: field:workflow.workitem,state:0 msgid "State" -msgstr "Stát" +msgstr "Stav" #. module: base #: selection:base.language.install,lang:0 @@ -7649,7 +7649,7 @@ msgstr "Změnit heslo" #. module: base #: model:res.country,name:base.nl msgid "Netherlands" -msgstr "Nizozemí" +msgstr "Nizozemsko" #. module: base #: model:ir.ui.menu,name:base.next_id_4 @@ -8137,7 +8137,7 @@ msgstr "Asociace" #. module: base #: model:res.country,name:base.cl msgid "Chile" -msgstr "Čile" +msgstr "Chile" #. module: base #: model:ir.ui.menu,name:base.menu_address_book @@ -8185,7 +8185,7 @@ msgstr "Popisek pole" #. module: base #: model:res.country,name:base.dj msgid "Djibouti" -msgstr "Djibouti" +msgstr "Džibutsko" #. module: base #: field:ir.translation,value:0 @@ -8364,7 +8364,7 @@ msgstr "Chyba" #. module: base #: model:res.country,name:base.pm msgid "Saint Pierre and Miquelon" -msgstr "Saint Pierre a Miquelon" +msgstr "Svatý Pierre a Miquelon" #. module: base #: help:ir.actions.report.xml,header:0 @@ -8540,7 +8540,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sa msgid "Saudi Arabia" -msgstr "Saudská Arábie" +msgstr "Saúdská Arábie" #. module: base #: help:res.partner,supplier:0 @@ -8637,7 +8637,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sv msgid "El Salvador" -msgstr "El Salvador" +msgstr "Salvador" #. module: base #: field:res.bank,phone:0 @@ -8937,7 +8937,7 @@ msgstr "Pracovní postup, který má být spuštěn pro tento model." #. module: base #: model:res.country,name:base.jm msgid "Jamaica" -msgstr "Jamaika" +msgstr "Jamajka" #. module: base #: model:ir.actions.act_window,help:base.action_partner_category_form @@ -9407,3 +9407,6 @@ msgstr "Srí Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ruština / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Zarovnání čísla" diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po index da07b07a1e9..d8cb77ac991 100644 --- a/openerp/addons/base/i18n/da.po +++ b/openerp/addons/base/i18n/da.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-02-07 05:09+0000\n" -"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n" +"PO-Revision-Date: 2011-09-24 16:40+0000\n" +"Last-Translator: John Mertens Pallesen <Unknown>\n" "Language-Team: Danish <da@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -141,7 +141,7 @@ msgstr "" #: code:addons/base/res/res_user.py:507 #, python-format msgid "Warning!" -msgstr "" +msgstr "Advarsel!" #. module: base #: code:addons/base/ir/ir_model.py:304 @@ -196,7 +196,7 @@ msgstr "" #: model:ir.actions.act_window,name:base.action_res_company_tree #: model:ir.ui.menu,name:base.menu_action_res_company_tree msgid "Company's Structure" -msgstr "" +msgstr "Virksomhedens struktur" #. module: base #: selection:base.language.install,lang:0 @@ -277,7 +277,7 @@ msgstr "" #. module: base #: field:res.partner,credit_limit:0 msgid "Credit Limit" -msgstr "" +msgstr "Kreditgrænse" #. module: base #: field:ir.model.data,date_update:0 @@ -372,7 +372,7 @@ msgstr "Fransk Guyana" #. module: base #: selection:base.language.install,lang:0 msgid "Greek / Ελληνικά" -msgstr "" +msgstr "Græsk / Greek" #. module: base #: selection:base.language.install,lang:0 @@ -483,7 +483,7 @@ msgstr "" #. module: base #: view:res.config.users:0 msgid "New User" -msgstr "" +msgstr "Ny bruger" #. module: base #: view:base.language.export:0 @@ -525,7 +525,7 @@ msgstr "Eritrea" #: view:res.config:0 #: view:res.config.installer:0 msgid "description" -msgstr "" +msgstr "Beskrivelse" #. module: base #: model:ir.ui.menu,name:base.menu_base_action_rule @@ -563,7 +563,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Swedish / svenska" -msgstr "" +msgstr "Svensk / Swedish" #. module: base #: model:res.country,name:base.rs @@ -601,7 +601,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Albanian / Shqip" -msgstr "" +msgstr "Albanien" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_opportunity @@ -641,7 +641,7 @@ msgstr "Mine partnere" #. module: base #: view:ir.actions.report.xml:0 msgid "XML Report" -msgstr "" +msgstr "XML rapport" #. module: base #: model:res.country,name:base.es @@ -651,7 +651,7 @@ msgstr "Spanien" #. module: base #: model:ir.ui.menu,name:base.menu_translation_export msgid "Import / Export" -msgstr "" +msgstr "Import / Eksport" #. module: base #: help:ir.actions.act_window,domain:0 @@ -681,7 +681,7 @@ msgstr "" #: field:res.partner,mobile:0 #: field:res.partner.address,mobile:0 msgid "Mobile" -msgstr "" +msgstr "Mobil" #. module: base #: model:res.country,name:base.om @@ -692,7 +692,7 @@ msgstr "Oman" #: model:ir.actions.act_window,name:base.action_payterm_form #: model:ir.model,name:base.model_res_payterm msgid "Payment term" -msgstr "" +msgstr "Betalingsbetingelse" #. module: base #: model:res.country,name:base.nu @@ -859,7 +859,7 @@ msgstr "" #: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form #: model:ir.ui.menu,name:base.menu_publisher_warranty_contract msgid "Contracts" -msgstr "" +msgstr "Kontrakter" #. module: base #: selection:base.language.install,lang:0 @@ -884,12 +884,12 @@ msgstr "Niger" #. module: base #: selection:base.language.install,lang:0 msgid "Chinese (HK)" -msgstr "" +msgstr "Kinesisk (HK)" #. module: base #: model:res.country,name:base.ba msgid "Bosnia-Herzegovina" -msgstr "" +msgstr "Bosnien-Hercegovina" #. module: base #: view:base.language.export:0 @@ -931,7 +931,7 @@ msgstr "" #. module: base #: field:base.module.import,module_name:0 msgid "Module Name" -msgstr "" +msgstr "Modulnavn" #. module: base #: model:res.country,name:base.mh @@ -990,7 +990,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_hr_dasboard msgid "Dashboard" -msgstr "" +msgstr "Oversigt" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root @@ -1011,7 +1011,7 @@ msgstr "Funktioner" #: view:ir.module.module:0 #: report:ir.module.reference.graph:0 msgid "Version" -msgstr "" +msgstr "Version" #. module: base #: view:ir.model.access:0 @@ -1382,7 +1382,7 @@ msgstr "" #. module: base #: model:res.country,name:base.fi msgid "Finland" -msgstr "" +msgstr "Finland" #. module: base #: selection:ir.actions.act_window,view_type:0 @@ -1407,7 +1407,7 @@ msgstr "" #. module: base #: view:base.language.export:0 msgid "https://help.launchpad.net/Translations" -msgstr "" +msgstr "https://help.launchpad.net/Translations" #. module: base #: field:ir.actions.act_window,view_mode:0 @@ -1430,7 +1430,7 @@ msgstr "" #. module: base #: view:res.log:0 msgid "Logs" -msgstr "" +msgstr "Logfiler" #. module: base #: selection:base.language.install,lang:0 @@ -1613,7 +1613,7 @@ msgstr "" #: selection:ir.translation,type:0 #: field:multi_company.default,field_id:0 msgid "Field" -msgstr "" +msgstr "Felt" #. module: base #: view:ir.rule:0 @@ -1623,14 +1623,14 @@ msgstr "" #. module: base #: model:res.country,name:base.fo msgid "Faroe Islands" -msgstr "" +msgstr "Færøerne" #. module: base #: selection:res.config.users,view:0 #: selection:res.config.view,view:0 #: selection:res.users,view:0 msgid "Simplified" -msgstr "" +msgstr "Forenklet" #. module: base #: model:res.country,name:base.st @@ -1640,7 +1640,7 @@ msgstr "" #. module: base #: selection:res.partner.address,type:0 msgid "Invoice" -msgstr "" +msgstr "Faktura" #. module: base #: selection:base.language.install,lang:0 @@ -1650,12 +1650,12 @@ msgstr "" #. module: base #: model:res.country,name:base.bb msgid "Barbados" -msgstr "" +msgstr "Barbados" #. module: base #: model:res.country,name:base.mg msgid "Madagascar" -msgstr "" +msgstr "Madagaskar" #. module: base #: code:addons/base/ir/ir_model.py:96 @@ -1674,12 +1674,12 @@ msgstr "" #: view:ir.ui.menu:0 #: field:ir.ui.menu,name:0 msgid "Menu" -msgstr "" +msgstr "Menu" #. module: base #: field:res.currency,rate:0 msgid "Current Rate" -msgstr "" +msgstr "Aktuel kurs" #. module: base #: field:ir.ui.view.custom,ref_id:0 @@ -1721,7 +1721,7 @@ msgstr "" #. module: base #: model:res.country,name:base.zw msgid "Zimbabwe" -msgstr "" +msgstr "Zimbabwe" #. module: base #: view:base.module.update:0 @@ -1736,7 +1736,7 @@ msgstr "" #. module: base #: field:ir.actions.server,email:0 msgid "Email Address" -msgstr "" +msgstr "E-mail adresse" #. module: base #: selection:base.language.install,lang:0 @@ -1752,12 +1752,12 @@ msgstr "" #. module: base #: model:res.country,name:base.tt msgid "Trinidad and Tobago" -msgstr "" +msgstr "Trinidad og Tobago" #. module: base #: model:res.country,name:base.lv msgid "Latvia" -msgstr "" +msgstr "Letland" #. module: base #: view:ir.values:0 @@ -1782,7 +1782,7 @@ msgstr "" #. module: base #: model:res.country,name:base.py msgid "Paraguay" -msgstr "" +msgstr "Paraguay" #. module: base #: model:ir.model,name:base.model_ir_actions_act_window_close @@ -1797,7 +1797,7 @@ msgstr "" #. module: base #: model:res.country,name:base.lt msgid "Lithuania" -msgstr "" +msgstr "Litauen" #. module: base #: model:ir.actions.act_window,name:base.action_view_partner_clear_ids @@ -1827,12 +1827,12 @@ msgstr "" #. module: base #: model:res.country,name:base.si msgid "Slovenia" -msgstr "" +msgstr "Slovenien" #. module: base #: model:res.country,name:base.pk msgid "Pakistan" -msgstr "" +msgstr "Pakistan" #. module: base #: code:addons/orm.py:1350 @@ -1843,7 +1843,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_email_gateway_form msgid "Messages" -msgstr "" +msgstr "Meddelelser" #. module: base #: code:addons/base/ir/ir_model.py:303 @@ -1855,7 +1855,7 @@ msgstr "" #: code:addons/base/module/wizard/base_update_translations.py:38 #, python-format msgid "Error!" -msgstr "" +msgstr "Fejl!" #. module: base #: view:res.lang:0 @@ -1880,7 +1880,7 @@ msgstr "" #. module: base #: model:res.country,name:base.nz msgid "New Zealand" -msgstr "" +msgstr "New Zealand" #. module: base #: code:addons/orm.py:3366 @@ -1927,7 +1927,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bd msgid "Bangladesh" -msgstr "" +msgstr "Bangladesh" #. module: base #: constraint:res.company:0 @@ -1953,7 +1953,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cu msgid "Cuba" -msgstr "" +msgstr "Cuba" #. module: base #: model:ir.model,name:base.model_res_partner_event @@ -1963,12 +1963,12 @@ msgstr "" #. module: base #: model:res.widget,title:base.facebook_widget msgid "Facebook" -msgstr "" +msgstr "Facebook" #. module: base #: model:res.country,name:base.am msgid "Armenia" -msgstr "" +msgstr "Armenien" #. module: base #: model:ir.actions.act_window,name:base.ir_property_form @@ -1984,14 +1984,14 @@ msgstr "" #. module: base #: model:res.country,name:base.se msgid "Sweden" -msgstr "" +msgstr "Sverige" #. module: base #: selection:ir.actions.act_window.view,view_mode:0 #: selection:ir.ui.view,type:0 #: selection:wizard.ir.model.menu.create.line,view_type:0 msgid "Gantt" -msgstr "" +msgstr "Gantt" #. module: base #: view:ir.property:0 @@ -2002,7 +2002,7 @@ msgstr "" #: model:ir.model,name:base.model_res_partner_bank_type #: view:res.partner.bank.type:0 msgid "Bank Account Type" -msgstr "" +msgstr "Bank Kontotype" #. module: base #: field:base.language.export,config_logo:0 @@ -2019,7 +2019,7 @@ msgstr "" #: field:res.config.users,config_logo:0 #: field:res.config.view,config_logo:0 msgid "Image" -msgstr "" +msgstr "Billede" #. module: base #: view:ir.actions.server:0 @@ -2034,7 +2034,7 @@ msgstr "" #. module: base #: model:res.country,name:base.at msgid "Austria" -msgstr "" +msgstr "Østrig" #. module: base #: selection:base.language.install,state:0 @@ -2049,7 +2049,7 @@ msgstr "" #: selection:ir.ui.view,type:0 #: selection:wizard.ir.model.menu.create.line,view_type:0 msgid "Calendar" -msgstr "" +msgstr "Kalender" #. module: base #: field:res.partner.address,partner_id:0 @@ -2143,7 +2143,7 @@ msgstr "" #. module: base #: field:res.partner.address,birthdate:0 msgid "Birthdate" -msgstr "" +msgstr "Fødselsdato" #. module: base #: model:ir.actions.act_window,name:base.action_partner_title_contact @@ -2183,12 +2183,12 @@ msgstr "" #. module: base #: model:res.country,name:base.uy msgid "Uruguay" -msgstr "" +msgstr "Uruguay" #. module: base #: selection:base.language.install,lang:0 msgid "Finnish / Suomi" -msgstr "" +msgstr "Finsk / Suomi" #. module: base #: field:ir.rule,perm_write:0 @@ -2203,7 +2203,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "German / Deutsch" -msgstr "" +msgstr "Tysk / Deutsch" #. module: base #: help:ir.actions.server,trigger_name:0 @@ -2218,7 +2218,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Portugese / Português" -msgstr "" +msgstr "Portugisisk / Português" #. module: base #: model:res.partner.title,name:base.res_partner_title_sir @@ -2245,7 +2245,7 @@ msgstr "" #. module: base #: model:res.country,name:base.mt msgid "Malta" -msgstr "" +msgstr "Malta" #. module: base #: field:ir.actions.server,fields_lines:0 @@ -2261,7 +2261,7 @@ msgstr "" #: report:ir.module.reference.graph:0 #: field:ir.translation,module:0 msgid "Module" -msgstr "" +msgstr "Modul" #. module: base #: field:ir.attachment,description:0 @@ -2272,7 +2272,7 @@ msgstr "" #: field:res.partner.event,description:0 #: view:res.request:0 msgid "Description" -msgstr "" +msgstr "Beskrivelse" #. module: base #: model:ir.actions.act_window,name:base.action_workflow_instance_form @@ -2283,7 +2283,7 @@ msgstr "" #. module: base #: model:res.country,name:base.aq msgid "Antarctica" -msgstr "" +msgstr "Antarktis" #. module: base #: field:ir.actions.report.xml,auto:0 @@ -2336,7 +2336,7 @@ msgstr "" #. module: base #: view:res.payterm:0 msgid "Payment Term" -msgstr "" +msgstr "Betalingsbetingelse" #. module: base #: selection:res.lang,direction:0 @@ -2417,7 +2417,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ru msgid "Russian Federation" -msgstr "" +msgstr "Rusland" #. module: base #: selection:base.language.install,lang:0 @@ -2427,13 +2427,13 @@ msgstr "" #. module: base #: field:res.company,name:0 msgid "Company Name" -msgstr "" +msgstr "Virksomhedsnavn" #. module: base #: model:ir.actions.act_window,name:base.action_country #: model:ir.ui.menu,name:base.menu_country_partner msgid "Countries" -msgstr "" +msgstr "Lande" #. module: base #: selection:ir.translation,type:0 @@ -2448,7 +2448,7 @@ msgstr "" #. module: base #: view:ir.property:0 msgid "Field Information" -msgstr "" +msgstr "Feltinformation" #. module: base #: view:ir.actions.todo:0 @@ -2464,7 +2464,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 msgid "VAT" -msgstr "" +msgstr "Moms" #. module: base #: view:res.lang:0 @@ -2545,7 +2545,7 @@ msgstr "" #. module: base #: model:res.country,name:base.me msgid "Montenegro" -msgstr "" +msgstr "Montenegro" #. module: base #: view:ir.cron:0 @@ -2556,7 +2556,7 @@ msgstr "" #: view:res.partner:0 #: field:res.partner,category_id:0 msgid "Categories" -msgstr "" +msgstr "Kategorier" #. module: base #: view:base.language.import:0 @@ -2576,7 +2576,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ly msgid "Libya" -msgstr "" +msgstr "Libyen" #. module: base #: model:res.country,name:base.cf @@ -2586,18 +2586,18 @@ msgstr "" #. module: base #: model:res.country,name:base.li msgid "Liechtenstein" -msgstr "" +msgstr "Liechtenstein" #. module: base #: model:ir.model,name:base.model_partner_sms_send #: view:partner.sms.send:0 msgid "Send SMS" -msgstr "" +msgstr "Send SMS" #. module: base #: field:res.partner,ean13:0 msgid "EAN13" -msgstr "" +msgstr "EAN13" #. module: base #: code:addons/orm.py:1622 @@ -2608,7 +2608,7 @@ msgstr "" #. module: base #: model:res.country,name:base.pt msgid "Portugal" -msgstr "" +msgstr "Portugal" #. module: base #: sql_constraint:ir.model.data:0 @@ -2648,7 +2648,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_res_lang_act_window #: view:res.lang:0 msgid "Languages" -msgstr "" +msgstr "Sprog" #. module: base #: selection:workflow.activity,join_mode:0 @@ -2659,7 +2659,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ec msgid "Ecuador" -msgstr "" +msgstr "Equador" #. module: base #: code:addons/base/module/wizard/base_export_language.py:52 @@ -2676,12 +2676,12 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_partner_form #: view:res.partner:0 msgid "Customers" -msgstr "" +msgstr "Kunder" #. module: base #: model:res.country,name:base.au msgid "Australia" -msgstr "" +msgstr "Australien" #. module: base #: help:res.partner,lang:0 @@ -2693,7 +2693,7 @@ msgstr "" #. module: base #: report:ir.module.reference.graph:0 msgid "Menu :" -msgstr "" +msgstr "Menu:" #. module: base #: selection:ir.model.fields,state:0 @@ -2708,7 +2708,7 @@ msgstr "" #. module: base #: field:ir.actions.todo,restart:0 msgid "Restart" -msgstr "" +msgstr "Genstart" #. module: base #: field:ir.actions.report.xml,report_sxw_content:0 @@ -2776,7 +2776,7 @@ msgstr "" #. module: base #: view:res.company:0 msgid "Header/Footer" -msgstr "" +msgstr "Sidehoved/sidefod" #. module: base #: help:ir.actions.act_window,help:0 @@ -2829,13 +2829,13 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.marketing_menu msgid "Marketing" -msgstr "" +msgstr "Markedsføring" #. module: base #: view:res.partner.bank:0 #: model:res.partner.bank.type,name:base.bank_normal msgid "Bank account" -msgstr "" +msgstr "Bank konto" #. module: base #: selection:base.language.install,lang:0 @@ -2855,17 +2855,17 @@ msgstr "" #. module: base #: field:ir.module.module,license:0 msgid "License" -msgstr "" +msgstr "Licens" #. module: base #: field:ir.attachment,url:0 msgid "Url" -msgstr "" +msgstr "Adresse" #. module: base #: selection:ir.actions.todo,restart:0 msgid "Always" -msgstr "" +msgstr "Altid" #. module: base #: selection:ir.translation,type:0 @@ -2876,7 +2876,7 @@ msgstr "" #: field:ir.actions.server,srcmodel_id:0 #: field:ir.model.fields,model_id:0 msgid "Model" -msgstr "" +msgstr "Model" #. module: base #: view:base.language.install:0 @@ -2911,7 +2911,7 @@ msgstr "" #: field:res.partner.address,zip:0 #: field:res.partner.bank,zip:0 msgid "Zip" -msgstr "" +msgstr "Postnummer" #. module: base #: view:ir.module.module:0 @@ -2946,12 +2946,12 @@ msgstr "" #. module: base #: model:res.country,name:base.bo msgid "Bolivia" -msgstr "" +msgstr "Bolivia" #. module: base #: model:res.country,name:base.gh msgid "Ghana" -msgstr "" +msgstr "Ghana" #. module: base #: field:res.lang,direction:0 @@ -2973,7 +2973,7 @@ msgstr "" #: view:res.groups:0 #: field:res.groups,rule_groups:0 msgid "Rules" -msgstr "" +msgstr "Regler" #. module: base #: code:addons/base/module/module.py:216 @@ -3040,7 +3040,7 @@ msgstr "" #: view:res.config:0 #: view:res.config.installer:0 msgid "Skip" -msgstr "" +msgstr "Spring over" #. module: base #: model:res.country,name:base.ls @@ -3056,7 +3056,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ke msgid "Kenya" -msgstr "" +msgstr "Kenya" #. module: base #: view:res.partner.event:0 @@ -3092,17 +3092,17 @@ msgstr "" #. module: base #: model:res.country,name:base.sm msgid "San Marino" -msgstr "" +msgstr "San Marino" #. module: base #: model:res.country,name:base.bm msgid "Bermuda" -msgstr "" +msgstr "Bermuda" #. module: base #: model:res.country,name:base.pe msgid "Peru" -msgstr "" +msgstr "Peru" #. module: base #: selection:ir.model.fields,on_delete:0 @@ -3162,7 +3162,7 @@ msgstr "" #: view:ir.model.access:0 #: view:ir.rule:0 msgid "Full Access" -msgstr "" +msgstr "Fuld adgang" #. module: base #: view:ir.actions.act_window:0 @@ -3171,7 +3171,7 @@ msgstr "" #: view:ir.model.fields:0 #: model:ir.ui.menu,name:base.menu_security msgid "Security" -msgstr "" +msgstr "Sikkerhed" #. module: base #: model:res.widget,title:base.openerp_favorites_twitter_widget @@ -3181,14 +3181,14 @@ msgstr "" #. module: base #: model:res.country,name:base.za msgid "South Africa" -msgstr "" +msgstr "Sydafrika" #. module: base #: view:ir.module.module:0 #: selection:ir.module.module,state:0 #: selection:ir.module.module.dependency,state:0 msgid "Installed" -msgstr "" +msgstr "Installeret" #. module: base #: selection:base.language.install,lang:0 @@ -3204,12 +3204,12 @@ msgstr "" #. module: base #: model:res.country,name:base.sn msgid "Senegal" -msgstr "" +msgstr "Senegal" #. module: base #: model:res.country,name:base.hu msgid "Hungary" -msgstr "" +msgstr "Ungarn" #. module: base #: model:ir.model,name:base.model_res_groups @@ -3219,7 +3219,7 @@ msgstr "" #. module: base #: model:res.country,name:base.br msgid "Brazil" -msgstr "" +msgstr "Brasilien" #. module: base #: view:res.lang:0 @@ -3234,7 +3234,7 @@ msgstr "" #. module: base #: field:ir.sequence,number_next:0 msgid "Next Number" -msgstr "" +msgstr "Næste nummer" #. module: base #: help:workflow.transition,condition:0 @@ -3255,12 +3255,12 @@ msgstr "" #. module: base #: model:res.country,name:base.sy msgid "Syria" -msgstr "" +msgstr "Syrien" #. module: base #: view:res.lang:0 msgid "======================================================" -msgstr "" +msgstr "======================================================" #. module: base #: help:ir.actions.server,mobile:0 @@ -3288,7 +3288,7 @@ msgstr "" #: field:res.partner.event,date:0 #: field:res.request,date_sent:0 msgid "Date" -msgstr "" +msgstr "Dato" #. module: base #: field:ir.actions.report.xml,report_sxw:0 @@ -3298,7 +3298,7 @@ msgstr "" #. module: base #: view:ir.attachment:0 msgid "Data" -msgstr "" +msgstr "Data" #. module: base #: field:ir.ui.menu,parent_id:0 @@ -3364,7 +3364,7 @@ msgstr "" #. module: base #: model:res.country,name:base.mx msgid "Mexico" -msgstr "" +msgstr "Mexico" #. module: base #: model:ir.ui.menu,name:base.menu_base_config_plugins @@ -3384,7 +3384,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ni msgid "Nicaragua" -msgstr "" +msgstr "Nicaragua" #. module: base #: code:addons/orm.py:1046 @@ -3416,7 +3416,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ve msgid "Venezuela" -msgstr "" +msgstr "Venezuela" #. module: base #: view:res.lang:0 @@ -3426,7 +3426,7 @@ msgstr "" #. module: base #: model:res.country,name:base.zm msgid "Zambia" -msgstr "" +msgstr "Zambia" #. module: base #: help:res.partner,user_id:0 @@ -3453,7 +3453,7 @@ msgstr "" #. module: base #: model:res.country,name:base.kz msgid "Kazakhstan" -msgstr "" +msgstr "Kazakstan" #. module: base #: view:res.lang:0 @@ -3536,17 +3536,17 @@ msgstr "" #. module: base #: field:ir.module.module,demo:0 msgid "Demo data" -msgstr "" +msgstr "Demostrations data" #. module: base #: selection:base.language.install,lang:0 msgid "English (UK)" -msgstr "" +msgstr "Engelsk (UK)" #. module: base #: selection:base.language.install,lang:0 msgid "Japanese / 日本語" -msgstr "" +msgstr "Japansk / 日本語" #. module: base #: help:workflow.transition,act_from:0 @@ -3580,7 +3580,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "English (CA)" -msgstr "" +msgstr "Engelsk (CA)" #. module: base #: model:ir.model,name:base.model_publisher_warranty_contract @@ -3590,7 +3590,7 @@ msgstr "" #. module: base #: model:res.country,name:base.et msgid "Ethiopia" -msgstr "" +msgstr "Etiopien" #. module: base #: help:res.country.state,code:0 @@ -3631,7 +3631,7 @@ msgstr "" #. module: base #: view:ir.translation:0 msgid "Translation" -msgstr "" +msgstr "Oversættelse" #. module: base #: selection:res.request,state:0 @@ -3689,7 +3689,7 @@ msgstr "" #: field:res.partner.bank,state:0 #: field:res.partner.bank.type.field,bank_type_id:0 msgid "Bank Type" -msgstr "" +msgstr "Bank type" #. module: base #: code:addons/base/res/res_user.py:58 @@ -3757,7 +3757,7 @@ msgstr "" #. module: base #: selection:ir.cron,interval_type:0 msgid "Hours" -msgstr "" +msgstr "Timer" #. module: base #: model:res.country,name:base.gp @@ -3770,7 +3770,7 @@ msgstr "" #: code:addons/base/res/res_lang.py:161 #, python-format msgid "User Error" -msgstr "" +msgstr "Bruger fejl!" #. module: base #: help:workflow.transition,signal:0 @@ -3803,18 +3803,18 @@ msgstr "" #. module: base #: view:ir.attachment:0 msgid "Month" -msgstr "" +msgstr "Måned" #. module: base #: model:res.country,name:base.my msgid "Malaysia" -msgstr "" +msgstr "Malaysien" #. module: base #: view:base.language.install:0 #: model:ir.actions.act_window,name:base.action_view_base_language_install msgid "Load Official Translation" -msgstr "" +msgstr "Hent den officielle oversættelse" #. module: base #: model:ir.model,name:base.model_res_request_history @@ -3893,7 +3893,7 @@ msgstr "" #. module: base #: view:res.currency:0 msgid "Price Accuracy" -msgstr "" +msgstr "Pris nøjagtighed" #. module: base #: selection:base.language.install,lang:0 @@ -3909,7 +3909,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "French / Français" -msgstr "" +msgstr "Fransk / Français" #. module: base #: code:addons/orm.py:1049 @@ -3971,7 +3971,7 @@ msgstr "" #. module: base #: model:res.country,name:base.fj msgid "Fiji" -msgstr "" +msgstr "Fiji" #. module: base #: field:ir.model.fields,size:0 @@ -3981,12 +3981,12 @@ msgstr "" #. module: base #: model:res.country,name:base.sd msgid "Sudan" -msgstr "" +msgstr "Sudan" #. module: base #: model:res.country,name:base.fm msgid "Micronesia" -msgstr "" +msgstr "Mikronesien" #. module: base #: view:res.request.history:0 @@ -3998,7 +3998,7 @@ msgstr "" #: field:ir.module.module,menus_by_module:0 #: view:res.groups:0 msgid "Menus" -msgstr "" +msgstr "Menuer" #. module: base #: selection:base.language.install,lang:0 @@ -4008,7 +4008,7 @@ msgstr "" #. module: base #: model:res.country,name:base.il msgid "Israel" -msgstr "" +msgstr "Israel" #. module: base #: model:ir.actions.wizard,name:base.wizard_server_action_create @@ -4025,7 +4025,7 @@ msgstr "" #. module: base #: field:res.lang,time_format:0 msgid "Time Format" -msgstr "" +msgstr "Tidsformat" #. module: base #: view:ir.module.module:0 @@ -4045,7 +4045,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_management #: model:ir.ui.menu,name:base.menu_module_tree msgid "Modules" -msgstr "" +msgstr "Moduler" #. module: base #: view:workflow.activity:0 @@ -4071,12 +4071,12 @@ msgstr "" #: view:res.bank:0 #: field:res.partner,bank_ids:0 msgid "Banks" -msgstr "" +msgstr "Banker" #. module: base #: view:res.log:0 msgid "Unread" -msgstr "" +msgstr "Ulæst" #. module: base #: field:ir.cron,doall:0 @@ -4102,7 +4102,7 @@ msgstr "" #. module: base #: model:res.country,name:base.uk msgid "United Kingdom" -msgstr "" +msgstr "Storbritannien" #. module: base #: view:res.config:0 @@ -4124,7 +4124,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bw msgid "Botswana" -msgstr "" +msgstr "Botswana" #. module: base #: model:ir.actions.act_window,name:base.action_partner_title_partner @@ -4213,7 +4213,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_main_pm msgid "Project" -msgstr "" +msgstr "Projekt" #. module: base #: field:ir.ui.menu,web_icon_hover_data:0 @@ -4274,7 +4274,7 @@ msgstr "" #. module: base #: field:res.partner,employee:0 msgid "Employee" -msgstr "" +msgstr "Ansat" #. module: base #: field:ir.model.access,perm_create:0 @@ -4289,7 +4289,7 @@ msgstr "" #. module: base #: field:ir.actions.server,copy_object:0 msgid "Copy Of" -msgstr "" +msgstr "Kopi af" #. module: base #: field:ir.model,osv_memory:0 @@ -4327,7 +4327,7 @@ msgstr "" #: view:ir.model:0 #: field:ir.model.fields,ttype:0 msgid "Field Type" -msgstr "" +msgstr "Felttype" #. module: base #: field:res.country.state,code:0 @@ -4353,14 +4353,14 @@ msgstr "" #. module: base #: model:res.country,name:base.vn msgid "Vietnam" -msgstr "" +msgstr "Vietnam" #. module: base #: field:res.config.users,signature:0 #: view:res.users:0 #: field:res.users,signature:0 msgid "Signature" -msgstr "" +msgstr "Signatur" #. module: base #: code:addons/fields.py:456 @@ -4372,7 +4372,7 @@ msgstr "" #: code:addons/fields.py:664 #, python-format msgid "Not Implemented" -msgstr "" +msgstr "Ikke implementeret" #. module: base #: model:ir.model,name:base.model_res_widget_user @@ -4382,7 +4382,7 @@ msgstr "" #. module: base #: field:res.partner.category,complete_name:0 msgid "Full Name" -msgstr "" +msgstr "Fulde navn" #. module: base #: view:base.module.configuration:0 @@ -4427,7 +4427,7 @@ msgstr "" #: view:res.partner:0 #: field:res.partner,user_id:0 msgid "Salesman" -msgstr "" +msgstr "Sælger" #. module: base #: field:res.partner,address:0 @@ -4462,7 +4462,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cz msgid "Czech Republic" -msgstr "" +msgstr "Tjekkiet" #. module: base #: view:res.widget.wizard:0 @@ -4527,12 +4527,12 @@ msgstr "" #. module: base #: model:res.country,name:base.na msgid "Namibia" -msgstr "" +msgstr "Namibia" #. module: base #: model:res.country,name:base.mn msgid "Mongolia" -msgstr "" +msgstr "Mongoliet" #. module: base #: view:ir.module.module:0 @@ -4547,7 +4547,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bi msgid "Burundi" -msgstr "" +msgstr "Burundi" #. module: base #: view:base.language.install:0 @@ -4568,12 +4568,12 @@ msgstr "" #. module: base #: view:res.log:0 msgid "My Logs" -msgstr "" +msgstr "Mine logfiler" #. module: base #: model:res.country,name:base.bt msgid "Bhutan" -msgstr "" +msgstr "Bhutan" #. module: base #: help:ir.sequence,number_next:0 @@ -4603,7 +4603,7 @@ msgstr "" #. module: base #: field:base.language.export,format:0 msgid "File Format" -msgstr "" +msgstr "Filformat" #. module: base #: field:res.lang,iso_code:0 @@ -4619,7 +4619,7 @@ msgstr "" #: view:res.log:0 #: field:res.log,read:0 msgid "Read" -msgstr "" +msgstr "Læst" #. module: base #: sql_constraint:res.country:0 @@ -4649,7 +4649,7 @@ msgstr "" #: field:res.config.users,password:0 #: field:res.users,password:0 msgid "Password" -msgstr "" +msgstr "Adgangskode" #. module: base #: model:ir.actions.act_window,name:base.action_model_fields @@ -4659,12 +4659,12 @@ msgstr "" #: view:ir.model.fields:0 #: model:ir.ui.menu,name:base.ir_model_model_fields msgid "Fields" -msgstr "" +msgstr "Felter" #. module: base #: model:ir.actions.act_window,name:base.action_partner_employee_form msgid "Employees" -msgstr "" +msgstr "Ansatte" #. module: base #: help:res.log,read:0 @@ -4705,12 +4705,12 @@ msgstr "" #: model:ir.actions.act_window,name:base.action_partner_address_form #: model:ir.ui.menu,name:base.menu_partner_address_form msgid "Addresses" -msgstr "" +msgstr "Adresser" #. module: base #: model:res.country,name:base.mm msgid "Myanmar" -msgstr "" +msgstr "Myanmar (Burma)" #. module: base #: selection:base.language.install,lang:0 @@ -4722,12 +4722,12 @@ msgstr "" #: field:res.partner.address,street:0 #: field:res.partner.bank,street:0 msgid "Street" -msgstr "" +msgstr "Vej" #. module: base #: model:res.country,name:base.yu msgid "Yugoslavia" -msgstr "" +msgstr "Jugoslavien" #. module: base #: field:ir.model.data,name:0 @@ -4737,12 +4737,12 @@ msgstr "" #. module: base #: model:res.country,name:base.ca msgid "Canada" -msgstr "" +msgstr "Canada" #. module: base #: selection:ir.module.module.dependency,state:0 msgid "Unknown" -msgstr "" +msgstr "Ukendt" #. module: base #: model:ir.actions.act_window,name:base.action_res_users_my @@ -4758,17 +4758,17 @@ msgstr "" #. module: base #: field:partner.sms.send,text:0 msgid "SMS Message" -msgstr "" +msgstr "SMS besked" #. module: base #: model:res.country,name:base.cm msgid "Cameroon" -msgstr "" +msgstr "Cameroun" #. module: base #: model:res.country,name:base.bf msgid "Burkina Faso" -msgstr "" +msgstr "Burkina Faso" #. module: base #: selection:ir.actions.todo,state:0 @@ -4835,7 +4835,7 @@ msgstr "" #. module: base #: report:ir.module.reference.graph:0 msgid "1cm 28cm 20cm 28cm" -msgstr "" +msgstr "1cm 28cm 20cm 28cm" #. module: base #: field:ir.module.module,maintainer:0 @@ -4855,7 +4855,7 @@ msgstr "" #. module: base #: model:ir.actions.report.xml,name:base.res_partner_address_report msgid "Labels" -msgstr "" +msgstr "Etiketter" #. module: base #: field:partner.wizard.spam,email_from:0 @@ -4945,7 +4945,7 @@ msgstr "" #. module: base #: model:res.country,name:base.us msgid "United States" -msgstr "" +msgstr "USA" #. module: base #: view:ir.module.module:0 @@ -4978,7 +4978,7 @@ msgstr "" #. module: base #: model:res.country,name:base.kw msgid "Kuwait" -msgstr "" +msgstr "Kuwait" #. module: base #: field:workflow.workitem,inst_id:0 @@ -5001,7 +5001,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ng msgid "Nigeria" -msgstr "" +msgstr "Nigeria" #. module: base #: code:addons/base/ir/ir_model.py:250 @@ -5012,7 +5012,7 @@ msgstr "" #. module: base #: model:ir.actions.act_window,name:base.action_partner_sms_send msgid "SMS Send" -msgstr "" +msgstr "SMS sendt" #. module: base #: field:res.company,user_ids:0 @@ -5037,7 +5037,7 @@ msgstr "" #. module: base #: model:res.country,name:base.hk msgid "Hong Kong" -msgstr "" +msgstr "Hong Kong" #. module: base #: help:ir.actions.server,name:0 @@ -5059,12 +5059,12 @@ msgstr "" #. module: base #: model:res.country,name:base.ph msgid "Philippines" -msgstr "" +msgstr "Filippinerne" #. module: base #: model:res.country,name:base.ma msgid "Morocco" -msgstr "" +msgstr "Marokko" #. module: base #: view:res.lang:0 @@ -5084,7 +5084,7 @@ msgstr "" #. module: base #: model:res.country,name:base.td msgid "Chad" -msgstr "" +msgstr "Tchad" #. module: base #: model:ir.model,name:base.model_workflow_transition @@ -5131,7 +5131,7 @@ msgstr "" #. module: base #: model:res.country,name:base.np msgid "Nepal" -msgstr "" +msgstr "Nepal" #. module: base #: code:addons/orm.py:2307 @@ -5233,12 +5233,12 @@ msgstr "" #: field:base.language.export,data:0 #: field:base.language.import,data:0 msgid "File" -msgstr "" +msgstr "Fil" #. module: base #: view:res.config.users:0 msgid "Add User" -msgstr "" +msgstr "Tilføj bruger" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install @@ -5261,7 +5261,7 @@ msgstr "" #: field:res.partner.address,is_supplier_add:0 #: model:res.partner.category,name:base.res_partner_category_8 msgid "Supplier" -msgstr "" +msgstr "Leverandør" #. module: base #: view:ir.actions.server:0 @@ -5349,7 +5349,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ae msgid "United Arab Emirates" -msgstr "" +msgstr "De Forenede Arabiske Emirater" #. module: base #: model:ir.ui.menu,name:base.menu_crm_case_job_req_main @@ -5373,7 +5373,7 @@ msgstr "" #: view:ir.rule:0 #: field:ir.rule,global:0 msgid "Global" -msgstr "" +msgstr "Globalt" #. module: base #: model:res.country,name:base.mp @@ -5427,22 +5427,22 @@ msgstr "" #: view:ir.translation:0 #: model:ir.ui.menu,name:base.menu_translation msgid "Translations" -msgstr "" +msgstr "Oversættelser" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base #: view:ir.actions.report.xml:0 msgid "Report" -msgstr "" +msgstr "Rapport" #. module: base #: model:res.country,name:base.ua msgid "Ukraine" -msgstr "" +msgstr "Ukraine" #. module: base #: model:res.country,name:base.to @@ -5558,12 +5558,12 @@ msgstr "" #. module: base #: model:res.country,name:base.dz msgid "Algeria" -msgstr "" +msgstr "Algeriet" #. module: base #: model:res.country,name:base.be msgid "Belgium" -msgstr "" +msgstr "Belgien" #. module: base #: model:ir.model,name:base.model_osv_memory_autovacuum @@ -5579,12 +5579,12 @@ msgstr "" #: field:res.partner,lang:0 #: field:res.users,context_lang:0 msgid "Language" -msgstr "" +msgstr "Sprog" #. module: base #: model:res.country,name:base.gm msgid "Gambia" -msgstr "" +msgstr "Gambia" #. module: base #: model:ir.actions.act_window,name:base.action_res_company_form @@ -5596,7 +5596,7 @@ msgstr "" #: view:res.users:0 #: field:res.users,company_ids:0 msgid "Companies" -msgstr "" +msgstr "Virksomheder" #. module: base #: view:res.lang:0 @@ -5661,12 +5661,12 @@ msgstr "" #. module: base #: selection:base.language.export,format:0 msgid "PO File" -msgstr "" +msgstr "PO fil" #. module: base #: model:res.country,name:base.nt msgid "Neutral Zone" -msgstr "" +msgstr "Neutral Zone" #. module: base #: selection:base.language.install,lang:0 @@ -5686,7 +5686,7 @@ msgstr "" #. module: base #: model:res.partner.category,name:base.res_partner_category_9 msgid "Components Supplier" -msgstr "" +msgstr "Komponent leverandør" #. module: base #: model:ir.actions.act_window,name:base.action_res_users @@ -5697,7 +5697,7 @@ msgstr "" #: field:res.groups,users:0 #: view:res.users:0 msgid "Users" -msgstr "" +msgstr "Brugere" #. module: base #: field:ir.module.module,published_version:0 @@ -5707,7 +5707,7 @@ msgstr "" #. module: base #: model:res.country,name:base.is msgid "Iceland" -msgstr "" +msgstr "Island" #. module: base #: model:ir.actions.act_window,name:base.ir_action_window @@ -5728,7 +5728,7 @@ msgstr "" #. module: base #: model:res.country,name:base.de msgid "Germany" -msgstr "" +msgstr "Tyskland" #. module: base #: view:ir.sequence:0 @@ -5738,7 +5738,7 @@ msgstr "" #. module: base #: model:res.partner.category,name:base.res_partner_category_14 msgid "Bad customers" -msgstr "" +msgstr "Dårlige kunder" #. module: base #: report:ir.module.reference.graph:0 @@ -5748,7 +5748,7 @@ msgstr "" #. module: base #: model:res.country,name:base.gy msgid "Guyana" -msgstr "" +msgstr "Guyana" #. module: base #: help:ir.actions.act_window,view_type:0 @@ -5771,7 +5771,7 @@ msgstr "" #. module: base #: model:res.country,name:base.hn msgid "Honduras" -msgstr "" +msgstr "Honduras" #. module: base #: help:res.config.users,menu_tips:0 @@ -5783,7 +5783,7 @@ msgstr "" #. module: base #: model:res.country,name:base.eg msgid "Egypt" -msgstr "" +msgstr "Ægypten" #. module: base #: field:ir.rule,perm_read:0 @@ -5805,7 +5805,7 @@ msgstr "" #. module: base #: field:base.language.import,name:0 msgid "Language Name" -msgstr "" +msgstr "Sprog navn" #. module: base #: selection:ir.property,type:0 @@ -5886,7 +5886,7 @@ msgstr "" #: field:res.partner,comment:0 #: model:res.widget,title:base.note_widget msgid "Notes" -msgstr "" +msgstr "Noter" #. module: base #: field:ir.config_parameter,value:0 @@ -5911,7 +5911,7 @@ msgstr "" #: field:res.bank,code:0 #: field:res.partner.bank.type,code:0 msgid "Code" -msgstr "" +msgstr "Kode" #. module: base #: model:ir.model,name:base.model_res_config_installer @@ -5921,17 +5921,17 @@ msgstr "" #. module: base #: model:res.country,name:base.mc msgid "Monaco" -msgstr "" +msgstr "Monaco" #. module: base #: selection:ir.cron,interval_type:0 msgid "Minutes" -msgstr "" +msgstr "Minutter" #. module: base #: selection:ir.translation,type:0 msgid "Help" -msgstr "" +msgstr "Hjælp" #. module: base #: help:res.config.users,menu_id:0 @@ -5986,7 +5986,7 @@ msgstr "" #. module: base #: model:res.country,name:base.fr msgid "France" -msgstr "" +msgstr "Frankrig" #. module: base #: model:ir.model,name:base.model_res_log @@ -6008,7 +6008,7 @@ msgstr "" #. module: base #: selection:ir.cron,interval_type:0 msgid "Weeks" -msgstr "" +msgstr "Uger" #. module: base #: model:res.country,name:base.af @@ -6019,7 +6019,7 @@ msgstr "" #: code:addons/base/module/wizard/base_module_import.py:67 #, python-format msgid "Error !" -msgstr "" +msgstr "Fejl!" #. module: base #: model:res.partner.bank.type.field,name:base.bank_normal_field_contry @@ -6047,7 +6047,7 @@ msgstr "" #: field:res.bank,fax:0 #: field:res.partner.address,fax:0 msgid "Fax" -msgstr "" +msgstr "Fax" #. module: base #: field:res.lang,thousands_sep:0 @@ -6094,7 +6094,7 @@ msgstr "" #. module: base #: model:res.country,name:base.pa msgid "Panama" -msgstr "" +msgstr "Panama" #. module: base #: model:res.partner.title,name:base.res_partner_title_ltd @@ -6116,7 +6116,7 @@ msgstr "" #. module: base #: model:res.country,name:base.gi msgid "Gibraltar" -msgstr "" +msgstr "Gibraltar" #. module: base #: field:ir.actions.report.xml,report_name:0 @@ -6144,7 +6144,7 @@ msgstr "" #: field:res.config.users,name:0 #: field:res.users,name:0 msgid "User Name" -msgstr "" +msgstr "Brugernavn" #. module: base #: view:ir.sequence:0 @@ -6173,7 +6173,7 @@ msgstr "" #. module: base #: selection:ir.cron,interval_type:0 msgid "Months" -msgstr "" +msgstr "Måneder" #. module: base #: field:ir.actions.act_window,search_view:0 @@ -6198,7 +6198,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_sale_config_sales #: model:ir.ui.menu,name:base.menu_sales msgid "Sales" -msgstr "" +msgstr "Salg" #. module: base #: field:ir.actions.server,child_ids:0 @@ -6234,17 +6234,17 @@ msgstr "" #: field:res.partner.address,city:0 #: field:res.partner.bank,city:0 msgid "City" -msgstr "" +msgstr "By" #. module: base #: model:res.country,name:base.qa msgid "Qatar" -msgstr "" +msgstr "Qatar" #. module: base #: model:res.country,name:base.it msgid "Italy" -msgstr "" +msgstr "Italien" #. module: base #: view:ir.actions.todo:0 @@ -6262,12 +6262,12 @@ msgstr "" #: field:res.partner,email:0 #: field:res.users,email:0 msgid "E-mail" -msgstr "" +msgstr "E-mail" #. module: base #: selection:ir.module.module,license:0 msgid "GPL-3 or later version" -msgstr "" +msgstr "GPL-3 eller senere version" #. module: base #: field:workflow.activity,action:0 @@ -6277,7 +6277,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "English (US)" -msgstr "" +msgstr "Engelsk (US)" #. module: base #: model:ir.actions.act_window,name:base.action_model_data @@ -6313,12 +6313,12 @@ msgstr "" #: view:res.users:0 #: field:res.users,address_id:0 msgid "Address" -msgstr "" +msgstr "Adresse" #. module: base #: field:ir.module.module,latest_version:0 msgid "Installed version" -msgstr "" +msgstr "Installeret version" #. module: base #: selection:base.language.install,lang:0 @@ -6328,7 +6328,7 @@ msgstr "" #. module: base #: model:res.country,name:base.mr msgid "Mauritania" -msgstr "" +msgstr "Mauretanien" #. module: base #: model:ir.model,name:base.model_ir_translation @@ -6344,7 +6344,7 @@ msgstr "" #: view:workflow.activity:0 #: field:workflow.workitem,act_id:0 msgid "Activity" -msgstr "" +msgstr "Aktivitet" #. module: base #: view:res.partner:0 @@ -6370,7 +6370,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cg msgid "Congo" -msgstr "" +msgstr "Congo" #. module: base #: view:res.lang:0 @@ -6385,7 +6385,7 @@ msgstr "Standardværdi" #. module: base #: model:ir.ui.menu,name:base.menu_tools msgid "Tools" -msgstr "" +msgstr "Værktøj" #. module: base #: model:res.country,name:base.kn @@ -6427,7 +6427,7 @@ msgstr "" #: selection:ir.module.module,state:0 #: selection:ir.module.module.dependency,state:0 msgid "Not Installed" -msgstr "" +msgstr "Ikke installeret" #. module: base #: view:workflow.activity:0 @@ -6438,7 +6438,7 @@ msgstr "" #. module: base #: field:ir.ui.menu,icon:0 msgid "Icon" -msgstr "" +msgstr "Ikon" #. module: base #: help:ir.model.fields,model_id:0 @@ -6466,12 +6466,12 @@ msgstr "" #. module: base #: model:res.country,name:base.ye msgid "Yemen" -msgstr "" +msgstr "Yemen" #. module: base #: selection:workflow.activity,split_mode:0 msgid "Or" -msgstr "" +msgstr "Eller" #. module: base #: model:ir.actions.act_window,name:base.res_log_act_window @@ -6482,12 +6482,12 @@ msgstr "" #. module: base #: model:res.country,name:base.al msgid "Albania" -msgstr "" +msgstr "Albanien" #. module: base #: model:res.country,name:base.ws msgid "Samoa" -msgstr "" +msgstr "Samoa" #. module: base #: code:addons/base/res/res_lang.py:161 @@ -6555,14 +6555,14 @@ msgstr "" #. module: base #: model:res.country,name:base.la msgid "Laos" -msgstr "" +msgstr "Laos" #. module: base #: selection:ir.actions.server,state:0 #: field:res.config.users,user_email:0 #: field:res.users,user_email:0 msgid "Email" -msgstr "" +msgstr "E-mail" #. module: base #: field:res.config.users,action_id:0 @@ -6593,7 +6593,7 @@ msgstr "" #. module: base #: model:res.country,name:base.tg msgid "Togo" -msgstr "" +msgstr "Togo" #. module: base #: selection:ir.module.module,license:0 @@ -6603,7 +6603,7 @@ msgstr "" #. module: base #: selection:workflow.activity,kind:0 msgid "Stop All" -msgstr "" +msgstr "Stop alle" #. module: base #: code:addons/orm.py:412 @@ -6644,7 +6644,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ro msgid "Romania" -msgstr "" +msgstr "Rumænien" #. module: base #: help:ir.cron,doall:0 @@ -6678,7 +6678,7 @@ msgstr "" #: field:res.config.users,context_tz:0 #: field:res.users,context_tz:0 msgid "Timezone" -msgstr "" +msgstr "Tidszone" #. module: base #: model:ir.model,name:base.model_ir_actions_report_xml @@ -6731,7 +6731,7 @@ msgstr "" #. module: base #: model:res.country,name:base.by msgid "Belarus" -msgstr "" +msgstr "Hviderusland" #. module: base #: field:ir.actions.act_window,name:0 @@ -6755,7 +6755,7 @@ msgstr "" #. module: base #: selection:res.request,priority:0 msgid "Normal" -msgstr "" +msgstr "Normal" #. module: base #: field:res.bank,street2:0 @@ -6786,12 +6786,12 @@ msgstr "" #: view:res.users:0 #: field:res.widget.user,user_id:0 msgid "User" -msgstr "" +msgstr "Bruger" #. module: base #: model:res.country,name:base.pr msgid "Puerto Rico" -msgstr "" +msgstr "Puerto Rico" #. module: base #: view:ir.actions.act_window:0 @@ -6816,7 +6816,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ch msgid "Switzerland" -msgstr "" +msgstr "Schweiz" #. module: base #: model:res.country,name:base.gd @@ -6841,7 +6841,7 @@ msgstr "" #. module: base #: view:base.language.install:0 msgid "Load" -msgstr "" +msgstr "Indlæs" #. module: base #: help:res.config.users,name:0 @@ -6870,7 +6870,7 @@ msgstr "" #. module: base #: model:res.country,name:base.so msgid "Somalia" -msgstr "" +msgstr "Somalia" #. module: base #: selection:publisher_warranty.contract,state:0 @@ -6892,7 +6892,7 @@ msgstr "" #: field:res.request,act_to:0 #: field:res.request.history,act_to:0 msgid "To" -msgstr "" +msgstr "Til" #. module: base #: view:ir.cron:0 @@ -6909,12 +6909,12 @@ msgstr "" #. module: base #: selection:ir.module.module,license:0 msgid "GPL Version 2" -msgstr "" +msgstr "GPL Version 2" #. module: base #: selection:ir.module.module,license:0 msgid "GPL Version 3" -msgstr "" +msgstr "GPL Version 3" #. module: base #: code:addons/orm.py:836 @@ -6939,7 +6939,7 @@ msgstr "" #: field:res.partner.address,is_customer_add:0 #: model:res.partner.category,name:base.res_partner_category_0 msgid "Customer" -msgstr "" +msgstr "Kunde" #. module: base #: selection:base.language.install,lang:0 @@ -6949,7 +6949,7 @@ msgstr "" #. module: base #: field:ir.module.module,shortdesc:0 msgid "Short Description" -msgstr "" +msgstr "Kort beskrivelse" #. module: base #: field:ir.actions.act_window,context:0 @@ -6975,7 +6975,7 @@ msgstr "" #. module: base #: field:res.request.history,date_sent:0 msgid "Date sent" -msgstr "" +msgstr "Dato sendt" #. module: base #: view:ir.sequence:0 @@ -7002,12 +7002,12 @@ msgstr "" #. module: base #: model:res.country,name:base.tn msgid "Tunisia" -msgstr "" +msgstr "Tunesien" #. module: base #: model:ir.ui.menu,name:base.menu_mrp_root msgid "Manufacturing" -msgstr "" +msgstr "Produktion" #. module: base #: model:res.country,name:base.km @@ -7153,12 +7153,12 @@ msgstr "" #: code:addons/base/res/res_user.py:580 #, python-format msgid "Warning !" -msgstr "" +msgstr "Advarsel!" #. module: base #: model:res.widget,title:base.google_maps_widget msgid "Google Maps" -msgstr "" +msgstr "Google Maps" #. module: base #: model:ir.ui.menu,name:base.menu_base_config @@ -7210,17 +7210,17 @@ msgstr "" #. module: base #: model:res.country,name:base.tr msgid "Turkey" -msgstr "" +msgstr "Tyrkiet" #. module: base #: model:res.country,name:base.fk msgid "Falkland Islands" -msgstr "" +msgstr "Falklandsøerne" #. module: base #: model:res.country,name:base.lb msgid "Lebanon" -msgstr "" +msgstr "Libanon" #. module: base #: view:ir.actions.report.xml:0 @@ -7263,7 +7263,7 @@ msgstr "" #: view:base.language.install:0 #: model:ir.ui.menu,name:base.menu_view_base_language_install msgid "Load an Official Translation" -msgstr "" +msgstr "Hent en officiel oversættelse" #. module: base #: view:res.currency:0 @@ -7375,7 +7375,7 @@ msgstr "" #: view:ir.module.module:0 #: field:ir.module.module,category_id:0 msgid "Category" -msgstr "" +msgstr "Kategori" #. module: base #: view:ir.attachment:0 @@ -7388,17 +7388,17 @@ msgstr "" #: field:ir.actions.server,sms:0 #: selection:ir.actions.server,state:0 msgid "SMS" -msgstr "" +msgstr "SMS" #. module: base #: model:res.country,name:base.cr msgid "Costa Rica" -msgstr "" +msgstr "Costa Rica" #. module: base #: view:workflow.activity:0 msgid "Conditions" -msgstr "" +msgstr "Betingelser" #. module: base #: model:ir.actions.act_window,name:base.action_partner_other_form @@ -7410,7 +7410,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_action_currency_form #: view:res.currency:0 msgid "Currencies" -msgstr "" +msgstr "Valutaer" #. module: base #: sql_constraint:res.groups:0 @@ -7435,12 +7435,12 @@ msgstr "" #. module: base #: model:res.country,name:base.dk msgid "Denmark" -msgstr "" +msgstr "Danmark" #. module: base #: field:res.country,code:0 msgid "Country Code" -msgstr "" +msgstr "Lande kode" #. module: base #: model:ir.model,name:base.model_workflow_instance @@ -7485,7 +7485,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ee msgid "Estonia" -msgstr "" +msgstr "Estland" #. module: base #: model:ir.ui.menu,name:base.dashboard @@ -7506,7 +7506,7 @@ msgstr "" #. module: base #: model:res.country,name:base.nl msgid "Netherlands" -msgstr "" +msgstr "Holland" #. module: base #: model:ir.ui.menu,name:base.next_id_4 @@ -7541,7 +7541,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_emails #: model:ir.ui.menu,name:base.menu_mail_gateway msgid "Emails" -msgstr "" +msgstr "E-mails" #. module: base #: model:res.country,name:base.cd @@ -7563,7 +7563,7 @@ msgstr "" #. module: base #: model:res.country,name:base.jp msgid "Japan" -msgstr "" +msgstr "Japan" #. module: base #: field:ir.cron,numbercall:0 @@ -7591,7 +7591,7 @@ msgstr "" #. module: base #: model:res.country,name:base.gr msgid "Greece" -msgstr "" +msgstr "Grækenland" #. module: base #: field:res.request,trigger_date:0 @@ -7643,7 +7643,7 @@ msgstr "" #: view:ir.model.fields:0 #: field:ir.model.fields,translate:0 msgid "Translate" -msgstr "" +msgstr "Oversæt" #. module: base #: field:res.request.history,body:0 @@ -7653,7 +7653,7 @@ msgstr "" #. module: base #: view:partner.wizard.spam:0 msgid "Send Email" -msgstr "" +msgstr "Send e-mail" #. module: base #: field:res.config.users,menu_id:0 @@ -7692,7 +7692,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_procurement_management_supplier_name #: view:res.partner:0 msgid "Suppliers" -msgstr "" +msgstr "Leverandører" #. module: base #: view:publisher_warranty.contract.wizard:0 @@ -7729,12 +7729,12 @@ msgstr "" #. module: base #: model:res.country,name:base.gl msgid "Greenland" -msgstr "" +msgstr "Grønland" #. module: base #: field:res.partner.bank,acc_number:0 msgid "Account Number" -msgstr "" +msgstr "Kontonummer" #. module: base #: view:res.lang:0 @@ -7749,7 +7749,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cy msgid "Cyprus" -msgstr "" +msgstr "Cypern" #. module: base #: view:base.module.import:0 @@ -7764,13 +7764,13 @@ msgstr "" #: field:partner.wizard.spam,subject:0 #: field:res.request,name:0 msgid "Subject" -msgstr "" +msgstr "Emne" #. module: base #: field:res.request,act_from:0 #: field:res.request.history,act_from:0 msgid "From" -msgstr "" +msgstr "Fra" #. module: base #: view:res.users:0 @@ -7811,7 +7811,7 @@ msgstr "" #. module: base #: model:res.country,name:base.cn msgid "China" -msgstr "" +msgstr "Kina" #. module: base #: code:addons/base/res/res_user.py:516 @@ -7841,7 +7841,7 @@ msgstr "" #. module: base #: model:res.country,name:base.id msgid "Indonesia" -msgstr "" +msgstr "Indonesien" #. module: base #: view:base.update.translations:0 @@ -7861,7 +7861,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bg msgid "Bulgaria" -msgstr "" +msgstr "Bulgarien" #. module: base #: view:publisher_warranty.contract.wizard:0 @@ -7871,7 +7871,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ao msgid "Angola" -msgstr "" +msgstr "Angola" #. module: base #: model:res.country,name:base.tf @@ -7886,7 +7886,7 @@ msgstr "" #: field:res.currency,name:0 #: field:res.currency.rate,currency_id:0 msgid "Currency" -msgstr "" +msgstr "Valuta" #. module: base #: field:res.partner.canal,name:0 @@ -7917,7 +7917,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_administration msgid "Administration" -msgstr "" +msgstr "Administration" #. module: base #: view:base.module.update:0 @@ -7971,12 +7971,12 @@ msgstr "" #. module: base #: model:res.country,name:base.ki msgid "Kiribati" -msgstr "" +msgstr "Kiribati" #. module: base #: model:res.country,name:base.iq msgid "Iraq" -msgstr "" +msgstr "Irak" #. module: base #: model:ir.ui.menu,name:base.menu_association @@ -7986,14 +7986,14 @@ msgstr "" #. module: base #: model:res.country,name:base.cl msgid "Chile" -msgstr "" +msgstr "Chile" #. module: base #: model:ir.ui.menu,name:base.menu_address_book #: model:ir.ui.menu,name:base.menu_config_address_book #: model:ir.ui.menu,name:base.menu_procurement_management_supplier msgid "Address Book" -msgstr "" +msgstr "Adressebog" #. module: base #: model:ir.model,name:base.model_ir_sequence_type @@ -8003,12 +8003,12 @@ msgstr "" #. module: base #: selection:base.language.export,format:0 msgid "CSV File" -msgstr "" +msgstr "CSV fil" #. module: base #: field:res.company,account_no:0 msgid "Account No." -msgstr "" +msgstr "Konto nummer" #. module: base #: code:addons/base/res/res_lang.py:157 @@ -8034,7 +8034,7 @@ msgstr "" #. module: base #: model:res.country,name:base.dj msgid "Djibouti" -msgstr "" +msgstr "Djibouti" #. module: base #: field:ir.translation,value:0 @@ -8044,7 +8044,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ag msgid "Antigua and Barbuda" -msgstr "" +msgstr "Antigua og Barbuda" #. module: base #: code:addons/orm.py:3166 @@ -8057,7 +8057,7 @@ msgstr "" #. module: base #: model:res.country,name:base.zr msgid "Zaire" -msgstr "" +msgstr "Zaire" #. module: base #: field:ir.model.data,res_id:0 @@ -8091,7 +8091,7 @@ msgstr "" #. module: base #: view:res.request:0 msgid "Reply" -msgstr "" +msgstr "Svar" #. module: base #: selection:base.language.install,lang:0 @@ -8166,7 +8166,7 @@ msgstr "" #. module: base #: model:res.country,name:base.hr msgid "Croatia" -msgstr "" +msgstr "Kroatien" #. module: base #: help:res.bank,bic:0 @@ -8176,7 +8176,7 @@ msgstr "" #. module: base #: model:res.country,name:base.tm msgid "Turkmenistan" -msgstr "" +msgstr "Turkmenistan" #. module: base #: code:addons/base/ir/ir_actions.py:597 @@ -8208,7 +8208,7 @@ msgstr "" #: code:addons/orm.py:3199 #, python-format msgid "Error" -msgstr "" +msgstr "Fejl!" #. module: base #: model:res.country,name:base.pm @@ -8239,12 +8239,12 @@ msgstr "" #. module: base #: model:res.country,name:base.tz msgid "Tanzania" -msgstr "" +msgstr "Tanzania" #. module: base #: selection:base.language.install,lang:0 msgid "Danish / Dansk" -msgstr "" +msgstr "Danish / Dansk" #. module: base #: selection:ir.model.fields,select_level:0 @@ -8309,7 +8309,7 @@ msgstr "" #. module: base #: view:res.request:0 msgid "Send" -msgstr "" +msgstr "Send" #. module: base #: field:res.config.users,menu_tips:0 @@ -8370,7 +8370,7 @@ msgstr "" #. module: base #: model:res.country,name:base.do msgid "Dominican Republic" -msgstr "" +msgstr "Den Dominikanske Republik" #. module: base #: selection:base.language.install,lang:0 @@ -8388,7 +8388,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sa msgid "Saudi Arabia" -msgstr "" +msgstr "Saudi-Arabien" #. module: base #: help:res.partner,supplier:0 @@ -8432,7 +8432,7 @@ msgstr "" #. module: base #: field:ir.actions.report.xml,report_xml:0 msgid "XML path" -msgstr "" +msgstr "XML sti" #. module: base #: selection:ir.actions.todo,restart:0 @@ -8442,12 +8442,12 @@ msgstr "" #. module: base #: model:res.country,name:base.gn msgid "Guinea" -msgstr "" +msgstr "Guinea" #. module: base #: model:res.country,name:base.lu msgid "Luxembourg" -msgstr "" +msgstr "Luxembourg" #. module: base #: help:ir.values,key2:0 @@ -8484,14 +8484,14 @@ msgstr "" #. module: base #: model:res.country,name:base.sv msgid "El Salvador" -msgstr "" +msgstr "El Salvador" #. module: base #: field:res.bank,phone:0 #: field:res.partner,phone:0 #: field:res.partner.address,phone:0 msgid "Phone" -msgstr "" +msgstr "Telefon" #. module: base #: field:ir.cron,active:0 @@ -8509,12 +8509,12 @@ msgstr "" #: view:workflow.instance:0 #: view:workflow.workitem:0 msgid "Active" -msgstr "" +msgstr "Aktiv" #. module: base #: model:res.country,name:base.th msgid "Thailand" -msgstr "" +msgstr "Thailand" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_lead @@ -8535,7 +8535,7 @@ msgstr "" #: selection:workflow.activity,join_mode:0 #: selection:workflow.activity,split_mode:0 msgid "And" -msgstr "" +msgstr "Og" #. module: base #: field:ir.model.fields,relation:0 @@ -8551,7 +8551,7 @@ msgstr "" #. module: base #: model:res.country,name:base.uz msgid "Uzbekistan" -msgstr "" +msgstr "Usbekistan" #. module: base #: model:ir.model,name:base.model_ir_actions_act_window @@ -8572,7 +8572,7 @@ msgstr "" #. module: base #: model:res.country,name:base.tw msgid "Taiwan" -msgstr "" +msgstr "Taiwan" #. module: base #: model:ir.model,name:base.model_res_currency_rate @@ -8682,7 +8682,7 @@ msgstr "" #: field:base.language.export,name:0 #: field:ir.attachment,datas_fname:0 msgid "Filename" -msgstr "" +msgstr "Filnavn" #. module: base #: field:ir.model,access_ids:0 @@ -8693,7 +8693,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sk msgid "Slovak Republic" -msgstr "" +msgstr "Slovakiet" #. module: base #: model:ir.ui.menu,name:base.publisher_warranty @@ -8708,7 +8708,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ar msgid "Argentina" -msgstr "" +msgstr "Argentina" #. module: base #: field:res.groups,name:0 @@ -8718,7 +8718,7 @@ msgstr "" #. module: base #: model:res.country,name:base.bh msgid "Bahrain" -msgstr "" +msgstr "Bahrain" #. module: base #: model:res.partner.category,name:base.res_partner_category_12 @@ -8740,7 +8740,7 @@ msgstr "" #: view:res.users:0 #: field:res.users,company_id:0 msgid "Company" -msgstr "" +msgstr "Virksomhed" #. module: base #: view:res.users:0 @@ -8780,7 +8780,7 @@ msgstr "" #. module: base #: model:res.country,name:base.jm msgid "Jamaica" -msgstr "" +msgstr "Jamaica" #. module: base #: model:ir.actions.act_window,help:base.action_partner_category_form @@ -8800,7 +8800,7 @@ msgstr "" #: code:addons/base/res/partner/partner.py:250 #, python-format msgid "Warning" -msgstr "" +msgstr "Advarsel!" #. module: base #: selection:base.language.install,lang:0 @@ -8840,7 +8840,7 @@ msgstr "" #. module: base #: model:res.country,name:base.rw msgid "Rwanda" -msgstr "" +msgstr "Rwanda" #. module: base #: view:ir.sequence:0 @@ -8865,7 +8865,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sg msgid "Singapore" -msgstr "" +msgstr "Singapore" #. module: base #: selection:ir.actions.act_window,target:0 @@ -8895,7 +8895,7 @@ msgstr "" #: field:res.partner.address,country_id:0 #: field:res.partner.bank,country_id:0 msgid "Country" -msgstr "" +msgstr "Land" #. module: base #: field:ir.model.fields,complete_name:0 @@ -8918,12 +8918,12 @@ msgstr "" #. module: base #: field:res.partner.category,name:0 msgid "Category Name" -msgstr "" +msgstr "Kategori Navn" #. module: base #: model:res.partner.category,name:base.res_partner_category_15 msgid "IT sector" -msgstr "" +msgstr "IT sektor" #. module: base #: view:ir.actions.act_window:0 @@ -8975,7 +8975,7 @@ msgstr "" #: selection:ir.ui.view,type:0 #: selection:wizard.ir.model.menu.create.line,view_type:0 msgid "Graph" -msgstr "" +msgstr "Graf" #. module: base #: model:ir.model,name:base.model_ir_actions_server @@ -9017,7 +9017,7 @@ msgstr "" #. module: base #: model:ir.ui.menu,name:base.menu_localisation msgid "Localisation" -msgstr "" +msgstr "Lokalisering" #. module: base #: view:ir.actions.server:0 @@ -9070,7 +9070,7 @@ msgstr "" #. module: base #: field:ir.actions.server,mobile:0 msgid "Mobile No" -msgstr "" +msgstr "Mobil nr." #. module: base #: model:ir.actions.act_window,name:base.action_partner_by_category @@ -9084,7 +9084,7 @@ msgstr "" #. module: base #: view:base.module.upgrade:0 msgid "System Update" -msgstr "" +msgstr "Systemopdatering" #. module: base #: selection:ir.translation,type:0 @@ -9099,18 +9099,18 @@ msgstr "" #. module: base #: model:res.country,name:base.sc msgid "Seychelles" -msgstr "" +msgstr "Seychellerne" #. module: base #: model:ir.model,name:base.model_res_partner_bank #: view:res.partner.bank:0 msgid "Bank Accounts" -msgstr "" +msgstr "Bankkonti" #. module: base #: model:res.country,name:base.sl msgid "Sierra Leone" -msgstr "" +msgstr "Sierra Leone" #. module: base #: view:res.company:0 @@ -9126,7 +9126,7 @@ msgstr "" #. module: base #: field:res.partner.bank,owner_name:0 msgid "Account Owner" -msgstr "" +msgstr "Konto ejer" #. module: base #: code:addons/base/res/res_user.py:256 @@ -9155,7 +9155,7 @@ msgstr "" #: field:res.partner.address,function:0 #: selection:workflow.activity,kind:0 msgid "Function" -msgstr "" +msgstr "Funktion" #. module: base #: view:res.widget:0 @@ -9165,12 +9165,12 @@ msgstr "" #. module: base #: selection:ir.actions.todo,restart:0 msgid "Never" -msgstr "" +msgstr "Aldrig" #. module: base #: selection:res.partner.address,type:0 msgid "Delivery" -msgstr "" +msgstr "Levering" #. module: base #: model:res.partner.title,name:base.res_partner_title_pvt_ltd @@ -9197,7 +9197,7 @@ msgstr "" #. module: base #: model:res.country,name:base.kp msgid "North Korea" -msgstr "" +msgstr "Nordkorea" #. module: base #: selection:ir.actions.server,state:0 @@ -9240,7 +9240,7 @@ msgstr "" #. module: base #: model:res.country,name:base.lk msgid "Sri Lanka" -msgstr "" +msgstr "Sri Lanka" #. module: base #: selection:base.language.install,lang:0 diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po index 4dbe8f4c0cf..1e72e0907df 100644 --- a/openerp/addons/base/i18n/de.po +++ b/openerp/addons/base/i18n/de.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-18 11:51+0000\n" +"PO-Revision-Date: 2011-09-30 21:28+0000\n" "Last-Translator: Thorsten Vocks (OpenBig.org) <thorsten.vocks@big-" "consulting.net>\n" "Language-Team: German <kde-i18n-doc@kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5702,7 +5702,7 @@ msgstr "Übersetzungen" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Stellenanzahl" #. module: base @@ -9656,3 +9656,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russian / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Stellenanzahl" diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po index 4bca6580496..4f0102b4a63 100644 --- a/openerp/addons/base/i18n/el.po +++ b/openerp/addons/base/i18n/el.po @@ -6,14 +6,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-18 08:23+0000\n" +"PO-Revision-Date: 2011-09-30 21:21+0000\n" "Last-Translator: Dimitris Andavoglou <dimitrisand@gmail.com>\n" "Language-Team: nls@hellug.gr <nls@hellug.gr>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" "X-Poedit-Country: GREECE\n" "X-Poedit-Language: Greek\n" "X-Poedit-SourceCharset: utf-8\n" @@ -5614,7 +5614,7 @@ msgstr "Μεταφράσεις" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Συμπλήρωση αριθμών" #. module: base @@ -9476,3 +9476,6 @@ msgstr "Σρι Λάνκα / Κευλάνη" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ρώσσικα / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Συμπλήρωση αριθμών" diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po index e9c4a7b1bc0..c4f9260336f 100644 --- a/openerp/addons/base/i18n/en_GB.po +++ b/openerp/addons/base/i18n/en_GB.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-07-28 15:35+0000\n" -"Last-Translator: John Bradshaw <Unknown>\n" +"PO-Revision-Date: 2011-09-30 20:48+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: English (United Kingdom) <en_GB@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -1972,7 +1972,7 @@ msgstr "Iteration Actions" #. module: base #: help:multi_company.default,company_id:0 msgid "Company where the user is connected" -msgstr "" +msgstr "Company where the user is connected" #. module: base #: field:publisher_warranty.contract,date_stop:0 @@ -2583,7 +2583,7 @@ msgstr "Search Actions" #: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check #: view:partner.wizard.ean.check:0 msgid "Ean check" -msgstr "" +msgstr "Ean check" #. module: base #: field:res.partner,vat:0 @@ -2623,7 +2623,7 @@ msgstr "GPL-2 or later version" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_sir msgid "M." -msgstr "" +msgstr "M." #. module: base #: code:addons/base/module/module.py:429 @@ -3001,7 +3001,7 @@ msgstr "License" #. module: base #: field:ir.attachment,url:0 msgid "Url" -msgstr "" +msgstr "Url" #. module: base #: selection:ir.actions.todo,restart:0 @@ -3153,7 +3153,7 @@ msgstr "Workflows" #. module: base #: field:ir.translation,xml_id:0 msgid "XML Id" -msgstr "" +msgstr "XML Id" #. module: base #: model:ir.actions.act_window,name:base.action_config_user_form @@ -3224,7 +3224,7 @@ msgstr "Abkhazian / аҧсуа" #. module: base #: view:base.module.configuration:0 msgid "System Configuration Done" -msgstr "" +msgstr "System Configuration Done" #. module: base #: code:addons/orm.py:929 @@ -3271,7 +3271,7 @@ msgstr "That contract is already registered in the system." #. module: base #: help:ir.sequence,suffix:0 msgid "Suffix value of the record for the sequence" -msgstr "" +msgstr "Suffix value of the record for the sequence" #. module: base #: selection:base.language.install,lang:0 @@ -3343,7 +3343,7 @@ msgstr "Installed" #. module: base #: selection:base.language.install,lang:0 msgid "Ukrainian / українська" -msgstr "" +msgstr "Ukrainian / українська" #. module: base #: model:ir.actions.act_window,name:base.action_translation @@ -3389,7 +3389,7 @@ msgstr "Next Number" #. module: base #: help:workflow.transition,condition:0 msgid "Expression to be satisfied if we want the transition done." -msgstr "" +msgstr "Expression to be satisfied if we want the transition done." #. module: base #: selection:base.language.install,lang:0 @@ -3518,6 +3518,12 @@ msgid "" "Would your payment have been carried out after this mail was sent, please " "consider the present one as void." msgstr "" +"Please note that the following payments are now due. If your payment " +" has been sent, kindly forward your payment details. If " +"payment will be delayed, please contact us to " +"discuss. \n" +"If payment was performed after this mail was sent, please consider the " +"present one as void." #. module: base #: model:res.country,name:base.mx @@ -3673,6 +3679,8 @@ msgid "" "If set to true, the action will not be displayed on the right toolbar of a " "form view" msgstr "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view" #. module: base #: model:res.country,name:base.ms @@ -3717,7 +3725,7 @@ msgstr "English (UK)" #. module: base #: selection:base.language.install,lang:0 msgid "Japanese / 日本語" -msgstr "" +msgstr "Japanese / 日本語" #. module: base #: help:workflow.transition,act_from:0 @@ -3725,6 +3733,8 @@ msgid "" "Source activity. When this activity is over, the condition is tested to " "determine if we can start the ACT_TO activity." msgstr "" +"Source activity. When this activity is over, the condition is tested to " +"determine if we can start the ACT_TO activity." #. module: base #: model:res.partner.category,name:base.res_partner_category_3 @@ -3885,7 +3895,7 @@ msgstr "Init Date" #. module: base #: selection:base.language.install,lang:0 msgid "Gujarati / ગુજરાતી" -msgstr "" +msgstr "Gujarati / ગુજરાતી" #. module: base #: code:addons/base/module/module.py:257 @@ -3953,6 +3963,9 @@ msgid "" "form, signal tests the name of the pressed button. If signal is NULL, no " "button is necessary to validate this transition." msgstr "" +"When the operation of transition comes from a button press in the client " +"form, signal tests the name of the pressed button. If signal is NULL, no " +"button is necessary to validate this transition." #. module: base #: help:multi_company.default,object_id:0 @@ -3972,7 +3985,7 @@ msgstr "Menu Name" #. module: base #: view:ir.module.module:0 msgid "Author Website" -msgstr "" +msgstr "Author Website" #. module: base #: view:ir.attachment:0 @@ -4012,6 +4025,8 @@ msgid "" "Whether values for this field can be translated (enables the translation " "mechanism for that field)" msgstr "" +"Whether values for this field can be translated (enables the translation " +"mechanism for that field)" #. module: base #: view:res.lang:0 @@ -4072,13 +4087,13 @@ msgstr "Price Accuracy" #. module: base #: selection:base.language.install,lang:0 msgid "Latvian / latviešu valoda" -msgstr "" +msgstr "Latvian / latviešu valoda" #. module: base #: view:res.config:0 #: view:res.config.installer:0 msgid "vsep" -msgstr "" +msgstr "vsep" #. module: base #: selection:base.language.install,lang:0 @@ -4099,7 +4114,7 @@ msgstr "Workitem" #. module: base #: view:ir.actions.todo:0 msgid "Set as Todo" -msgstr "" +msgstr "Set as Todo" #. module: base #: field:ir.actions.act_window.view,act_window_id:0 @@ -4177,7 +4192,7 @@ msgstr "Menus" #. module: base #: selection:base.language.install,lang:0 msgid "Serbian (Latin) / srpski" -msgstr "" +msgstr "Serbian (Latin) / srpski" #. module: base #: model:res.country,name:base.il @@ -4353,7 +4368,7 @@ msgstr "" #. module: base #: view:base.language.import:0 msgid "- module,type,name,res_id,src,value" -msgstr "" +msgstr "- module,type,name,res_id,src,value" #. module: base #: selection:base.language.install,lang:0 @@ -4372,7 +4387,7 @@ msgstr "" #. module: base #: help:ir.model.fields,relation:0 msgid "For relationship fields, the technical name of the target model" -msgstr "" +msgstr "For relationship fields, the technical name of the target model" #. module: base #: selection:base.language.install,lang:0 @@ -4387,7 +4402,7 @@ msgstr "Inherited View" #. module: base #: view:ir.translation:0 msgid "Source Term" -msgstr "" +msgstr "Source Term" #. module: base #: model:ir.ui.menu,name:base.menu_main_pm @@ -4397,7 +4412,7 @@ msgstr "Project" #. module: base #: field:ir.ui.menu,web_icon_hover_data:0 msgid "Web Icon Image (hover)" -msgstr "" +msgstr "Web Icon Image (hover)" #. module: base #: view:base.module.import:0 @@ -4417,7 +4432,7 @@ msgstr "Create User" #. module: base #: view:partner.clear.ids:0 msgid "Want to Clear Ids ? " -msgstr "" +msgstr "Want to Clear Ids ? " #. module: base #: field:publisher_warranty.contract,name:0 @@ -4469,17 +4484,17 @@ msgstr "Fed. State" #. module: base #: field:ir.actions.server,copy_object:0 msgid "Copy Of" -msgstr "" +msgstr "Copy Of" #. module: base #: field:ir.model,osv_memory:0 msgid "In-memory model" -msgstr "" +msgstr "In-memory model" #. module: base #: view:partner.clear.ids:0 msgid "Clear Ids" -msgstr "" +msgstr "Clear Ids" #. module: base #: model:res.country,name:base.io @@ -4501,7 +4516,7 @@ msgstr "Field Mapping" #. module: base #: view:publisher_warranty.contract:0 msgid "Refresh Validation Dates" -msgstr "" +msgstr "Refresh Validation Dates" #. module: base #: view:ir.model:0 @@ -4572,7 +4587,7 @@ msgstr "_Ok" #. module: base #: help:ir.filters,user_id:0 msgid "False means for every user" -msgstr "" +msgstr "False means for every user" #. module: base #: code:addons/base/module/module.py:198 @@ -4621,6 +4636,7 @@ msgstr "Contacts" msgid "" "Unable to delete this document because it is used as a default property" msgstr "" +"Unable to delete this document because it is used as a default property" #. module: base #: view:res.widget.wizard:0 @@ -4674,7 +4690,7 @@ msgstr "" #: code:addons/orm.py:1350 #, python-format msgid "Insufficient fields for Calendar View!" -msgstr "" +msgstr "Insufficient fields for Calendar View!" #. module: base #: selection:ir.property,type:0 @@ -4687,6 +4703,8 @@ msgid "" "The path to the main report file (depending on Report Type) or NULL if the " "content is in another data field" msgstr "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another data field" #. module: base #: help:res.config.users,company_id:0 @@ -4748,7 +4766,7 @@ msgstr "Close" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (MX) / Español (MX)" -msgstr "" +msgstr "Spanish (MX) / Español (MX)" #. module: base #: view:res.log:0 @@ -4783,7 +4801,7 @@ msgstr "Publisher Warranty Contracts" #. module: base #: help:res.log,name:0 msgid "The logging message." -msgstr "" +msgstr "The logging message." #. module: base #: field:base.language.export,format:0 @@ -5018,7 +5036,7 @@ msgstr "" #. module: base #: help:ir.cron,interval_number:0 msgid "Repeat every x." -msgstr "" +msgstr "Repeat every x." #. module: base #: wizard_view:server.action.create,step_1:0 @@ -5078,6 +5096,8 @@ msgid "" "If specified, this action will be opened at logon for this user, in addition " "to the standard menu." msgstr "" +"If specified, this action will be opened at logon for this user, in addition " +"to the standard menu." #. module: base #: view:ir.values:0 @@ -5088,7 +5108,7 @@ msgstr "Client Actions" #: code:addons/orm.py:1806 #, python-format msgid "The exists method is not implemented on this object !" -msgstr "" +msgstr "The exists method is not implemented on this object !" #. module: base #: code:addons/base/module/module.py:336 @@ -5113,7 +5133,7 @@ msgstr "Connect Events to Actions" #. module: base #: model:ir.model,name:base.model_base_update_translations msgid "base.update.translations" -msgstr "" +msgstr "base.update.translations" #. module: base #: field:ir.module.category,parent_id:0 @@ -5124,7 +5144,7 @@ msgstr "Parent Category" #. module: base #: selection:ir.property,type:0 msgid "Integer Big" -msgstr "" +msgstr "Integer Big" #. module: base #: selection:res.partner.address,type:0 @@ -5158,7 +5178,7 @@ msgstr "Communication" #. module: base #: view:ir.actions.report.xml:0 msgid "RML Report" -msgstr "" +msgstr "RML Report" #. module: base #: model:ir.model,name:base.model_ir_server_object_lines @@ -5206,7 +5226,7 @@ msgstr "Nigeria" #: code:addons/base/ir/ir_model.py:250 #, python-format msgid "For selection fields, the Selection Options must be given!" -msgstr "" +msgstr "For selection fields, the Selection Options must be given!" #. module: base #: model:ir.actions.act_window,name:base.action_partner_sms_send @@ -5254,6 +5274,13 @@ msgid "" "installed the CRM, with the history tab, you can track all the interactions " "with a partner such as opportunities, emails, or sales orders issued." msgstr "" +"Customers (also called Partners in other areas of the system) helps you " +"manage your address book of companies whether they are prospects, customers " +"and/or suppliers. The partner form allows you to track and record all the " +"necessary information to interact with your partners from the company " +"address to their contacts as well as pricelists, and much more. If you " +"installed the CRM, with the history tab, you can track all interactions with " +"a partner such as opportunities, emails, or sales orders issued." #. module: base #: model:res.country,name:base.ph @@ -5278,7 +5305,7 @@ msgstr "Content" #. module: base #: help:ir.rule,global:0 msgid "If no group is specified the rule is global and applied to everyone" -msgstr "" +msgstr "If no group is specified the rule is global and applied to everyone" #. module: base #: model:res.country,name:base.td @@ -5355,6 +5382,9 @@ msgid "" "groups. If this field is empty, OpenERP will compute visibility based on the " "related object's read access." msgstr "" +"If you have groups, the visibility of this menu will be based on these " +"groups. If this field is empty, OpenERP will compute visibility based on the " +"related object's read access." #. module: base #: model:ir.actions.act_window,name:base.action_ui_view_custom @@ -5496,7 +5526,7 @@ msgstr "Spanish (EC) / Español (EC)" #. module: base #: help:ir.ui.view,xml_id:0 msgid "ID of the view defined in xml file" -msgstr "" +msgstr "ID of the view defined in xml file" #. module: base #: model:ir.model,name:base.model_base_module_import @@ -5512,7 +5542,7 @@ msgstr "American Samoa" #. module: base #: help:ir.actions.act_window,res_model:0 msgid "Model name of the object to open in the view window" -msgstr "" +msgstr "Model name of the object to open in the view window" #. module: base #: field:res.log,secondary:0 @@ -5639,8 +5669,8 @@ msgstr "Translations" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" -msgstr "Number padding" +msgid "Number Padding" +msgstr "Number Padding" #. module: base #: view:ir.actions.report.xml:0 @@ -5692,11 +5722,15 @@ msgid "" "Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " "be possible to email new users." msgstr "" +"If an email is provided, the user will be sent a message welcoming them.\n" +"\n" +"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " +"be possible to email new users." #. module: base #: selection:base.language.install,lang:0 msgid "Flemish (BE) / Vlaams (BE)" -msgstr "" +msgstr "Flemish (BE) / Vlaams (BE)" #. module: base #: field:ir.cron,interval_number:0 @@ -5746,7 +5780,7 @@ msgstr "ir.actions.todo" #: code:addons/base/res/res_config.py:94 #, python-format msgid "Couldn't find previous ir.actions.todo" -msgstr "" +msgstr "Couldn't find previous ir.actions.todo" #. module: base #: view:ir.actions.act_window:0 @@ -5761,7 +5795,7 @@ msgstr "Custom Shortcuts" #. module: base #: selection:base.language.install,lang:0 msgid "Vietnamese / Tiếng Việt" -msgstr "" +msgstr "Vietnamese / Tiếng Việt" #. module: base #: model:res.country,name:base.dz @@ -5776,7 +5810,7 @@ msgstr "Belgium" #. module: base #: model:ir.model,name:base.model_osv_memory_autovacuum msgid "osv_memory.autovacuum" -msgstr "" +msgstr "osv_memory.autovacuum" #. module: base #: field:base.language.export,lang:0 @@ -5809,30 +5843,30 @@ msgstr "Companies" #. module: base #: view:res.lang:0 msgid "%H - Hour (24-hour clock) [00,23]." -msgstr "" +msgstr "%H - Hour (24-hour clock) [00,23]." #. module: base #: model:ir.model,name:base.model_res_widget msgid "res.widget" -msgstr "" +msgstr "res.widget" #. module: base #: code:addons/base/ir/ir_model.py:258 #, python-format msgid "Model %s does not exist!" -msgstr "" +msgstr "Model %s does not exist!" #. module: base #: code:addons/base/res/res_lang.py:159 #, python-format msgid "You cannot delete the language which is User's Preferred Language !" -msgstr "" +msgstr "You cannot delete the language which is User's Preferred Language !" #. module: base #: code:addons/fields.py:103 #, python-format msgid "Not implemented get_memory method !" -msgstr "" +msgstr "Not implemented get_memory method !" #. module: base #: view:ir.actions.server:0 @@ -5879,7 +5913,7 @@ msgstr "Neutral Zone" #. module: base #: selection:base.language.install,lang:0 msgid "Hindi / हिंदी" -msgstr "" +msgstr "Hindi / हिंदी" #. module: base #: view:ir.model:0 @@ -5926,7 +5960,7 @@ msgstr "Window Actions" #. module: base #: view:res.lang:0 msgid "%I - Hour (12-hour clock) [01,12]." -msgstr "" +msgstr "%I - Hour (12-hour clock) [01,12]." #. module: base #: selection:publisher_warranty.contract.wizard,state:0 @@ -5964,12 +5998,14 @@ msgid "" "View type: set to 'tree' for a hierarchical tree view, or 'form' for other " "views" msgstr "" +"View type: set to 'tree' for a hierarchical tree view, or 'form' for other " +"views" #. module: base #: code:addons/base/res/res_config.py:421 #, python-format msgid "Click 'Continue' to configure the next addon..." -msgstr "" +msgstr "Click 'Continue' to configure the next addon..." #. module: base #: field:ir.actions.server,record_id:0 @@ -6010,7 +6046,7 @@ msgstr "" #: code:addons/base/ir/ir_actions.py:629 #, python-format msgid "Please specify server option --email-from !" -msgstr "" +msgstr "Please specify server option --email-from !" #. module: base #: field:base.language.import,name:0 @@ -6070,6 +6106,7 @@ msgid "" "It gives the status if the tip has to be displayed or not when a user " "executes an action" msgstr "" +"It shows if the tip is to be displayed or not when a user executes an action" #. module: base #: view:ir.model:0 @@ -6126,7 +6163,7 @@ msgstr "Code" #. module: base #: model:ir.model,name:base.model_res_config_installer msgid "res.config.installer" -msgstr "" +msgstr "res.config.installer" #. module: base #: model:res.country,name:base.mc @@ -6170,7 +6207,7 @@ msgstr "Sequence Codes" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (CO) / Español (CO)" -msgstr "" +msgstr "Spanish (CO) / Español (CO)" #. module: base #: view:base.module.configuration:0 @@ -6178,6 +6215,8 @@ msgid "" "All pending configuration wizards have been executed. You may restart " "individual wizards via the list of configuration wizards." msgstr "" +"All pending configuration wizards have been executed. You may restart " +"individual wizards via the list of configuration wizards." #. module: base #: wizard_button:server.action.create,step_1,create:0 @@ -6187,7 +6226,7 @@ msgstr "Create" #. module: base #: view:ir.sequence:0 msgid "Current Year with Century: %(year)s" -msgstr "" +msgstr "Current Year with Century: %(year)s" #. module: base #: field:ir.exports,export_fields:0 @@ -6202,13 +6241,13 @@ msgstr "France" #. module: base #: model:ir.model,name:base.model_res_log msgid "res.log" -msgstr "" +msgstr "res.log" #. module: base #: help:ir.translation,module:0 #: help:ir.translation,xml_id:0 msgid "Maps to the ir_model_data for which this translation is provided." -msgstr "" +msgstr "Maps to the ir_model_data for which this translation is provided." #. module: base #: view:workflow.activity:0 @@ -6302,7 +6341,7 @@ msgstr "Todo" #. module: base #: field:ir.attachment,datas:0 msgid "File Content" -msgstr "" +msgstr "File Content" #. module: base #: model:res.country,name:base.pa @@ -6319,12 +6358,13 @@ msgstr "Ltd" msgid "" "The group that a user must have to be authorized to validate this transition." msgstr "" +"The group that a user must have to be authorized to validate this transition." #. module: base #: constraint:res.config.users:0 #: constraint:res.users:0 msgid "The chosen company is not in the allowed companies for this user" -msgstr "" +msgstr "The chosen company is not in the allowed companies for this user" #. module: base #: model:res.country,name:base.gi @@ -6346,6 +6386,7 @@ msgstr "Pitcairn Island" msgid "" "We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." msgstr "" +"We suggest reloading the menu tab to see the new menus (Ctrl+T then Ctrl+R)." #. module: base #: model:ir.actions.act_window,name:base.action_rule @@ -6398,7 +6439,7 @@ msgstr "Search View" #. module: base #: sql_constraint:res.lang:0 msgid "The code of the language must be unique !" -msgstr "" +msgstr "The code of the language must be unique !" #. module: base #: model:ir.actions.act_window,name:base.action_attachment @@ -6441,7 +6482,7 @@ msgstr "Write Access" #. module: base #: view:res.lang:0 msgid "%m - Month number [01,12]." -msgstr "" +msgstr "%m - Month number [01,12]." #. module: base #: field:res.bank,city:0 @@ -6499,7 +6540,7 @@ msgstr "English (US)" #: view:ir.model.data:0 #: model:ir.ui.menu,name:base.ir_model_data_menu msgid "Object Identifiers" -msgstr "" +msgstr "Object Identifiers" #. module: base #: model:ir.actions.act_window,help:base.action_partner_title_partner @@ -6507,11 +6548,13 @@ msgid "" "Manage the partner titles you want to have available in your system. The " "partner titles is the legal status of the company: Private Limited, SA, etc." msgstr "" +"Manage the partner titles you want to have available in your system. The " +"partner title is the legal status of the company: Private Limited, SA, etc." #. module: base #: view:base.language.export:0 msgid "To browse official translations, you can start with these links:" -msgstr "" +msgstr "To browse official translations, you can start with these links:" #. module: base #: code:addons/base/ir/ir_model.py:484 @@ -6520,6 +6563,8 @@ msgid "" "You can not read this document (%s) ! Be sure your user belongs to one of " "these groups: %s." msgstr "" +"You can not read this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." #. module: base #: view:res.bank:0 @@ -6538,7 +6583,7 @@ msgstr "Installed version" #. module: base #: selection:base.language.install,lang:0 msgid "Mongolian / монгол" -msgstr "" +msgstr "Mongolian / монгол" #. module: base #: model:res.country,name:base.mr @@ -6553,7 +6598,7 @@ msgstr "ir.translation" #. module: base #: view:base.module.update:0 msgid "Module update result" -msgstr "" +msgstr "Module update result" #. module: base #: view:workflow.activity:0 @@ -6575,7 +6620,7 @@ msgstr "Parent Company" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (CR) / Español (CR)" -msgstr "" +msgstr "Spanish (CR) / Español (CR)" #. module: base #: field:res.currency.rate,rate:0 @@ -6615,6 +6660,9 @@ msgid "" "for the currency: %s \n" "at the date: %s" msgstr "" +"No rate found \n" +"for the currency: %s \n" +"at the date: %s" #. module: base #: model:ir.actions.act_window,help:base.action_ui_view_custom @@ -6622,6 +6670,8 @@ msgid "" "Customized views are used when users reorganize the content of their " "dashboard views (via web client)" msgstr "" +"Customised views are used when users reorganise the content of their " +"dashboard views (via web client)" #. module: base #: field:ir.model,name:0 @@ -6660,7 +6710,7 @@ msgstr "Icon" #. module: base #: help:ir.model.fields,model_id:0 msgid "The model this field belongs to" -msgstr "" +msgstr "The model this field belongs to" #. module: base #: model:res.country,name:base.mq @@ -6670,7 +6720,7 @@ msgstr "Martinique (French)" #. module: base #: view:ir.sequence.type:0 msgid "Sequences Type" -msgstr "" +msgstr "Sequences Type" #. module: base #: model:ir.actions.act_window,name:base.res_request-act @@ -6694,7 +6744,7 @@ msgstr "Or" #: model:ir.actions.act_window,name:base.res_log_act_window #: model:ir.ui.menu,name:base.menu_res_log_act_window msgid "Client Logs" -msgstr "" +msgstr "Client Logs" #. module: base #: model:res.country,name:base.al @@ -6713,6 +6763,8 @@ msgid "" "You cannot delete the language which is Active !\n" "Please de-activate the language first." msgstr "" +"You cannot delete a language which is active !\n" +"Please de-activate the language first." #. module: base #: view:base.language.install:0 @@ -6721,6 +6773,8 @@ msgid "" "Please be patient, this operation may take a few minutes (depending on the " "number of modules currently installed)..." msgstr "" +"Please be patient, this operation may take a few minutes (depending on the " +"number of modules currently installed)..." #. module: base #: field:ir.ui.menu,child_id:0 @@ -6739,18 +6793,18 @@ msgstr "Problem in configuration `Record Id` in Server Action!" #: code:addons/orm.py:2316 #, python-format msgid "ValidateError" -msgstr "" +msgstr "ValidateError" #. module: base #: view:base.module.import:0 #: view:base.module.update:0 msgid "Open Modules" -msgstr "" +msgstr "Open Modules" #. module: base #: model:ir.actions.act_window,help:base.action_res_bank_form msgid "Manage bank records you want to be used in the system." -msgstr "" +msgstr "Manage bank records you want to be used in the system." #. module: base #: view:base.module.import:0 @@ -6768,6 +6822,8 @@ msgid "" "The path to the main report file (depending on Report Type) or NULL if the " "content is in another field" msgstr "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another field" #. module: base #: model:res.country,name:base.la @@ -6794,6 +6850,8 @@ msgid "" "The sum of the data (2nd field) is null.\n" "We can't draw a pie chart !" msgstr "" +"The sum of the data (2nd field) is null.\n" +"We can't draw a pie chart !" #. module: base #: model:ir.ui.menu,name:base.menu_lunch_reporting @@ -6815,7 +6873,7 @@ msgstr "Togo" #. module: base #: selection:ir.module.module,license:0 msgid "Other Proprietary" -msgstr "" +msgstr "Other Proprietary" #. module: base #: selection:workflow.activity,kind:0 @@ -6826,7 +6884,7 @@ msgstr "Stop All" #: code:addons/orm.py:412 #, python-format msgid "The read_group method is not implemented on this object !" -msgstr "" +msgstr "The read_group method is not implemented on this object !" #. module: base #: view:ir.model.data:0 @@ -6846,7 +6904,7 @@ msgstr "Cascade" #. module: base #: field:workflow.transition,group_id:0 msgid "Group Required" -msgstr "" +msgstr "Group Required" #. module: base #: view:ir.actions.configuration.wizard:0 @@ -6869,17 +6927,19 @@ msgid "" "Enable this if you want to execute missed occurences as soon as the server " "restarts." msgstr "" +"Enable this if you want to execute missed occurences as soon as the server " +"restarts." #. module: base #: view:base.module.upgrade:0 msgid "Start update" -msgstr "" +msgstr "Start update" #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:144 #, python-format msgid "Contract validation error" -msgstr "" +msgstr "Contract validation error" #. module: base #: field:res.country.state,name:0 @@ -6906,7 +6966,7 @@ msgstr "ir.actions.report.xml" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_miss msgid "Mss" -msgstr "" +msgstr "Mss" #. module: base #: model:ir.model,name:base.model_ir_ui_view @@ -6916,7 +6976,7 @@ msgstr "ir.ui.view" #. module: base #: constraint:res.partner:0 msgid "Error ! You can not create recursive associated members." -msgstr "" +msgstr "Error ! You can not create recursive associated members." #. module: base #: help:res.lang,code:0 @@ -6931,7 +6991,7 @@ msgstr "OpenERP Partners" #. module: base #: model:ir.ui.menu,name:base.menu_hr_manager msgid "HR Manager Dashboard" -msgstr "" +msgstr "HR Manager Dashboard" #. module: base #: code:addons/base/module/module.py:253 @@ -6939,11 +6999,12 @@ msgstr "" msgid "" "Unable to install module \"%s\" because an external dependency is not met: %s" msgstr "" +"Unable to install module \"%s\" because an external dependency is not met: %s" #. module: base #: view:ir.module.module:0 msgid "Search modules" -msgstr "" +msgstr "Search modules" #. module: base #: model:res.country,name:base.by @@ -6968,6 +7029,10 @@ msgid "" "not connect to the system. You can assign them groups in order to give them " "specific access to the applications they need to use in the system." msgstr "" +"Create and manage users that will connect to the system. Users can be " +"deactivated should there be a period of time during which they will/should " +"not connect to the system. You can assign them groups to give them specific " +"access to the applications they need to use." #. module: base #: selection:res.request,priority:0 @@ -6983,13 +7048,13 @@ msgstr "Street2" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_update msgid "Module Update" -msgstr "" +msgstr "Module Update" #. module: base #: code:addons/base/module/wizard/base_module_upgrade.py:95 #, python-format msgid "Following modules are not installed or unknown: %s" -msgstr "" +msgstr "Following modules are not installed or unknown: %s" #. module: base #: view:ir.cron:0 @@ -7018,7 +7083,7 @@ msgstr "Open Window" #. module: base #: field:ir.actions.act_window,auto_search:0 msgid "Auto Search" -msgstr "" +msgstr "Auto Search" #. module: base #: field:ir.actions.act_window,filter:0 @@ -7064,25 +7129,25 @@ msgstr "Load" #: help:res.config.users,name:0 #: help:res.users,name:0 msgid "The new user's real name, used for searching and most listings" -msgstr "" +msgstr "The new user's real name, used for searching and most listings" #. module: base #: code:addons/osv.py:154 #: code:addons/osv.py:156 #, python-format msgid "Integrity Error" -msgstr "" +msgstr "Integrity Error" #. module: base #: model:ir.model,name:base.model_ir_wizard_screen msgid "ir.wizard.screen" -msgstr "" +msgstr "ir.wizard.screen" #. module: base #: code:addons/base/ir/ir_model.py:223 #, python-format msgid "Size of the field can never be less than 1 !" -msgstr "" +msgstr "Size of the field can never be less than 1 !" #. module: base #: model:res.country,name:base.so @@ -7092,7 +7157,7 @@ msgstr "Somalia" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Terminated" -msgstr "" +msgstr "Terminated" #. module: base #: model:res.partner.category,name:base.res_partner_category_13 @@ -7102,7 +7167,7 @@ msgstr "Important customers" #. module: base #: view:res.lang:0 msgid "Update Terms" -msgstr "" +msgstr "Update Terms" #. module: base #: field:partner.sms.send,mobile_to:0 @@ -7121,7 +7186,7 @@ msgstr "Arguments" #: code:addons/orm.py:716 #, python-format msgid "Database ID doesn't exist: %s : %s" -msgstr "" +msgstr "Database ID doesn't exist: %s : %s" #. module: base #: selection:ir.module.module,license:0 @@ -7137,7 +7202,7 @@ msgstr "GPL Version 3" #: code:addons/orm.py:836 #, python-format msgid "key '%s' not found in selection field '%s'" -msgstr "" +msgstr "key '%s' not found in selection field '%s'" #. module: base #: view:partner.wizard.ean.check:0 @@ -7148,7 +7213,7 @@ msgstr "Correct EAN13" #: code:addons/orm.py:2317 #, python-format msgid "The value \"%s\" for the field \"%s\" is not in the selection" -msgstr "" +msgstr "The value \"%s\" for the field \"%s\" is not in the selection" #. module: base #: field:res.partner,customer:0 @@ -9499,3 +9564,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russian / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Number padding" diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po index 75c938bb99f..d6ef5d0624b 100644 --- a/openerp/addons/base/i18n/es.po +++ b/openerp/addons/base/i18n/es.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-23 17:39+0000\n" -"Last-Translator: Esther Xaus (Zikzakmedia) <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:27+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5723,7 +5723,7 @@ msgstr "Traducciones" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Relleno del número" #. module: base @@ -9679,3 +9679,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ruso / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Relleno del número" diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po index f22db5e97a5..3eac408dd86 100644 --- a/openerp/addons/base/i18n/es_AR.po +++ b/openerp/addons/base/i18n/es_AR.po @@ -4778,7 +4778,7 @@ msgstr "Traducciones" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Relleno del número" #. module: base diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po index 6a7b66979ae..9a5dd8a395a 100644 --- a/openerp/addons/base/i18n/es_CL.po +++ b/openerp/addons/base/i18n/es_CL.po @@ -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: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5725,8 +5725,8 @@ msgstr "Traducciones" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" -msgstr "Relleno del número" +msgid "Number Padding" +msgstr "" #. module: base #: view:ir.actions.report.xml:0 @@ -9683,3 +9683,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ruso / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Relleno del número" diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po index 172217838e6..92d19599418 100644 --- a/openerp/addons/base/i18n/es_EC.po +++ b/openerp/addons/base/i18n/es_EC.po @@ -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: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5712,8 +5712,8 @@ msgstr "Traducciones" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" -msgstr "Relleno del número" +msgid "Number Padding" +msgstr "" #. module: base #: view:ir.actions.report.xml:0 @@ -9673,3 +9673,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russian / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Relleno del número" diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po index 6062726cdc9..fe5202aae51 100644 --- a/openerp/addons/base/i18n/et.po +++ b/openerp/addons/base/i18n/et.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-11-30 09:51+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 20:58+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5488,7 +5488,7 @@ msgstr "Tõlked" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Arvu täidistus" #. module: base @@ -9318,3 +9318,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Vene keel / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Arvu täidistus" diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po index 8b92327e5ac..af8e2ab0f78 100644 --- a/openerp/addons/base/i18n/eu.po +++ b/openerp/addons/base/i18n/eu.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po index 584d51a545e..5d1463fc39e 100644 --- a/openerp/addons/base/i18n/fa.po +++ b/openerp/addons/base/i18n/fa.po @@ -3,14 +3,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-16 08:41+0000\n" +"PO-Revision-Date: 2011-09-30 21:08+0000\n" "Last-Translator: avion <nat@sethack.com>\n" "Language-Team: OpenERP Iran <info@openerp-iran.com>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" "X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" "X-Poedit-Language: Persian\n" @@ -5496,7 +5496,7 @@ msgstr "برگردانها" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "پیمایش شمارگانی" #. module: base @@ -9330,3 +9330,6 @@ msgstr "سریلانکا" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "روسی / русский язык" + +#~ msgid "Number padding" +#~ msgstr "پیمایش شمارگانی" diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po index d730070ecf9..b19ce001779 100644 --- a/openerp/addons/base/i18n/fa_AF.po +++ b/openerp/addons/base/i18n/fa_AF.po @@ -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: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po index 16526bf9807..25048b8c81a 100644 --- a/openerp/addons/base/i18n/fi.po +++ b/openerp/addons/base/i18n/fi.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-26 13:00+0000\n" +"PO-Revision-Date: 2011-09-30 21:12+0000\n" "Last-Translator: Ville Lindfors <villi@iki.fi>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5664,7 +5664,7 @@ msgstr "Käännökset" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Täytenumerot" #. module: base @@ -9597,3 +9597,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Venäjä / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Täytenumerot" diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po index 6fb9188fd3c..256bfd053c5 100644 --- a/openerp/addons/base/i18n/fr.po +++ b/openerp/addons/base/i18n/fr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-18 12:43+0000\n" -"Last-Translator: Aline (OpenERP) <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:11+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5717,7 +5717,7 @@ msgstr "Traductions" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Remplissage" #. module: base @@ -9690,3 +9690,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russie / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Remplissage" diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po index 8547223c29c..455785414b8 100644 --- a/openerp/addons/base/i18n/gl.po +++ b/openerp/addons/base/i18n/gl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-27 08:22+0000\n" -"Last-Translator: David Diz <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:09+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: Galician <gl@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5695,7 +5695,7 @@ msgstr "Traducións" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Número de enchido" #. module: base @@ -9647,3 +9647,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Rusia / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Número de enchido" diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po index 0e14797c6ee..cbcf2390d80 100644 --- a/openerp/addons/base/i18n/he.po +++ b/openerp/addons/base/i18n/he.po @@ -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: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5472,7 +5472,7 @@ msgstr "תרגומים" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po index e82d8fb80cc..92fad63ac53 100644 --- a/openerp/addons/base/i18n/hr.po +++ b/openerp/addons/base/i18n/hr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-17 14:09+0000\n" +"PO-Revision-Date: 2011-09-30 20:43+0000\n" "Last-Translator: Goran Kliska <gkliska@gmail.com>\n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" "Language: hr\n" #. module: base @@ -5553,7 +5553,7 @@ msgstr "Prijevodi" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Dopunjavanje na duljinu" #. module: base @@ -9427,3 +9427,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ruski / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Dopunjavanje na duljinu" diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po index 043b188ece7..eee5301951b 100644 --- a/openerp/addons/base/i18n/hu.po +++ b/openerp/addons/base/i18n/hu.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-03-03 17:34+0000\n" +"PO-Revision-Date: 2011-09-30 21:29+0000\n" "Last-Translator: NOVOTRADE RENDSZERHÁZ ( novotrade.hu ) " "<openerp@novotrade.hu>\n" "Language-Team: Hungarian <openerp-hungarian-team@lists.launchpad.net>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5666,8 +5666,8 @@ msgstr "Fordítások" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" -msgstr "Number padding" +msgid "Number Padding" +msgstr "Number Padding" #. module: base #: view:ir.actions.report.xml:0 @@ -9610,3 +9610,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Orosz / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Number padding" diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po index f47eb825bc2..5ed2d1bf9ff 100644 --- a/openerp/addons/base/i18n/hy.po +++ b/openerp/addons/base/i18n/hy.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:01+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po index 969f42eb804..80ba676aada 100644 --- a/openerp/addons/base/i18n/id.po +++ b/openerp/addons/base/i18n/id.po @@ -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: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5435,7 +5435,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po index f0973c0a8e4..c0deb80c7b6 100644 --- a/openerp/addons/base/i18n/is.po +++ b/openerp/addons/base/i18n/is.po @@ -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: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po index 3a106c0498a..c2d137a9e4a 100644 --- a/openerp/addons/base/i18n/it.po +++ b/openerp/addons/base/i18n/it.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-04-28 13:32+0000\n" +"PO-Revision-Date: 2011-09-30 21:28+0000\n" "Last-Translator: Lorenzo Battistini - Agile BG - Domsense " "<lorenzo.battistini@agilebg.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5713,7 +5713,7 @@ msgstr "Traduzioni" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Riempimento Numero" #. module: base @@ -9678,3 +9678,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russian / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Riempimento Numero" diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po index 2d6310e5312..38a08080ba7 100644 --- a/openerp/addons/base/i18n/ja.po +++ b/openerp/addons/base/i18n/ja.po @@ -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: 2011-09-01 04:41+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po new file mode 100644 index 00000000000..aec7bf4f3dd --- /dev/null +++ b/openerp/addons/base/i18n/kk.po @@ -0,0 +1,9248 @@ +# Kazakh translation for openobject-server +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the openobject-server package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-server\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2011-01-11 11:14+0000\n" +"PO-Revision-Date: 2011-09-16 07:28+0000\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: Kazakh <kk@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" + +#. module: base +#: view:ir.filters:0 +#: field:ir.model.fields,domain:0 +#: field:ir.rule,domain:0 +#: field:ir.rule,domain_force:0 +#: field:res.partner.title,domain:0 +msgid "Domain" +msgstr "Домен" + +#. module: base +#: model:res.country,name:base.sh +msgid "Saint Helena" +msgstr "Әулие Елена ар." + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Other Configuration" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "DateTime" +msgstr "Күн мен уақыт" + +#. module: base +#: code:addons/fields.py:534 +#, python-format +msgid "" +"The second argument of the many2many field %s must be a SQL table !You used " +"%s, which is not a valid SQL table name." +msgstr "" + +#. module: base +#: view:ir.values:0 +#: field:ir.values,meta_unpickle:0 +msgid "Metadata" +msgstr "Метаақпарат" + +#. module: base +#: field:ir.ui.view,arch:0 +#: field:ir.ui.view.custom,arch:0 +msgid "View Architecture" +msgstr "" + +#. module: base +#: field:base.language.import,code:0 +msgid "Code (eg:en__US)" +msgstr "" + +#. module: base +#: view:workflow:0 +#: view:workflow.activity:0 +#: field:workflow.activity,wkf_id:0 +#: field:workflow.instance,wkf_id:0 +#: field:workflow.transition,wkf_id:0 +#: field:workflow.workitem,wkf_id:0 +msgid "Workflow" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "SMS - Gateway: clickatell" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hungarian / Magyar" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Not Searchable" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (VE) / Español (VE)" +msgstr "" + +#. module: base +#: field:ir.actions.server,wkf_model_id:0 +msgid "Workflow On" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,display_menu_tip:0 +msgid "Display Menu Tips" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Views" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:485 +#, python-format +msgid "" +"You can not write in this document (%s) ! Be sure your user belongs to one " +"of these groups: %s." +msgstr "" + +#. module: base +#: help:ir.model.fields,domain:0 +msgid "" +"The optional domain to restrict possible values for relationship fields, " +"specified as a Python expression defining a list of triplets. For example: " +"[('color','=','red')]" +msgstr "" + +#. module: base +#: field:res.partner,ref:0 +msgid "Reference" +msgstr "Сілтеме" + +#. module: base +#: field:ir.actions.act_window,target:0 +msgid "Target Window" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:507 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:304 +#, python-format +msgid "" +"Properties of base fields cannot be altered in this manner! Please modify " +"them through Python code, preferably through a custom addon!" +msgstr "" + +#. module: base +#: code:addons/osv.py:133 +#, python-format +msgid "Constraint Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_custom +msgid "ir.ui.view.custom" +msgstr "" + +#. module: base +#: model:res.country,name:base.sz +msgid "Swaziland" +msgstr "Свазиленд" + +#. module: base +#: code:addons/orm.py:1993 +#: code:addons/orm.py:3653 +#, python-format +msgid "created." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_woodsuppliers0 +msgid "Wood Suppliers" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:303 +#, python-format +msgid "" +"Some installed modules depend on the module you plan to Uninstall :\n" +" %s" +msgstr "" + +#. module: base +#: field:ir.sequence,number_increment:0 +msgid "Increment Number" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_tree +#: model:ir.ui.menu,name:base.menu_action_res_company_tree +msgid "Company's Structure" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Inuktitut / ᐃᓄᒃᑎᑐᑦ" +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Search Partner" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:132 +#, python-format +msgid "\"smtp_server\" needs to be set to send mails to users" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:60 +#, python-format +msgid "new" +msgstr "жаңа" + +#. module: base +#: field:ir.actions.report.xml,multi:0 +msgid "On multiple doc." +msgstr "" + +#. module: base +#: field:ir.module.category,module_nr:0 +msgid "Number of Modules" +msgstr "" + +#. module: base +#: help:multi_company.default,company_dest_id:0 +msgid "Company to store the current record" +msgstr "" + +#. module: base +#: field:res.partner.bank.type.field,size:0 +msgid "Max. Size" +msgstr "" + +#. module: base +#: field:res.partner.address,name:0 +msgid "Contact Name" +msgstr "Контакт атауы" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:56 +#, python-format +msgid "" +"Save this document to a %s file and edit it with a specific software or a " +"text editor. The file encoding is UTF-8." +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The name of the language must be unique !" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "active" +msgstr "белсенді" + +#. module: base +#: field:ir.actions.wizard,wiz_name:0 +msgid "Wizard Name" +msgstr "" + +#. module: base +#: code:addons/orm.py:2160 +#, python-format +msgid "Invalid group_by" +msgstr "" + +#. module: base +#: field:res.partner,credit_limit:0 +msgid "Credit Limit" +msgstr "" + +#. module: base +#: field:ir.model.data,date_update:0 +msgid "Update Date" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Owner" +msgstr "Иесі" + +#. module: base +#: field:ir.actions.act_window,src_model:0 +msgid "Source Object" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Config Wizard Steps" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_sc +msgid "ir.ui.view_sc" +msgstr "" + +#. module: base +#: field:res.widget.user,widget_id:0 +#: field:res.widget.wizard,widgets_list:0 +msgid "Widget" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,group_id:0 +#: view:res.config.users:0 +msgid "Group" +msgstr "Тобы" + +#. module: base +#: field:ir.exports.line,name:0 +#: field:ir.translation,name:0 +#: field:res.partner.bank.type.field,name:0 +msgid "Field Name" +msgstr "" + +#. module: base +#: wizard_view:server.action.create,init:0 +#: wizard_field:server.action.create,init,type:0 +msgid "Select Action Type" +msgstr "" + +#. module: base +#: model:res.country,name:base.tv +msgid "Tuvalu" +msgstr "Тувалу" + +#. module: base +#: selection:ir.model,state:0 +msgid "Custom Object" +msgstr "" + +#. module: base +#: field:res.lang,date_format:0 +msgid "Date Format" +msgstr "Уақыт таңба пшімі" + +#. module: base +#: field:res.bank,email:0 +#: field:res.partner.address,email:0 +msgid "E-Mail" +msgstr "Эл.поштасы" + +#. module: base +#: model:res.country,name:base.an +msgid "Netherlands Antilles" +msgstr "Нидерландияның Антиль аралдары" + +#. module: base +#: code:addons/base/res/res_user.py:389 +#, python-format +msgid "" +"You can not remove the admin user as it is used internally for resources " +"created by OpenERP (updates, module installation, ...)" +msgstr "" + +#. module: base +#: model:res.country,name:base.gf +msgid "French Guyana" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Greek / Ελληνικά" +msgstr "Греция" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bosnian / bosanski jezik" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,attachment_use:0 +msgid "" +"If you check this, then the second time the user prints with same attachment " +"name, it returns the previous report." +msgstr "" + +#. module: base +#: code:addons/orm.py:904 +#, python-format +msgid "The read method is not implemented on this object !" +msgstr "" + +#. module: base +#: help:res.lang,iso_code:0 +msgid "This ISO code is the name of po files to use for translations" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Your system will be updated." +msgstr "" + +#. module: base +#: field:ir.actions.todo,note:0 +#: selection:ir.property,type:0 +msgid "Text" +msgstr "Мәтін" + +#. module: base +#: field:res.country,name:0 +msgid "Country Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.co +msgid "Colombia" +msgstr "Колумбия" + +#. module: base +#: view:ir.module.module:0 +msgid "Schedule Upgrade" +msgstr "" + +#. module: base +#: code:addons/orm.py:838 +#, python-format +msgid "Key/value '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: help:res.country,code:0 +msgid "" +"The ISO country code in two chars.\n" +"You can use this field for quick search." +msgstr "" + +#. module: base +#: model:res.country,name:base.pw +msgid "Palau" +msgstr "Палау" + +#. module: base +#: view:res.partner:0 +msgid "Sales & Purchases" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Untranslated" +msgstr "Аударылмаған" + +#. module: base +#: help:ir.actions.act_window,context:0 +msgid "" +"Context dictionary as Python expression, empty by default (Default: {})" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_wizard +#: view:ir.actions.wizard:0 +#: model:ir.ui.menu,name:base.menu_ir_action_wizard +msgid "Wizards" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_miscellaneoussuppliers0 +msgid "Miscellaneous Suppliers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:255 +#, python-format +msgid "Custom fields must have a name that starts with 'x_' !" +msgstr "" + +#. module: base +#: help:ir.actions.server,action_id:0 +msgid "Select the Action Window, Report, Wizard to be executed." +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "New User" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export done" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Model Description" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,src_model:0 +msgid "" +"Optional model name of the objects on which this action should be visible" +msgstr "" + +#. module: base +#: field:workflow.transition,trigger_expr_id:0 +msgid "Trigger Expression" +msgstr "" + +#. module: base +#: model:res.country,name:base.jo +msgid "Jordan" +msgstr "Хордан" + +#. module: base +#: view:ir.module.module:0 +msgid "Certified" +msgstr "" + +#. module: base +#: model:res.country,name:base.er +msgid "Eritrea" +msgstr "Эритрея" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "description" +msgstr "сипаттамасы" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_action_rule +msgid "Automated Actions" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_actions +msgid "ir.actions.actions" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Want to check Ean ? " +msgstr "" + +#. module: base +#: field:ir.values,key2:0 +msgid "Event Type" +msgstr "Оқиға түрі" + +#. module: base +#: view:base.language.export:0 +msgid "" +"OpenERP translations (core, modules, clients) are managed through " +"Launchpad.net, our open source project management facility. We use their " +"online interface to synchronize all translations efforts." +msgstr "" + +#. module: base +#: field:res.partner,title:0 +msgid "Partner Form" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Swedish / svenska" +msgstr "" + +#. module: base +#: model:res.country,name:base.rs +msgid "Serbia" +msgstr "Сербия" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard View" +msgstr "" + +#. module: base +#: model:res.country,name:base.kh +msgid "Cambodia, Kingdom of" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_form +#: view:ir.sequence:0 +#: model:ir.ui.menu,name:base.menu_ir_sequence_form +#: model:ir.ui.menu,name:base.next_id_5 +msgid "Sequences" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_import +msgid "Language Import" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_users +msgid "res.config.users" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Albanian / Shqip" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_opportunity +msgid "Opportunities" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_export +msgid "base.language.export" +msgstr "" + +#. module: base +#: model:res.country,name:base.pg +msgid "Papua New Guinea" +msgstr "Папуа - Жаңа Гвинея" + +#. module: base +#: help:ir.actions.report.xml,report_type:0 +msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_4 +msgid "Basic Partner" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "," +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "My Partners" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "XML Report" +msgstr "" + +#. module: base +#: model:res.country,name:base.es +msgid "Spain" +msgstr "Испания" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_export +msgid "Import / Export" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,domain:0 +msgid "" +"Optional domain filtering of the destination data, as a Python expression" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade +#: model:ir.model,name:base.model_base_module_upgrade +msgid "Module Upgrade" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "" +"Groups are used to define access rights on objects and the visibility of " +"screens and menus" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (UY) / Español (UY)" +msgstr "" + +#. module: base +#: field:res.partner,mobile:0 +#: field:res.partner.address,mobile:0 +msgid "Mobile" +msgstr "Қалтафон" + +#. module: base +#: model:res.country,name:base.om +msgid "Oman" +msgstr "Оман" + +#. module: base +#: model:ir.actions.act_window,name:base.action_payterm_form +#: model:ir.model,name:base.model_res_payterm +msgid "Payment term" +msgstr "" + +#. module: base +#: model:res.country,name:base.nu +msgid "Niue" +msgstr "Ниуэ" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Work Days" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other OSI Approved Licence" +msgstr "" + +#. module: base +#: help:res.config.users,context_lang:0 +#: help:res.users,context_lang:0 +msgid "" +"Sets the language for the user's user interface, when UI translations are " +"available" +msgstr "" + +#. module: base +#: code:addons/orm.py:1043 +#, python-format +msgid "The unlink method is not implemented on this object !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_menu_create +#: view:wizard.ir.model.menu.create:0 +msgid "Create Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.in +msgid "India" +msgstr "Үндістан" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request_link-act +#: model:ir.ui.menu,name:base.menu_res_request_link_act +msgid "Request Reference Types" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "client_action_multi, client_action_relate" +msgstr "" + +#. module: base +#: model:res.country,name:base.ad +msgid "Andorra, Principality of" +msgstr "Андорра" + +#. module: base +#: field:ir.module.category,child_ids:0 +#: field:res.partner.category,child_ids:0 +msgid "Child Categories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_config_parameter +msgid "ir.config_parameter" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "TGZ Archive" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%B - Full month name." +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: field:ir.attachment,type:0 +#: field:ir.model,state:0 +#: field:ir.model.fields,state:0 +#: field:ir.property,type:0 +#: field:ir.server.object.lines,type:0 +#: field:ir.translation,type:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: field:ir.values,key:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Type" +msgstr "Түрі" + +#. module: base +#: code:addons/orm.py:210 +#, python-format +msgid "" +"Language with code \"%s\" is not defined in your system !\n" +"Define it through the Administration menu." +msgstr "" + +#. module: base +#: model:res.country,name:base.gu +msgid "Guam (USA)" +msgstr "Гуам (АҚШ)" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_project +msgid "Human Resources Dashboard" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:507 +#, python-format +msgid "Setting empty passwords is not allowed for security reasons!" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +#: selection:workflow.activity,kind:0 +msgid "Dummy" +msgstr "Жай" + +#. module: base +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ky +msgid "Cayman Islands" +msgstr "Кайман ар-ы" + +#. module: base +#: model:res.country,name:base.kr +msgid "South Korea" +msgstr "Корей Республикасы" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_transition_form +#: model:ir.ui.menu,name:base.menu_workflow_transition +#: view:workflow.activity:0 +msgid "Transitions" +msgstr "" + +#. module: base +#: code:addons/orm.py:4020 +#, python-format +msgid "Record #%d of %s not found, cannot copy!" +msgstr "" + +#. module: base +#: field:ir.module.module,contributors:0 +msgid "Contributors" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Char" +msgstr "Симв." + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract +msgid "Contracts" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (AR) / Español (AR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.ug +msgid "Uganda" +msgstr "Уганда" + +#. module: base +#: field:ir.model.access,perm_unlink:0 +msgid "Delete Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.ne +msgid "Niger" +msgstr "Нигер" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (HK)" +msgstr "" + +#. module: base +#: model:res.country,name:base.ba +msgid "Bosnia-Herzegovina" +msgstr "Босния және Герцоговина" + +#. module: base +#: view:base.language.export:0 +msgid "" +"To improve or expand the official translations, you should use directly " +"Lauchpad's web interface (Rosetta). If you need to perform mass translation, " +"Launchpad also allows uploading full .po files at once" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (GT) / Español (GT)" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "" +"%W - Week number of the year (Monday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Monday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: field:ir.module.module,website:0 +#: field:res.partner,website:0 +msgid "Website" +msgstr "Веб сайт" + +#. module: base +#: model:res.country,name:base.gs +msgid "S. Georgia & S. Sandwich Isls." +msgstr "" + +#. module: base +#: field:ir.actions.url,url:0 +msgid "Action URL" +msgstr "" + +#. module: base +#: field:base.module.import,module_name:0 +msgid "Module Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.mh +msgid "Marshall Islands" +msgstr "Маршалл аралдары" + +#. module: base +#: code:addons/base/ir/ir_model.py:328 +#, python-format +msgid "Changing the model of a field is forbidden!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ht +msgid "Haiti" +msgstr "Гаити" + +#. module: base +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +msgid "Search" +msgstr "Іздеу" + +#. module: base +#: code:addons/osv.py:136 +#, python-format +msgid "" +"The operation cannot be completed, probably due to the following:\n" +"- deletion: you may be trying to delete a record while other records still " +"reference it\n" +"- creation/update: a mandatory field is not correctly set" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"2. Group-specific rules are combined together with a logical AND operator" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:206 +#, python-format +msgid "Operation Canceled" +msgstr "" + +#. module: base +#: help:base.language.export,lang:0 +msgid "To export a new language, do not select a language." +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Request Date" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_dasboard +msgid "Dashboard" +msgstr "Аспаптар панелі" + +#. module: base +#: model:ir.ui.menu,name:base.menu_purchase_root +msgid "Purchases" +msgstr "" + +#. module: base +#: model:res.country,name:base.md +msgid "Moldavia" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Features" +msgstr "Мүмкіндіктер" + +#. module: base +#: view:ir.module.module:0 +#: report:ir.module.reference.graph:0 +msgid "Version" +msgstr "Нұсқа" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_read:0 +#: view:ir.rule:0 +msgid "Read Access" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports +msgid "ir.exports" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "No language with code \"%s\" exists" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#, python-format +msgid "Error during communication with the publisher warranty server." +msgstr "" + +#. module: base +#: help:ir.actions.server,email:0 +msgid "" +"Provides the fields that will be used to fetch the email address, e.g. when " +"you select the invoice, then `object.invoice_address_id.email` is the field " +"which gives the correct address" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%Y - Year with century." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "-" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "" +"This wizard helps you register a publisher warranty contract in your OpenERP " +"system. After the contract has been registered, you will be able to send " +"issues directly to OpenERP." +msgstr "" + +#. module: base +#: code:addons/orm.py:1744 +#, python-format +msgid "The search method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:wizard.ir.model.menu.create:0 +msgid "Create _Menu" +msgstr "" + +#. module: base +#: field:res.payterm,name:0 +msgid "Payment Term (short name)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_bank +#: view:res.bank:0 +#: field:res.partner.bank,bank:0 +msgid "Bank" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports_line +msgid "ir.exports.line" +msgstr "" + +#. module: base +#: help:base.language.install,overwrite:0 +msgid "" +"If you check this box, your customized translations will be overwritten and " +"replaced by the official ones." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml:0 +msgid "Main report file path" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_report_xml +#: field:ir.module.module,reports_by_module:0 +#: model:ir.ui.menu,name:base.menu_ir_action_report_xml +msgid "Reports" +msgstr "" + +#. module: base +#: help:ir.actions.act_window.view,multi:0 +#: help:ir.actions.report.xml,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: field:workflow,on_create:0 +msgid "On Create" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:607 +#, python-format +msgid "" +"'%s' contains too many dots. XML ids should not contain dots ! These are " +"used to refer to other modules data, as in module.reference_id" +msgstr "" + +#. module: base +#: field:partner.sms.send,user:0 +#: field:res.config.users,login:0 +#: field:res.users,login:0 +msgid "Login" +msgstr "Кіру" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Access all the fields related to the current object using expressions, i.e. " +"object.partner_id.name " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country_state +msgid "Country state" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Float" +msgstr "Қалқымалы" + +#. module: base +#: model:ir.model,name:base.model_res_request_link +msgid "res.request.link" +msgstr "" + +#. module: base +#: field:ir.actions.wizard,name:0 +msgid "Wizard Info" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: model:ir.actions.act_window,name:base.action_wizard_lang_export +#: model:ir.ui.menu,name:base.menu_wizard_lang_export +msgid "Export Translation" +msgstr "" + +#. module: base +#: help:res.log,secondary:0 +msgid "" +"Do not display this log if it belongs to the same object the user is working " +"on" +msgstr "" + +#. module: base +#: model:res.country,name:base.tp +msgid "East Timor" +msgstr "Шығыс Тимор" + +#. module: base +#: model:res.company,follow_up_msg:base.main_company +msgid "" +"Date : %(date)s\n" +"\n" +"Dear %(partner_name)s,\n" +"\n" +"Please find in attachment a reminder of all your unpaid invoices, for a " +"total amount due of:\n" +"\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"Thanks,\n" +"--\n" +"%(user_signature)s\n" +"%(company_name)s" +msgstr "" + +#. module: base +#: field:res.currency,accuracy:0 +msgid "Computational Accuracy" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Sinhalese / සිංහල" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create_line +msgid "wizard.ir.model.menu.create.line" +msgstr "" + +#. module: base +#: field:ir.attachment,res_id:0 +msgid "Attached ID" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day: %(day)s" +msgstr "" + +#. module: base +#: model:res.country,name:base.mv +msgid "Maldives" +msgstr "Мальдив ар-ы" + +#. module: base +#: help:ir.values,res_id:0 +msgid "Keep 0 if the action must appear on all resources." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_rule +msgid "ir.rule" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Days" +msgstr "күн" + +#. module: base +#: help:ir.actions.server,condition:0 +msgid "" +"Condition that is to be tested before action is executed, e.g. " +"object.list_price > object.cost_price" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:155 +#: code:addons/base/res/res_company.py:66 +#, python-format +msgid " (copy)" +msgstr " (көшірме)" + +#. module: base +#: view:res.lang:0 +msgid "7. %H:%M:%S ==> 18:25:20" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.category:0 +#: field:res.partner.category,partner_ids:0 +msgid "Partners" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_left:0 +msgid "Left parent" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_act_window +msgid "Homepage Widgets" +msgstr "" + +#. module: base +#: help:ir.actions.server,message:0 +msgid "" +"Specify the message. You can use the fields from the object. e.g. `Dear [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: field:ir.attachment,res_model:0 +msgid "Attached Model" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Domain Setup" +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_name:0 +msgid "Trigger Name" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_model_access +msgid "ir.model.access" +msgstr "" + +#. module: base +#: field:ir.cron,priority:0 +#: field:res.request,priority:0 +#: field:res.request.link,priority:0 +msgid "Priority" +msgstr "Маңыздылығы" + +#. module: base +#: field:workflow.transition,act_from:0 +msgid "Source Activity" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Legend (for prefix, suffix)" +msgstr "" + +#. module: base +#: selection:ir.server.object.lines,type:0 +msgid "Formula" +msgstr "Формула" + +#. module: base +#: code:addons/base/res/res_user.py:389 +#, python-format +msgid "Can not remove root user!" +msgstr "" + +#. module: base +#: model:res.country,name:base.mw +msgid "Malawi" +msgstr "Малави" + +#. module: base +#: code:addons/base/res/res_user.py:51 +#: code:addons/base/res/res_user.py:413 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: base +#: field:res.partner.address,type:0 +msgid "Address Type" +msgstr "" + +#. module: base +#: view:ir.ui.menu:0 +msgid "Full Path" +msgstr "Толық жолы" + +#. module: base +#: view:res.request:0 +msgid "References" +msgstr "References" + +#. module: base +#: view:res.lang:0 +msgid "" +"%U - Week number of the year (Sunday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Sunday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Advanced" +msgstr "Жетелеу" + +#. module: base +#: model:res.country,name:base.fi +msgid "Finland" +msgstr "Финляндия" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Tree" +msgstr "Бұтақ" + +#. module: base +#: help:res.config.users,password:0 +msgid "" +"Keep empty if you don't want the user to be able to connect on the system." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Create / Write / Copy" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://help.launchpad.net/Translations" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_mode:0 +msgid "View Mode" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"When using CSV format, please also check that the first line of your file is " +"one of the following:" +msgstr "" + +#. module: base +#: code:addons/fields.py:114 +#, python-format +msgid "Not implemented search_memory method !" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Logs" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish / Español" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KP) / 한국어 (KP)" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "" +"This wizard will scan all module repositories on the server side to detect " +"newly added modules as well as any change to existing modules." +msgstr "" + +#. module: base +#: field:res.company,logo:0 +msgid "Logo" +msgstr "" + +#. module: base +#: view:res.partner.address:0 +msgid "Search Contact" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Uninstall (beta)" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +#: selection:ir.actions.url,target:0 +msgid "New Window" +msgstr "" + +#. module: base +#: model:res.country,name:base.bs +msgid "Bahamas" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:250 +#, python-format +msgid "" +"Couldn't generate the next id because some partners have an alphabetic id !" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attachment" +msgstr "" + +#. module: base +#: model:res.country,name:base.ie +msgid "Ireland" +msgstr "" + +#. module: base +#: field:base.module.update,update:0 +msgid "Number of modules updated" +msgstr "" + +#. module: base +#: code:addons/fields.py:100 +#, python-format +msgid "Not implemented set_memory method !" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +msgid "Workflow Activity" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND " +"GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view +msgid "" +"Views allows you to personalize each view of OpenERP. You can add new " +"fields, move fields, rename them or delete the ones that you do not need." +msgstr "" + +#. module: base +#: field:ir.actions.act_window,groups_id:0 +#: model:ir.actions.act_window,name:base.action_res_groups +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,groups_id:0 +#: view:ir.actions.todo:0 +#: field:ir.actions.todo,groups_id:0 +#: field:ir.actions.wizard,groups_id:0 +#: view:ir.model:0 +#: field:ir.model.fields,groups:0 +#: field:ir.rule,groups:0 +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,groups_id:0 +#: model:ir.ui.menu,name:base.menu_action_res_groups +#: field:res.config.users,groups_id:0 +#: view:res.groups:0 +#: view:res.users:0 +#: field:res.users,groups_id:0 +msgid "Groups" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CL) / Español (CL)" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "" +"Create additional users and assign them groups that will allow them to have " +"access to selected functionalities within the system. Click on 'Done' if you " +"do not wish to add more users at this stage, you can always do this later." +msgstr "" + +#. module: base +#: model:res.country,name:base.bz +msgid "Belize" +msgstr "" + +#. module: base +#: model:res.country,name:base.ge +msgid "Georgia" +msgstr "" + +#. module: base +#: model:res.country,name:base.pl +msgid "Poland" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,view_mode:0 +msgid "" +"Comma-separated list of allowed view modes, such as 'form', 'tree', " +"'calendar', etc. (Default: tree,form)" +msgstr "" + +#. module: base +#: code:addons/orm.py:3147 +#, python-format +msgid "A document was modified since you last viewed it (%s:%d)" +msgstr "" + +#. module: base +#: view:workflow:0 +msgid "Workflow Editor" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be removed" +msgstr "Жоюға" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence +msgid "ir.sequence" +msgstr "" + +#. module: base +#: help:ir.actions.server,expression:0 +msgid "" +"Enter the field/expression that will return the list. E.g. select the sale " +"order in Object, and you can have loop on the sales order line. Expression = " +"`object.order_line`." +msgstr "" + +#. module: base +#: field:ir.property,fields_id:0 +#: selection:ir.translation,type:0 +#: field:multi_company.default,field_id:0 +msgid "Field" +msgstr "Өріс" + +#. module: base +#: view:ir.rule:0 +msgid "Groups (no group = global)" +msgstr "" + +#. module: base +#: model:res.country,name:base.fo +msgid "Faroe Islands" +msgstr "Форд-Айленд" + +#. module: base +#: selection:res.config.users,view:0 +#: selection:res.config.view,view:0 +#: selection:res.users,view:0 +msgid "Simplified" +msgstr "" + +#. module: base +#: model:res.country,name:base.st +msgid "Saint Tome (Sao Tome) and Principe" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Invoice" +msgstr "Инвойс" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese (BR) / Português (BR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bb +msgid "Barbados" +msgstr "Барбадос" + +#. module: base +#: model:res.country,name:base.mg +msgid "Madagascar" +msgstr "Мадагаскар" + +#. module: base +#: code:addons/base/ir/ir_model.py:96 +#, python-format +msgid "" +"The Object name must start with x_ and not contain any special character !" +msgstr "" + +#. module: base +#: field:ir.actions.configuration.wizard,note:0 +msgid "Next Wizard" +msgstr "Келесі" + +#. module: base +#: model:ir.actions.act_window,name:base.action_menu_admin +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,name:0 +msgid "Menu" +msgstr "Мәзір" + +#. module: base +#: field:res.currency,rate:0 +msgid "Current Rate" +msgstr "" + +#. module: base +#: field:ir.ui.view.custom,ref_id:0 +msgid "Original View" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action To Launch" +msgstr "" + +#. module: base +#: field:ir.actions.url,target:0 +msgid "Action Target" +msgstr "" + +#. module: base +#: model:res.country,name:base.ai +msgid "Anguilla" +msgstr "Ангилья" + +#. module: base +#: field:ir.ui.view_sc,name:0 +msgid "Shortcut Name" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,limit:0 +msgid "Default limit for the list view" +msgstr "" + +#. module: base +#: help:ir.actions.server,write_id:0 +msgid "" +"Provide the field name that the record id refers to for the write operation. " +"If it is empty it will refer to the active id of the object." +msgstr "" + +#. module: base +#: model:res.country,name:base.zw +msgid "Zimbabwe" +msgstr "Зимбабве" + +#. module: base +#: view:base.module.update:0 +msgid "Please be patient, as this operation may take a few seconds..." +msgstr "" + +#. module: base +#: help:ir.values,action_id:0 +msgid "This field is not used, it only helps you to select the right action." +msgstr "" + +#. module: base +#: field:ir.actions.server,email:0 +msgid "Email Address" +msgstr "Эл.пошта адресі" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (BE) / Français (BE)" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: field:workflow.activity,action_id:0 +msgid "Server Action" +msgstr "" + +#. module: base +#: model:res.country,name:base.tt +msgid "Trinidad and Tobago" +msgstr "Тринидад және Тобаго" + +#. module: base +#: model:res.country,name:base.lv +msgid "Latvia" +msgstr "Латвия" + +#. module: base +#: view:ir.values:0 +msgid "Values" +msgstr "Мәндері" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mappings" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export Translations" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom +msgid "Customization" +msgstr "Жекелендіру" + +#. module: base +#: model:res.country,name:base.py +msgid "Paraguay" +msgstr "Парагвай" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_close +msgid "ir.actions.act_window_close" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,col1:0 +msgid "Destination" +msgstr "Қайда:" + +#. module: base +#: model:res.country,name:base.lt +msgid "Lithuania" +msgstr "Литва" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_clear_ids +#: model:ir.model,name:base.model_partner_clear_ids +#: view:partner.clear.ids:0 +msgid "Clear IDs" +msgstr "" + +#. module: base +#: help:ir.cron,model:0 +msgid "" +"Name of object whose function will be called when this scheduler will run. " +"e.g. 'res.partener'" +msgstr "" + +#. module: base +#: code:addons/orm.py:1040 +#, python-format +msgid "The perm_read method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%y - Year without century [00,99]." +msgstr "" + +#. module: base +#: model:res.country,name:base.si +msgid "Slovenia" +msgstr "Словения" + +#. module: base +#: model:res.country,name:base.pk +msgid "Pakistan" +msgstr "Пәкістан" + +#. module: base +#: code:addons/orm.py:1350 +#, python-format +msgid "Invalid Object Architecture!" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_email_gateway_form +msgid "Messages" +msgstr "Хаттар" + +#. module: base +#: code:addons/base/ir/ir_model.py:303 +#: code:addons/base/ir/ir_model.py:317 +#: code:addons/base/ir/ir_model.py:319 +#: code:addons/base/ir/ir_model.py:321 +#: code:addons/base/ir/ir_model.py:328 +#: code:addons/base/ir/ir_model.py:331 +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "Error!" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%p - Equivalent of either AM or PM." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Actions" +msgstr "" + +#. module: base +#: help:multi_company.default,company_id:0 +msgid "Company where the user is connected" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_stop:0 +msgid "Ending Date" +msgstr "" + +#. module: base +#: model:res.country,name:base.nz +msgid "New Zealand" +msgstr "Жаңа Зеландия" + +#. module: base +#: code:addons/orm.py:3366 +#, python-format +msgid "" +"One of the records you are trying to modify has already been deleted " +"(Document type: %s)." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country +msgid "" +"Display and manage the list of all countries that can be assigned to your " +"partner records. You can create or delete countries to make sure the ones " +"you are working on will be maintained." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_7 +msgid "Openstuff.net" +msgstr "" + +#. module: base +#: model:res.country,name:base.nf +msgid "Norfolk Island" +msgstr "Норфолк аралы" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KR) / 한국어 (KR)" +msgstr "" + +#. module: base +#: help:ir.model.fields,model:0 +msgid "The technical name of the model this field belongs to" +msgstr "" + +#. module: base +#: field:ir.actions.server,action_id:0 +#: selection:ir.actions.server,state:0 +msgid "Client Action" +msgstr "" + +#. module: base +#: model:res.country,name:base.bd +msgid "Bangladesh" +msgstr "Бангладеш" + +#. module: base +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Valid" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "XSL" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:322 +#, python-format +msgid "Can not upgrade module '%s'. It is not installed." +msgstr "" + +#. module: base +#: model:res.country,name:base.cu +msgid "Cuba" +msgstr "Куба" + +#. module: base +#: model:ir.model,name:base.model_res_partner_event +msgid "res.partner.event" +msgstr "" + +#. module: base +#: model:res.widget,title:base.facebook_widget +msgid "Facebook" +msgstr "" + +#. module: base +#: model:res.country,name:base.am +msgid "Armenia" +msgstr "Армения" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_property_form +#: model:ir.ui.menu,name:base.menu_ir_property_form_all +msgid "Configuration Parameters" +msgstr "" + +#. module: base +#: constraint:ir.cron:0 +msgid "Invalid arguments" +msgstr "" + +#. module: base +#: model:res.country,name:base.se +msgid "Sweden" +msgstr "Швеция" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Gantt" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Property" +msgstr "Қасиеті" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type +#: view:res.partner.bank.type:0 +msgid "Bank Account Type" +msgstr "" + +#. module: base +#: field:base.language.export,config_logo:0 +#: field:base.language.import,config_logo:0 +#: field:base.language.install,config_logo:0 +#: field:base.module.import,config_logo:0 +#: field:base.module.update,config_logo:0 +#: field:base.update.translations,config_logo:0 +#: field:ir.actions.configuration.wizard,config_logo:0 +#: field:ir.wizard.screen,config_logo:0 +#: field:publisher_warranty.contract.wizard,config_logo:0 +#: field:res.config,config_logo:0 +#: field:res.config.installer,config_logo:0 +#: field:res.config.users,config_logo:0 +#: field:res.config.view,config_logo:0 +msgid "Image" +msgstr "Сурет" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Action Configuration" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Canceled" +msgstr "Болмайтын" + +#. module: base +#: model:res.country,name:base.at +msgid "Austria" +msgstr "Аустрия" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "done" +msgstr "орындалды" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: model:ir.ui.menu,name:base.menu_calendar_configuration +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Calendar" +msgstr "Күнтізбе" + +#. module: base +#: field:res.partner.address,partner_id:0 +msgid "Partner Name" +msgstr "" + +#. module: base +#: field:workflow.activity,signal_send:0 +msgid "Signal (subflow.*)" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_17 +msgid "HR sector" +msgstr "" + +#. module: base +#: code:addons/orm.py:3817 +#, python-format +msgid "" +"Invalid \"order\" specified. A valid \"order\" specification is a comma-" +"separated list of valid field names (optionally followed by asc/desc for the " +"direction)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module_dependency +msgid "Module dependency" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Draft" +msgstr "Жоба" + +#. module: base +#: selection:res.config.users,view:0 +#: selection:res.config.view,view:0 +#: selection:res.users,view:0 +msgid "Extended" +msgstr "Кеңейтілген" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_contact +msgid "" +"Manage the contact titles you want to have available in your system and the " +"way you want to print them in letters and other documents. Some example: " +"Mr., Mrs. " +msgstr "" + +#. module: base +#: field:res.company,rml_footer1:0 +msgid "Report Footer 1" +msgstr "" + +#. module: base +#: field:res.company,rml_footer2:0 +msgid "Report Footer 2" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:res.groups:0 +#: field:res.groups,model_access:0 +msgid "Access Controls" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,dependencies_id:0 +msgid "Dependencies" +msgstr "Тәуеліділіктер" + +#. module: base +#: field:multi_company.default,company_id:0 +msgid "Main Company" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_hover:0 +msgid "Web Icon File (hover)" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"If you use a formula type, use a python expression using the variable " +"'object'." +msgstr "" + +#. module: base +#: field:res.partner.address,birthdate:0 +msgid "Birthdate" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_contact +#: model:ir.ui.menu,name:base.menu_partner_title_contact +msgid "Contact Titles" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Please double-check that the file encoding is set to UTF-8 (sometimes called " +"Unicode) when the translator exports it." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (DO) / Español (DO)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_activity +msgid "workflow.activity" +msgstr "" + +#. module: base +#: help:ir.ui.view_sc,res_id:0 +msgid "" +"Reference of the target resource, whose model/table depends on the 'Resource " +"Name' field." +msgstr "" + +#. module: base +#: field:ir.model.fields,select_level:0 +msgid "Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.uy +msgid "Uruguay" +msgstr "Уругвай" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Finnish / Suomi" +msgstr "" + +#. module: base +#: field:ir.rule,perm_write:0 +msgid "Apply For Write" +msgstr "" + +#. module: base +#: field:ir.sequence,prefix:0 +msgid "Prefix" +msgstr "Префикс" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "German / Deutsch" +msgstr "" + +#. module: base +#: help:ir.actions.server,trigger_name:0 +msgid "Select the Signal name that is to be used as the trigger." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Fields Mapping" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese / Português" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_sir +msgid "Sir" +msgstr "" + +#. module: base +#: code:addons/orm.py:1622 +#, python-format +msgid "There is no view of type '%s' defined for the structure!" +msgstr "" + +#. module: base +#: field:ir.default,ref_id:0 +msgid "ID Ref." +msgstr "" + +#. module: base +#: model:ir.actions.server,name:base.action_start_configurator +#: model:ir.ui.menu,name:base.menu_view_base_module_configuration +msgid "Start Configuration" +msgstr "" + +#. module: base +#: model:res.country,name:base.mt +msgid "Malta" +msgstr "Мальта" + +#. module: base +#: field:ir.actions.server,fields_lines:0 +msgid "Field Mappings." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module +#: view:ir.model.data:0 +#: field:ir.model.data,module:0 +#: view:ir.module.module:0 +#: field:ir.module.module.dependency,module_id:0 +#: report:ir.module.reference.graph:0 +#: field:ir.translation,module:0 +msgid "Module" +msgstr "Модулі" + +#. module: base +#: field:ir.attachment,description:0 +#: view:ir.module.module:0 +#: field:ir.module.module,description:0 +#: field:res.partner.bank,name:0 +#: view:res.partner.event:0 +#: field:res.partner.event,description:0 +#: view:res.request:0 +msgid "Description" +msgstr "Сипаттамасы" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_instance_form +#: model:ir.ui.menu,name:base.menu_workflow_instance +msgid "Instances" +msgstr "" + +#. module: base +#: model:res.country,name:base.aq +msgid "Antarctica" +msgstr "Антарктика" + +#. module: base +#: field:ir.actions.report.xml,auto:0 +msgid "Custom python parser" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "_Import" +msgstr "И_мпорттау" + +#. module: base +#: view:res.partner.canal:0 +msgid "Channel" +msgstr "Канал" + +#. module: base +#: field:res.lang,grouping:0 +msgid "Separator Format" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Unvalidated" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_9 +msgid "Database Structure" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_mass_mail +#: model:ir.model,name:base.model_partner_wizard_spam +#: view:partner.wizard.spam:0 +msgid "Mass Mailing" +msgstr "" + +#. module: base +#: model:res.country,name:base.yt +msgid "Mayotte" +msgstr "Майотта" + +#. module: base +#: code:addons/base/ir/ir_actions.py:597 +#, python-format +msgid "Please specify an action to launch !" +msgstr "" + +#. module: base +#: view:res.payterm:0 +msgid "Payment Term" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Right-to-Left" +msgstr "Оңнан солға" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.actions_ir_filters_view +#: view:ir.filters:0 +#: model:ir.model,name:base.model_ir_filters +#: model:ir.ui.menu,name:base.menu_ir_filters +msgid "Filters" +msgstr "Сүзгілер" + +#. module: base +#: code:addons/orm.py:758 +#, python-format +msgid "Please check that all your lines have %d columns." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_cron_act +#: view:ir.cron:0 +#: model:ir.ui.menu,name:base.menu_ir_cron_act +msgid "Scheduled Actions" +msgstr "" + +#. module: base +#: field:res.partner.address,title:0 +#: field:res.partner.title,name:0 +#: field:res.widget,title:0 +msgid "Title" +msgstr "Атауы" + +#. module: base +#: help:ir.property,res_id:0 +msgid "If not set, acts as a default value for new resources" +msgstr "" + +#. module: base +#: code:addons/orm.py:3448 +#, python-format +msgid "Recursivity Detected." +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:262 +#, python-format +msgid "Recursion error in modules dependencies !" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"This wizard helps you add a new language to your OpenERP system. After " +"loading a new language it becomes available as default interface language " +"for users and partners." +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Create a Menu" +msgstr "" + +#. module: base +#: help:res.partner,vat:0 +msgid "" +"Value Added Tax number. Check the box if the partner is subjected to the " +"VAT. Used by the VAT legal statement." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_maintenance_contract +msgid "maintenance.contract" +msgstr "" + +#. module: base +#: model:res.country,name:base.ru +msgid "Russian Federation" +msgstr "Ресей" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Urdu / اردو" +msgstr "" + +#. module: base +#: field:res.company,name:0 +msgid "Company Name" +msgstr "Компаниясының атауы" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country +#: model:ir.ui.menu,name:base.menu_country_partner +msgid "Countries" +msgstr "Елдер" + +#. module: base +#: selection:ir.translation,type:0 +msgid "RML (deprecated - use Report)" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Record rules" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Field Information" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Search Actions" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check +#: view:partner.wizard.ean.check:0 +msgid "Ean check" +msgstr "" + +#. module: base +#: field:res.partner,vat:0 +msgid "VAT" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "12. %w ==> 5 ( Friday is the 6th day)" +msgstr "" + +#. module: base +#: constraint:res.partner.category:0 +msgid "Error ! You can not create recursive categories." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%x - Appropriate date representation." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%d - Day of the month [01,31]." +msgstr "" + +#. module: base +#: model:res.country,name:base.tj +msgid "Tajikistan" +msgstr "Тәжікстан" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-2 or later version" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_sir +msgid "M." +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:429 +#, python-format +msgid "" +"Can not create the module file:\n" +" %s" +msgstr "" + +#. module: base +#: code:addons/orm.py:2973 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: read, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.nr +msgid "Nauru" +msgstr "Науру" + +#. module: base +#: code:addons/base/module/module.py:200 +#, python-format +msgid "The certificate ID of the module must be unique !" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_property +msgid "ir.property" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Form" +msgstr "Пішін" + +#. module: base +#: model:res.country,name:base.me +msgid "Montenegro" +msgstr "Черногория" + +#. module: base +#: view:ir.cron:0 +msgid "Technical Data" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,category_id:0 +msgid "Categories" +msgstr "Категориялар" + +#. module: base +#: view:base.language.import:0 +msgid "" +"If you need another language than the official ones available, you can " +"import a language pack from here. Other OpenERP languages than the official " +"ones can be found on launchpad." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be upgraded" +msgstr "" + +#. module: base +#: model:res.country,name:base.ly +msgid "Libya" +msgstr "Ливия" + +#. module: base +#: model:res.country,name:base.cf +msgid "Central African Republic" +msgstr "Орталық Африка Республикасы" + +#. module: base +#: model:res.country,name:base.li +msgid "Liechtenstein" +msgstr "Лихтенштейн" + +#. module: base +#: model:ir.model,name:base.model_partner_sms_send +#: view:partner.sms.send:0 +msgid "Send SMS" +msgstr "SMS жіберу" + +#. module: base +#: field:res.partner,ean13:0 +msgid "EAN13" +msgstr "" + +#. module: base +#: code:addons/orm.py:1622 +#, python-format +msgid "Invalid Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.pt +msgid "Portugal" +msgstr "Португалия" + +#. module: base +#: sql_constraint:ir.model.data:0 +msgid "" +"You cannot have multiple records with the same id for the same module !" +msgstr "" + +#. module: base +#: field:ir.module.module,certificate:0 +msgid "Quality Certificate" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "6. %d, %m ==> 05, 12" +msgstr "" + +#. module: base +#: field:res.config.users,date:0 +#: field:res.users,date:0 +msgid "Last Connection" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,help:0 +msgid "Action description" +msgstr "" + +#. module: base +#: help:res.partner,customer:0 +msgid "Check this box if the partner is a customer." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_lang_act_window +#: model:ir.model,name:base.model_res_lang +#: model:ir.ui.menu,name:base.menu_res_lang_act_window +#: view:res.lang:0 +msgid "Languages" +msgstr "Тілдер:" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "Xor" +msgstr "" + +#. module: base +#: model:res.country,name:base.ec +msgid "Ecuador" +msgstr "Экуадор" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:52 +#, python-format +msgid "" +"Save this document to a .CSV file and open it with your favourite " +"spreadsheet software. The file encoding is UTF-8. You have to translate the " +"latest column before reimporting it." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_customer_form +#: model:ir.actions.act_window,name:base.action_partner_form +#: model:ir.ui.menu,name:base.menu_partner_form +#: view:res.partner:0 +msgid "Customers" +msgstr "" + +#. module: base +#: model:res.country,name:base.au +msgid "Australia" +msgstr "Аустралия" + +#. module: base +#: help:res.partner,lang:0 +msgid "" +"If the selected language is loaded in the system, all documents related to " +"this partner will be printed in this language. If not, it will be english." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Menu :" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Base Field" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Validate" +msgstr "Дұрыстығын тексеру" + +#. module: base +#: field:ir.actions.todo,restart:0 +msgid "Restart" +msgstr "Қайта жүктеу" + +#. module: base +#: field:ir.actions.report.xml,report_sxw_content:0 +#: field:ir.actions.report.xml,report_sxw_content_data:0 +msgid "SXW content" +msgstr "" + +#. module: base +#: view:ir.actions.wizard:0 +#: field:wizard.ir.model.menu.create.line,wizard_id:0 +msgid "Wizard" +msgstr "Шебері" + +#. module: base +#: view:ir.cron:0 +msgid "Action to Trigger" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:136 +#, python-format +msgid "\"email_from\" needs to be set to send welcome mails to users" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Constraint" +msgstr "" + +#. module: base +#: selection:ir.values,key:0 +#: selection:res.partner.address,type:0 +msgid "Default" +msgstr "Әдетті" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,required:0 +#: field:res.partner.bank.type.field,required:0 +msgid "Required" +msgstr "Міндетті" + +#. module: base +#: view:res.users:0 +msgid "Default Filters" +msgstr "" + +#. module: base +#: field:res.request.history,name:0 +msgid "Summary" +msgstr "Мазмұндамасы" + +#. module: base +#: field:multi_company.default,expression:0 +msgid "Expression" +msgstr "Өрнегі" + +#. module: base +#: help:ir.actions.server,subject:0 +msgid "" +"Specify the subject. You can use fields from the object, e.g. `Hello [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Header/Footer" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,help:0 +msgid "" +"Optional help text for the users with a description of the target view, such " +"as its usage and purpose." +msgstr "" + +#. module: base +#: model:res.country,name:base.va +msgid "Holy See (Vatican City State)" +msgstr "Ватикан" + +#. module: base +#: field:base.module.import,module_file:0 +msgid "Module .ZIP file" +msgstr "" + +#. module: base +#: field:ir.ui.view,xml_id:0 +msgid "XML ID" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_16 +msgid "Telecom sector" +msgstr "" + +#. module: base +#: field:workflow.transition,trigger_model:0 +msgid "Trigger Object" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Current Activity" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,in_transitions:0 +msgid "Incoming Transitions" +msgstr "" + +#. module: base +#: model:res.country,name:base.sr +msgid "Suriname" +msgstr "Суринам" + +#. module: base +#: model:ir.ui.menu,name:base.marketing_menu +msgid "Marketing" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +#: model:res.partner.bank.type,name:base.bank_normal +msgid "Bank account" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (HN) / Español (HN)" +msgstr "" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequence Type" +msgstr "" + +#. module: base +#: view:ir.ui.view.custom:0 +msgid "Customized Architecture" +msgstr "" + +#. module: base +#: field:ir.module.module,license:0 +msgid "License" +msgstr "Лицензия" + +#. module: base +#: field:ir.attachment,url:0 +msgid "Url" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "Always" +msgstr "Әрқашан" + +#. module: base +#: selection:ir.translation,type:0 +msgid "SQL Constraint" +msgstr "" + +#. module: base +#: field:ir.actions.server,srcmodel_id:0 +#: field:ir.model.fields,model_id:0 +msgid "Model" +msgstr "Түрі" + +#. module: base +#: view:base.language.install:0 +msgid "" +"The selected language has been successfully installed. You must change the " +"preferences of the user and open a new menu to view the changes." +msgstr "" + +#. module: base +#: sql_constraint:ir.config_parameter:0 +msgid "Key must be unique." +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open a Window" +msgstr "" + +#. module: base +#: model:res.country,name:base.gq +msgid "Equatorial Guinea" +msgstr "Экваториалдық Гвинея" + +#. module: base +#: view:base.module.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_module_import +msgid "Module Import" +msgstr "" + +#. module: base +#: field:res.bank,zip:0 +#: field:res.partner.address,zip:0 +#: field:res.partner.bank,zip:0 +msgid "Zip" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,author:0 +msgid "Author" +msgstr "Авторы" + +#. module: base +#: model:res.country,name:base.mk +msgid "FYROM" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%c - Appropriate date and time representation." +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:422 +#, python-format +msgid "" +"Your database is now fully configured.\n" +"\n" +"Click 'Continue' and enjoy your OpenERP experience..." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hebrew / עִבְרִי" +msgstr "" + +#. module: base +#: model:res.country,name:base.bo +msgid "Bolivia" +msgstr "Боливия" + +#. module: base +#: model:res.country,name:base.gh +msgid "Ghana" +msgstr "Гана" + +#. module: base +#: field:res.lang,direction:0 +msgid "Direction" +msgstr "Бағыты" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.action_ui_view +#: field:ir.actions.act_window,view_ids:0 +#: field:ir.actions.act_window,views:0 +#: field:ir.module.module,views_by_module:0 +#: model:ir.ui.menu,name:base.menu_action_ui_view +#: view:ir.ui.view:0 +msgid "Views" +msgstr "Көріністер" + +#. module: base +#: view:res.groups:0 +#: field:res.groups,rule_groups:0 +msgid "Rules" +msgstr "Ережелер" + +#. module: base +#: code:addons/base/module/module.py:216 +#, python-format +msgid "You try to remove a module that is installed or will be installed" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "The selected modules have been updated / installed !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PR) / Español (PR)" +msgstr "" + +#. module: base +#: model:res.country,name:base.gt +msgid "Guatemala" +msgstr "Гватемала" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_form +#: model:ir.ui.menu,name:base.menu_low_workflow +#: model:ir.ui.menu,name:base.menu_workflow +#: model:ir.ui.menu,name:base.menu_workflow_root +msgid "Workflows" +msgstr "" + +#. module: base +#: field:ir.translation,xml_id:0 +msgid "XML Id" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_config_user_form +msgid "Create Users" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_title +msgid "res.partner.title" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "tree_but_action, client_print_multi" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_retailers0 +msgid "Retailers" +msgstr "" + +#. module: base +#: help:ir.cron,priority:0 +msgid "" +"0=Very Urgent\n" +"10=Not urgent" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "Skip" +msgstr "Аттап кету" + +#. module: base +#: model:res.country,name:base.ls +msgid "Lesotho" +msgstr "Лесото" + +#. module: base +#: code:addons/base/ir/ir_model.py:114 +#, python-format +msgid "You can not remove the model '%s' !" +msgstr "" + +#. module: base +#: model:res.country,name:base.ke +msgid "Kenya" +msgstr "Кения" + +#. module: base +#: view:res.partner.event:0 +msgid "Event" +msgstr "Оқиға" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom_reports +msgid "Custom Reports" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Abkhazian / аҧсуа" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "System Configuration Done" +msgstr "" + +#. module: base +#: code:addons/orm.py:929 +#, python-format +msgid "Error occurred while validating the field(s) %s: %s" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Generic" +msgstr "Жалпы" + +#. module: base +#: model:res.country,name:base.sm +msgid "San Marino" +msgstr "Сан-Марино" + +#. module: base +#: model:res.country,name:base.bm +msgid "Bermuda" +msgstr "Бермуд ар-ы" + +#. module: base +#: model:res.country,name:base.pe +msgid "Peru" +msgstr "Перу" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Set NULL" +msgstr "" + +#. module: base +#: model:res.country,name:base.bj +msgid "Benin" +msgstr "Бенин" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:281 +#, python-format +msgid "That contract is already registered in the system." +msgstr "" + +#. module: base +#: help:ir.sequence,suffix:0 +msgid "Suffix value of the record for the sequence" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PY) / Español (PY)" +msgstr "" + +#. module: base +#: field:ir.config_parameter,key:0 +msgid "Key" +msgstr "Кілт" + +#. module: base +#: field:res.company,rml_header:0 +msgid "RML Header" +msgstr "" + +#. module: base +#: field:partner.sms.send,app_id:0 +msgid "API ID" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:486 +#, python-format +msgid "" +"You can not create this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:res.country,name:base.mu +msgid "Mauritius" +msgstr "Маврикий" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +msgid "Full Access" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.wizard:0 +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.menu_security +msgid "Security" +msgstr "Қауіпсіздік" + +#. module: base +#: model:res.widget,title:base.openerp_favorites_twitter_widget +msgid "OpenERP Favorites" +msgstr "" + +#. module: base +#: model:res.country,name:base.za +msgid "South Africa" +msgstr "Оңтүстік Африка" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Installed" +msgstr "Орнатылған" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Ukrainian / українська" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_translation +#: model:ir.ui.menu,name:base.menu_action_translation +msgid "Translation Terms" +msgstr "" + +#. module: base +#: model:res.country,name:base.sn +msgid "Senegal" +msgstr "Сенегал" + +#. module: base +#: model:res.country,name:base.hu +msgid "Hungary" +msgstr "Венгрия" + +#. module: base +#: model:ir.model,name:base.model_res_groups +msgid "res.groups" +msgstr "" + +#. module: base +#: model:res.country,name:base.br +msgid "Brazil" +msgstr "Бразилия" + +#. module: base +#: view:res.lang:0 +msgid "%M - Minute [00,59]." +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Affero GPL-3" +msgstr "" + +#. module: base +#: field:ir.sequence,number_next:0 +msgid "Next Number" +msgstr "" + +#. module: base +#: help:workflow.transition,condition:0 +msgid "Expression to be satisfied if we want the transition done." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PA) / Español (PA)" +msgstr "" + +#. module: base +#: view:res.currency:0 +#: field:res.currency,rate_ids:0 +msgid "Rates" +msgstr "" + +#. module: base +#: model:res.country,name:base.sy +msgid "Syria" +msgstr "Сирия" + +#. module: base +#: view:res.lang:0 +msgid "======================================================" +msgstr "" + +#. module: base +#: help:ir.actions.server,mobile:0 +msgid "" +"Provides fields that be used to fetch the mobile number, e.g. you select the " +"invoice, then `object.invoice_address_id.mobile` is the field which gives " +"the correct mobile number" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System update completed" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "draft" +msgstr "Жоба" + +#. module: base +#: selection:ir.property,type:0 +#: field:res.currency,date:0 +#: field:res.currency.rate,name:0 +#: field:res.partner,date:0 +#: field:res.partner.event,date:0 +#: field:res.request,date_sent:0 +msgid "Date" +msgstr "Күні" + +#. module: base +#: field:ir.actions.report.xml,report_sxw:0 +msgid "SXW path" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Data" +msgstr "Дерек" + +#. module: base +#: field:ir.ui.menu,parent_id:0 +#: field:wizard.ir.model.menu.create,menu_id:0 +msgid "Parent Menu" +msgstr "" + +#. module: base +#: field:ir.rule,perm_unlink:0 +msgid "Apply For Delete" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:319 +#, python-format +msgid "Cannot rename column to %s, because that column already exists!" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attached To" +msgstr "" + +#. module: base +#: field:res.lang,decimal_point:0 +msgid "Decimal Separator" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_groups +msgid "" +"A group is a set of functional areas that will be assigned to the user in " +"order to give them access and rights to specific applications and tasks in " +"the system. You can create custom groups or edit the ones existing by " +"default in order to customize the view of the menu that users will be able " +"to see. Whether they can have a read, write, create and delete access right " +"can be managed from here." +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.request:0 +#: field:res.request,history:0 +msgid "History" +msgstr "Журналы" + +#. module: base +#: field:ir.attachment,create_uid:0 +msgid "Creator" +msgstr "Құрушысы" + +#. module: base +#: model:res.company,overdue_msg:base.main_company +msgid "" +"Please note that the following payments are now due. If your payment " +" has been sent, kindly forward your payment details. If " +"payment will be delayed further, please contact us " +"to discuss. \n" +"Would your payment have been carried out after this mail was sent, please " +"consider the present one as void." +msgstr "" + +#. module: base +#: model:res.country,name:base.mx +msgid "Mexico" +msgstr "Мексика" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config_plugins +msgid "Plugins" +msgstr "Плагиндер" + +#. module: base +#: field:res.company,child_ids:0 +msgid "Child Companies" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_users +msgid "res.users" +msgstr "" + +#. module: base +#: model:res.country,name:base.ni +msgid "Nicaragua" +msgstr "Никарагуа" + +#. module: base +#: code:addons/orm.py:1046 +#, python-format +msgid "The write method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "General Description" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_config_simple_view_form +#: view:res.config.view:0 +msgid "Configure Your Interface" +msgstr "" + +#. module: base +#: field:ir.values,meta:0 +msgid "Meta Datas" +msgstr "" + +#. module: base +#: sql_constraint:ir.ui.view_sc:0 +msgid "Shortcut for this menu already exists!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ve +msgid "Venezuela" +msgstr "Венесуэла" + +#. module: base +#: view:res.lang:0 +msgid "9. %j ==> 340" +msgstr "" + +#. module: base +#: model:res.country,name:base.zm +msgid "Zambia" +msgstr "Замбия" + +#. module: base +#: help:res.partner,user_id:0 +msgid "" +"The internal user that is in charge of communicating with this partner if " +"any." +msgstr "" + +#. module: base +#: field:res.partner,parent_id:0 +msgid "Parent Partner" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Upgrade" +msgstr "" + +#. module: base +#: model:res.country,name:base.ci +msgid "Ivory Coast (Cote D'Ivoire)" +msgstr "" + +#. module: base +#: model:res.country,name:base.kz +msgid "Kazakhstan" +msgstr "Қазақстан" + +#. module: base +#: view:res.lang:0 +msgid "%w - Weekday number [0(Sunday),6]." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_form +msgid "" +"A customer is an entity you do business with, like a company or an " +"organization. A customer can have several contacts or addresses which are " +"the people working for this company. You can use the history tab, to follow " +"all transactions related to a customer: sales order, emails, opportunities, " +"claims, etc. If you use the email gateway, the Outlook or the Thunderbird " +"plugin, don't forget to register emails to each contact so that the gateway " +"will automatically attach incoming emails to the right partner." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,name:0 +#: field:ir.actions.todo,name:0 +#: field:ir.cron,name:0 +#: field:ir.model.access,name:0 +#: field:ir.model.fields,name:0 +#: field:ir.module.category,name:0 +#: field:ir.module.module,name:0 +#: field:ir.module.module.dependency,name:0 +#: report:ir.module.reference.graph:0 +#: field:ir.property,name:0 +#: field:ir.rule,name:0 +#: field:ir.sequence,name:0 +#: field:ir.sequence.type,name:0 +#: field:ir.values,name:0 +#: field:multi_company.default,name:0 +#: field:res.bank,name:0 +#: field:res.config.view,name:0 +#: field:res.lang,name:0 +#: field:res.partner,name:0 +#: field:res.partner.bank.type,name:0 +#: view:res.partner.event:0 +#: field:res.request.link,name:0 +#: field:workflow,name:0 +#: field:workflow.activity,name:0 +msgid "Name" +msgstr "Атауы" + +#. module: base +#: help:ir.actions.act_window,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view" +msgstr "" + +#. module: base +#: model:res.country,name:base.ms +msgid "Montserrat" +msgstr "Монсеррат" + +#. module: base +#: code:addons/base/ir/ir_model.py:205 +#, python-format +msgid "" +"The Selection Options expression is not a valid Pythonic expression.Please " +"provide an expression in the [('key','Label'), ...] format." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_app +msgid "Application Terms" +msgstr "" + +#. module: base +#: help:res.config.users,context_tz:0 +#: help:res.users,context_tz:0 +msgid "" +"The user's timezone, used to perform timezone conversions between the server " +"and the client." +msgstr "" + +#. module: base +#: field:ir.module.module,demo:0 +msgid "Demo data" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (UK)" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Japanese / 日本語" +msgstr "Жапонша" + +#. module: base +#: help:workflow.transition,act_from:0 +msgid "" +"Source activity. When this activity is over, the condition is tested to " +"determine if we can start the ACT_TO activity." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_3 +msgid "Starter Partner" +msgstr "" + +#. module: base +#: help:ir.model.fields,relation_field:0 +msgid "" +"For one2many fields, the field on the target model that implement the " +"opposite many2one relationship" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_view +msgid "ir.actions.act_window.view" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Web" +msgstr "Веб" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (CA)" +msgstr "Ангылша" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract +msgid "publisher_warranty.contract" +msgstr "" + +#. module: base +#: model:res.country,name:base.et +msgid "Ethiopia" +msgstr "Эфиопия" + +#. module: base +#: help:res.country.state,code:0 +msgid "The state code in three chars.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.sj +msgid "Svalbard and Jan Mayen Islands" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_wizard +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.wizard" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.server:0 +#: view:ir.filters:0 +#: view:res.request:0 +msgid "Group By" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "title" +msgstr "Тақырыбы..." + +#. module: base +#: model:ir.model,name:base.model_base_language_install +msgid "Install Language" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Translation" +msgstr "Аудару" + +#. module: base +#: selection:res.request,state:0 +msgid "closed" +msgstr "жабык" + +#. module: base +#: selection:base.language.export,state:0 +msgid "get" +msgstr "" + +#. module: base +#: help:ir.model.fields,on_delete:0 +msgid "On delete property for many2one fields" +msgstr "" + +#. module: base +#: field:ir.actions.server,write_id:0 +msgid "Write Id" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_product +msgid "Products" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,domain:0 +#: field:ir.filters,domain:0 +msgid "Domain Value" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "SMS Configuration" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (BO) / Español (BO)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_access_act +#: model:ir.ui.menu,name:base.menu_ir_access_act +msgid "Access Controls List" +msgstr "" + +#. module: base +#: model:res.country,name:base.um +msgid "USA Minor Outlying Islands" +msgstr "" + +#. module: base +#: field:res.partner.bank,state:0 +#: field:res.partner.bank.type.field,bank_type_id:0 +msgid "Bank Type" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:58 +#: code:addons/base/res/res_user.py:67 +#, python-format +msgid "The name of the group can not start with \"-\"" +msgstr "" + +#. module: base +#: view:ir.ui.view_sc:0 +#: field:res.partner.title,shortcut:0 +msgid "Shortcut" +msgstr "Тіркесім" + +#. module: base +#: field:ir.model.data,date_init:0 +msgid "Init Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Gujarati / ગુજરાતી" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:257 +#, python-format +msgid "" +"Unable to process module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Please enter the serial key provided in your contract document:" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_start:0 +msgid "Flow Start" +msgstr "" + +#. module: base +#: code:addons/__init__.py:834 +#, python-format +msgid "module base cannot be loaded! (hint: verify addons-path)" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Bank Account Owner" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form +msgid "Client Actions Connections" +msgstr "" + +#. module: base +#: field:ir.attachment,res_name:0 +#: field:ir.ui.view_sc,resource:0 +msgid "Resource Name" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Hours" +msgstr "Сағат" + +#. module: base +#: model:res.country,name:base.gp +msgid "Guadeloupe (French)" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:157 +#: code:addons/base/res/res_lang.py:159 +#: code:addons/base/res/res_lang.py:161 +#, python-format +msgid "User Error" +msgstr "" + +#. module: base +#: help:workflow.transition,signal:0 +msgid "" +"When the operation of transition comes from a button pressed in the client " +"form, signal tests the name of the pressed button. If signal is NULL, no " +"button is necessary to validate this transition." +msgstr "" + +#. module: base +#: help:multi_company.default,object_id:0 +msgid "Object affected by this rule" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Directory" +msgstr "Каталог" + +#. module: base +#: field:wizard.ir.model.menu.create,name:0 +msgid "Menu Name" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Author Website" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Month" +msgstr "Ай" + +#. module: base +#: model:res.country,name:base.my +msgid "Malaysia" +msgstr "Малайзия" + +#. module: base +#: view:base.language.install:0 +#: model:ir.actions.act_window,name:base.action_view_base_language_install +msgid "Load Official Translation" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request_history +msgid "res.request.history" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Client Action Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_address +#: view:res.partner.address:0 +msgid "Partner Addresses" +msgstr "" + +#. module: base +#: help:ir.model.fields,translate:0 +msgid "" +"Whether values for this field can be translated (enables the translation " +"mechanism for that field)" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%S - Seconds [00,61]." +msgstr "" + +#. module: base +#: model:res.country,name:base.cv +msgid "Cape Verde" +msgstr "Кабо-Верде" + +#. module: base +#: view:base.module.import:0 +msgid "Select module package to import (.zip file):" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_res_partner_event +#: field:res.partner,events:0 +#: field:res.partner.event,name:0 +#: model:res.widget,title:base.events_widget +msgid "Events" +msgstr "Оқиғалар" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_url +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.url" +msgstr "" + +#. module: base +#: model:res.widget,title:base.currency_converter_widget +msgid "Currency Converter" +msgstr "" + +#. module: base +#: code:addons/orm.py:156 +#, python-format +msgid "Wrong ID for the browse record, got %r, expected an integer." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_addess_tree +#: view:res.partner:0 +msgid "Partner Contacts" +msgstr "" + +#. module: base +#: field:base.module.update,add:0 +msgid "Number of modules added" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Price Accuracy" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Latvian / latviešu valoda" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "vsep" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French / Français" +msgstr "" + +#. module: base +#: code:addons/orm.py:1049 +#, python-format +msgid "The create method is not implemented on this object !" +msgstr "" + +#. module: base +#: field:workflow.triggers,workitem_id:0 +msgid "Workitem" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Set as Todo" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,act_window_id:0 +#: view:ir.actions.actions:0 +#: field:ir.actions.todo,action_id:0 +#: field:ir.ui.menu,action:0 +#: field:ir.values,action_id:0 +#: selection:ir.values,key:0 +#: view:res.users:0 +msgid "Action" +msgstr "Әрекет" + +#. module: base +#: view:ir.actions.server:0 +msgid "Email Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_cron +msgid "ir.cron" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Combination of rules" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year without Century: %(y)s" +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_obj_id:0 +msgid "Trigger On" +msgstr "" + +#. module: base +#: sql_constraint:ir.rule:0 +msgid "Rule must have at least one checked access right !" +msgstr "" + +#. module: base +#: model:res.country,name:base.fj +msgid "Fiji" +msgstr "Фиджи" + +#. module: base +#: field:ir.model.fields,size:0 +msgid "Size" +msgstr "Көлемі" + +#. module: base +#: model:res.country,name:base.sd +msgid "Sudan" +msgstr "Судан" + +#. module: base +#: model:res.country,name:base.fm +msgid "Micronesia" +msgstr "Микронезия" + +#. module: base +#: view:res.request.history:0 +msgid "Request History" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,menus:0 +#: field:ir.module.module,menus_by_module:0 +#: view:res.groups:0 +msgid "Menus" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Latin) / srpski" +msgstr "" + +#. module: base +#: model:res.country,name:base.il +msgid "Israel" +msgstr "Израиль" + +#. module: base +#: model:ir.actions.wizard,name:base.wizard_server_action_create +msgid "Create Action" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_model +#: model:ir.model,name:base.model_ir_model +#: model:ir.ui.menu,name:base.ir_model_model_menu +msgid "Objects" +msgstr "" + +#. module: base +#: field:res.lang,time_format:0 +msgid "Time Format" +msgstr "Уақыт пішімі" + +#. module: base +#: view:ir.module.module:0 +msgid "Defined Reports" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report xml" +msgstr "" + +#. module: base +#: field:base.language.export,modules:0 +#: model:ir.actions.act_window,name:base.action_module_open_categ +#: model:ir.actions.act_window,name:base.open_module_tree +#: view:ir.module.module:0 +#: model:ir.ui.menu,name:base.menu_management +#: model:ir.ui.menu,name:base.menu_module_tree +msgid "Modules" +msgstr "Модульдер" + +#. module: base +#: view:workflow.activity:0 +#: selection:workflow.activity,kind:0 +#: field:workflow.activity,subflow_id:0 +#: field:workflow.workitem,subflow_id:0 +msgid "Subflow" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config +msgid "res.config" +msgstr "" + +#. module: base +#: field:workflow.transition,signal:0 +msgid "Signal (button Name)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_bank_form +#: model:ir.ui.menu,name:base.menu_action_res_bank_form +#: view:res.bank:0 +#: field:res.partner,bank_ids:0 +msgid "Banks" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Unread" +msgstr "Оқылмаған" + +#. module: base +#: field:ir.cron,doall:0 +msgid "Repeat Missed" +msgstr "" + +#. module: base +#: help:ir.actions.server,state:0 +msgid "Type of the Action that is to be executed" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,server_id:0 +msgid "Object Mapping" +msgstr "" + +#. module: base +#: help:res.currency,rate:0 +#: help:res.currency.rate,rate:0 +msgid "The rate of the currency to the currency of rate 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.uk +msgid "United Kingdom" +msgstr "Ұлы Британия" + +#. module: base +#: view:res.config:0 +#: view:res.config.users:0 +#: view:res.config.view:0 +msgid "res_config_contents" +msgstr "" + +#. module: base +#: help:res.partner.category,active:0 +msgid "The active field allows you to hide the category without removing it." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Object:" +msgstr "Объекті:" + +#. module: base +#: model:res.country,name:base.bw +msgid "Botswana" +msgstr "Ботсвана" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_partner +#: model:ir.ui.menu,name:base.menu_partner_title_partner +#: view:res.partner.title:0 +msgid "Partner Titles" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,auto_refresh:0 +msgid "Add an auto-refresh on the view" +msgstr "" + +#. module: base +#: help:res.partner,employee:0 +msgid "Check this box if the partner is an Employee." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml_content:0 +#: field:ir.actions.report.xml,report_rml_content_data:0 +msgid "RML content" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_workitem_form +#: model:ir.ui.menu,name:base.menu_workflow_workitem +msgid "Workitems" +msgstr "" + +#. module: base +#: field:base.language.export,advice:0 +msgid "Advice" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_attachment +msgid "ir.attachment" +msgstr "" + +#. module: base +#: code:addons/orm.py:3533 +#, python-format +msgid "" +"You cannot perform this operation. New Record Creation is not allowed for " +"this object as this object is for reporting purpose." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- module,type,name,res_id,src,value" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Lithuanian / Lietuvių kalba" +msgstr "" + +#. module: base +#: help:ir.actions.server,record_id:0 +msgid "" +"Provide the field name where the record id is stored after the create " +"operations. If it is empty, you can not track the new record." +msgstr "" + +#. module: base +#: help:ir.model.fields,relation:0 +msgid "For relationship fields, the technical name of the target model" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Indonesian / Bahasa Indonesia" +msgstr "" + +#. module: base +#: field:ir.ui.view,inherit_id:0 +msgid "Inherited View" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Source Term" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_main_pm +msgid "Project" +msgstr "Жоба" + +#. module: base +#: field:ir.ui.menu,web_icon_hover_data:0 +msgid "Web Icon Image (hover)" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Module file successfully imported!" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +msgid "Cancelled" +msgstr "Бас тартылған" + +#. module: base +#: view:res.config.users:0 +msgid "Create User" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Want to Clear Ids ? " +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,name:0 +#: field:publisher_warranty.contract.wizard,name:0 +msgid "Serial Key" +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "Low" +msgstr "Төмен" + +#. module: base +#: model:ir.ui.menu,name:base.menu_audit +msgid "Audit" +msgstr "" + +#. module: base +#: model:res.country,name:base.lc +msgid "Saint Lucia" +msgstr "Сент-Люсия" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Maintenance Contract" +msgstr "" + +#. module: base +#: help:ir.actions.server,trigger_obj_id:0 +msgid "Select the object from the model on which the workflow will executed." +msgstr "" + +#. module: base +#: field:res.partner,employee:0 +msgid "Employee" +msgstr "" + +#. module: base +#: field:ir.model.access,perm_create:0 +msgid "Create Access" +msgstr "" + +#. module: base +#: field:res.partner.address,state_id:0 +msgid "Fed. State" +msgstr "" + +#. module: base +#: field:ir.actions.server,copy_object:0 +msgid "Copy Of" +msgstr "" + +#. module: base +#: field:ir.model,osv_memory:0 +msgid "In-memory model" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Clear Ids" +msgstr "" + +#. module: base +#: model:res.country,name:base.io +msgid "British Indian Ocean Territory" +msgstr "Британияның Үнді мұхиттағы жері" + +#. module: base +#: field:res.config.users,view:0 +#: field:res.config.view,view:0 +#: field:res.users,view:0 +msgid "Interface" +msgstr "Интерфейс" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mapping" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Refresh Validation Dates" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: field:ir.model.fields,ttype:0 +msgid "Field Type" +msgstr "" + +#. module: base +#: field:res.country.state,code:0 +msgid "State Code" +msgstr "" + +#. module: base +#: field:ir.model.fields,on_delete:0 +msgid "On delete" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Left-to-Right" +msgstr "Солдан оңға" + +#. module: base +#: view:res.lang:0 +#: field:res.lang,translatable:0 +msgid "Translatable" +msgstr "" + +#. module: base +#: model:res.country,name:base.vn +msgid "Vietnam" +msgstr "Вьетнам" + +#. module: base +#: field:res.config.users,signature:0 +#: view:res.users:0 +#: field:res.users,signature:0 +msgid "Signature" +msgstr "Қолтаңба" + +#. module: base +#: code:addons/fields.py:456 +#: code:addons/fields.py:654 +#: code:addons/fields.py:656 +#: code:addons/fields.py:658 +#: code:addons/fields.py:660 +#: code:addons/fields.py:662 +#: code:addons/fields.py:664 +#, python-format +msgid "Not Implemented" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_user +msgid "res.widget.user" +msgstr "" + +#. module: base +#: field:res.partner.category,complete_name:0 +msgid "Full Name" +msgstr "Толық аты" + +#. module: base +#: view:base.module.configuration:0 +msgid "_Ok" +msgstr "" + +#. module: base +#: help:ir.filters,user_id:0 +msgid "False means for every user" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:198 +#, python-format +msgid "The name of the module must be unique !" +msgstr "" + +#. module: base +#: model:res.country,name:base.mz +msgid "Mozambique" +msgstr "Мозамбик" + +#. module: base +#: model:ir.ui.menu,name:base.menu_project_long_term +msgid "Long Term Planning" +msgstr "" + +#. module: base +#: field:ir.actions.server,message:0 +#: view:partner.sms.send:0 +#: field:partner.wizard.spam,text:0 +#: field:res.log,name:0 +msgid "Message" +msgstr "Хат" + +#. module: base +#: field:ir.actions.act_window.view,multi:0 +msgid "On Multiple Doc." +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,user_id:0 +msgid "Salesman" +msgstr "" + +#. module: base +#: field:res.partner,address:0 +#: view:res.partner.address:0 +msgid "Contacts" +msgstr "Контакттар" + +#. module: base +#: code:addons/orm.py:3199 +#, python-format +msgid "" +"Unable to delete this document because it is used as a default property" +msgstr "" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Add" +msgstr "Қосу" + +#. module: base +#: view:base.module.upgrade:0 +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_window +#: model:ir.ui.menu,name:base.menu_view_base_module_upgrade +msgid "Apply Scheduled Upgrades" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Widgets" +msgstr "Виджеттер" + +#. module: base +#: model:res.country,name:base.cz +msgid "Czech Republic" +msgstr "Чехия" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Widget Wizard" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.act_ir_actions_todo_form +msgid "" +"The configuration wizards are used to help you configure a new instance of " +"OpenERP. They are launched during the installation of new modules, but you " +"can choose to restart some wizards manually from this menu." +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:206 +#, python-format +msgid "" +"Please use the change password wizard (in User Preferences or User menu) to " +"change your own password." +msgstr "" + +#. module: base +#: code:addons/orm.py:1350 +#, python-format +msgid "Insufficient fields for Calendar View!" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer" +msgstr "Бүтін сан" + +#. module: base +#: help:ir.actions.report.xml,report_rml:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another data field" +msgstr "" + +#. module: base +#: help:res.config.users,company_id:0 +#: help:res.users,company_id:0 +msgid "The company this user is currently working for." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create +msgid "wizard.ir.model.menu.create" +msgstr "" + +#. module: base +#: view:workflow.transition:0 +msgid "Transition" +msgstr "" + +#. module: base +#: field:res.groups,menu_access:0 +msgid "Access Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.na +msgid "Namibia" +msgstr "Намибия" + +#. module: base +#: model:res.country,name:base.mn +msgid "Mongolia" +msgstr "Монғолия" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Menus" +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "mdx" +msgstr "" + +#. module: base +#: model:res.country,name:base.bi +msgid "Burundi" +msgstr "Бурунди" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.request:0 +#: wizard_button:server.action.create,init,end:0 +#: wizard_button:server.action.create,step_1,end:0 +msgid "Close" +msgstr "Жабу" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (MX) / Español (MX)" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "My Logs" +msgstr "" + +#. module: base +#: model:res.country,name:base.bt +msgid "Bhutan" +msgstr "" + +#. module: base +#: help:ir.sequence,number_next:0 +msgid "Next number of this sequence" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_11 +msgid "Textile Suppliers" +msgstr "" + +#. module: base +#: selection:ir.actions.url,target:0 +msgid "This Window" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contracts" +msgstr "" + +#. module: base +#: help:res.log,name:0 +msgid "The logging message." +msgstr "" + +#. module: base +#: field:base.language.export,format:0 +msgid "File Format" +msgstr "" + +#. module: base +#: field:res.lang,iso_code:0 +msgid "ISO code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_view +msgid "res.config.view" +msgstr "" + +#. module: base +#: view:res.log:0 +#: field:res.log,read:0 +msgid "Read" +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The name of the country must be unique !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country_state +msgid "" +"If you are working on the American market, you can manage the different " +"federal states you are working on from here. Each state is attached to one " +"country." +msgstr "" + +#. module: base +#: view:workflow.workitem:0 +msgid "Workflow Workitems" +msgstr "" + +#. module: base +#: model:res.country,name:base.vc +msgid "Saint Vincent & Grenadines" +msgstr "" + +#. module: base +#: field:partner.sms.send,password:0 +#: field:res.config.users,password:0 +#: field:res.users,password:0 +msgid "Password" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_fields +#: view:ir.model:0 +#: field:ir.model,field_id:0 +#: model:ir.model,name:base.model_ir_model_fields +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.ir_model_model_fields +msgid "Fields" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_employee_form +msgid "Employees" +msgstr "" + +#. module: base +#: help:res.log,read:0 +msgid "" +"If this log item has been read, get() should not send it to the client" +msgstr "" + +#. module: base +#: field:res.company,rml_header2:0 +#: field:res.company,rml_header3:0 +msgid "RML Internal Header" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view_id:0 +msgid "Search View Ref." +msgstr "" + +#. module: base +#: field:ir.module.module,installed_version:0 +msgid "Latest version" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.res_partner_canal-act +msgid "" +"Track from where is coming your leads and opportunities by creating specific " +"channels that will be maintained at the creation of a document in the " +"system. Some examples of channels can be: Website, Phone Call, Reseller, etc." +msgstr "" + +#. module: base +#: model:res.partner.bank.type.field,name:base.bank_normal_field +msgid "acc_number" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_address_form +#: model:ir.ui.menu,name:base.menu_partner_address_form +msgid "Addresses" +msgstr "" + +#. module: base +#: model:res.country,name:base.mm +msgid "Myanmar" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (CN) / 简体中文" +msgstr "" + +#. module: base +#: field:res.bank,street:0 +#: field:res.partner.address,street:0 +#: field:res.partner.bank,street:0 +msgid "Street" +msgstr "" + +#. module: base +#: model:res.country,name:base.yu +msgid "Yugoslavia" +msgstr "" + +#. module: base +#: field:ir.model.data,name:0 +msgid "XML Identifier" +msgstr "" + +#. module: base +#: model:res.country,name:base.ca +msgid "Canada" +msgstr "" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Unknown" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users_my +msgid "Change My Preferences" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:164 +#, python-format +msgid "Invalid model name in the action definition." +msgstr "" + +#. module: base +#: field:partner.sms.send,text:0 +msgid "SMS Message" +msgstr "" + +#. module: base +#: model:res.country,name:base.cm +msgid "Cameroon" +msgstr "" + +#. module: base +#: model:res.country,name:base.bf +msgid "Burkina Faso" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +msgid "Skipped" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Custom Field" +msgstr "" + +#. module: base +#: field:ir.module.module,web:0 +msgid "Has a web component" +msgstr "" + +#. module: base +#: model:res.country,name:base.cc +msgid "Cocos (Keeling) Islands" +msgstr "" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "init" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "11. %U or %W ==> 48 (49th week)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type_field +msgid "Bank type fields" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Dutch / Nederlands" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:384 +#, python-format +msgid "" +"\n" +"\n" +"This addon is already installed on your system" +msgstr "" + +#. module: base +#: help:ir.cron,interval_number:0 +msgid "Repeat every x." +msgstr "" + +#. module: base +#: wizard_view:server.action.create,step_1:0 +#: wizard_field:server.action.create,step_1,report:0 +msgid "Select Report" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "1cm 28cm 20cm 28cm" +msgstr "" + +#. module: base +#: field:ir.module.module,maintainer:0 +msgid "Maintainer" +msgstr "" + +#. module: base +#: field:ir.sequence,suffix:0 +msgid "Suffix" +msgstr "" + +#. module: base +#: model:res.country,name:base.mo +msgid "Macau" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.res_partner_address_report +msgid "Labels" +msgstr "" + +#. module: base +#: field:partner.wizard.spam,email_from:0 +msgid "Sender's email" +msgstr "" + +#. module: base +#: field:ir.default,field_name:0 +msgid "Object Field" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PE) / Español (PE)" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (CH) / Français (CH)" +msgstr "" + +#. module: base +#: help:res.config.users,action_id:0 +#: help:res.users,action_id:0 +msgid "" +"If specified, this action will be opened at logon for this user, in addition " +"to the standard menu." +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Client Actions" +msgstr "" + +#. module: base +#: code:addons/orm.py:1806 +#, python-format +msgid "The exists method is not implemented on this object !" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:336 +#, python-format +msgid "" +"You try to upgrade a module that depends on the module: %s.\n" +"But this module is not available in your system." +msgstr "" + +#. module: base +#: field:workflow.transition,act_to:0 +msgid "Destination Activity" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Connect Events to Actions" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_update_translations +msgid "base.update.translations" +msgstr "" + +#. module: base +#: field:ir.module.category,parent_id:0 +#: field:res.partner.category,parent_id:0 +msgid "Parent Category" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer Big" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +#: selection:res.partner.title,domain:0 +#: view:res.users:0 +msgid "Contact" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_menu +msgid "ir.ui.menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.us +msgid "United States" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Uninstall" +msgstr "" + +#. module: base +#: view:res.bank:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Communication" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "RML Report" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_server_object_lines +msgid "ir.server.object.lines" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:531 +#, python-format +msgid "Module %s: Invalid Quality Certificate" +msgstr "" + +#. module: base +#: model:res.country,name:base.kw +msgid "Kuwait" +msgstr "" + +#. module: base +#: field:workflow.workitem,inst_id:0 +msgid "Instance" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,attachment:0 +msgid "" +"This is the filename of the attachment used to store the printing result. " +"Keep empty to not save the printed reports. You can use a python expression " +"with the object and time variables." +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Many2One" +msgstr "" + +#. module: base +#: model:res.country,name:base.ng +msgid "Nigeria" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:250 +#, python-format +msgid "For selection fields, the Selection Options must be given!" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_sms_send +msgid "SMS Send" +msgstr "" + +#. module: base +#: field:res.company,user_ids:0 +msgid "Accepted Users" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_data:0 +msgid "Web Icon Image" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Values for Event Type" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Always Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.hk +msgid "Hong Kong" +msgstr "" + +#. module: base +#: help:ir.actions.server,name:0 +msgid "Easy to Refer action by name e.g. One Sales Order -> Many Invoices" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_address_form +msgid "" +"Customers (also called Partners in other areas of the system) helps you " +"manage your address book of companies whether they are prospects, customers " +"and/or suppliers. The partner form allows you to track and record all the " +"necessary information to interact with your partners from the company " +"address to their contacts as well as pricelists, and much more. If you " +"installed the CRM, with the history tab, you can track all the interactions " +"with a partner such as opportunities, emails, or sales orders issued." +msgstr "" + +#. module: base +#: model:res.country,name:base.ph +msgid "Philippines" +msgstr "" + +#. module: base +#: model:res.country,name:base.ma +msgid "Morocco" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "2. %a ,%A ==> Fri, Friday" +msgstr "" + +#. module: base +#: field:res.widget,content:0 +msgid "Content" +msgstr "" + +#. module: base +#: help:ir.rule,global:0 +msgid "If no group is specified the rule is global and applied to everyone" +msgstr "" + +#. module: base +#: model:res.country,name:base.td +msgid "Chad" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_transition +msgid "workflow.transition" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%a - Abbreviated weekday name." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Introspection report on objects" +msgstr "" + +#. module: base +#: model:res.country,name:base.pf +msgid "Polynesia (French)" +msgstr "" + +#. module: base +#: model:res.country,name:base.dm +msgid "Dominica" +msgstr "" + +#. module: base +#: sql_constraint:publisher_warranty.contract:0 +msgid "" +"Your publisher warranty contract is already subscribed in the system !" +msgstr "" + +#. module: base +#: help:ir.cron,nextcall:0 +msgid "Next planned execution date for this scheduler" +msgstr "" + +#. module: base +#: help:res.config.users,view:0 +#: help:res.users,view:0 +msgid "Choose between the simplified interface and the extended one" +msgstr "" + +#. module: base +#: model:res.country,name:base.np +msgid "Nepal" +msgstr "" + +#. module: base +#: code:addons/orm.py:2307 +#, python-format +msgid "" +"Invalid value for reference field \"%s\" (last part must be a non-zero " +"integer): \"%s\"" +msgstr "" + +#. module: base +#: help:ir.cron,args:0 +msgid "Arguments to be passed to the method. e.g. (uid,)" +msgstr "" + +#. module: base +#: help:ir.ui.menu,groups_id:0 +msgid "" +"If you have groups, the visibility of this menu will be based on these " +"groups. If this field is empty, OpenERP will compute visibility based on the " +"related object's read access." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_ui_view_custom +#: model:ir.ui.menu,name:base.menu_action_ui_view_custom +#: view:ir.ui.view.custom:0 +msgid "Customized Views" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "Bulk SMS send" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Seconde: %(sec)s" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_view_base_module_update +msgid "Update Modules List" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:255 +#, python-format +msgid "" +"Unable to upgrade module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:257 +#, python-format +msgid "" +"Please keep in mind that documents currently displayed may not be relevant " +"after switching to another company. If you have unsaved changes, please make " +"sure to save and close all forms before switching to a different company. " +"(You can click on Cancel in the User Preferences now)" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Continue" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Thai / ภาษาไทย" +msgstr "" + +#. module: base +#: code:addons/orm.py:158 +#, python-format +msgid "Object %s does not exists" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovenian / slovenščina" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,attachment_use:0 +msgid "Reload from Attachment" +msgstr "" + +#. module: base +#: model:res.country,name:base.bv +msgid "Bouvet Island" +msgstr "" + +#. module: base +#: field:ir.attachment,name:0 +msgid "Attachment Name" +msgstr "" + +#. module: base +#: field:base.language.export,data:0 +#: field:base.language.import,data:0 +msgid "File" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "Add User" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install +msgid "Module Upgrade Install" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_configuration_wizard +msgid "ir.actions.configuration.wizard" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%b - Abbreviated month name." +msgstr "" + +#. module: base +#: field:res.partner,supplier:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_supplier_add:0 +#: model:res.partner.category,name:base.res_partner_category_8 +msgid "Supplier" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Multi Actions" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: view:base.language.import:0 +#: view:wizard.ir.model.menu.create:0 +msgid "_Close" +msgstr "" + +#. module: base +#: field:multi_company.default,company_dest_id:0 +msgid "Default Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (EC) / Español (EC)" +msgstr "" + +#. module: base +#: help:ir.ui.view,xml_id:0 +msgid "ID of the view defined in xml file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_import +#: model:ir.ui.menu,name:base.menu_view_base_module_import +msgid "Import Module" +msgstr "" + +#. module: base +#: model:res.country,name:base.as +msgid "American Samoa" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,res_model:0 +msgid "Model name of the object to open in the view window" +msgstr "" + +#. module: base +#: field:res.log,secondary:0 +msgid "Secondary Log" +msgstr "" + +#. module: base +#: field:ir.model.fields,selectable:0 +msgid "Selectable" +msgstr "" + +#. module: base +#: view:res.request.link:0 +msgid "Request Link" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: field:ir.module.module,url:0 +msgid "URL" +msgstr "" + +#. module: base +#: help:res.country,name:0 +msgid "The full name of the country." +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Iteration" +msgstr "" + +#. module: base +#: code:addons/orm.py:3448 +#: code:addons/orm.py:3532 +#, python-format +msgid "UserError" +msgstr "" + +#. module: base +#: model:res.country,name:base.ae +msgid "United Arab Emirates" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_case_job_req_main +msgid "Recruitment" +msgstr "" + +#. module: base +#: model:res.country,name:base.re +msgid "Reunion (French)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:321 +#, python-format +msgid "" +"New column name must still start with x_ , because it is a custom field!" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +#: field:ir.rule,global:0 +msgid "Global" +msgstr "" + +#. module: base +#: model:res.country,name:base.mp +msgid "Northern Mariana Islands" +msgstr "" + +#. module: base +#: model:res.country,name:base.sb +msgid "Solomon Islands" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:490 +#: code:addons/orm.py:1897 +#: code:addons/orm.py:2972 +#: code:addons/orm.py:3165 +#: code:addons/orm.py:3365 +#: code:addons/orm.py:3817 +#, python-format +msgid "AccessError" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Waiting" +msgstr "" + +#. module: base +#: code:addons/__init__.py:834 +#, python-format +msgid "Could not load base module" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "8. %I:%M:%S %p ==> 06:25:20 PM" +msgstr "" + +#. module: base +#: code:addons/orm.py:1803 +#, python-format +msgid "The copy method is not implemented on this object !" +msgstr "" + +#. module: base +#: field:res.log,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: base +#: view:ir.translation:0 +#: model:ir.ui.menu,name:base.menu_translation +msgid "Translations" +msgstr "" + +#. module: base +#: field:ir.sequence,padding:0 +msgid "Number Padding" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report" +msgstr "" + +#. module: base +#: model:res.country,name:base.ua +msgid "Ukraine" +msgstr "" + +#. module: base +#: model:res.country,name:base.to +msgid "Tonga" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_category +#: view:ir.module.category:0 +msgid "Module Category" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Ignore" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reference Guide" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Architecture" +msgstr "" + +#. module: base +#: model:res.country,name:base.ml +msgid "Mali" +msgstr "" + +#. module: base +#: help:res.config.users,email:0 +#: help:res.users,email:0 +msgid "" +"If an email is provided, the user will be sent a message welcoming him.\n" +"\n" +"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " +"be possible to email new users." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Flemish (BE) / Vlaams (BE)" +msgstr "" + +#. module: base +#: field:ir.cron,interval_number:0 +msgid "Interval Number" +msgstr "" + +#. module: base +#: model:res.country,name:base.tk +msgid "Tokelau" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xsl:0 +msgid "XSL path" +msgstr "" + +#. module: base +#: model:res.country,name:base.bn +msgid "Brunei Darussalam" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: field:ir.actions.act_window,view_type:0 +#: field:ir.actions.act_window.view,view_mode:0 +#: field:ir.ui.view,type:0 +#: field:wizard.ir.model.menu.create.line,view_type:0 +msgid "View Type" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_2 +msgid "User Interface" +msgstr "" + +#. module: base +#: field:ir.attachment,create_date:0 +msgid "Date Created" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_todo +msgid "ir.actions.todo" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:94 +#, python-format +msgid "Couldn't find previous ir.actions.todo" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "General Settings" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration_shortcut +msgid "Custom Shortcuts" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Vietnamese / Tiếng Việt" +msgstr "" + +#. module: base +#: model:res.country,name:base.dz +msgid "Algeria" +msgstr "" + +#. module: base +#: model:res.country,name:base.be +msgid "Belgium" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_osv_memory_autovacuum +msgid "osv_memory.autovacuum" +msgstr "" + +#. module: base +#: field:base.language.export,lang:0 +#: field:base.language.install,lang:0 +#: field:base.update.translations,lang:0 +#: field:ir.translation,lang:0 +#: field:res.config.users,context_lang:0 +#: field:res.partner,lang:0 +#: field:res.users,context_lang:0 +msgid "Language" +msgstr "" + +#. module: base +#: model:res.country,name:base.gm +msgid "Gambia" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_form +#: model:ir.model,name:base.model_res_company +#: model:ir.ui.menu,name:base.menu_action_res_company_form +#: model:ir.ui.menu,name:base.menu_res_company_global +#: view:res.company:0 +#: field:res.config.users,company_ids:0 +#: view:res.users:0 +#: field:res.users,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%H - Hour (24-hour clock) [00,23]." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget +msgid "res.widget" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:258 +#, python-format +msgid "Model %s does not exist!" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:159 +#, python-format +msgid "You cannot delete the language which is User's Preferred Language !" +msgstr "" + +#. module: base +#: code:addons/fields.py:103 +#, python-format +msgid "Not implemented get_memory method !" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: field:ir.actions.server,code:0 +#: selection:ir.actions.server,state:0 +msgid "Python Code" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:67 +#, python-format +msgid "Can not create the module file: %s !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_meta_information +msgid "The kernel of OpenERP, needed for all installation." +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:base.module.upgrade:0 +#: view:base.update.translations:0 +#: view:partner.clear.ids:0 +#: view:partner.sms.send:0 +#: view:partner.wizard.spam:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.widget.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "PO File" +msgstr "" + +#. module: base +#: model:res.country,name:base.nt +msgid "Neutral Zone" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hindi / हिंदी" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Custom" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Current" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_9 +msgid "Components Supplier" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users +#: field:ir.default,uid:0 +#: model:ir.ui.menu,name:base.menu_action_res_users +#: model:ir.ui.menu,name:base.menu_users +#: view:res.groups:0 +#: field:res.groups,users:0 +#: view:res.users:0 +msgid "Users" +msgstr "" + +#. module: base +#: field:ir.module.module,published_version:0 +msgid "Published Version" +msgstr "" + +#. module: base +#: model:res.country,name:base.is +msgid "Iceland" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_window +#: model:ir.ui.menu,name:base.menu_ir_action_window +msgid "Window Actions" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%I - Hour (12-hour clock) [01,12]." +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Finished" +msgstr "" + +#. module: base +#: model:res.country,name:base.de +msgid "Germany" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Week of the year: %(woy)s" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_14 +msgid "Bad customers" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reports :" +msgstr "" + +#. module: base +#: model:res.country,name:base.gy +msgid "Guyana" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,view_type:0 +msgid "" +"View type: set to 'tree' for a hierarchical tree view, or 'form' for other " +"views" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:421 +#, python-format +msgid "Click 'Continue' to configure the next addon..." +msgstr "" + +#. module: base +#: field:ir.actions.server,record_id:0 +msgid "Create Id" +msgstr "" + +#. module: base +#: model:res.country,name:base.hn +msgid "Honduras" +msgstr "" + +#. module: base +#: help:res.config.users,menu_tips:0 +#: help:res.users,menu_tips:0 +msgid "" +"Check out this box if you want to always display tips on each menu action" +msgstr "" + +#. module: base +#: model:res.country,name:base.eg +msgid "Egypt" +msgstr "" + +#. module: base +#: field:ir.rule,perm_read:0 +msgid "Apply For Read" +msgstr "" + +#. module: base +#: help:ir.actions.server,model_id:0 +msgid "" +"Select the object on which the action will work (read, write, create)." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:629 +#, python-format +msgid "Please specify server option --email-from !" +msgstr "" + +#. module: base +#: field:base.language.import,name:0 +msgid "Language Name" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Boolean" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Fields Description" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: view:ir.cron:0 +#: view:ir.model.access:0 +#: view:ir.model.data:0 +#: view:ir.model.fields:0 +#: view:ir.module.module:0 +#: view:ir.rule:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +#: view:workflow.activity:0 +msgid "Group By..." +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,readonly:0 +#: field:res.partner.bank.type.field,readonly:0 +msgid "Readonly" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,view_id:0 +#: field:ir.default,page:0 +#: selection:ir.translation,type:0 +#: field:wizard.ir.model.menu.create.line,view_id:0 +msgid "View" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be installed" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,display_menu_tip:0 +msgid "" +"It gives the status if the tip has to be displayed or not when a user " +"executes an action" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: model:ir.module.module,shortdesc:base.module_meta_information +#: field:res.currency,base:0 +msgid "Base" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Telugu / తెలుగు" +msgstr "" + +#. module: base +#: model:res.country,name:base.lr +msgid "Liberia" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: view:ir.model:0 +#: view:res.groups:0 +#: view:res.partner:0 +#: field:res.partner,comment:0 +#: model:res.widget,title:base.note_widget +msgid "Notes" +msgstr "" + +#. module: base +#: field:ir.config_parameter,value:0 +#: field:ir.property,value_binary:0 +#: field:ir.property,value_datetime:0 +#: field:ir.property,value_float:0 +#: field:ir.property,value_integer:0 +#: field:ir.property,value_reference:0 +#: field:ir.property,value_text:0 +#: selection:ir.server.object.lines,type:0 +#: field:ir.server.object.lines,value:0 +#: view:ir.values:0 +#: field:ir.values,value:0 +#: field:ir.values,value_unpickle:0 +msgid "Value" +msgstr "" + +#. module: base +#: field:ir.sequence,code:0 +#: field:ir.sequence.type,code:0 +#: selection:ir.translation,type:0 +#: field:res.bank,code:0 +#: field:res.partner.bank.type,code:0 +msgid "Code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_installer +msgid "res.config.installer" +msgstr "" + +#. module: base +#: model:res.country,name:base.mc +msgid "Monaco" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Minutes" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Help" +msgstr "" + +#. module: base +#: help:res.config.users,menu_id:0 +#: help:res.users,menu_id:0 +msgid "" +"If specified, the action will replace the standard menu for this user." +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Write Object" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_fundrising +msgid "Fund Raising" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_type +#: model:ir.ui.menu,name:base.menu_ir_sequence_type +msgid "Sequence Codes" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CO) / Español (CO)" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "" +"All pending configuration wizards have been executed. You may restart " +"individual wizards via the list of configuration wizards." +msgstr "" + +#. module: base +#: wizard_button:server.action.create,step_1,create:0 +msgid "Create" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year with Century: %(year)s" +msgstr "" + +#. module: base +#: field:ir.exports,export_fields:0 +msgid "Export ID" +msgstr "" + +#. module: base +#: model:res.country,name:base.fr +msgid "France" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_log +msgid "res.log" +msgstr "" + +#. module: base +#: help:ir.translation,module:0 +#: help:ir.translation,xml_id:0 +msgid "Maps to the ir_model_data for which this translation is provided." +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_stop:0 +msgid "Flow Stop" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Weeks" +msgstr "" + +#. module: base +#: model:res.country,name:base.af +msgid "Afghanistan, Islamic State of" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:67 +#, python-format +msgid "Error !" +msgstr "" + +#. module: base +#: model:res.partner.bank.type.field,name:base.bank_normal_field_contry +msgid "country_id" +msgstr "" + +#. module: base +#: field:ir.cron,interval_type:0 +msgid "Interval Unit" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,kind:0 +#: field:workflow.activity,kind:0 +msgid "Kind" +msgstr "" + +#. module: base +#: code:addons/orm.py:3775 +#, python-format +msgid "This method does not exist anymore" +msgstr "" + +#. module: base +#: field:res.bank,fax:0 +#: field:res.partner.address,fax:0 +msgid "Fax" +msgstr "" + +#. module: base +#: field:res.lang,thousands_sep:0 +msgid "Thousands Separator" +msgstr "" + +#. module: base +#: field:res.request,create_date:0 +msgid "Created Date" +msgstr "" + +#. module: base +#: help:ir.actions.server,loop_action:0 +msgid "" +"Select the action that will be executed. Loop action will not be avaliable " +"inside loop." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (TW) / 正體字" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request +msgid "res.request" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "In Memory" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Todo" +msgstr "" + +#. module: base +#: field:ir.attachment,datas:0 +msgid "File Content" +msgstr "" + +#. module: base +#: model:res.country,name:base.pa +msgid "Panama" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_ltd +msgid "Ltd" +msgstr "" + +#. module: base +#: help:workflow.transition,group_id:0 +msgid "" +"The group that a user must have to be authorized to validate this transition." +msgstr "" + +#. module: base +#: constraint:res.config.users:0 +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" + +#. module: base +#: model:res.country,name:base.gi +msgid "Gibraltar" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_name:0 +msgid "Service Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.pn +msgid "Pitcairn Island" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "" +"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_rule +#: model:ir.ui.menu,name:base.menu_action_rule +msgid "Record Rules" +msgstr "" + +#. module: base +#: field:res.config.users,name:0 +#: field:res.users,name:0 +msgid "User Name" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the year: %(doy)s" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.model.fields:0 +#: view:workflow.activity:0 +msgid "Properties" +msgstr "" + +#. module: base +#: help:ir.sequence,padding:0 +msgid "" +"OpenERP will automatically adds some '0' on the left of the 'Next Number' to " +"get the required padding size." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%A - Full weekday name." +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Months" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view:0 +msgid "Search View" +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The code of the language must be unique !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_attachment +#: view:ir.actions.report.xml:0 +#: view:ir.attachment:0 +#: model:ir.ui.menu,name:base.menu_action_attachment +msgid "Attachments" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_partner +#: model:ir.ui.menu,name:base.menu_sale_config_sales +#: model:ir.ui.menu,name:base.menu_sales +msgid "Sales" +msgstr "" + +#. module: base +#: field:ir.actions.server,child_ids:0 +msgid "Other Actions" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +#: view:res.config.users:0 +msgid "Done" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_miss +msgid "Miss" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_write:0 +#: view:ir.rule:0 +msgid "Write Access" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%m - Month number [01,12]." +msgstr "" + +#. module: base +#: field:res.bank,city:0 +#: field:res.partner,city:0 +#: field:res.partner.address,city:0 +#: field:res.partner.bank,city:0 +msgid "City" +msgstr "" + +#. module: base +#: model:res.country,name:base.qa +msgid "Qatar" +msgstr "" + +#. module: base +#: model:res.country,name:base.it +msgid "Italy" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +#: selection:ir.actions.todo,state:0 +msgid "To Do" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Estonian / Eesti keel" +msgstr "" + +#. module: base +#: field:res.config.users,email:0 +#: field:res.partner,email:0 +#: field:res.users,email:0 +msgid "E-mail" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-3 or later version" +msgstr "" + +#. module: base +#: field:workflow.activity,action:0 +msgid "Python Action" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (US)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_data +#: view:ir.model.data:0 +#: model:ir.ui.menu,name:base.ir_model_data_menu +msgid "Object Identifiers" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_partner +msgid "" +"Manage the partner titles you want to have available in your system. The " +"partner titles is the legal status of the company: Private Limited, SA, etc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "To browse official translations, you can start with these links:" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:484 +#, python-format +msgid "" +"You can not read this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: view:res.bank:0 +#: field:res.config.users,address_id:0 +#: view:res.partner.address:0 +#: view:res.users:0 +#: field:res.users,address_id:0 +msgid "Address" +msgstr "" + +#. module: base +#: field:ir.module.module,latest_version:0 +msgid "Installed version" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Mongolian / монгол" +msgstr "" + +#. module: base +#: model:res.country,name:base.mr +msgid "Mauritania" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_translation +msgid "ir.translation" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Module update result" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.workitem,act_id:0 +msgid "Activity" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Postal Address" +msgstr "" + +#. module: base +#: field:res.company,parent_id:0 +msgid "Parent Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CR) / Español (CR)" +msgstr "" + +#. module: base +#: field:res.currency.rate,rate:0 +msgid "Rate" +msgstr "" + +#. module: base +#: model:res.country,name:base.cg +msgid "Congo" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Examples" +msgstr "" + +#. module: base +#: field:ir.default,value:0 +msgid "Default Value" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_tools +msgid "Tools" +msgstr "" + +#. module: base +#: model:res.country,name:base.kn +msgid "Saint Kitts & Nevis Anguilla" +msgstr "" + +#. module: base +#: code:addons/base/res/res_currency.py:100 +#, python-format +msgid "" +"No rate found \n" +"for the currency: %s \n" +"at the date: %s" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view_custom +msgid "" +"Customized views are used when users reorganize the content of their " +"dashboard views (via web client)" +msgstr "" + +#. module: base +#: field:ir.model,name:0 +#: field:ir.model.fields,model:0 +#: field:ir.values,model:0 +msgid "Object Name" +msgstr "" + +#. module: base +#: help:ir.actions.server,srcmodel_id:0 +msgid "" +"Object in which you want to create / write the object. If it is empty then " +"refer to the Object field." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Not Installed" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,out_transitions:0 +msgid "Outgoing Transitions" +msgstr "" + +#. module: base +#: field:ir.ui.menu,icon:0 +msgid "Icon" +msgstr "" + +#. module: base +#: help:ir.model.fields,model_id:0 +msgid "The model this field belongs to" +msgstr "" + +#. module: base +#: model:res.country,name:base.mq +msgid "Martinique (French)" +msgstr "" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequences Type" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request-act +#: model:ir.ui.menu,name:base.menu_res_request_act +#: model:ir.ui.menu,name:base.menu_resquest_ref +#: view:res.request:0 +msgid "Requests" +msgstr "" + +#. module: base +#: model:res.country,name:base.ye +msgid "Yemen" +msgstr "" + +#. module: base +#: selection:workflow.activity,split_mode:0 +msgid "Or" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_log_act_window +#: model:ir.ui.menu,name:base.menu_res_log_act_window +msgid "Client Logs" +msgstr "" + +#. module: base +#: model:res.country,name:base.al +msgid "Albania" +msgstr "" + +#. module: base +#: model:res.country,name:base.ws +msgid "Samoa" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:161 +#, python-format +msgid "" +"You cannot delete the language which is Active !\n" +"Please de-activate the language first." +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +msgid "" +"Please be patient, this operation may take a few minutes (depending on the " +"number of modules currently installed)..." +msgstr "" + +#. module: base +#: field:ir.ui.menu,child_id:0 +msgid "Child IDs" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:713 +#: code:addons/base/ir/ir_actions.py:716 +#, python-format +msgid "Problem in configuration `Record Id` in Server Action!" +msgstr "" + +#. module: base +#: code:addons/orm.py:2306 +#: code:addons/orm.py:2316 +#, python-format +msgid "ValidateError" +msgstr "" + +#. module: base +#: view:base.module.import:0 +#: view:base.module.update:0 +msgid "Open Modules" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_bank_form +msgid "Manage bank records you want to be used in the system." +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Import module" +msgstr "" + +#. module: base +#: field:ir.actions.server,loop_action:0 +msgid "Loop Action" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_file:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another field" +msgstr "" + +#. module: base +#: model:res.country,name:base.la +msgid "Laos" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +#: field:res.config.users,user_email:0 +#: field:res.users,user_email:0 +msgid "Email" +msgstr "" + +#. module: base +#: field:res.config.users,action_id:0 +#: field:res.users,action_id:0 +msgid "Home Action" +msgstr "" + +#. module: base +#: code:addons/custom.py:558 +#, python-format +msgid "" +"The sum of the data (2nd field) is null.\n" +"We can't draw a pie chart !" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_lunch_reporting +#: model:ir.ui.menu,name:base.menu_project_report +#: model:ir.ui.menu,name:base.menu_report_association +#: model:ir.ui.menu,name:base.menu_report_marketing +#: model:ir.ui.menu,name:base.menu_reporting +#: model:ir.ui.menu,name:base.next_id_64 +#: model:ir.ui.menu,name:base.next_id_73 +#: model:ir.ui.menu,name:base.reporting_menu +msgid "Reporting" +msgstr "" + +#. module: base +#: model:res.country,name:base.tg +msgid "Togo" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other Proprietary" +msgstr "" + +#. module: base +#: selection:workflow.activity,kind:0 +msgid "Stop All" +msgstr "" + +#. module: base +#: code:addons/orm.py:412 +#, python-format +msgid "The read_group method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:ir.model.data:0 +msgid "Updatable" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "3. %x ,%X ==> 12/05/08, 18:25:20" +msgstr "" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Cascade" +msgstr "" + +#. module: base +#: field:workflow.transition,group_id:0 +msgid "Group Required" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Next Configuration Step" +msgstr "" + +#. module: base +#: field:res.groups,comment:0 +msgid "Comment" +msgstr "" + +#. module: base +#: model:res.country,name:base.ro +msgid "Romania" +msgstr "" + +#. module: base +#: help:ir.cron,doall:0 +msgid "" +"Enable this if you want to execute missed occurences as soon as the server " +"restarts." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Start update" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:144 +#, python-format +msgid "Contract validation error" +msgstr "" + +#. module: base +#: field:res.country.state,name:0 +msgid "State Name" +msgstr "" + +#. module: base +#: field:workflow.activity,join_mode:0 +msgid "Join Mode" +msgstr "" + +#. module: base +#: field:res.config.users,context_tz:0 +#: field:res.users,context_tz:0 +msgid "Timezone" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_report_xml +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.report.xml" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_miss +msgid "Mss" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view +msgid "ir.ui.view" +msgstr "" + +#. module: base +#: constraint:res.partner:0 +msgid "Error ! You can not create recursive associated members." +msgstr "" + +#. module: base +#: help:res.lang,code:0 +msgid "This field is used to set/get locales for user" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_2 +msgid "OpenERP Partners" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_manager +msgid "HR Manager Dashboard" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:253 +#, python-format +msgid "" +"Unable to install module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Search modules" +msgstr "" + +#. module: base +#: model:res.country,name:base.by +msgid "Belarus" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,name:0 +#: field:ir.actions.act_window_close,name:0 +#: field:ir.actions.actions,name:0 +#: field:ir.actions.server,name:0 +#: field:ir.actions.url,name:0 +#: field:ir.filters,name:0 +msgid "Action Name" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_users +msgid "" +"Create and manage users that will connect to the system. Users can be " +"deactivated should there be a period of time during which they will/should " +"not connect to the system. You can assign them groups in order to give them " +"specific access to the applications they need to use in the system." +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "Normal" +msgstr "" + +#. module: base +#: field:res.bank,street2:0 +#: field:res.partner.address,street2:0 +msgid "Street2" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_update +msgid "Module Update" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Following modules are not installed or unknown: %s" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,user_id:0 +#: view:ir.filters:0 +#: field:ir.filters,user_id:0 +#: field:ir.ui.view.custom,user_id:0 +#: field:ir.values,user_id:0 +#: field:res.log,user_id:0 +#: field:res.partner.event,user_id:0 +#: view:res.users:0 +#: field:res.widget.user,user_id:0 +msgid "User" +msgstr "" + +#. module: base +#: model:res.country,name:base.pr +msgid "Puerto Rico" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open Window" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,auto_search:0 +msgid "Auto Search" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,filter:0 +msgid "Filter" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_madam +msgid "Ms." +msgstr "" + +#. module: base +#: model:res.country,name:base.ch +msgid "Switzerland" +msgstr "" + +#. module: base +#: model:res.country,name:base.gd +msgid "Grenada" +msgstr "" + +#. module: base +#: model:res.country,name:base.wf +msgid "Wallis and Futuna Islands" +msgstr "" + +#. module: base +#: selection:server.action.create,init,type:0 +msgid "Open Report" +msgstr "" + +#. module: base +#: field:res.currency,rounding:0 +msgid "Rounding factor" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "Load" +msgstr "" + +#. module: base +#: help:res.config.users,name:0 +#: help:res.users,name:0 +msgid "The new user's real name, used for searching and most listings" +msgstr "" + +#. module: base +#: code:addons/osv.py:154 +#: code:addons/osv.py:156 +#, python-format +msgid "Integrity Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_wizard_screen +msgid "ir.wizard.screen" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:223 +#, python-format +msgid "Size of the field can never be less than 1 !" +msgstr "" + +#. module: base +#: model:res.country,name:base.so +msgid "Somalia" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Terminated" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_13 +msgid "Important customers" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Update Terms" +msgstr "" + +#. module: base +#: field:partner.sms.send,mobile_to:0 +#: field:res.request,act_to:0 +#: field:res.request.history,act_to:0 +msgid "To" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,args:0 +msgid "Arguments" +msgstr "" + +#. module: base +#: code:addons/orm.py:716 +#, python-format +msgid "Database ID doesn't exist: %s : %s" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 2" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 3" +msgstr "" + +#. module: base +#: code:addons/orm.py:836 +#, python-format +msgid "key '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Correct EAN13" +msgstr "" + +#. module: base +#: code:addons/orm.py:2317 +#, python-format +msgid "The value \"%s\" for the field \"%s\" is not in the selection" +msgstr "" + +#. module: base +#: field:res.partner,customer:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_customer_add:0 +#: model:res.partner.category,name:base.res_partner_category_0 +msgid "Customer" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (NI) / Español (NI)" +msgstr "" + +#. module: base +#: field:ir.module.module,shortdesc:0 +msgid "Short Description" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,context:0 +#: field:ir.filters,context:0 +msgid "Context Value" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->24: %(h24)s" +msgstr "" + +#. module: base +#: field:ir.cron,nextcall:0 +msgid "Next Execution Date" +msgstr "" + +#. module: base +#: help:multi_company.default,field_id:0 +msgid "Select field property" +msgstr "" + +#. module: base +#: field:res.request.history,date_sent:0 +msgid "Date sent" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Month: %(month)s" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,sequence:0 +#: field:ir.actions.server,sequence:0 +#: field:ir.actions.todo,sequence:0 +#: view:ir.cron:0 +#: view:ir.sequence:0 +#: field:ir.ui.menu,sequence:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,priority:0 +#: field:ir.ui.view_sc,sequence:0 +#: field:multi_company.default,sequence:0 +#: field:res.partner.bank,sequence:0 +#: field:res.widget.user,sequence:0 +#: field:wizard.ir.model.menu.create.line,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.tn +msgid "Tunisia" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_mrp_root +msgid "Manufacturing" +msgstr "" + +#. module: base +#: model:res.country,name:base.km +msgid "Comoros" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_server_action +#: view:ir.actions.server:0 +#: model:ir.ui.menu,name:base.menu_server_action +msgid "Server Actions" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Install" +msgstr "" + +#. module: base +#: field:ir.model.fields,selection:0 +msgid "Selection Options" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_right:0 +msgid "Right parent" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Legends for Date and Time Formats" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Copy Object" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:581 +#, python-format +msgid "" +"Group(s) cannot be deleted, because some user(s) still belong to them: %s !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country_state +#: model:ir.ui.menu,name:base.menu_country_state_partner +msgid "Fed. States" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:res.groups:0 +msgid "Access Rules" +msgstr "" + +#. module: base +#: field:ir.default,ref_table:0 +msgid "Table Ref." +msgstr "" + +#. module: base +#: field:ir.actions.act_window,res_model:0 +#: field:ir.actions.report.xml,model:0 +#: field:ir.actions.server,model_id:0 +#: field:ir.actions.wizard,model:0 +#: field:ir.cron,model:0 +#: field:ir.default,field_tbl:0 +#: field:ir.filters,model_id:0 +#: field:ir.model,model:0 +#: view:ir.model.access:0 +#: field:ir.model.access,model_id:0 +#: view:ir.model.data:0 +#: field:ir.model.data,model:0 +#: view:ir.model.fields:0 +#: view:ir.rule:0 +#: field:ir.rule,model_id:0 +#: selection:ir.translation,type:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,model:0 +#: view:ir.values:0 +#: field:ir.values,model_id:0 +#: field:multi_company.default,object_id:0 +#: field:res.log,res_model:0 +#: field:res.request.link,object:0 +#: field:workflow.triggers,model:0 +msgid "Object" +msgstr "" + +#. module: base +#: code:addons/osv.py:151 +#, python-format +msgid "" +"\n" +"\n" +"[object with reference: %s - %s]" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_default +msgid "ir.default" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Minute: %(min)s" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +#: model:ir.actions.act_window,name:base.action_wizard_update_translations +#: model:ir.ui.menu,name:base.menu_wizard_update_translations +msgid "Synchronize Translations" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_10 +msgid "Scheduler" +msgstr "" + +#. module: base +#: help:ir.cron,numbercall:0 +msgid "" +"Number of time the function is called,\n" +"a negative number indicates no limit" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:331 +#, python-format +msgid "" +"Changing the type of a column is not yet supported. Please drop it and " +"create it again!" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,user_id:0 +msgid "User Ref." +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:580 +#, python-format +msgid "Warning !" +msgstr "" + +#. module: base +#: model:res.widget,title:base.google_maps_widget +msgid "Google Maps" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config +#: model:ir.ui.menu,name:base.menu_config +#: model:ir.ui.menu,name:base.menu_event_config +#: model:ir.ui.menu,name:base.menu_lunch_survey_root +#: model:ir.ui.menu,name:base.menu_marketing_config_association +#: model:ir.ui.menu,name:base.menu_marketing_config_root +#: view:res.company:0 +msgid "Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract_wizard +msgid "publisher_warranty.contract.wizard" +msgstr "" + +#. module: base +#: field:ir.actions.server,expression:0 +msgid "Loop Expression" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_start:0 +msgid "Starting Date" +msgstr "" + +#. module: base +#: help:res.partner,website:0 +msgid "Website of Partner" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_5 +msgid "Gold Partner" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner +#: field:res.company,partner_id:0 +#: view:res.partner.address:0 +#: field:res.partner.bank,partner_id:0 +#: field:res.partner.event,partner_id:0 +#: selection:res.partner.title,domain:0 +#: model:res.request.link,name:base.req_link_partner +msgid "Partner" +msgstr "" + +#. module: base +#: model:res.country,name:base.tr +msgid "Turkey" +msgstr "" + +#. module: base +#: model:res.country,name:base.fk +msgid "Falkland Islands" +msgstr "" + +#. module: base +#: model:res.country,name:base.lb +msgid "Lebanon" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,report_type:0 +msgid "Report Type" +msgstr "" + +#. module: base +#: field:ir.actions.todo,state:0 +#: view:ir.module.module:0 +#: field:ir.module.module,state:0 +#: field:ir.module.module.dependency,state:0 +#: field:publisher_warranty.contract,state:0 +#: field:res.bank,state:0 +#: view:res.country.state:0 +#: field:res.partner.bank,state_id:0 +#: view:res.request:0 +#: field:res.request,state:0 +#: field:workflow.instance,state:0 +#: field:workflow.workitem,state:0 +msgid "State" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Galician / Galego" +msgstr "" + +#. module: base +#: model:res.country,name:base.no +msgid "Norway" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "4. %b, %B ==> Dec, December" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: model:ir.ui.menu,name:base.menu_view_base_language_install +msgid "Load an Official Translation" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Miscelleanous" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_10 +msgid "Open Source Service Company" +msgstr "" + +#. module: base +#: model:res.country,name:base.kg +msgid "Kyrgyz Republic (Kyrgyzstan)" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "waiting" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_file:0 +msgid "Report file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_triggers +msgid "workflow.triggers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:62 +#, python-format +msgid "Invalid search criterions" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Created" +msgstr "" + +#. module: base +#: help:ir.actions.wizard,multi:0 +msgid "" +"If set to true, the wizard will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- type,name,res_id,src,value" +msgstr "" + +#. module: base +#: model:res.country,name:base.hm +msgid "Heard and McDonald Islands" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_id:0 +msgid "View Ref." +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Selection" +msgstr "" + +#. module: base +#: field:res.company,rml_header1:0 +msgid "Report Header" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,type:0 +#: field:ir.actions.act_window_close,type:0 +#: field:ir.actions.actions,type:0 +#: field:ir.actions.report.xml,type:0 +#: view:ir.actions.server:0 +#: field:ir.actions.server,state:0 +#: field:ir.actions.server,type:0 +#: field:ir.actions.url,type:0 +#: field:ir.actions.wizard,type:0 +msgid "Action Type" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:268 +#, python-format +msgid "" +"You try to install module '%s' that depends on module '%s'.\n" +"But the latter module is not available in your system." +msgstr "" + +#. module: base +#: view:base.language.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_import_language +#: model:ir.ui.menu,name:base.menu_view_base_import_language +msgid "Import Translation" +msgstr "" + +#. module: base +#: field:res.partner.bank.type,field_ids:0 +msgid "Type fields" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,category_id:0 +msgid "Category" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: selection:ir.property,type:0 +msgid "Binary" +msgstr "" + +#. module: base +#: field:ir.actions.server,sms:0 +#: selection:ir.actions.server,state:0 +msgid "SMS" +msgstr "" + +#. module: base +#: model:res.country,name:base.cr +msgid "Costa Rica" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +msgid "Conditions" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_other_form +msgid "Other Partners" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_currency_form +#: model:ir.ui.menu,name:base.menu_action_currency_form +#: view:res.currency:0 +msgid "Currencies" +msgstr "" + +#. module: base +#: sql_constraint:res.groups:0 +msgid "The name of the group must be unique !" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->12: %(h12)s" +msgstr "" + +#. module: base +#: help:res.partner.address,active:0 +msgid "Uncheck the active field to hide the contact." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_wizard +msgid "Add a widget for User" +msgstr "" + +#. module: base +#: model:res.country,name:base.dk +msgid "Denmark" +msgstr "" + +#. module: base +#: field:res.country,code:0 +msgid "Country Code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_instance +msgid "workflow.instance" +msgstr "" + +#. module: base +#: code:addons/orm.py:278 +#, python-format +msgid "Unknown attribute %s in %s " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "10. %S ==> 20" +msgstr "" + +#. module: base +#: code:addons/fields.py:106 +#, python-format +msgid "undefined get method !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Norwegian Bokmål / Norsk bokmål" +msgstr "" + +#. module: base +#: help:res.config.users,new_password:0 +#: help:res.users,new_password:0 +msgid "" +"Only specify a value if you want to change the user password. This user will " +"have to logout and login again!" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_madam +msgid "Madam" +msgstr "" + +#. module: base +#: model:res.country,name:base.ee +msgid "Estonia" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.dashboard +msgid "Dashboards" +msgstr "" + +#. module: base +#: help:ir.attachment,type:0 +msgid "Binary File or external URL" +msgstr "" + +#. module: base +#: field:res.config.users,new_password:0 +#: field:res.users,new_password:0 +msgid "Change password" +msgstr "" + +#. module: base +#: model:res.country,name:base.nl +msgid "Netherlands" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_4 +msgid "Low Level Objects" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Your Logo - Use a size of about 450x150 pixels." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_values +msgid "ir.values" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Occitan (FR, post 1500) / Occitan" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.open_module_tree +msgid "" +"You can install new modules in order to activate new features, menu, reports " +"or data in your OpenERP instance. To install some modules, click on the " +"button \"Schedule for Installation\" from the form view, then click on " +"\"Apply Scheduled Upgrades\" to migrate your system." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_emails +#: model:ir.ui.menu,name:base.menu_mail_gateway +msgid "Emails" +msgstr "" + +#. module: base +#: model:res.country,name:base.cd +msgid "Congo, The Democratic Republic of the" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Malayalam / മലയാളം" +msgstr "" + +#. module: base +#: view:res.request:0 +#: field:res.request,body:0 +#: field:res.request.history,req_id:0 +msgid "Request" +msgstr "" + +#. module: base +#: model:res.country,name:base.jp +msgid "Japan" +msgstr "" + +#. module: base +#: field:ir.cron,numbercall:0 +msgid "Number of Calls" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +#: field:base.module.upgrade,module_info:0 +msgid "Modules to update" +msgstr "" + +#. module: base +#: help:ir.actions.server,sequence:0 +msgid "" +"Important when you deal with multiple actions, the execution order will be " +"decided based on this, low number is higher priority." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,header:0 +msgid "Add RML header" +msgstr "" + +#. module: base +#: model:res.country,name:base.gr +msgid "Greece" +msgstr "" + +#. module: base +#: field:res.request,trigger_date:0 +msgid "Trigger Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Croatian / hrvatski jezik" +msgstr "" + +#. module: base +#: field:base.language.install,overwrite:0 +msgid "Overwrite Existing Terms" +msgstr "" + +#. module: base +#: help:ir.actions.server,code:0 +msgid "Python code to be executed" +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The code of the country must be unique !" +msgstr "" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Uninstallable" +msgstr "" + +#. module: base +#: view:res.partner.category:0 +msgid "Partner Category" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Trigger" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_update +msgid "Update Module" +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,translate:0 +msgid "Translate" +msgstr "" + +#. module: base +#: field:res.request.history,body:0 +msgid "Body" +msgstr "" + +#. module: base +#: view:partner.wizard.spam:0 +msgid "Send Email" +msgstr "" + +#. module: base +#: field:res.config.users,menu_id:0 +#: field:res.users,menu_id:0 +msgid "Menu Action" +msgstr "" + +#. module: base +#: help:ir.model.fields,selection:0 +msgid "" +"List of options for a selection field, specified as a Python expression " +"defining a list of (key, label) pairs. For example: " +"[('blue','Blue'),('yellow','Yellow')]" +msgstr "" + +#. module: base +#: selection:base.language.export,state:0 +msgid "choose" +msgstr "" + +#. module: base +#: help:ir.model,osv_memory:0 +msgid "" +"Indicates whether this object model lives in memory only, i.e. is not " +"persisted (osv.osv_memory)" +msgstr "" + +#. module: base +#: field:res.partner,child_ids:0 +#: field:res.request,ref_partner_id:0 +msgid "Partner Ref." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_supplier_form +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier_name +#: view:res.partner:0 +msgid "Suppliers" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Register" +msgstr "" + +#. module: base +#: field:res.request,ref_doc2:0 +msgid "Document Ref 2" +msgstr "" + +#. module: base +#: field:res.request,ref_doc1:0 +msgid "Document Ref 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.ga +msgid "Gabon" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_model_data +msgid "ir.model.data" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.rule:0 +#: view:res.groups:0 +msgid "Access Rights" +msgstr "" + +#. module: base +#: model:res.country,name:base.gl +msgid "Greenland" +msgstr "" + +#. module: base +#: field:res.partner.bank,acc_number:0 +msgid "Account Number" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "1. %c ==> Fri Dec 5 18:25:20 2008" +msgstr "" + +#. module: base +#: model:res.country,name:base.nc +msgid "New Caledonia (French)" +msgstr "" + +#. module: base +#: model:res.country,name:base.cy +msgid "Cyprus" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "" +"This wizard helps you add a new language to you OpenERP system. After " +"loading a new language it becomes available as default interface language " +"for users and partners." +msgstr "" + +#. module: base +#: field:ir.actions.server,subject:0 +#: field:partner.wizard.spam,subject:0 +#: field:res.request,name:0 +msgid "Subject" +msgstr "" + +#. module: base +#: field:res.request,act_from:0 +#: field:res.request.history,act_from:0 +msgid "From" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Preferences" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_consumers0 +msgid "Consumers" +msgstr "" + +#. module: base +#: view:res.config:0 +#: wizard_button:server.action.create,init,step_1:0 +msgid "Next" +msgstr "" + +#. module: base +#: help:ir.cron,function:0 +msgid "" +"Name of the method to be called on the object when this scheduler is " +"executed." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:219 +#, python-format +msgid "" +"The Selection Options expression is must be in the [('key','Label'), ...] " +"format!" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Miscellaneous" +msgstr "" + +#. module: base +#: model:res.country,name:base.cn +msgid "China" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:516 +#, python-format +msgid "" +"--\n" +"%(name)s %(email)s\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.eh +msgid "Western Sahara" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow +msgid "workflow" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_company_form +msgid "" +"Create and manage the companies that will be managed by OpenERP from here. " +"Shops or subsidiaries can be created and maintained from here." +msgstr "" + +#. module: base +#: model:res.country,name:base.id +msgid "Indonesia" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +msgid "" +"This wizard will detect new terms to translate in the application, so that " +"you can then add translations manually or perform a complete export (as a " +"template for a new language example)." +msgstr "" + +#. module: base +#: help:multi_company.default,expression:0 +msgid "" +"Expression, must be True to match\n" +"use context.get or user (browse)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bg +msgid "Bulgaria" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Publisher warranty contract successfully registered!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ao +msgid "Angola" +msgstr "" + +#. module: base +#: model:res.country,name:base.tf +msgid "French Southern Territories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_currency +#: field:res.company,currency_id:0 +#: field:res.company,currency_ids:0 +#: view:res.currency:0 +#: field:res.currency,name:0 +#: field:res.currency.rate,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: base +#: field:res.partner.canal,name:0 +msgid "Channel Name" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "5. %y, %Y ==> 08, 2008" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_ltd +msgid "ltd" +msgstr "" + +#. module: base +#: field:ir.values,res_id:0 +#: field:res.log,res_id:0 +msgid "Object ID" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Landscape" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration +msgid "Administration" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Click on Update below to start the process..." +msgstr "" + +#. module: base +#: model:res.country,name:base.ir +msgid "Iran" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_user_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_user_act_window +msgid "Widgets per User" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovak / Slovenský jazyk" +msgstr "" + +#. module: base +#: field:base.language.export,state:0 +#: field:ir.ui.menu,icon_pict:0 +#: field:publisher_warranty.contract.wizard,state:0 +msgid "unknown" +msgstr "" + +#. module: base +#: field:res.currency,symbol:0 +msgid "Symbol" +msgstr "" + +#. module: base +#: help:res.config.users,login:0 +#: help:res.users,login:0 +msgid "Used to log into the system" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +msgid "Synchronize Translation" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,res_id:0 +msgid "Resource Ref." +msgstr "" + +#. module: base +#: model:res.country,name:base.ki +msgid "Kiribati" +msgstr "" + +#. module: base +#: model:res.country,name:base.iq +msgid "Iraq" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_association +msgid "Association" +msgstr "" + +#. module: base +#: model:res.country,name:base.cl +msgid "Chile" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_address_book +#: model:ir.ui.menu,name:base.menu_config_address_book +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier +msgid "Address Book" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence_type +msgid "ir.sequence.type" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "CSV File" +msgstr "" + +#. module: base +#: field:res.company,account_no:0 +msgid "Account No." +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:157 +#, python-format +msgid "Base Language 'en_US' can not be deleted !" +msgstr "" + +#. module: base +#: selection:ir.model,state:0 +msgid "Base Object" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Dependencies :" +msgstr "" + +#. module: base +#: field:ir.model.fields,field_description:0 +msgid "Field Label" +msgstr "" + +#. module: base +#: model:res.country,name:base.dj +msgid "Djibouti" +msgstr "" + +#. module: base +#: field:ir.translation,value:0 +msgid "Translation Value" +msgstr "" + +#. module: base +#: model:res.country,name:base.ag +msgid "Antigua and Barbuda" +msgstr "" + +#. module: base +#: code:addons/orm.py:3166 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: %s, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.zr +msgid "Zaire" +msgstr "" + +#. module: base +#: field:ir.model.data,res_id:0 +#: field:ir.translation,res_id:0 +#: field:workflow.instance,res_id:0 +#: field:workflow.triggers,res_id:0 +msgid "Resource ID" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.model,info:0 +msgid "Information" +msgstr "" + +#. module: base +#: view:res.widget.user:0 +msgid "User Widgets" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Update Module List" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Other" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Reply" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Turkish / Türkçe" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_activity_form +#: model:ir.ui.menu,name:base.menu_workflow_activity +#: view:workflow:0 +#: field:workflow,activities:0 +msgid "Activities" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,auto_refresh:0 +msgid "Auto-Refresh" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:62 +#, python-format +msgid "The osv_memory field can only be compared with = and != operator." +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "Diagram" +msgstr "" + +#. module: base +#: help:multi_company.default,name:0 +msgid "Name it to easily find a record" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.grant_menu_access +#: model:ir.ui.menu,name:base.menu_grant_menu_access +msgid "Menu Items" +msgstr "" + +#. module: base +#: constraint:ir.rule:0 +msgid "Rules are not supported for osv_memory objects !" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_event_association +#: model:ir.ui.menu,name:base.menu_event_main +msgid "Events Organisation" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_actions +#: model:ir.ui.menu,name:base.menu_custom_action +#: model:ir.ui.menu,name:base.menu_ir_sequence_actions +#: model:ir.ui.menu,name:base.next_id_6 +#: view:workflow.activity:0 +msgid "Actions" +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "High" +msgstr "" + +#. module: base +#: field:ir.exports.line,export_id:0 +msgid "Export" +msgstr "" + +#. module: base +#: model:res.country,name:base.hr +msgid "Croatia" +msgstr "" + +#. module: base +#: help:res.bank,bic:0 +msgid "Bank Identifier Code" +msgstr "" + +#. module: base +#: model:res.country,name:base.tm +msgid "Turkmenistan" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:597 +#: code:addons/base/ir/ir_actions.py:629 +#: code:addons/base/ir/ir_actions.py:713 +#: code:addons/base/ir/ir_actions.py:716 +#: code:addons/base/ir/ir_model.py:114 +#: code:addons/base/ir/ir_model.py:204 +#: code:addons/base/ir/ir_model.py:218 +#: code:addons/base/ir/ir_model.py:232 +#: code:addons/base/ir/ir_model.py:250 +#: code:addons/base/ir/ir_model.py:255 +#: code:addons/base/ir/ir_model.py:258 +#: code:addons/base/module/module.py:215 +#: code:addons/base/module/module.py:258 +#: code:addons/base/module/module.py:262 +#: code:addons/base/module/module.py:268 +#: code:addons/base/module/module.py:303 +#: code:addons/base/module/module.py:321 +#: code:addons/base/module/module.py:336 +#: code:addons/base/module/module.py:429 +#: code:addons/base/module/module.py:531 +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#: code:addons/base/publisher_warranty/publisher_warranty.py:281 +#: code:addons/base/res/res_currency.py:100 +#: code:addons/base/res/res_user.py:57 +#: code:addons/base/res/res_user.py:66 +#: code:addons/custom.py:558 +#: code:addons/orm.py:3199 +#, python-format +msgid "Error" +msgstr "" + +#. module: base +#: model:res.country,name:base.pm +msgid "Saint Pierre and Miquelon" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,header:0 +msgid "Add or not the coporate RML header" +msgstr "" + +#. module: base +#: help:workflow.transition,act_to:0 +msgid "The destination activity." +msgstr "" + +#. module: base +#: view:base.module.update:0 +#: view:base.update.translations:0 +msgid "Update" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.ir_module_reference_print +msgid "Technical guide" +msgstr "" + +#. module: base +#: model:res.country,name:base.tz +msgid "Tanzania" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Danish / Dansk" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Advanced Search (deprecated)" +msgstr "" + +#. module: base +#: model:res.country,name:base.cx +msgid "Christmas Island" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Other Actions Configuration" +msgstr "" + +#. module: base +#: view:res.config.installer:0 +msgid "Install Modules" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_partner_canal-act +#: model:ir.model,name:base.model_res_partner_canal +#: model:ir.ui.menu,name:base.menu_res_partner_canal-act +#: view:res.partner.canal:0 +msgid "Channels" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Extra Info" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form_action +#: model:ir.ui.menu,name:base.menu_values_form_action +msgid "Client Events" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Schedule for Installation" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_partner_wizard_ean_check +msgid "Ean Check" +msgstr "" + +#. module: base +#: sql_constraint:res.config.users:0 +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_multi_company_default +msgid "Default multi company" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Send" +msgstr "" + +#. module: base +#: field:res.config.users,menu_tips:0 +#: field:res.users,menu_tips:0 +msgid "Menu Tips" +msgstr "" + +#. module: base +#: field:ir.translation,src:0 +msgid "Source" +msgstr "" + +#. module: base +#: help:res.partner.address,partner_id:0 +msgid "Keep empty for a private address, not related to partner." +msgstr "" + +#. module: base +#: model:res.country,name:base.vu +msgid "Vanuatu" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Internal Header/Footer" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:59 +#, python-format +msgid "" +"Save this document to a .tgz file. This archive containt UTF-8 %s files and " +"may be uploaded to launchpad." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Start configuration" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "_Export" +msgstr "" + +#. module: base +#: field:base.language.install,state:0 +#: field:base.module.import,state:0 +#: field:base.module.update,state:0 +msgid "state" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Catalan / Català" +msgstr "" + +#. module: base +#: model:res.country,name:base.do +msgid "Dominican Republic" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Cyrillic) / српски" +msgstr "" + +#. module: base +#: code:addons/orm.py:2161 +#, python-format +msgid "" +"Invalid group_by specification: \"%s\".\n" +"A group_by specification must be a list of valid fields." +msgstr "" + +#. module: base +#: model:res.country,name:base.sa +msgid "Saudi Arabia" +msgstr "" + +#. module: base +#: help:res.partner,supplier:0 +msgid "" +"Check this box if the partner is a supplier. If it's not checked, purchase " +"people will not see it when encoding a purchase order." +msgstr "" + +#. module: base +#: field:ir.model.fields,relation_field:0 +msgid "Relation Field" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "Event Logs" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_configuration.py:37 +#, python-format +msgid "System Configuration done" +msgstr "" + +#. module: base +#: field:workflow.triggers,instance_id:0 +msgid "Destination Instance" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,multi:0 +#: field:ir.actions.wizard,multi:0 +msgid "Action on Multiple Doc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://translations.launchpad.net/openobject" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xml:0 +msgid "XML path" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "On Skip" +msgstr "" + +#. module: base +#: model:res.country,name:base.gn +msgid "Guinea" +msgstr "" + +#. module: base +#: model:res.country,name:base.lu +msgid "Luxembourg" +msgstr "" + +#. module: base +#: help:ir.values,key2:0 +msgid "" +"The kind of action or button in the client side that will trigger the action." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_ui_menu.py:285 +#, python-format +msgid "Error ! You can not create recursive Menu." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_add_wizard +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract_add +#: view:publisher_warranty.contract.wizard:0 +msgid "Register a Contract" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"3. If user belongs to several groups, the results from step 2 are combined " +"with logical OR operator" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:145 +#, python-format +msgid "Please check your publisher warranty contract name and validity." +msgstr "" + +#. module: base +#: model:res.country,name:base.sv +msgid "El Salvador" +msgstr "" + +#. module: base +#: field:res.bank,phone:0 +#: field:res.partner,phone:0 +#: field:res.partner.address,phone:0 +msgid "Phone" +msgstr "" + +#. module: base +#: field:ir.cron,active:0 +#: field:ir.sequence,active:0 +#: field:res.bank,active:0 +#: field:res.config.users,active:0 +#: field:res.currency,active:0 +#: field:res.lang,active:0 +#: field:res.partner,active:0 +#: field:res.partner.address,active:0 +#: field:res.partner.canal,active:0 +#: field:res.partner.category,active:0 +#: field:res.request,active:0 +#: field:res.users,active:0 +#: view:workflow.instance:0 +#: view:workflow.workitem:0 +msgid "Active" +msgstr "" + +#. module: base +#: model:res.country,name:base.th +msgid "Thailand" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_lead +msgid "Leads & Opportunities" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Romanian / română" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "System Logs" +msgstr "" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "And" +msgstr "" + +#. module: base +#: field:ir.model.fields,relation:0 +msgid "Object Relation" +msgstr "" + +#. module: base +#: view:ir.rule:0 +#: view:res.partner:0 +msgid "General" +msgstr "" + +#. module: base +#: model:res.country,name:base.uz +msgid "Uzbekistan" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.act_window" +msgstr "" + +#. module: base +#: field:ir.rule,perm_create:0 +msgid "Apply For Create" +msgstr "" + +#. module: base +#: model:res.country,name:base.vi +msgid "Virgin Islands (USA)" +msgstr "" + +#. module: base +#: model:res.country,name:base.tw +msgid "Taiwan" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_currency_rate +msgid "Currency Rate" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.grant_menu_access +msgid "" +"Manage and customize the items available and displayed in your OpenERP " +"system menu. You can delete an item by clicking on the box at the beginning " +"of each line and then delete it through the button that appeared. Items can " +"be assigned to specific groups in order to make them accessible to some " +"users within the system." +msgstr "" + +#. module: base +#: field:ir.ui.view,field_parent:0 +msgid "Child Field" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,usage:0 +#: field:ir.actions.act_window_close,usage:0 +#: field:ir.actions.actions,usage:0 +#: field:ir.actions.report.xml,usage:0 +#: field:ir.actions.server,usage:0 +#: field:ir.actions.wizard,usage:0 +msgid "Action Usage" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_workitem +msgid "workflow.workitem" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +msgid "Not Installable" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "View :" +msgstr "" + +#. module: base +#: field:ir.model.fields,view_load:0 +msgid "View Auto-Load" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:232 +#, python-format +msgid "You cannot remove the field '%s' !" +msgstr "" + +#. module: base +#: field:ir.exports,resource:0 +#: view:ir.property:0 +#: field:ir.property,res_id:0 +msgid "Resource" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon:0 +msgid "Web Icon File" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Persian / فارس" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "View Ordering" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Unmet dependency !" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Supported file formats: *.csv (Comma-separated values) or *.po (GetText " +"Portable Objects)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:487 +#, python-format +msgid "" +"You can not delete this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_configuration +msgid "base.module.configuration" +msgstr "" + +#. module: base +#: field:base.language.export,name:0 +#: field:ir.attachment,datas_fname:0 +msgid "Filename" +msgstr "" + +#. module: base +#: field:ir.model,access_ids:0 +#: view:ir.model.access:0 +msgid "Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.sk +msgid "Slovak Republic" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.publisher_warranty +msgid "Publisher Warranty" +msgstr "" + +#. module: base +#: model:res.country,name:base.aw +msgid "Aruba" +msgstr "" + +#. module: base +#: model:res.country,name:base.ar +msgid "Argentina" +msgstr "" + +#. module: base +#: field:res.groups,name:0 +msgid "Group Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.bh +msgid "Bahrain" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_12 +msgid "Segmentation" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: field:ir.attachment,company_id:0 +#: field:ir.default,company_id:0 +#: field:ir.property,company_id:0 +#: field:ir.sequence,company_id:0 +#: field:ir.values,company_id:0 +#: view:res.company:0 +#: field:res.config.users,company_id:0 +#: field:res.currency,company_id:0 +#: field:res.partner,company_id:0 +#: field:res.partner.address,company_id:0 +#: view:res.users:0 +#: field:res.users,company_id:0 +msgid "Company" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Email & Signature" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contract" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bulgarian / български език" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_aftersale +msgid "After-Sale Services" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Launch" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,limit:0 +msgid "Limit" +msgstr "" + +#. module: base +#: help:ir.actions.server,wkf_model_id:0 +msgid "Workflow to be executed on this model." +msgstr "" + +#. module: base +#: model:res.country,name:base.jm +msgid "Jamaica" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_category_form +msgid "" +"Manage the partner categories in order to better classify them for tracking " +"and analysis purposes. A partner may belong to several categories and " +"categories have a hierarchy structure: a partner belonging to a category " +"also belong to his parent category." +msgstr "" + +#. module: base +#: model:res.country,name:base.az +msgid "Azerbaijan" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:250 +#, python-format +msgid "Warning" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Arabic / الْعَرَبيّة" +msgstr "" + +#. module: base +#: model:res.country,name:base.vg +msgid "Virgin Islands (British)" +msgstr "" + +#. module: base +#: view:ir.property:0 +#: model:ir.ui.menu,name:base.next_id_15 +msgid "Parameters" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Czech / Čeština" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Trigger Configuration" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_supplier_form +msgid "" +"You can access all information regarding your suppliers from the supplier " +"form: accounting data, history of emails, meetings, purchases, etc. You can " +"uncheck the 'Suppliers' filter button in order to search in all your " +"partners, including customers and prospects." +msgstr "" + +#. module: base +#: model:res.country,name:base.rw +msgid "Rwanda" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the week (0:Monday): %(weekday)s" +msgstr "" + +#. module: base +#: model:res.country,name:base.ck +msgid "Cook Islands" +msgstr "" + +#. module: base +#: field:ir.model.data,noupdate:0 +msgid "Non Updatable" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Klingon" +msgstr "" + +#. module: base +#: model:res.country,name:base.sg +msgid "Singapore" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +msgid "Current Window" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action Source" +msgstr "" + +#. module: base +#: view:res.config.view:0 +msgid "" +"If you use OpenERP for the first time we strongly advise you to select the " +"simplified interface, which has less features but is easier. You can always " +"switch later from the user preferences." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country +#: field:res.bank,country:0 +#: view:res.country:0 +#: field:res.country.state,country_id:0 +#: field:res.partner,country:0 +#: view:res.partner.address:0 +#: field:res.partner.address,country_id:0 +#: field:res.partner.bank,country_id:0 +msgid "Country" +msgstr "" + +#. module: base +#: field:ir.model.fields,complete_name:0 +#: field:ir.ui.menu,complete_name:0 +msgid "Complete Name" +msgstr "" + +#. module: base +#: field:ir.values,object:0 +msgid "Is Object" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"1. Global rules are combined together with a logical AND operator, and with " +"the result of the following steps" +msgstr "" + +#. module: base +#: field:res.partner.category,name:0 +msgid "Category Name" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_15 +msgid "IT sector" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Select Groups" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%X - Appropriate time representation." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (SV) / Español (SV)" +msgstr "" + +#. module: base +#: help:res.lang,grouping:0 +msgid "" +"The Separator Format should be like [,n] where 0 < n :starting from Unit " +"digit.-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be " +"1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as " +"106,500. Provided ',' as the thousand separator in each case." +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Portrait" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:317 +#, python-format +msgid "Can only rename one column at a time!" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Button" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Report/Template" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Graph" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_server +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.server" +msgstr "" + +#. module: base +#: field:ir.actions.configuration.wizard,progress:0 +#: field:res.config,progress:0 +#: field:res.config.installer,progress:0 +#: field:res.config.users,progress:0 +#: field:res.config.view,progress:0 +msgid "Configuration Progress" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form +#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form +#: model:ir.ui.menu,name:base.next_id_11 +msgid "Configuration Wizards" +msgstr "" + +#. module: base +#: field:res.lang,code:0 +msgid "Locale Code" +msgstr "" + +#. module: base +#: field:workflow.activity,split_mode:0 +msgid "Split Mode" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Note that this operation might take a few minutes." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_localisation +msgid "Localisation" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Action to Launch" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Execution" +msgstr "" + +#. module: base +#: field:ir.actions.server,condition:0 +#: field:workflow.transition,condition:0 +msgid "Condition" +msgstr "" + +#. module: base +#: help:ir.values,model_id:0 +msgid "This field is not used, it only helps you to select a good model." +msgstr "" + +#. module: base +#: field:ir.ui.view,name:0 +msgid "View Name" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Italian / Italiano" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,attachment:0 +msgid "Save As Attachment Prefix" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Only one client action will be executed, last client action will be " +"considered in case of multiple client actions." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%j - Day of the year [001,366]." +msgstr "" + +#. module: base +#: field:ir.actions.server,mobile:0 +msgid "Mobile No" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_by_category +#: model:ir.actions.act_window,name:base.action_partner_category_form +#: model:ir.model,name:base.model_res_partner_category +#: model:ir.ui.menu,name:base.menu_partner_category_form +#: view:res.partner.category:0 +msgid "Partner Categories" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System Update" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Field" +msgstr "" + +#. module: base +#: help:ir.sequence,prefix:0 +msgid "Prefix value of the record for the sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.sc +msgid "Seychelles" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank +#: view:res.partner.bank:0 +msgid "Bank Accounts" +msgstr "" + +#. module: base +#: model:res.country,name:base.sl +msgid "Sierra Leone" +msgstr "" + +#. module: base +#: view:res.company:0 +#: view:res.partner:0 +msgid "General Information" +msgstr "" + +#. module: base +#: model:res.country,name:base.tc +msgid "Turks and Caicos Islands" +msgstr "" + +#. module: base +#: field:res.partner.bank,owner_name:0 +msgid "Account Owner" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:256 +#, python-format +msgid "Company Switch Warning" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_widget_wizard +msgid "Homepage Widgets Management" +msgstr "" + +#. module: base +#: field:workflow,osv:0 +#: field:workflow.instance,res_type:0 +msgid "Resource Object" +msgstr "" + +#. module: base +#: help:ir.sequence,number_increment:0 +msgid "The next number of the sequence will be incremented by this number" +msgstr "" + +#. module: base +#: field:ir.cron,function:0 +#: field:res.partner.address,function:0 +#: selection:workflow.activity,kind:0 +msgid "Function" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Search Widget" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "Never" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Delivery" +msgstr "" + +#. module: base +#: 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 "" + +#. module: base +#: model:res.country,name:base.gw +msgid "Guinea Bissau" +msgstr "" + +#. module: base +#: view:workflow.instance:0 +msgid "Workflow Instances" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:261 +#, python-format +msgid "Partners: " +msgstr "" + +#. module: base +#: model:res.country,name:base.kp +msgid "North Korea" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Create Object" +msgstr "" + +#. module: base +#: view:ir.filters:0 +#: field:res.log,context:0 +msgid "Context" +msgstr "" + +#. module: base +#: field:res.bank,bic:0 +msgid "BIC/Swift code" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_1 +msgid "Prospect" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Polish / Język polski" +msgstr "" + +#. module: base +#: field:ir.exports,name:0 +msgid "Export Name" +msgstr "" + +#. module: base +#: help:res.partner.address,type:0 +msgid "" +"Used to select automatically the right address according to the context in " +"sales and purchases documents." +msgstr "" + +#. module: base +#: model:res.country,name:base.lk +msgid "Sri Lanka" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Russian / русский язык" +msgstr "" diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po index 0025fb970e6..b3e6de7ada7 100644 --- a/openerp/addons/base/i18n/ko.po +++ b/openerp/addons/base/i18n/ko.po @@ -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: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -39,7 +39,7 @@ msgstr "기타 설정" #. module: base #: selection:ir.property,type:0 msgid "DateTime" -msgstr "" +msgstr "일시" #. module: base #: code:addons/fields.py:534 @@ -48,6 +48,8 @@ msgid "" "The second argument of the many2many field %s must be a SQL table !You used " "%s, which is not a valid SQL table name." msgstr "" +"many2many 필드 %s 의 두번째 매개변수는 SQL테이블이어야 합니다.\r\n" +"당신은 SQL테이블이름이 아닌 %s를 사용했습니다." #. module: base #: view:ir.values:0 @@ -79,12 +81,12 @@ msgstr "워크플로우" #. module: base #: view:partner.sms.send:0 msgid "SMS - Gateway: clickatell" -msgstr "" +msgstr "SMS - 게이트웨이:clickatell" #. module: base #: selection:base.language.install,lang:0 msgid "Hungarian / Magyar" -msgstr "" +msgstr "헝가리어" #. module: base #: selection:ir.model.fields,select_level:0 @@ -94,7 +96,7 @@ msgstr "검색 불가능" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (VE) / Español (VE)" -msgstr "" +msgstr "스페인어" #. module: base #: field:ir.actions.server,wkf_model_id:0 @@ -117,7 +119,7 @@ msgstr "생성된 뷰" msgid "" "You can not write in this document (%s) ! Be sure your user belongs to one " "of these groups: %s." -msgstr "" +msgstr "이 문서(%s)안에 쓸 수 있는 권한이 없습니다. 당신의 계정이 그룹 %s 에 속해 있는 멤버인지 확인하세요." #. module: base #: help:ir.model.fields,domain:0 @@ -125,7 +127,7 @@ msgid "" "The optional domain to restrict possible values for relationship fields, " "specified as a Python expression defining a list of triplets. For example: " "[('color','=','red')]" -msgstr "" +msgstr "선택적 도메인은 파이썬의 표현식과 같은 관계 필드를 위해 가능한 값들을 제한한다. 예: [('색상','=','빨강')]" #. module: base #: field:res.partner,ref:0 @@ -165,7 +167,7 @@ msgstr "" #. module: base #: model:res.country,name:base.sz msgid "Swaziland" -msgstr "" +msgstr "스와질랜드" #. module: base #: code:addons/orm.py:1993 @@ -203,7 +205,7 @@ msgstr "회사 구조" #. module: base #: selection:base.language.install,lang:0 msgid "Inuktitut / ᐃᓄᒃᑎᑐᑦ" -msgstr "" +msgstr "이뉴잇" #. module: base #: view:res.partner:0 @@ -214,7 +216,7 @@ msgstr "거래처 검색" #: code:addons/base/res/res_user.py:132 #, python-format msgid "\"smtp_server\" needs to be set to send mails to users" -msgstr "" +msgstr "\"smtp_server\"는 사용자에게 메일을 보내기 위해 필요하다." #. module: base #: code:addons/base/module/wizard/base_export_language.py:60 @@ -225,7 +227,7 @@ msgstr "새로" #. module: base #: field:ir.actions.report.xml,multi:0 msgid "On multiple doc." -msgstr "" +msgstr "여러 문서상" #. module: base #: field:ir.module.category,module_nr:0 @@ -235,7 +237,7 @@ msgstr "모듈 수" #. module: base #: help:multi_company.default,company_dest_id:0 msgid "Company to store the current record" -msgstr "" +msgstr "현재 레코드를 저장할 회사" #. module: base #: field:res.partner.bank.type.field,size:0 @@ -258,7 +260,7 @@ msgstr "이 문서를 %s 파일로 저장하고, 특별한 소프트웨어 또ëŠ #. module: base #: sql_constraint:res.lang:0 msgid "The name of the language must be unique !" -msgstr "" +msgstr "언어 명은 유일해아 한다." #. module: base #: selection:res.request,state:0 @@ -274,7 +276,7 @@ msgstr "위저드 이름" #: code:addons/orm.py:2160 #, python-format msgid "Invalid group_by" -msgstr "" +msgstr "잘못된 group_by" #. module: base #: field:res.partner,credit_limit:0 @@ -557,6 +559,8 @@ msgid "" "Launchpad.net, our open source project management facility. We use their " "online interface to synchronize all translations efforts." msgstr "" +"OpenERP 번역(코어, 모듈들, 클라이언트)은 Launchpad.net에 의해 이루어지며,\r\n" +"Launchpad.net은 오픈소스 프로젝트 관리기능입니다." #. module: base #: field:res.partner,title:0 @@ -581,7 +585,7 @@ msgstr "위저드 뷰" #. module: base #: model:res.country,name:base.kh msgid "Cambodia, Kingdom of" -msgstr "" +msgstr "캄보디아" #. module: base #: model:ir.actions.act_window,name:base.ir_sequence_form @@ -604,7 +608,7 @@ msgstr "" #. module: base #: selection:base.language.install,lang:0 msgid "Albanian / Shqip" -msgstr "" +msgstr "아라비안" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_opportunity @@ -634,7 +638,7 @@ msgstr "기본 파트너" #. module: base #: report:ir.module.reference.graph:0 msgid "," -msgstr "" +msgstr "," #. module: base #: view:res.partner:0 @@ -678,7 +682,7 @@ msgstr "그룹은 오브젝트의 접근권한 및 화면과 메뉴 노출 관ë¦ #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (UY) / Español (UY)" -msgstr "" +msgstr "스페인어" #. module: base #: field:res.partner,mobile:0 @@ -751,7 +755,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ad msgid "Andorra, Principality of" -msgstr "" +msgstr "안도라" #. module: base #: field:ir.module.category,child_ids:0 @@ -767,7 +771,7 @@ msgstr "" #. module: base #: selection:base.language.export,format:0 msgid "TGZ Archive" -msgstr "" +msgstr "TGZ 아카이브" #. module: base #: view:res.lang:0 @@ -848,7 +852,7 @@ msgstr "트랜지션" #: code:addons/orm.py:4020 #, python-format msgid "Record #%d of %s not found, cannot copy!" -msgstr "" +msgstr "레코드 #%d (%s) 가 발견되지 않아서 복사될 수 없습니다." #. module: base #: field:ir.module.module,contributors:0 @@ -869,7 +873,7 @@ msgstr "계약서" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (AR) / Español (AR)" -msgstr "" +msgstr "스페인어" #. module: base #: model:res.country,name:base.ug @@ -903,11 +907,13 @@ msgid "" "Lauchpad's web interface (Rosetta). If you need to perform mass translation, " "Launchpad also allows uploading full .po files at once" msgstr "" +"공식적인 번역을 확장하거나 개선하기 위해, 당신은 Lauchpad의 웹인터페이스를 사용할 있습니다.\r\n" +"당신이 대량의 번역을 적용하기 원한다면 Lauchpad의 .po파일을 다운로드/업로드기능을 사용하시면 됩니다." #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (GT) / Español (GT)" -msgstr "" +msgstr "스페인" #. module: base #: view:res.lang:0 @@ -928,7 +934,7 @@ msgstr "웹 사이트" #. module: base #: model:res.country,name:base.gs msgid "S. Georgia & S. Sandwich Isls." -msgstr "" +msgstr "세인트 조지아와 세이트 샌드위치 섬" #. module: base #: field:ir.actions.url,url:0 @@ -949,7 +955,7 @@ msgstr "마셜 제도" #: code:addons/base/ir/ir_model.py:328 #, python-format msgid "Changing the model of a field is forbidden!" -msgstr "" +msgstr "필드 모델 변경은 금지되어 있습니다." #. module: base #: model:res.country,name:base.ht @@ -971,18 +977,21 @@ msgid "" "reference it\n" "- creation/update: a mandatory field is not correctly set" msgstr "" +"오퍼레이션이 다음과 같은 이유로 완료될 수 없습니다.\n" +"- 삭제 : 다른 레코드가 참고하고 있는 해당 레코드를 삭제하려고 합니다.\n" +"- 생성/수정 : 필수 필드가 올바르게 셋팅되지 않습니다." #. module: base #: view:ir.rule:0 msgid "" "2. Group-specific rules are combined together with a logical AND operator" -msgstr "" +msgstr "2. 그룹 정의 규칙은 논리 And 연산자와 함께 결합되어 있습니다." #. module: base #: code:addons/base/res/res_user.py:206 #, python-format msgid "Operation Canceled" -msgstr "" +msgstr "오퍼레이션 취소" #. module: base #: help:base.language.export,lang:0 @@ -992,22 +1001,22 @@ msgstr "새 언어를 내보낼려면, 언어를 선택하지 마십시오." #. module: base #: view:res.request:0 msgid "Request Date" -msgstr "" +msgstr "요청한 날짜" #. module: base #: model:ir.ui.menu,name:base.menu_hr_dasboard msgid "Dashboard" -msgstr "" +msgstr "대쉬보드" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root msgid "Purchases" -msgstr "" +msgstr "구매" #. module: base #: model:res.country,name:base.md msgid "Moldavia" -msgstr "" +msgstr "몰디브" #. module: base #: view:ir.module.module:0 @@ -1036,13 +1045,13 @@ msgstr "" #: code:addons/base/module/wizard/base_update_translations.py:38 #, python-format msgid "No language with code \"%s\" exists" -msgstr "" +msgstr "코드 \"%s\"를 가진 언어가 존재하지 않습니다." #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:163 #, python-format msgid "Error during communication with the publisher warranty server." -msgstr "" +msgstr "퍼블리셔 보증 서버와 통신할 수 없습니다." #. module: base #: help:ir.actions.server,email:0 @@ -1051,16 +1060,18 @@ msgid "" "you select the invoice, then `object.invoice_address_id.email` is the field " "which gives the correct address" msgstr "" +"이메일 주소를 가져오기 위해 사용할 필드를 제공하세요.\r\n" +"예) 송장을 선택할 때, 올바를 이메일 주소를 가져오기 위한 필드는 `object.invoice_address_id.email`입니다." #. module: base #: view:res.lang:0 msgid "%Y - Year with century." -msgstr "" +msgstr "%Y - 년도" #. module: base #: report:ir.module.reference.graph:0 msgid "-" -msgstr "" +msgstr "-" #. module: base #: view:publisher_warranty.contract.wizard:0 @@ -1069,6 +1080,8 @@ msgid "" "system. After the contract has been registered, you will be able to send " "issues directly to OpenERP." msgstr "" +"이 마법사기능은 당신의 OpenERP시스템에서 퍼블리셔 보증 연락처를 등록할 수 있도록 도와줍니다.\r\n" +"연락처가 등록된 후, OpenERP에 직접 문제점,이슈를 보낼 수 있습니다." #. module: base #: code:addons/orm.py:1744 @@ -1079,7 +1092,7 @@ msgstr "이 검색 방식은 이 오브젝트에 적용되지 않음!" #. module: base #: view:wizard.ir.model.menu.create:0 msgid "Create _Menu" -msgstr "" +msgstr "메뉴 생성" #. module: base #: field:res.payterm,name:0 @@ -1103,12 +1116,12 @@ msgstr "" msgid "" "If you check this box, your customized translations will be overwritten and " "replaced by the official ones." -msgstr "" +msgstr "이 박스를 체크하면, 당신의 커스터마이즈된 번역를 공식적인 번역으로 대체될 것입니다." #. module: base #: field:ir.actions.report.xml,report_rml:0 msgid "Main report file path" -msgstr "" +msgstr "주요 보고서 파일 경로" #. module: base #: model:ir.actions.act_window,name:base.ir_action_report_xml @@ -1137,6 +1150,8 @@ msgid "" "'%s' contains too many dots. XML ids should not contain dots ! These are " "used to refer to other modules data, as in module.reference_id" msgstr "" +"'%s'는 너무 많은 점들 포함하고 있다. XML id들에 점이 포함되서는 안된다.\r\n" +"그것들은 다른 모듈의 자료를 참조하기 위해 사용된다." #. module: base #: field:partner.sms.send,user:0 @@ -1150,7 +1165,7 @@ msgstr "로그인" msgid "" "Access all the fields related to the current object using expressions, i.e. " "object.partner_id.name " -msgstr "" +msgstr "표현식을 사용하는 현재 객체에 관련된 필드를 액세스하라. 가령 object.partner_id.name " #. module: base #: model:ir.model,name:base.model_res_country_state @@ -1160,7 +1175,7 @@ msgstr "국가 상태" #. module: base #: selection:ir.property,type:0 msgid "Float" -msgstr "" +msgstr "부동소수" #. module: base #: model:ir.model,name:base.model_res_request_link @@ -1177,19 +1192,19 @@ msgstr "위저드 정보" #: model:ir.actions.act_window,name:base.action_wizard_lang_export #: model:ir.ui.menu,name:base.menu_wizard_lang_export msgid "Export Translation" -msgstr "" +msgstr "번역을 내보내기" #. module: base #: help:res.log,secondary:0 msgid "" "Do not display this log if it belongs to the same object the user is working " "on" -msgstr "" +msgstr "만약 로그가 현 사용자가 동작하고 있는 객체에 속해 있다면, 로그를 표시하지 마십시오." #. module: base #: model:res.country,name:base.tp msgid "East Timor" -msgstr "" +msgstr "동티모르" #. module: base #: model:res.company,follow_up_msg:base.main_company @@ -1208,6 +1223,17 @@ msgid "" "%(user_signature)s\n" "%(company_name)s" msgstr "" +"날짜 : %(date)s\n" +"%(파트너 이름)s 님께\n" +"\n" +"당신이 아직 지불하지 않는 송장을 첨부파일에서 확인하시길 부탁드립니다.\n" +"해당 금액은 다음과 같습니다.\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"감사합니다.\n" +"\n" +"%(사용자 서명)s\n" +"%(회사명)s" #. module: base #: field:res.currency,accuracy:0 @@ -1217,7 +1243,7 @@ msgstr "계산 정확성" #. module: base #: selection:base.language.install,lang:0 msgid "Sinhalese / සිංහල" -msgstr "" +msgstr "신할라어" #. module: base #: model:ir.model,name:base.model_wizard_ir_model_menu_create_line @@ -1237,7 +1263,7 @@ msgstr "일: %(day)s" #. module: base #: model:res.country,name:base.mv msgid "Maldives" -msgstr "" +msgstr "몰디브" #. module: base #: help:ir.values,res_id:0 @@ -1266,7 +1292,7 @@ msgstr "액션이 실행되기 전에 테스트될 조건. e.g. object.list_pric #: code:addons/base/res/res_company.py:66 #, python-format msgid " (copy)" -msgstr "" +msgstr " (사본)" #. module: base #: view:res.lang:0 @@ -1283,13 +1309,13 @@ msgstr "파트너" #. module: base #: field:res.partner.category,parent_left:0 msgid "Left parent" -msgstr "" +msgstr "왼쪽 여백" #. module: base #: model:ir.actions.act_window,name:base.res_widget_act_window #: model:ir.ui.menu,name:base.menu_res_widget_act_window msgid "Homepage Widgets" -msgstr "" +msgstr "홈페이지 위젯" #. module: base #: help:ir.actions.server,message:0 @@ -1307,7 +1333,7 @@ msgstr "첨부된 모델" #. module: base #: view:ir.rule:0 msgid "Domain Setup" -msgstr "" +msgstr "도메인 설정" #. module: base #: field:ir.actions.server,trigger_name:0 @@ -1350,14 +1376,14 @@ msgstr "루트 사용자를 제거할 수는 없음!" #. module: base #: model:res.country,name:base.mw msgid "Malawi" -msgstr "" +msgstr "말라위" #. module: base #: code:addons/base/res/res_user.py:51 #: code:addons/base/res/res_user.py:413 #, python-format msgid "%s (copy)" -msgstr "" +msgstr "%s (사본)" #. module: base #: field:res.partner.address,type:0 @@ -1367,7 +1393,7 @@ msgstr "주소 타입" #. module: base #: view:ir.ui.menu:0 msgid "Full Path" -msgstr "" +msgstr "전체 경로" #. module: base #: view:res.request:0 @@ -1387,12 +1413,12 @@ msgstr "" #. module: base #: view:ir.ui.view:0 msgid "Advanced" -msgstr "" +msgstr "고급 기능" #. module: base #: model:res.country,name:base.fi msgid "Finland" -msgstr "" +msgstr "핀란드" #. module: base #: selection:ir.actions.act_window,view_type:0 @@ -1412,7 +1438,7 @@ msgstr "이 사용자가 시스템에 접속하지 못하도록 하려면 체크 #. module: base #: view:ir.actions.server:0 msgid "Create / Write / Copy" -msgstr "" +msgstr "생성 / 쓰기 / 복사" #. module: base #: view:base.language.export:0 @@ -1429,23 +1455,23 @@ msgstr "보기 모드" msgid "" "When using CSV format, please also check that the first line of your file is " "one of the following:" -msgstr "" +msgstr "CSV형식를 사용할 때, 파일의 첫째 줄이 다음과 같은지 확인하십시오." #. module: base #: code:addons/fields.py:114 #, python-format msgid "Not implemented search_memory method !" -msgstr "" +msgstr "search_memory 방식이 구현되지 않음" #. module: base #: view:res.log:0 msgid "Logs" -msgstr "" +msgstr "로그" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish / Español" -msgstr "" +msgstr "스페인어" #. module: base #: selection:base.language.install,lang:0 @@ -1458,6 +1484,8 @@ msgid "" "This wizard will scan all module repositories on the server side to detect " "newly added modules as well as any change to existing modules." msgstr "" +"이 마법사기능은 서버측의 모든 모듈 레포지터리를 검색할 것입니다.\r\n" +"왜냐하면 기존 모듈의 변경뿐 아니라 새로운 모듈이 있는지를 알아내기 위해서입니다." #. module: base #: field:res.company,logo:0 @@ -1467,7 +1495,7 @@ msgstr "로고" #. module: base #: view:res.partner.address:0 msgid "Search Contact" -msgstr "" +msgstr "연락처 찾기" #. module: base #: view:ir.module.module:0 @@ -1483,7 +1511,7 @@ msgstr "새 창" #. module: base #: model:res.country,name:base.bs msgid "Bahamas" -msgstr "" +msgstr "바하마제도" #. module: base #: code:addons/base/res/partner/partner.py:250 @@ -1500,7 +1528,7 @@ msgstr "첨부" #. module: base #: model:res.country,name:base.ie msgid "Ireland" -msgstr "" +msgstr "아일랜드" #. module: base #: field:base.module.update,update:0 @@ -1516,7 +1544,7 @@ msgstr "set_memory method를 수행 못함 !" #. module: base #: view:workflow.activity:0 msgid "Workflow Activity" -msgstr "" +msgstr "워크플로어 활동" #. module: base #: view:ir.rule:0 @@ -1524,6 +1552,8 @@ msgid "" "Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND " "GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" msgstr "" +"예: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND GROUP_A_RULE_2) " +"OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" #. module: base #: model:ir.actions.act_window,help:base.action_ui_view @@ -1531,6 +1561,8 @@ msgid "" "Views allows you to personalize each view of OpenERP. You can add new " "fields, move fields, rename them or delete the ones that you do not need." msgstr "" +"뷰 기능은 OpenERP의 각 뷰를 개인화하도록 한다. \r\n" +"새로운 필드를 추가, 이동, 변경, 삭제할 수 있다." #. module: base #: field:ir.actions.act_window,groups_id:0 @@ -1556,7 +1588,7 @@ msgstr "그룹" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (CL) / Español (CL)" -msgstr "" +msgstr "스페인어" #. module: base #: view:res.config.users:0 @@ -1565,45 +1597,47 @@ msgid "" "access to selected functionalities within the system. Click on 'Done' if you " "do not wish to add more users at this stage, you can always do this later." msgstr "" +"추가 사용자를 생성하고, 시스템내 적당한 기능을 할 수 있는 권한을 부여하기 위해 적당한 그룹에 할당하세요. 이 단계에서 더이상의 사용자 " +"생성을 원하지 않으면 \"완료\"를 클릭하세요." #. module: base #: model:res.country,name:base.bz msgid "Belize" -msgstr "" +msgstr "벨리제" #. module: base #: model:res.country,name:base.ge msgid "Georgia" -msgstr "" +msgstr "그루지아" #. module: base #: model:res.country,name:base.pl msgid "Poland" -msgstr "" +msgstr "폴란드" #. module: base #: help:ir.actions.act_window,view_mode:0 msgid "" "Comma-separated list of allowed view modes, such as 'form', 'tree', " "'calendar', etc. (Default: tree,form)" -msgstr "" +msgstr "'폼', '트리', '달력'과 같은 보기 모드를 구분하기 위한 쉼표,구분 리스트" #. module: base #: code:addons/orm.py:3147 #, python-format msgid "A document was modified since you last viewed it (%s:%d)" -msgstr "" +msgstr "문서는 당신이 마지막으로 본 시점이후에 수정되었다. (%s:%d)" #. module: base #: view:workflow:0 msgid "Workflow Editor" -msgstr "" +msgstr "워크플로어 편집기" #. module: base #: selection:ir.module.module,state:0 #: selection:ir.module.module.dependency,state:0 msgid "To be removed" -msgstr "제거 예정" +msgstr "지울 것" #. module: base #: model:ir.model,name:base.model_ir_sequence @@ -1625,56 +1659,56 @@ msgstr "" #: selection:ir.translation,type:0 #: field:multi_company.default,field_id:0 msgid "Field" -msgstr "" +msgstr "필드" #. module: base #: view:ir.rule:0 msgid "Groups (no group = global)" -msgstr "" +msgstr "그룹 ( 그룹없음 = 전체 )" #. module: base #: model:res.country,name:base.fo msgid "Faroe Islands" -msgstr "" +msgstr "페어로우섬" #. module: base #: selection:res.config.users,view:0 #: selection:res.config.view,view:0 #: selection:res.users,view:0 msgid "Simplified" -msgstr "" +msgstr "간체" #. module: base #: model:res.country,name:base.st msgid "Saint Tome (Sao Tome) and Principe" -msgstr "" +msgstr "세인트 톰 (사오 톰) 과 프린시프섬" #. module: base #: selection:res.partner.address,type:0 msgid "Invoice" -msgstr "인보이스" +msgstr "송장" #. module: base #: selection:base.language.install,lang:0 msgid "Portugese (BR) / Português (BR)" -msgstr "" +msgstr "포루트칼" #. module: base #: model:res.country,name:base.bb msgid "Barbados" -msgstr "" +msgstr "바베이도스" #. module: base #: model:res.country,name:base.mg msgid "Madagascar" -msgstr "" +msgstr "마다가스카르" #. module: base #: code:addons/base/ir/ir_model.py:96 #, python-format msgid "" "The Object name must start with x_ and not contain any special character !" -msgstr "오브젝트 이름은 x_로 시작해야 하며, 특수 문자가 포함되면 안됩니다." +msgstr "오브젝트 이름은 x_로 시작해야 하며, 특수 문자를 포함해서는 안 됩니다 !" #. module: base #: field:ir.actions.configuration.wizard,note:0 @@ -1711,17 +1745,17 @@ msgstr "액션 타깃" #. module: base #: model:res.country,name:base.ai msgid "Anguilla" -msgstr "" +msgstr "앙골라" #. module: base #: field:ir.ui.view_sc,name:0 msgid "Shortcut Name" -msgstr "지름길 이름" +msgstr "단축키 명" #. module: base #: help:ir.actions.act_window,limit:0 msgid "Default limit for the list view" -msgstr "리스트뷰를 위한 디폴트 리미트" +msgstr "리스트 뷰를 위한 기본 제한" #. module: base #: help:ir.actions.server,write_id:0 @@ -1733,12 +1767,12 @@ msgstr "쓰기 오퍼레이션을 위해 레코드 ID가 참조하는 필드 이 #. module: base #: model:res.country,name:base.zw msgid "Zimbabwe" -msgstr "" +msgstr "짐바브웨" #. module: base #: view:base.module.update:0 msgid "Please be patient, as this operation may take a few seconds..." -msgstr "" +msgstr "오퍼레이션이 끝날 때까지 기다리세요." #. module: base #: help:ir.values,action_id:0 @@ -1753,7 +1787,7 @@ msgstr "이메일 주소" #. module: base #: selection:base.language.install,lang:0 msgid "French (BE) / Français (BE)" -msgstr "" +msgstr "프랑스어" #. module: base #: view:ir.actions.server:0 @@ -1764,12 +1798,12 @@ msgstr "서버 액션" #. module: base #: model:res.country,name:base.tt msgid "Trinidad and Tobago" -msgstr "" +msgstr "트리니다드 토바고" #. module: base #: model:res.country,name:base.lv msgid "Latvia" -msgstr "" +msgstr "라트비아" #. module: base #: view:ir.values:0 @@ -1784,7 +1818,7 @@ msgstr "필드 매핑" #. module: base #: view:base.language.export:0 msgid "Export Translations" -msgstr "" +msgstr "번역 내보내기" #. module: base #: model:ir.ui.menu,name:base.menu_custom @@ -1794,7 +1828,7 @@ msgstr "고객화" #. module: base #: model:res.country,name:base.py msgid "Paraguay" -msgstr "" +msgstr "파라과이" #. module: base #: model:ir.model,name:base.model_ir_actions_act_window_close @@ -1809,7 +1843,7 @@ msgstr "목적지" #. module: base #: model:res.country,name:base.lt msgid "Lithuania" -msgstr "" +msgstr "리투아니아" #. module: base #: model:ir.actions.act_window,name:base.action_view_partner_clear_ids @@ -1823,7 +1857,7 @@ msgstr "" msgid "" "Name of object whose function will be called when this scheduler will run. " "e.g. 'res.partener'" -msgstr "" +msgstr "이 스케줄러가 수행될 때, 함수가 호출되는 객체의 이름 예) 'res.partener'" #. module: base #: code:addons/orm.py:1040 @@ -1834,28 +1868,28 @@ msgstr "perm_read 메쏘드는 이 오브젝트에 적용되지 않음!" #. module: base #: view:res.lang:0 msgid "%y - Year without century [00,99]." -msgstr "" +msgstr "2자리수 연도" #. module: base #: model:res.country,name:base.si msgid "Slovenia" -msgstr "" +msgstr "슬로베니아" #. module: base #: model:res.country,name:base.pk msgid "Pakistan" -msgstr "" +msgstr "파키스탄" #. module: base #: code:addons/orm.py:1350 #, python-format msgid "Invalid Object Architecture!" -msgstr "" +msgstr "잘못된 객체 아키텍쳐" #. module: base #: model:ir.ui.menu,name:base.menu_email_gateway_form msgid "Messages" -msgstr "" +msgstr "메세지" #. module: base #: code:addons/base/ir/ir_model.py:303 @@ -1867,7 +1901,7 @@ msgstr "" #: code:addons/base/module/wizard/base_update_translations.py:38 #, python-format msgid "Error!" -msgstr "" +msgstr "오류!" #. module: base #: view:res.lang:0 @@ -1877,12 +1911,12 @@ msgstr "%p - AM 또는 PM의 등가물" #. module: base #: view:ir.actions.server:0 msgid "Iteration Actions" -msgstr "" +msgstr "반복형 동작들" #. module: base #: help:multi_company.default,company_id:0 msgid "Company where the user is connected" -msgstr "" +msgstr "사용자가 연결된 회사" #. module: base #: field:publisher_warranty.contract,date_stop:0 @@ -1892,7 +1926,7 @@ msgstr "종료 날짜" #. module: base #: model:res.country,name:base.nz msgid "New Zealand" -msgstr "" +msgstr "뉴질랜드" #. module: base #: code:addons/orm.py:3366 @@ -1900,7 +1934,7 @@ msgstr "" msgid "" "One of the records you are trying to modify has already been deleted " "(Document type: %s)." -msgstr "" +msgstr "당신이 수정하려고 하는 레코드중의 하나는 이미 삭제되었습니다.( 자료 유형 : %s)." #. module: base #: model:ir.actions.act_window,help:base.action_country @@ -1909,6 +1943,8 @@ msgid "" "partner records. You can create or delete countries to make sure the ones " "you are working on will be maintained." msgstr "" +"당신의 파트너 기록에 할당될 수 있는 모든 나라들의 목록을 나타내고 관리하세요.\r\n" +"당신이 일하고 있는 나라가 유지될 것인지 확실시하기 위하여 나라를 생성하고 삭제할 수 있습니다." #. module: base #: model:res.partner.category,name:base.res_partner_category_7 @@ -1918,7 +1954,7 @@ msgstr "" #. module: base #: model:res.country,name:base.nf msgid "Norfolk Island" -msgstr "" +msgstr "노퍽 제도" #. module: base #: selection:base.language.install,lang:0 @@ -1928,7 +1964,7 @@ msgstr "" #. module: base #: help:ir.model.fields,model:0 msgid "The technical name of the model this field belongs to" -msgstr "" +msgstr "이 필드가 속한 모델의 기술적 명칭" #. module: base #: field:ir.actions.server,action_id:0 @@ -1939,7 +1975,7 @@ msgstr "클라이언트 액션ㅇ" #. module: base #: model:res.country,name:base.bd msgid "Bangladesh" -msgstr "" +msgstr "방글라데시" #. module: base #: constraint:res.company:0 @@ -1965,7 +2001,7 @@ msgstr "모듈 '%s' 을 업그레이드할 수 없습니다. 설치 안됨." #. module: base #: model:res.country,name:base.cu msgid "Cuba" -msgstr "" +msgstr "쿠바" #. module: base #: model:ir.model,name:base.model_res_partner_event @@ -1975,28 +2011,28 @@ msgstr "" #. module: base #: model:res.widget,title:base.facebook_widget msgid "Facebook" -msgstr "" +msgstr "페이스북" #. module: base #: model:res.country,name:base.am msgid "Armenia" -msgstr "" +msgstr "아르메니아" #. module: base #: model:ir.actions.act_window,name:base.ir_property_form #: model:ir.ui.menu,name:base.menu_ir_property_form_all msgid "Configuration Parameters" -msgstr "" +msgstr "구성 파라메터" #. module: base #: constraint:ir.cron:0 msgid "Invalid arguments" -msgstr "" +msgstr "인자가 잘못되었습니다" #. module: base #: model:res.country,name:base.se msgid "Sweden" -msgstr "" +msgstr "스웨덴" #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -2031,29 +2067,29 @@ msgstr "은행 계정 타입" #: field:res.config.users,config_logo:0 #: field:res.config.view,config_logo:0 msgid "Image" -msgstr "" +msgstr "이미지" #. module: base #: view:ir.actions.server:0 msgid "Iteration Action Configuration" -msgstr "" +msgstr "반복형 동작 구성" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Canceled" -msgstr "" +msgstr "취소" #. module: base #: model:res.country,name:base.at msgid "Austria" -msgstr "" +msgstr "오스트리아" #. module: base #: selection:base.language.install,state:0 #: selection:base.module.import,state:0 #: selection:base.module.update,state:0 msgid "done" -msgstr "" +msgstr "완료" #. module: base #: selection:ir.actions.act_window.view,view_mode:0 @@ -2066,7 +2102,7 @@ msgstr "카렌터" #. module: base #: field:res.partner.address,partner_id:0 msgid "Partner Name" -msgstr "" +msgstr "협력사 이름" #. module: base #: field:workflow.activity,signal_send:0 @@ -2086,6 +2122,8 @@ msgid "" "separated list of valid field names (optionally followed by asc/desc for the " "direction)" msgstr "" +"잘못된 \"주문\"입니다. 올바른 \"주문\" 명세는 올바른 필드이름들의 쉼표,구분 리스트입니다. ( 선택적으로 오름차순/내림차순 방향을 " +"따릅니다.)" #. module: base #: model:ir.model,name:base.model_ir_module_module_dependency @@ -2102,7 +2140,7 @@ msgstr "초안" #: selection:res.config.view,view:0 #: selection:res.users,view:0 msgid "Extended" -msgstr "" +msgstr "확장됨" #. module: base #: model:ir.actions.act_window,help:base.action_partner_title_contact @@ -2110,7 +2148,7 @@ msgid "" "Manage the contact titles you want to have available in your system and the " "way you want to print them in letters and other documents. Some example: " "Mr., Mrs. " -msgstr "" +msgstr "시스템에서 사용가능한 연락처의 필드들과 편지나 문서에 나타내는 호칭(예:Mr, Mrs) 방식을 정하십시오. " #. module: base #: field:res.company,rml_footer1:0 @@ -2143,7 +2181,7 @@ msgstr "메인 기업" #. module: base #: field:ir.ui.menu,web_icon_hover:0 msgid "Web Icon File (hover)" -msgstr "" +msgstr "웹 아이콘 파일" #. module: base #: view:ir.actions.server:0 @@ -2168,24 +2206,24 @@ msgstr "연락처 제목" msgid "" "Please double-check that the file encoding is set to UTF-8 (sometimes called " "Unicode) when the translator exports it." -msgstr "" +msgstr "번역기가 파일을 내보내기할 때, 파일 인코딩이 UTF-8으로 셋팅되는지 더블 클릭하여 확인하세요." #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (DO) / Español (DO)" -msgstr "" +msgstr "스페인어(DO)/에스파뇰(DO)" #. module: base #: model:ir.model,name:base.model_workflow_activity msgid "workflow.activity" -msgstr "" +msgstr "워크플로어.동작" #. module: base #: help:ir.ui.view_sc,res_id:0 msgid "" "Reference of the target resource, whose model/table depends on the 'Resource " "Name' field." -msgstr "" +msgstr "타겟 자원의 참조 모델/테이블은 \"자원 이름\"필드에 좌우된다." #. module: base #: field:ir.model.fields,select_level:0 @@ -2195,17 +2233,17 @@ msgstr "검색 가능" #. module: base #: model:res.country,name:base.uy msgid "Uruguay" -msgstr "" +msgstr "우루과이" #. module: base #: selection:base.language.install,lang:0 msgid "Finnish / Suomi" -msgstr "" +msgstr "핀란드어 / 수오미" #. module: base #: field:ir.rule,perm_write:0 msgid "Apply For Write" -msgstr "" +msgstr "쓰기 적용" #. module: base #: field:ir.sequence,prefix:0 @@ -2215,7 +2253,7 @@ msgstr "접두사" #. module: base #: selection:base.language.install,lang:0 msgid "German / Deutsch" -msgstr "" +msgstr "독일어" #. module: base #: help:ir.actions.server,trigger_name:0 @@ -2230,7 +2268,7 @@ msgstr "필드 매핑" #. module: base #: selection:base.language.install,lang:0 msgid "Portugese / Português" -msgstr "" +msgstr "포르투갈어" #. module: base #: model:res.partner.title,name:base.res_partner_title_sir @@ -2241,7 +2279,7 @@ msgstr "" #: code:addons/orm.py:1622 #, python-format msgid "There is no view of type '%s' defined for the structure!" -msgstr "" +msgstr "구조를 위한 정의된 유형 '%s'의 뷰는 없다." #. module: base #: field:ir.default,ref_id:0 @@ -2252,12 +2290,12 @@ msgstr "" #: model:ir.actions.server,name:base.action_start_configurator #: model:ir.ui.menu,name:base.menu_view_base_module_configuration msgid "Start Configuration" -msgstr "" +msgstr "시작 구성" #. module: base #: model:res.country,name:base.mt msgid "Malta" -msgstr "" +msgstr "몰타" #. module: base #: field:ir.actions.server,fields_lines:0 @@ -2295,17 +2333,17 @@ msgstr "인스턴스" #. module: base #: model:res.country,name:base.aq msgid "Antarctica" -msgstr "" +msgstr "남극" #. module: base #: field:ir.actions.report.xml,auto:0 msgid "Custom python parser" -msgstr "" +msgstr "커스텀 파이썬 파서" #. module: base #: view:base.language.import:0 msgid "_Import" -msgstr "" +msgstr "가져오기(_I)" #. module: base #: view:res.partner.canal:0 @@ -2337,7 +2375,7 @@ msgstr "대량 메일 발송" #. module: base #: model:res.country,name:base.yt msgid "Mayotte" -msgstr "" +msgstr "마요트" #. module: base #: code:addons/base/ir/ir_actions.py:597 @@ -2362,7 +2400,7 @@ msgstr "오른쪽에서 왼쪽으로" #: model:ir.model,name:base.model_ir_filters #: model:ir.ui.menu,name:base.menu_ir_filters msgid "Filters" -msgstr "" +msgstr "필터들" #. module: base #: code:addons/orm.py:758 @@ -2387,7 +2425,7 @@ msgstr "제목" #. module: base #: help:ir.property,res_id:0 msgid "If not set, acts as a default value for new resources" -msgstr "" +msgstr "셋팅되어 있지 않다면 새로운 자원에 대하여 기본값으로서 동작하라." #. module: base #: code:addons/orm.py:3448 @@ -2408,6 +2446,8 @@ msgid "" "loading a new language it becomes available as default interface language " "for users and partners." msgstr "" +"이 마법사기능은 OpenERP시스템에 새로운 언어를 추가할 수 있도록 해준다. 새로운 언어를 로딩한 후, 사용자와 협력사를 위한 기본 " +"사용언어로서 사용가능하게 된다." #. module: base #: view:ir.model:0 @@ -2424,17 +2464,17 @@ msgstr "VAT 번호. 파트너가 VAT 부과 대상이면 이 박스를 체크하 #. module: base #: model:ir.model,name:base.model_maintenance_contract msgid "maintenance.contract" -msgstr "" +msgstr "유지관리.연락처" #. module: base #: model:res.country,name:base.ru msgid "Russian Federation" -msgstr "" +msgstr "러시아 연방" #. module: base #: selection:base.language.install,lang:0 msgid "Urdu / اردو" -msgstr "" +msgstr "우르드" #. module: base #: field:res.company,name:0 @@ -2450,7 +2490,7 @@ msgstr "국가들" #. module: base #: selection:ir.translation,type:0 msgid "RML (deprecated - use Report)" -msgstr "" +msgstr "RML ( 더이상 사용안됨 - 보고서 사용 )" #. module: base #: view:ir.rule:0 @@ -2460,12 +2500,12 @@ msgstr "기록 규칙" #. module: base #: view:ir.property:0 msgid "Field Information" -msgstr "" +msgstr "필드 정보" #. module: base #: view:ir.actions.todo:0 msgid "Search Actions" -msgstr "" +msgstr "검색 동작들" #. module: base #: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check @@ -2476,7 +2516,7 @@ msgstr "" #. module: base #: field:res.partner,vat:0 msgid "VAT" -msgstr "" +msgstr "부가세" #. module: base #: view:res.lang:0 @@ -2501,12 +2541,12 @@ msgstr "" #. module: base #: model:res.country,name:base.tj msgid "Tajikistan" -msgstr "" +msgstr "타지키스탄" #. module: base #: selection:ir.module.module,license:0 msgid "GPL-2 or later version" -msgstr "" +msgstr "GPL-2 또는 이후 버젼" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_sir @@ -2529,18 +2569,18 @@ msgstr "" msgid "" "Operation prohibited by access rules, or performed on an already deleted " "document (Operation: read, Document type: %s)." -msgstr "" +msgstr "접근 규칙에 의해 금지된 동작이거나 이미 삭제된 문서에 수행된 동작임 ( 동작: 읽기, 문서 유형: %s)." #. module: base #: model:res.country,name:base.nr msgid "Nauru" -msgstr "" +msgstr "나우루어" #. module: base #: code:addons/base/module/module.py:200 #, python-format msgid "The certificate ID of the module must be unique !" -msgstr "" +msgstr "모듈의 인증 ID는 유일해야 한다." #. module: base #: model:ir.model,name:base.model_ir_property @@ -2559,7 +2599,7 @@ msgstr "양식" #. module: base #: model:res.country,name:base.me msgid "Montenegro" -msgstr "" +msgstr "몬테네그로" #. module: base #: view:ir.cron:0 @@ -2579,6 +2619,8 @@ msgid "" "import a language pack from here. Other OpenERP languages than the official " "ones can be found on launchpad." msgstr "" +"당신이 공식적인 언어이외 다른 언어가 사용가능하도록 하는 것이 필요하다면 여기로 부터 언어팩을 가져오기 할 수 있다. 다른 언어는 " +"Lauchpad에서 찾을 수 있습니다." #. module: base #: view:ir.module.module:0 @@ -2590,17 +2632,17 @@ msgstr "갱신 예정" #. module: base #: model:res.country,name:base.ly msgid "Libya" -msgstr "" +msgstr "리비아" #. module: base #: model:res.country,name:base.cf msgid "Central African Republic" -msgstr "" +msgstr "중앙 아프리카 공화국" #. module: base #: model:res.country,name:base.li msgid "Liechtenstein" -msgstr "" +msgstr "리히텐슈타인" #. module: base #: model:ir.model,name:base.model_partner_sms_send @@ -2617,18 +2659,18 @@ msgstr "" #: code:addons/orm.py:1622 #, python-format msgid "Invalid Architecture!" -msgstr "" +msgstr "잘못된 아키텍쳐" #. module: base #: model:res.country,name:base.pt msgid "Portugal" -msgstr "" +msgstr "포르투칼" #. module: base #: sql_constraint:ir.model.data:0 msgid "" "You cannot have multiple records with the same id for the same module !" -msgstr "" +msgstr "당신은 동일한 모듈에 대하여 동일한 id를 가진 여러 레코드를 가질 수 없다." #. module: base #: field:ir.module.module,certificate:0 @@ -2644,12 +2686,12 @@ msgstr "" #: field:res.config.users,date:0 #: field:res.users,date:0 msgid "Last Connection" -msgstr "" +msgstr "마지막 연결" #. module: base #: field:ir.actions.act_window,help:0 msgid "Action description" -msgstr "" +msgstr "액션 설명" #. module: base #: help:res.partner,customer:0 @@ -2673,7 +2715,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ec msgid "Ecuador" -msgstr "" +msgstr "에콰도르" #. module: base #: code:addons/base/module/wizard/base_export_language.py:52 @@ -2692,12 +2734,12 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_partner_form #: view:res.partner:0 msgid "Customers" -msgstr "" +msgstr "고객" #. module: base #: model:res.country,name:base.au msgid "Australia" -msgstr "" +msgstr "호주" #. module: base #: help:res.partner,lang:0 @@ -2720,12 +2762,12 @@ msgstr "베이스 필드" #. module: base #: view:publisher_warranty.contract:0 msgid "Validate" -msgstr "" +msgstr "검증" #. module: base #: field:ir.actions.todo,restart:0 msgid "Restart" -msgstr "" +msgstr "재시작" #. module: base #: field:ir.actions.report.xml,report_sxw_content:0 @@ -2748,7 +2790,7 @@ msgstr "트리거 액션" #: code:addons/base/res/res_user.py:136 #, python-format msgid "\"email_from\" needs to be set to send welcome mails to users" -msgstr "" +msgstr "\"email_from\"은 사용자들에게 환영메일을 보내도록 셋팅될 필요가 있다." #. module: base #: selection:ir.translation,type:0 @@ -2771,7 +2813,7 @@ msgstr "요구됨" #. module: base #: view:res.users:0 msgid "Default Filters" -msgstr "" +msgstr "기본 필터들" #. module: base #: field:res.request.history,name:0 @@ -2781,7 +2823,7 @@ msgstr "요약" #. module: base #: field:multi_company.default,expression:0 msgid "Expression" -msgstr "" +msgstr "표현식" #. module: base #: help:ir.actions.server,subject:0 @@ -2801,12 +2843,12 @@ msgstr "헤더 / 푸터" msgid "" "Optional help text for the users with a description of the target view, such " "as its usage and purpose." -msgstr "" +msgstr "선택적 도움말은 타겟 뷰의 사용과 목적에 대하여 설명을 제공한다." #. module: base #: model:res.country,name:base.va msgid "Holy See (Vatican City State)" -msgstr "" +msgstr "교황청 (바티칸 시국)" #. module: base #: field:base.module.import,module_file:0 @@ -2831,7 +2873,7 @@ msgstr "오브젝트 트리거" #. module: base #: view:res.users:0 msgid "Current Activity" -msgstr "" +msgstr "현재 동작들" #. module: base #: view:workflow.activity:0 @@ -2842,12 +2884,12 @@ msgstr "인커밍 트랜지션" #. module: base #: model:res.country,name:base.sr msgid "Suriname" -msgstr "" +msgstr "수리남" #. module: base #: model:ir.ui.menu,name:base.marketing_menu msgid "Marketing" -msgstr "" +msgstr "마케팅" #. module: base #: view:res.partner.bank:0 @@ -2858,7 +2900,7 @@ msgstr "은행 계정" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (HN) / Español (HN)" -msgstr "" +msgstr "스페인어" #. module: base #: view:ir.sequence.type:0 @@ -2868,7 +2910,7 @@ msgstr "시퀀스 타입" #. module: base #: view:ir.ui.view.custom:0 msgid "Customized Architecture" -msgstr "" +msgstr "커스터마이징되는 구조" #. module: base #: field:ir.module.module,license:0 @@ -2878,17 +2920,17 @@ msgstr "라이선스" #. module: base #: field:ir.attachment,url:0 msgid "Url" -msgstr "" +msgstr "Url" #. module: base #: selection:ir.actions.todo,restart:0 msgid "Always" -msgstr "" +msgstr "항상" #. module: base #: selection:ir.translation,type:0 msgid "SQL Constraint" -msgstr "" +msgstr "SQL 제약" #. module: base #: field:ir.actions.server,srcmodel_id:0 @@ -2901,12 +2943,12 @@ msgstr "모델" msgid "" "The selected language has been successfully installed. You must change the " "preferences of the user and open a new menu to view the changes." -msgstr "" +msgstr "선택한 언어가 성공적으로 설치되었습니다. 사용자 옵션을 바꾸어야 하며 변경내용을 보기위하여 새로운 메뉴를 열어야 합니다." #. module: base #: sql_constraint:ir.config_parameter:0 msgid "Key must be unique." -msgstr "" +msgstr "키는 유일해야 한다." #. module: base #: view:ir.actions.act_window:0 @@ -2916,7 +2958,7 @@ msgstr "창 열기" #. module: base #: model:res.country,name:base.gq msgid "Equatorial Guinea" -msgstr "" +msgstr "적도 기니" #. module: base #: view:base.module.import:0 @@ -2954,22 +2996,22 @@ msgid "" "Your database is now fully configured.\n" "\n" "Click 'Continue' and enjoy your OpenERP experience..." -msgstr "" +msgstr "데이터베이스가 모두 구성되었습니다." #. module: base #: selection:base.language.install,lang:0 msgid "Hebrew / עִבְרִי" -msgstr "" +msgstr "히브리어" #. module: base #: model:res.country,name:base.bo msgid "Bolivia" -msgstr "" +msgstr "볼리비아" #. module: base #: model:res.country,name:base.gh msgid "Ghana" -msgstr "" +msgstr "가나" #. module: base #: field:res.lang,direction:0 @@ -3002,17 +3044,17 @@ msgstr "설치된 혹은 설치 예정 모듈을 제거하려 합니다." #. module: base #: view:base.module.upgrade:0 msgid "The selected modules have been updated / installed !" -msgstr "" +msgstr "선택된 모듈은 업데이트/설치되었습니다." #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PR) / Español (PR)" -msgstr "" +msgstr "스페인어" #. module: base #: model:res.country,name:base.gt msgid "Guatemala" -msgstr "" +msgstr "과테말라" #. module: base #: model:ir.actions.act_window,name:base.action_workflow_form @@ -3030,7 +3072,7 @@ msgstr "" #. module: base #: model:ir.actions.act_window,name:base.action_config_user_form msgid "Create Users" -msgstr "" +msgstr "사용자 생성" #. module: base #: model:ir.model,name:base.model_res_partner_title @@ -3045,7 +3087,7 @@ msgstr "" #. module: base #: model:res.partner.category,name:base.res_partner_category_retailers0 msgid "Retailers" -msgstr "" +msgstr "유통업자들" #. module: base #: help:ir.cron,priority:0 @@ -3065,7 +3107,7 @@ msgstr "건너뛰기" #. module: base #: model:res.country,name:base.ls msgid "Lesotho" -msgstr "" +msgstr "레소토" #. module: base #: code:addons/base/ir/ir_model.py:114 @@ -3076,27 +3118,27 @@ msgstr "귀하는 모델 '%s'을 제거할 수 없음!" #. module: base #: model:res.country,name:base.ke msgid "Kenya" -msgstr "" +msgstr "케냐" #. module: base #: view:res.partner.event:0 msgid "Event" -msgstr "" +msgstr "이벤트" #. module: base #: model:ir.ui.menu,name:base.menu_custom_reports msgid "Custom Reports" -msgstr "" +msgstr "사용자 정의 보고서" #. module: base #: selection:base.language.install,lang:0 msgid "Abkhazian / аҧсуа" -msgstr "" +msgstr "아브카지안" #. module: base #: view:base.module.configuration:0 msgid "System Configuration Done" -msgstr "" +msgstr "시스템 구성 완료" #. module: base #: code:addons/orm.py:929 @@ -3107,22 +3149,22 @@ msgstr "필드 %s를 검증하는 동안 오류 발생: %s" #. module: base #: view:ir.property:0 msgid "Generic" -msgstr "" +msgstr "일반" #. module: base #: model:res.country,name:base.sm msgid "San Marino" -msgstr "" +msgstr "산마리노" #. module: base #: model:res.country,name:base.bm msgid "Bermuda" -msgstr "" +msgstr "버뮤다 제도" #. module: base #: model:res.country,name:base.pe msgid "Peru" -msgstr "" +msgstr "페루" #. module: base #: selection:ir.model.fields,on_delete:0 @@ -3132,33 +3174,33 @@ msgstr "NULL로 설정" #. module: base #: model:res.country,name:base.bj msgid "Benin" -msgstr "" +msgstr "베닌" #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:281 #, python-format msgid "That contract is already registered in the system." -msgstr "" +msgstr "연락처는 이미 시스템에 등록되었습니다." #. module: base #: help:ir.sequence,suffix:0 msgid "Suffix value of the record for the sequence" -msgstr "" +msgstr "순열에 대한 레코드의 접미사값" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PY) / Español (PY)" -msgstr "" +msgstr "스페인어" #. module: base #: field:ir.config_parameter,key:0 msgid "Key" -msgstr "" +msgstr "키" #. module: base #: field:res.company,rml_header:0 msgid "RML Header" -msgstr "" +msgstr "RML 헤더" #. module: base #: field:partner.sms.send,app_id:0 @@ -3171,18 +3213,18 @@ msgstr "" msgid "" "You can not create this document (%s) ! Be sure your user belongs to one of " "these groups: %s." -msgstr "" +msgstr "당신은 이 문서(%s)을 생성할 수 없습니다 ! 당신의 계정이 이 그룹들중 하나에 속해져 있는지 확인하십시오. : %s" #. module: base #: model:res.country,name:base.mu msgid "Mauritius" -msgstr "" +msgstr "마우리티우스" #. module: base #: view:ir.model.access:0 #: view:ir.rule:0 msgid "Full Access" -msgstr "" +msgstr "전체 접근" #. module: base #: view:ir.actions.act_window:0 @@ -3196,12 +3238,12 @@ msgstr "보안" #. module: base #: model:res.widget,title:base.openerp_favorites_twitter_widget msgid "OpenERP Favorites" -msgstr "" +msgstr "OpenERP 즐겨찾기" #. module: base #: model:res.country,name:base.za msgid "South Africa" -msgstr "" +msgstr "남아프리카공화국" #. module: base #: view:ir.module.module:0 @@ -3213,23 +3255,23 @@ msgstr "설치됨" #. module: base #: selection:base.language.install,lang:0 msgid "Ukrainian / українська" -msgstr "" +msgstr "우크라이나" #. module: base #: model:ir.actions.act_window,name:base.action_translation #: model:ir.ui.menu,name:base.menu_action_translation msgid "Translation Terms" -msgstr "" +msgstr "용어 번역" #. module: base #: model:res.country,name:base.sn msgid "Senegal" -msgstr "" +msgstr "세네갈" #. module: base #: model:res.country,name:base.hu msgid "Hungary" -msgstr "" +msgstr "헝가리" #. module: base #: model:ir.model,name:base.model_res_groups @@ -3239,12 +3281,12 @@ msgstr "" #. module: base #: model:res.country,name:base.br msgid "Brazil" -msgstr "" +msgstr "브라질" #. module: base #: view:res.lang:0 msgid "%M - Minute [00,59]." -msgstr "" +msgstr "%M - 분 [00,59]." #. module: base #: selection:ir.module.module,license:0 @@ -3259,7 +3301,7 @@ msgstr "다음 번호" #. module: base #: help:workflow.transition,condition:0 msgid "Expression to be satisfied if we want the transition done." -msgstr "" +msgstr "우리가 변경을 원한다면 표현식은 만족되어진다." #. module: base #: selection:base.language.install,lang:0 @@ -3275,7 +3317,7 @@ msgstr "비율" #. module: base #: model:res.country,name:base.sy msgid "Syria" -msgstr "" +msgstr "시리아" #. module: base #: view:res.lang:0 @@ -3295,7 +3337,7 @@ msgstr "" #. module: base #: view:base.module.upgrade:0 msgid "System update completed" -msgstr "" +msgstr "시스템 업데이트 완료" #. module: base #: selection:res.request,state:0 @@ -3331,13 +3373,13 @@ msgstr "부모 메뉴" #. module: base #: field:ir.rule,perm_unlink:0 msgid "Apply For Delete" -msgstr "" +msgstr "삭제 적용" #. module: base #: code:addons/base/ir/ir_model.py:319 #, python-format msgid "Cannot rename column to %s, because that column already exists!" -msgstr "" +msgstr "컬럼이 이미 존재하기 때문에, 컬럼명을 %s로 변경할 수 없다." #. module: base #: view:ir.attachment:0 @@ -3359,6 +3401,9 @@ msgid "" "to see. Whether they can have a read, write, create and delete access right " "can be managed from here." msgstr "" +"그룹은 시스템내에서 특정 애플리케이션과 태스크로의 접근과 권한을 사용자에게 주기위하여 사용자들에게 할당한 기능적 영역의 집합니다. 당신은 " +"사용자가 볼수 있도록 할 메뉴의 모습을 커스터마이징하기 위하여 사용자정의 그룹을 만들거나 기존의 것을 변경할 수 있다. 그룹이 가지는 " +"접근권한을 여기에서 관리될 수 있다." #. module: base #: view:res.partner:0 @@ -3382,16 +3427,18 @@ msgid "" "Would your payment have been carried out after this mail was sent, please " "consider the present one as void." msgstr "" +"다음과 같은 지불은 지금 필요합니다. 당신이 지불을 처리했다면 상세지불내역을 전달해 주십시오. 결제가 좀더 연기된다면 연락바랍니다. 이 " +"메일이 전송된 후 당시의 결제가 이루어지기를 바랍니다." #. module: base #: model:res.country,name:base.mx msgid "Mexico" -msgstr "" +msgstr "멕시코" #. module: base #: model:ir.ui.menu,name:base.menu_base_config_plugins msgid "Plugins" -msgstr "" +msgstr "플러그인" #. module: base #: field:res.company,child_ids:0 @@ -3406,7 +3453,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ni msgid "Nicaragua" -msgstr "" +msgstr "니카라과" #. module: base #: code:addons/orm.py:1046 @@ -3423,7 +3470,7 @@ msgstr "일반 설명" #: model:ir.actions.act_window,name:base.action_config_simple_view_form #: view:res.config.view:0 msgid "Configure Your Interface" -msgstr "" +msgstr "인터페이스 구성" #. module: base #: field:ir.values,meta:0 @@ -3433,12 +3480,12 @@ msgstr "메타데이타" #. module: base #: sql_constraint:ir.ui.view_sc:0 msgid "Shortcut for this menu already exists!" -msgstr "" +msgstr "이 메뉴에 대한 단축키가 이미 존재합니다." #. module: base #: model:res.country,name:base.ve msgid "Venezuela" -msgstr "" +msgstr "베네수엘라" #. module: base #: view:res.lang:0 @@ -3448,7 +3495,7 @@ msgstr "" #. module: base #: model:res.country,name:base.zm msgid "Zambia" -msgstr "" +msgstr "잠비아" #. module: base #: help:res.partner,user_id:0 @@ -3460,22 +3507,22 @@ msgstr "이 파트너와의 소통을 담당하는 내부 사용자" #. module: base #: field:res.partner,parent_id:0 msgid "Parent Partner" -msgstr "" +msgstr "상위 파트너" #. module: base #: view:ir.module.module:0 msgid "Cancel Upgrade" -msgstr "" +msgstr "업그레이드 취소" #. module: base #: model:res.country,name:base.ci msgid "Ivory Coast (Cote D'Ivoire)" -msgstr "" +msgstr "코트디부아르" #. module: base #: model:res.country,name:base.kz msgid "Kazakhstan" -msgstr "" +msgstr "카자흐스탄" #. module: base #: view:res.lang:0 @@ -3532,7 +3579,7 @@ msgstr "" #. module: base #: model:res.country,name:base.ms msgid "Montserrat" -msgstr "" +msgstr "몬세라트산" #. module: base #: code:addons/base/ir/ir_model.py:205 @@ -5457,7 +5504,7 @@ msgstr "번역" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po index 2a31023df0f..71f2b0c5116 100644 --- a/openerp/addons/base/i18n/lt.po +++ b/openerp/addons/base/i18n/lt.po @@ -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: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5464,7 +5464,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lt_LT.po b/openerp/addons/base/i18n/lt_LT.po index 7aee4518a19..5c98c806928 100644 --- a/openerp/addons/base/i18n/lt_LT.po +++ b/openerp/addons/base/i18n/lt_LT.po @@ -4618,7 +4618,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po index cd1ef4c77fe..38532bef174 100644 --- a/openerp/addons/base/i18n/lv.po +++ b/openerp/addons/base/i18n/lv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-19 08:19+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:23+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: Latvian <lv@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:03+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5514,7 +5514,7 @@ msgstr "Tulkojumi" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Ciparu vietas" #. module: base @@ -9356,3 +9356,6 @@ msgstr "Šrilanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Krievu / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Ciparu vietas" diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po index bb8f47fcf7c..e5e1f7bf252 100644 --- a/openerp/addons/base/i18n/mk.po +++ b/openerp/addons/base/i18n/mk.po @@ -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: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po index 12c8460790f..797df905133 100644 --- a/openerp/addons/base/i18n/mn.po +++ b/openerp/addons/base/i18n/mn.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0.0-rc1\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-16 08:03+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:29+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5533,7 +5533,7 @@ msgstr "Орчуулгууд" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Тоон дугаарын урт" #. module: base @@ -9369,3 +9369,6 @@ msgstr "Шриланк" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Орос хэл / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Тоон дугаарын урт" diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po index c62673f2b19..ad136cf464e 100644 --- a/openerp/addons/base/i18n/nb.po +++ b/openerp/addons/base/i18n/nb.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-03-11 05:06+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:06+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: Norwegian Bokmal <nb@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5530,7 +5530,7 @@ msgstr "Oversettelser" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Bunnfyll" #. module: base @@ -9371,3 +9371,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "" + +#~ msgid "Number padding" +#~ msgstr "Bunnfyll" diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po index 2bb60f29b38..57df6c192f4 100644 --- a/openerp/addons/base/i18n/nl.po +++ b/openerp/addons/base/i18n/nl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-19 08:35+0000\n" -"Last-Translator: Stefan Rijnhart (Therp) <Unknown>\n" +"PO-Revision-Date: 2011-09-30 20:44+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:40+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:02+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5702,7 +5702,7 @@ msgstr "Vertalingen" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Nummer verspringing" #. module: base @@ -9653,3 +9653,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russisch / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Nummer verspringing" diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po index 09b17071edd..72a89e3dda6 100644 --- a/openerp/addons/base/i18n/nl_BE.po +++ b/openerp/addons/base/i18n/nl_BE.po @@ -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: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5447,7 +5447,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/nl_NL.po b/openerp/addons/base/i18n/nl_NL.po index 704c25a9d46..eeef0f9010e 100644 --- a/openerp/addons/base/i18n/nl_NL.po +++ b/openerp/addons/base/i18n/nl_NL.po @@ -4796,7 +4796,7 @@ msgstr "Vertalingen" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Nummer verspringing" #. module: base diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po index 9b8f0c8769c..332be04207c 100644 --- a/openerp/addons/base/i18n/pl.po +++ b/openerp/addons/base/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-24 19:15+0000\n" +"PO-Revision-Date: 2011-09-30 21:13+0000\n" "Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:42+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5612,7 +5612,7 @@ msgstr "Tłumaczenia" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Liczba cyfr" #. module: base @@ -9507,3 +9507,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "" + +#~ msgid "Number padding" +#~ msgstr "Liczba cyfr" diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po index 88b097ffe71..cee7a6eda8a 100644 --- a/openerp/addons/base/i18n/pt.po +++ b/openerp/addons/base/i18n/pt.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-03-16 22:11+0000\n" -"Last-Translator: Paulo Borges <Unknown>\n" +"PO-Revision-Date: 2011-09-30 20:30+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5591,7 +5591,7 @@ msgstr "Traduções" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Dígitos do número" #. module: base @@ -9471,3 +9471,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russo / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Dígitos do número" diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po index 254c642a060..79dc0c324a0 100644 --- a/openerp/addons/base/i18n/pt_BR.po +++ b/openerp/addons/base/i18n/pt_BR.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: pt_BR\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-05-10 19:52+0000\n" +"PO-Revision-Date: 2011-09-30 21:22+0000\n" "Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n" "Language-Team: <pt@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5687,7 +5687,7 @@ msgstr "Traduções" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Preencher número" #. module: base @@ -9637,3 +9637,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Russo / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Preencher número" diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po index 7f6e34b2edc..7df48b5a664 100644 --- a/openerp/addons/base/i18n/ro.po +++ b/openerp/addons/base/i18n/ro.po @@ -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: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5555,7 +5555,7 @@ msgstr "Traduceri" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po index 48133981214..391adaac3b1 100644 --- a/openerp/addons/base/i18n/ru.po +++ b/openerp/addons/base/i18n/ru.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-05-26 04:57+0000\n" -"Last-Translator: Pomazan Bogdan <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:03+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:04+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5689,7 +5689,7 @@ msgstr "Переводы" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Выравнивание чисел" #. module: base @@ -9647,3 +9647,6 @@ msgstr "Шри-Ланка" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Русский / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Выравнивание чисел" diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po index df5f44b9ef4..10016a1cfff 100644 --- a/openerp/addons/base/i18n/sk.po +++ b/openerp/addons/base/i18n/sk.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-19 08:23+0000\n" +"PO-Revision-Date: 2011-09-30 21:16+0000\n" "Last-Translator: Peter Kohaut <peter.kohaut@gmail.com>\n" "Language-Team: Slovak <sk@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5598,7 +5598,7 @@ msgstr "Preklady" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Zarovanie čísla" #. module: base @@ -9506,3 +9506,6 @@ msgstr "Srí Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Rusčina / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Zarovanie čísla" diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po index fc0c7518e38..dbb290a3b5a 100644 --- a/openerp/addons/base/i18n/sl.po +++ b/openerp/addons/base/i18n/sl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-01 06:59+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:29+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -33,12 +33,12 @@ msgstr "Sveta Helena" #. module: base #: view:ir.actions.report.xml:0 msgid "Other Configuration" -msgstr "" +msgstr "Ostale nastavitve" #. module: base #: selection:ir.property,type:0 msgid "DateTime" -msgstr "" +msgstr "DatumČas" #. module: base #: code:addons/fields.py:534 @@ -47,12 +47,14 @@ msgid "" "The second argument of the many2many field %s must be a SQL table !You used " "%s, which is not a valid SQL table name." msgstr "" +"Drugi argument od polja many2many %s mora biti SQL tabela! Uporabili ste %s, " +"ki ni veljavno ime SQL tabele." #. module: base #: view:ir.values:0 #: field:ir.values,meta_unpickle:0 msgid "Metadata" -msgstr "Metapodatki" +msgstr "Meta podatki" #. module: base #: field:ir.ui.view,arch:0 @@ -73,7 +75,7 @@ msgstr "Oznaka (n.pr.: sl_SI)" #: field:workflow.transition,wkf_id:0 #: field:workflow.workitem,wkf_id:0 msgid "Workflow" -msgstr "Potek dela" +msgstr "Delovni proces" #. module: base #: view:partner.sms.send:0 @@ -98,12 +100,12 @@ msgstr "Špansko" #. module: base #: field:ir.actions.server,wkf_model_id:0 msgid "Workflow On" -msgstr "Vklopi potek dela" +msgstr "Vklopi delovni proces" #. module: base #: field:ir.actions.act_window,display_menu_tip:0 msgid "Display Menu Tips" -msgstr "Prikaži tip menija" +msgstr "Prikaži namige menija" #. module: base #: view:ir.module.module:0 @@ -117,6 +119,8 @@ msgid "" "You can not write in this document (%s) ! Be sure your user belongs to one " "of these groups: %s." msgstr "" +"Ne morete pisati v ta dokument (%s)! Bodite prepričani, da vaš uporabnik " +"sodi v eno od teh skupin: %s." #. module: base #: help:ir.model.fields,domain:0 @@ -125,11 +129,14 @@ msgid "" "specified as a Python expression defining a list of triplets. For example: " "[('color','=','red')]" msgstr "" +"Opcijska domena, ki omeji možne vrednosti za sorodna polja, navedena kot " +"Python izrazi, ki opredeljujejo seznam trojčkov. Kot npr: " +"[('color','=','red')]" #. module: base #: field:res.partner,ref:0 msgid "Reference" -msgstr "Referenca" +msgstr "Sklic" #. module: base #: field:ir.actions.act_window,target:0 @@ -140,7 +147,7 @@ msgstr "Ciljno okno" #: code:addons/base/res/res_user.py:507 #, python-format msgid "Warning!" -msgstr "" +msgstr "Opozorilo!" #. module: base #: code:addons/base/ir/ir_model.py:304 @@ -149,12 +156,14 @@ msgid "" "Properties of base fields cannot be altered in this manner! Please modify " "them through Python code, preferably through a custom addon!" msgstr "" +"Lastnosti baze polj ni mogoče spremeniti na ta način! Prosimo, da jih " +"spremenite preko kode Python, po možnosti z dodatkom po meri!" #. module: base #: code:addons/osv.py:133 #, python-format msgid "Constraint Error" -msgstr "" +msgstr "Napaka omejitve" #. module: base #: model:ir.model,name:base.model_ir_ui_view_custom @@ -164,14 +173,14 @@ msgstr "ir.ui.view.custom" #. module: base #: model:res.country,name:base.sz msgid "Swaziland" -msgstr "Svazi" +msgstr "Švica" #. module: base #: code:addons/orm.py:1993 #: code:addons/orm.py:3653 #, python-format msgid "created." -msgstr "" +msgstr "ustvarjeno." #. module: base #: model:res.partner.category,name:base.res_partner_category_woodsuppliers0 @@ -185,17 +194,19 @@ msgid "" "Some installed modules depend on the module you plan to Uninstall :\n" " %s" msgstr "" +"Nekateri nameščeni moduli so odvisni od modula, ki ga želite odstraniti:\n" +" %s" #. module: base #: field:ir.sequence,number_increment:0 msgid "Increment Number" -msgstr "Prirastek zaporedja" +msgstr "Dobiček" #. module: base #: model:ir.actions.act_window,name:base.action_res_company_tree #: model:ir.ui.menu,name:base.menu_action_res_company_tree msgid "Company's Structure" -msgstr "Struktura družbe" +msgstr "Struktura podjetja" #. module: base #: selection:base.language.install,lang:0 @@ -205,13 +216,15 @@ msgstr "" #. module: base #: view:res.partner:0 msgid "Search Partner" -msgstr "" +msgstr "Iskanje partnerja" #. module: base #: code:addons/base/res/res_user.py:132 #, python-format msgid "\"smtp_server\" needs to be set to send mails to users" msgstr "" +"\"smtp strežnik\" mora biti nastavljen, da se lahko pošilja e-pošto " +"uporabnikom" #. module: base #: code:addons/base/module/wizard/base_export_language.py:60 @@ -232,7 +245,7 @@ msgstr "Število modulov" #. module: base #: help:multi_company.default,company_dest_id:0 msgid "Company to store the current record" -msgstr "" +msgstr "Podjetje za shranjevanje trenutnega zapisa" #. module: base #: field:res.partner.bank.type.field,size:0 @@ -242,7 +255,7 @@ msgstr "Maksimalna velikost" #. module: base #: field:res.partner.address,name:0 msgid "Contact Name" -msgstr "Naziv stika" +msgstr "Ime stika" #. module: base #: code:addons/base/module/wizard/base_export_language.py:56 @@ -252,12 +265,12 @@ msgid "" "text editor. The file encoding is UTF-8." msgstr "" "Shrani ta dokument v datoteko %s in ga uredi z ustreznim urejevalnikom. " -"Kodni tabela je UTF-8." +"Kodni nabor je UTF-8." #. module: base #: sql_constraint:res.lang:0 msgid "The name of the language must be unique !" -msgstr "" +msgstr "Ime jezika mora biti edinstven!" #. module: base #: selection:res.request,state:0 @@ -273,12 +286,12 @@ msgstr "Ime čarovnika" #: code:addons/orm.py:2160 #, python-format msgid "Invalid group_by" -msgstr "" +msgstr "Neveljavna skupina_z" #. module: base #: field:res.partner,credit_limit:0 msgid "Credit Limit" -msgstr "" +msgstr "Meja posojila" #. module: base #: field:ir.model.data,date_update:0 @@ -288,12 +301,12 @@ msgstr "Datum posodobitve" #. module: base #: view:ir.attachment:0 msgid "Owner" -msgstr "" +msgstr "Lastnik" #. module: base #: field:ir.actions.act_window,src_model:0 msgid "Source Object" -msgstr "Izvorni objekt" +msgstr "Izvorni predmet" #. module: base #: view:ir.actions.todo:0 @@ -309,7 +322,7 @@ msgstr "ir.ui.view_sc" #: field:res.widget.user,widget_id:0 #: field:res.widget.wizard,widgets_list:0 msgid "Widget" -msgstr "" +msgstr "Gradnik" #. module: base #: view:ir.model.access:0 @@ -323,23 +336,23 @@ msgstr "Skupina" #: field:ir.translation,name:0 #: field:res.partner.bank.type.field,name:0 msgid "Field Name" -msgstr "Naziv polja" +msgstr "Ime polja" #. module: base #: wizard_view:server.action.create,init:0 #: wizard_field:server.action.create,init,type:0 msgid "Select Action Type" -msgstr "" +msgstr "Izberi tip dejanja" #. module: base #: model:res.country,name:base.tv msgid "Tuvalu" -msgstr "tuvalujščina" +msgstr "Tuvalu" #. module: base #: selection:ir.model,state:0 msgid "Custom Object" -msgstr "Objekt po meri" +msgstr "Predmet po meri" #. module: base #: field:res.lang,date_format:0 @@ -375,7 +388,7 @@ msgstr "Francoska Gvajana" #. module: base #: selection:base.language.install,lang:0 msgid "Greek / Ελληνικά" -msgstr "" +msgstr "Grški / Ελληνικά" #. module: base #: selection:base.language.install,lang:0 @@ -388,22 +401,24 @@ msgid "" "If you check this, then the second time the user prints with same attachment " "name, it returns the previous report." msgstr "" +"Če označite to, potem bo drugič ko uporabnik natisne z enakim imenom " +"prilogo, se vrne v prejšnje poročilo." #. module: base #: code:addons/orm.py:904 #, python-format msgid "The read method is not implemented on this object !" -msgstr "Metoda 'read' ni implementirana za ta objekt." +msgstr "Metoa 'read' ni implementirana za ta predmet." #. module: base #: help:res.lang,iso_code:0 msgid "This ISO code is the name of po files to use for translations" -msgstr "" +msgstr "ISO koda je ime po datotek za uporabo prevodov." #. module: base #: view:base.module.upgrade:0 msgid "Your system will be updated." -msgstr "" +msgstr "Vaš sistem bo posodobljen." #. module: base #: field:ir.actions.todo,note:0 @@ -414,7 +429,7 @@ msgstr "Besedilo" #. module: base #: field:res.country,name:0 msgid "Country Name" -msgstr "Naziv države" +msgstr "Ime države" #. module: base #: model:res.country,name:base.co @@ -430,7 +445,7 @@ msgstr "Razporedi nadgradnjo" #: code:addons/orm.py:838 #, python-format msgid "Key/value '%s' not found in selection field '%s'" -msgstr "" +msgstr "Ključ/vrednost '%s' ni mogoče najti v izbranem polju '%s'" #. module: base #: help:res.country,code:0 @@ -449,18 +464,18 @@ msgstr "Palau" #. module: base #: view:res.partner:0 msgid "Sales & Purchases" -msgstr "Prodaja in nabava" +msgstr "Prodaja & Nabava" #. module: base #: view:ir.translation:0 msgid "Untranslated" -msgstr "" +msgstr "Ni prevedeno" #. module: base #: help:ir.actions.act_window,context:0 msgid "" "Context dictionary as Python expression, empty by default (Default: {})" -msgstr "" +msgstr "Kontekst slovar kot izraz Python, prazno privzeto (privzeto: {})" #. module: base #: model:ir.actions.act_window,name:base.ir_action_wizard @@ -472,7 +487,7 @@ msgstr "Čarovniki" #. module: base #: model:res.partner.category,name:base.res_partner_category_miscellaneoussuppliers0 msgid "Miscellaneous Suppliers" -msgstr "" +msgstr "Razni dobavitelji" #. module: base #: code:addons/base/ir/ir_model.py:255 @@ -483,12 +498,12 @@ msgstr "Nazivi polj po meri se morajo začeti z 'x_'." #. module: base #: help:ir.actions.server,action_id:0 msgid "Select the Action Window, Report, Wizard to be executed." -msgstr "" +msgstr "Izberite okno dejanja, poročila, čarovnika, ki naj bo izvršeno." #. module: base #: view:res.config.users:0 msgid "New User" -msgstr "" +msgstr "Nov uporabnik" #. module: base #: view:base.language.export:0 @@ -504,7 +519,7 @@ msgstr "Opis modela" #: help:ir.actions.act_window,src_model:0 msgid "" "Optional model name of the objects on which this action should be visible" -msgstr "" +msgstr "Ime opcijskega modula predmeta na katerem bo to dejanje vidno" #. module: base #: field:workflow.transition,trigger_expr_id:0 @@ -519,7 +534,7 @@ msgstr "Jordanija" #. module: base #: view:ir.module.module:0 msgid "Certified" -msgstr "" +msgstr "Preverjeno" #. module: base #: model:res.country,name:base.er @@ -530,12 +545,12 @@ msgstr "Eritreja" #: view:res.config:0 #: view:res.config.installer:0 msgid "description" -msgstr "" +msgstr "opis" #. module: base #: model:ir.ui.menu,name:base.menu_base_action_rule msgid "Automated Actions" -msgstr "" +msgstr "Avtomatska dejanja" #. module: base #: model:ir.model,name:base.model_ir_actions_actions @@ -545,7 +560,7 @@ msgstr "ir.actions.actions" #. module: base #: view:partner.wizard.ean.check:0 msgid "Want to check Ean ? " -msgstr "" +msgstr "Ali želite preveriti Ean? " #. module: base #: field:ir.values,key2:0 @@ -559,16 +574,19 @@ msgid "" "Launchpad.net, our open source project management facility. We use their " "online interface to synchronize all translations efforts." msgstr "" +"OpenERP prevodi (jedro, moduli, klienti) se upravljajp skoz Launchpad.net, " +"ki je naš odprto kodni objekt za upravljanje. Uporabljamo njihov spletni " +"vmesnik za sinhronizacijo vseh prevodov." #. module: base #: field:res.partner,title:0 msgid "Partner Form" -msgstr "" +msgstr "Obrazec partnerja" #. module: base #: selection:base.language.install,lang:0 msgid "Swedish / svenska" -msgstr "Švedsko" +msgstr "Švedsko / svenska" #. module: base #: model:res.country,name:base.rs @@ -596,27 +614,27 @@ msgstr "Zaporedja" #. module: base #: model:ir.model,name:base.model_base_language_import msgid "Language Import" -msgstr "" +msgstr "Uvoz jezika" #. module: base #: model:ir.model,name:base.model_res_config_users msgid "res.config.users" -msgstr "" +msgstr "Copy text \t res.config.users" #. module: base #: selection:base.language.install,lang:0 msgid "Albanian / Shqip" -msgstr "" +msgstr "Albansko /Shqip" #. module: base #: model:ir.ui.menu,name:base.menu_crm_config_opportunity msgid "Opportunities" -msgstr "" +msgstr "Priložnosti" #. module: base #: model:ir.model,name:base.model_base_language_export msgid "base.language.export" -msgstr "" +msgstr "base.language.export" #. module: base #: model:res.country,name:base.pg @@ -627,6 +645,7 @@ msgstr "Papua Nova Gvineja" #: help:ir.actions.report.xml,report_type:0 msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." msgstr "" +"Tip poročila, npr. pdf, html, raw, sxw, odt, html2html, mako2html, ..." #. module: base #: model:res.partner.category,name:base.res_partner_category_4 @@ -641,12 +660,12 @@ msgstr "," #. module: base #: view:res.partner:0 msgid "My Partners" -msgstr "" +msgstr "Moji partnerji" #. module: base #: view:ir.actions.report.xml:0 msgid "XML Report" -msgstr "" +msgstr "XML poročilo" #. module: base #: model:res.country,name:base.es @@ -662,13 +681,13 @@ msgstr "Uvoz / Izvoz" #: help:ir.actions.act_window,domain:0 msgid "" "Optional domain filtering of the destination data, as a Python expression" -msgstr "" +msgstr "Dodatna domena filtriranje za destinacije podatkov, kot izraz Python" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_upgrade #: model:ir.model,name:base.model_base_module_upgrade msgid "Module Upgrade" -msgstr "" +msgstr "Posodobitev modula" #. module: base #: view:res.config.users:0 @@ -676,11 +695,13 @@ msgid "" "Groups are used to define access rights on objects and the visibility of " "screens and menus" msgstr "" +"Skupine se uporablja za opredelitev pravice dostopa do predmetov, ter za " +"vidnost zaslonov in menijev" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (UY) / Español (UY)" -msgstr "" +msgstr "Špansko (UY) / Español (UY)" #. module: base #: field:res.partner,mobile:0 @@ -697,7 +718,7 @@ msgstr "Oman" #: model:ir.actions.act_window,name:base.action_payterm_form #: model:ir.model,name:base.model_res_payterm msgid "Payment term" -msgstr "Plačilni pogoj" +msgstr "" #. module: base #: model:res.country,name:base.nu @@ -712,7 +733,7 @@ msgstr "Delovni dnevi" #. module: base #: selection:ir.module.module,license:0 msgid "Other OSI Approved Licence" -msgstr "" +msgstr "Ostale OSI dvoljene licence" #. module: base #: help:res.config.users,context_lang:0 @@ -721,12 +742,13 @@ msgid "" "Sets the language for the user's user interface, when UI translations are " "available" msgstr "" +"Nastavi jezik za uporabniški vmesnik uporabnika, ko so prevodi UI na voljo" #. module: base #: code:addons/orm.py:1043 #, python-format msgid "The unlink method is not implemented on this object !" -msgstr "Metoda 'unlink' ni implementirana za ta objekt." +msgstr "Metoda 'unlink' ni implementirana za ta predmet." #. module: base #: model:ir.actions.act_window,name:base.act_menu_create @@ -743,12 +765,12 @@ msgstr "Indija" #: model:ir.actions.act_window,name:base.res_request_link-act #: model:ir.ui.menu,name:base.menu_res_request_link_act msgid "Request Reference Types" -msgstr "" +msgstr "Zahtevaj tipe sklicov" #. module: base #: view:ir.values:0 msgid "client_action_multi, client_action_relate" -msgstr "" +msgstr "client_action_multi, client_action_relate" #. module: base #: model:res.country,name:base.ad @@ -759,12 +781,12 @@ msgstr "Andora, Principat" #: field:ir.module.category,child_ids:0 #: field:res.partner.category,child_ids:0 msgid "Child Categories" -msgstr "Kategorije otrok" +msgstr "Kategorije podrejenih" #. module: base #: model:ir.model,name:base.model_ir_config_parameter msgid "ir.config_parameter" -msgstr "" +msgstr "ir.config_parameter" #. module: base #: selection:base.language.export,format:0 @@ -799,6 +821,8 @@ msgid "" "Language with code \"%s\" is not defined in your system !\n" "Define it through the Administration menu." msgstr "" +"Jezik s kodo \"%s\" ni določen na vašem sistemu!\n" +"Določite ga v Administracijskem meniju." #. module: base #: model:res.country,name:base.gu @@ -808,13 +832,13 @@ msgstr "Guam (USA)" #. module: base #: model:ir.ui.menu,name:base.menu_hr_project msgid "Human Resources Dashboard" -msgstr "" +msgstr "Nadzorna plošča človeških virov" #. module: base #: code:addons/base/res/res_user.py:507 #, python-format msgid "Setting empty passwords is not allowed for security reasons!" -msgstr "" +msgstr "Nastavitev brez gesla ni dovoljeno zaradi varnostnih razlogov!" #. module: base #: selection:ir.actions.server,state:0 @@ -825,7 +849,7 @@ msgstr "Začasno" #. module: base #: constraint:ir.ui.view:0 msgid "Invalid XML for View Architecture!" -msgstr "Neveljaven XML za arhitekturo pogleda." +msgstr "Neveljaven XML za arhitekturo pogleda!" #. module: base #: model:res.country,name:base.ky @@ -848,28 +872,28 @@ msgstr "Prehodi" #: code:addons/orm.py:4020 #, python-format msgid "Record #%d of %s not found, cannot copy!" -msgstr "" +msgstr "Zapisa #%d od %s ni mogoče najti. Ne morem kopirati!" #. module: base #: field:ir.module.module,contributors:0 msgid "Contributors" -msgstr "" +msgstr "Sodelavci" #. module: base #: selection:ir.property,type:0 msgid "Char" -msgstr "" +msgstr "Znak" #. module: base #: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form #: model:ir.ui.menu,name:base.menu_publisher_warranty_contract msgid "Contracts" -msgstr "" +msgstr "Pogodbe" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (AR) / Español (AR)" -msgstr "Špansko" +msgstr "Špansko (AR) / Español (AR)" #. module: base #: model:res.country,name:base.ug @@ -879,17 +903,17 @@ msgstr "Uganda" #. module: base #: field:ir.model.access,perm_unlink:0 msgid "Delete Access" -msgstr "" +msgstr "Izbriši dostop" #. module: base #: model:res.country,name:base.ne msgid "Niger" -msgstr "Niger" +msgstr "Nigerija" #. module: base #: selection:base.language.install,lang:0 msgid "Chinese (HK)" -msgstr "" +msgstr "Kitajsko (HK)" #. module: base #: model:res.country,name:base.ba @@ -903,11 +927,14 @@ msgid "" "Lauchpad's web interface (Rosetta). If you need to perform mass translation, " "Launchpad also allows uploading full .po files at once" msgstr "" +"Če želite izboljšati ali razširiti uradne prevode, morate uporabljati " +"neposredno Lauchpad spletni vmesnik (Rosetta). Če morate opraviti množično " +"prevod, Launchpad tudi omogoča tudi nalaganje polno. PO datotek hkrati" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (GT) / Español (GT)" -msgstr "" +msgstr "Špansko (GT) / Español (GT)" #. module: base #: view:res.lang:0 @@ -916,12 +943,15 @@ msgid "" "decimal number [00,53]. All days in a new year preceding the first Monday " "are considered to be in week 0." msgstr "" +"%W - Številka tedna v letu (ponedeljek kot prvi dan v tednu), kot decimalno " +"število [00,53]. Vse dni v novem letu pred prvim ponedeljekom se šteje, da " +"je v tednu 0." #. module: base #: field:ir.module.module,website:0 #: field:res.partner,website:0 msgid "Website" -msgstr "Spletno mesto" +msgstr "Spletna stran" #. module: base #: model:res.country,name:base.gs @@ -931,7 +961,7 @@ msgstr "" #. module: base #: field:ir.actions.url,url:0 msgid "Action URL" -msgstr "" +msgstr "URL dejanja" #. module: base #: field:base.module.import,module_name:0 @@ -941,13 +971,13 @@ msgstr "Ime modula" #. module: base #: model:res.country,name:base.mh msgid "Marshall Islands" -msgstr "Marshallovi otoki" +msgstr "Maršalovi otoki" #. module: base #: code:addons/base/ir/ir_model.py:328 #, python-format msgid "Changing the model of a field is forbidden!" -msgstr "" +msgstr "Spreminjanje modela polja ni dovoljeno!" #. module: base #: model:res.country,name:base.ht @@ -958,7 +988,7 @@ msgstr "Haiti" #: view:ir.ui.view:0 #: selection:ir.ui.view,type:0 msgid "Search" -msgstr "" +msgstr "Iskanje" #. module: base #: code:addons/osv.py:136 @@ -969,38 +999,43 @@ msgid "" "reference it\n" "- creation/update: a mandatory field is not correctly set" msgstr "" +"Operacije ni mogoče zaključiti zaradi naslednjih zadev:\n" +"- izbris: poizkušate izbrisati zapis med tem, ko drug zapis še vedno kaže " +"nanj\n" +"- ustvariti/posodobiti: obvezno polje ni pravilno nastavljeno" #. module: base #: view:ir.rule:0 msgid "" "2. Group-specific rules are combined together with a logical AND operator" msgstr "" +"Skupinsko-specifična pravila so združena skupaj z logičnim operatorjem AND" #. module: base #: code:addons/base/res/res_user.py:206 #, python-format msgid "Operation Canceled" -msgstr "" +msgstr "Operacija preklicana" #. module: base #: help:base.language.export,lang:0 msgid "To export a new language, do not select a language." -msgstr "Jezika ne izbirajte za izvoz novega jezika." +msgstr "Ne izbirajte jezika za izvoz novega jezika." #. module: base #: view:res.request:0 msgid "Request Date" -msgstr "" +msgstr "Datum zahtevka" #. module: base #: model:ir.ui.menu,name:base.menu_hr_dasboard msgid "Dashboard" -msgstr "" +msgstr "Nadzorna plošča" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root msgid "Purchases" -msgstr "" +msgstr "Nabave" #. module: base #: model:res.country,name:base.md @@ -1034,13 +1069,13 @@ msgstr "ir.exports" #: code:addons/base/module/wizard/base_update_translations.py:38 #, python-format msgid "No language with code \"%s\" exists" -msgstr "" +msgstr "Ne obstaja jezik s kodo \"%s\"" #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:163 #, python-format msgid "Error during communication with the publisher warranty server." -msgstr "" +msgstr "Napaka pri komuniciranju s strežnikom založniške garancije." #. module: base #: help:ir.actions.server,email:0 @@ -1049,11 +1084,14 @@ msgid "" "you select the invoice, then `object.invoice_address_id.email` is the field " "which gives the correct address" msgstr "" +"Zagotavlja polja, ki se bodo uporabljala za pridobivanje e-poštnih naslovov, " +"npr. ko izberete račun, nato pa polje `object.invoice_address_id.email`, ki " +"daje pravi naslov" #. module: base #: view:res.lang:0 msgid "%Y - Year with century." -msgstr "" +msgstr "%Y - leto s stoletji" #. module: base #: report:ir.module.reference.graph:0 @@ -1067,22 +1105,25 @@ msgid "" "system. After the contract has been registered, you will be able to send " "issues directly to OpenERP." msgstr "" +"Ta čarovnik vam pomaga registrirati pogodbo garancije založnika v vašem " +"OpenERP sistemu. Ko je pogodba registrirana, boste lahko poslali vprašanja " +"direktno na OpenERP." #. module: base #: code:addons/orm.py:1744 #, python-format msgid "The search method is not implemented on this object !" -msgstr "Metoda 'search' ni implementirana za ta objekt." +msgstr "Metoda 'search' ni implementira v predmet." #. module: base #: view:wizard.ir.model.menu.create:0 msgid "Create _Menu" -msgstr "" +msgstr "Ustvari_meni" #. module: base #: field:res.payterm,name:0 msgid "Payment Term (short name)" -msgstr "" +msgstr "Plačilni pogoj (kratko ime)" #. module: base #: model:ir.model,name:base.model_res_bank @@ -1102,11 +1143,13 @@ msgid "" "If you check this box, your customized translations will be overwritten and " "replaced by the official ones." msgstr "" +"Če označite to polje, bodo prilagojeni prevodi prepisani in zamenjani z " +"uradnimi." #. module: base #: field:ir.actions.report.xml,report_rml:0 msgid "Main report file path" -msgstr "" +msgstr "Pot datoteke glavnega poročila" #. module: base #: model:ir.actions.act_window,name:base.ir_action_report_xml @@ -1122,6 +1165,8 @@ msgid "" "If set to true, the action will not be displayed on the right toolbar of a " "form view." msgstr "" +"Če je nastavljeno na true, potem to dejanje ne bo prikazano v desni orodni " +"vrstici pogleda obrazca." #. module: base #: field:workflow,on_create:0 @@ -1135,6 +1180,8 @@ msgid "" "'%s' contains too many dots. XML ids should not contain dots ! These are " "used to refer to other modules data, as in module.reference_id" msgstr "" +"'%s' vsebuje preveč pik. XML id-ki ne smejo vsebovati pik! To se uporablja " +"za nanašanje na druge podatke modulov, kot je module.reference_id" #. module: base #: field:partner.sms.send,user:0 @@ -1149,6 +1196,8 @@ msgid "" "Access all the fields related to the current object using expressions, i.e. " "object.partner_id.name " msgstr "" +"Dostop do vseh polj, povezanih s trenutnim predmetom s pomočjo izrazov, npr. " +"object.partner_id.name " #. module: base #: model:ir.model,name:base.model_res_country_state @@ -1158,7 +1207,7 @@ msgstr "Zvezna država" #. module: base #: selection:ir.property,type:0 msgid "Float" -msgstr "" +msgstr "Plavajoče" #. module: base #: model:ir.model,name:base.model_res_request_link @@ -1168,14 +1217,14 @@ msgstr "res.request.link" #. module: base #: field:ir.actions.wizard,name:0 msgid "Wizard Info" -msgstr "" +msgstr "Info čarovnika" #. module: base #: view:base.language.export:0 #: model:ir.actions.act_window,name:base.action_wizard_lang_export #: model:ir.ui.menu,name:base.menu_wizard_lang_export msgid "Export Translation" -msgstr "" +msgstr "Izvoz prevoda" #. module: base #: help:res.log,secondary:0 @@ -1183,6 +1232,7 @@ msgid "" "Do not display this log if it belongs to the same object the user is working " "on" msgstr "" +"Ne prikaži dnevnika, če pripada na istem predmetu na katerem dela uporabnik" #. module: base #: model:res.country,name:base.tp @@ -1206,6 +1256,19 @@ msgid "" "%(user_signature)s\n" "%(company_name)s" msgstr "" +"Datum: %(date)s\n" +"\n" +"Spoštovani %(partner_name)s,\n" +"\n" +"Prosimo, najdete v priponki opomnik vseh vaših neplačanih računov, skupni " +"znesek:\n" +"\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"Hvala,\n" +"--\n" +"%(user_signature)s\n" +"%(company_name)s" #. module: base #: field:res.currency,accuracy:0 @@ -1225,7 +1288,7 @@ msgstr "wizard.ir.model.menu.create.line" #. module: base #: field:ir.attachment,res_id:0 msgid "Attached ID" -msgstr "" +msgstr "ID pripetja" #. module: base #: view:ir.sequence:0 @@ -1240,7 +1303,7 @@ msgstr "Maldivi" #. module: base #: help:ir.values,res_id:0 msgid "Keep 0 if the action must appear on all resources." -msgstr "" +msgstr "Obdržite 0, če se mora dejanje pojaviti v vseh virih." #. module: base #: model:ir.model,name:base.model_ir_rule @@ -1258,13 +1321,15 @@ msgid "" "Condition that is to be tested before action is executed, e.g. " "object.list_price > object.cost_price" msgstr "" +"Pogoj, ki ga je treba preskusiti, preden se dejanje izvede, npr. " +"object.list_price > object.cost_price" #. module: base #: code:addons/base/res/partner/partner.py:155 #: code:addons/base/res/res_company.py:66 #, python-format msgid " (copy)" -msgstr "" +msgstr " (kopija)" #. module: base #: view:res.lang:0 @@ -1281,13 +1346,13 @@ msgstr "Partnerji" #. module: base #: field:res.partner.category,parent_left:0 msgid "Left parent" -msgstr "" +msgstr "Levi izvor" #. module: base #: model:ir.actions.act_window,name:base.res_widget_act_window #: model:ir.ui.menu,name:base.menu_res_widget_act_window msgid "Homepage Widgets" -msgstr "" +msgstr "Gradnik domače strani" #. module: base #: help:ir.actions.server,message:0 @@ -1295,16 +1360,18 @@ msgid "" "Specify the message. You can use the fields from the object. e.g. `Dear [[ " "object.partner_id.name ]]`" msgstr "" +"Navedite sporočilo. Lahko uporabite polja iz predmeta. npr. 'Spoštovani " +"[[object.partner_id.name]]'" #. module: base #: field:ir.attachment,res_model:0 msgid "Attached Model" -msgstr "" +msgstr "Pripeti model" #. module: base #: view:ir.rule:0 msgid "Domain Setup" -msgstr "" +msgstr "Namestitev domene" #. module: base #: field:ir.actions.server,trigger_name:0 @@ -1342,7 +1409,7 @@ msgstr "Formula" #: code:addons/base/res/res_user.py:389 #, python-format msgid "Can not remove root user!" -msgstr "Ne morete odstaniti uporabnika 'root'." +msgstr "Ne morete odstaniti uporabnika 'root'!" #. module: base #: model:res.country,name:base.mw @@ -1354,7 +1421,7 @@ msgstr "Malavi" #: code:addons/base/res/res_user.py:413 #, python-format msgid "%s (copy)" -msgstr "" +msgstr "%s (kopija)" #. module: base #: field:res.partner.address,type:0 @@ -1364,7 +1431,7 @@ msgstr "Vrsta naslova" #. module: base #: view:ir.ui.menu:0 msgid "Full Path" -msgstr "" +msgstr "Celotna pot" #. module: base #: view:res.request:0 @@ -1378,11 +1445,14 @@ msgid "" "decimal number [00,53]. All days in a new year preceding the first Sunday " "are considered to be in week 0." msgstr "" +"%U - številka tedna v letu (nedelja kot prvi dan tedna) je decimalno " +"število[00,53]. Vse dnevi v novem letu pred prvo nedeljo se šteje, da je v 0 " +"tednu." #. module: base #: view:ir.ui.view:0 msgid "Advanced" -msgstr "" +msgstr "Napredno" #. module: base #: model:res.country,name:base.fi @@ -1396,23 +1466,23 @@ msgstr "Finska" #: selection:ir.ui.view,type:0 #: selection:wizard.ir.model.menu.create.line,view_type:0 msgid "Tree" -msgstr "Drevo" +msgstr "Drevesni prikaz" #. module: base #: help:res.config.users,password:0 msgid "" "Keep empty if you don't want the user to be able to connect on the system." -msgstr "" +msgstr "Obdržite prazno, če ne želite, da se uporabnik poveže na sistem." #. module: base #: view:ir.actions.server:0 msgid "Create / Write / Copy" -msgstr "" +msgstr "Ustvari / Zapiši / Kopiraj" #. module: base #: view:base.language.export:0 msgid "https://help.launchpad.net/Translations" -msgstr "" +msgstr "https://help.launchpad.net/Translations" #. module: base #: field:ir.actions.act_window,view_mode:0 @@ -1425,27 +1495,29 @@ msgid "" "When using CSV format, please also check that the first line of your file is " "one of the following:" msgstr "" +"Ko uporabljate CSV format, prosim preverite tudi prve vrstice vaše datoteke " +"ena od naslednje:" #. module: base #: code:addons/fields.py:114 #, python-format msgid "Not implemented search_memory method !" -msgstr "Metoda 'search_memory' ni implementirana." +msgstr "Metoda 'search_memory' ni implementirana!" #. module: base #: view:res.log:0 msgid "Logs" -msgstr "" +msgstr "Dnevniki" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish / Español" -msgstr "Špansko" +msgstr "Špansko / Español" #. module: base #: selection:base.language.install,lang:0 msgid "Korean (KP) / 한국어 (KP)" -msgstr "" +msgstr "Korejsko (KP) / 한국어 (KP)" #. module: base #: view:base.module.update:0 @@ -1453,6 +1525,8 @@ msgid "" "This wizard will scan all module repositories on the server side to detect " "newly added modules as well as any change to existing modules." msgstr "" +"Ta čarovnik po pregledal vse skladišča modulov na strani strežnik za " +"odkrivanje novo dodanih modulov kot tudi vse spremembe na obstoječih modulih." #. module: base #: field:res.company,logo:0 @@ -1462,7 +1536,7 @@ msgstr "Logotip" #. module: base #: view:res.partner.address:0 msgid "Search Contact" -msgstr "" +msgstr "Išči po stikih" #. module: base #: view:ir.module.module:0 @@ -1486,13 +1560,13 @@ msgstr "Bahami" msgid "" "Couldn't generate the next id because some partners have an alphabetic id !" msgstr "" -"Ni bilo možno ustvariti naslednjega IDja, saj imajo nekateri partnerji " -"črkovni ID." +"Ni bilo možno ustvariti sledečega IDja, ker imajo nekateri partnerji črkovni " +"ID!" #. module: base #: view:ir.attachment:0 msgid "Attachment" -msgstr "Priponke" +msgstr "Priponka" #. module: base #: model:res.country,name:base.ie @@ -1508,12 +1582,12 @@ msgstr "Število osveženih modulov" #: code:addons/fields.py:100 #, python-format msgid "Not implemented set_memory method !" -msgstr "Metoda 'set_memory' ni implementirana." +msgstr "Metoda 'set_memory' ni implementirana!" #. module: base #: view:workflow.activity:0 msgid "Workflow Activity" -msgstr "" +msgstr "Aktivnost delovnega procesa" #. module: base #: view:ir.rule:0 @@ -1521,6 +1595,8 @@ msgid "" "Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND " "GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" msgstr "" +"Primer: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND " +"GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" #. module: base #: model:ir.actions.act_window,help:base.action_ui_view @@ -1528,6 +1604,9 @@ msgid "" "Views allows you to personalize each view of OpenERP. You can add new " "fields, move fields, rename them or delete the ones that you do not need." msgstr "" +"Pogledi vam dovolijo prilagoditev vsak pogled OpenERP. Dodate lahko nova " +"polja, premaknite polja, jih preimenujete ali izbrišete tiste, ki jih ne " +"potrebujete." #. module: base #: field:ir.actions.act_window,groups_id:0 @@ -1553,7 +1632,7 @@ msgstr "Skupine" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (CL) / Español (CL)" -msgstr "" +msgstr "Špansko (CL) / Español (CL)" #. module: base #: view:res.config.users:0 @@ -1562,6 +1641,10 @@ msgid "" "access to selected functionalities within the system. Click on 'Done' if you " "do not wish to add more users at this stage, you can always do this later." msgstr "" +"Ustvarjajte dodatne uporabnike in jih dodelite skupinam, ki jim bodo " +"omogočila dostop do izbranih funkcij v sistemu. Kliknite na \"Končano\", če " +"ne želite dodati več uporabnikov na tej stopnji, lahko pa to naredite tudi " +"kasneje." #. module: base #: model:res.country,name:base.bz @@ -1584,17 +1667,19 @@ msgid "" "Comma-separated list of allowed view modes, such as 'form', 'tree', " "'calendar', etc. (Default: tree,form)" msgstr "" +"Z vejico ločen seznam dovoljenih načinov pogleda, kot so \"oblika\", " +"\"drevo\", \"koledar\", itd (Default: drevo, oblika)" #. module: base #: code:addons/orm.py:3147 #, python-format msgid "A document was modified since you last viewed it (%s:%d)" -msgstr "" +msgstr "Dokument je bil spremenjem po vašem zadnjem ogledu (%s:%d)" #. module: base #: view:workflow:0 msgid "Workflow Editor" -msgstr "" +msgstr "Urejevalnik delovnik procesov" #. module: base #: selection:ir.module.module,state:0 @@ -1614,6 +1699,9 @@ msgid "" "order in Object, and you can have loop on the sales order line. Expression = " "`object.order_line`." msgstr "" +"Vpišite polje / izraz, ki bo vrnil na seznam. Npr. izberite prodajo vrstni " +"red predmetov, in lahko imate zanko na vrstici prodajnega naročila. Izraz = " +"`object.order_line`." #. module: base #: field:ir.property,fields_id:0 @@ -1625,7 +1713,7 @@ msgstr "Polje" #. module: base #: view:ir.rule:0 msgid "Groups (no group = global)" -msgstr "" +msgstr "Skupine (ni skupine = globalno)" #. module: base #: model:res.country,name:base.fo @@ -1637,7 +1725,7 @@ msgstr "Ferski otoki" #: selection:res.config.view,view:0 #: selection:res.users,view:0 msgid "Simplified" -msgstr "" +msgstr "Poenostavljen" #. module: base #: model:res.country,name:base.st @@ -1652,7 +1740,7 @@ msgstr "Račun" #. module: base #: selection:base.language.install,lang:0 msgid "Portugese (BR) / Português (BR)" -msgstr "" +msgstr "Portugalsko (BR) / Português (BR)" #. module: base #: model:res.country,name:base.bb @@ -1670,7 +1758,7 @@ msgstr "Madagaskar" msgid "" "The Object name must start with x_ and not contain any special character !" msgstr "" -"Naziv objekta se mora začeti z 'x_' in ne sme vsebovati posebnih znakov." +"Naziv predmeta se mora začet z x_ in ne sme vsebovati posebnih znakov!" #. module: base #: field:ir.actions.configuration.wizard,note:0 @@ -1682,27 +1770,27 @@ msgstr "Naslednji čarovnik" #: view:ir.ui.menu:0 #: field:ir.ui.menu,name:0 msgid "Menu" -msgstr "Menu" +msgstr "Meni" #. module: base #: field:res.currency,rate:0 msgid "Current Rate" -msgstr "" +msgstr "Trenutno razmerje" #. module: base #: field:ir.ui.view.custom,ref_id:0 msgid "Original View" -msgstr "" +msgstr "Originalni pogled" #. module: base #: view:ir.values:0 msgid "Action To Launch" -msgstr "" +msgstr "Dejanje za zagon" #. module: base #: field:ir.actions.url,target:0 msgid "Action Target" -msgstr "" +msgstr "Cilj dejanja" #. module: base #: model:res.country,name:base.ai @@ -1725,6 +1813,8 @@ msgid "" "Provide the field name that the record id refers to for the write operation. " "If it is empty it will refer to the active id of the object." msgstr "" +"Navedite ime polja, ki se nanaša na zapis id za operacijo pisanja. Če je " +"prazna, se bo nanašalo na aktivni id predmeta." #. module: base #: model:res.country,name:base.zw @@ -1735,11 +1825,12 @@ msgstr "Zimbabve" #: view:base.module.update:0 msgid "Please be patient, as this operation may take a few seconds..." msgstr "" +"Prosimo, bodite potrpežljivi, saj lahko ta operacija traja nekaj sekund ..." #. module: base #: help:ir.values,action_id:0 msgid "This field is not used, it only helps you to select the right action." -msgstr "" +msgstr "Polje ni v uporabi, pomagam vas samo izbrati pravo dejanje." #. module: base #: field:ir.actions.server,email:0 @@ -1749,7 +1840,7 @@ msgstr "E-poštni naslov" #. module: base #: selection:base.language.install,lang:0 msgid "French (BE) / Français (BE)" -msgstr "" +msgstr "Francosko (BE) / Français (BE)" #. module: base #: view:ir.actions.server:0 @@ -1780,7 +1871,7 @@ msgstr "Preslikave polj" #. module: base #: view:base.language.export:0 msgid "Export Translations" -msgstr "" +msgstr "Izvoz prevodov" #. module: base #: model:ir.ui.menu,name:base.menu_custom @@ -1812,7 +1903,7 @@ msgstr "Litva" #: model:ir.model,name:base.model_partner_clear_ids #: view:partner.clear.ids:0 msgid "Clear IDs" -msgstr "" +msgstr "Počiši ID-je" #. module: base #: help:ir.cron,model:0 @@ -1820,17 +1911,19 @@ msgid "" "Name of object whose function will be called when this scheduler will run. " "e.g. 'res.partener'" msgstr "" +"Ime predmeta, katerih funkcija se bo klicalal, ko bo to tekel " +"razporejevalnik. npr. \"res.partener\"" #. module: base #: code:addons/orm.py:1040 #, python-format msgid "The perm_read method is not implemented on this object !" -msgstr "Metoda 'perm_read' ni implementirana za ta objekt." +msgstr "Metoda 'perm_read' ni implementirana za ta predmet!" #. module: base #: view:res.lang:0 msgid "%y - Year without century [00,99]." -msgstr "" +msgstr "%y - Leto brez stoletja [00,99]." #. module: base #: model:res.country,name:base.si @@ -1846,12 +1939,12 @@ msgstr "Pakistan" #: code:addons/orm.py:1350 #, python-format msgid "Invalid Object Architecture!" -msgstr "" +msgstr "Neveljavna arhitektura predmeta!" #. module: base #: model:ir.ui.menu,name:base.menu_email_gateway_form msgid "Messages" -msgstr "" +msgstr "Sporočila" #. module: base #: code:addons/base/ir/ir_model.py:303 @@ -1868,17 +1961,17 @@ msgstr "Napaka!" #. module: base #: view:res.lang:0 msgid "%p - Equivalent of either AM or PM." -msgstr "" +msgstr "%p - ekvivalenten bodisi AM ali PM." #. module: base #: view:ir.actions.server:0 msgid "Iteration Actions" -msgstr "" +msgstr "Ponovitvena dejanja" #. module: base #: help:multi_company.default,company_id:0 msgid "Company where the user is connected" -msgstr "" +msgstr "Podjetje kamor je uporabnik povezan" #. module: base #: field:publisher_warranty.contract,date_stop:0 @@ -1897,6 +1990,8 @@ msgid "" "One of the records you are trying to modify has already been deleted " "(Document type: %s)." msgstr "" +"Eden izmed zapisov, ki jih poskušate spremeniti, so že izbrisana (Vrsta " +"dokumenta: %s)." #. module: base #: model:ir.actions.act_window,help:base.action_country @@ -1905,6 +2000,9 @@ msgid "" "partner records. You can create or delete countries to make sure the ones " "you are working on will be maintained." msgstr "" +"Prikaz in upravljanje seznam vseh držav, ki jih je mogoče dodeliti vašemu " +"zapisu partnerja. Lahko ustvarite ali izbrišete države, da se prepričate, da " +"tisti s katerimi delate, da so vzdrževani." #. module: base #: model:res.partner.category,name:base.res_partner_category_7 @@ -1919,18 +2017,18 @@ msgstr "Otok Norfolk" #. module: base #: selection:base.language.install,lang:0 msgid "Korean (KR) / 한국어 (KR)" -msgstr "" +msgstr "Korejsko (KR) / 한국어 (KR)" #. module: base #: help:ir.model.fields,model:0 msgid "The technical name of the model this field belongs to" -msgstr "" +msgstr "Tehnično ime modela h kateremu to polje pripada" #. module: base #: field:ir.actions.server,action_id:0 #: selection:ir.actions.server,state:0 msgid "Client Action" -msgstr "Odjemalčeva akcija" +msgstr "Klientovo dejanje" #. module: base #: model:res.country,name:base.bd @@ -1940,7 +2038,7 @@ msgstr "Bangladeš" #. module: base #: constraint:res.company:0 msgid "Error! You can not create recursive companies." -msgstr "Napaka. Ne morete ustvariti rekurzivnih družb." +msgstr "Napaka! Ne morete ustvariti rekurzivnih podjetij." #. module: base #: selection:publisher_warranty.contract,state:0 @@ -1971,7 +2069,7 @@ msgstr "res.partner.event" #. module: base #: model:res.widget,title:base.facebook_widget msgid "Facebook" -msgstr "" +msgstr "Facebook" #. module: base #: model:res.country,name:base.am @@ -1982,12 +2080,12 @@ msgstr "Armenija" #: model:ir.actions.act_window,name:base.ir_property_form #: model:ir.ui.menu,name:base.menu_ir_property_form_all msgid "Configuration Parameters" -msgstr "" +msgstr "Parametri konfiguracije" #. module: base #: constraint:ir.cron:0 msgid "Invalid arguments" -msgstr "" +msgstr "Neveljavni argumenti" #. module: base #: model:res.country,name:base.se @@ -2027,17 +2125,17 @@ msgstr "Vrsta bančnega računa" #: field:res.config.users,config_logo:0 #: field:res.config.view,config_logo:0 msgid "Image" -msgstr "" +msgstr "Slika" #. module: base #: view:ir.actions.server:0 msgid "Iteration Action Configuration" -msgstr "" +msgstr "Konfiguracija ponovitvenega dejanja" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Canceled" -msgstr "" +msgstr "Preklicano" #. module: base #: model:res.country,name:base.at @@ -2062,7 +2160,7 @@ msgstr "Koledar" #. module: base #: field:res.partner.address,partner_id:0 msgid "Partner Name" -msgstr "" +msgstr "Ime partnerja" #. module: base #: field:workflow.activity,signal_send:0 @@ -2072,7 +2170,7 @@ msgstr "" #. module: base #: model:res.partner.category,name:base.res_partner_category_17 msgid "HR sector" -msgstr "" +msgstr "Sektor HR" #. module: base #: code:addons/orm.py:3817 @@ -2082,6 +2180,9 @@ msgid "" "separated list of valid field names (optionally followed by asc/desc for the " "direction)" msgstr "" +"Navedeno neveljavno \"naročilo\" Veljavna specifikacija \"naročila\" je z " +"vejico ločen seznam veljavnih imen polj (opcijsko za smetri sledi " +"naraščajoče/padajoče)" #. module: base #: model:ir.model,name:base.model_ir_module_module_dependency @@ -2098,7 +2199,7 @@ msgstr "Osnutek" #: selection:res.config.view,view:0 #: selection:res.users,view:0 msgid "Extended" -msgstr "" +msgstr "Razširjeno" #. module: base #: model:ir.actions.act_window,help:base.action_partner_title_contact @@ -2107,6 +2208,9 @@ msgid "" "way you want to print them in letters and other documents. Some example: " "Mr., Mrs. " msgstr "" +"Upravljanje kontaktnih naslovov, ki jih želite imeti na voljo v vašem " +"sistemu in tako, kot želite, da jih natisnete na pisma in druge dokumente " +"Nekateri primere: gospod, gospa. " #. module: base #: field:res.company,rml_footer1:0 @@ -2134,12 +2238,12 @@ msgstr "Odvisnosti" #. module: base #: field:multi_company.default,company_id:0 msgid "Main Company" -msgstr "Glavna družba" +msgstr "Glavno podjetje" #. module: base #: field:ir.ui.menu,web_icon_hover:0 msgid "Web Icon File (hover)" -msgstr "" +msgstr "Datoteka spletne ikone (hover)" #. module: base #: view:ir.actions.server:0 @@ -2147,6 +2251,8 @@ msgid "" "If you use a formula type, use a python expression using the variable " "'object'." msgstr "" +"Če uporabite tip formule, uporabite python izraz z uporabo spremenljivke " +"'object'." #. module: base #: field:res.partner.address,birthdate:0 @@ -2157,7 +2263,7 @@ msgstr "Datum rojstva" #: model:ir.actions.act_window,name:base.action_partner_title_contact #: model:ir.ui.menu,name:base.menu_partner_title_contact msgid "Contact Titles" -msgstr "" +msgstr "Naziv kontakta" #. module: base #: view:base.language.import:0 @@ -2165,11 +2271,13 @@ msgid "" "Please double-check that the file encoding is set to UTF-8 (sometimes called " "Unicode) when the translator exports it." msgstr "" +"Prosimo, še enkrat preverite, da je nastavljeno za datoteko kodiranje UTF-8 " +"(včasih se imenuje Unicode), ko je prevajalec izvozi." #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (DO) / Español (DO)" -msgstr "" +msgstr "Špansko (DO) / Español (DO)" #. module: base #: model:ir.model,name:base.model_workflow_activity @@ -2182,11 +2290,13 @@ msgid "" "Reference of the target resource, whose model/table depends on the 'Resource " "Name' field." msgstr "" +"Sklic ciljnega vira, katerega model / tabela je odvisno od polja \"Ime " +"vira\"." #. module: base #: field:ir.model.fields,select_level:0 msgid "Searchable" -msgstr "" +msgstr "Možno iskati" #. module: base #: model:res.country,name:base.uy @@ -2196,12 +2306,12 @@ msgstr "Urugvaj" #. module: base #: selection:base.language.install,lang:0 msgid "Finnish / Suomi" -msgstr "" +msgstr "Finsko / Suomi" #. module: base #: field:ir.rule,perm_write:0 msgid "Apply For Write" -msgstr "" +msgstr "Uporabi za pisanje" #. module: base #: field:ir.sequence,prefix:0 @@ -2211,12 +2321,12 @@ msgstr "Predpona" #. module: base #: selection:base.language.install,lang:0 msgid "German / Deutsch" -msgstr "" +msgstr "Nemško / Deutsch" #. module: base #: help:ir.actions.server,trigger_name:0 msgid "Select the Signal name that is to be used as the trigger." -msgstr "" +msgstr "Izberite ime signala, ki bo uporabljeno za sprožilec." #. module: base #: view:ir.actions.server:0 @@ -2226,7 +2336,7 @@ msgstr "Preslikava polj" #. module: base #: selection:base.language.install,lang:0 msgid "Portugese / Português" -msgstr "" +msgstr "Portugalsko/ Português" #. module: base #: model:res.partner.title,name:base.res_partner_title_sir @@ -2237,7 +2347,7 @@ msgstr "Gospod" #: code:addons/orm.py:1622 #, python-format msgid "There is no view of type '%s' defined for the structure!" -msgstr "" +msgstr "Ni navedeno vrste pogleda '%s' za strukturo!" #. module: base #: field:ir.default,ref_id:0 @@ -2248,7 +2358,7 @@ msgstr "Sklic ID" #: model:ir.actions.server,name:base.action_start_configurator #: model:ir.ui.menu,name:base.menu_view_base_module_configuration msgid "Start Configuration" -msgstr "" +msgstr "Začni s konfiguracijo" #. module: base #: model:res.country,name:base.mt @@ -2258,7 +2368,7 @@ msgstr "Malta" #. module: base #: field:ir.actions.server,fields_lines:0 msgid "Field Mappings." -msgstr "" +msgstr "Preslikave polj" #. module: base #: model:ir.model,name:base.model_ir_module_module @@ -2286,7 +2396,7 @@ msgstr "Opis" #: model:ir.actions.act_window,name:base.action_workflow_instance_form #: model:ir.ui.menu,name:base.menu_workflow_instance msgid "Instances" -msgstr "Pojavitve" +msgstr "Primeri" #. module: base #: model:res.country,name:base.aq @@ -2296,12 +2406,12 @@ msgstr "Antarktika" #. module: base #: field:ir.actions.report.xml,auto:0 msgid "Custom python parser" -msgstr "" +msgstr "Python parser po meri" #. module: base #: view:base.language.import:0 msgid "_Import" -msgstr "" +msgstr "_Uvozi" #. module: base #: view:res.partner.canal:0 @@ -2311,17 +2421,17 @@ msgstr "Kanal" #. module: base #: field:res.lang,grouping:0 msgid "Separator Format" -msgstr "" +msgstr "Oblika ločila" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Unvalidated" -msgstr "" +msgstr "Ni potrjeno" #. module: base #: model:ir.ui.menu,name:base.next_id_9 msgid "Database Structure" -msgstr "Struktura skladišča podatkov" +msgstr "Struktura podatkovne baze" #. module: base #: model:ir.actions.act_window,name:base.action_partner_mass_mail @@ -2339,7 +2449,7 @@ msgstr "Mayotte" #: code:addons/base/ir/ir_actions.py:597 #, python-format msgid "Please specify an action to launch !" -msgstr "" +msgstr "Prosim, navedite dejanje za zagon!" #. module: base #: view:res.payterm:0 @@ -2349,7 +2459,7 @@ msgstr "Plačilni pogoj" #. module: base #: selection:res.lang,direction:0 msgid "Right-to-Left" -msgstr "" +msgstr "Z desne na levo" #. module: base #: view:ir.actions.act_window:0 @@ -2358,7 +2468,7 @@ msgstr "" #: model:ir.model,name:base.model_ir_filters #: model:ir.ui.menu,name:base.menu_ir_filters msgid "Filters" -msgstr "" +msgstr "Filtri" #. module: base #: code:addons/orm.py:758 @@ -2371,31 +2481,31 @@ msgstr "Preverite, če imajo vse vaše vrstice %d stolpcev." #: view:ir.cron:0 #: model:ir.ui.menu,name:base.menu_ir_cron_act msgid "Scheduled Actions" -msgstr "Planirane akcije" +msgstr "Planirana dejanja" #. module: base #: field:res.partner.address,title:0 #: field:res.partner.title,name:0 #: field:res.widget,title:0 msgid "Title" -msgstr "Titula" +msgstr "Naziv" #. module: base #: help:ir.property,res_id:0 msgid "If not set, acts as a default value for new resources" -msgstr "" +msgstr "Če ni nastavljeno, se obnaša kot privzera vrednost za nove vire" #. module: base #: code:addons/orm.py:3448 #, python-format msgid "Recursivity Detected." -msgstr "" +msgstr "Zaznana rekurzivnost." #. module: base #: code:addons/base/module/module.py:262 #, python-format msgid "Recursion error in modules dependencies !" -msgstr "Napaka rekurzije v odvisnostih modulov." +msgstr "Napaka rekurzije v odvisnostih modulih!" #. module: base #: view:base.language.install:0 @@ -2404,11 +2514,14 @@ msgid "" "loading a new language it becomes available as default interface language " "for users and partners." msgstr "" +"Ta čarovnik vam pomaga pri dodajanju novega jezika v vaš OpenERP sistem. Po " +"nalaganju novega jezika, postane dostopen kot privzeti jezik vmesnika vašim " +"uporabnikom in partnerjem." #. module: base #: view:ir.model:0 msgid "Create a Menu" -msgstr "Ustvari menu" +msgstr "Ustvari meni" #. module: base #: help:res.partner,vat:0 @@ -2416,11 +2529,13 @@ msgid "" "Value Added Tax number. Check the box if the partner is subjected to the " "VAT. Used by the VAT legal statement." msgstr "" +"Številka davka na dodano vrednost. Preverite polje, če je partner predmet " +"DDV. Uporabljeno za DDV pravno izjavo." #. module: base #: model:ir.model,name:base.model_maintenance_contract msgid "maintenance.contract" -msgstr "" +msgstr "maintenance.contract" #. module: base #: model:res.country,name:base.ru @@ -2435,7 +2550,7 @@ msgstr "" #. module: base #: field:res.company,name:0 msgid "Company Name" -msgstr "Naziv družbe" +msgstr "Ime podjetja" #. module: base #: model:ir.actions.act_window,name:base.action_country @@ -2446,7 +2561,7 @@ msgstr "Države" #. module: base #: selection:ir.translation,type:0 msgid "RML (deprecated - use Report)" -msgstr "" +msgstr "RML (opuščeno - uporabite Poročilo)" #. module: base #: view:ir.rule:0 @@ -2456,43 +2571,43 @@ msgstr "Posnemi pravila" #. module: base #: view:ir.property:0 msgid "Field Information" -msgstr "" +msgstr "Podatki polja" #. module: base #: view:ir.actions.todo:0 msgid "Search Actions" -msgstr "" +msgstr "Dejanje iskanja" #. module: base #: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check #: view:partner.wizard.ean.check:0 msgid "Ean check" -msgstr "" +msgstr "Preveri ean" #. module: base #: field:res.partner,vat:0 msgid "VAT" -msgstr "DDV ID" +msgstr "DDV" #. module: base #: view:res.lang:0 msgid "12. %w ==> 5 ( Friday is the 6th day)" -msgstr "" +msgstr "12. %w ==> (Petek je šesti dan)" #. module: base #: constraint:res.partner.category:0 msgid "Error ! You can not create recursive categories." -msgstr "Napaka! Ne morete ustvariti rekurzivne kategorije." +msgstr "Napaka! Rekurzivnih kategorij ne morete ustvariti." #. module: base #: view:res.lang:0 msgid "%x - Appropriate date representation." -msgstr "" +msgstr "%x - Ustrezen datum zastopanja." #. module: base #: view:res.lang:0 msgid "%d - Day of the month [01,31]." -msgstr "" +msgstr "%d - Dan v mesecu [01,31]." #. module: base #: model:res.country,name:base.tj @@ -2502,12 +2617,12 @@ msgstr "Tadžikistan" #. module: base #: selection:ir.module.module,license:0 msgid "GPL-2 or later version" -msgstr "" +msgstr "GPL-2 ali naslednja verzija" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_sir msgid "M." -msgstr "" +msgstr "G." #. module: base #: code:addons/base/module/module.py:429 @@ -2526,17 +2641,19 @@ msgid "" "Operation prohibited by access rules, or performed on an already deleted " "document (Operation: read, Document type: %s)." msgstr "" +"Operacijo prepovedujejo dostopna pravila, ali se izvajajo na že izbrisanem " +"dokumentnu (Operacija: branje, vrsta dokumenta: %s)." #. module: base #: model:res.country,name:base.nr msgid "Nauru" -msgstr "" +msgstr "Nauru" #. module: base #: code:addons/base/module/module.py:200 #, python-format msgid "The certificate ID of the module must be unique !" -msgstr "" +msgstr "ID potrdila modula mora biti edinstven!" #. module: base #: model:ir.model,name:base.model_ir_property @@ -2560,7 +2677,7 @@ msgstr "Črna gora" #. module: base #: view:ir.cron:0 msgid "Technical Data" -msgstr "" +msgstr "Tehnični podatki" #. module: base #: view:res.partner:0 @@ -2575,13 +2692,15 @@ msgid "" "import a language pack from here. Other OpenERP languages than the official " "ones can be found on launchpad." msgstr "" +"Če potrebujete drug jezik, ki je uradno dostopen, ga lahko tukaj uvozite. " +"Ostali OpenERP jeziki, ki niso uradni, so dostopni na launchpad." #. module: base #: view:ir.module.module:0 #: selection:ir.module.module,state:0 #: selection:ir.module.module.dependency,state:0 msgid "To be upgraded" -msgstr "Za nadgraditi" +msgstr "Bo nadgrajeno" #. module: base #: model:res.country,name:base.ly @@ -2596,7 +2715,7 @@ msgstr "Centralnoafriška republika" #. module: base #: model:res.country,name:base.li msgid "Liechtenstein" -msgstr "" +msgstr "Liechtenstein" #. module: base #: model:ir.model,name:base.model_partner_sms_send @@ -2613,7 +2732,7 @@ msgstr "Črtna koda (EAN13)" #: code:addons/orm.py:1622 #, python-format msgid "Invalid Architecture!" -msgstr "" +msgstr "Neveljavna arhitektura" #. module: base #: model:res.country,name:base.pt @@ -2624,12 +2743,12 @@ msgstr "Portugalska" #: sql_constraint:ir.model.data:0 msgid "" "You cannot have multiple records with the same id for the same module !" -msgstr "" +msgstr "Ne morete imeti več zapisov z istim id za isti modul!" #. module: base #: field:ir.module.module,certificate:0 msgid "Quality Certificate" -msgstr "" +msgstr "Potrdilo kakovosti" #. module: base #: view:res.lang:0 @@ -2640,17 +2759,17 @@ msgstr "6. %d, %m ==> 05, 12" #: field:res.config.users,date:0 #: field:res.users,date:0 msgid "Last Connection" -msgstr "" +msgstr "Zadnja povezava" #. module: base #: field:ir.actions.act_window,help:0 msgid "Action description" -msgstr "" +msgstr "Opis dejanja" #. module: base #: help:res.partner,customer:0 msgid "Check this box if the partner is a customer." -msgstr "" +msgstr "Označite to polje, če je partner stranka." #. module: base #: model:ir.actions.act_window,name:base.res_lang_act_window @@ -2664,7 +2783,7 @@ msgstr "Jeziki" #: selection:workflow.activity,join_mode:0 #: selection:workflow.activity,split_mode:0 msgid "Xor" -msgstr "Izključujoči ALI" +msgstr "Xor" #. module: base #: model:res.country,name:base.ec @@ -2689,7 +2808,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_partner_form #: view:res.partner:0 msgid "Customers" -msgstr "" +msgstr "Stranke" #. module: base #: model:res.country,name:base.au @@ -2718,12 +2837,12 @@ msgstr "Osnovno polje" #. module: base #: view:publisher_warranty.contract:0 msgid "Validate" -msgstr "" +msgstr "Preveri" #. module: base #: field:ir.actions.todo,restart:0 msgid "Restart" -msgstr "" +msgstr "Ponoven zagon" #. module: base #: field:ir.actions.report.xml,report_sxw_content:0 @@ -2740,13 +2859,15 @@ msgstr "Čarovnik" #. module: base #: view:ir.cron:0 msgid "Action to Trigger" -msgstr "" +msgstr "Dejanje za zagon" #. module: base #: code:addons/base/res/res_user.py:136 #, python-format msgid "\"email_from\" needs to be set to send welcome mails to users" msgstr "" +"\"email_form\" mora biti nastavljen za pošiljanje e-pošte dobrodošlice " +"uporabnikom" #. module: base #: selection:ir.translation,type:0 @@ -2764,12 +2885,12 @@ msgstr "Privzeto" #: field:ir.model.fields,required:0 #: field:res.partner.bank.type.field,required:0 msgid "Required" -msgstr "Obvezno" +msgstr "Zahtevano" #. module: base #: view:res.users:0 msgid "Default Filters" -msgstr "" +msgstr "Privzeti filtri" #. module: base #: field:res.request.history,name:0 @@ -2779,7 +2900,7 @@ msgstr "Povzetek" #. module: base #: field:multi_company.default,expression:0 msgid "Expression" -msgstr "" +msgstr "Izraz" #. module: base #: help:ir.actions.server,subject:0 @@ -2787,6 +2908,8 @@ msgid "" "Specify the subject. You can use fields from the object, e.g. `Hello [[ " "object.partner_id.name ]]`" msgstr "" +"Navedite predmet. Uporabite lahko polja iz predmeta, npr. 'Pozdravljeni " +"[[object.partner_id.name]]'" #. module: base #: view:res.company:0 @@ -2799,6 +2922,8 @@ msgid "" "Optional help text for the users with a description of the target view, such " "as its usage and purpose." msgstr "" +"Opcijski teksti pomoči za uporabnike z opisi ciljnega pogleda, kot je " +"uporaba in namen." #. module: base #: model:res.country,name:base.va @@ -2813,28 +2938,28 @@ msgstr ".ZIP datoteka modula" #. module: base #: field:ir.ui.view,xml_id:0 msgid "XML ID" -msgstr "" +msgstr "ID XML" #. module: base #: model:res.partner.category,name:base.res_partner_category_16 msgid "Telecom sector" -msgstr "" +msgstr "Sektor telekom" #. module: base #: field:workflow.transition,trigger_model:0 msgid "Trigger Object" -msgstr "" +msgstr "Predmet sprožilca" #. module: base #: view:res.users:0 msgid "Current Activity" -msgstr "" +msgstr "Trenutna aktivnost" #. module: base #: view:workflow.activity:0 #: field:workflow.activity,in_transitions:0 msgid "Incoming Transitions" -msgstr "" +msgstr "Prihajajočite transakcije" #. module: base #: model:res.country,name:base.sr @@ -2844,7 +2969,7 @@ msgstr "Surinam" #. module: base #: model:ir.ui.menu,name:base.marketing_menu msgid "Marketing" -msgstr "" +msgstr "Marketing" #. module: base #: view:res.partner.bank:0 @@ -2855,7 +2980,7 @@ msgstr "Bančni račun" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (HN) / Español (HN)" -msgstr "" +msgstr "Špansko (HN) / Español (HN)" #. module: base #: view:ir.sequence.type:0 @@ -2865,7 +2990,7 @@ msgstr "Vrsta zaporedja" #. module: base #: view:ir.ui.view.custom:0 msgid "Customized Architecture" -msgstr "" +msgstr "Prilagojena arhitektura" #. module: base #: field:ir.module.module,license:0 @@ -2875,17 +3000,17 @@ msgstr "Licenca" #. module: base #: field:ir.attachment,url:0 msgid "Url" -msgstr "" +msgstr "Url" #. module: base #: selection:ir.actions.todo,restart:0 msgid "Always" -msgstr "" +msgstr "Vedno" #. module: base #: selection:ir.translation,type:0 msgid "SQL Constraint" -msgstr "" +msgstr "SQL omejitve" #. module: base #: field:ir.actions.server,srcmodel_id:0 @@ -2899,11 +3024,13 @@ msgid "" "The selected language has been successfully installed. You must change the " "preferences of the user and open a new menu to view the changes." msgstr "" +"Izbrani jezik je bil uspešno nameščen. Spremeniti morate lasnosti uporabnika " +"in odpreti nov meni za ogled sprememb." #. module: base #: sql_constraint:ir.config_parameter:0 msgid "Key must be unique." -msgstr "" +msgstr "Ključ mora biti edinstven." #. module: base #: view:ir.actions.act_window:0 @@ -2919,7 +3046,7 @@ msgstr "Ekvatorialna Gvineja" #: view:base.module.import:0 #: model:ir.actions.act_window,name:base.action_view_base_module_import msgid "Module Import" -msgstr "" +msgstr "Uvoz modula" #. module: base #: field:res.bank,zip:0 @@ -2937,12 +3064,12 @@ msgstr "Avtor" #. module: base #: model:res.country,name:base.mk msgid "FYROM" -msgstr "" +msgstr "FYROM" #. module: base #: view:res.lang:0 msgid "%c - Appropriate date and time representation." -msgstr "" +msgstr "%c - Ustrezni datum in čas zastopanja." #. module: base #: code:addons/base/res/res_config.py:422 @@ -2952,11 +3079,14 @@ msgid "" "\n" "Click 'Continue' and enjoy your OpenERP experience..." msgstr "" +"Vaša podatkovna baza je v celoti konfigurirana.\n" +"\n" +"Kliknite 'Nadaljuj' in uživajte v izkušnji OpenERP..." #. module: base #: selection:base.language.install,lang:0 msgid "Hebrew / עִבְרִי" -msgstr "" +msgstr "Židovsko / עִבְרִי" #. module: base #: model:res.country,name:base.bo @@ -2999,12 +3129,12 @@ msgstr "Poskušate odstraniti modul, ki je nameščen ali bo nameščen" #. module: base #: view:base.module.upgrade:0 msgid "The selected modules have been updated / installed !" -msgstr "" +msgstr "Izbrani moduli so bili posodobljeni / nameščeni!" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PR) / Español (PR)" -msgstr "" +msgstr "Špansko (PR) / Español (PR)" #. module: base #: model:res.country,name:base.gt @@ -3017,17 +3147,17 @@ msgstr "Gvatemala" #: model:ir.ui.menu,name:base.menu_workflow #: model:ir.ui.menu,name:base.menu_workflow_root msgid "Workflows" -msgstr "Poteki dela" +msgstr "Delovni procesi" #. module: base #: field:ir.translation,xml_id:0 msgid "XML Id" -msgstr "" +msgstr "Id XML" #. module: base #: model:ir.actions.act_window,name:base.action_config_user_form msgid "Create Users" -msgstr "" +msgstr "Ustvari uporabnike" #. module: base #: model:ir.model,name:base.model_res_partner_title @@ -3037,12 +3167,12 @@ msgstr "res.partner.title" #. module: base #: view:ir.values:0 msgid "tree_but_action, client_print_multi" -msgstr "" +msgstr "Copy text \t tree_but_action, client_print_multi" #. module: base #: model:res.partner.category,name:base.res_partner_category_retailers0 msgid "Retailers" -msgstr "" +msgstr "Trgovci na drobno" #. module: base #: help:ir.cron,priority:0 @@ -3068,7 +3198,7 @@ msgstr "Lesoto" #: code:addons/base/ir/ir_model.py:114 #, python-format msgid "You can not remove the model '%s' !" -msgstr "Ne morete odstraniti modela '%s'." +msgstr "Ne morete odstraniti modela '%s'!" #. module: base #: model:res.country,name:base.ke @@ -3078,12 +3208,12 @@ msgstr "Kenija" #. module: base #: view:res.partner.event:0 msgid "Event" -msgstr "" +msgstr "Dogodek" #. module: base #: model:ir.ui.menu,name:base.menu_custom_reports msgid "Custom Reports" -msgstr "" +msgstr "Poročila po meri" #. module: base #: selection:base.language.install,lang:0 @@ -3093,18 +3223,18 @@ msgstr "" #. module: base #: view:base.module.configuration:0 msgid "System Configuration Done" -msgstr "" +msgstr "Konfiguracija sistema končana" #. module: base #: code:addons/orm.py:929 #, python-format msgid "Error occurred while validating the field(s) %s: %s" -msgstr "" +msgstr "Napaka se je pojavila med preverjanjem polj %s: %s" #. module: base #: view:ir.property:0 msgid "Generic" -msgstr "" +msgstr "Splošno" #. module: base #: model:res.country,name:base.sm @@ -3135,17 +3265,17 @@ msgstr "Benin" #: code:addons/base/publisher_warranty/publisher_warranty.py:281 #, python-format msgid "That contract is already registered in the system." -msgstr "" +msgstr "Ta pogodba je že registrirana v sistemu." #. module: base #: help:ir.sequence,suffix:0 msgid "Suffix value of the record for the sequence" -msgstr "" +msgstr "Pripona vrednosti zapisa za zaporedje" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PY) / Español (PY)" -msgstr "" +msgstr "Špansko (PY) / Español (PY)" #. module: base #: field:ir.config_parameter,key:0 @@ -3169,17 +3299,19 @@ msgid "" "You can not create this document (%s) ! Be sure your user belongs to one of " "these groups: %s." msgstr "" +"Ne morete ustvariti tega dokumenta (%s)! Bodite prepričani, da vaš " +"uporabnik pripada tem skupinam: %s." #. module: base #: model:res.country,name:base.mu msgid "Mauritius" -msgstr "" +msgstr "Mauricius" #. module: base #: view:ir.model.access:0 #: view:ir.rule:0 msgid "Full Access" -msgstr "" +msgstr "Polni dostop" #. module: base #: view:ir.actions.act_window:0 @@ -3193,7 +3325,7 @@ msgstr "Varnost" #. module: base #: model:res.widget,title:base.openerp_favorites_twitter_widget msgid "OpenERP Favorites" -msgstr "" +msgstr "OpenERP priljubljene" #. module: base #: model:res.country,name:base.za @@ -3210,13 +3342,13 @@ msgstr "Namščen" #. module: base #: selection:base.language.install,lang:0 msgid "Ukrainian / українська" -msgstr "" +msgstr "Ukrajinsko / українська" #. module: base #: model:ir.actions.act_window,name:base.action_translation #: model:ir.ui.menu,name:base.menu_action_translation msgid "Translation Terms" -msgstr "" +msgstr "Pogoji prevodov" #. module: base #: model:res.country,name:base.sn @@ -3241,12 +3373,12 @@ msgstr "Brazilija" #. module: base #: view:res.lang:0 msgid "%M - Minute [00,59]." -msgstr "" +msgstr "%M - Minute [00,59]." #. module: base #: selection:ir.module.module,license:0 msgid "Affero GPL-3" -msgstr "" +msgstr "Affero GPL-3" #. module: base #: field:ir.sequence,number_next:0 @@ -3256,12 +3388,12 @@ msgstr "Naslednja številka" #. module: base #: help:workflow.transition,condition:0 msgid "Expression to be satisfied if we want the transition done." -msgstr "" +msgstr "Izraz, ki ja treba izpolniti, če želimo izpolniti transakcijo." #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PA) / Español (PA)" -msgstr "" +msgstr "Špansko (PA) / Español (PA)" #. module: base #: view:res.currency:0 @@ -3286,11 +3418,14 @@ msgid "" "invoice, then `object.invoice_address_id.mobile` is the field which gives " "the correct mobile number" msgstr "" +"Zagotavlja polja, ki se uporablja za pridobivanje mobilne številke, npr, " +"izberete račun, nato pa polje `object.invoice_address_id.mobile`, ki daje " +"pravo mobilno številko" #. module: base #: view:base.module.upgrade:0 msgid "System update completed" -msgstr "" +msgstr "Posodobitev sistema je končano" #. module: base #: selection:res.request,state:0 @@ -3321,28 +3456,28 @@ msgstr "Podatki" #: field:ir.ui.menu,parent_id:0 #: field:wizard.ir.model.menu.create,menu_id:0 msgid "Parent Menu" -msgstr "Nadmenu" +msgstr "Nameni" #. module: base #: field:ir.rule,perm_unlink:0 msgid "Apply For Delete" -msgstr "" +msgstr "Uporabi za izbris" #. module: base #: code:addons/base/ir/ir_model.py:319 #, python-format msgid "Cannot rename column to %s, because that column already exists!" -msgstr "" +msgstr "Ne morem preimenovati stolpca v %s, ker ta stolpec že obstaja." #. module: base #: view:ir.attachment:0 msgid "Attached To" -msgstr "" +msgstr "Pripeto k" #. module: base #: field:res.lang,decimal_point:0 msgid "Decimal Separator" -msgstr "" +msgstr "Decimalni ločevalnik" #. module: base #: model:ir.actions.act_window,help:base.action_res_groups @@ -3354,6 +3489,12 @@ msgid "" "to see. Whether they can have a read, write, create and delete access right " "can be managed from here." msgstr "" +"Skupina je nabor funkcionalnih območij, ki bodo dodeljene uporabniku, da se " +"jim omogoči dostop in pravice do specifičnih aplikacij in nalog v sistemu. " +"Lahko ustvarite skupine po meri ali uredite tiste, ki veljajo privzeto, da " +"si prilagodite pogled menija, ki ga bodo uporabniki lahko videli. Ali lahko " +"imajo pravice za dosotp do branje, pisanje, ustvarjanje in brisanje, lahko " +"upravljate od tukaj." #. module: base #: view:res.partner:0 @@ -3377,6 +3518,12 @@ msgid "" "Would your payment have been carried out after this mail was sent, please " "consider the present one as void." msgstr "" +"Prosimo, upoštevajte, da so naslednja plačila sedaj na vrsti. Če je bilo " +"poslano vaše plačilo, prosimo, posredujte vaše podatke plačila. Če bo " +"plačilo dodatno zamudilo, se prosim obrnite na nas glede tega. " +" \n" +"Če je bilo vaše plačilo izvedeno po tem, ko je bil poslano to sporočilo, " +"prosimo, obravnavajte prejšnjega kot neveljavnega." #. module: base #: model:res.country,name:base.mx @@ -3386,12 +3533,12 @@ msgstr "Mehika" #. module: base #: model:ir.ui.menu,name:base.menu_base_config_plugins msgid "Plugins" -msgstr "" +msgstr "Vtičniki" #. module: base #: field:res.company,child_ids:0 msgid "Child Companies" -msgstr "Hčerinske družbe" +msgstr "Hčerinska podjetja" #. module: base #: model:ir.model,name:base.model_res_users @@ -3407,7 +3554,7 @@ msgstr "Nikaragva" #: code:addons/orm.py:1046 #, python-format msgid "The write method is not implemented on this object !" -msgstr "Metoda 'write' ni implementirana za ta objekt." +msgstr "Metoda 'write' ni implementirana za ta predmet!" #. module: base #: view:res.partner.event:0 @@ -3418,7 +3565,7 @@ msgstr "Splošni opis" #: model:ir.actions.act_window,name:base.action_config_simple_view_form #: view:res.config.view:0 msgid "Configure Your Interface" -msgstr "" +msgstr "Nastavite vaš vmesnik" #. module: base #: field:ir.values,meta:0 @@ -3428,7 +3575,7 @@ msgstr "Meta podatki" #. module: base #: sql_constraint:ir.ui.view_sc:0 msgid "Shortcut for this menu already exists!" -msgstr "" +msgstr "Bližnjica za ta meni že obstaja!" #. module: base #: model:res.country,name:base.ve @@ -3456,7 +3603,7 @@ msgstr "" #. module: base #: field:res.partner,parent_id:0 msgid "Parent Partner" -msgstr "" +msgstr "Matični partner" #. module: base #: view:ir.module.module:0 @@ -3476,7 +3623,7 @@ msgstr "Kazahstan" #. module: base #: view:res.lang:0 msgid "%w - Weekday number [0(Sunday),6]." -msgstr "" +msgstr "%w - Številka dneva v tednu [0(nedelja),6]" #. module: base #: model:ir.actions.act_window,help:base.action_partner_form @@ -3489,6 +3636,13 @@ msgid "" "plugin, don't forget to register emails to each contact so that the gateway " "will automatically attach incoming emails to the right partner." msgstr "" +"Stranka je bistvo s katerim poslujete, kot podjetje ali organizacija. " +"Stranka ima lahko več kontaktov ali naslovov, ki so ljudje, kateri delajo za " +"t o podjetje. Lahko uporabite zavihek zgodovina, za spremljanje vseh " +"transakcij stranke, prodajna naročila, e-pošta, priložnosti, pritožbe, itd. " +"Če uporabljate e-poštni prehod, vtičnik Outlook ali Thunderbird, ne pozabite " +"registrirati e-pošte vsakemu kontaktu, tako da bo prehod avtomatsko pripel e-" +"pošte k pravemu partnerju." #. module: base #: field:ir.actions.report.xml,name:0 @@ -3516,7 +3670,7 @@ msgstr "" #: field:workflow,name:0 #: field:workflow.activity,name:0 msgid "Name" -msgstr "Naziv" +msgstr "Ime" #. module: base #: help:ir.actions.act_window,multi:0 @@ -3524,6 +3678,8 @@ msgid "" "If set to true, the action will not be displayed on the right toolbar of a " "form view" msgstr "" +"Če je nastavljeno na true, dejanje ne bo prikazano v desni orodni vrstici " +"pogleda obrazca." #. module: base #: model:res.country,name:base.ms @@ -3537,6 +3693,8 @@ msgid "" "The Selection Options expression is not a valid Pythonic expression.Please " "provide an expression in the [('key','Label'), ...] format." msgstr "" +"Izraz možnosti izražanja ni veljaven Pythonic izraza. Prosim navedite izraz " +"v [(\"ključ\", \"oznaka\"), ...] obliki." #. module: base #: model:ir.ui.menu,name:base.menu_translation_app @@ -3550,6 +3708,8 @@ msgid "" "The user's timezone, used to perform timezone conversions between the server " "and the client." msgstr "" +"Uporabniški časovni pas, uporabljen za pretvorbo časovnega pasa med " +"strežnikom in klientom." #. module: base #: field:ir.module.module,demo:0 @@ -3559,12 +3719,12 @@ msgstr "Predstavitveni podatki" #. module: base #: selection:base.language.install,lang:0 msgid "English (UK)" -msgstr "" +msgstr "Angleščina (Združeno kraljestvo)" #. module: base #: selection:base.language.install,lang:0 msgid "Japanese / 日本語" -msgstr "" +msgstr "Japonsko / 日本語" #. module: base #: help:workflow.transition,act_from:0 @@ -3572,11 +3732,13 @@ msgid "" "Source activity. When this activity is over, the condition is tested to " "determine if we can start the ACT_TO activity." msgstr "" +"Vir dejavnost. Ko je ta dejavnost končana je pogoj preizkušen, da se " +"ugotovi, ali bomo lahko začeli dejavnost ACT_TO." #. module: base #: model:res.partner.category,name:base.res_partner_category_3 msgid "Starter Partner" -msgstr "" +msgstr "Začetni partner" #. module: base #: help:ir.model.fields,relation_field:0 @@ -3584,6 +3746,8 @@ msgid "" "For one2many fields, the field on the target model that implement the " "opposite many2one relationship" msgstr "" +"Za one2many polja, v polje na ciljni model, ki izvajajo nasprotno odnos " +"many2one" #. module: base #: model:ir.model,name:base.model_ir_actions_act_window_view @@ -3598,12 +3762,12 @@ msgstr "Splet" #. module: base #: selection:base.language.install,lang:0 msgid "English (CA)" -msgstr "" +msgstr "Angleško (CA)" #. module: base #: model:ir.model,name:base.model_publisher_warranty_contract msgid "publisher_warranty.contract" -msgstr "" +msgstr "publisher_warranty.contract" #. module: base #: model:res.country,name:base.et @@ -3613,12 +3777,12 @@ msgstr "Etiopija" #. module: base #: help:res.country.state,code:0 msgid "The state code in three chars.\n" -msgstr "" +msgstr "Koda zvezne države v treh znakih.\n" #. module: base #: model:res.country,name:base.sj msgid "Svalbard and Jan Mayen Islands" -msgstr "" +msgstr "Svalbardovi in Jan Mayenovi otoki" #. module: base #: model:ir.model,name:base.model_ir_actions_wizard @@ -3639,17 +3803,17 @@ msgstr "Združi po" #: view:res.config:0 #: view:res.config.installer:0 msgid "title" -msgstr "" +msgstr "naslov" #. module: base #: model:ir.model,name:base.model_base_language_install msgid "Install Language" -msgstr "" +msgstr "Namesti jezik" #. module: base #: view:ir.translation:0 msgid "Translation" -msgstr "" +msgstr "Prevod" #. module: base #: selection:res.request,state:0 @@ -3669,34 +3833,34 @@ msgstr "Lastnost 'on_delete' za za 'many2one' polja" #. module: base #: field:ir.actions.server,write_id:0 msgid "Write Id" -msgstr "" +msgstr "Id zapisa" #. module: base #: model:ir.ui.menu,name:base.menu_product msgid "Products" -msgstr "" +msgstr "Izdelki" #. module: base #: field:ir.actions.act_window,domain:0 #: field:ir.filters,domain:0 msgid "Domain Value" -msgstr "" +msgstr "Vrednost domene" #. module: base #: view:ir.actions.server:0 msgid "SMS Configuration" -msgstr "" +msgstr "SMS konfiguracija" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (BO) / Español (BO)" -msgstr "" +msgstr "Špansko (BO) / Español (BO)" #. module: base #: model:ir.actions.act_window,name:base.ir_access_act #: model:ir.ui.menu,name:base.menu_ir_access_act msgid "Access Controls List" -msgstr "" +msgstr "Seznam kontrole dostopa" #. module: base #: model:res.country,name:base.um @@ -3707,7 +3871,7 @@ msgstr "" #: field:res.partner.bank,state:0 #: field:res.partner.bank.type.field,bank_type_id:0 msgid "Bank Type" -msgstr "" +msgstr "Vrsta banke" #. module: base #: code:addons/base/res/res_user.py:58 @@ -3738,11 +3902,13 @@ msgstr "" msgid "" "Unable to process module \"%s\" because an external dependency is not met: %s" msgstr "" +"Ni mogoče procesirati modula \"%s\", ker zunanja odvisnost ni izpolnjena: %s" #. module: base #: view:publisher_warranty.contract.wizard:0 msgid "Please enter the serial key provided in your contract document:" msgstr "" +"Prosim vnestite serijski ključ, ki je naveden na vašem dokumentu pogodbe" #. module: base #: view:workflow.activity:0 @@ -3754,23 +3920,23 @@ msgstr "Začetek poteka dela" #: code:addons/__init__.py:834 #, python-format msgid "module base cannot be loaded! (hint: verify addons-path)" -msgstr "" +msgstr "osnova modula ne more biti naložena (namig: preverite pod dodatkov)" #. module: base #: view:res.partner.bank:0 msgid "Bank Account Owner" -msgstr "" +msgstr "Lastnik bančnega računa" #. module: base #: model:ir.actions.act_window,name:base.act_values_form msgid "Client Actions Connections" -msgstr "" +msgstr "Povezave dejanj klienta" #. module: base #: field:ir.attachment,res_name:0 #: field:ir.ui.view_sc,resource:0 msgid "Resource Name" -msgstr "Naziv resursa" +msgstr "Ime vira" #. module: base #: selection:ir.cron,interval_type:0 @@ -3797,11 +3963,14 @@ msgid "" "form, signal tests the name of the pressed button. If signal is NULL, no " "button is necessary to validate this transition." msgstr "" +"Ko operacija transakcije pride iz pritisnjenega gumba v obrazcu klienta, " +"signal testira ime pritisnjenega gumba. Če je signal NULL, ni potreben gumb " +"za preverjanje transakcije." #. module: base #: help:multi_company.default,object_id:0 msgid "Object affected by this rule" -msgstr "" +msgstr "To pravilo vpliva na predmet" #. module: base #: report:ir.module.reference.graph:0 @@ -3811,17 +3980,17 @@ msgstr "Imenik" #. module: base #: field:wizard.ir.model.menu.create,name:0 msgid "Menu Name" -msgstr "Naziv menuja" +msgstr "Ime Menija" #. module: base #: view:ir.module.module:0 msgid "Author Website" -msgstr "" +msgstr "Avtorjeva spletna stran" #. module: base #: view:ir.attachment:0 msgid "Month" -msgstr "" +msgstr "Mesec" #. module: base #: model:res.country,name:base.my @@ -3832,7 +4001,7 @@ msgstr "Malezija" #: view:base.language.install:0 #: model:ir.actions.act_window,name:base.action_view_base_language_install msgid "Load Official Translation" -msgstr "" +msgstr "Naloži uraden prevod" #. module: base #: model:ir.model,name:base.model_res_request_history @@ -3842,7 +4011,7 @@ msgstr "res.request.history" #. module: base #: view:ir.actions.server:0 msgid "Client Action Configuration" -msgstr "" +msgstr "Nastavitve klientovih dejanj" #. module: base #: model:ir.model,name:base.model_res_partner_address @@ -3856,11 +4025,13 @@ msgid "" "Whether values for this field can be translated (enables the translation " "mechanism for that field)" msgstr "" +"Ali so lahko te vrednosti za to polje prevedene (omogoči prevajalni " +"mehanizem za to polje)" #. module: base #: view:res.lang:0 msgid "%S - Seconds [00,61]." -msgstr "" +msgstr "%S - Sekund [00,61]" #. module: base #: model:res.country,name:base.cv @@ -3870,7 +4041,7 @@ msgstr "Zelenortski otoki" #. module: base #: view:base.module.import:0 msgid "Select module package to import (.zip file):" -msgstr "" +msgstr "Izberite paket modula za uvoz (.zip datoteka)" #. module: base #: model:ir.actions.act_window,name:base.act_res_partner_event @@ -3889,13 +4060,14 @@ msgstr "ir.actions.url" #. module: base #: model:res.widget,title:base.currency_converter_widget msgid "Currency Converter" -msgstr "" +msgstr "Pretvornik valik" #. module: base #: code:addons/orm.py:156 #, python-format msgid "Wrong ID for the browse record, got %r, expected an integer." msgstr "" +"Napačen ID za brskanje zapisa, dobljen %r, pričakovano celo številko." #. module: base #: model:ir.actions.act_window,name:base.action_partner_addess_tree @@ -3911,7 +4083,7 @@ msgstr "Število dodanih modulov" #. module: base #: view:res.currency:0 msgid "Price Accuracy" -msgstr "" +msgstr "Natančnost cene" #. module: base #: selection:base.language.install,lang:0 @@ -3922,7 +4094,7 @@ msgstr "" #: view:res.config:0 #: view:res.config.installer:0 msgid "vsep" -msgstr "" +msgstr "vsep" #. module: base #: selection:base.language.install,lang:0 @@ -3933,17 +4105,17 @@ msgstr "" #: code:addons/orm.py:1049 #, python-format msgid "The create method is not implemented on this object !" -msgstr "Metoda 'create' ni implementirana za ta objekt." +msgstr "Metoda 'create' ni implementirana za ta predmet!" #. module: base #: field:workflow.triggers,workitem_id:0 msgid "Workitem" -msgstr "" +msgstr "Postavka dela" #. module: base #: view:ir.actions.todo:0 msgid "Set as Todo" -msgstr "" +msgstr "Nastavi na Je treba opraviti" #. module: base #: field:ir.actions.act_window.view,act_window_id:0 @@ -3954,7 +4126,7 @@ msgstr "" #: selection:ir.values,key:0 #: view:res.users:0 msgid "Action" -msgstr "Akcija" +msgstr "Dejanje" #. module: base #: view:ir.actions.server:0 @@ -3969,22 +4141,22 @@ msgstr "ir.cron" #. module: base #: view:ir.rule:0 msgid "Combination of rules" -msgstr "" +msgstr "Kombinacija pravil" #. module: base #: view:ir.sequence:0 msgid "Current Year without Century: %(y)s" -msgstr "" +msgstr "Trenutno leto brez stoletja: %(y)s" #. module: base #: field:ir.actions.server,trigger_obj_id:0 msgid "Trigger On" -msgstr "" +msgstr "Sprožilec vključen" #. module: base #: sql_constraint:ir.rule:0 msgid "Rule must have at least one checked access right !" -msgstr "" +msgstr "Pravilo mora imet vsaj eno označeno pravilo dostopa!" #. module: base #: model:res.country,name:base.fj @@ -4016,7 +4188,7 @@ msgstr "Zgodovina zahteve" #: field:ir.module.module,menus_by_module:0 #: view:res.groups:0 msgid "Menus" -msgstr "Menuji" +msgstr "Meniji" #. module: base #: selection:base.language.install,lang:0 @@ -4038,17 +4210,17 @@ msgstr "Ustvari dejanje" #: model:ir.model,name:base.model_ir_model #: model:ir.ui.menu,name:base.ir_model_model_menu msgid "Objects" -msgstr "Objekti" +msgstr "Predmeti" #. module: base #: field:res.lang,time_format:0 msgid "Time Format" -msgstr "Oblika zapisa časa" +msgstr "Oblika časa" #. module: base #: view:ir.module.module:0 msgid "Defined Reports" -msgstr "" +msgstr "Opredeljena poročila" #. module: base #: view:ir.actions.report.xml:0 @@ -4076,7 +4248,7 @@ msgstr "Delni potek" #. module: base #: model:ir.model,name:base.model_res_config msgid "res.config" -msgstr "" +msgstr "res.config" #. module: base #: field:workflow.transition,signal:0 @@ -4099,17 +4271,17 @@ msgstr "" #. module: base #: field:ir.cron,doall:0 msgid "Repeat Missed" -msgstr "" +msgstr "Zgrešene ponovitve" #. module: base #: help:ir.actions.server,state:0 msgid "Type of the Action that is to be executed" -msgstr "" +msgstr "Vrsta dejanja, ki bo izvršeno" #. module: base #: field:ir.server.object.lines,server_id:0 msgid "Object Mapping" -msgstr "Preslikava objekta" +msgstr "Preslikava predmeta" #. module: base #: help:res.currency,rate:0 @@ -4127,29 +4299,30 @@ msgstr "Združeno kraljestvo" #: view:res.config.users:0 #: view:res.config.view:0 msgid "res_config_contents" -msgstr "" +msgstr "res_config_contents" #. module: base #: help:res.partner.category,active:0 msgid "The active field allows you to hide the category without removing it." msgstr "" +"Polje dejanja vam dovoljuje skrivanje kategorije brez, da bi jo odstranili." #. module: base #: report:ir.module.reference.graph:0 msgid "Object:" -msgstr "Objekt:" +msgstr "Predmet:" #. module: base #: model:res.country,name:base.bw msgid "Botswana" -msgstr "" +msgstr "Botsvana" #. module: base #: model:ir.actions.act_window,name:base.action_partner_title_partner #: model:ir.ui.menu,name:base.menu_partner_title_partner #: view:res.partner.title:0 msgid "Partner Titles" -msgstr "" +msgstr "Nazivi partnerja" #. module: base #: help:ir.actions.act_window,auto_refresh:0 @@ -4159,7 +4332,7 @@ msgstr "Dodaj samoosvežitev k pogledu" #. module: base #: help:res.partner,employee:0 msgid "Check this box if the partner is an Employee." -msgstr "" +msgstr "Označi to polje, če je partner zaposlen" #. module: base #: field:ir.actions.report.xml,report_rml_content:0 @@ -4171,7 +4344,7 @@ msgstr "RML vsebina" #: model:ir.actions.act_window,name:base.action_workflow_workitem_form #: model:ir.ui.menu,name:base.menu_workflow_workitem msgid "Workitems" -msgstr "" +msgstr "Predmeti dela" #. module: base #: field:base.language.export,advice:0 @@ -4190,11 +4363,13 @@ msgid "" "You cannot perform this operation. New Record Creation is not allowed for " "this object as this object is for reporting purpose." msgstr "" +"Ne morete izvesti te operacije. Ustvaritev novega zapisa ni dovoljeno za ta " +"predemet, ker je ta predmet namenjen samo za poročanje." #. module: base #: view:base.language.import:0 msgid "- module,type,name,res_id,src,value" -msgstr "" +msgstr "- module,type,name,res_id,src,value" #. module: base #: selection:base.language.install,lang:0 @@ -4207,11 +4382,13 @@ msgid "" "Provide the field name where the record id is stored after the create " "operations. If it is empty, you can not track the new record." msgstr "" +"Navedite ime polja kjer je id zapisa shranjen po operaciji kreacije. Če je " +"prazen, ne morete slediti novega zapisa." #. module: base #: help:ir.model.fields,relation:0 msgid "For relationship fields, the technical name of the target model" -msgstr "" +msgstr "Za sorodna polja, tehnično ime ciljnega modela" #. module: base #: selection:base.language.install,lang:0 @@ -4226,43 +4403,43 @@ msgstr "Podedovan pogled" #. module: base #: view:ir.translation:0 msgid "Source Term" -msgstr "" +msgstr "Izraz izvora" #. module: base #: model:ir.ui.menu,name:base.menu_main_pm msgid "Project" -msgstr "" +msgstr "Projekt" #. module: base #: field:ir.ui.menu,web_icon_hover_data:0 msgid "Web Icon Image (hover)" -msgstr "" +msgstr "Slika spletne ikone (hover)" #. module: base #: view:base.module.import:0 msgid "Module file successfully imported!" -msgstr "" +msgstr "Datoteka modula je bila uspešno uvožena!" #. module: base #: selection:ir.actions.todo,state:0 msgid "Cancelled" -msgstr "" +msgstr "Preklicano" #. module: base #: view:res.config.users:0 msgid "Create User" -msgstr "" +msgstr "Ustvari uporabnika" #. module: base #: view:partner.clear.ids:0 msgid "Want to Clear Ids ? " -msgstr "" +msgstr "Želite počistiti Id-je? " #. module: base #: field:publisher_warranty.contract,name:0 #: field:publisher_warranty.contract.wizard,name:0 msgid "Serial Key" -msgstr "" +msgstr "Serijski ključ" #. module: base #: selection:res.request,priority:0 @@ -4272,12 +4449,12 @@ msgstr "Nizka" #. module: base #: model:ir.ui.menu,name:base.menu_audit msgid "Audit" -msgstr "" +msgstr "Pregled računov" #. module: base #: model:res.country,name:base.lc msgid "Saint Lucia" -msgstr "" +msgstr "Sveta Lucija" #. module: base #: view:publisher_warranty.contract:0 @@ -4287,12 +4464,12 @@ msgstr "Vzdrežvalna pogodba" #. module: base #: help:ir.actions.server,trigger_obj_id:0 msgid "Select the object from the model on which the workflow will executed." -msgstr "" +msgstr "Izberite predmet iz modela na katerem bo delovni proces izvršen." #. module: base #: field:res.partner,employee:0 msgid "Employee" -msgstr "" +msgstr "Zaposleni" #. module: base #: field:ir.model.access,perm_create:0 @@ -4302,34 +4479,34 @@ msgstr "Ustvari dostop" #. module: base #: field:res.partner.address,state_id:0 msgid "Fed. State" -msgstr "" +msgstr "Zvezna država" #. module: base #: field:ir.actions.server,copy_object:0 msgid "Copy Of" -msgstr "" +msgstr "Kopija" #. module: base #: field:ir.model,osv_memory:0 msgid "In-memory model" -msgstr "" +msgstr "Model v spominu" #. module: base #: view:partner.clear.ids:0 msgid "Clear Ids" -msgstr "" +msgstr "Počisti Id-je" #. module: base #: model:res.country,name:base.io msgid "British Indian Ocean Territory" -msgstr "Britanska ozemlja v Indijskem oceanu" +msgstr "Britansko ozemlje v indijskem oceanu" #. module: base #: field:res.config.users,view:0 #: field:res.config.view,view:0 #: field:res.users,view:0 msgid "Interface" -msgstr "" +msgstr "Vmesnik" #. module: base #: view:ir.actions.server:0 @@ -4339,7 +4516,7 @@ msgstr "Preslikava polj" #. module: base #: view:publisher_warranty.contract:0 msgid "Refresh Validation Dates" -msgstr "" +msgstr "Osveži datume preverjanja" #. module: base #: view:ir.model:0 @@ -4395,7 +4572,7 @@ msgstr "Ni implementirano" #. module: base #: model:ir.model,name:base.model_res_widget_user msgid "res.widget.user" -msgstr "" +msgstr "res.widget.user" #. module: base #: field:res.partner.category,complete_name:0 @@ -4405,18 +4582,18 @@ msgstr "Polno ime" #. module: base #: view:base.module.configuration:0 msgid "_Ok" -msgstr "" +msgstr "_V redu" #. module: base #: help:ir.filters,user_id:0 msgid "False means for every user" -msgstr "" +msgstr "False pomeni za vsakega uporabnika" #. module: base #: code:addons/base/module/module.py:198 #, python-format msgid "The name of the module must be unique !" -msgstr "" +msgstr "Ime modula mora biti edinstven!" #. module: base #: model:res.country,name:base.mz @@ -4426,7 +4603,7 @@ msgstr "Mozambik" #. module: base #: model:ir.ui.menu,name:base.menu_project_long_term msgid "Long Term Planning" -msgstr "" +msgstr "Dolgoročno načrtovanje" #. module: base #: field:ir.actions.server,message:0 @@ -4439,13 +4616,13 @@ msgstr "Sporočilo" #. module: base #: field:ir.actions.act_window.view,multi:0 msgid "On Multiple Doc." -msgstr "" +msgstr "Na večih dokumentih" #. module: base #: view:res.partner:0 #: field:res.partner,user_id:0 msgid "Salesman" -msgstr "" +msgstr "Prodajalec" #. module: base #: field:res.partner,address:0 @@ -4459,11 +4636,12 @@ msgstr "Stiki" msgid "" "Unable to delete this document because it is used as a default property" msgstr "" +"Ne morem izbrisati tega dokumenta, ker se uporablja kot privzeta lastnost" #. module: base #: view:res.widget.wizard:0 msgid "Add" -msgstr "" +msgstr "Dodaj" #. module: base #: view:base.module.upgrade:0 @@ -4475,7 +4653,7 @@ msgstr "Izvedi planirane nadgradnje" #. module: base #: view:res.widget:0 msgid "Widgets" -msgstr "" +msgstr "Gradniki" #. module: base #: model:res.country,name:base.cz @@ -4485,7 +4663,7 @@ msgstr "Češka republika" #. module: base #: view:res.widget.wizard:0 msgid "Widget Wizard" -msgstr "" +msgstr "Čarovnik gradnikov" #. module: base #: model:ir.actions.act_window,help:base.act_ir_actions_todo_form @@ -4494,6 +4672,9 @@ msgid "" "OpenERP. They are launched during the installation of new modules, but you " "can choose to restart some wizards manually from this menu." msgstr "" +"Konfiguracijski čarovniki se uporabljajo za konfiguracijo novega primerka " +"OpenERP. Ti se zaženejo med namestitvijo novih modulov, vendar pa se lahko " +"odločite, da ponovno zaženete nekaj čarovnikov ročno iz tega menija." #. module: base #: code:addons/base/res/res_user.py:206 @@ -4502,17 +4683,19 @@ msgid "" "Please use the change password wizard (in User Preferences or User menu) to " "change your own password." msgstr "" +"Prosim, uporabite ta čarovnik za spreminjanje glesa (v Uporabniških " +"nastavitvah ali meniju Uporabnik), za spremembo vašega gesla." #. module: base #: code:addons/orm.py:1350 #, python-format msgid "Insufficient fields for Calendar View!" -msgstr "" +msgstr "Premalo pol za pogled koledarja!" #. module: base #: selection:ir.property,type:0 msgid "Integer" -msgstr "" +msgstr "Celo število" #. module: base #: help:ir.actions.report.xml,report_rml:0 @@ -4520,12 +4703,14 @@ msgid "" "The path to the main report file (depending on Report Type) or NULL if the " "content is in another data field" msgstr "" +"Pot do datoteke glavnega poročila (odvisno od vrste poročila) ali NULL, če " +"je vsebina v drugem polju podatkov" #. module: base #: help:res.config.users,company_id:0 #: help:res.users,company_id:0 msgid "The company this user is currently working for." -msgstr "" +msgstr "Podjetje, za katerega trenutno dela ta uporabnik." #. module: base #: model:ir.model,name:base.model_wizard_ir_model_menu_create @@ -4540,7 +4725,7 @@ msgstr "Prehod" #. module: base #: field:res.groups,menu_access:0 msgid "Access Menu" -msgstr "" +msgstr "Meni dostopa" #. module: base #: model:res.country,name:base.na @@ -4555,12 +4740,12 @@ msgstr "Mongolija" #. module: base #: view:ir.module.module:0 msgid "Created Menus" -msgstr "" +msgstr "Ustvarjeni meniji" #. module: base #: selection:ir.ui.view,type:0 msgid "mdx" -msgstr "" +msgstr "mdx" #. module: base #: model:res.country,name:base.bi @@ -4581,12 +4766,12 @@ msgstr "Zapri" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (MX) / Español (MX)" -msgstr "" +msgstr "Špansko (MX) / Español (MX)" #. module: base #: view:res.log:0 msgid "My Logs" -msgstr "" +msgstr "Moji dnevniki" #. module: base #: model:res.country,name:base.bt @@ -4596,7 +4781,7 @@ msgstr "Butan" #. module: base #: help:ir.sequence,number_next:0 msgid "Next number of this sequence" -msgstr "" +msgstr "Naslednja številka tega zaporedja" #. module: base #: model:res.partner.category,name:base.res_partner_category_11 @@ -4611,12 +4796,12 @@ msgstr "To okno" #. module: base #: view:publisher_warranty.contract:0 msgid "Publisher Warranty Contracts" -msgstr "" +msgstr "Pogodbe založniške garancije" #. module: base #: help:res.log,name:0 msgid "The logging message." -msgstr "" +msgstr "Prijavno sporočilo." #. module: base #: field:base.language.export,format:0 @@ -4626,7 +4811,7 @@ msgstr "Oblika datoteke" #. module: base #: field:res.lang,iso_code:0 msgid "ISO code" -msgstr "" +msgstr "ISO koda" #. module: base #: model:ir.model,name:base.model_res_config_view @@ -4637,12 +4822,12 @@ msgstr "res.config.view" #: view:res.log:0 #: field:res.log,read:0 msgid "Read" -msgstr "" +msgstr "Branje" #. module: base #: sql_constraint:res.country:0 msgid "The name of the country must be unique !" -msgstr "" +msgstr "Ime države mora biti edinstveno!" #. module: base #: model:ir.actions.act_window,help:base.action_country_state @@ -4651,11 +4836,13 @@ msgid "" "federal states you are working on from here. Each state is attached to one " "country." msgstr "" +"Če delate na ameriškem trgu, lahko tukaj upravljate različne zvezne dežele " +"na katerih delatej. Vsako stanje je vezano na eno državo." #. module: base #: view:workflow.workitem:0 msgid "Workflow Workitems" -msgstr "Elementi poteka dela" +msgstr "Elementi delovnih procesov" #. module: base #: model:res.country,name:base.vc @@ -4682,13 +4869,13 @@ msgstr "Polja" #. module: base #: model:ir.actions.act_window,name:base.action_partner_employee_form msgid "Employees" -msgstr "" +msgstr "Zaposleni" #. module: base #: help:res.log,read:0 msgid "" "If this log item has been read, get() should not send it to the client" -msgstr "" +msgstr "Če je bil ta predmet dnevnika prebran, get() ne sme poslati klientu" #. module: base #: field:res.company,rml_header2:0 @@ -4713,6 +4900,10 @@ msgid "" "channels that will be maintained at the creation of a document in the " "system. Some examples of channels can be: Website, Phone Call, Reseller, etc." msgstr "" +"Sledite od kje prihajajo vaše poti in priložnosti z ustvarjanjem " +"specifičnega kanala, ki se bo vzdrževal z ustvarjanjem dokumenta v sistemu. " +"Nekateri primeri kanalov so lahko: Spletna stran, Telefonski klic, " +"Preprodajalec, itd." #. module: base #: model:res.partner.bank.type.field,name:base.bank_normal_field @@ -4791,7 +4982,7 @@ msgstr "Burkina Faso" #. module: base #: selection:ir.actions.todo,state:0 msgid "Skipped" -msgstr "Preskočeno" +msgstr "Izpuščeno" #. module: base #: selection:ir.model.fields,state:0 @@ -4801,7 +4992,7 @@ msgstr "Polje po meri" #. module: base #: field:ir.module.module,web:0 msgid "Has a web component" -msgstr "" +msgstr "Ima spletno komponento" #. module: base #: model:res.country,name:base.cc @@ -4813,17 +5004,17 @@ msgstr "Kokosovi (Keelingovi) otoki" #: selection:base.module.import,state:0 #: selection:base.module.update,state:0 msgid "init" -msgstr "" +msgstr "init" #. module: base #: view:res.lang:0 msgid "11. %U or %W ==> 48 (49th week)" -msgstr "" +msgstr "11. %U ali %w ==> 48 (49 teden)" #. module: base #: model:ir.model,name:base.model_res_partner_bank_type_field msgid "Bank type fields" -msgstr "" +msgstr "Polja vrste banke" #. module: base #: selection:base.language.install,lang:0 @@ -4838,11 +5029,14 @@ msgid "" "\n" "This addon is already installed on your system" msgstr "" +"\n" +"\n" +"Ta dodatek je že nameščen na vaš sistem" #. module: base #: help:ir.cron,interval_number:0 msgid "Repeat every x." -msgstr "" +msgstr "Ponovi vsakih x." #. module: base #: wizard_view:server.action.create,step_1:0 @@ -4858,7 +5052,7 @@ msgstr "1cm 28cm 20cm 28cm" #. module: base #: field:ir.module.module,maintainer:0 msgid "Maintainer" -msgstr "" +msgstr "Vzdrževalec" #. module: base #: field:ir.sequence,suffix:0 @@ -4883,17 +5077,17 @@ msgstr "E-pošta pošiljatelja" #. module: base #: field:ir.default,field_name:0 msgid "Object Field" -msgstr "" +msgstr "Polje predmeta" #. module: base #: selection:base.language.install,lang:0 msgid "Spanish (PE) / Español (PE)" -msgstr "" +msgstr "Špansko (PE) / Español (PE)" #. module: base #: selection:base.language.install,lang:0 msgid "French (CH) / Français (CH)" -msgstr "" +msgstr "Francosko (CH) / Français (CH)" #. module: base #: help:res.config.users,action_id:0 @@ -4902,17 +5096,19 @@ msgid "" "If specified, this action will be opened at logon for this user, in addition " "to the standard menu." msgstr "" +"Če je navedeno, bo to dejanje odprto ob prijavi tega uporabnika, poleg " +"standardnega menija." #. module: base #: view:ir.values:0 msgid "Client Actions" -msgstr "" +msgstr "Klientova dejanja" #. module: base #: code:addons/orm.py:1806 #, python-format msgid "The exists method is not implemented on this object !" -msgstr "" +msgstr "Obstoječa metoda ni implementirana v ta predmet!" #. module: base #: code:addons/base/module/module.py:336 @@ -4921,21 +5117,23 @@ msgid "" "You try to upgrade a module that depends on the module: %s.\n" "But this module is not available in your system." msgstr "" +"Poizkušate nadgraditi modul, ki je odvisen od tega modula: %s.\n" +"Ampak ta modul ni dostopen na vašem sistemu." #. module: base #: field:workflow.transition,act_to:0 msgid "Destination Activity" -msgstr "" +msgstr "Dejanja destinacije" #. module: base #: view:ir.values:0 msgid "Connect Events to Actions" -msgstr "" +msgstr "Poveži dogodke dejanjem" #. module: base #: model:ir.model,name:base.model_base_update_translations msgid "base.update.translations" -msgstr "" +msgstr "base.update.translations" #. module: base #: field:ir.module.category,parent_id:0 @@ -4975,12 +5173,12 @@ msgstr "Prekliči odstranitev" #: view:res.partner:0 #: view:res.partner.address:0 msgid "Communication" -msgstr "" +msgstr "Komunikacija" #. module: base #: view:ir.actions.report.xml:0 msgid "RML Report" -msgstr "" +msgstr "RML poročilo" #. module: base #: model:ir.model,name:base.model_ir_server_object_lines @@ -4991,7 +5189,7 @@ msgstr "ir.server.object.lines" #: code:addons/base/module/module.py:531 #, python-format msgid "Module %s: Invalid Quality Certificate" -msgstr "" +msgstr "Modul %s: Neveljavno potrdilo kakovosti" #. module: base #: model:res.country,name:base.kw @@ -5001,7 +5199,7 @@ msgstr "Kuvajt" #. module: base #: field:workflow.workitem,inst_id:0 msgid "Instance" -msgstr "Primerek" +msgstr "Primer" #. module: base #: help:ir.actions.report.xml,attachment:0 @@ -5010,11 +5208,14 @@ msgid "" "Keep empty to not save the printed reports. You can use a python expression " "with the object and time variables." msgstr "" +"To je ime datoteke priloge, ki se uporablja za shranjevanje tiskanja " +"rezultatov. Naj bo prazno, če ne želite shraniti tiskanih poročil. Lahko " +"uporabite python izraz s predmetom in spremenljivk časa." #. module: base #: selection:ir.property,type:0 msgid "Many2One" -msgstr "" +msgstr "Many2One" #. module: base #: model:res.country,name:base.ng @@ -5025,27 +5226,27 @@ msgstr "Nigerija" #: code:addons/base/ir/ir_model.py:250 #, python-format msgid "For selection fields, the Selection Options must be given!" -msgstr "" +msgstr "Za izbrana polja mora biti podana Možnost izbire!" #. module: base #: model:ir.actions.act_window,name:base.action_partner_sms_send msgid "SMS Send" -msgstr "" +msgstr "Pošlji SMS" #. module: base #: field:res.company,user_ids:0 msgid "Accepted Users" -msgstr "" +msgstr "Sprejeti uporabniki" #. module: base #: field:ir.ui.menu,web_icon_data:0 msgid "Web Icon Image" -msgstr "" +msgstr "Slika spletne ikone" #. module: base #: view:ir.values:0 msgid "Values for Event Type" -msgstr "" +msgstr "Vrednosti za vrsto dogodka" #. module: base #: selection:ir.model.fields,select_level:0 @@ -5061,6 +5262,7 @@ msgstr "Hong Kong" #: help:ir.actions.server,name:0 msgid "Easy to Refer action by name e.g. One Sales Order -> Many Invoices" msgstr "" +"Enostavno si oglejte akcije npr. Eno prodajno naročilo -> Več računov" #. module: base #: model:ir.actions.act_window,help:base.action_partner_address_form @@ -5073,6 +5275,13 @@ msgid "" "installed the CRM, with the history tab, you can track all the interactions " "with a partner such as opportunities, emails, or sales orders issued." msgstr "" +"Kupci (imenovani tudi partnerji na drugih področjih sistema), vam pomaga " +"upravljati adresar podjetij, ali so kupci in / ali dobavitelji. Obrazec " +"partnerji vam omogoča spremljanje in zapisovanje vseh potrebnih informacij " +"za interakcijo s svojimi partnerji iz naslova podjetja kot tudi z njihovimi " +"kontakti in pa tudi ceniki, in še veliko več. Če ste namestili CRM, z " +"zavihkom zgodovina, lahko sledite vse interakcije s partnerjem, kot so " +"priložnosti, e-pošte, ali izdanimi prodajnimi nalogi." #. module: base #: model:res.country,name:base.ph @@ -5087,17 +5296,19 @@ msgstr "Maroko" #. module: base #: view:res.lang:0 msgid "2. %a ,%A ==> Fri, Friday" -msgstr "" +msgstr "2. %a, %A ==> Pet, Petek" #. module: base #: field:res.widget,content:0 msgid "Content" -msgstr "" +msgstr "Vsebina" #. module: base #: help:ir.rule,global:0 msgid "If no group is specified the rule is global and applied to everyone" msgstr "" +"Če ni navedena nobena skupina, je potem pravilo globalno in je uveljavljeno " +"za vsakogar" #. module: base #: model:res.country,name:base.td @@ -5112,17 +5323,17 @@ msgstr "workflow.transition" #. module: base #: view:res.lang:0 msgid "%a - Abbreviated weekday name." -msgstr "" +msgstr "%a - skrajšano ime dneva v tednu." #. module: base #: report:ir.module.reference.graph:0 msgid "Introspection report on objects" -msgstr "Intospektivno poročilo o objektih" +msgstr "Introspektivna poročila o predmetih" #. module: base #: model:res.country,name:base.pf msgid "Polynesia (French)" -msgstr "" +msgstr "Polinezija (Francosko)" #. module: base #: model:res.country,name:base.dm @@ -5133,18 +5344,18 @@ msgstr "Dominika" #: sql_constraint:publisher_warranty.contract:0 msgid "" "Your publisher warranty contract is already subscribed in the system !" -msgstr "" +msgstr "Vaša pogodba založniške garancije je že vpisana v sistem!" #. module: base #: help:ir.cron,nextcall:0 msgid "Next planned execution date for this scheduler" -msgstr "" +msgstr "Naslednji načrtovani datum za izvedbo tega razporejevalnika" #. module: base #: help:res.config.users,view:0 #: help:res.users,view:0 msgid "Choose between the simplified interface and the extended one" -msgstr "" +msgstr "Izberite med poenostavljenim vmesnikom ali razširjenim" #. module: base #: model:res.country,name:base.np @@ -5158,11 +5369,13 @@ msgid "" "Invalid value for reference field \"%s\" (last part must be a non-zero " "integer): \"%s\"" msgstr "" +"Neveljavna vrednost za referenčno polje \"%s\" (zadnji del mora biti ne " +"nično celo število): \"%s\"" #. module: base #: help:ir.cron,args:0 msgid "Arguments to be passed to the method. e.g. (uid,)" -msgstr "" +msgstr "Argumenti, ki se prenesejo na metodo. na primer (uid,)" #. module: base #: help:ir.ui.menu,groups_id:0 @@ -5171,13 +5384,16 @@ msgid "" "groups. If this field is empty, OpenERP will compute visibility based on the " "related object's read access." msgstr "" +"Če imate skupine, bo vidnost tega menija osnovana na teh skupinah. Če je to " +"polje prazno, bo OpenERP izračunal vidljivost osnovano na dostopih branja " +"povezanih predmetov." #. module: base #: model:ir.actions.act_window,name:base.action_ui_view_custom #: model:ir.ui.menu,name:base.menu_action_ui_view_custom #: view:ir.ui.view.custom:0 msgid "Customized Views" -msgstr "" +msgstr "Prilagojeni pogledi" #. module: base #: view:partner.sms.send:0 @@ -5187,7 +5403,7 @@ msgstr "Masovno SMS pošiljanje" #. module: base #: view:ir.sequence:0 msgid "Seconde: %(sec)s" -msgstr "" +msgstr "Sekunda: %(sec)s" #. module: base #: model:ir.ui.menu,name:base.menu_view_base_module_update @@ -5200,6 +5416,7 @@ msgstr "Posodobi seznam modulov" msgid "" "Unable to upgrade module \"%s\" because an external dependency is not met: %s" msgstr "" +"Ni mogoče nadgraditi modula \"%s\", ker ne izpolnjuje zunanje odvisnosti: %s" #. module: base #: code:addons/base/res/res_user.py:257 @@ -5210,6 +5427,10 @@ msgid "" "sure to save and close all forms before switching to a different company. " "(You can click on Cancel in the User Preferences now)" msgstr "" +"Ne pozabite, da so dokumenti, ki so trenutno prikazani, morda ne bodo " +"ustrezni, po prehodu na drugo podjetje. Če imate neshranjene spremembe, se " +"prepričajte, da shranite in zaprite vse oblike pred prehodom na drugo " +"podjetje. (Lahko sedaj kliknete Prekliči v Uporabniških nastavitvah)" #. module: base #: view:ir.actions.configuration.wizard:0 @@ -5225,7 +5446,7 @@ msgstr "" #: code:addons/orm.py:158 #, python-format msgid "Object %s does not exists" -msgstr "" +msgstr "Predmet %s ne obstaja" #. module: base #: selection:base.language.install,lang:0 @@ -5235,7 +5456,7 @@ msgstr "Slovenian / slovenščina" #. module: base #: field:ir.actions.report.xml,attachment_use:0 msgid "Reload from Attachment" -msgstr "" +msgstr "Ponovno naloži iz priponke" #. module: base #: model:res.country,name:base.bv @@ -5245,7 +5466,7 @@ msgstr "Bouvetov otok" #. module: base #: field:ir.attachment,name:0 msgid "Attachment Name" -msgstr "Naziv priloge" +msgstr "Ime priponke" #. module: base #: field:base.language.export,data:0 @@ -5261,7 +5482,7 @@ msgstr "Dodaj uporabnika" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install msgid "Module Upgrade Install" -msgstr "" +msgstr "Namestitev nadgranje modula" #. module: base #: model:ir.model,name:base.model_ir_actions_configuration_wizard @@ -5285,7 +5506,7 @@ msgstr "Dobavitelj" #: view:ir.actions.server:0 #: selection:ir.actions.server,state:0 msgid "Multi Actions" -msgstr "" +msgstr "Več dejanj" #. module: base #: view:base.language.export:0 @@ -5297,7 +5518,7 @@ msgstr "_Zapri" #. module: base #: field:multi_company.default,company_dest_id:0 msgid "Default Company" -msgstr "" +msgstr "Privzeto podjetje" #. module: base #: selection:base.language.install,lang:0 @@ -5307,13 +5528,13 @@ msgstr "" #. module: base #: help:ir.ui.view,xml_id:0 msgid "ID of the view defined in xml file" -msgstr "" +msgstr "ID pogleda opredeljenega v xml datoteki" #. module: base #: model:ir.model,name:base.model_base_module_import #: model:ir.ui.menu,name:base.menu_view_base_module_import msgid "Import Module" -msgstr "" +msgstr "Uvozi modul" #. module: base #: model:res.country,name:base.as @@ -5323,17 +5544,17 @@ msgstr "Ameriška Samoa" #. module: base #: help:ir.actions.act_window,res_model:0 msgid "Model name of the object to open in the view window" -msgstr "" +msgstr "Ime modula predmeta za odpiranje v oknu pogleda" #. module: base #: field:res.log,secondary:0 msgid "Secondary Log" -msgstr "" +msgstr "Sekundarni dnevnik" #. module: base #: field:ir.model.fields,selectable:0 msgid "Selectable" -msgstr "" +msgstr "Izberljivo" #. module: base #: view:res.request.link:0 @@ -5355,7 +5576,7 @@ msgstr "Polni ime države" #. module: base #: selection:ir.actions.server,state:0 msgid "Iteration" -msgstr "" +msgstr "Ponovitev" #. module: base #: code:addons/orm.py:3448 @@ -5372,7 +5593,7 @@ msgstr "Združeni arabski Emirati" #. module: base #: model:ir.ui.menu,name:base.menu_crm_case_job_req_main msgid "Recruitment" -msgstr "" +msgstr "Zaposlovanje" #. module: base #: model:res.country,name:base.re @@ -5384,7 +5605,7 @@ msgstr "" #, python-format msgid "" "New column name must still start with x_ , because it is a custom field!" -msgstr "" +msgstr "Novo ime stolpca se mora začeti z x_, ker je polje po meri!" #. module: base #: view:ir.model.access:0 @@ -5417,29 +5638,29 @@ msgstr "Napaka dostopa" #. module: base #: view:res.request:0 msgid "Waiting" -msgstr "" +msgstr "Čakanje" #. module: base #: code:addons/__init__.py:834 #, python-format msgid "Could not load base module" -msgstr "" +msgstr "Ne morem naložiti osnovnega modula" #. module: base #: view:res.lang:0 msgid "8. %I:%M:%S %p ==> 06:25:20 PM" -msgstr "" +msgstr "8. %I:%M:%S %p ==> 06:25:20" #. module: base #: code:addons/orm.py:1803 #, python-format msgid "The copy method is not implemented on this object !" -msgstr "Metoda 'copy' ni implementirana za ta objekt." +msgstr "Metoda 'kopiranja' ni implementirana za ta predmet." #. module: base #: field:res.log,create_date:0 msgid "Creation Date" -msgstr "" +msgstr "Ustvarjeno dne" #. module: base #: view:ir.translation:0 @@ -5449,13 +5670,13 @@ msgstr "Prevodi" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Zapolnitev številke" #. module: base #: view:ir.actions.report.xml:0 msgid "Report" -msgstr "" +msgstr "Poročilo" #. module: base #: model:res.country,name:base.ua @@ -5476,7 +5697,7 @@ msgstr "Kategorija modulov" #. module: base #: view:partner.wizard.ean.check:0 msgid "Ignore" -msgstr "" +msgstr "Prezri" #. module: base #: report:ir.module.reference.graph:0 @@ -5486,7 +5707,7 @@ msgstr "Priročnik" #. module: base #: view:ir.ui.view:0 msgid "Architecture" -msgstr "" +msgstr "Arhitektura" #. module: base #: model:res.country,name:base.ml @@ -5502,6 +5723,11 @@ msgid "" "Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " "be possible to email new users." msgstr "" +"Če je naveden e-poštni naslov, bo uporabniku poslano sporočilo " +"dobrodošlice.\n" +"\n" +"Opozorilo: če \"email_from\" in \"smtp_server\" ni konfigurirana, potem ne " +"bo možno poslati e-pošte novim uporabnikom." #. module: base #: selection:base.language.install,lang:0 @@ -5526,7 +5752,7 @@ msgstr "XSL pot" #. module: base #: model:res.country,name:base.bn msgid "Brunei Darussalam" -msgstr "" +msgstr "Brunej" #. module: base #: view:ir.actions.act_window:0 @@ -5556,17 +5782,17 @@ msgstr "ir.actions.todo" #: code:addons/base/res/res_config.py:94 #, python-format msgid "Couldn't find previous ir.actions.todo" -msgstr "" +msgstr "Ni mogoče najti prejšnjega ir.action.todo" #. module: base #: view:ir.actions.act_window:0 msgid "General Settings" -msgstr "" +msgstr "Splošne nastavitve" #. module: base #: model:ir.ui.menu,name:base.menu_administration_shortcut msgid "Custom Shortcuts" -msgstr "" +msgstr "Bližnjice po meri" #. module: base #: selection:base.language.install,lang:0 @@ -5586,7 +5812,7 @@ msgstr "Belgija" #. module: base #: model:ir.model,name:base.model_osv_memory_autovacuum msgid "osv_memory.autovacuum" -msgstr "" +msgstr "Copy text \t osv_memory.autovacuum" #. module: base #: field:base.language.export,lang:0 @@ -5614,29 +5840,29 @@ msgstr "Gambija" #: view:res.users:0 #: field:res.users,company_ids:0 msgid "Companies" -msgstr "Družbe" +msgstr "Podjetja" #. module: base #: view:res.lang:0 msgid "%H - Hour (24-hour clock) [00,23]." -msgstr "" +msgstr "%H . Ura (24-urna ura) [00,23]" #. module: base #: model:ir.model,name:base.model_res_widget msgid "res.widget" -msgstr "" +msgstr "res.widget" #. module: base #: code:addons/base/ir/ir_model.py:258 #, python-format msgid "Model %s does not exist!" -msgstr "" +msgstr "Model %s ne obstaja!" #. module: base #: code:addons/base/res/res_lang.py:159 #, python-format msgid "You cannot delete the language which is User's Preferred Language !" -msgstr "" +msgstr "Ne morete izbrisati jezika, ker je želeni jezik uporabnika!" #. module: base #: code:addons/fields.py:103 @@ -5649,7 +5875,7 @@ msgstr "Metoda 'get_memory' ni implementirana." #: field:ir.actions.server,code:0 #: selection:ir.actions.server,state:0 msgid "Python Code" -msgstr "Python kod" +msgstr "Python koda" #. module: base #: code:addons/base/module/wizard/base_module_import.py:67 @@ -5660,7 +5886,7 @@ msgstr "Datoteke modula: %s ni mogoče ustvariti." #. module: base #: model:ir.module.module,description:base.module_meta_information msgid "The kernel of OpenERP, needed for all installation." -msgstr "" +msgstr "Kernel OpenERP potreben za vse namestitve." #. module: base #: view:base.language.install:0 @@ -5694,17 +5920,17 @@ msgstr "" #. module: base #: view:ir.model:0 msgid "Custom" -msgstr "" +msgstr "Po meni" #. module: base #: view:res.request:0 msgid "Current" -msgstr "" +msgstr "Trenutno" #. module: base #: model:res.partner.category,name:base.res_partner_category_9 msgid "Components Supplier" -msgstr "" +msgstr "Dobavitelj komponent" #. module: base #: model:ir.actions.act_window,name:base.action_res_users @@ -5731,17 +5957,17 @@ msgstr "Islandija" #: model:ir.actions.act_window,name:base.ir_action_window #: model:ir.ui.menu,name:base.menu_ir_action_window msgid "Window Actions" -msgstr "Okenske akcije" +msgstr "Okenska dejanja" #. module: base #: view:res.lang:0 msgid "%I - Hour (12-hour clock) [01,12]." -msgstr "" +msgstr "%I - Ura (12-urna ura) [01,12]" #. module: base #: selection:publisher_warranty.contract.wizard,state:0 msgid "Finished" -msgstr "" +msgstr "Končano" #. module: base #: model:res.country,name:base.de @@ -5751,12 +5977,12 @@ msgstr "Nemčija" #. module: base #: view:ir.sequence:0 msgid "Week of the year: %(woy)s" -msgstr "" +msgstr "Teden leta: %(woy)s" #. module: base #: model:res.partner.category,name:base.res_partner_category_14 msgid "Bad customers" -msgstr "Slabi kupci" +msgstr "Slabe stranke" #. module: base #: report:ir.module.reference.graph:0 @@ -5774,17 +6000,19 @@ msgid "" "View type: set to 'tree' for a hierarchical tree view, or 'form' for other " "views" msgstr "" +"Vrsta pogleda: nastavljeno na \"drevo\" za hierarhično pogled drevesa,ali " +"\"obrazec\" za druge poglede" #. module: base #: code:addons/base/res/res_config.py:421 #, python-format msgid "Click 'Continue' to configure the next addon..." -msgstr "" +msgstr "Kliknite \"Nadaljuj\" za konfiguracijo naslednjega dodatka..." #. module: base #: field:ir.actions.server,record_id:0 msgid "Create Id" -msgstr "" +msgstr "Ustvari Id" #. module: base #: model:res.country,name:base.hn @@ -5797,6 +6025,7 @@ msgstr "Honduras" msgid "" "Check out this box if you want to always display tips on each menu action" msgstr "" +"Označite to polje, če želite da so namigi prikazani na vsakem dejanju menija" #. module: base #: model:res.country,name:base.eg @@ -5806,29 +6035,31 @@ msgstr "Egipt" #. module: base #: field:ir.rule,perm_read:0 msgid "Apply For Read" -msgstr "" +msgstr "Uveljavi za branje" #. module: base #: help:ir.actions.server,model_id:0 msgid "" "Select the object on which the action will work (read, write, create)." msgstr "" +"Izberite ta predmet na katerem bo delovalo to dejanje (branje, pisanje, " +"ustvarjanje)." #. module: base #: code:addons/base/ir/ir_actions.py:629 #, python-format msgid "Please specify server option --email-from !" -msgstr "" +msgstr "Prosim, navedite možnost strežnika --email-from!" #. module: base #: field:base.language.import,name:0 msgid "Language Name" -msgstr "" +msgstr "Ime jezika" #. module: base #: selection:ir.property,type:0 msgid "Boolean" -msgstr "" +msgstr "Logična vrednost" #. module: base #: view:ir.model:0 @@ -5849,7 +6080,7 @@ msgstr "Opis polj" #: view:res.partner.address:0 #: view:workflow.activity:0 msgid "Group By..." -msgstr "" +msgstr "Združi po ..." #. module: base #: view:ir.model.fields:0 @@ -5878,6 +6109,7 @@ msgid "" "It gives the status if the tip has to be displayed or not when a user " "executes an action" msgstr "" +"Daje status, če mora biti namig prikazan ali ne, ko uporabnik izvede dejanje" #. module: base #: view:ir.model:0 @@ -5934,7 +6166,7 @@ msgstr "Oznaka" #. module: base #: model:ir.model,name:base.model_res_config_installer msgid "res.config.installer" -msgstr "" +msgstr "res.config.installer" #. module: base #: model:res.country,name:base.mc @@ -5957,22 +6189,23 @@ msgstr "Pomoč" msgid "" "If specified, the action will replace the standard menu for this user." msgstr "" +"Če je navedeno, bo dejanje zamenjalo standardni meni za tega uporabnika." #. module: base #: selection:ir.actions.server,state:0 msgid "Write Object" -msgstr "Zapiši objekt" +msgstr "Zapiši predmet" #. module: base #: model:ir.ui.menu,name:base.menu_fundrising msgid "Fund Raising" -msgstr "" +msgstr "Zbiranje sredstev" #. module: base #: model:ir.actions.act_window,name:base.ir_sequence_type #: model:ir.ui.menu,name:base.menu_ir_sequence_type msgid "Sequence Codes" -msgstr "" +msgstr "Kode zaporedja" #. module: base #: selection:base.language.install,lang:0 @@ -5985,6 +6218,8 @@ msgid "" "All pending configuration wizards have been executed. You may restart " "individual wizards via the list of configuration wizards." msgstr "" +"Vsi konfiguracijski čarovniki v teku so bili izvedeni. Ponovno morate " +"zagnati vsak čarovnik preko seznama konfiguracijskih čarovnikov." #. module: base #: wizard_button:server.action.create,step_1,create:0 @@ -5994,12 +6229,12 @@ msgstr "Ustvari" #. module: base #: view:ir.sequence:0 msgid "Current Year with Century: %(year)s" -msgstr "" +msgstr "Trenutno leto s stoletji: %(year)s" #. module: base #: field:ir.exports,export_fields:0 msgid "Export ID" -msgstr "" +msgstr "ID izvoza" #. module: base #: model:res.country,name:base.fr @@ -6009,7 +6244,7 @@ msgstr "Francija" #. module: base #: model:ir.model,name:base.model_res_log msgid "res.log" -msgstr "" +msgstr "res.log" #. module: base #: help:ir.translation,module:0 @@ -6021,7 +6256,7 @@ msgstr "" #: view:workflow.activity:0 #: field:workflow.activity,flow_stop:0 msgid "Flow Stop" -msgstr "Konec poteka dela" +msgstr "Zaustavi delovni proces" #. module: base #: selection:ir.cron,interval_type:0 @@ -6083,6 +6318,8 @@ msgid "" "Select the action that will be executed. Loop action will not be avaliable " "inside loop." msgstr "" +"Izberite dejanje, ki bo izvršeno. Dejanja zanke ne bodo na voljo znotraj " +"zanke." #. module: base #: selection:base.language.install,lang:0 @@ -6097,17 +6334,17 @@ msgstr "res.request" #. module: base #: view:ir.model:0 msgid "In Memory" -msgstr "" +msgstr "V spominu" #. module: base #: view:ir.actions.todo:0 msgid "Todo" -msgstr "" +msgstr "Za narediti" #. module: base #: field:ir.attachment,datas:0 msgid "File Content" -msgstr "" +msgstr "Vsebina datoteke" #. module: base #: model:res.country,name:base.pa @@ -6124,12 +6361,13 @@ msgstr "d.o.o." msgid "" "The group that a user must have to be authorized to validate this transition." msgstr "" +"Skupina, katere uporabnik mora biti avtoriziran, za preverbo tega prehoda." #. module: base #: constraint:res.config.users:0 #: constraint:res.users:0 msgid "The chosen company is not in the allowed companies for this user" -msgstr "" +msgstr "Izbrano podjetje ni v dovoljenih podjetjih za tega uporabnika" #. module: base #: model:res.country,name:base.gi @@ -6139,7 +6377,7 @@ msgstr "Gibraltar" #. module: base #: field:ir.actions.report.xml,report_name:0 msgid "Service Name" -msgstr "" +msgstr "Ime storitve" #. module: base #: model:res.country,name:base.pn @@ -6151,6 +6389,8 @@ msgstr "" msgid "" "We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." msgstr "" +"Svetujemo vam, da ponovno naložite ta zavihek menija, da boste videli nove " +"menije (Ctrl+T nato Ctrl+R)." #. module: base #: model:ir.actions.act_window,name:base.action_rule @@ -6162,31 +6402,31 @@ msgstr "Posnemi pravila" #: field:res.config.users,name:0 #: field:res.users,name:0 msgid "User Name" -msgstr "" +msgstr "Ime uporabnika" #. module: base #: view:ir.sequence:0 msgid "Day of the year: %(doy)s" -msgstr "" +msgstr "Dan tega leta: %(dot)s" #. module: base #: view:ir.model:0 #: view:ir.model.fields:0 #: view:workflow.activity:0 msgid "Properties" -msgstr "Karakteristike" +msgstr "Lastnosti" #. module: base #: help:ir.sequence,padding:0 msgid "" "OpenERP will automatically adds some '0' on the left of the 'Next Number' to " "get the required padding size." -msgstr "" +msgstr "OpenERP bo avtomatično dodak nekatere '0' na levo stran" #. module: base #: view:res.lang:0 msgid "%A - Full weekday name." -msgstr "" +msgstr "%A - polno ime delovnega dne" #. module: base #: selection:ir.cron,interval_type:0 @@ -6196,12 +6436,12 @@ msgstr "Meseci" #. module: base #: field:ir.actions.act_window,search_view:0 msgid "Search View" -msgstr "" +msgstr "Pogled iskanja" #. module: base #: sql_constraint:res.lang:0 msgid "The code of the language must be unique !" -msgstr "" +msgstr "Koda jezika mora biti edinstvena!" #. module: base #: model:ir.actions.act_window,name:base.action_attachment @@ -6216,12 +6456,12 @@ msgstr "Priloge" #: model:ir.ui.menu,name:base.menu_sale_config_sales #: model:ir.ui.menu,name:base.menu_sales msgid "Sales" -msgstr "" +msgstr "Prodaja" #. module: base #: field:ir.actions.server,child_ids:0 msgid "Other Actions" -msgstr "Druge akcije" +msgstr "Druga dejanja" #. module: base #: selection:ir.actions.todo,state:0 @@ -6244,7 +6484,7 @@ msgstr "Dovoljenje za pisanje" #. module: base #: view:res.lang:0 msgid "%m - Month number [01,12]." -msgstr "" +msgstr "%m - številka meseca [01,12]" #. module: base #: field:res.bank,city:0 @@ -6252,7 +6492,7 @@ msgstr "" #: field:res.partner.address,city:0 #: field:res.partner.bank,city:0 msgid "City" -msgstr "Mesto/kraj" +msgstr "Mesto" #. module: base #: model:res.country,name:base.qa @@ -6268,7 +6508,7 @@ msgstr "Italija" #: view:ir.actions.todo:0 #: selection:ir.actions.todo,state:0 msgid "To Do" -msgstr "" +msgstr "Za narediti" #. module: base #: selection:base.language.install,lang:0 @@ -6280,12 +6520,12 @@ msgstr "Estonsko" #: field:res.partner,email:0 #: field:res.users,email:0 msgid "E-mail" -msgstr "" +msgstr "E-pošta" #. module: base #: selection:ir.module.module,license:0 msgid "GPL-3 or later version" -msgstr "" +msgstr "GPL-3 ali naslednje verzije" #. module: base #: field:workflow.activity,action:0 @@ -6295,14 +6535,14 @@ msgstr "Python akcija" #. module: base #: selection:base.language.install,lang:0 msgid "English (US)" -msgstr "" +msgstr "Angleški (ZDA)" #. module: base #: model:ir.actions.act_window,name:base.action_model_data #: view:ir.model.data:0 #: model:ir.ui.menu,name:base.ir_model_data_menu msgid "Object Identifiers" -msgstr "" +msgstr "Identifikatorji predmeta" #. module: base #: model:ir.actions.act_window,help:base.action_partner_title_partner @@ -6310,11 +6550,13 @@ msgid "" "Manage the partner titles you want to have available in your system. The " "partner titles is the legal status of the company: Private Limited, SA, etc." msgstr "" +"Urejanje naslovov partnerjev, ki jih želite imeti dostopne na vašem sistemu. " +"Naslov partnerjev je pravni status podjetja: korporacija, d.d., itd." #. module: base #: view:base.language.export:0 msgid "To browse official translations, you can start with these links:" -msgstr "" +msgstr "Za brskanje po uradnih prevodih, lahko začnete s temi povezavami:" #. module: base #: code:addons/base/ir/ir_model.py:484 @@ -6323,6 +6565,8 @@ msgid "" "You can not read this document (%s) ! Be sure your user belongs to one of " "these groups: %s." msgstr "" +"Ne morete prebrati tega dokumenta (%s)! Bodite prepričani, vaš uporabniški " +"sodi v eno od teh skupin: %s." #. module: base #: view:res.bank:0 @@ -6356,7 +6600,7 @@ msgstr "ir.translation" #. module: base #: view:base.module.update:0 msgid "Module update result" -msgstr "" +msgstr "Rezultat posodobitve modula" #. module: base #: view:workflow.activity:0 @@ -6368,12 +6612,12 @@ msgstr "Aktivnost" #: view:res.partner:0 #: view:res.partner.address:0 msgid "Postal Address" -msgstr "" +msgstr "Poštni naslov" #. module: base #: field:res.company,parent_id:0 msgid "Parent Company" -msgstr "" +msgstr "Krovno podjetje" #. module: base #: selection:base.language.install,lang:0 @@ -6393,7 +6637,7 @@ msgstr "Kongo" #. module: base #: view:res.lang:0 msgid "Examples" -msgstr "Zgledi" +msgstr "Primeri" #. module: base #: field:ir.default,value:0 @@ -6403,7 +6647,7 @@ msgstr "Privzeta vrednost" #. module: base #: model:ir.ui.menu,name:base.menu_tools msgid "Tools" -msgstr "" +msgstr "Orodja" #. module: base #: model:res.country,name:base.kn @@ -6418,6 +6662,9 @@ msgid "" "for the currency: %s \n" "at the date: %s" msgstr "" +"Ni mogoče najti tečaja \n" +"za valuto: %s \n" +"na dan: %s" #. module: base #: model:ir.actions.act_window,help:base.action_ui_view_custom @@ -6425,13 +6672,15 @@ msgid "" "Customized views are used when users reorganize the content of their " "dashboard views (via web client)" msgstr "" +"Prilagojeni pogledi se uporabljajo ko uporabnik reorganizira vsebino " +"njegovega pogleda pregledne plošče (preko spletnega klienta)" #. module: base #: field:ir.model,name:0 #: field:ir.model.fields,model:0 #: field:ir.values,model:0 msgid "Object Name" -msgstr "Naziv objekta" +msgstr "Ime predmeta" #. module: base #: help:ir.actions.server,srcmodel_id:0 @@ -6439,6 +6688,8 @@ msgid "" "Object in which you want to create / write the object. If it is empty then " "refer to the Object field." msgstr "" +"Predmet na katerem želite ustvariti / zapisati predmet. Če je prazno, potem " +"preberite polje Predmeta." #. module: base #: view:ir.module.module:0 @@ -6451,7 +6702,7 @@ msgstr "Ni nameščen" #: view:workflow.activity:0 #: field:workflow.activity,out_transitions:0 msgid "Outgoing Transitions" -msgstr "" +msgstr "Izhodni prehodi" #. module: base #: field:ir.ui.menu,icon:0 @@ -6461,7 +6712,7 @@ msgstr "Ikona" #. module: base #: help:ir.model.fields,model_id:0 msgid "The model this field belongs to" -msgstr "" +msgstr "Model kateremu ta polja pripadajo" #. module: base #: model:res.country,name:base.mq @@ -6471,7 +6722,7 @@ msgstr "" #. module: base #: view:ir.sequence.type:0 msgid "Sequences Type" -msgstr "" +msgstr "Vrsta zaporedja" #. module: base #: model:ir.actions.act_window,name:base.res_request-act @@ -6495,7 +6746,7 @@ msgstr "Ali" #: model:ir.actions.act_window,name:base.res_log_act_window #: model:ir.ui.menu,name:base.menu_res_log_act_window msgid "Client Logs" -msgstr "" +msgstr "Dnevniki klienta" #. module: base #: model:res.country,name:base.al @@ -6514,6 +6765,8 @@ msgid "" "You cannot delete the language which is Active !\n" "Please de-activate the language first." msgstr "" +"Ne morete izbrisati jezika, ki je Aktiven!\n" +"Prosim, najprej deaktivirajte jezik." #. module: base #: view:base.language.install:0 @@ -6522,6 +6775,8 @@ msgid "" "Please be patient, this operation may take a few minutes (depending on the " "number of modules currently installed)..." msgstr "" +"Prosimo, bodite potrpežljivi,ta operacija lahko traja nekaj minut (odvisno " +"od števila modulov trenutno nameščenih) ..." #. module: base #: field:ir.ui.menu,child_id:0 @@ -6533,7 +6788,7 @@ msgstr "" #: code:addons/base/ir/ir_actions.py:716 #, python-format msgid "Problem in configuration `Record Id` in Server Action!" -msgstr "" +msgstr "Problem pri konfiguraciji. 'ID zapisa\" v dejanju strežnika!" #. module: base #: code:addons/orm.py:2306 @@ -6546,12 +6801,12 @@ msgstr "Napaka preverjanja" #: view:base.module.import:0 #: view:base.module.update:0 msgid "Open Modules" -msgstr "" +msgstr "Odprti moduli" #. module: base #: model:ir.actions.act_window,help:base.action_res_bank_form msgid "Manage bank records you want to be used in the system." -msgstr "" +msgstr "Urejanje zapisov banke, katere želite uporabiti v sistemu." #. module: base #: view:base.module.import:0 @@ -6561,7 +6816,7 @@ msgstr "Uvozi modul" #. module: base #: field:ir.actions.server,loop_action:0 msgid "Loop Action" -msgstr "" +msgstr "Dejanje zanke" #. module: base #: help:ir.actions.report.xml,report_file:0 @@ -6569,6 +6824,8 @@ msgid "" "The path to the main report file (depending on Report Type) or NULL if the " "content is in another field" msgstr "" +"Pot do glavnega poročila (odvisno od vrste poročila) ali NULL, če je vsebina " +"na drugem področju" #. module: base #: model:res.country,name:base.la @@ -6586,7 +6843,7 @@ msgstr "E-pošta" #: field:res.config.users,action_id:0 #: field:res.users,action_id:0 msgid "Home Action" -msgstr "" +msgstr "Domače dejanje" #. module: base #: code:addons/custom.py:558 @@ -6595,6 +6852,8 @@ msgid "" "The sum of the data (2nd field) is null.\n" "We can't draw a pie chart !" msgstr "" +"Vsota podatkov (2. polje) je nična.\n" +"Ne moremo narisati pitinega grafa!" #. module: base #: model:ir.ui.menu,name:base.menu_lunch_reporting @@ -6606,7 +6865,7 @@ msgstr "" #: model:ir.ui.menu,name:base.next_id_73 #: model:ir.ui.menu,name:base.reporting_menu msgid "Reporting" -msgstr "" +msgstr "Poročanje" #. module: base #: model:res.country,name:base.tg @@ -6616,28 +6875,28 @@ msgstr "Togo" #. module: base #: selection:ir.module.module,license:0 msgid "Other Proprietary" -msgstr "" +msgstr "Druga lastništva" #. module: base #: selection:workflow.activity,kind:0 msgid "Stop All" -msgstr "Vse ustavi" +msgstr "Ustavi vse" #. module: base #: code:addons/orm.py:412 #, python-format msgid "The read_group method is not implemented on this object !" -msgstr "" +msgstr "Metoda 'bralna_skupina' ni implementirana v ta predmet!" #. module: base #: view:ir.model.data:0 msgid "Updatable" -msgstr "" +msgstr "Možno posodobiti" #. module: base #: view:res.lang:0 msgid "3. %x ,%X ==> 12/05/08, 18:25:20" -msgstr "3. %x ,%X ==> 12/05/08, 18:25:20" +msgstr "3. %x ,%X ==> 12/05/08, 18:25:20" #. module: base #: selection:ir.model.fields,on_delete:0 @@ -6647,7 +6906,7 @@ msgstr "Kaskadno" #. module: base #: field:workflow.transition,group_id:0 msgid "Group Required" -msgstr "" +msgstr "Zahtevana skupina" #. module: base #: view:ir.actions.configuration.wizard:0 @@ -6657,7 +6916,7 @@ msgstr "Naslednji konfiguracijski korak" #. module: base #: field:res.groups,comment:0 msgid "Comment" -msgstr "Pripomba" +msgstr "Opomba" #. module: base #: model:res.country,name:base.ro @@ -6670,22 +6929,24 @@ msgid "" "Enable this if you want to execute missed occurences as soon as the server " "restarts." msgstr "" +"Omogočite to, če želite izvršiti zamujene dogodke, takoj ko se strežnik " +"ponovno zažene." #. module: base #: view:base.module.upgrade:0 msgid "Start update" -msgstr "" +msgstr "Začni posodobitev" #. module: base #: code:addons/base/publisher_warranty/publisher_warranty.py:144 #, python-format msgid "Contract validation error" -msgstr "" +msgstr "Napaka preverjanja pogodbe" #. module: base #: field:res.country.state,name:0 msgid "State Name" -msgstr "Naziv države" +msgstr "Ime države" #. module: base #: field:workflow.activity,join_mode:0 @@ -6707,7 +6968,7 @@ msgstr "ir.actions.report.xml" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_miss msgid "Mss" -msgstr "" +msgstr "Gospodična" #. module: base #: model:ir.model,name:base.model_ir_ui_view @@ -6717,12 +6978,14 @@ msgstr "ir.ui.view" #. module: base #: constraint:res.partner:0 msgid "Error ! You can not create recursive associated members." -msgstr "" +msgstr "Napaka! Ni mogoče rekurzivno kreirati pridruženih članov" #. module: base #: help:res.lang,code:0 msgid "This field is used to set/get locales for user" msgstr "" +"To polje se uporablja za nastavljanje/pridobivanje uporabnikovih jezikovnih " +"nastavitev" #. module: base #: model:res.partner.category,name:base.res_partner_category_2 @@ -6732,7 +6995,7 @@ msgstr "OpenERP partnerji" #. module: base #: model:ir.ui.menu,name:base.menu_hr_manager msgid "HR Manager Dashboard" -msgstr "" +msgstr "Pregledna plošča HR upravitelja" #. module: base #: code:addons/base/module/module.py:253 @@ -6740,11 +7003,13 @@ msgstr "" msgid "" "Unable to install module \"%s\" because an external dependency is not met: %s" msgstr "" +"Ni mogoče namestiti modula \"%s\", ker zunanje odvisnosti niso izpolnjene: " +"%s." #. module: base #: view:ir.module.module:0 msgid "Search modules" -msgstr "" +msgstr "Iskanje modulov" #. module: base #: model:res.country,name:base.by @@ -6759,7 +7024,7 @@ msgstr "Belorusija" #: field:ir.actions.url,name:0 #: field:ir.filters,name:0 msgid "Action Name" -msgstr "Naziv akcije" +msgstr "Ime dejanja" #. module: base #: model:ir.actions.act_window,help:base.action_res_users @@ -6769,6 +7034,10 @@ msgid "" "not connect to the system. You can assign them groups in order to give them " "specific access to the applications they need to use in the system." msgstr "" +"Ustvarite in uredite uporabnike, ki se bodo povezovali na sistem. Uporabnike " +"lahko izključite. Ne bi smelo biti časovno obdobje, v katerem / se ne bo " +"treba povezati s sistemom. Lahko jih dodelite v skupine, ki jim dajo posebne " +"dostope do aplikacij, ki jih potrebujejo za uporabo v sistemu." #. module: base #: selection:res.request,priority:0 @@ -6784,13 +7053,13 @@ msgstr "Naslov 2" #. module: base #: model:ir.actions.act_window,name:base.action_view_base_module_update msgid "Module Update" -msgstr "" +msgstr "Posodobitev modula" #. module: base #: code:addons/base/module/wizard/base_module_upgrade.py:95 #, python-format msgid "Following modules are not installed or unknown: %s" -msgstr "" +msgstr "Naslednji moduli niso nameščeni ali neznano: %s" #. module: base #: view:ir.cron:0 @@ -6819,7 +7088,7 @@ msgstr "Odpri okno" #. module: base #: field:ir.actions.act_window,auto_search:0 msgid "Auto Search" -msgstr "" +msgstr "Avto iskanje" #. module: base #: field:ir.actions.act_window,filter:0 @@ -6829,7 +7098,7 @@ msgstr "Filter" #. module: base #: model:res.partner.title,shortcut:base.res_partner_title_madam msgid "Ms." -msgstr "" +msgstr "Ga." #. module: base #: model:res.country,name:base.ch @@ -6859,31 +7128,31 @@ msgstr "Faktor zaokroževanja" #. module: base #: view:base.language.install:0 msgid "Load" -msgstr "" +msgstr "Naloži" #. module: base #: help:res.config.users,name:0 #: help:res.users,name:0 msgid "The new user's real name, used for searching and most listings" -msgstr "" +msgstr "Pravo ime novega uporabnika, uporabljeno za iskanje in za vse ostalo" #. module: base #: code:addons/osv.py:154 #: code:addons/osv.py:156 #, python-format msgid "Integrity Error" -msgstr "" +msgstr "Napaka integritete" #. module: base #: model:ir.model,name:base.model_ir_wizard_screen msgid "ir.wizard.screen" -msgstr "" +msgstr "Copy text \t ir.wizard.screen" #. module: base #: code:addons/base/ir/ir_model.py:223 #, python-format msgid "Size of the field can never be less than 1 !" -msgstr "" +msgstr "Velikost polja ne more biti manjša od 1" #. module: base #: model:res.country,name:base.so @@ -6893,17 +7162,17 @@ msgstr "Somalija" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Terminated" -msgstr "" +msgstr "Zaključen" #. module: base #: model:res.partner.category,name:base.res_partner_category_13 msgid "Important customers" -msgstr "Pomembni kupci" +msgstr "Uvožene stranke" #. module: base #: view:res.lang:0 msgid "Update Terms" -msgstr "" +msgstr "Pogoji posodobitve" #. module: base #: field:partner.sms.send,mobile_to:0 @@ -6922,28 +7191,28 @@ msgstr "Argumenti" #: code:addons/orm.py:716 #, python-format msgid "Database ID doesn't exist: %s : %s" -msgstr "" +msgstr "ID podatkovne batze ne obstaja: %s : %s" #. module: base #: selection:ir.module.module,license:0 msgid "GPL Version 2" -msgstr "" +msgstr "GPL verzija 2" #. module: base #: selection:ir.module.module,license:0 msgid "GPL Version 3" -msgstr "" +msgstr "GPL verzija 3" #. module: base #: code:addons/orm.py:836 #, python-format msgid "key '%s' not found in selection field '%s'" -msgstr "" +msgstr "ključa '%s' ni mogoče najti med izbranim poljem '%s'" #. module: base #: view:partner.wizard.ean.check:0 msgid "Correct EAN13" -msgstr "" +msgstr "Popravite EAN13" #. module: base #: code:addons/orm.py:2317 @@ -6957,7 +7226,7 @@ msgstr "Vrednost \"%s\" za polje \"%s\" ni na voljo pri izbiri" #: field:res.partner.address,is_customer_add:0 #: model:res.partner.category,name:base.res_partner_category_0 msgid "Customer" -msgstr "Kupec" +msgstr "Stranka" #. module: base #: selection:base.language.install,lang:0 @@ -6973,22 +7242,22 @@ msgstr "Kratek opis" #: field:ir.actions.act_window,context:0 #: field:ir.filters,context:0 msgid "Context Value" -msgstr "Kontekst" +msgstr "Vrednost zveze" #. module: base #: view:ir.sequence:0 msgid "Hour 00->24: %(h24)s" -msgstr "" +msgstr "Ur 00-> 24: 5(h24)s" #. module: base #: field:ir.cron,nextcall:0 msgid "Next Execution Date" -msgstr "" +msgstr "Naslednji datum izvršitve" #. module: base #: help:multi_company.default,field_id:0 msgid "Select field property" -msgstr "" +msgstr "Izberi polje lastnosti" #. module: base #: field:res.request.history,date_sent:0 @@ -7025,7 +7294,7 @@ msgstr "Tunizija" #. module: base #: model:ir.ui.menu,name:base.menu_mrp_root msgid "Manufacturing" -msgstr "" +msgstr "Proizvodnja" #. module: base #: model:res.country,name:base.km @@ -7037,7 +7306,7 @@ msgstr "Komori" #: view:ir.actions.server:0 #: model:ir.ui.menu,name:base.menu_server_action msgid "Server Actions" -msgstr "Strežniške akcije" +msgstr "Dejanja strežnika" #. module: base #: view:ir.module.module:0 @@ -7047,22 +7316,22 @@ msgstr "Prekliči namestitev" #. module: base #: field:ir.model.fields,selection:0 msgid "Selection Options" -msgstr "" +msgstr "Možnosti izbire" #. module: base #: field:res.partner.category,parent_right:0 msgid "Right parent" -msgstr "" +msgstr "Desni starš" #. module: base #: view:res.lang:0 msgid "Legends for Date and Time Formats" -msgstr "" +msgstr "Legenda za obliko datuma in časa" #. module: base #: selection:ir.actions.server,state:0 msgid "Copy Object" -msgstr "" +msgstr "Kopiraj predmet" #. module: base #: code:addons/base/res/res_user.py:581 @@ -7070,12 +7339,13 @@ msgstr "" msgid "" "Group(s) cannot be deleted, because some user(s) still belong to them: %s !" msgstr "" +"Skupin ni mogoče izbrisati, ker jim nekateri uporabniki še kar pripadajo: %s!" #. module: base #: model:ir.actions.act_window,name:base.action_country_state #: model:ir.ui.menu,name:base.menu_country_state_partner msgid "Fed. States" -msgstr "" +msgstr "Zvezne države" #. module: base #: view:ir.model:0 @@ -7114,7 +7384,7 @@ msgstr "Sklic tabele" #: field:res.request.link,object:0 #: field:workflow.triggers,model:0 msgid "Object" -msgstr "Objekt" +msgstr "Predmet" #. module: base #: code:addons/osv.py:151 @@ -7124,6 +7394,9 @@ msgid "" "\n" "[object with reference: %s - %s]" msgstr "" +"\n" +"\n" +"[predmet z referencam: %s - %s]" #. module: base #: model:ir.model,name:base.model_ir_default @@ -7133,19 +7406,19 @@ msgstr "ir.default" #. module: base #: view:ir.sequence:0 msgid "Minute: %(min)s" -msgstr "" +msgstr "Minute: %(min)s" #. module: base #: view:base.update.translations:0 #: model:ir.actions.act_window,name:base.action_wizard_update_translations #: model:ir.ui.menu,name:base.menu_wizard_update_translations msgid "Synchronize Translations" -msgstr "" +msgstr "Sinhroniziraj prevode" #. module: base #: model:ir.ui.menu,name:base.next_id_10 msgid "Scheduler" -msgstr "" +msgstr "Razporejevalnik" #. module: base #: help:ir.cron,numbercall:0 @@ -7153,6 +7426,8 @@ msgid "" "Number of time the function is called,\n" "a negative number indicates no limit" msgstr "" +"Število časa ko je bila klicana ta funkcija,\n" +"negativno število pomeni brez omejitev" #. module: base #: code:addons/base/ir/ir_model.py:331 @@ -7161,11 +7436,13 @@ msgid "" "Changing the type of a column is not yet supported. Please drop it and " "create it again!" msgstr "" +"Spreminjanje vrste stopla še ni podprto. Prosim, izbrišite gain ga na novo " +"ustvarite!" #. module: base #: field:ir.ui.view_sc,user_id:0 msgid "User Ref." -msgstr "Sklic uporabnika" +msgstr "Referenca uporabnika" #. module: base #: code:addons/base/res/res_user.py:580 @@ -7176,7 +7453,7 @@ msgstr "Opozorilo!" #. module: base #: model:res.widget,title:base.google_maps_widget msgid "Google Maps" -msgstr "" +msgstr "Google Maps" #. module: base #: model:ir.ui.menu,name:base.menu_base_config @@ -7192,12 +7469,12 @@ msgstr "Konfiguracija" #. module: base #: model:ir.model,name:base.model_publisher_warranty_contract_wizard msgid "publisher_warranty.contract.wizard" -msgstr "" +msgstr "publisher_warranty.contract.wizard" #. module: base #: field:ir.actions.server,expression:0 msgid "Loop Expression" -msgstr "" +msgstr "Izraz zanke" #. module: base #: field:publisher_warranty.contract,date_start:0 @@ -7207,7 +7484,7 @@ msgstr "Začetni datum" #. module: base #: help:res.partner,website:0 msgid "Website of Partner" -msgstr "" +msgstr "Spletna stran partnerja" #. module: base #: model:res.partner.category,name:base.res_partner_category_5 @@ -7275,18 +7552,18 @@ msgstr "Norveška" #. module: base #: view:res.lang:0 msgid "4. %b, %B ==> Dec, December" -msgstr "" +msgstr "4. %b, %B ==> Dec, December" #. module: base #: view:base.language.install:0 #: model:ir.ui.menu,name:base.menu_view_base_language_install msgid "Load an Official Translation" -msgstr "" +msgstr "Naloži uraden prevod" #. module: base #: view:res.currency:0 msgid "Miscelleanous" -msgstr "" +msgstr "Mešano" #. module: base #: model:res.partner.category,name:base.res_partner_category_10 @@ -7306,7 +7583,7 @@ msgstr "čakajoče" #. module: base #: field:ir.actions.report.xml,report_file:0 msgid "Report file" -msgstr "" +msgstr "Datoteka poročila" #. module: base #: model:ir.model,name:base.model_workflow_triggers @@ -7317,12 +7594,12 @@ msgstr "workflow.triggers" #: code:addons/base/ir/ir_model.py:62 #, python-format msgid "Invalid search criterions" -msgstr "" +msgstr "Neveljaven kriterij iskanja" #. module: base #: view:ir.attachment:0 msgid "Created" -msgstr "" +msgstr "Ustvarjeno" #. module: base #: help:ir.actions.wizard,multi:0 @@ -7330,11 +7607,13 @@ msgid "" "If set to true, the wizard will not be displayed on the right toolbar of a " "form view." msgstr "" +"Če je nastavljeno na true, čarovnik ne bo prikazan na desni orodni vrstici " +"pogleda obrazca." #. module: base #: view:base.language.import:0 msgid "- type,name,res_id,src,value" -msgstr "" +msgstr "- vrsta, ime, res_id, src, vrednost" #. module: base #: model:res.country,name:base.hm @@ -7344,7 +7623,7 @@ msgstr "Heardovi in McDonaldovi otoki" #. module: base #: field:ir.actions.act_window,view_id:0 msgid "View Ref." -msgstr "Sklic pogleda" +msgstr "Referenca pogleda" #. module: base #: selection:ir.translation,type:0 @@ -7367,7 +7646,7 @@ msgstr "Glava izpisa" #: field:ir.actions.url,type:0 #: field:ir.actions.wizard,type:0 msgid "Action Type" -msgstr "Vrsta akcije" +msgstr "Vrsta dejanja" #. module: base #: code:addons/base/module/module.py:268 @@ -7376,18 +7655,20 @@ msgid "" "You try to install module '%s' that depends on module '%s'.\n" "But the latter module is not available in your system." msgstr "" +"Poizkušate naložiti modula '%s', ki je odvisen od modula '%s'.\n" +"Toda ta modul ni na voljo v vašem sistemu." #. module: base #: view:base.language.import:0 #: model:ir.actions.act_window,name:base.action_view_base_import_language #: model:ir.ui.menu,name:base.menu_view_base_import_language msgid "Import Translation" -msgstr "" +msgstr "Uvozi prevod" #. module: base #: field:res.partner.bank.type,field_ids:0 msgid "Type fields" -msgstr "" +msgstr "Vrste polj" #. module: base #: view:ir.module.module:0 @@ -7400,7 +7681,7 @@ msgstr "Kategorija" #: selection:ir.attachment,type:0 #: selection:ir.property,type:0 msgid "Binary" -msgstr "" +msgstr "Binarno" #. module: base #: field:ir.actions.server,sms:0 @@ -7416,12 +7697,12 @@ msgstr "Kostarika" #. module: base #: view:workflow.activity:0 msgid "Conditions" -msgstr "" +msgstr "Pogoji" #. module: base #: model:ir.actions.act_window,name:base.action_partner_other_form msgid "Other Partners" -msgstr "" +msgstr "Ostali partnerji" #. module: base #: model:ir.actions.act_window,name:base.action_currency_form @@ -7433,22 +7714,22 @@ msgstr "Valute" #. module: base #: sql_constraint:res.groups:0 msgid "The name of the group must be unique !" -msgstr "" +msgstr "Ime skupine mora biti edinstveno!" #. module: base #: view:ir.sequence:0 msgid "Hour 00->12: %(h12)s" -msgstr "" +msgstr "Ura 00->12: %(h12)s" #. module: base #: help:res.partner.address,active:0 msgid "Uncheck the active field to hide the contact." -msgstr "Za zakritje kontakta počisti polje 'Aktivno'." +msgstr "Odznačite aktivno polje za skrivanje tega kontakta." #. module: base #: model:ir.model,name:base.model_res_widget_wizard msgid "Add a widget for User" -msgstr "" +msgstr "Dodaj gradnik za uporabnika" #. module: base #: model:res.country,name:base.dk @@ -7469,18 +7750,18 @@ msgstr "workflow.instance" #: code:addons/orm.py:278 #, python-format msgid "Unknown attribute %s in %s " -msgstr "" +msgstr "Neznan atribut %s v %s " #. module: base #: view:res.lang:0 msgid "10. %S ==> 20" -msgstr "" +msgstr "Copy text \t 10. %S ==> 20" #. module: base #: code:addons/fields.py:106 #, python-format msgid "undefined get method !" -msgstr "Nedefinirana metoda 'get'" +msgstr "Nedefinirana metoda 'get'!" #. module: base #: selection:base.language.install,lang:0 @@ -7494,6 +7775,8 @@ msgid "" "Only specify a value if you want to change the user password. This user will " "have to logout and login again!" msgstr "" +"Samo navedite vrednost, če želite spremeniti geslo uporabnika. Uporabnik se " +"bo mora odjaviti in še enkrat prijaviti!" #. module: base #: model:res.partner.title,name:base.res_partner_title_madam @@ -7508,18 +7791,18 @@ msgstr "Estonija" #. module: base #: model:ir.ui.menu,name:base.dashboard msgid "Dashboards" -msgstr "" +msgstr "Pregledna plošča" #. module: base #: help:ir.attachment,type:0 msgid "Binary File or external URL" -msgstr "" +msgstr "Binarna datoteka ali zunanji URL" #. module: base #: field:res.config.users,new_password:0 #: field:res.users,new_password:0 msgid "Change password" -msgstr "" +msgstr "Spremeni geslo" #. module: base #: model:res.country,name:base.nl @@ -7529,7 +7812,7 @@ msgstr "Nizozemska" #. module: base #: model:ir.ui.menu,name:base.next_id_4 msgid "Low Level Objects" -msgstr "" +msgstr "Predmeti nizke ravni" #. module: base #: view:res.company:0 @@ -7554,12 +7837,16 @@ msgid "" "button \"Schedule for Installation\" from the form view, then click on " "\"Apply Scheduled Upgrades\" to migrate your system." msgstr "" +"Lahko namestite nove module, če želite aktivirati nove možnosti, meni, " +"poročila ali podatke v vašem OpenERP-ju. Za namestitev nekaterih modulov, " +"kliknite gumb \"Razporedi za namestitev\" iz pogleda obrazca, potem kliknite " +"na \"Uveljavi posodobitve razporeditve\" za migracijo sistema." #. module: base #: model:ir.ui.menu,name:base.menu_emails #: model:ir.ui.menu,name:base.menu_mail_gateway msgid "Emails" -msgstr "" +msgstr "E-pošta" #. module: base #: model:res.country,name:base.cd @@ -7592,7 +7879,7 @@ msgstr "Število klicev" #: view:base.module.upgrade:0 #: field:base.module.upgrade,module_info:0 msgid "Modules to update" -msgstr "Moduli za ažurirat" +msgstr "Moduli za posodobiti" #. module: base #: help:ir.actions.server,sequence:0 @@ -7600,6 +7887,8 @@ msgid "" "Important when you deal with multiple actions, the execution order will be " "decided based on this, low number is higher priority." msgstr "" +"Pomembno, ko se ukvarjate z več dejanji, se bo izvršba odločala na podlagi " +"tega, da ima majhno število večjo prednost." #. module: base #: field:ir.actions.report.xml,header:0 @@ -7624,27 +7913,27 @@ msgstr "Hrvaščina" #. module: base #: field:base.language.install,overwrite:0 msgid "Overwrite Existing Terms" -msgstr "" +msgstr "Prepiši obstoječe pogoje" #. module: base #: help:ir.actions.server,code:0 msgid "Python code to be executed" -msgstr "" +msgstr "Python koda, ki bo izvršena" #. module: base #: sql_constraint:res.country:0 msgid "The code of the country must be unique !" -msgstr "" +msgstr "Koda države mora biti edinstvena!" #. module: base #: selection:ir.module.module.dependency,state:0 msgid "Uninstallable" -msgstr "Nenamestljiv" +msgstr "" #. module: base #: view:res.partner.category:0 msgid "Partner Category" -msgstr "" +msgstr "Kategorija partnerja" #. module: base #: view:ir.actions.server:0 @@ -7655,7 +7944,7 @@ msgstr "Sprožitev" #. module: base #: model:ir.model,name:base.model_base_module_update msgid "Update Module" -msgstr "" +msgstr "Posodobi modul" #. module: base #: view:ir.model.fields:0 @@ -9268,3 +9557,6 @@ msgstr "Šrilanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "rusko" + +#~ msgid "Number padding" +#~ msgstr "Zapolnitev številke" diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po index 4d38cd56221..30f2c54bb2a 100644 --- a/openerp/addons/base/i18n/sq.po +++ b/openerp/addons/base/i18n/sq.po @@ -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: 2011-09-01 04:39+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:00+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5430,7 +5430,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po index 04a1487c320..0d81e8b9fea 100644 --- a/openerp/addons/base/i18n/sr.po +++ b/openerp/addons/base/i18n/sr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-11-15 08:29+0000\n" -"Last-Translator: OpenERP Administrators <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:23+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: Serbian <sr@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5575,7 +5575,7 @@ msgstr "Prevodi" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Dopunjavanje brojeva" #. module: base @@ -9460,3 +9460,6 @@ msgstr "Šri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Ruski / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Dopunjavanje brojeva" diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po index a545d3854a8..561bd88c69e 100644 --- a/openerp/addons/base/i18n/sr@latin.po +++ b/openerp/addons/base/i18n/sr@latin.po @@ -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: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po index 5dd00cab0ba..d1cb5e63c93 100644 --- a/openerp/addons/base/i18n/sv.po +++ b/openerp/addons/base/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-05-13 07:33+0000\n" +"PO-Revision-Date: 2011-09-30 21:31+0000\n" "Last-Translator: Anders Wallenquist <anders.wallenquist@vertel.se>\n" "Language-Team: <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:43+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5624,7 +5624,7 @@ msgstr "Översättningar" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Numerisk utfyllnad" #. module: base @@ -9509,3 +9509,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "ryska / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Numerisk utfyllnad" diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po index d785c5d635b..bda7407d9b1 100644 --- a/openerp/addons/base/i18n/th.po +++ b/openerp/addons/base/i18n/th.po @@ -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: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:05+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po index dede310a722..6051f9c1bbc 100644 --- a/openerp/addons/base/i18n/tlh.po +++ b/openerp/addons/base/i18n/tlh.po @@ -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: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5430,7 +5430,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po index a1661ed041e..6538fc4f237 100644 --- a/openerp/addons/base/i18n/tr.po +++ b/openerp/addons/base/i18n/tr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-05-26 05:01+0000\n" -"Last-Translator: Ahmet Altınışık <Unknown>\n" +"PO-Revision-Date: 2011-09-30 21:21+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5637,7 +5637,7 @@ msgstr "Çeviriler" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Numara dolgusu" #. module: base @@ -9544,3 +9544,6 @@ msgstr "Sri Lanka" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Rusça / русский язык" + +#~ msgid "Number padding" +#~ msgstr "Numara dolgusu" diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po index a024978394c..8c17a777bc4 100644 --- a/openerp/addons/base/i18n/uk.po +++ b/openerp/addons/base/i18n/uk.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-02-05 16:25+0000\n" -"Last-Translator: Casufi <Unknown>\n" +"PO-Revision-Date: 2011-09-30 20:34+0000\n" +"Last-Translator: Antony Lesuisse (OpenERP) <al@openerp.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5495,7 +5495,7 @@ msgstr "Переклади" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Вирівнювання номерів" #. module: base @@ -9321,3 +9321,6 @@ msgstr "Шрі-Ланка" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "Російська / Russian" + +#~ msgid "Number padding" +#~ msgstr "Вирівнювання номерів" diff --git a/openerp/addons/base/i18n/uk_UA.po b/openerp/addons/base/i18n/uk_UA.po index c1923fd44a9..c984308a4de 100644 --- a/openerp/addons/base/i18n/uk_UA.po +++ b/openerp/addons/base/i18n/uk_UA.po @@ -4636,7 +4636,7 @@ msgstr "Переклади" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "Вирівнювання номерів" #. module: base diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po index 2457121dad1..b503a31a6ab 100644 --- a/openerp/addons/base/i18n/ur.po +++ b/openerp/addons/base/i18n/ur.po @@ -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: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5431,7 +5431,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po index 417c64daba6..4dca37e5ade 100644 --- a/openerp/addons/base/i18n/vi.po +++ b/openerp/addons/base/i18n/vi.po @@ -9,13 +9,13 @@ msgstr "" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" "PO-Revision-Date: 2011-07-23 16:37+0000\n" -"Last-Translator: Phong Nguyen-Thanh <Unknown>\n" +"Last-Translator: OpenBMS JSC <Unknown>\n" "Language-Team: Vietnamese <vi@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:44+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5468,7 +5468,7 @@ msgstr "" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po index ccc8619e189..5cc1a6ad39d 100644 --- a/openerp/addons/base/i18n/zh_CN.po +++ b/openerp/addons/base/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-28 03:33+0000\n" +"PO-Revision-Date: 2011-09-30 21:27+0000\n" "Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -5471,7 +5471,7 @@ msgstr "翻译" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "数字位数" #. module: base @@ -9310,3 +9310,6 @@ msgstr "斯里兰卡" #: selection:base.language.install,lang:0 msgid "Russian / русский язык" msgstr "俄语 / русский язык" + +#~ msgid "Number padding" +#~ msgstr "数字位数" diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po new file mode 100644 index 00000000000..28b94f85e50 --- /dev/null +++ b/openerp/addons/base/i18n/zh_HK.po @@ -0,0 +1,9248 @@ +# Chinese (Hong Kong) translation for openobject-server +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the openobject-server package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-server\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2011-01-11 11:14+0000\n" +"PO-Revision-Date: 2011-09-30 15:06+0000\n" +"Last-Translator: Walter Cheuk <wwycheuk@gmail.com>\n" +"Language-Team: Chinese (Hong Kong) <zh_HK@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-10-01 05:06+0000\n" +"X-Generator: Launchpad (build 14071)\n" + +#. module: base +#: view:ir.filters:0 +#: field:ir.model.fields,domain:0 +#: field:ir.rule,domain:0 +#: field:ir.rule,domain_force:0 +#: field:res.partner.title,domain:0 +msgid "Domain" +msgstr "" + +#. module: base +#: model:res.country,name:base.sh +msgid "Saint Helena" +msgstr "聖海倫拿島" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Other Configuration" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "DateTime" +msgstr "" + +#. module: base +#: code:addons/fields.py:534 +#, python-format +msgid "" +"The second argument of the many2many field %s must be a SQL table !You used " +"%s, which is not a valid SQL table name." +msgstr "" + +#. module: base +#: view:ir.values:0 +#: field:ir.values,meta_unpickle:0 +msgid "Metadata" +msgstr "" + +#. module: base +#: field:ir.ui.view,arch:0 +#: field:ir.ui.view.custom,arch:0 +msgid "View Architecture" +msgstr "" + +#. module: base +#: field:base.language.import,code:0 +msgid "Code (eg:en__US)" +msgstr "" + +#. module: base +#: view:workflow:0 +#: view:workflow.activity:0 +#: field:workflow.activity,wkf_id:0 +#: field:workflow.instance,wkf_id:0 +#: field:workflow.transition,wkf_id:0 +#: field:workflow.workitem,wkf_id:0 +msgid "Workflow" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "SMS - Gateway: clickatell" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hungarian / Magyar" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Not Searchable" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (VE) / Español (VE)" +msgstr "西班牙文 (VE) / Español (VE)" + +#. module: base +#: field:ir.actions.server,wkf_model_id:0 +msgid "Workflow On" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,display_menu_tip:0 +msgid "Display Menu Tips" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Views" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:485 +#, python-format +msgid "" +"You can not write in this document (%s) ! Be sure your user belongs to one " +"of these groups: %s." +msgstr "" + +#. module: base +#: help:ir.model.fields,domain:0 +msgid "" +"The optional domain to restrict possible values for relationship fields, " +"specified as a Python expression defining a list of triplets. For example: " +"[('color','=','red')]" +msgstr "" + +#. module: base +#: field:res.partner,ref:0 +msgid "Reference" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,target:0 +msgid "Target Window" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:507 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:304 +#, python-format +msgid "" +"Properties of base fields cannot be altered in this manner! Please modify " +"them through Python code, preferably through a custom addon!" +msgstr "" + +#. module: base +#: code:addons/osv.py:133 +#, python-format +msgid "Constraint Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_custom +msgid "ir.ui.view.custom" +msgstr "" + +#. module: base +#: model:res.country,name:base.sz +msgid "Swaziland" +msgstr "" + +#. module: base +#: code:addons/orm.py:1993 +#: code:addons/orm.py:3653 +#, python-format +msgid "created." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_woodsuppliers0 +msgid "Wood Suppliers" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:303 +#, python-format +msgid "" +"Some installed modules depend on the module you plan to Uninstall :\n" +" %s" +msgstr "" + +#. module: base +#: field:ir.sequence,number_increment:0 +msgid "Increment Number" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_tree +#: model:ir.ui.menu,name:base.menu_action_res_company_tree +msgid "Company's Structure" +msgstr "公司架構" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Inuktitut / ᐃᓄᒃᑎᑐᑦ" +msgstr "梵文 / ᐃᓄᒃᑎᑐᑦ" + +#. module: base +#: view:res.partner:0 +msgid "Search Partner" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:132 +#, python-format +msgid "\"smtp_server\" needs to be set to send mails to users" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:60 +#, python-format +msgid "new" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,multi:0 +msgid "On multiple doc." +msgstr "" + +#. module: base +#: field:ir.module.category,module_nr:0 +msgid "Number of Modules" +msgstr "" + +#. module: base +#: help:multi_company.default,company_dest_id:0 +msgid "Company to store the current record" +msgstr "" + +#. module: base +#: field:res.partner.bank.type.field,size:0 +msgid "Max. Size" +msgstr "" + +#. module: base +#: field:res.partner.address,name:0 +msgid "Contact Name" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:56 +#, python-format +msgid "" +"Save this document to a %s file and edit it with a specific software or a " +"text editor. The file encoding is UTF-8." +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The name of the language must be unique !" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "active" +msgstr "" + +#. module: base +#: field:ir.actions.wizard,wiz_name:0 +msgid "Wizard Name" +msgstr "" + +#. module: base +#: code:addons/orm.py:2160 +#, python-format +msgid "Invalid group_by" +msgstr "" + +#. module: base +#: field:res.partner,credit_limit:0 +msgid "Credit Limit" +msgstr "" + +#. module: base +#: field:ir.model.data,date_update:0 +msgid "Update Date" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Owner" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,src_model:0 +msgid "Source Object" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Config Wizard Steps" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view_sc +msgid "ir.ui.view_sc" +msgstr "" + +#. module: base +#: field:res.widget.user,widget_id:0 +#: field:res.widget.wizard,widgets_list:0 +msgid "Widget" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,group_id:0 +#: view:res.config.users:0 +msgid "Group" +msgstr "" + +#. module: base +#: field:ir.exports.line,name:0 +#: field:ir.translation,name:0 +#: field:res.partner.bank.type.field,name:0 +msgid "Field Name" +msgstr "" + +#. module: base +#: wizard_view:server.action.create,init:0 +#: wizard_field:server.action.create,init,type:0 +msgid "Select Action Type" +msgstr "" + +#. module: base +#: model:res.country,name:base.tv +msgid "Tuvalu" +msgstr "" + +#. module: base +#: selection:ir.model,state:0 +msgid "Custom Object" +msgstr "" + +#. module: base +#: field:res.lang,date_format:0 +msgid "Date Format" +msgstr "" + +#. module: base +#: field:res.bank,email:0 +#: field:res.partner.address,email:0 +msgid "E-Mail" +msgstr "" + +#. module: base +#: model:res.country,name:base.an +msgid "Netherlands Antilles" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:389 +#, python-format +msgid "" +"You can not remove the admin user as it is used internally for resources " +"created by OpenERP (updates, module installation, ...)" +msgstr "" + +#. module: base +#: model:res.country,name:base.gf +msgid "French Guyana" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Greek / Ελληνικά" +msgstr "希臘文 / Ελληνικά" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bosnian / bosanski jezik" +msgstr "波斯尼亞文 / bosanski jezik" + +#. module: base +#: help:ir.actions.report.xml,attachment_use:0 +msgid "" +"If you check this, then the second time the user prints with same attachment " +"name, it returns the previous report." +msgstr "" + +#. module: base +#: code:addons/orm.py:904 +#, python-format +msgid "The read method is not implemented on this object !" +msgstr "" + +#. module: base +#: help:res.lang,iso_code:0 +msgid "This ISO code is the name of po files to use for translations" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Your system will be updated." +msgstr "" + +#. module: base +#: field:ir.actions.todo,note:0 +#: selection:ir.property,type:0 +msgid "Text" +msgstr "" + +#. module: base +#: field:res.country,name:0 +msgid "Country Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.co +msgid "Colombia" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Schedule Upgrade" +msgstr "" + +#. module: base +#: code:addons/orm.py:838 +#, python-format +msgid "Key/value '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: help:res.country,code:0 +msgid "" +"The ISO country code in two chars.\n" +"You can use this field for quick search." +msgstr "" + +#. module: base +#: model:res.country,name:base.pw +msgid "Palau" +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "Sales & Purchases" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Untranslated" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,context:0 +msgid "" +"Context dictionary as Python expression, empty by default (Default: {})" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_wizard +#: view:ir.actions.wizard:0 +#: model:ir.ui.menu,name:base.menu_ir_action_wizard +msgid "Wizards" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_miscellaneoussuppliers0 +msgid "Miscellaneous Suppliers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:255 +#, python-format +msgid "Custom fields must have a name that starts with 'x_' !" +msgstr "" + +#. module: base +#: help:ir.actions.server,action_id:0 +msgid "Select the Action Window, Report, Wizard to be executed." +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "New User" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export done" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Model Description" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,src_model:0 +msgid "" +"Optional model name of the objects on which this action should be visible" +msgstr "" + +#. module: base +#: field:workflow.transition,trigger_expr_id:0 +msgid "Trigger Expression" +msgstr "" + +#. module: base +#: model:res.country,name:base.jo +msgid "Jordan" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Certified" +msgstr "" + +#. module: base +#: model:res.country,name:base.er +msgid "Eritrea" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "description" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_action_rule +msgid "Automated Actions" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_actions +msgid "ir.actions.actions" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Want to check Ean ? " +msgstr "" + +#. module: base +#: field:ir.values,key2:0 +msgid "Event Type" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "" +"OpenERP translations (core, modules, clients) are managed through " +"Launchpad.net, our open source project management facility. We use their " +"online interface to synchronize all translations efforts." +msgstr "" + +#. module: base +#: field:res.partner,title:0 +msgid "Partner Form" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Swedish / svenska" +msgstr "" + +#. module: base +#: model:res.country,name:base.rs +msgid "Serbia" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard View" +msgstr "" + +#. module: base +#: model:res.country,name:base.kh +msgid "Cambodia, Kingdom of" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_form +#: view:ir.sequence:0 +#: model:ir.ui.menu,name:base.menu_ir_sequence_form +#: model:ir.ui.menu,name:base.next_id_5 +msgid "Sequences" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_import +msgid "Language Import" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_users +msgid "res.config.users" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Albanian / Shqip" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_opportunity +msgid "Opportunities" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_export +msgid "base.language.export" +msgstr "" + +#. module: base +#: model:res.country,name:base.pg +msgid "Papua New Guinea" +msgstr "巴布亞新畿內亞" + +#. module: base +#: help:ir.actions.report.xml,report_type:0 +msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_4 +msgid "Basic Partner" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "," +msgstr "" + +#. module: base +#: view:res.partner:0 +msgid "My Partners" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "XML Report" +msgstr "" + +#. module: base +#: model:res.country,name:base.es +msgid "Spain" +msgstr "西班牙" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_export +msgid "Import / Export" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,domain:0 +msgid "" +"Optional domain filtering of the destination data, as a Python expression" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade +#: model:ir.model,name:base.model_base_module_upgrade +msgid "Module Upgrade" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "" +"Groups are used to define access rights on objects and the visibility of " +"screens and menus" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (UY) / Español (UY)" +msgstr "西班牙文 (UY) / Español (UY)" + +#. module: base +#: field:res.partner,mobile:0 +#: field:res.partner.address,mobile:0 +msgid "Mobile" +msgstr "" + +#. module: base +#: model:res.country,name:base.om +msgid "Oman" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_payterm_form +#: model:ir.model,name:base.model_res_payterm +msgid "Payment term" +msgstr "" + +#. module: base +#: model:res.country,name:base.nu +msgid "Niue" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Work Days" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other OSI Approved Licence" +msgstr "" + +#. module: base +#: help:res.config.users,context_lang:0 +#: help:res.users,context_lang:0 +msgid "" +"Sets the language for the user's user interface, when UI translations are " +"available" +msgstr "" + +#. module: base +#: code:addons/orm.py:1043 +#, python-format +msgid "The unlink method is not implemented on this object !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_menu_create +#: view:wizard.ir.model.menu.create:0 +msgid "Create Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.in +msgid "India" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request_link-act +#: model:ir.ui.menu,name:base.menu_res_request_link_act +msgid "Request Reference Types" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "client_action_multi, client_action_relate" +msgstr "" + +#. module: base +#: model:res.country,name:base.ad +msgid "Andorra, Principality of" +msgstr "" + +#. module: base +#: field:ir.module.category,child_ids:0 +#: field:res.partner.category,child_ids:0 +msgid "Child Categories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_config_parameter +msgid "ir.config_parameter" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "TGZ Archive" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%B - Full month name." +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: field:ir.attachment,type:0 +#: field:ir.model,state:0 +#: field:ir.model.fields,state:0 +#: field:ir.property,type:0 +#: field:ir.server.object.lines,type:0 +#: field:ir.translation,type:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: field:ir.values,key:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Type" +msgstr "類型" + +#. module: base +#: code:addons/orm.py:210 +#, python-format +msgid "" +"Language with code \"%s\" is not defined in your system !\n" +"Define it through the Administration menu." +msgstr "" + +#. module: base +#: model:res.country,name:base.gu +msgid "Guam (USA)" +msgstr "關島(美屬)" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_project +msgid "Human Resources Dashboard" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:507 +#, python-format +msgid "Setting empty passwords is not allowed for security reasons!" +msgstr "因保安理由密碼不能留空!" + +#. module: base +#: selection:ir.actions.server,state:0 +#: selection:workflow.activity,kind:0 +msgid "Dummy" +msgstr "" + +#. module: base +#: constraint:ir.ui.view:0 +msgid "Invalid XML for View Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ky +msgid "Cayman Islands" +msgstr "開曼羣島" + +#. module: base +#: model:res.country,name:base.kr +msgid "South Korea" +msgstr "南韓" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_transition_form +#: model:ir.ui.menu,name:base.menu_workflow_transition +#: view:workflow.activity:0 +msgid "Transitions" +msgstr "" + +#. module: base +#: code:addons/orm.py:4020 +#, python-format +msgid "Record #%d of %s not found, cannot copy!" +msgstr "" + +#. module: base +#: field:ir.module.module,contributors:0 +msgid "Contributors" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Char" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract +msgid "Contracts" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (AR) / Español (AR)" +msgstr "西班牙文 (AR) / Español (AR)" + +#. module: base +#: model:res.country,name:base.ug +msgid "Uganda" +msgstr "烏干達" + +#. module: base +#: field:ir.model.access,perm_unlink:0 +msgid "Delete Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.ne +msgid "Niger" +msgstr "尼日爾" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (HK)" +msgstr "中文 (香港)" + +#. module: base +#: model:res.country,name:base.ba +msgid "Bosnia-Herzegovina" +msgstr "波斯尼亞" + +#. module: base +#: view:base.language.export:0 +msgid "" +"To improve or expand the official translations, you should use directly " +"Lauchpad's web interface (Rosetta). If you need to perform mass translation, " +"Launchpad also allows uploading full .po files at once" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (GT) / Español (GT)" +msgstr "西班牙文 (GT) / Español (GT)" + +#. module: base +#: view:res.lang:0 +msgid "" +"%W - Week number of the year (Monday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Monday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: field:ir.module.module,website:0 +#: field:res.partner,website:0 +msgid "Website" +msgstr "網站" + +#. module: base +#: model:res.country,name:base.gs +msgid "S. Georgia & S. Sandwich Isls." +msgstr "南喬治亞和南三文治羣島" + +#. module: base +#: field:ir.actions.url,url:0 +msgid "Action URL" +msgstr "" + +#. module: base +#: field:base.module.import,module_name:0 +msgid "Module Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.mh +msgid "Marshall Islands" +msgstr "馬紹爾羣島" + +#. module: base +#: code:addons/base/ir/ir_model.py:328 +#, python-format +msgid "Changing the model of a field is forbidden!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ht +msgid "Haiti" +msgstr "海地" + +#. module: base +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +msgid "Search" +msgstr "搜尋" + +#. module: base +#: code:addons/osv.py:136 +#, python-format +msgid "" +"The operation cannot be completed, probably due to the following:\n" +"- deletion: you may be trying to delete a record while other records still " +"reference it\n" +"- creation/update: a mandatory field is not correctly set" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"2. Group-specific rules are combined together with a logical AND operator" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:206 +#, python-format +msgid "Operation Canceled" +msgstr "" + +#. module: base +#: help:base.language.export,lang:0 +msgid "To export a new language, do not select a language." +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Request Date" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_dasboard +msgid "Dashboard" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_purchase_root +msgid "Purchases" +msgstr "" + +#. module: base +#: model:res.country,name:base.md +msgid "Moldavia" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Features" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: report:ir.module.reference.graph:0 +msgid "Version" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_read:0 +#: view:ir.rule:0 +msgid "Read Access" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports +msgid "ir.exports" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "No language with code \"%s\" exists" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#, python-format +msgid "Error during communication with the publisher warranty server." +msgstr "" + +#. module: base +#: help:ir.actions.server,email:0 +msgid "" +"Provides the fields that will be used to fetch the email address, e.g. when " +"you select the invoice, then `object.invoice_address_id.email` is the field " +"which gives the correct address" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%Y - Year with century." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "-" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "" +"This wizard helps you register a publisher warranty contract in your OpenERP " +"system. After the contract has been registered, you will be able to send " +"issues directly to OpenERP." +msgstr "" + +#. module: base +#: code:addons/orm.py:1744 +#, python-format +msgid "The search method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:wizard.ir.model.menu.create:0 +msgid "Create _Menu" +msgstr "" + +#. module: base +#: field:res.payterm,name:0 +msgid "Payment Term (short name)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_bank +#: view:res.bank:0 +#: field:res.partner.bank,bank:0 +msgid "Bank" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_exports_line +msgid "ir.exports.line" +msgstr "" + +#. module: base +#: help:base.language.install,overwrite:0 +msgid "" +"If you check this box, your customized translations will be overwritten and " +"replaced by the official ones." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml:0 +msgid "Main report file path" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_report_xml +#: field:ir.module.module,reports_by_module:0 +#: model:ir.ui.menu,name:base.menu_ir_action_report_xml +msgid "Reports" +msgstr "" + +#. module: base +#: help:ir.actions.act_window.view,multi:0 +#: help:ir.actions.report.xml,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: field:workflow,on_create:0 +msgid "On Create" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:607 +#, python-format +msgid "" +"'%s' contains too many dots. XML ids should not contain dots ! These are " +"used to refer to other modules data, as in module.reference_id" +msgstr "" + +#. module: base +#: field:partner.sms.send,user:0 +#: field:res.config.users,login:0 +#: field:res.users,login:0 +msgid "Login" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Access all the fields related to the current object using expressions, i.e. " +"object.partner_id.name " +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country_state +msgid "Country state" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Float" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request_link +msgid "res.request.link" +msgstr "" + +#. module: base +#: field:ir.actions.wizard,name:0 +msgid "Wizard Info" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: model:ir.actions.act_window,name:base.action_wizard_lang_export +#: model:ir.ui.menu,name:base.menu_wizard_lang_export +msgid "Export Translation" +msgstr "" + +#. module: base +#: help:res.log,secondary:0 +msgid "" +"Do not display this log if it belongs to the same object the user is working " +"on" +msgstr "" + +#. module: base +#: model:res.country,name:base.tp +msgid "East Timor" +msgstr "東帝汶" + +#. module: base +#: model:res.company,follow_up_msg:base.main_company +msgid "" +"Date : %(date)s\n" +"\n" +"Dear %(partner_name)s,\n" +"\n" +"Please find in attachment a reminder of all your unpaid invoices, for a " +"total amount due of:\n" +"\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"Thanks,\n" +"--\n" +"%(user_signature)s\n" +"%(company_name)s" +msgstr "" + +#. module: base +#: field:res.currency,accuracy:0 +msgid "Computational Accuracy" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Sinhalese / සිංහල" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create_line +msgid "wizard.ir.model.menu.create.line" +msgstr "" + +#. module: base +#: field:ir.attachment,res_id:0 +msgid "Attached ID" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day: %(day)s" +msgstr "" + +#. module: base +#: model:res.country,name:base.mv +msgid "Maldives" +msgstr "馬爾代夫" + +#. module: base +#: help:ir.values,res_id:0 +msgid "Keep 0 if the action must appear on all resources." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_rule +msgid "ir.rule" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Days" +msgstr "" + +#. module: base +#: help:ir.actions.server,condition:0 +msgid "" +"Condition that is to be tested before action is executed, e.g. " +"object.list_price > object.cost_price" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:155 +#: code:addons/base/res/res_company.py:66 +#, python-format +msgid " (copy)" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "7. %H:%M:%S ==> 18:25:20" +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.category:0 +#: field:res.partner.category,partner_ids:0 +msgid "Partners" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_left:0 +msgid "Left parent" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_act_window +msgid "Homepage Widgets" +msgstr "" + +#. module: base +#: help:ir.actions.server,message:0 +msgid "" +"Specify the message. You can use the fields from the object. e.g. `Dear [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: field:ir.attachment,res_model:0 +msgid "Attached Model" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Domain Setup" +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_name:0 +msgid "Trigger Name" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_model_access +msgid "ir.model.access" +msgstr "" + +#. module: base +#: field:ir.cron,priority:0 +#: field:res.request,priority:0 +#: field:res.request.link,priority:0 +msgid "Priority" +msgstr "" + +#. module: base +#: field:workflow.transition,act_from:0 +msgid "Source Activity" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Legend (for prefix, suffix)" +msgstr "" + +#. module: base +#: selection:ir.server.object.lines,type:0 +msgid "Formula" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:389 +#, python-format +msgid "Can not remove root user!" +msgstr "" + +#. module: base +#: model:res.country,name:base.mw +msgid "Malawi" +msgstr "馬拉維" + +#. module: base +#: code:addons/base/res/res_user.py:51 +#: code:addons/base/res/res_user.py:413 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: base +#: field:res.partner.address,type:0 +msgid "Address Type" +msgstr "" + +#. module: base +#: view:ir.ui.menu:0 +msgid "Full Path" +msgstr "完整路徑" + +#. module: base +#: view:res.request:0 +msgid "References" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "" +"%U - Week number of the year (Sunday as the first day of the week) as a " +"decimal number [00,53]. All days in a new year preceding the first Sunday " +"are considered to be in week 0." +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Advanced" +msgstr "" + +#. module: base +#: model:res.country,name:base.fi +msgid "Finland" +msgstr "芬蘭" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Tree" +msgstr "" + +#. module: base +#: help:res.config.users,password:0 +msgid "" +"Keep empty if you don't want the user to be able to connect on the system." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Create / Write / Copy" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://help.launchpad.net/Translations" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_mode:0 +msgid "View Mode" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"When using CSV format, please also check that the first line of your file is " +"one of the following:" +msgstr "" + +#. module: base +#: code:addons/fields.py:114 +#, python-format +msgid "Not implemented search_memory method !" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Logs" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish / Español" +msgstr "西班牙文 / Español" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KP) / 한국어 (KP)" +msgstr "韓文 (北韓) / 한국어 (KP)" + +#. module: base +#: view:base.module.update:0 +msgid "" +"This wizard will scan all module repositories on the server side to detect " +"newly added modules as well as any change to existing modules." +msgstr "" + +#. module: base +#: field:res.company,logo:0 +msgid "Logo" +msgstr "" + +#. module: base +#: view:res.partner.address:0 +msgid "Search Contact" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Uninstall (beta)" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,target:0 +#: selection:ir.actions.url,target:0 +msgid "New Window" +msgstr "" + +#. module: base +#: model:res.country,name:base.bs +msgid "Bahamas" +msgstr "巴哈馬羣島" + +#. module: base +#: code:addons/base/res/partner/partner.py:250 +#, python-format +msgid "" +"Couldn't generate the next id because some partners have an alphabetic id !" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attachment" +msgstr "" + +#. module: base +#: model:res.country,name:base.ie +msgid "Ireland" +msgstr "愛爾蘭" + +#. module: base +#: field:base.module.update,update:0 +msgid "Number of modules updated" +msgstr "" + +#. module: base +#: code:addons/fields.py:100 +#, python-format +msgid "Not implemented set_memory method !" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +msgid "Workflow Activity" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND " +"GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view +msgid "" +"Views allows you to personalize each view of OpenERP. You can add new " +"fields, move fields, rename them or delete the ones that you do not need." +msgstr "" + +#. module: base +#: field:ir.actions.act_window,groups_id:0 +#: model:ir.actions.act_window,name:base.action_res_groups +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,groups_id:0 +#: view:ir.actions.todo:0 +#: field:ir.actions.todo,groups_id:0 +#: field:ir.actions.wizard,groups_id:0 +#: view:ir.model:0 +#: field:ir.model.fields,groups:0 +#: field:ir.rule,groups:0 +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,groups_id:0 +#: model:ir.ui.menu,name:base.menu_action_res_groups +#: field:res.config.users,groups_id:0 +#: view:res.groups:0 +#: view:res.users:0 +#: field:res.users,groups_id:0 +msgid "Groups" +msgstr "羣組" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CL) / Español (CL)" +msgstr "西班牙文 (CL) / Español (CL)" + +#. module: base +#: view:res.config.users:0 +msgid "" +"Create additional users and assign them groups that will allow them to have " +"access to selected functionalities within the system. Click on 'Done' if you " +"do not wish to add more users at this stage, you can always do this later." +msgstr "" + +#. module: base +#: model:res.country,name:base.bz +msgid "Belize" +msgstr "伯利茲" + +#. module: base +#: model:res.country,name:base.ge +msgid "Georgia" +msgstr "格魯吉亞" + +#. module: base +#: model:res.country,name:base.pl +msgid "Poland" +msgstr "波蘭" + +#. module: base +#: help:ir.actions.act_window,view_mode:0 +msgid "" +"Comma-separated list of allowed view modes, such as 'form', 'tree', " +"'calendar', etc. (Default: tree,form)" +msgstr "" + +#. module: base +#: code:addons/orm.py:3147 +#, python-format +msgid "A document was modified since you last viewed it (%s:%d)" +msgstr "" + +#. module: base +#: view:workflow:0 +msgid "Workflow Editor" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be removed" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence +msgid "ir.sequence" +msgstr "" + +#. module: base +#: help:ir.actions.server,expression:0 +msgid "" +"Enter the field/expression that will return the list. E.g. select the sale " +"order in Object, and you can have loop on the sales order line. Expression = " +"`object.order_line`." +msgstr "" + +#. module: base +#: field:ir.property,fields_id:0 +#: selection:ir.translation,type:0 +#: field:multi_company.default,field_id:0 +msgid "Field" +msgstr "欄位" + +#. module: base +#: view:ir.rule:0 +msgid "Groups (no group = global)" +msgstr "" + +#. module: base +#: model:res.country,name:base.fo +msgid "Faroe Islands" +msgstr "法羅羣島" + +#. module: base +#: selection:res.config.users,view:0 +#: selection:res.config.view,view:0 +#: selection:res.users,view:0 +msgid "Simplified" +msgstr "" + +#. module: base +#: model:res.country,name:base.st +msgid "Saint Tome (Sao Tome) and Principe" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Invoice" +msgstr "發票" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese (BR) / Português (BR)" +msgstr "葡萄牙文 (BR) / Português (BR)" + +#. module: base +#: model:res.country,name:base.bb +msgid "Barbados" +msgstr "巴巴多斯" + +#. module: base +#: model:res.country,name:base.mg +msgid "Madagascar" +msgstr "馬達加斯加" + +#. module: base +#: code:addons/base/ir/ir_model.py:96 +#, python-format +msgid "" +"The Object name must start with x_ and not contain any special character !" +msgstr "" + +#. module: base +#: field:ir.actions.configuration.wizard,note:0 +msgid "Next Wizard" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_menu_admin +#: view:ir.ui.menu:0 +#: field:ir.ui.menu,name:0 +msgid "Menu" +msgstr "選單" + +#. module: base +#: field:res.currency,rate:0 +msgid "Current Rate" +msgstr "" + +#. module: base +#: field:ir.ui.view.custom,ref_id:0 +msgid "Original View" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action To Launch" +msgstr "" + +#. module: base +#: field:ir.actions.url,target:0 +msgid "Action Target" +msgstr "" + +#. module: base +#: model:res.country,name:base.ai +msgid "Anguilla" +msgstr "安圭拉" + +#. module: base +#: field:ir.ui.view_sc,name:0 +msgid "Shortcut Name" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,limit:0 +msgid "Default limit for the list view" +msgstr "" + +#. module: base +#: help:ir.actions.server,write_id:0 +msgid "" +"Provide the field name that the record id refers to for the write operation. " +"If it is empty it will refer to the active id of the object." +msgstr "" + +#. module: base +#: model:res.country,name:base.zw +msgid "Zimbabwe" +msgstr "津巴布韋" + +#. module: base +#: view:base.module.update:0 +msgid "Please be patient, as this operation may take a few seconds..." +msgstr "" + +#. module: base +#: help:ir.values,action_id:0 +msgid "This field is not used, it only helps you to select the right action." +msgstr "" + +#. module: base +#: field:ir.actions.server,email:0 +msgid "Email Address" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (BE) / Français (BE)" +msgstr "法文 (比利時) / Français (BE)" + +#. module: base +#: view:ir.actions.server:0 +#: field:workflow.activity,action_id:0 +msgid "Server Action" +msgstr "" + +#. module: base +#: model:res.country,name:base.tt +msgid "Trinidad and Tobago" +msgstr "千里達" + +#. module: base +#: model:res.country,name:base.lv +msgid "Latvia" +msgstr "拉脫維亞" + +#. module: base +#: view:ir.values:0 +msgid "Values" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mappings" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "Export Translations" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom +msgid "Customization" +msgstr "" + +#. module: base +#: model:res.country,name:base.py +msgid "Paraguay" +msgstr "巴拉圭" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_close +msgid "ir.actions.act_window_close" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,col1:0 +msgid "Destination" +msgstr "" + +#. module: base +#: model:res.country,name:base.lt +msgid "Lithuania" +msgstr "立陶宛" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_clear_ids +#: model:ir.model,name:base.model_partner_clear_ids +#: view:partner.clear.ids:0 +msgid "Clear IDs" +msgstr "" + +#. module: base +#: help:ir.cron,model:0 +msgid "" +"Name of object whose function will be called when this scheduler will run. " +"e.g. 'res.partener'" +msgstr "" + +#. module: base +#: code:addons/orm.py:1040 +#, python-format +msgid "The perm_read method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%y - Year without century [00,99]." +msgstr "" + +#. module: base +#: model:res.country,name:base.si +msgid "Slovenia" +msgstr "斯洛文尼亞" + +#. module: base +#: model:res.country,name:base.pk +msgid "Pakistan" +msgstr "巴基斯坦" + +#. module: base +#: code:addons/orm.py:1350 +#, python-format +msgid "Invalid Object Architecture!" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_email_gateway_form +msgid "Messages" +msgstr "訊息" + +#. module: base +#: code:addons/base/ir/ir_model.py:303 +#: code:addons/base/ir/ir_model.py:317 +#: code:addons/base/ir/ir_model.py:319 +#: code:addons/base/ir/ir_model.py:321 +#: code:addons/base/ir/ir_model.py:328 +#: code:addons/base/ir/ir_model.py:331 +#: code:addons/base/module/wizard/base_update_translations.py:38 +#, python-format +msgid "Error!" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%p - Equivalent of either AM or PM." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Actions" +msgstr "" + +#. module: base +#: help:multi_company.default,company_id:0 +msgid "Company where the user is connected" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_stop:0 +msgid "Ending Date" +msgstr "" + +#. module: base +#: model:res.country,name:base.nz +msgid "New Zealand" +msgstr "" + +#. module: base +#: code:addons/orm.py:3366 +#, python-format +msgid "" +"One of the records you are trying to modify has already been deleted " +"(Document type: %s)." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country +msgid "" +"Display and manage the list of all countries that can be assigned to your " +"partner records. You can create or delete countries to make sure the ones " +"you are working on will be maintained." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_7 +msgid "Openstuff.net" +msgstr "" + +#. module: base +#: model:res.country,name:base.nf +msgid "Norfolk Island" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Korean (KR) / 한국어 (KR)" +msgstr "韓文 (南韓) / 한국어 (KR)" + +#. module: base +#: help:ir.model.fields,model:0 +msgid "The technical name of the model this field belongs to" +msgstr "" + +#. module: base +#: field:ir.actions.server,action_id:0 +#: selection:ir.actions.server,state:0 +msgid "Client Action" +msgstr "" + +#. module: base +#: model:res.country,name:base.bd +msgid "Bangladesh" +msgstr "" + +#. module: base +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Valid" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "XSL" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:322 +#, python-format +msgid "Can not upgrade module '%s'. It is not installed." +msgstr "" + +#. module: base +#: model:res.country,name:base.cu +msgid "Cuba" +msgstr "古巴" + +#. module: base +#: model:ir.model,name:base.model_res_partner_event +msgid "res.partner.event" +msgstr "" + +#. module: base +#: model:res.widget,title:base.facebook_widget +msgid "Facebook" +msgstr "" + +#. module: base +#: model:res.country,name:base.am +msgid "Armenia" +msgstr "亞美尼亞" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_property_form +#: model:ir.ui.menu,name:base.menu_ir_property_form_all +msgid "Configuration Parameters" +msgstr "" + +#. module: base +#: constraint:ir.cron:0 +msgid "Invalid arguments" +msgstr "" + +#. module: base +#: model:res.country,name:base.se +msgid "Sweden" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Gantt" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Property" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type +#: view:res.partner.bank.type:0 +msgid "Bank Account Type" +msgstr "" + +#. module: base +#: field:base.language.export,config_logo:0 +#: field:base.language.import,config_logo:0 +#: field:base.language.install,config_logo:0 +#: field:base.module.import,config_logo:0 +#: field:base.module.update,config_logo:0 +#: field:base.update.translations,config_logo:0 +#: field:ir.actions.configuration.wizard,config_logo:0 +#: field:ir.wizard.screen,config_logo:0 +#: field:publisher_warranty.contract.wizard,config_logo:0 +#: field:res.config,config_logo:0 +#: field:res.config.installer,config_logo:0 +#: field:res.config.users,config_logo:0 +#: field:res.config.view,config_logo:0 +msgid "Image" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Iteration Action Configuration" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Canceled" +msgstr "" + +#. module: base +#: model:res.country,name:base.at +msgid "Austria" +msgstr "" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "done" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: model:ir.ui.menu,name:base.menu_calendar_configuration +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Calendar" +msgstr "" + +#. module: base +#: field:res.partner.address,partner_id:0 +msgid "Partner Name" +msgstr "" + +#. module: base +#: field:workflow.activity,signal_send:0 +msgid "Signal (subflow.*)" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_17 +msgid "HR sector" +msgstr "" + +#. module: base +#: code:addons/orm.py:3817 +#, python-format +msgid "" +"Invalid \"order\" specified. A valid \"order\" specification is a comma-" +"separated list of valid field names (optionally followed by asc/desc for the " +"direction)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module_dependency +msgid "Module dependency" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Draft" +msgstr "" + +#. module: base +#: selection:res.config.users,view:0 +#: selection:res.config.view,view:0 +#: selection:res.users,view:0 +msgid "Extended" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_contact +msgid "" +"Manage the contact titles you want to have available in your system and the " +"way you want to print them in letters and other documents. Some example: " +"Mr., Mrs. " +msgstr "" + +#. module: base +#: field:res.company,rml_footer1:0 +msgid "Report Footer 1" +msgstr "" + +#. module: base +#: field:res.company,rml_footer2:0 +msgid "Report Footer 2" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:res.groups:0 +#: field:res.groups,model_access:0 +msgid "Access Controls" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,dependencies_id:0 +msgid "Dependencies" +msgstr "" + +#. module: base +#: field:multi_company.default,company_id:0 +msgid "Main Company" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_hover:0 +msgid "Web Icon File (hover)" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"If you use a formula type, use a python expression using the variable " +"'object'." +msgstr "" + +#. module: base +#: field:res.partner.address,birthdate:0 +msgid "Birthdate" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_contact +#: model:ir.ui.menu,name:base.menu_partner_title_contact +msgid "Contact Titles" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Please double-check that the file encoding is set to UTF-8 (sometimes called " +"Unicode) when the translator exports it." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (DO) / Español (DO)" +msgstr "西班牙文 (DO) / Español (DO)" + +#. module: base +#: model:ir.model,name:base.model_workflow_activity +msgid "workflow.activity" +msgstr "" + +#. module: base +#: help:ir.ui.view_sc,res_id:0 +msgid "" +"Reference of the target resource, whose model/table depends on the 'Resource " +"Name' field." +msgstr "" + +#. module: base +#: field:ir.model.fields,select_level:0 +msgid "Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.uy +msgid "Uruguay" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Finnish / Suomi" +msgstr "" + +#. module: base +#: field:ir.rule,perm_write:0 +msgid "Apply For Write" +msgstr "" + +#. module: base +#: field:ir.sequence,prefix:0 +msgid "Prefix" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "German / Deutsch" +msgstr "德文 / Deutsch" + +#. module: base +#: help:ir.actions.server,trigger_name:0 +msgid "Select the Signal name that is to be used as the trigger." +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Fields Mapping" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Portugese / Português" +msgstr "葡萄牙文 / Português" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_sir +msgid "Sir" +msgstr "" + +#. module: base +#: code:addons/orm.py:1622 +#, python-format +msgid "There is no view of type '%s' defined for the structure!" +msgstr "" + +#. module: base +#: field:ir.default,ref_id:0 +msgid "ID Ref." +msgstr "" + +#. module: base +#: model:ir.actions.server,name:base.action_start_configurator +#: model:ir.ui.menu,name:base.menu_view_base_module_configuration +msgid "Start Configuration" +msgstr "" + +#. module: base +#: model:res.country,name:base.mt +msgid "Malta" +msgstr "" + +#. module: base +#: field:ir.actions.server,fields_lines:0 +msgid "Field Mappings." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_module +#: view:ir.model.data:0 +#: field:ir.model.data,module:0 +#: view:ir.module.module:0 +#: field:ir.module.module.dependency,module_id:0 +#: report:ir.module.reference.graph:0 +#: field:ir.translation,module:0 +msgid "Module" +msgstr "" + +#. module: base +#: field:ir.attachment,description:0 +#: view:ir.module.module:0 +#: field:ir.module.module,description:0 +#: field:res.partner.bank,name:0 +#: view:res.partner.event:0 +#: field:res.partner.event,description:0 +#: view:res.request:0 +msgid "Description" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_instance_form +#: model:ir.ui.menu,name:base.menu_workflow_instance +msgid "Instances" +msgstr "" + +#. module: base +#: model:res.country,name:base.aq +msgid "Antarctica" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,auto:0 +msgid "Custom python parser" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "_Import" +msgstr "" + +#. module: base +#: view:res.partner.canal:0 +msgid "Channel" +msgstr "" + +#. module: base +#: field:res.lang,grouping:0 +msgid "Separator Format" +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Unvalidated" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_9 +msgid "Database Structure" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_mass_mail +#: model:ir.model,name:base.model_partner_wizard_spam +#: view:partner.wizard.spam:0 +msgid "Mass Mailing" +msgstr "" + +#. module: base +#: model:res.country,name:base.yt +msgid "Mayotte" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:597 +#, python-format +msgid "Please specify an action to launch !" +msgstr "" + +#. module: base +#: view:res.payterm:0 +msgid "Payment Term" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Right-to-Left" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.actions_ir_filters_view +#: view:ir.filters:0 +#: model:ir.model,name:base.model_ir_filters +#: model:ir.ui.menu,name:base.menu_ir_filters +msgid "Filters" +msgstr "" + +#. module: base +#: code:addons/orm.py:758 +#, python-format +msgid "Please check that all your lines have %d columns." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_cron_act +#: view:ir.cron:0 +#: model:ir.ui.menu,name:base.menu_ir_cron_act +msgid "Scheduled Actions" +msgstr "" + +#. module: base +#: field:res.partner.address,title:0 +#: field:res.partner.title,name:0 +#: field:res.widget,title:0 +msgid "Title" +msgstr "" + +#. module: base +#: help:ir.property,res_id:0 +msgid "If not set, acts as a default value for new resources" +msgstr "" + +#. module: base +#: code:addons/orm.py:3448 +#, python-format +msgid "Recursivity Detected." +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:262 +#, python-format +msgid "Recursion error in modules dependencies !" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"This wizard helps you add a new language to your OpenERP system. After " +"loading a new language it becomes available as default interface language " +"for users and partners." +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Create a Menu" +msgstr "" + +#. module: base +#: help:res.partner,vat:0 +msgid "" +"Value Added Tax number. Check the box if the partner is subjected to the " +"VAT. Used by the VAT legal statement." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_maintenance_contract +msgid "maintenance.contract" +msgstr "" + +#. module: base +#: model:res.country,name:base.ru +msgid "Russian Federation" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Urdu / اردو" +msgstr "烏爾都文 / اردو" + +#. module: base +#: field:res.company,name:0 +msgid "Company Name" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country +#: model:ir.ui.menu,name:base.menu_country_partner +msgid "Countries" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "RML (deprecated - use Report)" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Record rules" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Field Information" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Search Actions" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check +#: view:partner.wizard.ean.check:0 +msgid "Ean check" +msgstr "" + +#. module: base +#: field:res.partner,vat:0 +msgid "VAT" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "12. %w ==> 5 ( Friday is the 6th day)" +msgstr "" + +#. module: base +#: constraint:res.partner.category:0 +msgid "Error ! You can not create recursive categories." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%x - Appropriate date representation." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%d - Day of the month [01,31]." +msgstr "" + +#. module: base +#: model:res.country,name:base.tj +msgid "Tajikistan" +msgstr "塔吉克" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-2 or later version" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_sir +msgid "M." +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:429 +#, python-format +msgid "" +"Can not create the module file:\n" +" %s" +msgstr "" + +#. module: base +#: code:addons/orm.py:2973 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: read, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.nr +msgid "Nauru" +msgstr "瑙魯" + +#. module: base +#: code:addons/base/module/module.py:200 +#, python-format +msgid "The certificate ID of the module must be unique !" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_property +msgid "ir.property" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window,view_type:0 +#: selection:ir.actions.act_window.view,view_mode:0 +#: view:ir.ui.view:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Form" +msgstr "" + +#. module: base +#: model:res.country,name:base.me +msgid "Montenegro" +msgstr "黑山" + +#. module: base +#: view:ir.cron:0 +msgid "Technical Data" +msgstr "技術資料" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,category_id:0 +msgid "Categories" +msgstr "分類" + +#. module: base +#: view:base.language.import:0 +msgid "" +"If you need another language than the official ones available, you can " +"import a language pack from here. Other OpenERP languages than the official " +"ones can be found on launchpad." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be upgraded" +msgstr "" + +#. module: base +#: model:res.country,name:base.ly +msgid "Libya" +msgstr "利比亞" + +#. module: base +#: model:res.country,name:base.cf +msgid "Central African Republic" +msgstr "中非共和國" + +#. module: base +#: model:res.country,name:base.li +msgid "Liechtenstein" +msgstr "列支敦士登" + +#. module: base +#: model:ir.model,name:base.model_partner_sms_send +#: view:partner.sms.send:0 +msgid "Send SMS" +msgstr "" + +#. module: base +#: field:res.partner,ean13:0 +msgid "EAN13" +msgstr "" + +#. module: base +#: code:addons/orm.py:1622 +#, python-format +msgid "Invalid Architecture!" +msgstr "" + +#. module: base +#: model:res.country,name:base.pt +msgid "Portugal" +msgstr "葡萄牙" + +#. module: base +#: sql_constraint:ir.model.data:0 +msgid "" +"You cannot have multiple records with the same id for the same module !" +msgstr "" + +#. module: base +#: field:ir.module.module,certificate:0 +msgid "Quality Certificate" +msgstr "品質證書" + +#. module: base +#: view:res.lang:0 +msgid "6. %d, %m ==> 05, 12" +msgstr "" + +#. module: base +#: field:res.config.users,date:0 +#: field:res.users,date:0 +msgid "Last Connection" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,help:0 +msgid "Action description" +msgstr "" + +#. module: base +#: help:res.partner,customer:0 +msgid "Check this box if the partner is a customer." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_lang_act_window +#: model:ir.model,name:base.model_res_lang +#: model:ir.ui.menu,name:base.menu_res_lang_act_window +#: view:res.lang:0 +msgid "Languages" +msgstr "語言" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "Xor" +msgstr "" + +#. module: base +#: model:res.country,name:base.ec +msgid "Ecuador" +msgstr "厄瓜多爾" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:52 +#, python-format +msgid "" +"Save this document to a .CSV file and open it with your favourite " +"spreadsheet software. The file encoding is UTF-8. You have to translate the " +"latest column before reimporting it." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_customer_form +#: model:ir.actions.act_window,name:base.action_partner_form +#: model:ir.ui.menu,name:base.menu_partner_form +#: view:res.partner:0 +msgid "Customers" +msgstr "" + +#. module: base +#: model:res.country,name:base.au +msgid "Australia" +msgstr "澳洲" + +#. module: base +#: help:res.partner,lang:0 +msgid "" +"If the selected language is loaded in the system, all documents related to " +"this partner will be printed in this language. If not, it will be english." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Menu :" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Base Field" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Validate" +msgstr "" + +#. module: base +#: field:ir.actions.todo,restart:0 +msgid "Restart" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_sxw_content:0 +#: field:ir.actions.report.xml,report_sxw_content_data:0 +msgid "SXW content" +msgstr "" + +#. module: base +#: view:ir.actions.wizard:0 +#: field:wizard.ir.model.menu.create.line,wizard_id:0 +msgid "Wizard" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Action to Trigger" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:136 +#, python-format +msgid "\"email_from\" needs to be set to send welcome mails to users" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Constraint" +msgstr "約束" + +#. module: base +#: selection:ir.values,key:0 +#: selection:res.partner.address,type:0 +msgid "Default" +msgstr "預設" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,required:0 +#: field:res.partner.bank.type.field,required:0 +msgid "Required" +msgstr "必要" + +#. module: base +#: view:res.users:0 +msgid "Default Filters" +msgstr "" + +#. module: base +#: field:res.request.history,name:0 +msgid "Summary" +msgstr "摘要" + +#. module: base +#: field:multi_company.default,expression:0 +msgid "Expression" +msgstr "" + +#. module: base +#: help:ir.actions.server,subject:0 +msgid "" +"Specify the subject. You can use fields from the object, e.g. `Hello [[ " +"object.partner_id.name ]]`" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Header/Footer" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,help:0 +msgid "" +"Optional help text for the users with a description of the target view, such " +"as its usage and purpose." +msgstr "" + +#. module: base +#: model:res.country,name:base.va +msgid "Holy See (Vatican City State)" +msgstr "梵蒂岡" + +#. module: base +#: field:base.module.import,module_file:0 +msgid "Module .ZIP file" +msgstr "" + +#. module: base +#: field:ir.ui.view,xml_id:0 +msgid "XML ID" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_16 +msgid "Telecom sector" +msgstr "電訊範疇" + +#. module: base +#: field:workflow.transition,trigger_model:0 +msgid "Trigger Object" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Current Activity" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,in_transitions:0 +msgid "Incoming Transitions" +msgstr "" + +#. module: base +#: model:res.country,name:base.sr +msgid "Suriname" +msgstr "蘇里南" + +#. module: base +#: model:ir.ui.menu,name:base.marketing_menu +msgid "Marketing" +msgstr "營銷" + +#. module: base +#: view:res.partner.bank:0 +#: model:res.partner.bank.type,name:base.bank_normal +msgid "Bank account" +msgstr "銀行帳戶" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (HN) / Español (HN)" +msgstr "西班牙文 (HN) / Español (HN)" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequence Type" +msgstr "" + +#. module: base +#: view:ir.ui.view.custom:0 +msgid "Customized Architecture" +msgstr "" + +#. module: base +#: field:ir.module.module,license:0 +msgid "License" +msgstr "" + +#. module: base +#: field:ir.attachment,url:0 +msgid "Url" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "Always" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "SQL Constraint" +msgstr "" + +#. module: base +#: field:ir.actions.server,srcmodel_id:0 +#: field:ir.model.fields,model_id:0 +msgid "Model" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "" +"The selected language has been successfully installed. You must change the " +"preferences of the user and open a new menu to view the changes." +msgstr "" + +#. module: base +#: sql_constraint:ir.config_parameter:0 +msgid "Key must be unique." +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open a Window" +msgstr "" + +#. module: base +#: model:res.country,name:base.gq +msgid "Equatorial Guinea" +msgstr "赤道畿內亞" + +#. module: base +#: view:base.module.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_module_import +msgid "Module Import" +msgstr "" + +#. module: base +#: field:res.bank,zip:0 +#: field:res.partner.address,zip:0 +#: field:res.partner.bank,zip:0 +msgid "Zip" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,author:0 +msgid "Author" +msgstr "" + +#. module: base +#: model:res.country,name:base.mk +msgid "FYROM" +msgstr "馬其頓" + +#. module: base +#: view:res.lang:0 +msgid "%c - Appropriate date and time representation." +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:422 +#, python-format +msgid "" +"Your database is now fully configured.\n" +"\n" +"Click 'Continue' and enjoy your OpenERP experience..." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hebrew / עִבְרִי" +msgstr "希伯來文 / עִבְרִי" + +#. module: base +#: model:res.country,name:base.bo +msgid "Bolivia" +msgstr "玻利維亞" + +#. module: base +#: model:res.country,name:base.gh +msgid "Ghana" +msgstr "加納" + +#. module: base +#: field:res.lang,direction:0 +msgid "Direction" +msgstr "方向" + +#. module: base +#: view:ir.actions.act_window:0 +#: model:ir.actions.act_window,name:base.action_ui_view +#: field:ir.actions.act_window,view_ids:0 +#: field:ir.actions.act_window,views:0 +#: field:ir.module.module,views_by_module:0 +#: model:ir.ui.menu,name:base.menu_action_ui_view +#: view:ir.ui.view:0 +msgid "Views" +msgstr "檢視" + +#. module: base +#: view:res.groups:0 +#: field:res.groups,rule_groups:0 +msgid "Rules" +msgstr "規則" + +#. module: base +#: code:addons/base/module/module.py:216 +#, python-format +msgid "You try to remove a module that is installed or will be installed" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "The selected modules have been updated / installed !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PR) / Español (PR)" +msgstr "西班牙文 (PR) / Español (PR)" + +#. module: base +#: model:res.country,name:base.gt +msgid "Guatemala" +msgstr "危地馬拉" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_form +#: model:ir.ui.menu,name:base.menu_low_workflow +#: model:ir.ui.menu,name:base.menu_workflow +#: model:ir.ui.menu,name:base.menu_workflow_root +msgid "Workflows" +msgstr "" + +#. module: base +#: field:ir.translation,xml_id:0 +msgid "XML Id" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_config_user_form +msgid "Create Users" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_title +msgid "res.partner.title" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "tree_but_action, client_print_multi" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_retailers0 +msgid "Retailers" +msgstr "零售商" + +#. module: base +#: help:ir.cron,priority:0 +msgid "" +"0=Very Urgent\n" +"10=Not urgent" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "Skip" +msgstr "" + +#. module: base +#: model:res.country,name:base.ls +msgid "Lesotho" +msgstr "萊索托" + +#. module: base +#: code:addons/base/ir/ir_model.py:114 +#, python-format +msgid "You can not remove the model '%s' !" +msgstr "" + +#. module: base +#: model:res.country,name:base.ke +msgid "Kenya" +msgstr "肯雅" + +#. module: base +#: view:res.partner.event:0 +msgid "Event" +msgstr "活動" + +#. module: base +#: model:ir.ui.menu,name:base.menu_custom_reports +msgid "Custom Reports" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Abkhazian / аҧсуа" +msgstr "阿布哈茲文 / аҧсуа" + +#. module: base +#: view:base.module.configuration:0 +msgid "System Configuration Done" +msgstr "" + +#. module: base +#: code:addons/orm.py:929 +#, python-format +msgid "Error occurred while validating the field(s) %s: %s" +msgstr "" + +#. module: base +#: view:ir.property:0 +msgid "Generic" +msgstr "通用" + +#. module: base +#: model:res.country,name:base.sm +msgid "San Marino" +msgstr "聖馬力諾" + +#. module: base +#: model:res.country,name:base.bm +msgid "Bermuda" +msgstr "百慕達" + +#. module: base +#: model:res.country,name:base.pe +msgid "Peru" +msgstr "秘魯" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Set NULL" +msgstr "" + +#. module: base +#: model:res.country,name:base.bj +msgid "Benin" +msgstr "貝寧" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:281 +#, python-format +msgid "That contract is already registered in the system." +msgstr "" + +#. module: base +#: help:ir.sequence,suffix:0 +msgid "Suffix value of the record for the sequence" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PY) / Español (PY)" +msgstr "西班牙文 (PY) / Español (PY)" + +#. module: base +#: field:ir.config_parameter,key:0 +msgid "Key" +msgstr "" + +#. module: base +#: field:res.company,rml_header:0 +msgid "RML Header" +msgstr "" + +#. module: base +#: field:partner.sms.send,app_id:0 +msgid "API ID" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:486 +#, python-format +msgid "" +"You can not create this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:res.country,name:base.mu +msgid "Mauritius" +msgstr "毛里裘斯" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +msgid "Full Access" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.wizard:0 +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.menu_security +msgid "Security" +msgstr "保安" + +#. module: base +#: model:res.widget,title:base.openerp_favorites_twitter_widget +msgid "OpenERP Favorites" +msgstr "" + +#. module: base +#: model:res.country,name:base.za +msgid "South Africa" +msgstr "南非" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Installed" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Ukrainian / українська" +msgstr "烏克蘭文 / українська" + +#. module: base +#: model:ir.actions.act_window,name:base.action_translation +#: model:ir.ui.menu,name:base.menu_action_translation +msgid "Translation Terms" +msgstr "" + +#. module: base +#: model:res.country,name:base.sn +msgid "Senegal" +msgstr "塞內加爾" + +#. module: base +#: model:res.country,name:base.hu +msgid "Hungary" +msgstr "匈牙利" + +#. module: base +#: model:ir.model,name:base.model_res_groups +msgid "res.groups" +msgstr "" + +#. module: base +#: model:res.country,name:base.br +msgid "Brazil" +msgstr "巴西" + +#. module: base +#: view:res.lang:0 +msgid "%M - Minute [00,59]." +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Affero GPL-3" +msgstr "" + +#. module: base +#: field:ir.sequence,number_next:0 +msgid "Next Number" +msgstr "" + +#. module: base +#: help:workflow.transition,condition:0 +msgid "Expression to be satisfied if we want the transition done." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PA) / Español (PA)" +msgstr "西班牙文 (PA) / Español (PA)" + +#. module: base +#: view:res.currency:0 +#: field:res.currency,rate_ids:0 +msgid "Rates" +msgstr "匯率" + +#. module: base +#: model:res.country,name:base.sy +msgid "Syria" +msgstr "敍利亞" + +#. module: base +#: view:res.lang:0 +msgid "======================================================" +msgstr "" + +#. module: base +#: help:ir.actions.server,mobile:0 +msgid "" +"Provides fields that be used to fetch the mobile number, e.g. you select the " +"invoice, then `object.invoice_address_id.mobile` is the field which gives " +"the correct mobile number" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System update completed" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "draft" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +#: field:res.currency,date:0 +#: field:res.currency.rate,name:0 +#: field:res.partner,date:0 +#: field:res.partner.event,date:0 +#: field:res.request,date_sent:0 +msgid "Date" +msgstr "日期" + +#. module: base +#: field:ir.actions.report.xml,report_sxw:0 +msgid "SXW path" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Data" +msgstr "" + +#. module: base +#: field:ir.ui.menu,parent_id:0 +#: field:wizard.ir.model.menu.create,menu_id:0 +msgid "Parent Menu" +msgstr "" + +#. module: base +#: field:ir.rule,perm_unlink:0 +msgid "Apply For Delete" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:319 +#, python-format +msgid "Cannot rename column to %s, because that column already exists!" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Attached To" +msgstr "" + +#. module: base +#: field:res.lang,decimal_point:0 +msgid "Decimal Separator" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_groups +msgid "" +"A group is a set of functional areas that will be assigned to the user in " +"order to give them access and rights to specific applications and tasks in " +"the system. You can create custom groups or edit the ones existing by " +"default in order to customize the view of the menu that users will be able " +"to see. Whether they can have a read, write, create and delete access right " +"can be managed from here." +msgstr "" + +#. module: base +#: view:res.partner:0 +#: view:res.request:0 +#: field:res.request,history:0 +msgid "History" +msgstr "" + +#. module: base +#: field:ir.attachment,create_uid:0 +msgid "Creator" +msgstr "" + +#. module: base +#: model:res.company,overdue_msg:base.main_company +msgid "" +"Please note that the following payments are now due. If your payment " +" has been sent, kindly forward your payment details. If " +"payment will be delayed further, please contact us " +"to discuss. \n" +"Would your payment have been carried out after this mail was sent, please " +"consider the present one as void." +msgstr "" + +#. module: base +#: model:res.country,name:base.mx +msgid "Mexico" +msgstr "墨西哥" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config_plugins +msgid "Plugins" +msgstr "" + +#. module: base +#: field:res.company,child_ids:0 +msgid "Child Companies" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_users +msgid "res.users" +msgstr "" + +#. module: base +#: model:res.country,name:base.ni +msgid "Nicaragua" +msgstr "" + +#. module: base +#: code:addons/orm.py:1046 +#, python-format +msgid "The write method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "General Description" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_config_simple_view_form +#: view:res.config.view:0 +msgid "Configure Your Interface" +msgstr "" + +#. module: base +#: field:ir.values,meta:0 +msgid "Meta Datas" +msgstr "" + +#. module: base +#: sql_constraint:ir.ui.view_sc:0 +msgid "Shortcut for this menu already exists!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ve +msgid "Venezuela" +msgstr "委內瑞拉" + +#. module: base +#: view:res.lang:0 +msgid "9. %j ==> 340" +msgstr "" + +#. module: base +#: model:res.country,name:base.zm +msgid "Zambia" +msgstr "贊比亞" + +#. module: base +#: help:res.partner,user_id:0 +msgid "" +"The internal user that is in charge of communicating with this partner if " +"any." +msgstr "" + +#. module: base +#: field:res.partner,parent_id:0 +msgid "Parent Partner" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Upgrade" +msgstr "" + +#. module: base +#: model:res.country,name:base.ci +msgid "Ivory Coast (Cote D'Ivoire)" +msgstr "科特迪瓦(象牙海岸)" + +#. module: base +#: model:res.country,name:base.kz +msgid "Kazakhstan" +msgstr "哈薩克" + +#. module: base +#: view:res.lang:0 +msgid "%w - Weekday number [0(Sunday),6]." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_form +msgid "" +"A customer is an entity you do business with, like a company or an " +"organization. A customer can have several contacts or addresses which are " +"the people working for this company. You can use the history tab, to follow " +"all transactions related to a customer: sales order, emails, opportunities, " +"claims, etc. If you use the email gateway, the Outlook or the Thunderbird " +"plugin, don't forget to register emails to each contact so that the gateway " +"will automatically attach incoming emails to the right partner." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,name:0 +#: field:ir.actions.todo,name:0 +#: field:ir.cron,name:0 +#: field:ir.model.access,name:0 +#: field:ir.model.fields,name:0 +#: field:ir.module.category,name:0 +#: field:ir.module.module,name:0 +#: field:ir.module.module.dependency,name:0 +#: report:ir.module.reference.graph:0 +#: field:ir.property,name:0 +#: field:ir.rule,name:0 +#: field:ir.sequence,name:0 +#: field:ir.sequence.type,name:0 +#: field:ir.values,name:0 +#: field:multi_company.default,name:0 +#: field:res.bank,name:0 +#: field:res.config.view,name:0 +#: field:res.lang,name:0 +#: field:res.partner,name:0 +#: field:res.partner.bank.type,name:0 +#: view:res.partner.event:0 +#: field:res.request.link,name:0 +#: field:workflow,name:0 +#: field:workflow.activity,name:0 +msgid "Name" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,multi:0 +msgid "" +"If set to true, the action will not be displayed on the right toolbar of a " +"form view" +msgstr "" + +#. module: base +#: model:res.country,name:base.ms +msgid "Montserrat" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:205 +#, python-format +msgid "" +"The Selection Options expression is not a valid Pythonic expression.Please " +"provide an expression in the [('key','Label'), ...] format." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_translation_app +msgid "Application Terms" +msgstr "" + +#. module: base +#: help:res.config.users,context_tz:0 +#: help:res.users,context_tz:0 +msgid "" +"The user's timezone, used to perform timezone conversions between the server " +"and the client." +msgstr "" + +#. module: base +#: field:ir.module.module,demo:0 +msgid "Demo data" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (UK)" +msgstr "英文 (英國)" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Japanese / 日本語" +msgstr "日文 / 日本語" + +#. module: base +#: help:workflow.transition,act_from:0 +msgid "" +"Source activity. When this activity is over, the condition is tested to " +"determine if we can start the ACT_TO activity." +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_3 +msgid "Starter Partner" +msgstr "" + +#. module: base +#: help:ir.model.fields,relation_field:0 +msgid "" +"For one2many fields, the field on the target model that implement the " +"opposite many2one relationship" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window_view +msgid "ir.actions.act_window.view" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Web" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (CA)" +msgstr "英文 (加拿大)" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract +msgid "publisher_warranty.contract" +msgstr "" + +#. module: base +#: model:res.country,name:base.et +msgid "Ethiopia" +msgstr "埃塞俄比亞" + +#. module: base +#: help:res.country.state,code:0 +msgid "The state code in three chars.\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.sj +msgid "Svalbard and Jan Mayen Islands" +msgstr "斯瓦爾巴羣島" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_wizard +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.wizard" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +#: view:ir.actions.report.xml:0 +#: view:ir.actions.server:0 +#: view:ir.filters:0 +#: view:res.request:0 +msgid "Group By" +msgstr "" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "title" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_language_install +msgid "Install Language" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Translation" +msgstr "" + +#. module: base +#: selection:res.request,state:0 +msgid "closed" +msgstr "" + +#. module: base +#: selection:base.language.export,state:0 +msgid "get" +msgstr "" + +#. module: base +#: help:ir.model.fields,on_delete:0 +msgid "On delete property for many2one fields" +msgstr "" + +#. module: base +#: field:ir.actions.server,write_id:0 +msgid "Write Id" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_product +msgid "Products" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,domain:0 +#: field:ir.filters,domain:0 +msgid "Domain Value" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "SMS Configuration" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (BO) / Español (BO)" +msgstr "西班牙文 (BO) / Español (BO)" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_access_act +#: model:ir.ui.menu,name:base.menu_ir_access_act +msgid "Access Controls List" +msgstr "" + +#. module: base +#: model:res.country,name:base.um +msgid "USA Minor Outlying Islands" +msgstr "" + +#. module: base +#: field:res.partner.bank,state:0 +#: field:res.partner.bank.type.field,bank_type_id:0 +msgid "Bank Type" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:58 +#: code:addons/base/res/res_user.py:67 +#, python-format +msgid "The name of the group can not start with \"-\"" +msgstr "" + +#. module: base +#: view:ir.ui.view_sc:0 +#: field:res.partner.title,shortcut:0 +msgid "Shortcut" +msgstr "" + +#. module: base +#: field:ir.model.data,date_init:0 +msgid "Init Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Gujarati / ગુજરાતી" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:257 +#, python-format +msgid "" +"Unable to process module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Please enter the serial key provided in your contract document:" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_start:0 +msgid "Flow Start" +msgstr "" + +#. module: base +#: code:addons/__init__.py:834 +#, python-format +msgid "module base cannot be loaded! (hint: verify addons-path)" +msgstr "" + +#. module: base +#: view:res.partner.bank:0 +msgid "Bank Account Owner" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form +msgid "Client Actions Connections" +msgstr "" + +#. module: base +#: field:ir.attachment,res_name:0 +#: field:ir.ui.view_sc,resource:0 +msgid "Resource Name" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Hours" +msgstr "" + +#. module: base +#: model:res.country,name:base.gp +msgid "Guadeloupe (French)" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:157 +#: code:addons/base/res/res_lang.py:159 +#: code:addons/base/res/res_lang.py:161 +#, python-format +msgid "User Error" +msgstr "" + +#. module: base +#: help:workflow.transition,signal:0 +msgid "" +"When the operation of transition comes from a button pressed in the client " +"form, signal tests the name of the pressed button. If signal is NULL, no " +"button is necessary to validate this transition." +msgstr "" + +#. module: base +#: help:multi_company.default,object_id:0 +msgid "Object affected by this rule" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Directory" +msgstr "" + +#. module: base +#: field:wizard.ir.model.menu.create,name:0 +msgid "Menu Name" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Author Website" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Month" +msgstr "" + +#. module: base +#: model:res.country,name:base.my +msgid "Malaysia" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: model:ir.actions.act_window,name:base.action_view_base_language_install +msgid "Load Official Translation" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_request_history +msgid "res.request.history" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Client Action Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_address +#: view:res.partner.address:0 +msgid "Partner Addresses" +msgstr "" + +#. module: base +#: help:ir.model.fields,translate:0 +msgid "" +"Whether values for this field can be translated (enables the translation " +"mechanism for that field)" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%S - Seconds [00,61]." +msgstr "" + +#. module: base +#: model:res.country,name:base.cv +msgid "Cape Verde" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Select module package to import (.zip file):" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_res_partner_event +#: field:res.partner,events:0 +#: field:res.partner.event,name:0 +#: model:res.widget,title:base.events_widget +msgid "Events" +msgstr "活動" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_url +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.url" +msgstr "" + +#. module: base +#: model:res.widget,title:base.currency_converter_widget +msgid "Currency Converter" +msgstr "" + +#. module: base +#: code:addons/orm.py:156 +#, python-format +msgid "Wrong ID for the browse record, got %r, expected an integer." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_addess_tree +#: view:res.partner:0 +msgid "Partner Contacts" +msgstr "" + +#. module: base +#: field:base.module.update,add:0 +msgid "Number of modules added" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Price Accuracy" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Latvian / latviešu valoda" +msgstr "拉脫維亞文 / latviešu valoda" + +#. module: base +#: view:res.config:0 +#: view:res.config.installer:0 +msgid "vsep" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French / Français" +msgstr "法文 / Français" + +#. module: base +#: code:addons/orm.py:1049 +#, python-format +msgid "The create method is not implemented on this object !" +msgstr "" + +#. module: base +#: field:workflow.triggers,workitem_id:0 +msgid "Workitem" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Set as Todo" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,act_window_id:0 +#: view:ir.actions.actions:0 +#: field:ir.actions.todo,action_id:0 +#: field:ir.ui.menu,action:0 +#: field:ir.values,action_id:0 +#: selection:ir.values,key:0 +#: view:res.users:0 +msgid "Action" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Email Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_cron +msgid "ir.cron" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "Combination of rules" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year without Century: %(y)s" +msgstr "" + +#. module: base +#: field:ir.actions.server,trigger_obj_id:0 +msgid "Trigger On" +msgstr "" + +#. module: base +#: sql_constraint:ir.rule:0 +msgid "Rule must have at least one checked access right !" +msgstr "" + +#. module: base +#: model:res.country,name:base.fj +msgid "Fiji" +msgstr "" + +#. module: base +#: field:ir.model.fields,size:0 +msgid "Size" +msgstr "" + +#. module: base +#: model:res.country,name:base.sd +msgid "Sudan" +msgstr "蘇丹" + +#. module: base +#: model:res.country,name:base.fm +msgid "Micronesia" +msgstr "" + +#. module: base +#: view:res.request.history:0 +msgid "Request History" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,menus:0 +#: field:ir.module.module,menus_by_module:0 +#: view:res.groups:0 +msgid "Menus" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Latin) / srpski" +msgstr "塞爾維亞文 (拉丁字母) / srpski" + +#. module: base +#: model:res.country,name:base.il +msgid "Israel" +msgstr "以色列" + +#. module: base +#: model:ir.actions.wizard,name:base.wizard_server_action_create +msgid "Create Action" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_model +#: model:ir.model,name:base.model_ir_model +#: model:ir.ui.menu,name:base.ir_model_model_menu +msgid "Objects" +msgstr "" + +#. module: base +#: field:res.lang,time_format:0 +msgid "Time Format" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Defined Reports" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report xml" +msgstr "" + +#. module: base +#: field:base.language.export,modules:0 +#: model:ir.actions.act_window,name:base.action_module_open_categ +#: model:ir.actions.act_window,name:base.open_module_tree +#: view:ir.module.module:0 +#: model:ir.ui.menu,name:base.menu_management +#: model:ir.ui.menu,name:base.menu_module_tree +msgid "Modules" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: selection:workflow.activity,kind:0 +#: field:workflow.activity,subflow_id:0 +#: field:workflow.workitem,subflow_id:0 +msgid "Subflow" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config +msgid "res.config" +msgstr "" + +#. module: base +#: field:workflow.transition,signal:0 +msgid "Signal (button Name)" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_bank_form +#: model:ir.ui.menu,name:base.menu_action_res_bank_form +#: view:res.bank:0 +#: field:res.partner,bank_ids:0 +msgid "Banks" +msgstr "" + +#. module: base +#: view:res.log:0 +msgid "Unread" +msgstr "" + +#. module: base +#: field:ir.cron,doall:0 +msgid "Repeat Missed" +msgstr "" + +#. module: base +#: help:ir.actions.server,state:0 +msgid "Type of the Action that is to be executed" +msgstr "" + +#. module: base +#: field:ir.server.object.lines,server_id:0 +msgid "Object Mapping" +msgstr "" + +#. module: base +#: help:res.currency,rate:0 +#: help:res.currency.rate,rate:0 +msgid "The rate of the currency to the currency of rate 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.uk +msgid "United Kingdom" +msgstr "英國" + +#. module: base +#: view:res.config:0 +#: view:res.config.users:0 +#: view:res.config.view:0 +msgid "res_config_contents" +msgstr "" + +#. module: base +#: help:res.partner.category,active:0 +msgid "The active field allows you to hide the category without removing it." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Object:" +msgstr "" + +#. module: base +#: model:res.country,name:base.bw +msgid "Botswana" +msgstr "博茨瓦納" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_title_partner +#: model:ir.ui.menu,name:base.menu_partner_title_partner +#: view:res.partner.title:0 +msgid "Partner Titles" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,auto_refresh:0 +msgid "Add an auto-refresh on the view" +msgstr "" + +#. module: base +#: help:res.partner,employee:0 +msgid "Check this box if the partner is an Employee." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_rml_content:0 +#: field:ir.actions.report.xml,report_rml_content_data:0 +msgid "RML content" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_workitem_form +#: model:ir.ui.menu,name:base.menu_workflow_workitem +msgid "Workitems" +msgstr "" + +#. module: base +#: field:base.language.export,advice:0 +msgid "Advice" +msgstr "忠告" + +#. module: base +#: model:ir.model,name:base.model_ir_attachment +msgid "ir.attachment" +msgstr "" + +#. module: base +#: code:addons/orm.py:3533 +#, python-format +msgid "" +"You cannot perform this operation. New Record Creation is not allowed for " +"this object as this object is for reporting purpose." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- module,type,name,res_id,src,value" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Lithuanian / Lietuvių kalba" +msgstr "立陶宛文 / Lietuvių kalba" + +#. module: base +#: help:ir.actions.server,record_id:0 +msgid "" +"Provide the field name where the record id is stored after the create " +"operations. If it is empty, you can not track the new record." +msgstr "" + +#. module: base +#: help:ir.model.fields,relation:0 +msgid "For relationship fields, the technical name of the target model" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Indonesian / Bahasa Indonesia" +msgstr "印尼文 / Bahasa Indonesia" + +#. module: base +#: field:ir.ui.view,inherit_id:0 +msgid "Inherited View" +msgstr "" + +#. module: base +#: view:ir.translation:0 +msgid "Source Term" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_main_pm +msgid "Project" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_hover_data:0 +msgid "Web Icon Image (hover)" +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Module file successfully imported!" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +msgid "Cancelled" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "Create User" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Want to Clear Ids ? " +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,name:0 +#: field:publisher_warranty.contract.wizard,name:0 +msgid "Serial Key" +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "Low" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_audit +msgid "Audit" +msgstr "審計" + +#. module: base +#: model:res.country,name:base.lc +msgid "Saint Lucia" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Maintenance Contract" +msgstr "" + +#. module: base +#: help:ir.actions.server,trigger_obj_id:0 +msgid "Select the object from the model on which the workflow will executed." +msgstr "" + +#. module: base +#: field:res.partner,employee:0 +msgid "Employee" +msgstr "" + +#. module: base +#: field:ir.model.access,perm_create:0 +msgid "Create Access" +msgstr "" + +#. module: base +#: field:res.partner.address,state_id:0 +msgid "Fed. State" +msgstr "" + +#. module: base +#: field:ir.actions.server,copy_object:0 +msgid "Copy Of" +msgstr "" + +#. module: base +#: field:ir.model,osv_memory:0 +msgid "In-memory model" +msgstr "" + +#. module: base +#: view:partner.clear.ids:0 +msgid "Clear Ids" +msgstr "" + +#. module: base +#: model:res.country,name:base.io +msgid "British Indian Ocean Territory" +msgstr "" + +#. module: base +#: field:res.config.users,view:0 +#: field:res.config.view,view:0 +#: field:res.users,view:0 +msgid "Interface" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Field Mapping" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Refresh Validation Dates" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: field:ir.model.fields,ttype:0 +msgid "Field Type" +msgstr "" + +#. module: base +#: field:res.country.state,code:0 +msgid "State Code" +msgstr "" + +#. module: base +#: field:ir.model.fields,on_delete:0 +msgid "On delete" +msgstr "" + +#. module: base +#: selection:res.lang,direction:0 +msgid "Left-to-Right" +msgstr "" + +#. module: base +#: view:res.lang:0 +#: field:res.lang,translatable:0 +msgid "Translatable" +msgstr "" + +#. module: base +#: model:res.country,name:base.vn +msgid "Vietnam" +msgstr "" + +#. module: base +#: field:res.config.users,signature:0 +#: view:res.users:0 +#: field:res.users,signature:0 +msgid "Signature" +msgstr "簽名" + +#. module: base +#: code:addons/fields.py:456 +#: code:addons/fields.py:654 +#: code:addons/fields.py:656 +#: code:addons/fields.py:658 +#: code:addons/fields.py:660 +#: code:addons/fields.py:662 +#: code:addons/fields.py:664 +#, python-format +msgid "Not Implemented" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_user +msgid "res.widget.user" +msgstr "" + +#. module: base +#: field:res.partner.category,complete_name:0 +msgid "Full Name" +msgstr "" + +#. module: base +#: view:base.module.configuration:0 +msgid "_Ok" +msgstr "" + +#. module: base +#: help:ir.filters,user_id:0 +msgid "False means for every user" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:198 +#, python-format +msgid "The name of the module must be unique !" +msgstr "" + +#. module: base +#: model:res.country,name:base.mz +msgid "Mozambique" +msgstr "莫三鼻給" + +#. module: base +#: model:ir.ui.menu,name:base.menu_project_long_term +msgid "Long Term Planning" +msgstr "" + +#. module: base +#: field:ir.actions.server,message:0 +#: view:partner.sms.send:0 +#: field:partner.wizard.spam,text:0 +#: field:res.log,name:0 +msgid "Message" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,multi:0 +msgid "On Multiple Doc." +msgstr "" + +#. module: base +#: view:res.partner:0 +#: field:res.partner,user_id:0 +msgid "Salesman" +msgstr "" + +#. module: base +#: field:res.partner,address:0 +#: view:res.partner.address:0 +msgid "Contacts" +msgstr "" + +#. module: base +#: code:addons/orm.py:3199 +#, python-format +msgid "" +"Unable to delete this document because it is used as a default property" +msgstr "" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Add" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_window +#: model:ir.ui.menu,name:base.menu_view_base_module_upgrade +msgid "Apply Scheduled Upgrades" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Widgets" +msgstr "" + +#. module: base +#: model:res.country,name:base.cz +msgid "Czech Republic" +msgstr "捷克" + +#. module: base +#: view:res.widget.wizard:0 +msgid "Widget Wizard" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.act_ir_actions_todo_form +msgid "" +"The configuration wizards are used to help you configure a new instance of " +"OpenERP. They are launched during the installation of new modules, but you " +"can choose to restart some wizards manually from this menu." +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:206 +#, python-format +msgid "" +"Please use the change password wizard (in User Preferences or User menu) to " +"change your own password." +msgstr "" + +#. module: base +#: code:addons/orm.py:1350 +#, python-format +msgid "Insufficient fields for Calendar View!" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_rml:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another data field" +msgstr "" + +#. module: base +#: help:res.config.users,company_id:0 +#: help:res.users,company_id:0 +msgid "The company this user is currently working for." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_wizard_ir_model_menu_create +msgid "wizard.ir.model.menu.create" +msgstr "" + +#. module: base +#: view:workflow.transition:0 +msgid "Transition" +msgstr "" + +#. module: base +#: field:res.groups,menu_access:0 +msgid "Access Menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.na +msgid "Namibia" +msgstr "" + +#. module: base +#: model:res.country,name:base.mn +msgid "Mongolia" +msgstr "蒙古" + +#. module: base +#: view:ir.module.module:0 +msgid "Created Menus" +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "mdx" +msgstr "" + +#. module: base +#: model:res.country,name:base.bi +msgid "Burundi" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.request:0 +#: wizard_button:server.action.create,init,end:0 +#: wizard_button:server.action.create,step_1,end:0 +msgid "Close" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (MX) / Español (MX)" +msgstr "西班牙文 (MX) / Español (MX)" + +#. module: base +#: view:res.log:0 +msgid "My Logs" +msgstr "" + +#. module: base +#: model:res.country,name:base.bt +msgid "Bhutan" +msgstr "不丹" + +#. module: base +#: help:ir.sequence,number_next:0 +msgid "Next number of this sequence" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_11 +msgid "Textile Suppliers" +msgstr "紡織品供應商" + +#. module: base +#: selection:ir.actions.url,target:0 +msgid "This Window" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contracts" +msgstr "" + +#. module: base +#: help:res.log,name:0 +msgid "The logging message." +msgstr "" + +#. module: base +#: field:base.language.export,format:0 +msgid "File Format" +msgstr "" + +#. module: base +#: field:res.lang,iso_code:0 +msgid "ISO code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_view +msgid "res.config.view" +msgstr "" + +#. module: base +#: view:res.log:0 +#: field:res.log,read:0 +msgid "Read" +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The name of the country must be unique !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_country_state +msgid "" +"If you are working on the American market, you can manage the different " +"federal states you are working on from here. Each state is attached to one " +"country." +msgstr "" + +#. module: base +#: view:workflow.workitem:0 +msgid "Workflow Workitems" +msgstr "" + +#. module: base +#: model:res.country,name:base.vc +msgid "Saint Vincent & Grenadines" +msgstr "" + +#. module: base +#: field:partner.sms.send,password:0 +#: field:res.config.users,password:0 +#: field:res.users,password:0 +msgid "Password" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_fields +#: view:ir.model:0 +#: field:ir.model,field_id:0 +#: model:ir.model,name:base.model_ir_model_fields +#: view:ir.model.fields:0 +#: model:ir.ui.menu,name:base.ir_model_model_fields +msgid "Fields" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_employee_form +msgid "Employees" +msgstr "" + +#. module: base +#: help:res.log,read:0 +msgid "" +"If this log item has been read, get() should not send it to the client" +msgstr "" + +#. module: base +#: field:res.company,rml_header2:0 +#: field:res.company,rml_header3:0 +msgid "RML Internal Header" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view_id:0 +msgid "Search View Ref." +msgstr "" + +#. module: base +#: field:ir.module.module,installed_version:0 +msgid "Latest version" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.res_partner_canal-act +msgid "" +"Track from where is coming your leads and opportunities by creating specific " +"channels that will be maintained at the creation of a document in the " +"system. Some examples of channels can be: Website, Phone Call, Reseller, etc." +msgstr "" + +#. module: base +#: model:res.partner.bank.type.field,name:base.bank_normal_field +msgid "acc_number" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_address_form +#: model:ir.ui.menu,name:base.menu_partner_address_form +msgid "Addresses" +msgstr "" + +#. module: base +#: model:res.country,name:base.mm +msgid "Myanmar" +msgstr "緬甸" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (CN) / 简体中文" +msgstr "中文 (簡體) / 简体中文" + +#. module: base +#: field:res.bank,street:0 +#: field:res.partner.address,street:0 +#: field:res.partner.bank,street:0 +msgid "Street" +msgstr "" + +#. module: base +#: model:res.country,name:base.yu +msgid "Yugoslavia" +msgstr "南斯拉夫" + +#. module: base +#: field:ir.model.data,name:0 +msgid "XML Identifier" +msgstr "" + +#. module: base +#: model:res.country,name:base.ca +msgid "Canada" +msgstr "加拿大" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Unknown" +msgstr "不詳" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users_my +msgid "Change My Preferences" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:164 +#, python-format +msgid "Invalid model name in the action definition." +msgstr "" + +#. module: base +#: field:partner.sms.send,text:0 +msgid "SMS Message" +msgstr "" + +#. module: base +#: model:res.country,name:base.cm +msgid "Cameroon" +msgstr "喀麥隆" + +#. module: base +#: model:res.country,name:base.bf +msgid "Burkina Faso" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +msgid "Skipped" +msgstr "" + +#. module: base +#: selection:ir.model.fields,state:0 +msgid "Custom Field" +msgstr "" + +#. module: base +#: field:ir.module.module,web:0 +msgid "Has a web component" +msgstr "" + +#. module: base +#: model:res.country,name:base.cc +msgid "Cocos (Keeling) Islands" +msgstr "" + +#. module: base +#: selection:base.language.install,state:0 +#: selection:base.module.import,state:0 +#: selection:base.module.update,state:0 +msgid "init" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "11. %U or %W ==> 48 (49th week)" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank_type_field +msgid "Bank type fields" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Dutch / Nederlands" +msgstr "荷蘭文 / Nederlands" + +#. module: base +#: code:addons/base/res/res_config.py:384 +#, python-format +msgid "" +"\n" +"\n" +"This addon is already installed on your system" +msgstr "" + +#. module: base +#: help:ir.cron,interval_number:0 +msgid "Repeat every x." +msgstr "" + +#. module: base +#: wizard_view:server.action.create,step_1:0 +#: wizard_field:server.action.create,step_1,report:0 +msgid "Select Report" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "1cm 28cm 20cm 28cm" +msgstr "" + +#. module: base +#: field:ir.module.module,maintainer:0 +msgid "Maintainer" +msgstr "" + +#. module: base +#: field:ir.sequence,suffix:0 +msgid "Suffix" +msgstr "" + +#. module: base +#: model:res.country,name:base.mo +msgid "Macau" +msgstr "澳門" + +#. module: base +#: model:ir.actions.report.xml,name:base.res_partner_address_report +msgid "Labels" +msgstr "" + +#. module: base +#: field:partner.wizard.spam,email_from:0 +msgid "Sender's email" +msgstr "" + +#. module: base +#: field:ir.default,field_name:0 +msgid "Object Field" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (PE) / Español (PE)" +msgstr "西班牙文 (PE) / Español (PE)" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "French (CH) / Français (CH)" +msgstr "法文 (瑞士) / Français (CH)" + +#. module: base +#: help:res.config.users,action_id:0 +#: help:res.users,action_id:0 +msgid "" +"If specified, this action will be opened at logon for this user, in addition " +"to the standard menu." +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Client Actions" +msgstr "" + +#. module: base +#: code:addons/orm.py:1806 +#, python-format +msgid "The exists method is not implemented on this object !" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:336 +#, python-format +msgid "" +"You try to upgrade a module that depends on the module: %s.\n" +"But this module is not available in your system." +msgstr "" + +#. module: base +#: field:workflow.transition,act_to:0 +msgid "Destination Activity" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Connect Events to Actions" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_update_translations +msgid "base.update.translations" +msgstr "" + +#. module: base +#: field:ir.module.category,parent_id:0 +#: field:res.partner.category,parent_id:0 +msgid "Parent Category" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Integer Big" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +#: selection:res.partner.title,domain:0 +#: view:res.users:0 +msgid "Contact" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_menu +msgid "ir.ui.menu" +msgstr "" + +#. module: base +#: model:res.country,name:base.us +msgid "United States" +msgstr "美國" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Uninstall" +msgstr "" + +#. module: base +#: view:res.bank:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Communication" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "RML Report" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_server_object_lines +msgid "ir.server.object.lines" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:531 +#, python-format +msgid "Module %s: Invalid Quality Certificate" +msgstr "" + +#. module: base +#: model:res.country,name:base.kw +msgid "Kuwait" +msgstr "科威特" + +#. module: base +#: field:workflow.workitem,inst_id:0 +msgid "Instance" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,attachment:0 +msgid "" +"This is the filename of the attachment used to store the printing result. " +"Keep empty to not save the printed reports. You can use a python expression " +"with the object and time variables." +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Many2One" +msgstr "" + +#. module: base +#: model:res.country,name:base.ng +msgid "Nigeria" +msgstr "尼日利亞" + +#. module: base +#: code:addons/base/ir/ir_model.py:250 +#, python-format +msgid "For selection fields, the Selection Options must be given!" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_sms_send +msgid "SMS Send" +msgstr "" + +#. module: base +#: field:res.company,user_ids:0 +msgid "Accepted Users" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon_data:0 +msgid "Web Icon Image" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Values for Event Type" +msgstr "" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Always Searchable" +msgstr "" + +#. module: base +#: model:res.country,name:base.hk +msgid "Hong Kong" +msgstr "香港" + +#. module: base +#: help:ir.actions.server,name:0 +msgid "Easy to Refer action by name e.g. One Sales Order -> Many Invoices" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_address_form +msgid "" +"Customers (also called Partners in other areas of the system) helps you " +"manage your address book of companies whether they are prospects, customers " +"and/or suppliers. The partner form allows you to track and record all the " +"necessary information to interact with your partners from the company " +"address to their contacts as well as pricelists, and much more. If you " +"installed the CRM, with the history tab, you can track all the interactions " +"with a partner such as opportunities, emails, or sales orders issued." +msgstr "" + +#. module: base +#: model:res.country,name:base.ph +msgid "Philippines" +msgstr "菲律賓" + +#. module: base +#: model:res.country,name:base.ma +msgid "Morocco" +msgstr "摩洛哥" + +#. module: base +#: view:res.lang:0 +msgid "2. %a ,%A ==> Fri, Friday" +msgstr "" + +#. module: base +#: field:res.widget,content:0 +msgid "Content" +msgstr "" + +#. module: base +#: help:ir.rule,global:0 +msgid "If no group is specified the rule is global and applied to everyone" +msgstr "" + +#. module: base +#: model:res.country,name:base.td +msgid "Chad" +msgstr "乍得" + +#. module: base +#: model:ir.model,name:base.model_workflow_transition +msgid "workflow.transition" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%a - Abbreviated weekday name." +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Introspection report on objects" +msgstr "" + +#. module: base +#: model:res.country,name:base.pf +msgid "Polynesia (French)" +msgstr "" + +#. module: base +#: model:res.country,name:base.dm +msgid "Dominica" +msgstr "多米尼克" + +#. module: base +#: sql_constraint:publisher_warranty.contract:0 +msgid "" +"Your publisher warranty contract is already subscribed in the system !" +msgstr "" + +#. module: base +#: help:ir.cron,nextcall:0 +msgid "Next planned execution date for this scheduler" +msgstr "" + +#. module: base +#: help:res.config.users,view:0 +#: help:res.users,view:0 +msgid "Choose between the simplified interface and the extended one" +msgstr "" + +#. module: base +#: model:res.country,name:base.np +msgid "Nepal" +msgstr "尼泊爾" + +#. module: base +#: code:addons/orm.py:2307 +#, python-format +msgid "" +"Invalid value for reference field \"%s\" (last part must be a non-zero " +"integer): \"%s\"" +msgstr "" + +#. module: base +#: help:ir.cron,args:0 +msgid "Arguments to be passed to the method. e.g. (uid,)" +msgstr "" + +#. module: base +#: help:ir.ui.menu,groups_id:0 +msgid "" +"If you have groups, the visibility of this menu will be based on these " +"groups. If this field is empty, OpenERP will compute visibility based on the " +"related object's read access." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_ui_view_custom +#: model:ir.ui.menu,name:base.menu_action_ui_view_custom +#: view:ir.ui.view.custom:0 +msgid "Customized Views" +msgstr "" + +#. module: base +#: view:partner.sms.send:0 +msgid "Bulk SMS send" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Seconde: %(sec)s" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_view_base_module_update +msgid "Update Modules List" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:255 +#, python-format +msgid "" +"Unable to upgrade module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:257 +#, python-format +msgid "" +"Please keep in mind that documents currently displayed may not be relevant " +"after switching to another company. If you have unsaved changes, please make " +"sure to save and close all forms before switching to a different company. " +"(You can click on Cancel in the User Preferences now)" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Continue" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Thai / ภาษาไทย" +msgstr "泰文 / ภาษาไทย" + +#. module: base +#: code:addons/orm.py:158 +#, python-format +msgid "Object %s does not exists" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovenian / slovenščina" +msgstr "斯洛文尼亞文 / slovenščina" + +#. module: base +#: field:ir.actions.report.xml,attachment_use:0 +msgid "Reload from Attachment" +msgstr "" + +#. module: base +#: model:res.country,name:base.bv +msgid "Bouvet Island" +msgstr "" + +#. module: base +#: field:ir.attachment,name:0 +msgid "Attachment Name" +msgstr "" + +#. module: base +#: field:base.language.export,data:0 +#: field:base.language.import,data:0 +msgid "File" +msgstr "" + +#. module: base +#: view:res.config.users:0 +msgid "Add User" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install +msgid "Module Upgrade Install" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_configuration_wizard +msgid "ir.actions.configuration.wizard" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%b - Abbreviated month name." +msgstr "" + +#. module: base +#: field:res.partner,supplier:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_supplier_add:0 +#: model:res.partner.category,name:base.res_partner_category_8 +msgid "Supplier" +msgstr "供應商" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Multi Actions" +msgstr "" + +#. module: base +#: view:base.language.export:0 +#: view:base.language.import:0 +#: view:wizard.ir.model.menu.create:0 +msgid "_Close" +msgstr "" + +#. module: base +#: field:multi_company.default,company_dest_id:0 +msgid "Default Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (EC) / Español (EC)" +msgstr "西班牙文 (EC) / Español (EC)" + +#. module: base +#: help:ir.ui.view,xml_id:0 +msgid "ID of the view defined in xml file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_import +#: model:ir.ui.menu,name:base.menu_view_base_module_import +msgid "Import Module" +msgstr "" + +#. module: base +#: model:res.country,name:base.as +msgid "American Samoa" +msgstr "美屬薩摩亞" + +#. module: base +#: help:ir.actions.act_window,res_model:0 +msgid "Model name of the object to open in the view window" +msgstr "" + +#. module: base +#: field:res.log,secondary:0 +msgid "Secondary Log" +msgstr "" + +#. module: base +#: field:ir.model.fields,selectable:0 +msgid "Selectable" +msgstr "" + +#. module: base +#: view:res.request.link:0 +msgid "Request Link" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: field:ir.module.module,url:0 +msgid "URL" +msgstr "" + +#. module: base +#: help:res.country,name:0 +msgid "The full name of the country." +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Iteration" +msgstr "" + +#. module: base +#: code:addons/orm.py:3448 +#: code:addons/orm.py:3532 +#, python-format +msgid "UserError" +msgstr "" + +#. module: base +#: model:res.country,name:base.ae +msgid "United Arab Emirates" +msgstr "阿聯酋" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_case_job_req_main +msgid "Recruitment" +msgstr "" + +#. module: base +#: model:res.country,name:base.re +msgid "Reunion (French)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:321 +#, python-format +msgid "" +"New column name must still start with x_ , because it is a custom field!" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: view:ir.rule:0 +#: field:ir.rule,global:0 +msgid "Global" +msgstr "" + +#. module: base +#: model:res.country,name:base.mp +msgid "Northern Mariana Islands" +msgstr "" + +#. module: base +#: model:res.country,name:base.sb +msgid "Solomon Islands" +msgstr "所羅門羣島" + +#. module: base +#: code:addons/base/ir/ir_model.py:490 +#: code:addons/orm.py:1897 +#: code:addons/orm.py:2972 +#: code:addons/orm.py:3165 +#: code:addons/orm.py:3365 +#: code:addons/orm.py:3817 +#, python-format +msgid "AccessError" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Waiting" +msgstr "" + +#. module: base +#: code:addons/__init__.py:834 +#, python-format +msgid "Could not load base module" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "8. %I:%M:%S %p ==> 06:25:20 PM" +msgstr "" + +#. module: base +#: code:addons/orm.py:1803 +#, python-format +msgid "The copy method is not implemented on this object !" +msgstr "" + +#. module: base +#: field:res.log,create_date:0 +msgid "Creation Date" +msgstr "" + +#. module: base +#: view:ir.translation:0 +#: model:ir.ui.menu,name:base.menu_translation +msgid "Translations" +msgstr "" + +#. module: base +#: field:ir.sequence,padding:0 +msgid "Number Padding" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Report" +msgstr "" + +#. module: base +#: model:res.country,name:base.ua +msgid "Ukraine" +msgstr "烏克蘭" + +#. module: base +#: model:res.country,name:base.to +msgid "Tonga" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_module_category +#: view:ir.module.category:0 +msgid "Module Category" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Ignore" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reference Guide" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Architecture" +msgstr "" + +#. module: base +#: model:res.country,name:base.ml +msgid "Mali" +msgstr "" + +#. module: base +#: help:res.config.users,email:0 +#: help:res.users,email:0 +msgid "" +"If an email is provided, the user will be sent a message welcoming him.\n" +"\n" +"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't " +"be possible to email new users." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Flemish (BE) / Vlaams (BE)" +msgstr "" + +#. module: base +#: field:ir.cron,interval_number:0 +msgid "Interval Number" +msgstr "" + +#. module: base +#: model:res.country,name:base.tk +msgid "Tokelau" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xsl:0 +msgid "XSL path" +msgstr "" + +#. module: base +#: model:res.country,name:base.bn +msgid "Brunei Darussalam" +msgstr "文萊" + +#. module: base +#: view:ir.actions.act_window:0 +#: field:ir.actions.act_window,view_type:0 +#: field:ir.actions.act_window.view,view_mode:0 +#: field:ir.ui.view,type:0 +#: field:wizard.ir.model.menu.create.line,view_type:0 +msgid "View Type" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_2 +msgid "User Interface" +msgstr "" + +#. module: base +#: field:ir.attachment,create_date:0 +msgid "Date Created" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_todo +msgid "ir.actions.todo" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:94 +#, python-format +msgid "Couldn't find previous ir.actions.todo" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "General Settings" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration_shortcut +msgid "Custom Shortcuts" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Vietnamese / Tiếng Việt" +msgstr "越南文 / Tiếng Việt" + +#. module: base +#: model:res.country,name:base.dz +msgid "Algeria" +msgstr "阿爾及利亞" + +#. module: base +#: model:res.country,name:base.be +msgid "Belgium" +msgstr "比利時" + +#. module: base +#: model:ir.model,name:base.model_osv_memory_autovacuum +msgid "osv_memory.autovacuum" +msgstr "" + +#. module: base +#: field:base.language.export,lang:0 +#: field:base.language.install,lang:0 +#: field:base.update.translations,lang:0 +#: field:ir.translation,lang:0 +#: field:res.config.users,context_lang:0 +#: field:res.partner,lang:0 +#: field:res.users,context_lang:0 +msgid "Language" +msgstr "" + +#. module: base +#: model:res.country,name:base.gm +msgid "Gambia" +msgstr "岡比亞" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_company_form +#: model:ir.model,name:base.model_res_company +#: model:ir.ui.menu,name:base.menu_action_res_company_form +#: model:ir.ui.menu,name:base.menu_res_company_global +#: view:res.company:0 +#: field:res.config.users,company_ids:0 +#: view:res.users:0 +#: field:res.users,company_ids:0 +msgid "Companies" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%H - Hour (24-hour clock) [00,23]." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget +msgid "res.widget" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:258 +#, python-format +msgid "Model %s does not exist!" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:159 +#, python-format +msgid "You cannot delete the language which is User's Preferred Language !" +msgstr "" + +#. module: base +#: code:addons/fields.py:103 +#, python-format +msgid "Not implemented get_memory method !" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: field:ir.actions.server,code:0 +#: selection:ir.actions.server,state:0 +msgid "Python Code" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:67 +#, python-format +msgid "Can not create the module file: %s !" +msgstr "" + +#. module: base +#: model:ir.module.module,description:base.module_meta_information +msgid "The kernel of OpenERP, needed for all installation." +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +#: view:base.module.update:0 +#: view:base.module.upgrade:0 +#: view:base.update.translations:0 +#: view:partner.clear.ids:0 +#: view:partner.sms.send:0 +#: view:partner.wizard.spam:0 +#: view:publisher_warranty.contract.wizard:0 +#: view:res.widget.wizard:0 +msgid "Cancel" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "PO File" +msgstr "" + +#. module: base +#: model:res.country,name:base.nt +msgid "Neutral Zone" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Hindi / हिंदी" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Custom" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Current" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_9 +msgid "Components Supplier" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_users +#: field:ir.default,uid:0 +#: model:ir.ui.menu,name:base.menu_action_res_users +#: model:ir.ui.menu,name:base.menu_users +#: view:res.groups:0 +#: field:res.groups,users:0 +#: view:res.users:0 +msgid "Users" +msgstr "" + +#. module: base +#: field:ir.module.module,published_version:0 +msgid "Published Version" +msgstr "" + +#. module: base +#: model:res.country,name:base.is +msgid "Iceland" +msgstr "冰島" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_action_window +#: model:ir.ui.menu,name:base.menu_ir_action_window +msgid "Window Actions" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%I - Hour (12-hour clock) [01,12]." +msgstr "" + +#. module: base +#: selection:publisher_warranty.contract.wizard,state:0 +msgid "Finished" +msgstr "" + +#. module: base +#: model:res.country,name:base.de +msgid "Germany" +msgstr "德國" + +#. module: base +#: view:ir.sequence:0 +msgid "Week of the year: %(woy)s" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_14 +msgid "Bad customers" +msgstr "壞客戶" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Reports :" +msgstr "" + +#. module: base +#: model:res.country,name:base.gy +msgid "Guyana" +msgstr "圭亞那" + +#. module: base +#: help:ir.actions.act_window,view_type:0 +msgid "" +"View type: set to 'tree' for a hierarchical tree view, or 'form' for other " +"views" +msgstr "" + +#. module: base +#: code:addons/base/res/res_config.py:421 +#, python-format +msgid "Click 'Continue' to configure the next addon..." +msgstr "" + +#. module: base +#: field:ir.actions.server,record_id:0 +msgid "Create Id" +msgstr "" + +#. module: base +#: model:res.country,name:base.hn +msgid "Honduras" +msgstr "洪都拉斯" + +#. module: base +#: help:res.config.users,menu_tips:0 +#: help:res.users,menu_tips:0 +msgid "" +"Check out this box if you want to always display tips on each menu action" +msgstr "" + +#. module: base +#: model:res.country,name:base.eg +msgid "Egypt" +msgstr "埃及" + +#. module: base +#: field:ir.rule,perm_read:0 +msgid "Apply For Read" +msgstr "" + +#. module: base +#: help:ir.actions.server,model_id:0 +msgid "" +"Select the object on which the action will work (read, write, create)." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:629 +#, python-format +msgid "Please specify server option --email-from !" +msgstr "" + +#. module: base +#: field:base.language.import,name:0 +msgid "Language Name" +msgstr "" + +#. module: base +#: selection:ir.property,type:0 +msgid "Boolean" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "Fields Description" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: view:ir.cron:0 +#: view:ir.model.access:0 +#: view:ir.model.data:0 +#: view:ir.model.fields:0 +#: view:ir.module.module:0 +#: view:ir.rule:0 +#: view:ir.ui.view:0 +#: view:ir.values:0 +#: view:res.partner:0 +#: view:res.partner.address:0 +#: view:workflow.activity:0 +msgid "Group By..." +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,readonly:0 +#: field:res.partner.bank.type.field,readonly:0 +msgid "Readonly" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,view_id:0 +#: field:ir.default,page:0 +#: selection:ir.translation,type:0 +#: field:wizard.ir.model.menu.create.line,view_id:0 +msgid "View" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "To be installed" +msgstr "" + +#. module: base +#: help:ir.actions.act_window,display_menu_tip:0 +msgid "" +"It gives the status if the tip has to be displayed or not when a user " +"executes an action" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: model:ir.module.module,shortdesc:base.module_meta_information +#: field:res.currency,base:0 +msgid "Base" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Telugu / తెలుగు" +msgstr "" + +#. module: base +#: model:res.country,name:base.lr +msgid "Liberia" +msgstr "利比里亞" + +#. module: base +#: view:ir.attachment:0 +#: view:ir.model:0 +#: view:res.groups:0 +#: view:res.partner:0 +#: field:res.partner,comment:0 +#: model:res.widget,title:base.note_widget +msgid "Notes" +msgstr "" + +#. module: base +#: field:ir.config_parameter,value:0 +#: field:ir.property,value_binary:0 +#: field:ir.property,value_datetime:0 +#: field:ir.property,value_float:0 +#: field:ir.property,value_integer:0 +#: field:ir.property,value_reference:0 +#: field:ir.property,value_text:0 +#: selection:ir.server.object.lines,type:0 +#: field:ir.server.object.lines,value:0 +#: view:ir.values:0 +#: field:ir.values,value:0 +#: field:ir.values,value_unpickle:0 +msgid "Value" +msgstr "" + +#. module: base +#: field:ir.sequence,code:0 +#: field:ir.sequence.type,code:0 +#: selection:ir.translation,type:0 +#: field:res.bank,code:0 +#: field:res.partner.bank.type,code:0 +msgid "Code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_config_installer +msgid "res.config.installer" +msgstr "" + +#. module: base +#: model:res.country,name:base.mc +msgid "Monaco" +msgstr "摩納哥" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Minutes" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Help" +msgstr "" + +#. module: base +#: help:res.config.users,menu_id:0 +#: help:res.users,menu_id:0 +msgid "" +"If specified, the action will replace the standard menu for this user." +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Write Object" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_fundrising +msgid "Fund Raising" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_type +#: model:ir.ui.menu,name:base.menu_ir_sequence_type +msgid "Sequence Codes" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CO) / Español (CO)" +msgstr "西班牙文 (CO) / Español (CO)" + +#. module: base +#: view:base.module.configuration:0 +msgid "" +"All pending configuration wizards have been executed. You may restart " +"individual wizards via the list of configuration wizards." +msgstr "" + +#. module: base +#: wizard_button:server.action.create,step_1,create:0 +msgid "Create" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Current Year with Century: %(year)s" +msgstr "" + +#. module: base +#: field:ir.exports,export_fields:0 +msgid "Export ID" +msgstr "" + +#. module: base +#: model:res.country,name:base.fr +msgid "France" +msgstr "法國" + +#. module: base +#: model:ir.model,name:base.model_res_log +msgid "res.log" +msgstr "" + +#. module: base +#: help:ir.translation,module:0 +#: help:ir.translation,xml_id:0 +msgid "Maps to the ir_model_data for which this translation is provided." +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,flow_stop:0 +msgid "Flow Stop" +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Weeks" +msgstr "" + +#. module: base +#: model:res.country,name:base.af +msgid "Afghanistan, Islamic State of" +msgstr "阿富汗" + +#. module: base +#: code:addons/base/module/wizard/base_module_import.py:67 +#, python-format +msgid "Error !" +msgstr "" + +#. module: base +#: model:res.partner.bank.type.field,name:base.bank_normal_field_contry +msgid "country_id" +msgstr "" + +#. module: base +#: field:ir.cron,interval_type:0 +msgid "Interval Unit" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,kind:0 +#: field:workflow.activity,kind:0 +msgid "Kind" +msgstr "" + +#. module: base +#: code:addons/orm.py:3775 +#, python-format +msgid "This method does not exist anymore" +msgstr "" + +#. module: base +#: field:res.bank,fax:0 +#: field:res.partner.address,fax:0 +msgid "Fax" +msgstr "" + +#. module: base +#: field:res.lang,thousands_sep:0 +msgid "Thousands Separator" +msgstr "" + +#. module: base +#: field:res.request,create_date:0 +msgid "Created Date" +msgstr "" + +#. module: base +#: help:ir.actions.server,loop_action:0 +msgid "" +"Select the action that will be executed. Loop action will not be avaliable " +"inside loop." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Chinese (TW) / 正體字" +msgstr "中文 (繁體) / 正體字" + +#. module: base +#: model:ir.model,name:base.model_res_request +msgid "res.request" +msgstr "" + +#. module: base +#: view:ir.model:0 +msgid "In Memory" +msgstr "" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Todo" +msgstr "" + +#. module: base +#: field:ir.attachment,datas:0 +msgid "File Content" +msgstr "" + +#. module: base +#: model:res.country,name:base.pa +msgid "Panama" +msgstr "巴拿馬" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_ltd +msgid "Ltd" +msgstr "" + +#. module: base +#: help:workflow.transition,group_id:0 +msgid "" +"The group that a user must have to be authorized to validate this transition." +msgstr "" + +#. module: base +#: constraint:res.config.users:0 +#: constraint:res.users:0 +msgid "The chosen company is not in the allowed companies for this user" +msgstr "" + +#. module: base +#: model:res.country,name:base.gi +msgid "Gibraltar" +msgstr "直布羅陀" + +#. module: base +#: field:ir.actions.report.xml,report_name:0 +msgid "Service Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.pn +msgid "Pitcairn Island" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "" +"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_rule +#: model:ir.ui.menu,name:base.menu_action_rule +msgid "Record Rules" +msgstr "" + +#. module: base +#: field:res.config.users,name:0 +#: field:res.users,name:0 +msgid "User Name" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the year: %(doy)s" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.model.fields:0 +#: view:workflow.activity:0 +msgid "Properties" +msgstr "" + +#. module: base +#: help:ir.sequence,padding:0 +msgid "" +"OpenERP will automatically adds some '0' on the left of the 'Next Number' to " +"get the required padding size." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%A - Full weekday name." +msgstr "" + +#. module: base +#: selection:ir.cron,interval_type:0 +msgid "Months" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,search_view:0 +msgid "Search View" +msgstr "" + +#. module: base +#: sql_constraint:res.lang:0 +msgid "The code of the language must be unique !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_attachment +#: view:ir.actions.report.xml:0 +#: view:ir.attachment:0 +#: model:ir.ui.menu,name:base.menu_action_attachment +msgid "Attachments" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_partner +#: model:ir.ui.menu,name:base.menu_sale_config_sales +#: model:ir.ui.menu,name:base.menu_sales +msgid "Sales" +msgstr "" + +#. module: base +#: field:ir.actions.server,child_ids:0 +msgid "Other Actions" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,state:0 +#: view:res.config.users:0 +msgid "Done" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_miss +msgid "Miss" +msgstr "" + +#. module: base +#: view:ir.model.access:0 +#: field:ir.model.access,perm_write:0 +#: view:ir.rule:0 +msgid "Write Access" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%m - Month number [01,12]." +msgstr "" + +#. module: base +#: field:res.bank,city:0 +#: field:res.partner,city:0 +#: field:res.partner.address,city:0 +#: field:res.partner.bank,city:0 +msgid "City" +msgstr "" + +#. module: base +#: model:res.country,name:base.qa +msgid "Qatar" +msgstr "卡塔爾" + +#. module: base +#: model:res.country,name:base.it +msgid "Italy" +msgstr "意大利" + +#. module: base +#: view:ir.actions.todo:0 +#: selection:ir.actions.todo,state:0 +msgid "To Do" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Estonian / Eesti keel" +msgstr "" + +#. module: base +#: field:res.config.users,email:0 +#: field:res.partner,email:0 +#: field:res.users,email:0 +msgid "E-mail" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL-3 or later version" +msgstr "" + +#. module: base +#: field:workflow.activity,action:0 +msgid "Python Action" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "English (US)" +msgstr "英文 (美國)" + +#. module: base +#: model:ir.actions.act_window,name:base.action_model_data +#: view:ir.model.data:0 +#: model:ir.ui.menu,name:base.ir_model_data_menu +msgid "Object Identifiers" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_title_partner +msgid "" +"Manage the partner titles you want to have available in your system. The " +"partner titles is the legal status of the company: Private Limited, SA, etc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "To browse official translations, you can start with these links:" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:484 +#, python-format +msgid "" +"You can not read this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: view:res.bank:0 +#: field:res.config.users,address_id:0 +#: view:res.partner.address:0 +#: view:res.users:0 +#: field:res.users,address_id:0 +msgid "Address" +msgstr "" + +#. module: base +#: field:ir.module.module,latest_version:0 +msgid "Installed version" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Mongolian / монгол" +msgstr "蒙古文 / монгол" + +#. module: base +#: model:res.country,name:base.mr +msgid "Mauritania" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_translation +msgid "ir.translation" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Module update result" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.workitem,act_id:0 +msgid "Activity" +msgstr "動態" + +#. module: base +#: view:res.partner:0 +#: view:res.partner.address:0 +msgid "Postal Address" +msgstr "" + +#. module: base +#: field:res.company,parent_id:0 +msgid "Parent Company" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (CR) / Español (CR)" +msgstr "西班牙文 (CR) / Español (CR)" + +#. module: base +#: field:res.currency.rate,rate:0 +msgid "Rate" +msgstr "" + +#. module: base +#: model:res.country,name:base.cg +msgid "Congo" +msgstr "剛果" + +#. module: base +#: view:res.lang:0 +msgid "Examples" +msgstr "" + +#. module: base +#: field:ir.default,value:0 +msgid "Default Value" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_tools +msgid "Tools" +msgstr "" + +#. module: base +#: model:res.country,name:base.kn +msgid "Saint Kitts & Nevis Anguilla" +msgstr "" + +#. module: base +#: code:addons/base/res/res_currency.py:100 +#, python-format +msgid "" +"No rate found \n" +"for the currency: %s \n" +"at the date: %s" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_ui_view_custom +msgid "" +"Customized views are used when users reorganize the content of their " +"dashboard views (via web client)" +msgstr "" + +#. module: base +#: field:ir.model,name:0 +#: field:ir.model.fields,model:0 +#: field:ir.values,model:0 +msgid "Object Name" +msgstr "" + +#. module: base +#: help:ir.actions.server,srcmodel_id:0 +msgid "" +"Object in which you want to create / write the object. If it is empty then " +"refer to the Object field." +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: selection:ir.module.module,state:0 +#: selection:ir.module.module.dependency,state:0 +msgid "Not Installed" +msgstr "" + +#. module: base +#: view:workflow.activity:0 +#: field:workflow.activity,out_transitions:0 +msgid "Outgoing Transitions" +msgstr "" + +#. module: base +#: field:ir.ui.menu,icon:0 +msgid "Icon" +msgstr "" + +#. module: base +#: help:ir.model.fields,model_id:0 +msgid "The model this field belongs to" +msgstr "" + +#. module: base +#: model:res.country,name:base.mq +msgid "Martinique (French)" +msgstr "" + +#. module: base +#: view:ir.sequence.type:0 +msgid "Sequences Type" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_request-act +#: model:ir.ui.menu,name:base.menu_res_request_act +#: model:ir.ui.menu,name:base.menu_resquest_ref +#: view:res.request:0 +msgid "Requests" +msgstr "" + +#. module: base +#: model:res.country,name:base.ye +msgid "Yemen" +msgstr "也門" + +#. module: base +#: selection:workflow.activity,split_mode:0 +msgid "Or" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_log_act_window +#: model:ir.ui.menu,name:base.menu_res_log_act_window +msgid "Client Logs" +msgstr "" + +#. module: base +#: model:res.country,name:base.al +msgid "Albania" +msgstr "阿爾巴尼亞" + +#. module: base +#: model:res.country,name:base.ws +msgid "Samoa" +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:161 +#, python-format +msgid "" +"You cannot delete the language which is Active !\n" +"Please de-activate the language first." +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: view:base.module.import:0 +msgid "" +"Please be patient, this operation may take a few minutes (depending on the " +"number of modules currently installed)..." +msgstr "" + +#. module: base +#: field:ir.ui.menu,child_id:0 +msgid "Child IDs" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_actions.py:713 +#: code:addons/base/ir/ir_actions.py:716 +#, python-format +msgid "Problem in configuration `Record Id` in Server Action!" +msgstr "" + +#. module: base +#: code:addons/orm.py:2306 +#: code:addons/orm.py:2316 +#, python-format +msgid "ValidateError" +msgstr "" + +#. module: base +#: view:base.module.import:0 +#: view:base.module.update:0 +msgid "Open Modules" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_bank_form +msgid "Manage bank records you want to be used in the system." +msgstr "" + +#. module: base +#: view:base.module.import:0 +msgid "Import module" +msgstr "" + +#. module: base +#: field:ir.actions.server,loop_action:0 +msgid "Loop Action" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,report_file:0 +msgid "" +"The path to the main report file (depending on Report Type) or NULL if the " +"content is in another field" +msgstr "" + +#. module: base +#: model:res.country,name:base.la +msgid "Laos" +msgstr "老撾" + +#. module: base +#: selection:ir.actions.server,state:0 +#: field:res.config.users,user_email:0 +#: field:res.users,user_email:0 +msgid "Email" +msgstr "" + +#. module: base +#: field:res.config.users,action_id:0 +#: field:res.users,action_id:0 +msgid "Home Action" +msgstr "" + +#. module: base +#: code:addons/custom.py:558 +#, python-format +msgid "" +"The sum of the data (2nd field) is null.\n" +"We can't draw a pie chart !" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_lunch_reporting +#: model:ir.ui.menu,name:base.menu_project_report +#: model:ir.ui.menu,name:base.menu_report_association +#: model:ir.ui.menu,name:base.menu_report_marketing +#: model:ir.ui.menu,name:base.menu_reporting +#: model:ir.ui.menu,name:base.next_id_64 +#: model:ir.ui.menu,name:base.next_id_73 +#: model:ir.ui.menu,name:base.reporting_menu +msgid "Reporting" +msgstr "" + +#. module: base +#: model:res.country,name:base.tg +msgid "Togo" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "Other Proprietary" +msgstr "" + +#. module: base +#: selection:workflow.activity,kind:0 +msgid "Stop All" +msgstr "" + +#. module: base +#: code:addons/orm.py:412 +#, python-format +msgid "The read_group method is not implemented on this object !" +msgstr "" + +#. module: base +#: view:ir.model.data:0 +msgid "Updatable" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "3. %x ,%X ==> 12/05/08, 18:25:20" +msgstr "" + +#. module: base +#: selection:ir.model.fields,on_delete:0 +msgid "Cascade" +msgstr "" + +#. module: base +#: field:workflow.transition,group_id:0 +msgid "Group Required" +msgstr "" + +#. module: base +#: view:ir.actions.configuration.wizard:0 +msgid "Next Configuration Step" +msgstr "" + +#. module: base +#: field:res.groups,comment:0 +msgid "Comment" +msgstr "" + +#. module: base +#: model:res.country,name:base.ro +msgid "Romania" +msgstr "羅馬尼亞" + +#. module: base +#: help:ir.cron,doall:0 +msgid "" +"Enable this if you want to execute missed occurences as soon as the server " +"restarts." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Start update" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:144 +#, python-format +msgid "Contract validation error" +msgstr "" + +#. module: base +#: field:res.country.state,name:0 +msgid "State Name" +msgstr "" + +#. module: base +#: field:workflow.activity,join_mode:0 +msgid "Join Mode" +msgstr "" + +#. module: base +#: field:res.config.users,context_tz:0 +#: field:res.users,context_tz:0 +msgid "Timezone" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_report_xml +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.report.xml" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_miss +msgid "Mss" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_ui_view +msgid "ir.ui.view" +msgstr "" + +#. module: base +#: constraint:res.partner:0 +msgid "Error ! You can not create recursive associated members." +msgstr "" + +#. module: base +#: help:res.lang,code:0 +msgid "This field is used to set/get locales for user" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_2 +msgid "OpenERP Partners" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_hr_manager +msgid "HR Manager Dashboard" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:253 +#, python-format +msgid "" +"Unable to install module \"%s\" because an external dependency is not met: %s" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Search modules" +msgstr "" + +#. module: base +#: model:res.country,name:base.by +msgid "Belarus" +msgstr "白俄羅斯" + +#. module: base +#: field:ir.actions.act_window,name:0 +#: field:ir.actions.act_window_close,name:0 +#: field:ir.actions.actions,name:0 +#: field:ir.actions.server,name:0 +#: field:ir.actions.url,name:0 +#: field:ir.filters,name:0 +msgid "Action Name" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_users +msgid "" +"Create and manage users that will connect to the system. Users can be " +"deactivated should there be a period of time during which they will/should " +"not connect to the system. You can assign them groups in order to give them " +"specific access to the applications they need to use in the system." +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "Normal" +msgstr "" + +#. module: base +#: field:res.bank,street2:0 +#: field:res.partner.address,street2:0 +msgid "Street2" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_view_base_module_update +msgid "Module Update" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Following modules are not installed or unknown: %s" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,user_id:0 +#: view:ir.filters:0 +#: field:ir.filters,user_id:0 +#: field:ir.ui.view.custom,user_id:0 +#: field:ir.values,user_id:0 +#: field:res.log,user_id:0 +#: field:res.partner.event,user_id:0 +#: view:res.users:0 +#: field:res.widget.user,user_id:0 +msgid "User" +msgstr "" + +#. module: base +#: model:res.country,name:base.pr +msgid "Puerto Rico" +msgstr "波多黎各" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Open Window" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,auto_search:0 +msgid "Auto Search" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,filter:0 +msgid "Filter" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_madam +msgid "Ms." +msgstr "" + +#. module: base +#: model:res.country,name:base.ch +msgid "Switzerland" +msgstr "瑞士" + +#. module: base +#: model:res.country,name:base.gd +msgid "Grenada" +msgstr "格林納達" + +#. module: base +#: model:res.country,name:base.wf +msgid "Wallis and Futuna Islands" +msgstr "" + +#. module: base +#: selection:server.action.create,init,type:0 +msgid "Open Report" +msgstr "" + +#. module: base +#: field:res.currency,rounding:0 +msgid "Rounding factor" +msgstr "" + +#. module: base +#: view:base.language.install:0 +msgid "Load" +msgstr "" + +#. module: base +#: help:res.config.users,name:0 +#: help:res.users,name:0 +msgid "The new user's real name, used for searching and most listings" +msgstr "" + +#. module: base +#: code:addons/osv.py:154 +#: code:addons/osv.py:156 +#, python-format +msgid "Integrity Error" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_wizard_screen +msgid "ir.wizard.screen" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:223 +#, python-format +msgid "Size of the field can never be less than 1 !" +msgstr "" + +#. module: base +#: model:res.country,name:base.so +msgid "Somalia" +msgstr "索馬里" + +#. module: base +#: selection:publisher_warranty.contract,state:0 +msgid "Terminated" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_13 +msgid "Important customers" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Update Terms" +msgstr "" + +#. module: base +#: field:partner.sms.send,mobile_to:0 +#: field:res.request,act_to:0 +#: field:res.request.history,act_to:0 +msgid "To" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.cron,args:0 +msgid "Arguments" +msgstr "" + +#. module: base +#: code:addons/orm.py:716 +#, python-format +msgid "Database ID doesn't exist: %s : %s" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 2" +msgstr "" + +#. module: base +#: selection:ir.module.module,license:0 +msgid "GPL Version 3" +msgstr "" + +#. module: base +#: code:addons/orm.py:836 +#, python-format +msgid "key '%s' not found in selection field '%s'" +msgstr "" + +#. module: base +#: view:partner.wizard.ean.check:0 +msgid "Correct EAN13" +msgstr "" + +#. module: base +#: code:addons/orm.py:2317 +#, python-format +msgid "The value \"%s\" for the field \"%s\" is not in the selection" +msgstr "" + +#. module: base +#: field:res.partner,customer:0 +#: view:res.partner.address:0 +#: field:res.partner.address,is_customer_add:0 +#: model:res.partner.category,name:base.res_partner_category_0 +msgid "Customer" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (NI) / Español (NI)" +msgstr "西班牙文 (NI) / Español (NI)" + +#. module: base +#: field:ir.module.module,shortdesc:0 +msgid "Short Description" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,context:0 +#: field:ir.filters,context:0 +msgid "Context Value" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->24: %(h24)s" +msgstr "" + +#. module: base +#: field:ir.cron,nextcall:0 +msgid "Next Execution Date" +msgstr "" + +#. module: base +#: help:multi_company.default,field_id:0 +msgid "Select field property" +msgstr "" + +#. module: base +#: field:res.request.history,date_sent:0 +msgid "Date sent" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Month: %(month)s" +msgstr "" + +#. module: base +#: field:ir.actions.act_window.view,sequence:0 +#: field:ir.actions.server,sequence:0 +#: field:ir.actions.todo,sequence:0 +#: view:ir.cron:0 +#: view:ir.sequence:0 +#: field:ir.ui.menu,sequence:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,priority:0 +#: field:ir.ui.view_sc,sequence:0 +#: field:multi_company.default,sequence:0 +#: field:res.partner.bank,sequence:0 +#: field:res.widget.user,sequence:0 +#: field:wizard.ir.model.menu.create.line,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.tn +msgid "Tunisia" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_mrp_root +msgid "Manufacturing" +msgstr "" + +#. module: base +#: model:res.country,name:base.km +msgid "Comoros" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_server_action +#: view:ir.actions.server:0 +#: model:ir.ui.menu,name:base.menu_server_action +msgid "Server Actions" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Cancel Install" +msgstr "" + +#. module: base +#: field:ir.model.fields,selection:0 +msgid "Selection Options" +msgstr "" + +#. module: base +#: field:res.partner.category,parent_right:0 +msgid "Right parent" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "Legends for Date and Time Formats" +msgstr "" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Copy Object" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:581 +#, python-format +msgid "" +"Group(s) cannot be deleted, because some user(s) still belong to them: %s !" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_country_state +#: model:ir.ui.menu,name:base.menu_country_state_partner +msgid "Fed. States" +msgstr "聯邦州" + +#. module: base +#: view:ir.model:0 +#: view:res.groups:0 +msgid "Access Rules" +msgstr "" + +#. module: base +#: field:ir.default,ref_table:0 +msgid "Table Ref." +msgstr "" + +#. module: base +#: field:ir.actions.act_window,res_model:0 +#: field:ir.actions.report.xml,model:0 +#: field:ir.actions.server,model_id:0 +#: field:ir.actions.wizard,model:0 +#: field:ir.cron,model:0 +#: field:ir.default,field_tbl:0 +#: field:ir.filters,model_id:0 +#: field:ir.model,model:0 +#: view:ir.model.access:0 +#: field:ir.model.access,model_id:0 +#: view:ir.model.data:0 +#: field:ir.model.data,model:0 +#: view:ir.model.fields:0 +#: view:ir.rule:0 +#: field:ir.rule,model_id:0 +#: selection:ir.translation,type:0 +#: view:ir.ui.view:0 +#: field:ir.ui.view,model:0 +#: view:ir.values:0 +#: field:ir.values,model_id:0 +#: field:multi_company.default,object_id:0 +#: field:res.log,res_model:0 +#: field:res.request.link,object:0 +#: field:workflow.triggers,model:0 +msgid "Object" +msgstr "" + +#. module: base +#: code:addons/osv.py:151 +#, python-format +msgid "" +"\n" +"\n" +"[object with reference: %s - %s]" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_default +msgid "ir.default" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Minute: %(min)s" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +#: model:ir.actions.act_window,name:base.action_wizard_update_translations +#: model:ir.ui.menu,name:base.menu_wizard_update_translations +msgid "Synchronize Translations" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_10 +msgid "Scheduler" +msgstr "" + +#. module: base +#: help:ir.cron,numbercall:0 +msgid "" +"Number of time the function is called,\n" +"a negative number indicates no limit" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:331 +#, python-format +msgid "" +"Changing the type of a column is not yet supported. Please drop it and " +"create it again!" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,user_id:0 +msgid "User Ref." +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:580 +#, python-format +msgid "Warning !" +msgstr "" + +#. module: base +#: model:res.widget,title:base.google_maps_widget +msgid "Google Maps" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_base_config +#: model:ir.ui.menu,name:base.menu_config +#: model:ir.ui.menu,name:base.menu_event_config +#: model:ir.ui.menu,name:base.menu_lunch_survey_root +#: model:ir.ui.menu,name:base.menu_marketing_config_association +#: model:ir.ui.menu,name:base.menu_marketing_config_root +#: view:res.company:0 +msgid "Configuration" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_publisher_warranty_contract_wizard +msgid "publisher_warranty.contract.wizard" +msgstr "" + +#. module: base +#: field:ir.actions.server,expression:0 +msgid "Loop Expression" +msgstr "" + +#. module: base +#: field:publisher_warranty.contract,date_start:0 +msgid "Starting Date" +msgstr "" + +#. module: base +#: help:res.partner,website:0 +msgid "Website of Partner" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_5 +msgid "Gold Partner" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner +#: field:res.company,partner_id:0 +#: view:res.partner.address:0 +#: field:res.partner.bank,partner_id:0 +#: field:res.partner.event,partner_id:0 +#: selection:res.partner.title,domain:0 +#: model:res.request.link,name:base.req_link_partner +msgid "Partner" +msgstr "" + +#. module: base +#: model:res.country,name:base.tr +msgid "Turkey" +msgstr "土耳其" + +#. module: base +#: model:res.country,name:base.fk +msgid "Falkland Islands" +msgstr "福克蘭羣島" + +#. module: base +#: model:res.country,name:base.lb +msgid "Lebanon" +msgstr "黎巴嫩" + +#. module: base +#: view:ir.actions.report.xml:0 +#: field:ir.actions.report.xml,report_type:0 +msgid "Report Type" +msgstr "" + +#. module: base +#: field:ir.actions.todo,state:0 +#: view:ir.module.module:0 +#: field:ir.module.module,state:0 +#: field:ir.module.module.dependency,state:0 +#: field:publisher_warranty.contract,state:0 +#: field:res.bank,state:0 +#: view:res.country.state:0 +#: field:res.partner.bank,state_id:0 +#: view:res.request:0 +#: field:res.request,state:0 +#: field:workflow.instance,state:0 +#: field:workflow.workitem,state:0 +msgid "State" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Galician / Galego" +msgstr "" + +#. module: base +#: model:res.country,name:base.no +msgid "Norway" +msgstr "挪威" + +#. module: base +#: view:res.lang:0 +msgid "4. %b, %B ==> Dec, December" +msgstr "" + +#. module: base +#: view:base.language.install:0 +#: model:ir.ui.menu,name:base.menu_view_base_language_install +msgid "Load an Official Translation" +msgstr "" + +#. module: base +#: view:res.currency:0 +msgid "Miscelleanous" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_10 +msgid "Open Source Service Company" +msgstr "" + +#. module: base +#: model:res.country,name:base.kg +msgid "Kyrgyz Republic (Kyrgyzstan)" +msgstr "吉爾吉斯" + +#. module: base +#: selection:res.request,state:0 +msgid "waiting" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_file:0 +msgid "Report file" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_triggers +msgid "workflow.triggers" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:62 +#, python-format +msgid "Invalid search criterions" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +msgid "Created" +msgstr "" + +#. module: base +#: help:ir.actions.wizard,multi:0 +msgid "" +"If set to true, the wizard will not be displayed on the right toolbar of a " +"form view." +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "- type,name,res_id,src,value" +msgstr "" + +#. module: base +#: model:res.country,name:base.hm +msgid "Heard and McDonald Islands" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,view_id:0 +msgid "View Ref." +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Selection" +msgstr "" + +#. module: base +#: field:res.company,rml_header1:0 +msgid "Report Header" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,type:0 +#: field:ir.actions.act_window_close,type:0 +#: field:ir.actions.actions,type:0 +#: field:ir.actions.report.xml,type:0 +#: view:ir.actions.server:0 +#: field:ir.actions.server,state:0 +#: field:ir.actions.server,type:0 +#: field:ir.actions.url,type:0 +#: field:ir.actions.wizard,type:0 +msgid "Action Type" +msgstr "" + +#. module: base +#: code:addons/base/module/module.py:268 +#, python-format +msgid "" +"You try to install module '%s' that depends on module '%s'.\n" +"But the latter module is not available in your system." +msgstr "" + +#. module: base +#: view:base.language.import:0 +#: model:ir.actions.act_window,name:base.action_view_base_import_language +#: model:ir.ui.menu,name:base.menu_view_base_import_language +msgid "Import Translation" +msgstr "" + +#. module: base +#: field:res.partner.bank.type,field_ids:0 +msgid "Type fields" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +#: field:ir.module.module,category_id:0 +msgid "Category" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: selection:ir.attachment,type:0 +#: selection:ir.property,type:0 +msgid "Binary" +msgstr "" + +#. module: base +#: field:ir.actions.server,sms:0 +#: selection:ir.actions.server,state:0 +msgid "SMS" +msgstr "" + +#. module: base +#: model:res.country,name:base.cr +msgid "Costa Rica" +msgstr "哥斯達黎加" + +#. module: base +#: view:workflow.activity:0 +msgid "Conditions" +msgstr "條件" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_other_form +msgid "Other Partners" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_currency_form +#: model:ir.ui.menu,name:base.menu_action_currency_form +#: view:res.currency:0 +msgid "Currencies" +msgstr "" + +#. module: base +#: sql_constraint:res.groups:0 +msgid "The name of the group must be unique !" +msgstr "" + +#. module: base +#: view:ir.sequence:0 +msgid "Hour 00->12: %(h12)s" +msgstr "" + +#. module: base +#: help:res.partner.address,active:0 +msgid "Uncheck the active field to hide the contact." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_widget_wizard +msgid "Add a widget for User" +msgstr "" + +#. module: base +#: model:res.country,name:base.dk +msgid "Denmark" +msgstr "丹麥" + +#. module: base +#: field:res.country,code:0 +msgid "Country Code" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_instance +msgid "workflow.instance" +msgstr "" + +#. module: base +#: code:addons/orm.py:278 +#, python-format +msgid "Unknown attribute %s in %s " +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "10. %S ==> 20" +msgstr "" + +#. module: base +#: code:addons/fields.py:106 +#, python-format +msgid "undefined get method !" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Norwegian Bokmål / Norsk bokmål" +msgstr "挪威文(Bokmål) / Norsk bokmål" + +#. module: base +#: help:res.config.users,new_password:0 +#: help:res.users,new_password:0 +msgid "" +"Only specify a value if you want to change the user password. This user will " +"have to logout and login again!" +msgstr "" + +#. module: base +#: model:res.partner.title,name:base.res_partner_title_madam +msgid "Madam" +msgstr "" + +#. module: base +#: model:res.country,name:base.ee +msgid "Estonia" +msgstr "愛沙尼亞" + +#. module: base +#: model:ir.ui.menu,name:base.dashboard +msgid "Dashboards" +msgstr "" + +#. module: base +#: help:ir.attachment,type:0 +msgid "Binary File or external URL" +msgstr "" + +#. module: base +#: field:res.config.users,new_password:0 +#: field:res.users,new_password:0 +msgid "Change password" +msgstr "" + +#. module: base +#: model:res.country,name:base.nl +msgid "Netherlands" +msgstr "荷蘭" + +#. module: base +#: model:ir.ui.menu,name:base.next_id_4 +msgid "Low Level Objects" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Your Logo - Use a size of about 450x150 pixels." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_values +msgid "ir.values" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Occitan (FR, post 1500) / Occitan" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.open_module_tree +msgid "" +"You can install new modules in order to activate new features, menu, reports " +"or data in your OpenERP instance. To install some modules, click on the " +"button \"Schedule for Installation\" from the form view, then click on " +"\"Apply Scheduled Upgrades\" to migrate your system." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_emails +#: model:ir.ui.menu,name:base.menu_mail_gateway +msgid "Emails" +msgstr "電郵" + +#. module: base +#: model:res.country,name:base.cd +msgid "Congo, The Democratic Republic of the" +msgstr "剛果民主共和國" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Malayalam / മലയാളം" +msgstr "" + +#. module: base +#: view:res.request:0 +#: field:res.request,body:0 +#: field:res.request.history,req_id:0 +msgid "Request" +msgstr "" + +#. module: base +#: model:res.country,name:base.jp +msgid "Japan" +msgstr "日本" + +#. module: base +#: field:ir.cron,numbercall:0 +msgid "Number of Calls" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +#: field:base.module.upgrade,module_info:0 +msgid "Modules to update" +msgstr "" + +#. module: base +#: help:ir.actions.server,sequence:0 +msgid "" +"Important when you deal with multiple actions, the execution order will be " +"decided based on this, low number is higher priority." +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,header:0 +msgid "Add RML header" +msgstr "" + +#. module: base +#: model:res.country,name:base.gr +msgid "Greece" +msgstr "希臘" + +#. module: base +#: field:res.request,trigger_date:0 +msgid "Trigger Date" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Croatian / hrvatski jezik" +msgstr "" + +#. module: base +#: field:base.language.install,overwrite:0 +msgid "Overwrite Existing Terms" +msgstr "" + +#. module: base +#: help:ir.actions.server,code:0 +msgid "Python code to be executed" +msgstr "" + +#. module: base +#: sql_constraint:res.country:0 +msgid "The code of the country must be unique !" +msgstr "" + +#. module: base +#: selection:ir.module.module.dependency,state:0 +msgid "Uninstallable" +msgstr "" + +#. module: base +#: view:res.partner.category:0 +msgid "Partner Category" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +#: selection:ir.actions.server,state:0 +msgid "Trigger" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_update +msgid "Update Module" +msgstr "" + +#. module: base +#: view:ir.model.fields:0 +#: field:ir.model.fields,translate:0 +msgid "Translate" +msgstr "" + +#. module: base +#: field:res.request.history,body:0 +msgid "Body" +msgstr "" + +#. module: base +#: view:partner.wizard.spam:0 +msgid "Send Email" +msgstr "" + +#. module: base +#: field:res.config.users,menu_id:0 +#: field:res.users,menu_id:0 +msgid "Menu Action" +msgstr "" + +#. module: base +#: help:ir.model.fields,selection:0 +msgid "" +"List of options for a selection field, specified as a Python expression " +"defining a list of (key, label) pairs. For example: " +"[('blue','Blue'),('yellow','Yellow')]" +msgstr "" + +#. module: base +#: selection:base.language.export,state:0 +msgid "choose" +msgstr "" + +#. module: base +#: help:ir.model,osv_memory:0 +msgid "" +"Indicates whether this object model lives in memory only, i.e. is not " +"persisted (osv.osv_memory)" +msgstr "" + +#. module: base +#: field:res.partner,child_ids:0 +#: field:res.request,ref_partner_id:0 +msgid "Partner Ref." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_supplier_form +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier_name +#: view:res.partner:0 +msgid "Suppliers" +msgstr "" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Register" +msgstr "" + +#. module: base +#: field:res.request,ref_doc2:0 +msgid "Document Ref 2" +msgstr "" + +#. module: base +#: field:res.request,ref_doc1:0 +msgid "Document Ref 1" +msgstr "" + +#. module: base +#: model:res.country,name:base.ga +msgid "Gabon" +msgstr "加蓬" + +#. module: base +#: model:ir.model,name:base.model_ir_model_data +msgid "ir.model.data" +msgstr "" + +#. module: base +#: view:ir.model:0 +#: view:ir.rule:0 +#: view:res.groups:0 +msgid "Access Rights" +msgstr "" + +#. module: base +#: model:res.country,name:base.gl +msgid "Greenland" +msgstr "格陵蘭" + +#. module: base +#: field:res.partner.bank,acc_number:0 +msgid "Account Number" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "1. %c ==> Fri Dec 5 18:25:20 2008" +msgstr "" + +#. module: base +#: model:res.country,name:base.nc +msgid "New Caledonia (French)" +msgstr "" + +#. module: base +#: model:res.country,name:base.cy +msgid "Cyprus" +msgstr "塞浦路斯" + +#. module: base +#: view:base.module.import:0 +msgid "" +"This wizard helps you add a new language to you OpenERP system. After " +"loading a new language it becomes available as default interface language " +"for users and partners." +msgstr "" + +#. module: base +#: field:ir.actions.server,subject:0 +#: field:partner.wizard.spam,subject:0 +#: field:res.request,name:0 +msgid "Subject" +msgstr "" + +#. module: base +#: field:res.request,act_from:0 +#: field:res.request.history,act_from:0 +msgid "From" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Preferences" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_consumers0 +msgid "Consumers" +msgstr "消費者" + +#. module: base +#: view:res.config:0 +#: wizard_button:server.action.create,init,step_1:0 +msgid "Next" +msgstr "" + +#. module: base +#: help:ir.cron,function:0 +msgid "" +"Name of the method to be called on the object when this scheduler is " +"executed." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:219 +#, python-format +msgid "" +"The Selection Options expression is must be in the [('key','Label'), ...] " +"format!" +msgstr "" + +#. module: base +#: view:ir.actions.report.xml:0 +msgid "Miscellaneous" +msgstr "" + +#. module: base +#: model:res.country,name:base.cn +msgid "China" +msgstr "中國" + +#. module: base +#: code:addons/base/res/res_user.py:516 +#, python-format +msgid "" +"--\n" +"%(name)s %(email)s\n" +msgstr "" + +#. module: base +#: model:res.country,name:base.eh +msgid "Western Sahara" +msgstr "西撒哈拉" + +#. module: base +#: model:ir.model,name:base.model_workflow +msgid "workflow" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_res_company_form +msgid "" +"Create and manage the companies that will be managed by OpenERP from here. " +"Shops or subsidiaries can be created and maintained from here." +msgstr "" + +#. module: base +#: model:res.country,name:base.id +msgid "Indonesia" +msgstr "印尼" + +#. module: base +#: view:base.update.translations:0 +msgid "" +"This wizard will detect new terms to translate in the application, so that " +"you can then add translations manually or perform a complete export (as a " +"template for a new language example)." +msgstr "" + +#. module: base +#: help:multi_company.default,expression:0 +msgid "" +"Expression, must be True to match\n" +"use context.get or user (browse)" +msgstr "" + +#. module: base +#: model:res.country,name:base.bg +msgid "Bulgaria" +msgstr "保加利亞" + +#. module: base +#: view:publisher_warranty.contract.wizard:0 +msgid "Publisher warranty contract successfully registered!" +msgstr "" + +#. module: base +#: model:res.country,name:base.ao +msgid "Angola" +msgstr "安哥拉" + +#. module: base +#: model:res.country,name:base.tf +msgid "French Southern Territories" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_currency +#: field:res.company,currency_id:0 +#: field:res.company,currency_ids:0 +#: view:res.currency:0 +#: field:res.currency,name:0 +#: field:res.currency.rate,currency_id:0 +msgid "Currency" +msgstr "" + +#. module: base +#: field:res.partner.canal,name:0 +msgid "Channel Name" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "5. %y, %Y ==> 08, 2008" +msgstr "" + +#. module: base +#: model:res.partner.title,shortcut:base.res_partner_title_ltd +msgid "ltd" +msgstr "" + +#. module: base +#: field:ir.values,res_id:0 +#: field:res.log,res_id:0 +msgid "Object ID" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Landscape" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_administration +msgid "Administration" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Click on Update below to start the process..." +msgstr "" + +#. module: base +#: model:res.country,name:base.ir +msgid "Iran" +msgstr "伊朗" + +#. module: base +#: model:ir.actions.act_window,name:base.res_widget_user_act_window +#: model:ir.ui.menu,name:base.menu_res_widget_user_act_window +msgid "Widgets per User" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Slovak / Slovenský jazyk" +msgstr "斯洛伐克文 / Slovenský jazyk" + +#. module: base +#: field:base.language.export,state:0 +#: field:ir.ui.menu,icon_pict:0 +#: field:publisher_warranty.contract.wizard,state:0 +msgid "unknown" +msgstr "" + +#. module: base +#: field:res.currency,symbol:0 +msgid "Symbol" +msgstr "" + +#. module: base +#: help:res.config.users,login:0 +#: help:res.users,login:0 +msgid "Used to log into the system" +msgstr "" + +#. module: base +#: view:base.update.translations:0 +msgid "Synchronize Translation" +msgstr "" + +#. module: base +#: field:ir.ui.view_sc,res_id:0 +msgid "Resource Ref." +msgstr "" + +#. module: base +#: model:res.country,name:base.ki +msgid "Kiribati" +msgstr "" + +#. module: base +#: model:res.country,name:base.iq +msgid "Iraq" +msgstr "伊拉克" + +#. module: base +#: model:ir.ui.menu,name:base.menu_association +msgid "Association" +msgstr "" + +#. module: base +#: model:res.country,name:base.cl +msgid "Chile" +msgstr "智利" + +#. module: base +#: model:ir.ui.menu,name:base.menu_address_book +#: model:ir.ui.menu,name:base.menu_config_address_book +#: model:ir.ui.menu,name:base.menu_procurement_management_supplier +msgid "Address Book" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_sequence_type +msgid "ir.sequence.type" +msgstr "" + +#. module: base +#: selection:base.language.export,format:0 +msgid "CSV File" +msgstr "" + +#. module: base +#: field:res.company,account_no:0 +msgid "Account No." +msgstr "" + +#. module: base +#: code:addons/base/res/res_lang.py:157 +#, python-format +msgid "Base Language 'en_US' can not be deleted !" +msgstr "" + +#. module: base +#: selection:ir.model,state:0 +msgid "Base Object" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "Dependencies :" +msgstr "" + +#. module: base +#: field:ir.model.fields,field_description:0 +msgid "Field Label" +msgstr "" + +#. module: base +#: model:res.country,name:base.dj +msgid "Djibouti" +msgstr "吉布提" + +#. module: base +#: field:ir.translation,value:0 +msgid "Translation Value" +msgstr "" + +#. module: base +#: model:res.country,name:base.ag +msgid "Antigua and Barbuda" +msgstr "" + +#. module: base +#: code:addons/orm.py:3166 +#, python-format +msgid "" +"Operation prohibited by access rules, or performed on an already deleted " +"document (Operation: %s, Document type: %s)." +msgstr "" + +#. module: base +#: model:res.country,name:base.zr +msgid "Zaire" +msgstr "扎伊爾" + +#. module: base +#: field:ir.model.data,res_id:0 +#: field:ir.translation,res_id:0 +#: field:workflow.instance,res_id:0 +#: field:workflow.triggers,res_id:0 +msgid "Resource ID" +msgstr "" + +#. module: base +#: view:ir.cron:0 +#: field:ir.model,info:0 +msgid "Information" +msgstr "" + +#. module: base +#: view:res.widget.user:0 +msgid "User Widgets" +msgstr "" + +#. module: base +#: view:base.module.update:0 +msgid "Update Module List" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Other" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Reply" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Turkish / Türkçe" +msgstr "土耳其文 / Türkçe" + +#. module: base +#: model:ir.actions.act_window,name:base.action_workflow_activity_form +#: model:ir.ui.menu,name:base.menu_workflow_activity +#: view:workflow:0 +#: field:workflow,activities:0 +msgid "Activities" +msgstr "動態" + +#. module: base +#: field:ir.actions.act_window,auto_refresh:0 +msgid "Auto-Refresh" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:62 +#, python-format +msgid "The osv_memory field can only be compared with = and != operator." +msgstr "" + +#. module: base +#: selection:ir.ui.view,type:0 +msgid "Diagram" +msgstr "" + +#. module: base +#: help:multi_company.default,name:0 +msgid "Name it to easily find a record" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.grant_menu_access +#: model:ir.ui.menu,name:base.menu_grant_menu_access +msgid "Menu Items" +msgstr "" + +#. module: base +#: constraint:ir.rule:0 +msgid "Rules are not supported for osv_memory objects !" +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_event_association +#: model:ir.ui.menu,name:base.menu_event_main +msgid "Events Organisation" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.ir_sequence_actions +#: model:ir.ui.menu,name:base.menu_custom_action +#: model:ir.ui.menu,name:base.menu_ir_sequence_actions +#: model:ir.ui.menu,name:base.next_id_6 +#: view:workflow.activity:0 +msgid "Actions" +msgstr "" + +#. module: base +#: selection:res.request,priority:0 +msgid "High" +msgstr "" + +#. module: base +#: field:ir.exports.line,export_id:0 +msgid "Export" +msgstr "" + +#. module: base +#: model:res.country,name:base.hr +msgid "Croatia" +msgstr "克羅地亞" + +#. module: base +#: help:res.bank,bic:0 +msgid "Bank Identifier Code" +msgstr "" + +#. module: base +#: model:res.country,name:base.tm +msgid "Turkmenistan" +msgstr "土庫曼" + +#. module: base +#: code:addons/base/ir/ir_actions.py:597 +#: code:addons/base/ir/ir_actions.py:629 +#: code:addons/base/ir/ir_actions.py:713 +#: code:addons/base/ir/ir_actions.py:716 +#: code:addons/base/ir/ir_model.py:114 +#: code:addons/base/ir/ir_model.py:204 +#: code:addons/base/ir/ir_model.py:218 +#: code:addons/base/ir/ir_model.py:232 +#: code:addons/base/ir/ir_model.py:250 +#: code:addons/base/ir/ir_model.py:255 +#: code:addons/base/ir/ir_model.py:258 +#: code:addons/base/module/module.py:215 +#: code:addons/base/module/module.py:258 +#: code:addons/base/module/module.py:262 +#: code:addons/base/module/module.py:268 +#: code:addons/base/module/module.py:303 +#: code:addons/base/module/module.py:321 +#: code:addons/base/module/module.py:336 +#: code:addons/base/module/module.py:429 +#: code:addons/base/module/module.py:531 +#: code:addons/base/publisher_warranty/publisher_warranty.py:163 +#: code:addons/base/publisher_warranty/publisher_warranty.py:281 +#: code:addons/base/res/res_currency.py:100 +#: code:addons/base/res/res_user.py:57 +#: code:addons/base/res/res_user.py:66 +#: code:addons/custom.py:558 +#: code:addons/orm.py:3199 +#, python-format +msgid "Error" +msgstr "" + +#. module: base +#: model:res.country,name:base.pm +msgid "Saint Pierre and Miquelon" +msgstr "" + +#. module: base +#: help:ir.actions.report.xml,header:0 +msgid "Add or not the coporate RML header" +msgstr "" + +#. module: base +#: help:workflow.transition,act_to:0 +msgid "The destination activity." +msgstr "" + +#. module: base +#: view:base.module.update:0 +#: view:base.update.translations:0 +msgid "Update" +msgstr "" + +#. module: base +#: model:ir.actions.report.xml,name:base.ir_module_reference_print +msgid "Technical guide" +msgstr "" + +#. module: base +#: model:res.country,name:base.tz +msgid "Tanzania" +msgstr "坦桑尼亞" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Danish / Dansk" +msgstr "丹麥文 / Dansk" + +#. module: base +#: selection:ir.model.fields,select_level:0 +msgid "Advanced Search (deprecated)" +msgstr "" + +#. module: base +#: model:res.country,name:base.cx +msgid "Christmas Island" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Other Actions Configuration" +msgstr "" + +#. module: base +#: view:res.config.installer:0 +msgid "Install Modules" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.res_partner_canal-act +#: model:ir.model,name:base.model_res_partner_canal +#: model:ir.ui.menu,name:base.menu_res_partner_canal-act +#: view:res.partner.canal:0 +msgid "Channels" +msgstr "" + +#. module: base +#: view:ir.ui.view:0 +msgid "Extra Info" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_values_form_action +#: model:ir.ui.menu,name:base.menu_values_form_action +msgid "Client Events" +msgstr "" + +#. module: base +#: view:ir.module.module:0 +msgid "Schedule for Installation" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_partner_wizard_ean_check +msgid "Ean Check" +msgstr "" + +#. module: base +#: sql_constraint:res.config.users:0 +#: sql_constraint:res.users:0 +msgid "You can not have two users with the same login !" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_multi_company_default +msgid "Default multi company" +msgstr "" + +#. module: base +#: view:res.request:0 +msgid "Send" +msgstr "" + +#. module: base +#: field:res.config.users,menu_tips:0 +#: field:res.users,menu_tips:0 +msgid "Menu Tips" +msgstr "" + +#. module: base +#: field:ir.translation,src:0 +msgid "Source" +msgstr "" + +#. module: base +#: help:res.partner.address,partner_id:0 +msgid "Keep empty for a private address, not related to partner." +msgstr "" + +#. module: base +#: model:res.country,name:base.vu +msgid "Vanuatu" +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Internal Header/Footer" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_export_language.py:59 +#, python-format +msgid "" +"Save this document to a .tgz file. This archive containt UTF-8 %s files and " +"may be uploaded to launchpad." +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Start configuration" +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "_Export" +msgstr "" + +#. module: base +#: field:base.language.install,state:0 +#: field:base.module.import,state:0 +#: field:base.module.update,state:0 +msgid "state" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Catalan / Català" +msgstr "" + +#. module: base +#: model:res.country,name:base.do +msgid "Dominican Republic" +msgstr "多明尼加共和國" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Serbian (Cyrillic) / српски" +msgstr "塞爾維亞文 (Cyrillic 字母) / српски" + +#. module: base +#: code:addons/orm.py:2161 +#, python-format +msgid "" +"Invalid group_by specification: \"%s\".\n" +"A group_by specification must be a list of valid fields." +msgstr "" + +#. module: base +#: model:res.country,name:base.sa +msgid "Saudi Arabia" +msgstr "沙特阿拉伯" + +#. module: base +#: help:res.partner,supplier:0 +msgid "" +"Check this box if the partner is a supplier. If it's not checked, purchase " +"people will not see it when encoding a purchase order." +msgstr "" + +#. module: base +#: field:ir.model.fields,relation_field:0 +msgid "Relation Field" +msgstr "" + +#. module: base +#: view:res.partner.event:0 +msgid "Event Logs" +msgstr "活動日誌" + +#. module: base +#: code:addons/base/module/wizard/base_module_configuration.py:37 +#, python-format +msgid "System Configuration done" +msgstr "" + +#. module: base +#: field:workflow.triggers,instance_id:0 +msgid "Destination Instance" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,multi:0 +#: field:ir.actions.wizard,multi:0 +msgid "Action on Multiple Doc." +msgstr "" + +#. module: base +#: view:base.language.export:0 +msgid "https://translations.launchpad.net/openobject" +msgstr "" + +#. module: base +#: field:ir.actions.report.xml,report_xml:0 +msgid "XML path" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "On Skip" +msgstr "" + +#. module: base +#: model:res.country,name:base.gn +msgid "Guinea" +msgstr "畿內亞" + +#. module: base +#: model:res.country,name:base.lu +msgid "Luxembourg" +msgstr "盧森堡" + +#. module: base +#: help:ir.values,key2:0 +msgid "" +"The kind of action or button in the client side that will trigger the action." +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_ui_menu.py:285 +#, python-format +msgid "Error ! You can not create recursive Menu." +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_add_wizard +#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract_add +#: view:publisher_warranty.contract.wizard:0 +msgid "Register a Contract" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"3. If user belongs to several groups, the results from step 2 are combined " +"with logical OR operator" +msgstr "" + +#. module: base +#: code:addons/base/publisher_warranty/publisher_warranty.py:145 +#, python-format +msgid "Please check your publisher warranty contract name and validity." +msgstr "" + +#. module: base +#: model:res.country,name:base.sv +msgid "El Salvador" +msgstr "薩爾瓦多" + +#. module: base +#: field:res.bank,phone:0 +#: field:res.partner,phone:0 +#: field:res.partner.address,phone:0 +msgid "Phone" +msgstr "" + +#. module: base +#: field:ir.cron,active:0 +#: field:ir.sequence,active:0 +#: field:res.bank,active:0 +#: field:res.config.users,active:0 +#: field:res.currency,active:0 +#: field:res.lang,active:0 +#: field:res.partner,active:0 +#: field:res.partner.address,active:0 +#: field:res.partner.canal,active:0 +#: field:res.partner.category,active:0 +#: field:res.request,active:0 +#: field:res.users,active:0 +#: view:workflow.instance:0 +#: view:workflow.workitem:0 +msgid "Active" +msgstr "" + +#. module: base +#: model:res.country,name:base.th +msgid "Thailand" +msgstr "泰國" + +#. module: base +#: model:ir.ui.menu,name:base.menu_crm_config_lead +msgid "Leads & Opportunities" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Romanian / română" +msgstr "羅馬尼亞文 / română" + +#. module: base +#: view:res.log:0 +msgid "System Logs" +msgstr "" + +#. module: base +#: selection:workflow.activity,join_mode:0 +#: selection:workflow.activity,split_mode:0 +msgid "And" +msgstr "" + +#. module: base +#: field:ir.model.fields,relation:0 +msgid "Object Relation" +msgstr "" + +#. module: base +#: view:ir.rule:0 +#: view:res.partner:0 +msgid "General" +msgstr "一般" + +#. module: base +#: model:res.country,name:base.uz +msgid "Uzbekistan" +msgstr "烏茲別克" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_act_window +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.act_window" +msgstr "" + +#. module: base +#: field:ir.rule,perm_create:0 +msgid "Apply For Create" +msgstr "" + +#. module: base +#: model:res.country,name:base.vi +msgid "Virgin Islands (USA)" +msgstr "處女羣島 (美屬)" + +#. module: base +#: model:res.country,name:base.tw +msgid "Taiwan" +msgstr "台灣" + +#. module: base +#: model:ir.model,name:base.model_res_currency_rate +msgid "Currency Rate" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.grant_menu_access +msgid "" +"Manage and customize the items available and displayed in your OpenERP " +"system menu. You can delete an item by clicking on the box at the beginning " +"of each line and then delete it through the button that appeared. Items can " +"be assigned to specific groups in order to make them accessible to some " +"users within the system." +msgstr "" + +#. module: base +#: field:ir.ui.view,field_parent:0 +msgid "Child Field" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,usage:0 +#: field:ir.actions.act_window_close,usage:0 +#: field:ir.actions.actions,usage:0 +#: field:ir.actions.report.xml,usage:0 +#: field:ir.actions.server,usage:0 +#: field:ir.actions.wizard,usage:0 +msgid "Action Usage" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_workflow_workitem +msgid "workflow.workitem" +msgstr "" + +#. module: base +#: selection:ir.module.module,state:0 +msgid "Not Installable" +msgstr "" + +#. module: base +#: report:ir.module.reference.graph:0 +msgid "View :" +msgstr "" + +#. module: base +#: field:ir.model.fields,view_load:0 +msgid "View Auto-Load" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:232 +#, python-format +msgid "You cannot remove the field '%s' !" +msgstr "" + +#. module: base +#: field:ir.exports,resource:0 +#: view:ir.property:0 +#: field:ir.property,res_id:0 +msgid "Resource" +msgstr "" + +#. module: base +#: field:ir.ui.menu,web_icon:0 +msgid "Web Icon File" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Persian / فارس" +msgstr "波斯文 / فارس" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "View Ordering" +msgstr "" + +#. module: base +#: code:addons/base/module/wizard/base_module_upgrade.py:95 +#, python-format +msgid "Unmet dependency !" +msgstr "" + +#. module: base +#: view:base.language.import:0 +msgid "" +"Supported file formats: *.csv (Comma-separated values) or *.po (GetText " +"Portable Objects)" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:487 +#, python-format +msgid "" +"You can not delete this document (%s) ! Be sure your user belongs to one of " +"these groups: %s." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_base_module_configuration +msgid "base.module.configuration" +msgstr "" + +#. module: base +#: field:base.language.export,name:0 +#: field:ir.attachment,datas_fname:0 +msgid "Filename" +msgstr "" + +#. module: base +#: field:ir.model,access_ids:0 +#: view:ir.model.access:0 +msgid "Access" +msgstr "" + +#. module: base +#: model:res.country,name:base.sk +msgid "Slovak Republic" +msgstr "斯洛伐克" + +#. module: base +#: model:ir.ui.menu,name:base.publisher_warranty +msgid "Publisher Warranty" +msgstr "" + +#. module: base +#: model:res.country,name:base.aw +msgid "Aruba" +msgstr "" + +#. module: base +#: model:res.country,name:base.ar +msgid "Argentina" +msgstr "阿根廷" + +#. module: base +#: field:res.groups,name:0 +msgid "Group Name" +msgstr "" + +#. module: base +#: model:res.country,name:base.bh +msgid "Bahrain" +msgstr "巴林" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_12 +msgid "Segmentation" +msgstr "" + +#. module: base +#: view:ir.attachment:0 +#: field:ir.attachment,company_id:0 +#: field:ir.default,company_id:0 +#: field:ir.property,company_id:0 +#: field:ir.sequence,company_id:0 +#: field:ir.values,company_id:0 +#: view:res.company:0 +#: field:res.config.users,company_id:0 +#: field:res.currency,company_id:0 +#: field:res.partner,company_id:0 +#: field:res.partner.address,company_id:0 +#: view:res.users:0 +#: field:res.users,company_id:0 +msgid "Company" +msgstr "" + +#. module: base +#: view:res.users:0 +msgid "Email & Signature" +msgstr "電郵 & 簽名" + +#. module: base +#: view:publisher_warranty.contract:0 +msgid "Publisher Warranty Contract" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Bulgarian / български език" +msgstr "保加利亞文 / български език" + +#. module: base +#: model:ir.ui.menu,name:base.menu_aftersale +msgid "After-Sale Services" +msgstr "售後服務" + +#. module: base +#: view:ir.actions.todo:0 +msgid "Launch" +msgstr "" + +#. module: base +#: field:ir.actions.act_window,limit:0 +msgid "Limit" +msgstr "" + +#. module: base +#: help:ir.actions.server,wkf_model_id:0 +msgid "Workflow to be executed on this model." +msgstr "" + +#. module: base +#: model:res.country,name:base.jm +msgid "Jamaica" +msgstr "牙買加" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_category_form +msgid "" +"Manage the partner categories in order to better classify them for tracking " +"and analysis purposes. A partner may belong to several categories and " +"categories have a hierarchy structure: a partner belonging to a category " +"also belong to his parent category." +msgstr "" + +#. module: base +#: model:res.country,name:base.az +msgid "Azerbaijan" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:250 +#, python-format +msgid "Warning" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Arabic / الْعَرَبيّة" +msgstr "阿拉伯文 / الْعَرَبيّة" + +#. module: base +#: model:res.country,name:base.vg +msgid "Virgin Islands (British)" +msgstr "處女羣島 (英屬)" + +#. module: base +#: view:ir.property:0 +#: model:ir.ui.menu,name:base.next_id_15 +msgid "Parameters" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Czech / Čeština" +msgstr "捷克文 / Čeština" + +#. module: base +#: view:ir.actions.server:0 +msgid "Trigger Configuration" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,help:base.action_partner_supplier_form +msgid "" +"You can access all information regarding your suppliers from the supplier " +"form: accounting data, history of emails, meetings, purchases, etc. You can " +"uncheck the 'Suppliers' filter button in order to search in all your " +"partners, including customers and prospects." +msgstr "" + +#. module: base +#: model:res.country,name:base.rw +msgid "Rwanda" +msgstr "盧旺達" + +#. module: base +#: view:ir.sequence:0 +msgid "Day of the week (0:Monday): %(weekday)s" +msgstr "" + +#. module: base +#: model:res.country,name:base.ck +msgid "Cook Islands" +msgstr "" + +#. module: base +#: field:ir.model.data,noupdate:0 +msgid "Non Updatable" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Klingon" +msgstr "" + +#. module: base +#: model:res.country,name:base.sg +msgid "Singapore" +msgstr "新加坡" + +#. module: base +#: selection:ir.actions.act_window,target:0 +msgid "Current Window" +msgstr "" + +#. module: base +#: view:ir.values:0 +msgid "Action Source" +msgstr "" + +#. module: base +#: view:res.config.view:0 +msgid "" +"If you use OpenERP for the first time we strongly advise you to select the " +"simplified interface, which has less features but is easier. You can always " +"switch later from the user preferences." +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_country +#: field:res.bank,country:0 +#: view:res.country:0 +#: field:res.country.state,country_id:0 +#: field:res.partner,country:0 +#: view:res.partner.address:0 +#: field:res.partner.address,country_id:0 +#: field:res.partner.bank,country_id:0 +msgid "Country" +msgstr "" + +#. module: base +#: field:ir.model.fields,complete_name:0 +#: field:ir.ui.menu,complete_name:0 +msgid "Complete Name" +msgstr "" + +#. module: base +#: field:ir.values,object:0 +msgid "Is Object" +msgstr "" + +#. module: base +#: view:ir.rule:0 +msgid "" +"1. Global rules are combined together with a logical AND operator, and with " +"the result of the following steps" +msgstr "" + +#. module: base +#: field:res.partner.category,name:0 +msgid "Category Name" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_15 +msgid "IT sector" +msgstr "" + +#. module: base +#: view:ir.actions.act_window:0 +msgid "Select Groups" +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%X - Appropriate time representation." +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Spanish (SV) / Español (SV)" +msgstr "西班牙文 (SV) / Español (SV)" + +#. module: base +#: help:res.lang,grouping:0 +msgid "" +"The Separator Format should be like [,n] where 0 < n :starting from Unit " +"digit.-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be " +"1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as " +"106,500. Provided ',' as the thousand separator in each case." +msgstr "" + +#. module: base +#: view:res.company:0 +msgid "Portrait" +msgstr "" + +#. module: base +#: code:addons/base/ir/ir_model.py:317 +#, python-format +msgid "Can only rename one column at a time!" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Button" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Report/Template" +msgstr "" + +#. module: base +#: selection:ir.actions.act_window.view,view_mode:0 +#: selection:ir.ui.view,type:0 +#: selection:wizard.ir.model.menu.create.line,view_type:0 +msgid "Graph" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_ir_actions_server +#: selection:ir.ui.menu,action:0 +msgid "ir.actions.server" +msgstr "" + +#. module: base +#: field:ir.actions.configuration.wizard,progress:0 +#: field:res.config,progress:0 +#: field:res.config.installer,progress:0 +#: field:res.config.users,progress:0 +#: field:res.config.view,progress:0 +msgid "Configuration Progress" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form +#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form +#: model:ir.ui.menu,name:base.next_id_11 +msgid "Configuration Wizards" +msgstr "" + +#. module: base +#: field:res.lang,code:0 +msgid "Locale Code" +msgstr "" + +#. module: base +#: field:workflow.activity,split_mode:0 +msgid "Split Mode" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "Note that this operation might take a few minutes." +msgstr "" + +#. module: base +#: model:ir.ui.menu,name:base.menu_localisation +msgid "Localisation" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "Action to Launch" +msgstr "" + +#. module: base +#: view:ir.cron:0 +msgid "Execution" +msgstr "" + +#. module: base +#: field:ir.actions.server,condition:0 +#: field:workflow.transition,condition:0 +msgid "Condition" +msgstr "" + +#. module: base +#: help:ir.values,model_id:0 +msgid "This field is not used, it only helps you to select a good model." +msgstr "" + +#. module: base +#: field:ir.ui.view,name:0 +msgid "View Name" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Italian / Italiano" +msgstr "意大利文 / Italiano" + +#. module: base +#: field:ir.actions.report.xml,attachment:0 +msgid "Save As Attachment Prefix" +msgstr "" + +#. module: base +#: view:ir.actions.server:0 +msgid "" +"Only one client action will be executed, last client action will be " +"considered in case of multiple client actions." +msgstr "" + +#. module: base +#: view:res.lang:0 +msgid "%j - Day of the year [001,366]." +msgstr "" + +#. module: base +#: field:ir.actions.server,mobile:0 +msgid "Mobile No" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_partner_by_category +#: model:ir.actions.act_window,name:base.action_partner_category_form +#: model:ir.model,name:base.model_res_partner_category +#: model:ir.ui.menu,name:base.menu_partner_category_form +#: view:res.partner.category:0 +msgid "Partner Categories" +msgstr "" + +#. module: base +#: view:base.module.upgrade:0 +msgid "System Update" +msgstr "" + +#. module: base +#: selection:ir.translation,type:0 +msgid "Wizard Field" +msgstr "" + +#. module: base +#: help:ir.sequence,prefix:0 +msgid "Prefix value of the record for the sequence" +msgstr "" + +#. module: base +#: model:res.country,name:base.sc +msgid "Seychelles" +msgstr "" + +#. module: base +#: model:ir.model,name:base.model_res_partner_bank +#: view:res.partner.bank:0 +msgid "Bank Accounts" +msgstr "" + +#. module: base +#: model:res.country,name:base.sl +msgid "Sierra Leone" +msgstr "塞拉利昂" + +#. module: base +#: view:res.company:0 +#: view:res.partner:0 +msgid "General Information" +msgstr "" + +#. module: base +#: model:res.country,name:base.tc +msgid "Turks and Caicos Islands" +msgstr "" + +#. module: base +#: field:res.partner.bank,owner_name:0 +msgid "Account Owner" +msgstr "" + +#. module: base +#: code:addons/base/res/res_user.py:256 +#, python-format +msgid "Company Switch Warning" +msgstr "" + +#. module: base +#: model:ir.actions.act_window,name:base.action_res_widget_wizard +msgid "Homepage Widgets Management" +msgstr "" + +#. module: base +#: field:workflow,osv:0 +#: field:workflow.instance,res_type:0 +msgid "Resource Object" +msgstr "" + +#. module: base +#: help:ir.sequence,number_increment:0 +msgid "The next number of the sequence will be incremented by this number" +msgstr "" + +#. module: base +#: field:ir.cron,function:0 +#: field:res.partner.address,function:0 +#: selection:workflow.activity,kind:0 +msgid "Function" +msgstr "" + +#. module: base +#: view:res.widget:0 +msgid "Search Widget" +msgstr "" + +#. module: base +#: selection:ir.actions.todo,restart:0 +msgid "Never" +msgstr "" + +#. module: base +#: selection:res.partner.address,type:0 +msgid "Delivery" +msgstr "" + +#. module: base +#: 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 "" + +#. module: base +#: model:res.country,name:base.gw +msgid "Guinea Bissau" +msgstr "" + +#. module: base +#: view:workflow.instance:0 +msgid "Workflow Instances" +msgstr "" + +#. module: base +#: code:addons/base/res/partner/partner.py:261 +#, python-format +msgid "Partners: " +msgstr "" + +#. module: base +#: model:res.country,name:base.kp +msgid "North Korea" +msgstr "北韓" + +#. module: base +#: selection:ir.actions.server,state:0 +msgid "Create Object" +msgstr "" + +#. module: base +#: view:ir.filters:0 +#: field:res.log,context:0 +msgid "Context" +msgstr "" + +#. module: base +#: field:res.bank,bic:0 +msgid "BIC/Swift code" +msgstr "" + +#. module: base +#: model:res.partner.category,name:base.res_partner_category_1 +msgid "Prospect" +msgstr "" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Polish / Język polski" +msgstr "波蘭文 / Język polski" + +#. module: base +#: field:ir.exports,name:0 +msgid "Export Name" +msgstr "" + +#. module: base +#: help:res.partner.address,type:0 +msgid "" +"Used to select automatically the right address according to the context in " +"sales and purchases documents." +msgstr "" + +#. module: base +#: model:res.country,name:base.lk +msgid "Sri Lanka" +msgstr "斯里蘭卡" + +#. module: base +#: selection:base.language.install,lang:0 +msgid "Russian / русский язык" +msgstr "俄文 / русский язык" diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po index 76f346231dc..62d7023c874 100644 --- a/openerp/addons/base/i18n/zh_TW.po +++ b/openerp/addons/base/i18n/zh_TW.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-28 02:14+0000\n" +"PO-Revision-Date: 2011-09-29 15:26+0000\n" "Last-Translator: Walter Cheuk <wwycheuk@gmail.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-09-01 04:45+0000\n" -"X-Generator: Launchpad (build 13827)\n" +"X-Launchpad-Export-Date: 2011-10-01 05:07+0000\n" +"X-Generator: Launchpad (build 14071)\n" #. module: base #: view:ir.filters:0 @@ -46,7 +46,7 @@ msgstr "日期時間" msgid "" "The second argument of the many2many field %s must be a SQL table !You used " "%s, which is not a valid SQL table name." -msgstr "many2many 欄位 %s 之第二個引數須為 SQL 表格!您用了並非有效 SQL 表格名稱之 %s。" +msgstr "「多對多(many2many)」欄位 %s 之第二個引數須為 SQL 表格!您用了並非有效 SQL 表格名稱之 %s。" #. module: base #: view:ir.values:0 @@ -103,7 +103,7 @@ msgstr "工作流程作用於" #. module: base #: field:ir.actions.act_window,display_menu_tip:0 msgid "Display Menu Tips" -msgstr "顯示選表提示" +msgstr "顯示選單提示" #. module: base #: view:ir.module.module:0 @@ -129,7 +129,7 @@ msgstr "" #. module: base #: field:res.partner,ref:0 msgid "Reference" -msgstr "參照" +msgstr "參考" #. module: base #: field:ir.actions.act_window,target:0 @@ -154,7 +154,7 @@ msgstr "" #: code:addons/osv.py:133 #, python-format msgid "Constraint Error" -msgstr "" +msgstr "約束錯誤" #. module: base #: model:ir.model,name:base.model_ir_ui_view_custom @@ -171,12 +171,12 @@ msgstr "史瓦濟蘭" #: code:addons/orm.py:3653 #, python-format msgid "created." -msgstr "" +msgstr "已建立。" #. module: base #: model:res.partner.category,name:base.res_partner_category_woodsuppliers0 msgid "Wood Suppliers" -msgstr "" +msgstr "木材供應商" #. module: base #: code:addons/base/module/module.py:303 @@ -224,7 +224,7 @@ msgstr "新" #. module: base #: field:ir.actions.report.xml,multi:0 msgid "On multiple doc." -msgstr "作用於多重檔案。" +msgstr "作用於多重文件。" #. module: base #: field:ir.module.category,module_nr:0 @@ -252,12 +252,12 @@ msgstr "聯絡人名稱" msgid "" "Save this document to a %s file and edit it with a specific software or a " "text editor. The file encoding is UTF-8." -msgstr "將此檔案儲存為%s檔案後可以特定軟體或文字編輯程式修改。檔案編碼為 UTF-8。" +msgstr "將此檔案存為 %s 檔案,並以特定軟體或文字編輯程式修改。檔案編碼為 UTF-8。" #. module: base #: sql_constraint:res.lang:0 msgid "The name of the language must be unique !" -msgstr "" +msgstr "語言名稱須與其他不同 !" #. module: base #: selection:res.request,state:0 @@ -329,7 +329,7 @@ msgstr "欄位名稱" #: wizard_view:server.action.create,init:0 #: wizard_field:server.action.create,init,type:0 msgid "Select Action Type" -msgstr "選擇動作類型" +msgstr "選取動作類型" #. module: base #: model:res.country,name:base.tv @@ -422,7 +422,7 @@ msgstr "哥倫比亞" #. module: base #: view:ir.module.module:0 msgid "Schedule Upgrade" -msgstr "排程升級" +msgstr "安排升級" #. module: base #: code:addons/orm.py:838 @@ -436,7 +436,7 @@ msgid "" "The ISO country code in two chars.\n" "You can use this field for quick search." msgstr "" -"ISO 國家代碼使用兩個字符。\n" +"ISO 國家代碼使用兩個字元。\n" "您可以使用該欄位來快速搜索。" #. module: base @@ -447,7 +447,7 @@ msgstr "帛琉" #. module: base #: view:res.partner:0 msgid "Sales & Purchases" -msgstr "銷售&採購" +msgstr "銷售 及 購貨" #. module: base #: view:ir.translation:0 @@ -481,7 +481,7 @@ msgstr "自訂欄位名稱開頭必須是 'x_' !" #. module: base #: help:ir.actions.server,action_id:0 msgid "Select the Action Window, Report, Wizard to be executed." -msgstr "選擇要執行的動作視窗、報表或精靈。" +msgstr "選取要執行之動作視窗、報表或精靈。" #. module: base #: view:res.config.users:0 @@ -502,7 +502,7 @@ msgstr "模型說明" #: help:ir.actions.act_window,src_model:0 msgid "" "Optional model name of the objects on which this action should be visible" -msgstr "" +msgstr "要可見動作的物件之模型名稱(可有可無)" #. module: base #: field:workflow.transition,trigger_expr_id:0 @@ -548,7 +548,7 @@ msgstr "是否檢查 Ean? " #. module: base #: field:ir.values,key2:0 msgid "Event Type" -msgstr "事件類型" +msgstr "活動類型" #. module: base #: view:base.language.export:0 @@ -684,7 +684,7 @@ msgstr "西班牙文 (UY) / Español (UY)" #: field:res.partner,mobile:0 #: field:res.partner.address,mobile:0 msgid "Mobile" -msgstr "手機" +msgstr "手提電話" #. module: base #: model:res.country,name:base.om @@ -741,7 +741,7 @@ msgstr "印度" #: model:ir.actions.act_window,name:base.res_request_link-act #: model:ir.ui.menu,name:base.menu_res_request_link_act msgid "Request Reference Types" -msgstr "請求參照類型" +msgstr "請求參考類型" #. module: base #: view:ir.values:0 @@ -812,7 +812,7 @@ msgstr "人力資源儀錶板" #: code:addons/base/res/res_user.py:507 #, python-format msgid "Setting empty passwords is not allowed for security reasons!" -msgstr "因保安理由密碼不能留空!" +msgstr "因安全理由密碼不能留空!" #. module: base #: selection:ir.actions.server,state:0 @@ -882,7 +882,7 @@ msgstr "刪除存取" #. module: base #: model:res.country,name:base.ne msgid "Niger" -msgstr "尼日爾" +msgstr "尼日" #. module: base #: selection:base.language.install,lang:0 @@ -998,7 +998,7 @@ msgstr "儀錶板" #. module: base #: model:ir.ui.menu,name:base.menu_purchase_root msgid "Purchases" -msgstr "採購" +msgstr "購貨" #. module: base #: model:res.country,name:base.md @@ -1120,7 +1120,7 @@ msgstr "報表" msgid "" "If set to true, the action will not be displayed on the right toolbar of a " "form view." -msgstr "如設為是,該動作不會顯示於表單檢視右側工具欄。" +msgstr "如設為真,該動作不會顯示於表單檢視右側工具欄。" #. module: base #: field:workflow,on_create:0 @@ -1239,7 +1239,7 @@ msgstr "馬爾地夫" #. module: base #: help:ir.values,res_id:0 msgid "Keep 0 if the action must appear on all resources." -msgstr "如果該動作要顯示於所有資源上的話請保持為「0」。" +msgstr "如該動作要顯示於所有資源的話請保持為「0」。" #. module: base #: model:ir.model,name:base.model_ir_rule @@ -1325,7 +1325,7 @@ msgstr "優先次序" #. module: base #: field:workflow.transition,act_from:0 msgid "Source Activity" -msgstr "來源活動" +msgstr "來源地動態" #. module: base #: view:ir.sequence:0 @@ -1368,7 +1368,7 @@ msgstr "完整路徑" #. module: base #: view:res.request:0 msgid "References" -msgstr "參照" +msgstr "參考" #. module: base #: view:res.lang:0 @@ -1510,7 +1510,7 @@ msgstr "" #. module: base #: view:workflow.activity:0 msgid "Workflow Activity" -msgstr "工作流程活動" +msgstr "工作流程動態" #. module: base #: view:ir.rule:0 @@ -1694,7 +1694,7 @@ msgstr "原始檢視" #. module: base #: view:ir.values:0 msgid "Action To Launch" -msgstr "要啟動之動作" +msgstr "要執行之動作" #. module: base #: field:ir.actions.url,target:0 @@ -1736,7 +1736,7 @@ msgstr "" #. module: base #: help:ir.values,action_id:0 msgid "This field is not used, it only helps you to select the right action." -msgstr "該欄位並未使用,只是為了幫您選擇正確的動作。" +msgstr "此欄位並未使用,只是為了幫您選擇正確動作。" #. module: base #: field:ir.actions.server,email:0 @@ -1916,7 +1916,7 @@ msgstr "諾福克島" #. module: base #: selection:base.language.install,lang:0 msgid "Korean (KR) / 한국어 (KR)" -msgstr "韓文 (KR) / 한국어 (KR)" +msgstr "韓文 (北韓) / 한국어 (KR)" #. module: base #: help:ir.model.fields,model:0 @@ -1927,7 +1927,7 @@ msgstr "" #: field:ir.actions.server,action_id:0 #: selection:ir.actions.server,state:0 msgid "Client Action" -msgstr "客戶端動作" +msgstr "用戶端動作" #. module: base #: model:res.country,name:base.bd @@ -2007,7 +2007,7 @@ msgstr "屬性" #: model:ir.model,name:base.model_res_partner_bank_type #: view:res.partner.bank.type:0 msgid "Bank Account Type" -msgstr "銀行帳戶類型" +msgstr "銀行帳號類型" #. module: base #: field:base.language.export,config_logo:0 @@ -2171,7 +2171,7 @@ msgstr "西班牙文 (DO) / Español (DO)" #. module: base #: model:ir.model,name:base.model_workflow_activity msgid "workflow.activity" -msgstr "工作流程.活動" +msgstr "工作流程.動態" #. module: base #: help:ir.ui.view_sc,res_id:0 @@ -2239,7 +2239,7 @@ msgstr "" #. module: base #: field:ir.default,ref_id:0 msgid "ID Ref." -msgstr "ID參照" +msgstr "ID參考" #. module: base #: model:ir.actions.server,name:base.action_start_configurator @@ -2313,7 +2313,7 @@ msgstr "分格格式" #. module: base #: selection:publisher_warranty.contract,state:0 msgid "Unvalidated" -msgstr "未檢驗" +msgstr "未驗證" #. module: base #: model:ir.ui.menu,name:base.next_id_9 @@ -2336,7 +2336,7 @@ msgstr "馬約特" #: code:addons/base/ir/ir_actions.py:597 #, python-format msgid "Please specify an action to launch !" -msgstr "請指定執行動作!" +msgstr "請指定要執行之動作!" #. module: base #: view:res.payterm:0 @@ -2368,7 +2368,7 @@ msgstr "請檢查所有行數皆有%d個欄位。" #: view:ir.cron:0 #: model:ir.ui.menu,name:base.menu_ir_cron_act msgid "Scheduled Actions" -msgstr "計劃的動作" +msgstr "已安排動作" #. module: base #: field:res.partner.address,title:0 @@ -2412,7 +2412,7 @@ msgstr "建立選單" msgid "" "Value Added Tax number. Check the box if the partner is subjected to the " "VAT. Used by the VAT legal statement." -msgstr "增值稅編號。如該伙伴適用於增值稅,請選擇。用於增值稅申報。" +msgstr "增值稅編號。如該伙伴需要繳交增值稅,請選擇。用於申報增值稅。" #. module: base #: model:ir.model,name:base.model_maintenance_contract @@ -2710,7 +2710,7 @@ msgstr "基礎欄位" #. module: base #: view:publisher_warranty.contract:0 msgid "Validate" -msgstr "檢驗" +msgstr "驗證" #. module: base #: field:ir.actions.todo,restart:0 @@ -2795,7 +2795,7 @@ msgstr "向用戶提供目標視窗之額外說明文字,如其用法及用途 #. module: base #: model:res.country,name:base.va msgid "Holy See (Vatican City State)" -msgstr "教廷(梵蒂岡)" +msgstr "教廷 (梵蒂岡)" #. module: base #: field:base.module.import,module_file:0 @@ -2810,7 +2810,7 @@ msgstr "" #. module: base #: model:res.partner.category,name:base.res_partner_category_16 msgid "Telecom sector" -msgstr "電訊範疇" +msgstr "電信範疇" #. module: base #: field:workflow.transition,trigger_model:0 @@ -2820,7 +2820,7 @@ msgstr "觸發器物件" #. module: base #: view:res.users:0 msgid "Current Activity" -msgstr "目前活動" +msgstr "當前動態" #. module: base #: view:workflow.activity:0 @@ -2842,7 +2842,7 @@ msgstr "行銷" #: view:res.partner.bank:0 #: model:res.partner.bank.type,name:base.bank_normal msgid "Bank account" -msgstr "銀行帳戶" +msgstr "銀行帳號" #. module: base #: selection:base.language.install,lang:0 @@ -2857,7 +2857,7 @@ msgstr "序列類型" #. module: base #: view:ir.ui.view.custom:0 msgid "Customized Architecture" -msgstr "自訂架構" +msgstr "自訂化架構" #. module: base #: field:ir.module.module,license:0 @@ -2877,7 +2877,7 @@ msgstr "必定" #. module: base #: selection:ir.translation,type:0 msgid "SQL Constraint" -msgstr "SQL 限制" +msgstr "SQL 約束" #. module: base #: field:ir.actions.server,srcmodel_id:0 @@ -3070,7 +3070,7 @@ msgstr "肯亞" #. module: base #: view:res.partner.event:0 msgid "Event" -msgstr "事件" +msgstr "活動" #. module: base #: model:ir.ui.menu,name:base.menu_custom_reports @@ -3080,7 +3080,7 @@ msgstr "自訂報表" #. module: base #: selection:base.language.install,lang:0 msgid "Abkhazian / аҧсуа" -msgstr "阿布哈茲文 / аҧсуа" +msgstr "阿布哈兹文 / аҧсуа" #. module: base #: view:base.module.configuration:0 @@ -3106,7 +3106,7 @@ msgstr "聖馬利諾" #. module: base #: model:res.country,name:base.bm msgid "Bermuda" -msgstr "百慕達" +msgstr "百慕大" #. module: base #: model:res.country,name:base.pe @@ -3180,7 +3180,7 @@ msgstr "完整存取" #: view:ir.model.fields:0 #: model:ir.ui.menu,name:base.menu_security msgid "Security" -msgstr "保安" +msgstr "安全" #. module: base #: model:res.widget,title:base.openerp_favorites_twitter_widget @@ -3481,8 +3481,8 @@ msgid "" "plugin, don't forget to register emails to each contact so that the gateway " "will automatically attach incoming emails to the right partner." msgstr "" -"客戶是指您與其做生意者,例如公司或機構。客戶可有多個聯絡人或地址,均屬於其員工。您可用「歷史」分頁追蹤所有有關交易:訂單、電郵、機會、退款要求等等。如您用" -"電郵閘道和 Outlook 或 Thunderbird 外掛程式,別忘了為聯絡人登記電郵,好讓閘道自動為合適伙伴寄送收到之電郵。" +"客戶是指您與其做生意者,例如公司或機構。客戶可有多個聯絡人或地址,均屬於其員工。您可用「歷史」分頁追蹤所有有關交易:訂單、電郵、商機、退款要求等等。如您用" +"電郵閘道、Outlook 或 Thunderbird 外掛程式,別忘了為聯絡人登記電郵,好讓閘道自動為合適伙伴寄送收到之電郵。" #. module: base #: field:ir.actions.report.xml,name:0 @@ -3517,7 +3517,7 @@ msgstr "名稱" msgid "" "If set to true, the action will not be displayed on the right toolbar of a " "form view" -msgstr "如設為是,該動作不會顯示於表單檢視右側工具欄" +msgstr "如設為真,該動作不會顯示於表單檢視右側工具欄" #. module: base #: model:res.country,name:base.ms @@ -3543,7 +3543,7 @@ msgstr "應用程式詞彙" msgid "" "The user's timezone, used to perform timezone conversions between the server " "and the client." -msgstr "" +msgstr "用戶之時區,用以為伺服器及用戶端進行時區轉換。" #. module: base #: field:ir.module.module,demo:0 @@ -3565,7 +3565,7 @@ msgstr "日文 / 日本語" msgid "" "Source activity. When this activity is over, the condition is tested to " "determine if we can start the ACT_TO activity." -msgstr "" +msgstr "來源地動態。當再無動態,會測試條件以決定是否開始 ACT_TO 動態。" #. module: base #: model:res.partner.category,name:base.res_partner_category_3 @@ -3618,7 +3618,7 @@ msgstr "冷岸及央麥恩群島" #: model:ir.model,name:base.model_ir_actions_wizard #: selection:ir.ui.menu,action:0 msgid "ir.actions.wizard" -msgstr "" +msgstr "ir.actions.wizard" #. module: base #: view:ir.actions.act_window:0 @@ -3753,12 +3753,12 @@ msgstr "無法載入模組基礎!(提示:檢查附加元件路徑)" #. module: base #: view:res.partner.bank:0 msgid "Bank Account Owner" -msgstr "銀行帳戶所有者" +msgstr "銀行帳號所有者" #. module: base #: model:ir.actions.act_window,name:base.act_values_form msgid "Client Actions Connections" -msgstr "客戶端動作連接" +msgstr "用戶端動作連線" #. module: base #: field:ir.attachment,res_name:0 @@ -3836,7 +3836,7 @@ msgstr "" #. module: base #: view:ir.actions.server:0 msgid "Client Action Configuration" -msgstr "客戶端動作設置" +msgstr "用戶端動作設定" #. module: base #: model:ir.model,name:base.model_res_partner_address @@ -3872,13 +3872,13 @@ msgstr "選取要匯入之模組套件 (.zip 檔):" #: field:res.partner.event,name:0 #: model:res.widget,title:base.events_widget msgid "Events" -msgstr "事件" +msgstr "活動" #. module: base #: model:ir.model,name:base.model_ir_actions_url #: selection:ir.ui.menu,action:0 msgid "ir.actions.url" -msgstr "" +msgstr "ir.actions.url" #. module: base #: model:res.widget,title:base.currency_converter_widget @@ -4098,7 +4098,7 @@ msgstr "重複錯過的" #. module: base #: help:ir.actions.server,state:0 msgid "Type of the Action that is to be executed" -msgstr "將要執行動作之類型" +msgstr "要執行動作之類型" #. module: base #: field:ir.server.object.lines,server_id:0 @@ -4706,7 +4706,7 @@ msgid "" "Track from where is coming your leads and opportunities by creating specific " "channels that will be maintained at the creation of a document in the " "system. Some examples of channels can be: Website, Phone Call, Reseller, etc." -msgstr "" +msgstr "於系統建立文件,以保持特定渠道追蹤潛在客戶及商機之來源。渠道例子有網站、電話查詢、零售商等等。" #. module: base #: model:res.partner.bank.type.field,name:base.bank_normal_field @@ -4765,7 +4765,7 @@ msgstr "變改我的偏好設定" #: code:addons/base/ir/ir_actions.py:164 #, python-format msgid "Invalid model name in the action definition." -msgstr "動作定義之模型名無效。" +msgstr "動作定義之模型名稱無效。" #. module: base #: field:partner.sms.send,text:0 @@ -4900,7 +4900,7 @@ msgstr "如指定,此動作會於此用戶登入時於標準選單以外額外 #. module: base #: view:ir.values:0 msgid "Client Actions" -msgstr "客戶端動作" +msgstr "用戶端動作" #. module: base #: code:addons/orm.py:1806 @@ -4921,12 +4921,12 @@ msgstr "" #. module: base #: field:workflow.transition,act_to:0 msgid "Destination Activity" -msgstr "目的地活動" +msgstr "目的地動態" #. module: base #: view:ir.values:0 msgid "Connect Events to Actions" -msgstr "把事件連接動作" +msgstr "把活動關聯到動作" #. module: base #: model:ir.model,name:base.model_base_update_translations @@ -5041,7 +5041,7 @@ msgstr "網頁圖示影像" #. module: base #: view:ir.values:0 msgid "Values for Event Type" -msgstr "事件類型值" +msgstr "活動類型值" #. module: base #: selection:ir.model.fields,select_level:0 @@ -5069,6 +5069,8 @@ msgid "" "installed the CRM, with the history tab, you can track all the interactions " "with a partner such as opportunities, emails, or sales orders issued." msgstr "" +"客戶(於系統其他地方又稱「伙伴」)助您管理其他公司,包括潛在客戶、客戶及/或供應商,之通訊錄。「伙伴表單」讓您追蹤及紀錄所有所需資訊,以讓您處理公司地址、" +"聯絡人、報價單等等。如您安裝了客戶關係管理(CRM)模組,以歷史分頁您可追蹤與伙伴有關之所有來往,如商機、電郵或銷售訂單等。" #. module: base #: model:res.country,name:base.ph @@ -5445,7 +5447,7 @@ msgstr "翻譯" #. module: base #: field:ir.sequence,padding:0 -msgid "Number padding" +msgid "Number Padding" msgstr "" #. module: base @@ -5552,7 +5554,7 @@ msgstr "" #: code:addons/base/res/res_config.py:94 #, python-format msgid "Couldn't find previous ir.actions.todo" -msgstr "" +msgstr "找不到之前的 ir.actions.todo" #. module: base #: view:ir.actions.act_window:0 @@ -5752,7 +5754,7 @@ msgstr "一年中的星期:%(woy)s" #. module: base #: model:res.partner.category,name:base.res_partner_category_14 msgid "Bad customers" -msgstr "差客戶" +msgstr "壞客戶" #. module: base #: report:ir.module.reference.graph:0 @@ -5792,7 +5794,7 @@ msgstr "宏都拉斯" #: help:res.users,menu_tips:0 msgid "" "Check out this box if you want to always display tips on each menu action" -msgstr "" +msgstr "如想於每個選單動作顯示提示,勾選此框" #. module: base #: model:res.country,name:base.eg @@ -6078,7 +6080,7 @@ msgstr "建立日期" msgid "" "Select the action that will be executed. Loop action will not be avaliable " "inside loop." -msgstr "選擇將要執行的動作。循環動作在循環內不可用。" +msgstr "選取要執行之動作。循環動作在循環內不可用。" #. module: base #: selection:base.language.install,lang:0 @@ -6358,7 +6360,7 @@ msgstr "模組更新結果" #: view:workflow.activity:0 #: field:workflow.workitem,act_id:0 msgid "Activity" -msgstr "活動" +msgstr "動態" #. module: base #: view:res.partner:0 @@ -6423,7 +6425,7 @@ msgstr "" msgid "" "Customized views are used when users reorganize the content of their " "dashboard views (via web client)" -msgstr "" +msgstr "當用戶(以 web client)重組其 dashboard 檢視即會使用自訂化檢視" #. module: base #: field:ir.model,name:0 @@ -6494,7 +6496,7 @@ msgstr "" #: model:ir.actions.act_window,name:base.res_log_act_window #: model:ir.ui.menu,name:base.menu_res_log_act_window msgid "Client Logs" -msgstr "客戶端日誌" +msgstr "用戶端日誌" #. module: base #: model:res.country,name:base.al @@ -6534,7 +6536,7 @@ msgstr "" #: code:addons/base/ir/ir_actions.py:716 #, python-format msgid "Problem in configuration `Record Id` in Server Action!" -msgstr "於伺服器動作之「Record Id」配置錯誤!" +msgstr "伺服器動作之「紀錄 Id」配置有問題!" #. module: base #: code:addons/orm.py:2306 @@ -6587,7 +6589,7 @@ msgstr "電郵" #: field:res.config.users,action_id:0 #: field:res.users,action_id:0 msgid "Home Action" -msgstr "家動作(Home Action)" +msgstr "家動作(Home Action)" #. module: base #: code:addons/custom.py:558 @@ -7603,7 +7605,7 @@ msgstr "要更新模組" msgid "" "Important when you deal with multiple actions, the execution order will be " "decided based on this, low number is higher priority." -msgstr "對於處理多個動作很重要,其決定動作執行順序;小的數字具較高優先次序。" +msgstr "對於處理多重動作很重要,其決定動作執行次序;小的數字具較高優先次序。" #. module: base #: field:ir.actions.report.xml,header:0 @@ -7756,7 +7758,7 @@ msgstr "格陵蘭" #. module: base #: field:res.partner.bank,acc_number:0 msgid "Account Number" -msgstr "帳戶號碼" +msgstr "帳號" #. module: base #: view:res.lang:0 @@ -7969,7 +7971,7 @@ msgstr "斯洛伐克文 / Slovenský jazyk" #: field:ir.ui.menu,icon_pict:0 #: field:publisher_warranty.contract.wizard,state:0 msgid "unknown" -msgstr "不明" +msgstr "不詳" #. module: base #: field:res.currency,symbol:0 @@ -8032,7 +8034,7 @@ msgstr "CSV 檔" #. module: base #: field:res.company,account_no:0 msgid "Account No." -msgstr "帳戶號碼" +msgstr "帳號" #. module: base #: code:addons/base/res/res_lang.py:157 @@ -8128,7 +8130,7 @@ msgstr "土耳其文 / Türkçe" #: view:workflow:0 #: field:workflow,activities:0 msgid "Activities" -msgstr "活動" +msgstr "動態" #. module: base #: field:ir.actions.act_window,auto_refresh:0 @@ -8166,7 +8168,7 @@ msgstr "" #: model:ir.ui.menu,name:base.menu_event_association #: model:ir.ui.menu,name:base.menu_event_main msgid "Events Organisation" -msgstr "事件組織" +msgstr "活動組織" #. module: base #: model:ir.actions.act_window,name:base.ir_sequence_actions @@ -8247,7 +8249,7 @@ msgstr "添加公司 RML 頁首與否" #. module: base #: help:workflow.transition,act_to:0 msgid "The destination activity." -msgstr "目的地活地。" +msgstr "目的地動態。" #. module: base #: view:base.module.update:0 @@ -8283,7 +8285,7 @@ msgstr "聖誕島" #. module: base #: view:ir.actions.server:0 msgid "Other Actions Configuration" -msgstr "其他動作設置" +msgstr "其他動作配置" #. module: base #: view:res.config.installer:0 @@ -8307,7 +8309,7 @@ msgstr "額外資訊" #: model:ir.actions.act_window,name:base.act_values_form_action #: model:ir.ui.menu,name:base.menu_values_form_action msgid "Client Events" -msgstr "客戶端事件" +msgstr "用戶端活動" #. module: base #: view:ir.module.module:0 @@ -8429,7 +8431,7 @@ msgstr "關聯欄位" #. module: base #: view:res.partner.event:0 msgid "Event Logs" -msgstr "事件日誌" +msgstr "活動日誌" #. module: base #: code:addons/base/module/wizard/base_module_configuration.py:37 @@ -8446,7 +8448,7 @@ msgstr "目的地實例" #: field:ir.actions.act_window,multi:0 #: field:ir.actions.wizard,multi:0 msgid "Action on Multiple Doc." -msgstr "動作作用於多個文件" +msgstr "多重文件之動作。" #. module: base #: view:base.language.export:0 @@ -8477,7 +8479,7 @@ msgstr "盧森堡" #: help:ir.values,key2:0 msgid "" "The kind of action or button in the client side that will trigger the action." -msgstr "客戶端的該類動作或按鈕將觸發此動作。" +msgstr "用戶端的該類動作或按鈕會觸發此動作。" #. module: base #: code:addons/base/ir/ir_ui_menu.py:285 @@ -8899,7 +8901,7 @@ msgstr "目前視窗" #. module: base #: view:ir.values:0 msgid "Action Source" -msgstr "動作來源" +msgstr "動作來源地" #. module: base #: view:res.config.view:0 @@ -9048,7 +9050,7 @@ msgstr "本地化" #. module: base #: view:ir.actions.server:0 msgid "Action to Launch" -msgstr "要啟動動作" +msgstr "要執行之動作" #. module: base #: view:ir.cron:0 @@ -9086,7 +9088,7 @@ msgstr "另存為附件前綴" msgid "" "Only one client action will be executed, last client action will be " "considered in case of multiple client actions." -msgstr "只能執行一個客戶端動作,如有多重動作只考慮最後一個。" +msgstr "只會執行一個用戶端動作,如有多重用戶端動作只考慮最後一個。" #. module: base #: view:res.lang:0 @@ -9131,7 +9133,7 @@ msgstr "塞席爾" #: model:ir.model,name:base.model_res_partner_bank #: view:res.partner.bank:0 msgid "Bank Accounts" -msgstr "銀行帳戶" +msgstr "銀行帳號" #. module: base #: model:res.country,name:base.sl @@ -9152,7 +9154,7 @@ msgstr "土克斯及開科斯群島" #. module: base #: field:res.partner.bank,owner_name:0 msgid "Account Owner" -msgstr "帳戶所有者" +msgstr "帳號所有者" #. module: base #: code:addons/base/res/res_user.py:256 diff --git a/openerp/addons/base/ir/__init__.py b/openerp/addons/base/ir/__init__.py index 9b4eb96df5f..4a6bd3c614c 100644 --- a/openerp/addons/base/ir/__init__.py +++ b/openerp/addons/base/ir/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ############################################################################## -# +# # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). # @@ -15,7 +15,7 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## @@ -36,6 +36,7 @@ import ir_rule import wizard import ir_config_parameter import osv_memory_autovacuum +import ir_mail_server # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml index 045fed2e2a0..7989bf6e180 100644 --- a/openerp/addons/base/ir/ir.xml +++ b/openerp/addons/base/ir/ir.xml @@ -152,6 +152,7 @@ <field name="padding"/> <field name="number_increment"/> <field name="number_next"/> + <field name="implementation"/> <separator colspan="4" string="Legend (for prefix, suffix)"/> <group col="8" colspan="4"> <group> @@ -191,6 +192,7 @@ <field name="company_id" groups="base.group_multi_company"/> <field name="number_next"/> <field name="number_increment"/> + <field name="implementation"/> </tree> </field> </record> @@ -548,6 +550,8 @@ <field name="view_id"/> </tree> </field> + <separator string="View Ordering" colspan="4"/> + <field colspan="4" name="help" nolabel="1"/> </group> </page> <page string="Security"> @@ -1251,7 +1255,7 @@ <record id="action_model_model" model="ir.actions.act_window"> - <field name="name">Objects</field> + <field name="name">Models</field> <field name="res_model">ir.model</field> <field name="view_type">form</field> <field name="context">{'manual':True}</field> @@ -1717,7 +1721,7 @@ <field name="name">Property multi-company</field> <field model="ir.model" name="model_id" ref="model_ir_property"/> <field eval="True" name="global"/> - <field name="domain_force">['|',('company_id','=',user.company_id.id),('company_id','=',False)]</field> + <field name="domain_force">['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field> </record> <!--server action view--> @@ -1743,7 +1747,9 @@ <page string="Trigger" attrs="{'invisible':[('state','!=','trigger')]}"> <separator colspan="4" string="Trigger Configuration"/> <field name="wkf_model_id" attrs="{'required':[('state','=','trigger')]}"/> - <field name="trigger_obj_id" context="{'key':''}" domain="[('model_id','=',model_id)]" attrs="{'required':[('state','=','trigger')]}"/> + <field name="trigger_obj_id" context="{'key':''}" + domain="[('model_id','=',model_id),('ttype','in',['many2one','int'])]" + attrs="{'required':[('state','=','trigger')]}"/> <field name="trigger_name" attrs="{'required':[('state','=','trigger')]}"/> </page> <page string="Action to Launch" attrs="{'invisible':[('state','!=','client_action')]}"> @@ -1851,7 +1857,7 @@ <field name="name">Config Wizard Steps</field> <field name="type">tree</field> <field name="arch" type="xml"> - <tree editable="bottom" string="Config Wizard Steps"> + <tree string="Config Wizard Steps"> <field name="sequence"/> <field name="action_id"/> <field name="category_id"/> @@ -1972,5 +1978,72 @@ <field name="sequence">5</field> </record> + <!-- ir.mail.server --> + <record model="ir.ui.view" id="ir_mail_server_form"> + <field name="name">ir.mail.server.form</field> + <field name="model">ir.mail_server</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Outgoing Mail Servers"> + <group colspan="4"> + <field name="name"/> + <field name="sequence"/> + </group> + <group col="2" colspan="4"> + <separator string="Connection Information" colspan="4"/> + <field name="smtp_host"/> + <field name="smtp_port"/> + <field name="smtp_debug" groups="base.group_extended"/> + </group> + <group col="2" colspan="4"> + <separator string="Security and Authentication" colspan="2"/> + <field name="smtp_encryption" on_change="on_change_encryption(smtp_encryption)"/> + <field name="smtp_user"/> + <field name="smtp_pass" password="True"/> + <button name="test_smtp_connection" type="object" string="Test Connection" icon="gtk-network" colspan="2"/> + </group> + </form> + </field> + </record> + + <record model="ir.ui.view" id="ir_mail_server_list"> + <field name="name">ir.mail.server.list</field> + <field name="model">ir.mail_server</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Outgoing Mail Servers"> + <field name="sequence"/> + <field name="name"/> + <field name="smtp_host"/> + <field name="smtp_user"/> + <field name="smtp_encryption"/> + </tree> + </field> + </record> + + <record id="view_ir_mail_server_search" model="ir.ui.view"> + <field name="name">ir.mail.server.search</field> + <field name="model">ir.mail_server</field> + <field name="type">search</field> + <field name="arch" type="xml"> + <search string="Outgoing Mail Servers"> + <field name="name"/> + <field name="smtp_host"/> + <field name="smtp_user"/> + <field name="smtp_encryption"/> + </search> + </field> + </record> + + <record model="ir.actions.act_window" id="action_ir_mail_server_list"> + <field name="name">Outgoing Mail Servers</field> + <field name="res_model">ir.mail_server</field> + <field name="view_type">form</field> + <field name="view_mode">tree,form</field> + <field name="view_id" ref="ir_mail_server_list" /> + <field name="search_view_id" ref="view_ir_mail_server_search"/> + </record> + <menuitem id="next_id_15" name="Parameters" parent="base.menu_config" groups="base.group_extended" /> + <menuitem id="menu_mail_servers" parent="base.next_id_15" action="action_ir_mail_server_list" sequence="15"/> </data> </openerp> diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 67c36b277dd..7850006c31a 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -418,7 +418,10 @@ class server_object_lines(osv.osv): _columns = { 'server_id': fields.many2one('ir.actions.server', 'Object Mapping'), 'col1': fields.many2one('ir.model.fields', 'Destination', required=True), - 'value': fields.text('Value', required=True), + 'value': fields.text('Value', required=True, help="Expression containing a value specification. \n" + "When Formula type is selected, this field may be a Python expression " + " that can use the same values as for the condition field on the server action.\n" + "If Value type is selected, the value will be used directly without evaluation."), 'type': fields.selection([ ('value','Value'), ('equation','Formula') @@ -435,14 +438,15 @@ server_object_lines() class actions_server(osv.osv): def _select_signals(self, cr, uid, context=None): - cr.execute("SELECT distinct w.osv, t.signal FROM wkf w, wkf_activity a, wkf_transition t \ - WHERE w.id = a.wkf_id AND t.act_from = a.id OR t.act_to = a.id AND t.signal!='' \ - AND t.signal NOT IN (null, NULL)") + cr.execute("""SELECT distinct w.osv, t.signal FROM wkf w, wkf_activity a, wkf_transition t + WHERE w.id = a.wkf_id AND + (t.act_from = a.id OR t.act_to = a.id) AND + t.signal IS NOT NULL""") result = cr.fetchall() or [] res = [] for rs in result: if rs[0] is not None and rs[1] is not None: - line = rs[0], "%s - (%s)" % (rs[1], rs[0]) + line = rs[1], "%s - (%s)" % (rs[1], rs[0]) res.append(line) return res @@ -453,13 +457,15 @@ class actions_server(osv.osv): return [(r['model'], r['name']) for r in res] + [('','')] def change_object(self, cr, uid, ids, copy_object, state, context=None): - if state == 'object_copy': + if state == 'object_copy' and copy_object: + if context is None: + context = {} model_pool = self.pool.get('ir.model') model = copy_object.split(',')[0] mid = model_pool.search(cr, uid, [('model','=',model)]) return { - 'value':{'srcmodel_id':mid[0]}, - 'context':context + 'value': {'srcmodel_id': mid[0]}, + 'context': context } else: return {} @@ -469,8 +475,19 @@ class actions_server(osv.osv): _sequence = 'ir_actions_id_seq' _order = 'sequence,name' _columns = { - 'name': fields.char('Action Name', required=True, size=64, help="Easy to Refer action by name e.g. One Sales Order -> Many Invoices", translate=True), - 'condition' : fields.char('Condition', size=256, required=True, help="Condition that is to be tested before action is executed, e.g. object.list_price > object.cost_price"), + 'name': fields.char('Action Name', required=True, size=64, translate=True), + 'condition' : fields.char('Condition', size=256, required=True, + help="Condition that is tested before the action is executed, " + "and prevent execution if it is not verified.\n" + "Example: object.list_price > 5000\n" + "It is a Python expression that can use the following values:\n" + " - self: ORM model of the record on which the action is triggered\n" + " - object or obj: browse_record of the record on which the action is triggered\n" + " - pool: ORM model pool (i.e. self.pool)\n" + " - time: Python time module\n" + " - cr: database cursor\n" + " - uid: current user id\n" + " - context: current context"), 'state': fields.selection([ ('client_action','Client Action'), ('dummy','Dummy'), @@ -484,16 +501,20 @@ class actions_server(osv.osv): ('object_write','Write Object'), ('other','Multi Actions'), ], 'Action Type', required=True, size=32, help="Type of the Action that is to be executed"), - 'code':fields.text('Python Code', help="Python code to be executed"), + 'code':fields.text('Python Code', help="Python code to be executed if condition is met.\n" + "It is a Python block that can use the same values as for the condition field"), 'sequence': fields.integer('Sequence', help="Important when you deal with multiple actions, the execution order will be decided based on this, low number is higher priority."), 'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create)."), 'action_id': fields.many2one('ir.actions.actions', 'Client Action', help="Select the Action Window, Report, Wizard to be executed."), - 'trigger_name': fields.selection(_select_signals, string='Trigger Name', size=128, help="Select the Signal name that is to be used as the trigger."), - 'wkf_model_id': fields.many2one('ir.model', 'Workflow On', help="Workflow to be executed on this model."), - 'trigger_obj_id': fields.many2one('ir.model.fields','Trigger On', help="Select the object from the model on which the workflow will executed."), - 'email': fields.char('Email Address', size=512, help="Provides the fields that will be used to fetch the email address, e.g. when you select the invoice, then `object.invoice_address_id.email` is the field which gives the correct address"), - 'subject': fields.char('Subject', size=1024, translate=True, help="Specify the subject. You can use fields from the object, e.g. `Hello [[ object.partner_id.name ]]`"), - 'message': fields.text('Message', translate=True, help="Specify the message. You can use the fields from the object. e.g. `Dear [[ object.partner_id.name ]]`"), + 'trigger_name': fields.selection(_select_signals, string='Trigger Signal', size=128, help="The workflow signal to trigger"), + 'wkf_model_id': fields.many2one('ir.model', 'Target Object', help="The object that should receive the workflow signal (must have an associated workflow)"), + 'trigger_obj_id': fields.many2one('ir.model.fields','Relation Field', help="The field on the current object that links to the target object record (must be a many2one, or an integer field with the record ID)"), + 'email': fields.char('Email Address', size=512, help="Expression that returns the email address to send to. Can be based on the same values as for the condition field.\n" + "Example: object.invoice_address_id.email, or 'me@example.com'"), + 'subject': fields.char('Subject', size=1024, translate=True, help="Email subject, may contain expressions enclosed in double brackets based on the same values as those " + "available in the condition field, e.g. `Hello [[ object.partner_id.name ]]`"), + 'message': fields.text('Message', translate=True, help="Email contents, may contain expressions enclosed in double brackets based on the same values as those " + "available in the condition field, e.g. `Dear [[ object.partner_id.name ]]`"), 'mobile': fields.char('Mobile No', size=512, help="Provides fields that be used to fetch the mobile number, e.g. you select the invoice, then `object.invoice_address_id.mobile` is the field which gives the correct mobile number"), 'sms': fields.char('SMS', size=160, translate=True), 'child_ids': fields.many2many('ir.actions.server', 'rel_server_actions', 'server_id', 'action_id', 'Other Actions'), @@ -512,12 +533,14 @@ class actions_server(osv.osv): 'condition': lambda *a: 'True', 'type': lambda *a: 'ir.actions.server', 'sequence': lambda *a: 5, - 'code': lambda *a: """# You can use the following variables -# - object or obj -# - time -# - cr -# - uid -# - ids + 'code': lambda *a: """# You can use the following variables: +# - self: ORM model of the record on which the action is triggered +# - object: browse_record of the record on which the action is triggered if there is one, otherwise None +# - pool: ORM model pool (i.e. self.pool) +# - time: Python time module +# - cr: database cursor +# - uid: current user id +# - context: current context # If you plan to return an action, assign: action = {...} """, } @@ -567,6 +590,7 @@ class actions_server(osv.osv): def merge_message(self, cr, uid, keystr, action, context=None): if context is None: context = {} + def merge(match): obj_pool = self.pool.get(action.model_id.model) id = context.get('active_id') @@ -601,14 +625,18 @@ class actions_server(osv.osv): context = {} user = self.pool.get('res.users').browse(cr, uid, uid) for action in self.browse(cr, uid, ids, context): + obj = None obj_pool = self.pool.get(action.model_id.model) - obj = obj_pool.browse(cr, uid, context['active_id'], context=context) + 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) cxt = { - 'context': dict(context), # copy context to prevent side-effects of eval + 'self': obj_pool, 'object': obj, + 'obj': obj, + 'pool': self.pool, 'time': time, 'cr': cr, - 'pool': self.pool, + 'context': dict(context), # copy context to prevent side-effects of eval 'uid': uid, 'user': user } @@ -623,20 +651,9 @@ class actions_server(osv.osv): .read(cr, uid, action.action_id.id, context=context) if action.state=='code': - localdict = { - 'self': self.pool.get(action.model_id.model), - 'context': dict(context), # copy context to prevent side-effects of eval - 'time': time, - 'ids': ids, - 'cr': cr, - 'uid': uid, - 'object':obj, - 'obj': obj, - 'user': user, - } - eval(action.code, localdict, mode="exec", nocopy=True) # nocopy allows to return 'action' - if 'action' in localdict: - return localdict['action'] + eval(action.code, cxt, mode="exec", nocopy=True) # nocopy allows to return 'action' + if 'action' in cxt: + return cxt['action'] if action.state == 'email': email_from = config['email_from'] @@ -649,7 +666,7 @@ class actions_server(osv.osv): if not address: logger.info('No partner email address specified, not sending any email.') continue - + if not email_from: logger.debug('--email-from command line option is not specified, using a fallback value instead.') if user.user_email: @@ -660,7 +677,10 @@ class actions_server(osv.osv): subject = self.merge_message(cr, uid, action.subject, action, context) body = self.merge_message(cr, uid, action.message, action, context) - if tools.email_send(email_from, [address], subject, body, debug=False, subtype='html') == True: + ir_mail_server = self.pool.get('ir.mail_server') + msg = ir_mail_server.build_email(email_from, [address], subject, body) + res_email = ir_mail_server.send_email(cr, uid, msg) + if res_email: logger.info('Email successfully sent to: %s', address) else: logger.warning('Failed to send email to: %s', address) @@ -668,10 +688,10 @@ class actions_server(osv.osv): if action.state == 'trigger': wf_service = netsvc.LocalService("workflow") model = action.wkf_model_id.model - obj_pool = self.pool.get(action.model_id.model) - res_id = self.pool.get(action.model_id.model).read(cr, uid, [context.get('active_id')], [action.trigger_obj_id.name]) - id = res_id [0][action.trigger_obj_id.name] - wf_service.trg_validate(uid, model, int(id), action.trigger_name, cr) + m2o_field_name = action.trigger_obj_id.name + target_id = obj_pool.read(cr, uid, context.get('active_id'), [m2o_field_name])[m2o_field_name] + target_id = target_id[0] if isinstance(target_id,tuple) else target_id + wf_service.trg_validate(uid, model, int(target_id), action.trigger_name, cr) if action.state == 'sms': #TODO: set the user and password from the system @@ -686,20 +706,9 @@ class actions_server(osv.osv): result = self.run(cr, uid, [act.id], context) if result: res.append(result) - return res if action.state == 'loop': - obj_pool = self.pool.get(action.model_id.model) - obj = obj_pool.browse(cr, uid, context['active_id'], context=context) - cxt = { - 'context': dict(context), # copy context to prevent side-effects of eval - 'object': obj, - 'time': time, - 'cr': cr, - 'pool' : self.pool, - 'uid' : uid - } expr = eval(str(action.expression), cxt) context['object'] = obj for i in expr: @@ -711,13 +720,6 @@ class actions_server(osv.osv): for exp in action.fields_lines: euq = exp.value if exp.type == 'equation': - obj_pool = self.pool.get(action.model_id.model) - obj = obj_pool.browse(cr, uid, context['active_id'], context=context) - cxt = { - 'context': dict(context), # copy context to prevent side-effects of eval - 'object': obj, - 'time': time, - } expr = eval(euq, cxt) else: expr = exp.value @@ -751,14 +753,7 @@ class actions_server(osv.osv): for exp in action.fields_lines: euq = exp.value if exp.type == 'equation': - obj_pool = self.pool.get(action.model_id.model) - obj = obj_pool.browse(cr, uid, context['active_id'], context=context) - expr = eval(euq, - { - 'context': dict(context), # copy context to prevent side-effects of eval - 'object': obj, - 'time': time, - }) + expr = eval(euq, cxt) else: expr = exp.value res[exp.col1.name] = expr @@ -775,21 +770,11 @@ class actions_server(osv.osv): for exp in action.fields_lines: euq = exp.value if exp.type == 'equation': - obj_pool = self.pool.get(action.model_id.model) - obj = obj_pool.browse(cr, uid, context['active_id'], context=context) - expr = eval(euq, - { - 'context': dict(context), # copy context to prevent side-effects of eval - 'object': obj, - 'time': time, - }) + expr = eval(euq, cxt) else: expr = exp.value res[exp.col1.name] = expr - obj_pool = None - res_id = False - model = action.copy_object.split(',')[0] cid = action.copy_object.split(',')[1] obj_pool = self.pool.get(model) @@ -825,7 +810,7 @@ ir_actions_todo_category() # This model use to register action services. TODO_STATES = [('open', 'To Do'), ('done', 'Done')] -TODO_TYPES = [('manual', 'Launch Manually'), +TODO_TYPES = [('manual', 'Launch Manually'),('once', 'Launch Manually Once'), ('automatic', 'Launch Automatically')] class ir_actions_todo(osv.osv): """ @@ -842,7 +827,8 @@ class ir_actions_todo(osv.osv): 'name': fields.char('Name', size=64), 'type': fields.selection(TODO_TYPES, 'Type', required=True, help="""Manual: Launched manually. -Automatic: Runs whenever the system is reconfigured."""), +Automatic: Runs whenever the system is reconfigured. +Launch Manually Once: after hacing been launched manually, it sets automatically to Done."""), 'groups_id': fields.many2many('res.groups', 'res_groups_action_rel', 'uid', 'gid', 'Groups'), 'note': fields.text('Text', translate=True), 'category_id': fields.many2one('ir.actions.todo.category','Category'), @@ -858,7 +844,7 @@ Automatic: Runs whenever the system is reconfigured."""), """ Launch Action of Wizard""" wizard_id = ids and ids[0] or False wizard = self.browse(cr, uid, wizard_id, context=context) - if wizard.type == 'automatic': + if wizard.type in ('automatic', 'once'): wizard.write({'state': 'done'}) # Load action @@ -905,13 +891,13 @@ Automatic: Runs whenever the system is reconfigured."""), done = filter( groups_match, self.browse(cr, uid, - self.search(cr, uid, ['&', ('state', '!=', 'open'), ('type', '=', 'manual')], context=context), + self.search(cr, uid, [('state', '!=', 'open')], context=context), context=context)) total = filter( groups_match, self.browse(cr, uid, - self.search(cr, uid, [('type', '=', 'manual')], context=context), + self.search(cr, uid, [], context=context), context=context)) return { diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py index 95a4cd8cab0..0612c1861d8 100644 --- a/openerp/addons/base/ir/ir_attachment.py +++ b/openerp/addons/base/ir/ir_attachment.py @@ -50,8 +50,7 @@ class ir_attachment(osv.osv): for model, mids in res_ids.items(): # ignore attachments that are not attached to a resource anymore when checking access rights # (resource was deleted but attachment was not) - cr.execute('select id from '+self.pool.get(model)._table+' where id in %s', (tuple(mids),)) - mids = [x[0] for x in cr.fetchall()] + mids = self.pool.get(model).exists(cr, uid, mids) ima.check(cr, uid, model, mode) self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context) diff --git a/openerp/addons/base/ir/ir_config_parameter.py b/openerp/addons/base/ir/ir_config_parameter.py index f8c0348e8f6..981dfd2798e 100644 --- a/openerp/addons/base/ir/ir_config_parameter.py +++ b/openerp/addons/base/ir/ir_config_parameter.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). +# Copyright (C) 2011 OpenERP SA (<http://www.openerp.com>). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -19,7 +19,7 @@ # ############################################################################## """ -A module to store some configuration parameters relative to a whole database. +Store database-specific configuration parameters """ from osv import osv,fields @@ -36,23 +36,19 @@ _default_parameters = { } class ir_config_parameter(osv.osv): - """ An osv to old configuration parameters for a given database. - - To be short, it's just a global dictionary of strings stored in a table. """ - + """Per-database storage of configuration key-value pairs.""" + _name = 'ir.config_parameter' - + _columns = { - # The key of the configuration parameter. 'key': fields.char('Key', size=256, required=True, select=1), - # The value of the configuration parameter. 'value': fields.text('Value', required=True), } - + _sql_constraints = [ ('key_uniq', 'unique (key)', 'Key must be unique.') ] - + def init(self, cr): """ Initializes the parameters listed in _default_parameters. @@ -63,12 +59,12 @@ class ir_config_parameter(osv.osv): self.set_param(cr, 1, key, func()) def get_param(self, cr, uid, key, default=False, context=None): - """ Get the value of a parameter. - - @param key: The key of the parameter. - @type key: string - @return: The value of the parameter, False if it does not exist. - @rtype: string + """Retrieve the value for a given key. + + :param string key: The key of the parameter value to retrieve. + :param string default: default value if parameter is missing. + :return: The value of the parameter, or ``default`` if it does not exist. + :rtype: string """ ids = self.search(cr, uid, [('key','=',key)], context=context) if not ids: @@ -78,15 +74,13 @@ class ir_config_parameter(osv.osv): return value def set_param(self, cr, uid, key, value, context=None): - """ Set the value of a parameter. + """Sets the value of a parameter. - @param key: The key of the parameter. - @type key: string - @param value: The value of the parameter. - @type value: string - @return: Return the previous value of the parameter of False if it did - not existed. - @rtype: string + :param string key: The key of the parameter value to set. + :param string value: The value to set. + :return: the previous value of the parameter or False if it did + not exist. + :rtype: string """ ids = self.search(cr, uid, [('key','=',key)], context=context) if ids: @@ -97,5 +91,3 @@ class ir_config_parameter(osv.osv): else: self.create(cr, uid, {'key': key, 'value': value}, context=context) return False - -ir_config_parameter() diff --git a/openerp/addons/base/ir/ir_cron.py b/openerp/addons/base/ir/ir_cron.py index 054a15257ef..af46b0ef3e0 100644 --- a/openerp/addons/base/ir/ir_cron.py +++ b/openerp/addons/base/ir/ir_cron.py @@ -21,13 +21,20 @@ import time import logging +import threading +import psycopg2 from datetime import datetime from dateutil.relativedelta import relativedelta + import netsvc -import tools -from tools.safe_eval import safe_eval as eval +import openerp import pooler +import tools +from openerp.cron import WAKE_UP_NOW from osv import fields, osv +from tools import DEFAULT_SERVER_DATETIME_FORMAT +from tools.safe_eval import safe_eval as eval +from tools.translate import _ def str2tuple(s): return eval('tuple(%s)' % (s or '')) @@ -41,10 +48,15 @@ _intervalTypes = { 'minutes': lambda interval: relativedelta(minutes=interval), } -class ir_cron(osv.osv, netsvc.Agent): - """ This is the ORM object that periodically executes actions. - Note that we use the netsvc.Agent()._logger member. +class ir_cron(osv.osv): + """ Model describing cron jobs (also called actions or tasks). """ + + # TODO: perhaps in the future we could consider a flag on ir.cron jobs + # that would cause database wake-up even if the database has not been + # loaded yet or was already unloaded (e.g. 'force_db_wakeup' or something) + # See also openerp.cron + _name = "ir.cron" _order = 'name' _columns = { @@ -54,17 +66,17 @@ class ir_cron(osv.osv, netsvc.Agent): 'interval_number': fields.integer('Interval Number',help="Repeat every x."), 'interval_type': fields.selection( [('minutes', 'Minutes'), ('hours', 'Hours'), ('work_days','Work Days'), ('days', 'Days'),('weeks', 'Weeks'), ('months', 'Months')], 'Interval Unit'), - 'numbercall': fields.integer('Number of Calls', help='Number of time the function is called,\na negative number indicates no limit'), - 'doall' : fields.boolean('Repeat Missed', help="Enable this if you want to execute missed occurences as soon as the server restarts."), - 'nextcall' : fields.datetime('Next Execution Date', required=True, help="Next planned execution date for this scheduler"), - 'model': fields.char('Object', size=64, help="Name of object whose function will be called when this scheduler will run. e.g. 'res.partener'"), - 'function': fields.char('Function', size=64, help="Name of the method to be called on the object when this scheduler is executed."), - 'args': fields.text('Arguments', help="Arguments to be passed to the method. e.g. (uid,)"), - 'priority': fields.integer('Priority', help='0=Very Urgent\n10=Not urgent') + 'numbercall': fields.integer('Number of Calls', help='How many times the method is called,\na negative number indicates no limit.'), + 'doall' : fields.boolean('Repeat Missed', help="Specify if missed occurrences should be executed when the server restarts."), + 'nextcall' : fields.datetime('Next Execution Date', required=True, help="Next planned execution date for this job."), + 'model': fields.char('Object', size=64, help="Model name on which the method to be called is located, e.g. 'res.partner'."), + 'function': fields.char('Method', size=64, help="Name of the method to be called when this job is processed."), + 'args': fields.text('Arguments', help="Arguments to be passed to the method, e.g. (uid,)."), + 'priority': fields.integer('Priority', help='The priority of the job, as an integer: 0 means higher priority, 10 means lower priority.') } _defaults = { - 'nextcall' : lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), + 'nextcall' : lambda *a: time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), 'priority' : lambda *a: 5, 'user_id' : lambda obj,cr,uid,context: uid, 'interval_number' : lambda *a: 1, @@ -74,6 +86,8 @@ class ir_cron(osv.osv, netsvc.Agent): 'doall' : lambda *a: 1 } + _logger = logging.getLogger('cron') + def _check_args(self, cr, uid, ids, context=None): try: for this in self.browse(cr, uid, ids, context): @@ -86,68 +100,164 @@ class ir_cron(osv.osv, netsvc.Agent): (_check_args, 'Invalid arguments', ['args']), ] - def _handle_callback_exception(self, cr, uid, model, func, args, job_id, job_exception): + def _handle_callback_exception(self, cr, uid, model_name, method_name, args, job_id, job_exception): + """ Method called when an exception is raised by a job. + + Simply logs the exception and rollback the transaction. + + :param model_name: model name on which the job method is located. + :param method_name: name of the method to call when this job is processed. + :param args: arguments of the method (without the usual self, cr, uid). + :param job_id: job id. + :param job_exception: exception raised by the job. + + """ cr.rollback() - logger=logging.getLogger('cron') - logger.exception("Call of self.pool.get('%s').%s(cr, uid, *%r) failed in Job %s" % (model, func, args, job_id)) + self._logger.exception("Call of self.pool.get('%s').%s(cr, uid, *%r) failed in Job %s" % (model_name, method_name, args, job_id)) + + def _callback(self, cr, uid, model_name, method_name, args, job_id): + """ Run the method associated to a given job - def _callback(self, cr, uid, model, func, args, job_id): + It takes care of logging and exception handling. + + :param model_name: model name on which the job method is located. + :param method_name: name of the method to call when this job is processed. + :param args: arguments of the method (without the usual self, cr, uid). + :param job_id: job id. + """ args = str2tuple(args) - m = self.pool.get(model) - if m and hasattr(m, func): - f = getattr(m, func) + model = self.pool.get(model_name) + if model and hasattr(model, method_name): + method = getattr(model, method_name) try: - netsvc.log('cron', (cr.dbname,uid,'*',model,func)+tuple(args), channel=logging.DEBUG, + netsvc.log('cron', (cr.dbname,uid,'*',model_name,method_name)+tuple(args), channel=logging.DEBUG, depth=(None if self._logger.isEnabledFor(logging.DEBUG_RPC_ANSWER) else 1), fn='object.execute') logger = logging.getLogger('execution time') if logger.isEnabledFor(logging.DEBUG): start_time = time.time() - f(cr, uid, *args) + method(cr, uid, *args) if logger.isEnabledFor(logging.DEBUG): end_time = time.time() - logger.log(logging.DEBUG, '%.3fs (%s, %s)' % (end_time - start_time, model, func)) + logger.log(logging.DEBUG, '%.3fs (%s, %s)' % (end_time - start_time, model_name, method_name)) except Exception, e: - self._handle_callback_exception(cr, uid, model, func, args, job_id, e) + self._handle_callback_exception(cr, uid, model_name, method_name, args, job_id, e) + + def _run_job(self, cr, job, now): + """ Run a given job taking care of the repetition. - def _poolJobs(self, db_name, check=False): + The cursor has a lock on the job (aquired by _run_jobs_multithread()) and this + method is run in a worker thread (spawned by _run_jobs_multithread())). + + :param job: job to be run (as a dictionary). + :param now: timestamp (result of datetime.now(), no need to call it multiple time). + + """ try: - db, pool = pooler.get_db_and_pool(db_name) - except: - return False + nextcall = datetime.strptime(job['nextcall'], DEFAULT_SERVER_DATETIME_FORMAT) + numbercall = job['numbercall'] + + ok = False + while nextcall < now and numbercall: + if numbercall > 0: + numbercall -= 1 + if not ok or job['doall']: + self._callback(cr, job['user_id'], job['model'], job['function'], job['args'], job['id']) + if numbercall: + nextcall += _intervalTypes[job['interval_type']](job['interval_number']) + ok = True + addsql = '' + if not numbercall: + addsql = ', active=False' + cr.execute("UPDATE ir_cron SET nextcall=%s, numbercall=%s"+addsql+" WHERE id=%s", + (nextcall.strftime(DEFAULT_SERVER_DATETIME_FORMAT), numbercall, job['id'])) + + if numbercall: + # Reschedule our own main cron thread if necessary. + # This is really needed if this job runs longer than its rescheduling period. + nextcall = time.mktime(nextcall.timetuple()) + openerp.cron.schedule_wakeup(nextcall, cr.dbname) + finally: + cr.commit() + cr.close() + openerp.cron.release_thread_slot() + + def _run_jobs_multithread(self): + # TODO remove 'check' argument from addons/base_action_rule/base_action_rule.py + """ Process the cron jobs by spawning worker threads. + + This selects in database all the jobs that should be processed. It then + tries to lock each of them and, if it succeeds, spawns a thread to run + the cron job (if it doesn't succeed, it means the job was already + locked to be taken care of by another thread). + + The cursor used to lock the job in database is given to the worker + thread (which has to close it itself). + + """ + db = self.pool.db cr = db.cursor() + db_name = db.dbname try: - if not pool._init: - now = datetime.now() - cr.execute('select * from ir_cron where numbercall<>0 and active and nextcall<=now() order by priority') - for job in cr.dictfetchall(): - nextcall = datetime.strptime(job['nextcall'], '%Y-%m-%d %H:%M:%S') - numbercall = job['numbercall'] - - ok = False - while nextcall < now and numbercall: - if numbercall > 0: - numbercall -= 1 - if not ok or job['doall']: - self._callback(cr, job['user_id'], job['model'], job['function'], job['args'], job['id']) - if numbercall: - nextcall += _intervalTypes[job['interval_type']](job['interval_number']) - ok = True - addsql = '' - if not numbercall: - addsql = ', active=False' - cr.execute("update ir_cron set nextcall=%s, numbercall=%s"+addsql+" where id=%s", (nextcall.strftime('%Y-%m-%d %H:%M:%S'), numbercall, job['id'])) - cr.commit() - - - cr.execute('select min(nextcall) as min_next_call from ir_cron where numbercall<>0 and active') + jobs = {} # mapping job ids to jobs for all jobs being processed. + now = datetime.now() + # Careful to compare timestamps with 'UTC' - everything is UTC as of v6.1. + cr.execute("""SELECT * FROM ir_cron + WHERE numbercall != 0 + AND active AND nextcall <= (now() at time zone 'UTC') + ORDER BY priority""") + for job in cr.dictfetchall(): + if not openerp.cron.get_thread_slots(): + break + jobs[job['id']] = job + + task_cr = db.cursor() + try: + # Try to grab an exclusive lock on the job row from within the task transaction + acquired_lock = False + task_cr.execute("""SELECT * + FROM ir_cron + WHERE id=%s + FOR UPDATE NOWAIT""", + (job['id'],), log_exceptions=False) + acquired_lock = True + except psycopg2.OperationalError, e: + if e.pgcode == '55P03': + # Class 55: Object not in prerequisite state; 55P03: lock_not_available + self._logger.debug('Another process/thread is already busy executing job `%s`, skipping it.', job['name']) + continue + else: + # Unexpected OperationalError + raise + finally: + if not acquired_lock: + # we're exiting due to an exception while acquiring the lot + task_cr.close() + + # Got the lock on the job row, now spawn a thread to execute it in the transaction with the lock + task_thread = threading.Thread(target=self._run_job, name=job['name'], args=(task_cr, job, now)) + # force non-daemon task threads (the runner thread must be daemon, and this property is inherited by default) + task_thread.setDaemon(False) + openerp.cron.take_thread_slot() + task_thread.start() + self._logger.debug('Cron execution thread for job `%s` spawned', job['name']) + + # Find next earliest job ignoring currently processed jobs (by this and other cron threads) + find_next_time_query = """SELECT min(nextcall) AS min_next_call + FROM ir_cron WHERE numbercall != 0 AND active""" + if jobs: + cr.execute(find_next_time_query + " AND id NOT IN %s", (tuple(jobs.keys()),)) + else: + cr.execute(find_next_time_query) next_call = cr.dictfetchone()['min_next_call'] + if next_call: - next_call = time.mktime(time.strptime(next_call, '%Y-%m-%d %H:%M:%S')) + next_call = time.mktime(time.strptime(next_call, DEFAULT_SERVER_DATETIME_FORMAT)) else: - next_call = int(time.time()) + 3600 # if do not find active cron job from database, it will run again after 1 day + # no matching cron job found in database, re-schedule arbitrarily in 1 day, + # this delay will likely be modified when running jobs complete their tasks + next_call = time.time() + (24*3600) - if not check: - self.setAlarm(self._poolJobs, next_call, db_name, db_name) + openerp.cron.schedule_wakeup(next_call, db_name) except Exception, ex: self._logger.warning('Exception in cron:', exc_info=True) @@ -156,12 +266,8 @@ class ir_cron(osv.osv, netsvc.Agent): cr.commit() cr.close() - def restart(self, dbname): - self.cancel(dbname) - # Reschedule cron processing job asap, but not in the current thread - self.setAlarm(self._poolJobs, time.time(), dbname, dbname) - def update_running_cron(self, cr): + """ Schedule as soon as possible a wake-up for this database. """ # Verify whether the server is already started and thus whether we need to commit # immediately our changes and restart the cron agent in order to apply the change # immediately. The commit() is needed because as soon as the cron is (re)started it @@ -171,23 +277,37 @@ class ir_cron(osv.osv, netsvc.Agent): # when the server is only starting or loading modules (hence the test on pool._init). if not self.pool._init: cr.commit() - self.restart(cr.dbname) + openerp.cron.schedule_wakeup(WAKE_UP_NOW, self.pool.db.dbname) + + def _try_lock(self, cr, uid, ids, context=None): + """Try to grab a dummy exclusive write-lock to the rows with the given ids, + to make sure a following write() or unlink() will not block due + to a process currently executing those cron tasks""" + try: + cr.execute("""SELECT id FROM "%s" WHERE id IN %%s FOR UPDATE NOWAIT""" % self._table, + (tuple(ids),), log_exceptions=False) + except psycopg2.OperationalError: + cr.rollback() # early rollback to allow translations to work for the user feedback + raise osv.except_osv(_("Record cannot be modified right now"), + _("This cron task is currently being executed and may not be modified, " + "please try again in a few minutes")) def create(self, cr, uid, vals, context=None): res = super(ir_cron, self).create(cr, uid, vals, context=context) self.update_running_cron(cr) return res - def write(self, cr, user, ids, vals, context=None): - res = super(ir_cron, self).write(cr, user, ids, vals, context=context) + def write(self, cr, uid, ids, vals, context=None): + self._try_lock(cr, uid, ids, context) + res = super(ir_cron, self).write(cr, uid, ids, vals, context=context) self.update_running_cron(cr) return res def unlink(self, cr, uid, ids, context=None): + self._try_lock(cr, uid, ids, context) res = super(ir_cron, self).unlink(cr, uid, ids, context=context) self.update_running_cron(cr) return res ir_cron() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py new file mode 100644 index 00000000000..e8d97160068 --- /dev/null +++ b/openerp/addons/base/ir/ir_mail_server.py @@ -0,0 +1,436 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011 OpenERP S.A (<http://www.openerp.com>) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/> +# +############################################################################## + +from email.MIMEText import MIMEText +from email.MIMEBase import MIMEBase +from email.MIMEMultipart import MIMEMultipart +from email.Header import Header +from email.Utils import formatdate, make_msgid, COMMASPACE +from email import Encoders +import logging +import re +import smtplib + +from osv import osv +from osv import fields +from openerp.tools.translate import _ +from openerp.tools import html2text +from openerp.tools.func import wraps +import openerp.tools as tools + +# ustr was originally from tools.misc. +# it is moved to loglevels until we refactor tools. +from openerp.loglevels import ustr + +_logger = logging.getLogger('ir.mail_server') + +class MailDeliveryException(osv.except_osv): + """Specific exception subclass for mail delivery errors""" + def __init__(self, name, value, exc_type='warning'): + super(MailDeliveryException, self).__init__(name, value, exc_type=exc_type) + +class WriteToLogger(object): + """debugging helper: behave as a fd and pipe to logger at the given level""" + def __init__(self, logger, level=logging.DEBUG): + self.logger = logger + self.level = level + + def write(self, s): + self.logger.log(self.level, s) + + +def try_coerce_ascii(string_utf8): + """Attempts to decode the given utf8-encoded string + as ASCII after coercing it to UTF-8, then return + the confirmed 7-bit ASCII string. + + If the process fails (because the string + contains non-ASCII characters) returns ``None``. + """ + try: + string_utf8.decode('ascii') + except UnicodeDecodeError: + return + return string_utf8 + +def encode_header(header_text): + """Returns an appropriate representation of the given header value, + suitable for direct assignment as a header value in an + email.message.Message. RFC2822 assumes that headers contain + only 7-bit characters, so we ensure it is the case, using + RFC2047 encoding when needed. + + :param header_text: unicode or utf-8 encoded string with header value + :rtype: string | email.header.Header + :return: if ``header_text`` represents a plain ASCII string, + return the same 7-bit string, otherwise returns an email.header.Header + that will perform the appropriate RFC2047 encoding of + non-ASCII values. + """ + if not header_text: return "" + # convert anything to utf-8, suitable for testing ASCIIness, as 7-bit chars are + # encoded as ASCII in utf-8 + header_text_utf8 = tools.ustr(header_text).encode('utf-8') + header_text_ascii = try_coerce_ascii(header_text_utf8) + # if this header contains non-ASCII characters, + # we'll need to wrap it up in a message.header.Header + # that will take care of RFC2047-encoding it as + # 7-bit string. + return header_text_ascii if header_text_ascii\ + else Header(header_text_utf8, 'utf-8') + +name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>') +address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)') + +def extract_rfc2822_addresses(text): + """Returns a list of valid RFC2822 addresses + that can be found in ``source``, ignoring + malformed ones and non-ASCII ones. + """ + if not text: return [] + candidates = address_pattern.findall(tools.ustr(text).encode('utf-8')) + return filter(try_coerce_ascii, candidates) + +def encode_rfc2822_address_header(header_text): + """If ``header_text`` contains non-ASCII characters, + attempts to locate patterns of the form + ``"Name" <address@domain>`` and replace the + ``"Name"`` portion by the RFC2047-encoded + version, preserving the address part untouched. + """ + header_text_utf8 = tools.ustr(header_text).encode('utf-8') + header_text_ascii = try_coerce_ascii(header_text_utf8) + if header_text_ascii: + return header_text_ascii + # non-ASCII characters are present, attempt to + # replace all "Name" patterns with the RFC2047- + # encoded version + def replace(match_obj): + name, email = match_obj.group(1), match_obj.group(2) + name_encoded = str(Header(name, 'utf-8')) + return "%s <%s>" % (name_encoded, email) + header_text_utf8 = name_with_email_pattern.sub(replace, + header_text_utf8) + # try again after encoding + header_text_ascii = try_coerce_ascii(header_text_utf8) + if header_text_ascii: + return header_text_ascii + # fallback to extracting pure addresses only, which could + # still cause a failure downstream if the actual addresses + # contain non-ASCII characters + return COMMASPACE.join(extract_rfc2822_addresses(header_text_utf8)) + + +class ir_mail_server(osv.osv): + """Represents an SMTP server, able to send outgoing e-mails, with SSL and TLS capabilities.""" + _name = "ir.mail_server" + + _columns = { + 'name': fields.char('Description', size=64, required=True, select=True), + 'smtp_host': fields.char('SMTP Server', size=128, required=True, help="Hostname or IP of SMTP server"), + 'smtp_port': fields.integer('SMTP Port', size=5, required=True, help="SMTP Port. Usually 465 for SSL, and 25 or 587 for other cases."), + 'smtp_user': fields.char('Username', size=64, help="Optional username for SMTP authentication"), + 'smtp_pass': fields.char('Password', size=64, help="Optional password for SMTP authentication"), + 'smtp_encryption': fields.selection([('none','None'), + ('starttls','TLS (STARTTLS)'), + ('ssl','SSL/TLS')], + string='Connection Security', required=True, + help="Choose the connection encryption scheme:\n" + "- None: SMTP sessions are done in cleartext.\n" + "- TLS (STARTTLS): TLS encryption is requested at start of SMTP session (Recommended)\n" + "- SSL/TLS: SMTP sessions are encrypted with SSL/TLS through a dedicated port (default: 465)"), + 'smtp_debug': fields.boolean('Debugging', help="If enabled, the full output of SMTP sessions will " + "be written to the server log at DEBUG level" + "(this is very verbose and may include confidential info!)"), + 'sequence': fields.integer('Priority', help="When no specific mail server is requested for a mail, the highest priority one " + "is used. Default priority is 10 (smaller number = higher priority)"), + } + + _defaults = { + 'smtp_port': 25, + 'sequence': 10, + 'smtp_encryption': 'none', + } + + def __init__(self, *args, **kwargs): + # Make sure we pipe the smtplib outputs to our own DEBUG logger + if not isinstance(smtplib.stderr, WriteToLogger): + logpiper = WriteToLogger(_logger) + smtplib.stderr = logpiper + smtplib.stdout = logpiper + return super(ir_mail_server, self).__init__(*args,**kwargs) + + def name_get(self, cr, uid, ids, context=None): + return [(a["id"], "(%s)" % (a['name'])) for a in self.read(cr, uid, ids, ['name'], context=context)] + + def test_smtp_connection(self, cr, uid, ids, context=None): + for smtp_server in self.browse(cr, uid, ids, context=context): + smtp = False + try: + smtp = self.connect(smtp_server.smtp_host, smtp_server.smtp_port, user=smtp_server.smtp_user, + password=smtp_server.smtp_pass, encryption=smtp_server.smtp_encryption, + smtp_debug=smtp_server.smtp_debug) + except Exception, e: + raise osv.except_osv(_("Connection test failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e)) + finally: + try: + if smtp: smtp.quit() + except Exception: + # ignored, just a consequence of the previous exception + pass + raise osv.except_osv(_("Connection test succeeded!"), _("Everything seems properly set up!")) + + def connect(self, host, port, user=None, password=None, encryption=False, smtp_debug=False): + """Returns a new SMTP connection to the give SMTP server, authenticated + with ``user`` and ``password`` if provided, and encrypted as requested + by the ``encryption`` parameter. + + :param host: host or IP of SMTP server to connect to + :param int port: SMTP port to connect to + :param user: optional username to authenticate with + :param password: optional password to authenticate with + :param string encryption: optional: ``'ssl'`` | ``'starttls'`` + :param bool smtp_debug: toggle debugging of SMTP sessions (all i/o + will be output in logs) + """ + if encryption == 'ssl': + if not 'SMTP_SSL' in smtplib.__all__: + raise osv.except_osv( + _("SMTP-over-SSL mode unavailable"), + _("Your OpenERP Server does not support SMTP-over-SSL. You could use STARTTLS instead." + "If SSL is needed, an upgrade to Python 2.6 on the server-side should do the trick.")) + connection = smtplib.SMTP_SSL(host, port) + else: + connection = smtplib.SMTP(host, port) + connection.set_debuglevel(smtp_debug) + if encryption == 'starttls': + # starttls() will perform ehlo() if needed first + # and will discard the previous list of services + # after successfully performing STARTTLS command, + # (as per RFC 3207) so for example any AUTH + # capability that appears only on encrypted channels + # will be correctly detected for next step + connection.starttls() + + if user: + # Attempt authentication - will raise if AUTH service not supported + connection.login(user, password) + return connection + + def build_email(self, email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False, + attachments=None, message_id=None, references=None, object_id=False, subtype='plain', headers=None): + """Constructs an RFC2822 email.message.Message object based on the keyword arguments passed, and returns it. + + :param string email_from: sender email address + :param list email_to: list of recipient addresses (to be joined with commas) + :param string subject: email subject (no pre-encoding/quoting necessary) + :param string body: email body, according to the ``subtype`` (by default, plaintext). + If html subtype is used, the message will be automatically converted + to plaintext and wrapped in multipart/alternative. + :param string reply_to: optional value of Reply-To header + :param string object_id: optional tracking identifier, to be included in the message-id for + recognizing replies. Suggested format for object-id is "res_id-model", + e.g. "12345-crm.lead". + :param string subtype: optional mime subtype for the text body (usually 'plain' or 'html'), + must match the format of the ``body`` parameter. Default is 'plain', + making the content part of the mail "text/plain". + :param list attachments: list of (filename, filecontents) pairs, where filecontents is a string + containing the bytes of the attachment + :param list email_cc: optional list of string values for CC header (to be joined with commas) + :param list email_bcc: optional list of string values for BCC header (to be joined with commas) + :param dict headers: optional map of headers to set on the outgoing mail (may override the + other headers, including Subject, Reply-To, Message-Id, etc.) + :rtype: email.message.Message (usually MIMEMultipart) + :return: the new RFC2822 email message + """ + email_from = email_from or tools.config.get('email_from') + assert email_from, "You must either provide a sender address explicitly or configure "\ + "a global sender address in the server configuration or with the "\ + "--email-from startup parameter." + + # Note: we must force all strings to to 8-bit utf-8 when crafting message, + # or use encode_header() for headers, which does it automatically. + + headers = headers or {} # need valid dict later + + if not email_cc: email_cc = [] + if not email_bcc: email_bcc = [] + if not body: body = u'' + + email_body_utf8 = ustr(body).encode('utf-8') + email_text_part = MIMEText(email_body_utf8 or '', _subtype=subtype, _charset='utf-8') + msg = MIMEMultipart() + + if not message_id: + if object_id: + message_id = tools.generate_tracking_message_id(object_id) + else: + message_id = make_msgid() + msg['Message-Id'] = encode_header(message_id) + if references: + msg['references'] = encode_header(references) + msg['Subject'] = encode_header(subject) + msg['From'] = encode_rfc2822_address_header(email_from) + del msg['Reply-To'] + if reply_to: + msg['Reply-To'] = encode_rfc2822_address_header(reply_to) + else: + msg['Reply-To'] = msg['From'] + msg['To'] = encode_rfc2822_address_header(COMMASPACE.join(email_to)) + if email_cc: + msg['Cc'] = encode_rfc2822_address_header(COMMASPACE.join(email_cc)) + if email_bcc: + msg['Bcc'] = encode_rfc2822_address_header(COMMASPACE.join(email_bcc)) + msg['Date'] = formatdate(localtime=True) + # Custom headers may override normal headers or provide additional ones + for key, value in headers.iteritems(): + msg[ustr(key).encode('utf-8')] = encode_header(value) + + if html2text and subtype == 'html': + # Always provide alternative text body if possible. + text_utf8 = tools.html2text(email_body_utf8.decode('utf-8')).encode('utf-8') + alternative_part = MIMEMultipart(_subtype="alternative") + alternative_part.attach(MIMEText(text_utf8, _charset='utf-8', _subtype='plain')) + alternative_part.attach(email_text_part) + msg.attach(alternative_part) + else: + msg.attach(email_text_part) + + if attachments: + for (fname, fcontent) in attachments: + filename_utf8 = ustr(fname).encode('utf-8') + part = MIMEBase('application', "octet-stream") + part.set_payload(fcontent) + Encoders.encode_base64(part) + # Force RFC2231 encoding for attachment filename + # See email.message.Message.add_header doc + part.add_header('Content-Disposition', 'attachment', + filename=('utf-8',None,filename_utf8)) + msg.attach(part) + return msg + + def send_email(self, cr, uid, message, mail_server_id=None, smtp_server=None, smtp_port=None, + smtp_user=None, smtp_password=None, smtp_encryption='none', smtp_debug=False, + context=None): + """Sends an email directly (no queuing). + + No retries are done, the caller should handle MailDeliveryException in order to ensure that + the mail is never lost. + + If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments. + If mail_server_id is None and smtp_server is None, use the default mail server (highest priority). + If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments. + If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config, + and fails if not found. + + :param message: the email.message.Message to send. The envelope sender will be extracted from the + ``Return-Path`` or ``From`` headers. The envelope recipients will be + extracted from the combined list of ``To``, ``CC`` and ``BCC`` headers. + :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments. + :param smtp_server: optional hostname of SMTP server to use + :param smtp_encryption: one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation) + :param smtp_port: optional SMTP port, if mail_server_id is not passed + :param smtp_user: optional SMTP user, if mail_server_id is not passed + :param smtp_password: optional SMTP password to use, if mail_server_id is not passed + :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed + :param debug: whether to turn on the SMTP level debugging, output to DEBUG log level + :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises + MailDeliveryException and logs root cause. + """ + smtp_from = message['Return-Path'] or message['From'] + assert smtp_from, "The Return-Path or From header is required for any outbound e-mail" + + # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters. + from_rfc2822 = extract_rfc2822_addresses(smtp_from) + assert len(from_rfc2822) == 1, "Malformed 'Return-Path' or 'From' address - it may only contain plain ASCII characters" + smtp_from = from_rfc2822[0] + email_to = message['To'] + email_cc = message['Cc'] + email_bcc = message['Bcc'] + smtp_to_list = filter(None, tools.flatten(map(extract_rfc2822_addresses,[email_to, email_cc, email_bcc]))) + assert smtp_to_list, "At least one valid recipient address should be specified for outgoing emails (To/Cc/Bcc)" + + # Get SMTP Server Details from Mail Server + mail_server = None + if mail_server_id: + mail_server = self.browse(cr, uid, mail_server_id) + elif not smtp_server: + mail_server_ids = self.search(cr, uid, [], order='sequence', limit=1) + if mail_server_ids: + mail_server = self.browse(cr, uid, mail_server_ids[0]) + else: + # we were passed an explicit smtp_server or nothing at all + smtp_server = smtp_server or tools.config.get('smtp_server') + smtp_port = tools.config.get('smtp_port', 25) if smtp_port is None else smtp_port + smtp_user = smtp_user or tools.config.get('smtp_user') + smtp_password = smtp_password or tools.config.get('smtp_password') + + if mail_server: + smtp_server = mail_server.smtp_host + smtp_user = mail_server.smtp_user + smtp_password = mail_server.smtp_pass + smtp_port = mail_server.smtp_port + smtp_encryption = mail_server.smtp_encryption + smtp_debug = smtp_debug or mail_server.smtp_debug + + if not smtp_server: + raise osv.except_osv( + _("Missing SMTP Server"), + _("Please define at least one SMTP server, or provide the SMTP parameters explicitly.")) + + try: + message_id = message['Message-Id'] + + # Add email in Maildir if smtp_server contains maildir. + if smtp_server.startswith('maildir:/'): + from mailbox import Maildir + maildir_path = smtp_server[8:] + mdir = Maildir(maildir_path, factory=None, create = True) + mdir.add(message.as_string(True)) + return message_id + + try: + smtp = self.connect(smtp_server, smtp_port, smtp_user, smtp_password, smtp_encryption, smtp_debug) + smtp.sendmail(smtp_from, smtp_to_list, message.as_string()) + finally: + try: + # Close Connection of SMTP Server + smtp.quit() + except Exception: + # ignored, just a consequence of the previous exception + pass + except Exception, e: + msg = _("Mail delivery failed via SMTP server '%s'.\n%s: %s") % (smtp_server, e.__class__.__name__, e) + _logger.exception(msg) + raise MailDeliveryException(_("Mail delivery failed"), msg) + return message_id + + def on_change_encryption(self, cr, uid, ids, smtp_encryption): + if smtp_encryption == 'ssl': + result = {'value': {'smtp_port': 465}} + if not 'SMTP_SSL' in smtplib.__all__: + result['warning'] = {'title': _('Warning'), + 'message': _('Your server does not seem to support SSL, you may want to try STARTTLS instead')} + else: + result = {'value': {'smtp_port': 25}} + return result + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 1ae54af0cb9..395bf3e8d60 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -56,14 +56,14 @@ def _in_modules(self, cr, uid, ids, field_name, arg, context=None): class ir_model(osv.osv): _name = 'ir.model' - _description = "Objects" + _description = "Models" _order = 'model' def _is_osv_memory(self, cr, uid, ids, field_name, arg, context=None): models = self.browse(cr, uid, ids, context=context) res = dict.fromkeys(ids) for model in models: - res[model.id] = isinstance(self.pool.get(model.model), osv.osv_memory) + res[model.id] = self.pool.get(model.model).is_transient() return res def _search_osv_memory(self, cr, uid, model, name, domain, context=None): @@ -85,8 +85,8 @@ class ir_model(osv.osv): return res _columns = { - 'name': fields.char('Object Name', size=64, translate=True, required=True), - 'model': fields.char('Object', size=64, required=True, select=1), + 'name': fields.char('Model Description', size=64, translate=True, required=True), + 'model': fields.char('Model', size=64, required=True, select=1), 'info': fields.text('Information'), 'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True), 'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Type',readonly=True), @@ -97,12 +97,12 @@ class ir_model(osv.osv): 'modules': fields.function(_in_modules, method=True, type='char', size=128, string='In modules', help='List of modules in which the object is defined or inherited'), 'view_ids': fields.function(_view_ids, method=True, type='one2many', obj='ir.ui.view', string='Views'), } - + _defaults = { 'model': lambda *a: 'x_', 'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base', } - + def _check_model_name(self, cr, uid, ids, context=None): for model in self.browse(cr, uid, ids, context=context): if model.state=='manual': @@ -114,9 +114,13 @@ class ir_model(osv.osv): def _model_name_msg(self, cr, uid, ids, context=None): return _('The Object name must start with x_ and not contain any special character !') + _constraints = [ (_check_model_name, _model_name_msg, ['model']), ] + _sql_constraints = [ + ('obj_name_uniq', 'unique (model)', 'Each model must be unique!'), + ] # overridden to allow searching both on model name (model field) # and model description (name field) @@ -161,7 +165,7 @@ class ir_model(osv.osv): pass x_custom_model._name = model x_custom_model._module = False - a = x_custom_model.createInstance(self.pool, cr) + a = x_custom_model.create_instance(self.pool, cr) if (not a._columns) or ('x_name' in a._columns.keys()): x_name = 'x_name' else: @@ -477,14 +481,12 @@ class ir_model_access(osv.osv): if isinstance(model, browse_record): assert model._table_name == 'ir.model', 'Invalid model object' - model_name = model.name + model_name = model.model else: model_name = model - # osv_memory objects can be read by everyone, as they only return - # results that belong to the current user (except for superuser) - model_obj = self.pool.get(model_name) - if isinstance(model_obj, osv.osv_memory): + # TransientModel records have no access rights, only an implicit access rule + if self.pool.get(model_name).is_transient(): return True # We check if a specific rule exists @@ -519,7 +521,7 @@ class ir_model_access(osv.osv): } raise except_orm(_('AccessError'), msgs[mode] % (model_name, groups) ) - return r + return r or False __cache_clearing_methods = [] @@ -616,7 +618,7 @@ class ir_model_data(osv.osv): """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 references to %s.%s' % (module, xml_id)) + 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] @@ -626,7 +628,7 @@ class ir_model_data(osv.osv): data_id = self._get_id(cr, uid, module, xml_id) res = self.read(cr, uid, data_id, ['model', 'res_id']) if not res['res_id']: - raise ValueError('No references to %s.%s' % (module, xml_id)) + raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id)) return (res['model'], res['res_id']) def get_object(self, cr, uid, module, xml_id, context=None): diff --git a/openerp/addons/base/ir/ir_rule.py b/openerp/addons/base/ir/ir_rule.py index 734d00eb9a2..33f926e55c2 100644 --- a/openerp/addons/base/ir/ir_rule.py +++ b/openerp/addons/base/ir/ir_rule.py @@ -26,8 +26,7 @@ from functools import partial import tools from tools.safe_eval import safe_eval as eval from tools.misc import unquote as unquote - -SUPERUSER_UID = 1 +from openerp import SUPERUSER_ID class ir_rule(osv.osv): _name = 'ir.rule' @@ -68,7 +67,7 @@ class ir_rule(osv.osv): return res def _check_model_obj(self, cr, uid, ids, context=None): - return not any(isinstance(self.pool.get(rule.model_id.model), osv.osv_memory) for rule in self.browse(cr, uid, ids, context)) + return not any(self.pool.get(rule.model_id.model).is_transient() for rule in self.browse(cr, uid, ids, context)) _columns = { 'name': fields.char('Name', size=128, select=1), @@ -104,7 +103,7 @@ class ir_rule(osv.osv): if mode not in self._MODES: raise ValueError('Invalid mode: %r' % (mode,)) - if uid == SUPERUSER_UID: + if uid == SUPERUSER_ID: return None cr.execute("""SELECT r.id FROM ir_rule r @@ -117,10 +116,10 @@ class ir_rule(osv.osv): rule_ids = [x[0] for x in cr.fetchall()] if rule_ids: # browse user as super-admin root to avoid access errors! - user = self.pool.get('res.users').browse(cr, SUPERUSER_UID, uid) + user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid) global_domains = [] # list of domains group_domains = {} # map: group -> list of domains - for rule in self.browse(cr, SUPERUSER_UID, rule_ids): + for rule in self.browse(cr, SUPERUSER_ID, rule_ids): # read 'domain' as UID to have the correct eval context for the rule. rule_domain = self.read(cr, uid, rule.id, ['domain'])['domain'] dom = expression.normalize(rule_domain) diff --git a/openerp/addons/base/ir/ir_sequence.py b/openerp/addons/base/ir/ir_sequence.py index 4267e92d54d..ff00127905a 100644 --- a/openerp/addons/base/ir/ir_sequence.py +++ b/openerp/addons/base/ir/ir_sequence.py @@ -19,83 +19,223 @@ # ############################################################################## +import logging import time -from osv import fields,osv -import pooler -class ir_sequence_type(osv.osv): +import openerp + +_logger = logging.getLogger('ir_sequence') + +class ir_sequence_type(openerp.osv.osv.osv): _name = 'ir.sequence.type' _order = 'name' _columns = { - 'name': fields.char('Name',size=64, required=True), - 'code': fields.char('Code',size=32, required=True), + 'name': openerp.osv.fields.char('Name', size=64, required=True), + 'code': openerp.osv.fields.char('Code', size=32, required=True), } -ir_sequence_type() + + _sql_constraints = [ + ('code_unique', 'unique(code)', '`code` must be unique.'), + ] def _code_get(self, cr, uid, context={}): cr.execute('select code, name from ir_sequence_type') return cr.fetchall() -class ir_sequence(osv.osv): +class ir_sequence(openerp.osv.osv.osv): + """ Sequence model. + + The sequence model allows to define and use so-called sequence objects. + Such objects are used to generate unique identifiers in a transaction-safe + way. + + """ _name = 'ir.sequence' _order = 'name' _columns = { - 'name': fields.char('Name',size=64, required=True), - 'code': fields.selection(_code_get, 'Code',size=64, required=True), - 'active': fields.boolean('Active'), - 'prefix': fields.char('Prefix',size=64, help="Prefix value of the record for the sequence"), - 'suffix': fields.char('Suffix',size=64, help="Suffix value of the record for the sequence"), - 'number_next': fields.integer('Next Number', required=True, help="Next number of this sequence"), - 'number_increment': fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"), - 'padding' : fields.integer('Number padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."), - 'company_id': fields.many2one('res.company', 'Company'), + 'name': openerp.osv.fields.char('Name', size=64, required=True), + 'code': openerp.osv.fields.selection(_code_get, 'Code', size=64), + 'implementation': openerp.osv.fields.selection( # TODO update the view + [('standard', 'Standard'), ('no_gap', 'No gap')], + 'Implementation', required=True, + help="Two sequence object implementations are offered: Standard " + "and 'No gap'. The later is slower than the former but forbids any" + " gap in the sequence (while they are possible in the former)."), + 'active': openerp.osv.fields.boolean('Active'), + 'prefix': openerp.osv.fields.char('Prefix', size=64, help="Prefix value of the record for the sequence"), + 'suffix': openerp.osv.fields.char('Suffix', size=64, help="Suffix value of the record for the sequence"), + 'number_next': openerp.osv.fields.integer('Next Number', required=True, help="Next number of this sequence"), + 'number_increment': openerp.osv.fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"), + 'padding' : openerp.osv.fields.integer('Number Padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."), + 'company_id': openerp.osv.fields.many2one('res.company', 'Company'), } _defaults = { - 'active': lambda *a: True, + 'implementation': 'standard', + 'active': True, 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'ir.sequence', context=c), - 'number_increment': lambda *a: 1, - 'number_next': lambda *a: 1, - 'padding' : lambda *a : 0, + 'number_increment': 1, + 'number_next': 1, + 'padding' : 0, } - def _process(self, s): - return (s or '') % { - 'year':time.strftime('%Y'), - 'month': time.strftime('%m'), - 'day':time.strftime('%d'), - 'y': time.strftime('%y'), - 'doy': time.strftime('%j'), - 'woy': time.strftime('%W'), - 'weekday': time.strftime('%w'), - 'h24': time.strftime('%H'), - 'h12': time.strftime('%I'), - 'min': time.strftime('%M'), - 'sec': time.strftime('%S'), - } + def init(self, cr): + return # Don't do the following index yet. + # CONSTRAINT/UNIQUE INDEX on (code, company_id) + # /!\ The unique constraint 'unique_name_company_id' is not sufficient, because SQL92 + # only support field names in constraint definitions, and we need a function here: + # we need to special-case company_id to treat all NULL company_id as equal, otherwise + # we would allow duplicate (code, NULL) ir_sequences. + cr.execute(""" + SELECT indexname FROM pg_indexes WHERE indexname = + 'ir_sequence_unique_code_company_id_idx'""") + if not cr.fetchone(): + cr.execute(""" + CREATE UNIQUE INDEX ir_sequence_unique_code_company_id_idx + ON ir_sequence (code, (COALESCE(company_id,-1)))""") + + def _create_sequence(self, cr, id, number_increment, number_next): + """ Create a PostreSQL sequence. + + There is no access rights check. + """ + assert isinstance(id, (int, long)) + sql = "CREATE SEQUENCE ir_sequence_%03d INCREMENT BY %%s START WITH %%s" % id + cr.execute(sql, (number_increment, number_next)) + + def _drop_sequence(self, cr, ids): + """ Drop the PostreSQL sequence if it exists. + + There is no access rights check. + """ + + ids = ids if isinstance(ids, (list, tuple)) else [ids] + assert all(isinstance(i, (int, long)) for i in ids), \ + "Only ids in (int, long) allowed." + names = ','.join('ir_sequence_%03d' % i for i in ids) + + # RESTRICT is the default; it prevents dropping the sequence if an + # object depends on it. + cr.execute("DROP SEQUENCE IF EXISTS %s RESTRICT " % names) + + def _alter_sequence(self, cr, id, number_increment, number_next): + """ Alter a PostreSQL sequence. + + There is no access rights check. + """ + assert isinstance(id, (int, long)) + cr.execute(""" + ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s + """ % id, (number_increment, number_next)) - def get_id(self, cr, uid, sequence_id, test='id', context=None): - assert test in ('code','id') - company_ids = self.pool.get('res.company').search(cr, uid, [], context=context) - cr.execute('''SELECT id, number_next, prefix, suffix, padding - FROM ir_sequence - WHERE %s=%%s - AND active=true - AND (company_id in %%s or company_id is NULL) - ORDER BY company_id, id - FOR UPDATE NOWAIT''' % test, - (sequence_id, tuple(company_ids))) - res = cr.dictfetchone() - if res: - cr.execute('UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s AND active=true', (res['id'],)) - if res['number_next']: - return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix']) + def create(self, cr, uid, values, context=None): + """ Create a sequence, in implementation == standard a fast gaps-allowed PostgreSQL sequence is used. + """ + values = self._add_missing_default_values(cr, uid, values, context) + values['id'] = super(ir_sequence, self).create(cr, uid, values, context) + if values['implementation'] == 'standard': + f = self._create_sequence(cr, values['id'], values['number_increment'], values['number_next']) + return values['id'] + + def unlink(self, cr, uid, ids, context=None): + super(ir_sequence, self).unlink(cr, uid, ids, context) + self._drop_sequence(cr, ids) + return True + + def write(self, cr, uid, ids, values, context=None): + if not isinstance(ids, (list, tuple)): + ids = [ids] + new_implementation = values.get('implementation') + rows = self.read(cr, uid, ids, ['implementation', 'number_increment', 'number_next'], context) + super(ir_sequence, self).write(cr, uid, ids, values, context) + + for row in rows: + # 4 cases: we test the previous impl. against the new one. + if row['implementation'] == 'standard': + i = values.get('number_increment', row['number_increment']) + n = values.get('number_next', row['number_next']) + if new_implementation in ('standard', None): + self._alter_sequence(cr, row['id'], i, n) + else: + self._drop_sequence(cr, row['id']) else: - return self._process(res['prefix']) + self._process(res['suffix']) - return False + if new_implementation in ('no_gap', None): + pass + else: + self._create_sequence(cr, row['id'], i, n) + + return True + + def _interpolate(self, s, d): + if s: + return s % d + return '' + + def _interpolation_dict(self): + t = time.localtime() # Actually, the server is always in UTC. + return { + 'year': time.strftime('%Y', t), + 'month': time.strftime('%m', t), + 'day': time.strftime('%d', t), + 'y': time.strftime('%y', t), + 'doy': time.strftime('%j', t), + 'woy': time.strftime('%W', t), + 'weekday': time.strftime('%w', t), + 'h24': time.strftime('%H', t), + 'h12': time.strftime('%I', t), + 'min': time.strftime('%M', t), + 'sec': time.strftime('%S', t), + } + + def _next(self, cr, uid, seq_ids, context=None): + if not seq_ids: + return False + seq = self.read(cr, uid, seq_ids[:1], ['implementation','number_next','prefix','suffix','padding'])[0] + if seq['implementation'] == 'standard': + cr.execute("SELECT nextval('ir_sequence_%03d')" % seq['id']) + seq['number_next'] = cr.fetchone() + else: + cr.execute("SELECT number_next FROM ir_sequence WHERE id=%s FOR UPDATE NOWAIT", (seq['id'],)) + cr.execute("UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s ", (seq['id'],)) + d = self._interpolation_dict() + interpolated_prefix = self._interpolate(seq['prefix'], d) + interpolated_suffix = self._interpolate(seq['suffix'], d) + return interpolated_prefix + '%%0%sd' % seq['padding'] % seq['number_next'] + interpolated_suffix + + def next_by_id(self, cr, uid, sequence_id, context=None): + """ Draw an interpolated string using the specified sequence.""" + self.check_read(cr, uid) + company_ids = self.pool.get('res.company').search(cr, uid, [], context=context) + [False] + ids = self.search(cr, uid, ['&',('id','=', sequence_id),('company_id','in',company_ids)]) + return self._next(cr, uid, ids, context) + + def next_by_code(self, cr, uid, sequence_code, context=None): + """ Draw an interpolated string using the specified sequence.""" + self.check_read(cr, uid) + company_ids = self.pool.get('res.company').search(cr, uid, [], context=context) + [False] + ids = self.search(cr, uid, ['&',('code','=', sequence_code),('company_id','in',company_ids)]) + return self._next(cr, uid, ids, context) + + def get_id(self, cr, uid, sequence_code_or_id, code_or_id='id', context=None): + """ Draw an interpolated string using the specified sequence. + + The sequence to use is specified by the ``sequence_code_or_id`` + argument, which can be a code or an id (as controlled by the + ``code_or_id`` argument. This method is deprecated. + """ + _logger.warning("ir_sequence.get() and ir_sequence.get_id() are deprecated. " + "Please use ir_sequence.next_by_code() or ir_sequence.next_by_id().") + if code_or_id == 'id': + return self.next_by_id(cr, uid, sequence_code_or_id, context) + else: + return self.next_by_code(cr, uid, sequence_code_or_id, context) + + def get(self, cr, uid, code, context=None): + """ Draw an interpolated string using the specified sequence. - def get(self, cr, uid, code): - return self.get_id(cr, uid, code, test='code') -ir_sequence() + The sequence to use is specified by its code. This method is + deprecated. + """ + return self.get_id(cr, uid, code, 'code', context) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 813ab514b0f..44f5d24823d 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -108,8 +108,8 @@ class ir_translation(osv.osv): 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, uid, name, tt, lang, ids) cr.execute('delete from ir_translation ' \ 'where lang=%s ' \ @@ -189,7 +189,7 @@ class ir_translation(osv.osv): 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_ids.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['res_id']) return result def unlink(self, cursor, user, ids, context=None): @@ -199,7 +199,7 @@ class ir_translation(osv.osv): 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'], source=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_ids.clear_cache(self, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], trans_obj['res_id']) result = super(ir_translation, self).unlink(cursor, user, ids, context=context) return result diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index 90990834c9b..c44ff716519 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -96,6 +96,19 @@ class view(osv.osv): if not cr.fetchone(): cr.execute('CREATE INDEX ir_ui_view_model_type_inherit_id ON ir_ui_view (model, type, inherit_id)') + def get_inheriting_views_arch(self, cr, uid, view_id, model, context=None): + """Retrieves the architecture of views that inherit from the given view. + + :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) + :rtype: list of tuples + :return: [(view_arch,view_id), ...] + """ + cr.execute("""SELECT arch, id FROM ir_ui_view WHERE inherit_id=%s AND model=%s + ORDER BY priority""", + (view_id, model)) + return cr.fetchall() + def write(self, cr, uid, ids, vals, context={}): if not isinstance(ids, (list, tuple)): ids = [ids] @@ -159,10 +172,10 @@ class view(osv.osv): label_string = "" if label: for lbl in eval(label): - if t.has_key(str(lbl)) and str(t[lbl])=='False': + if t.has_key(tools.ustr(lbl)) and tools.ustr(t[lbl])=='False': label_string = label_string + ' ' else: - label_string = label_string + " " + t[lbl] + label_string = label_string + " " + tools.ustr(t[lbl]) labels[str(t['id'])] = (a['id'],label_string) g = graph(nodes, transitions, no_ancester) g.process(start) diff --git a/openerp/addons/base/ir/osv_memory_autovacuum.py b/openerp/addons/base/ir/osv_memory_autovacuum.py index b2ab938d740..975fcd0a403 100644 --- a/openerp/addons/base/ir/osv_memory_autovacuum.py +++ b/openerp/addons/base/ir/osv_memory_autovacuum.py @@ -19,18 +19,15 @@ # ############################################################################## -from osv import osv -from osv.orm import orm_memory +import openerp -class osv_memory_autovacuum(osv.osv_memory): +class osv_memory_autovacuum(openerp.osv.osv.osv_memory): + """ Expose the osv_memory.vacuum() method to the cron jobs mechanism. """ _name = 'osv_memory.autovacuum' def power_on(self, cr, uid, context=None): - for model in self.pool.obj_list(): - obj = self.pool.get(model) - if isinstance(obj, orm_memory): - obj.vaccum(cr, uid) + for model in self.pool.models.values(): + if model.is_transient(): + model._transient_vacuum(cr, uid) return True -osv_memory_autovacuum() - diff --git a/openerp/addons/base/ir/wizard/__init__.py b/openerp/addons/base/ir/wizard/__init__.py index 99c6cdcd0de..3f5495524f5 100644 --- a/openerp/addons/base/ir/wizard/__init__.py +++ b/openerp/addons/base/ir/wizard/__init__.py @@ -20,6 +20,5 @@ ############################################################################## import wizard_menu import wizard_screen -import create_action # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/ir/wizard/create_action.py b/openerp/addons/base/ir/wizard/create_action.py deleted file mode 100644 index 335f7a5ce04..00000000000 --- a/openerp/addons/base/ir/wizard/create_action.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- - ############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -import wizard -import pooler -import time - -action_type = '''<?xml version="1.0"?> -<form string="Select Action Type"> - <field name="type"/> -</form>''' - -action_type_fields = { - 'type': {'string':"Select Action Type",'type':'selection','required':True ,'selection':[('ir.actions.report.xml','Open Report')]}, -} - -report_action = '''<?xml version="1.0"?> -<form string="Select Report"> - <field name="report" colspan="4"/> -</form>''' - -report_action_fields = { - 'report': {'string':"Select Report",'type':'many2one','relation':'ir.actions.report.xml', 'required':True}, -} - -class create_action(wizard.interface): - - def _create_report_action(self, cr, uid, data, context={}): - pool = pooler.get_pool(cr.dbname) - - reports = pool.get('ir.actions.report.xml') - form = data['form'] - - rpt = reports.browse(cr, uid, form['report']) - - action = """action = {"type": "ir.actions.report.xml","model":"%s","report_name": "%s","ids": context["active_ids"]}""" % (rpt.model, rpt.report_name) - - obj = pool.get('ir.actions.server') - obj.write(cr, uid, data['ids'], {'code':action}) - - return {} - - states = { - 'init': { - 'actions': [], - 'result': {'type':'form', 'arch':action_type,'fields':action_type_fields, 'state':[('step_1','Next'),('end','Close')]} - }, - 'step_1': { - 'actions': [], - 'result': {'type':'form', 'arch':report_action,'fields':report_action_fields, 'state':[('create','Create'),('end','Close')]} - }, - 'create': { - 'actions': [_create_report_action], - 'result': {'type':'state', 'state':'end'} - }, - } -create_action('server.action.create') - - diff --git a/openerp/addons/base/ir/wizard/wizard_menu_view.xml b/openerp/addons/base/ir/wizard/wizard_menu_view.xml index 4d3e7e7a26e..d99138d00e6 100644 --- a/openerp/addons/base/ir/wizard/wizard_menu_view.xml +++ b/openerp/addons/base/ir/wizard/wizard_menu_view.xml @@ -21,12 +21,5 @@ </field> </record> <act_window context="{'model_id': active_id}" id="act_menu_create" name="Create Menu" res_model="wizard.ir.model.menu.create" target="new" view_mode="form"/> - <wizard - id="wizard_server_action_create" - model="ir.actions.server" - name="server.action.create" - string="Create Action" - menu="False" - /> </data> </openerp> diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 034829b82b5..a35e4b5d1ce 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -107,48 +107,59 @@ class module(osv.osv): view_obj = self.pool.get('ir.ui.view') report_obj = self.pool.get('ir.actions.report.xml') menu_obj = self.pool.get('ir.ui.menu') - mlist = self.browse(cr, uid, ids, context=context) - mnames = {} - for m in mlist: - # skip uninstalled modules below, - # no data to find anyway - if m.state in ('installed', 'to upgrade', 'to remove'): - mnames[m.name] = m.id - res[m.id] = { - 'menus_by_module':[], - 'reports_by_module':[], + + dmodels = [] + if field_name is None or 'views_by_module' in field_name: + dmodels.append('ir.ui.view') + if field_name is None or 'reports_by_module' in field_name: + dmodels.append('ir.actions.report.xml') + if field_name is None or 'menus_by_module' in field_name: + dmodels.append('ir.ui.menu') + assert dmodels, "no models for %s" % field_name + + for module_rec in self.browse(cr, uid, ids, context=context): + res[module_rec.id] = { + 'menus_by_module': [], + 'reports_by_module': [], 'views_by_module': [] } - if not mnames: - return res + # Skip uninstalled modules below, no data to find anyway. + if module_rec.state not in ('installed', 'to upgrade', 'to remove'): + continue + + # then, search and group ir.model.data records + imd_models = dict( [(m,[]) for m in dmodels]) + imd_ids = model_data_obj.search(cr,uid,[('module','=', module_rec.name), + ('model','in',tuple(dmodels))]) - view_id = model_data_obj.search(cr,uid,[('module','in', mnames.keys()), - ('model','in',('ir.ui.view','ir.actions.report.xml','ir.ui.menu'))]) - for data_id in model_data_obj.browse(cr,uid,view_id,context): - # We use try except, because views or menus may not exist + for imd_res in model_data_obj.read(cr, uid, imd_ids, ['model', 'res_id'], context=context): + imd_models[imd_res['model']].append(imd_res['res_id']) + + # For each one of the models, get the names of these ids. + # We use try except, because views or menus may not exist. try: - key = data_id.model - res_mod_dic = res[mnames[data_id.module]] - if key=='ir.ui.view': - v = view_obj.browse(cr,uid,data_id.res_id) + res_mod_dic = res[module_rec.id] + for v in view_obj.browse(cr, uid, imd_models.get('ir.ui.view', []), context=context): aa = v.inherit_id and '* INHERIT ' or '' res_mod_dic['views_by_module'].append(aa + v.name + '('+v.type+')') - elif key=='ir.actions.report.xml': - res_mod_dic['reports_by_module'].append(report_obj.browse(cr,uid,data_id.res_id).name) - elif key=='ir.ui.menu': - res_mod_dic['menus_by_module'].append(menu_obj.browse(cr,uid,data_id.res_id).complete_name) + + for rx in report_obj.browse(cr, uid, imd_models.get('ir.actions.report.xml', []), context=context): + res_mod_dic['reports_by_module'].append(rx.name) + + for um in menu_obj.browse(cr, uid, imd_models.get('ir.ui.menu', []), context=context): + res_mod_dic['menus_by_module'].append(um.complete_name) except KeyError, e: self.__logger.warning( - 'Data not found for reference %s[%s:%s.%s]', data_id.model, - data_id.res_id, data_id.model, data_id.name, exc_info=True) - pass + 'Data not found for items of %s', module_rec.name) + except AttributeError, e: + self.__logger.warning( + 'Data not found for items of %s %s', module_rec.name, str(e)) except Exception, e: - self.__logger.warning('Unknown error while browsing %s[%s]', - data_id.model, data_id.res_id, exc_info=True) - pass + self.__logger.warning('Unknown error while fetching data of %s', + module_rec.name, exc_info=True) for key, value in res.iteritems(): - for k, v in res[key].iteritems() : + for k, v in res[key].iteritems(): res[key][k] = "\n".join(sorted(v)) return res @@ -437,12 +448,11 @@ class module(osv.osv): res.append(mod.url) if not download: continue - zipfile = urllib.urlopen(mod.url).read() + zip_content = urllib.urlopen(mod.url).read() fname = addons.get_module_path(str(mod.name)+'.zip', downloaded=True) try: - fp = file(fname, 'wb') - fp.write(zipfile) - fp.close() + with open(fname, 'wb') as fp: + fp.write(zip_content) except Exception: self.__logger.exception('Error when trying to create module ' 'file %s', fname) diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py index d73cd0864a6..fdb9a177d8b 100644 --- a/openerp/addons/base/module/wizard/base_import_language.py +++ b/openerp/addons/base/module/wizard/base_import_language.py @@ -35,9 +35,12 @@ class base_language_import(osv.osv_memory): 'name': fields.char('Language Name',size=64 , required=True), 'code': fields.char('Code (eg:en__US)',size=5 , required=True), 'data': fields.binary('File', required=True), + 'overwrite': fields.boolean('Overwrite Existing Terms', + help="If you enable this option, existing translations (including custom ones) " + "will be overwritten and replaced by those in this file"), } - def import_lang(self, cr, uid, ids, context): + def import_lang(self, cr, uid, ids, context=None): """ Import Language @param cr: the current row, from the database cursor. @@ -45,8 +48,11 @@ class base_language_import(osv.osv_memory): @param ids: the ID or list of IDs @param context: A standard dictionary """ - + if context is None: + context = {} import_data = self.browse(cr, uid, ids)[0] + if import_data.overwrite: + context.update(overwrite=True) fileobj = TemporaryFile('w+') fileobj.write(base64.decodestring(import_data.data)) @@ -56,7 +62,7 @@ class base_language_import(osv.osv_memory): fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po' fileobj.seek(0) - tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name) + tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name, context=context) tools.trans_update_res_ids(cr) fileobj.close() return {} diff --git a/openerp/addons/base/module/wizard/base_import_language_view.xml b/openerp/addons/base/module/wizard/base_import_language_view.xml index d313afc4080..4a1d7e5b758 100644 --- a/openerp/addons/base/module/wizard/base_import_language_view.xml +++ b/openerp/addons/base/module/wizard/base_import_language_view.xml @@ -27,6 +27,7 @@ <field name="name" width="200"/> <field name="code"/> <field name="data" colspan="4"/> + <field name="overwrite"/> </group> <group colspan="8" col="8"> <separator string="" colspan="8"/> diff --git a/openerp/addons/base/module/wizard/base_module_import.py b/openerp/addons/base/module/wizard/base_module_import.py index 05c3b18198d..3ef9132af0e 100644 --- a/openerp/addons/base/module/wizard/base_module_import.py +++ b/openerp/addons/base/module/wizard/base_module_import.py @@ -28,6 +28,8 @@ import base64 from tools.translate import _ from osv import osv, fields +ADDONS_PATH = tools.config['addons_path'].split(",")[-1] + class base_module_import(osv.osv_memory): """ Import Module """ @@ -37,7 +39,8 @@ class base_module_import(osv.osv_memory): _columns = { 'module_file': fields.binary('Module .ZIP file', required=True), - 'state':fields.selection([('init','init'),('done','done')], 'state', readonly=True), + 'state':fields.selection([('init','init'),('done','done')], + 'state', readonly=True), 'module_name': fields.char('Module Name', size=128), } @@ -48,26 +51,30 @@ class base_module_import(osv.osv_memory): def importzip(self, cr, uid, ids, context): (data,) = self.browse(cr, uid, ids , context=context) module_data = data.module_file - - val = base64.decodestring(module_data) + zip_data = base64.decodestring(module_data) fp = StringIO() - fp.write(val) - fdata = zipfile.ZipFile(fp, 'r') - fname = fdata.namelist()[0] - module_name = os.path.split(fname)[0] - - ad = tools.config['addons_path'].split(",")[-1] + fp.write(zip_data) + try: + file_data = zipfile.ZipFile(fp, 'r') + except zipfile.BadZipfile: + raise osv.except_osv(_('Error !'), _('File is not a zip file!')) + init_file_name = sorted(file_data.namelist())[0] + module_name = os.path.split(init_file_name)[0] - fname = os.path.join(ad, module_name+'.zip') + file_path = os.path.join(ADDONS_PATH, '%s.zip' % module_name) try: - fp = file(fname, 'wb') - fp.write(val) - fp.close() + zip_file = open(file_path, 'wb') except IOError: - raise osv.except_osv(_('Error !'), _('Can not create the module file: %s !') % (fname,) ) + raise osv.except_osv(_('Error !'), + _('Can not create the module file: %s !') % \ + (file_path,) ) + zip_file.write(zip_data) + zip_file.close() - self.pool.get('ir.module.module').update_list(cr, uid, {'module_name': module_name,}) - self.write(cr, uid, ids, {'state':'done', 'module_name': module_name}, context) + self.pool.get('ir.module.module').update_list(cr, uid, + {'module_name': module_name,}) + self.write(cr, uid, ids, {'state':'done', 'module_name': module_name}, + context) return False def action_module_open(self, cr, uid, ids, context): @@ -84,4 +91,4 @@ class base_module_import(osv.osv_memory): base_module_import() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_module_import_view.xml b/openerp/addons/base/module/wizard/base_module_import_view.xml index 8e43789b057..0ca3e14ea96 100644 --- a/openerp/addons/base/module/wizard/base_module_import_view.xml +++ b/openerp/addons/base/module/wizard/base_module_import_view.xml @@ -12,9 +12,10 @@ <group colspan="3" col="1"> <field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/> <newline/> - <label width="220" string="This wizard helps you add a new language to you OpenERP system. After loading a new language it becomes available as default interface language for users and partners."/> + <label width="220" string='This wizard helps you to import a new module to your OpenERP system. +After importing a new module you can install it by clicking on the button "Install" from the form view.'/> <label width="220"/> - <label width="220" string="Please be patient, this operation may take a few minutes (depending on the number of modules currently installed)..."/> + <label width="220" string="Please be patient, this operation may take a few minutes..."/> <field name="state" invisible="1"/> </group> <separator orientation="vertical" rowspan="5"/> diff --git a/openerp/addons/base/res/__init__.py b/openerp/addons/base/res/__init__.py index 9ce69f0c317..2b4da739f54 100644 --- a/openerp/addons/base/res/__init__.py +++ b/openerp/addons/base/res/__init__.py @@ -29,10 +29,10 @@ import res_bank import res_config import res_currency import res_company -import res_user +import res_users import res_request -import res_lang -import res_log +import res_lang +import res_log import res_widget import ir_property diff --git a/openerp/addons/base/res/ir_property_view.xml b/openerp/addons/base/res/ir_property_view.xml index af836a3c92e..67b3357a4df 100644 --- a/openerp/addons/base/res/ir_property_view.xml +++ b/openerp/addons/base/res/ir_property_view.xml @@ -13,6 +13,7 @@ help="Parameters that are used by all resources." domain="[('res_id','=',False)]"/> <separator orientation="vertical"/> + <field name="fields_id" /> <field name="name"/> <field name="company_id" groups="base.group_multi_company"/> </search> diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 3ad0cfcfb55..e2c5e091f97 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -88,6 +88,18 @@ class res_company(osv.osv): result[company.id][field] = address[field] or False return result + + def _get_bank_data(self, cr, uid, ids, field_names, arg, context=None): + """ Read the 'address' functional fields. """ + result = {} + for company in self.browse(cr, uid, ids, context=context): + r = [] + for bank in company.bank_ids: + if bank.footer: + r.append(bank.name_get(context=context)[0][1]) + result[company.id] = ' | '.join(r) + return result + def _set_address_data(self, cr, uid, company_id, name, value, arg, context=None): """ Write the 'address' functional fields. """ company = self.browse(cr, uid, company_id, context=context) @@ -102,19 +114,9 @@ class res_company(osv.osv): address_obj.create(cr, uid, {name: value or False, 'partner_id': company.partner_id.id}, context=context) return True - def _get_bank_data(self, cr, uid, ids, field_names, arg, context=None): - """ Read the 'address' functional fields. """ - result = {} - for company in self.browse(cr, uid, ids, context=context): - r = [] - for bank in company.bank_ids: - if bank.footer: - r.append(bank.name_get(context=context)[0][1]) - result[company.id] = ' | '.join(r) - return result _columns = { - 'name': fields.char('Company Name', size=64, required=True), + 'name': fields.related('partner_id', 'name', string='Company Name', size=64, required=True, store=True, type='char'), 'parent_id': fields.many2one('res.company', 'Parent Company', select=True), 'child_ids': fields.one2many('res.company', 'parent_id', 'Child Companies'), 'partner_id': fields.many2one('res.partner', 'Partner', required=True), @@ -143,6 +145,18 @@ class res_company(osv.osv): 'vat': fields.related('partner_id', 'vat', string="Tax ID", type="char", size=32), 'company_registry': fields.char('Company Registry', size=64), } + _sql_constraints = [ + ('name_uniq', 'unique (name)', 'The company name must be unique !') + ] + def on_change_header(self, cr, uid, ids, phone, email, fax, website, vat, reg=False, context={}): + val = [] + if phone: val.append(_('Phone: ')+phone) + if fax: val.append(_('Fax: ')+fax) + if website: val.append(_('Website: ')+website) + if vat: val.append(_('VAT: ')+vat) + if reg: val.append(_('Reg: ')+reg) + return {'value': {'rml_footer1':' | '.join(val)}} + def _search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): @@ -225,16 +239,6 @@ class res_company(osv.osv): self.cache_restart(cr) return super(res_company, self).write(cr, *args, **argv) - def generate_header(self, cr, uid, ids, context=None): - for c in self.browse(cr, uid, ids, context=context): - val = [] - if c.phone: val.append(_('Phone: ')+c.phone) - if c.fax: val.append(_('Fax: ')+c.fax) - if c.website: val.append(_('Website: ')+c.website) - if c.vat: val.append(_('VAT: ')+c.vat) - if c.company_registry: val.append(_('Reg: ')+c.company_registry) - self.write(cr,uid, [c.id], {'rml_footer1':' | '.join(val)}, context) - def _get_euro(self, cr, uid, context={}): try: return self.pool.get('res.currency').search(cr, uid, [])[0] @@ -242,9 +246,7 @@ class res_company(osv.osv): return False def _get_logo(self, cr, uid, ids): - return open(os.path.join( - tools.config['root_path'], '..', 'pixmaps', 'your_logo.png'), - 'rb') .read().encode('base64') + return open(os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'res_company_logo.png'), 'rb') .read().encode('base64') _header = """ <header> diff --git a/pixmaps/your_logo.png b/openerp/addons/base/res/res_company_logo.png Binary files differindex f5f05b08653..f5f05b08653 100644 --- a/pixmaps/your_logo.png +++ b/openerp/addons/base/res/res_company_logo.png diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index df508bad5c9..3cec8b740ec 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -39,27 +39,6 @@ class res_config_configurable(osv.osv_memory): _inherit = 'ir.wizard.screen' __logger = logging.getLogger(_name) - def get_current_progress(self, cr, uid, context=None): - '''Return a description the current progress of configuration: - a tuple of (non_open_todos:int, total_todos: int) - ''' - return itemgetter('done', 'total')( - self.pool.get('ir.actions.todo').progress(cr, uid, context=context)) - - def _progress(self, cr, uid, context=None): - closed, total = self.get_current_progress(cr, uid, context=context) - if total: - return round(closed*100./total) - return 100. - - _columns = dict( - progress = fields.float('Configuration Progress', readonly=True), - ) - - _defaults = dict( - progress = _progress, - ) - def _next_action(self, cr, uid, context=None): Todos = self.pool['ir.actions.todo'] self.__logger.info('getting next %s', Todos) @@ -91,11 +70,7 @@ class res_config_configurable(osv.osv_memory): res = next.action_launch(context=context) res['nodestroy'] = False return res - self.__logger.info('all configuration actions have been executed') - - current_user_menu = self.pool.get('res.users').browse(cr, uid, uid).menu_id - # return the action associated with the menu - return self.pool.get(current_user_menu.type).read(cr, uid, current_user_menu.id) + return {'type' : 'ir.actions.act_window_close'} def start(self, cr, uid, ids, context=None): return self.next(cr, uid, ids, context) diff --git a/openerp/addons/base/res/res_config.xml b/openerp/addons/base/res/res_config.xml index 56432f51f7b..2da5dc32e8e 100644 --- a/openerp/addons/base/res/res_config.xml +++ b/openerp/addons/base/res/res_config.xml @@ -21,12 +21,11 @@ <group colspan="8" col="8"> <separator string="" colspan="6"/> <group colspan="4" width="220"> - <field name="progress" widget="progressbar" nolabel="1" colspan="2"/> </group> <button name="action_skip" icon="gtk-jump-to" special="cancel" - type="object" string="Skip" colspan="1"/> + type="object" string="Cancel" colspan="1"/> <button name="action_next" icon="gtk-go-forward" - type="object" string="Next" colspan="1"/> + type="object" string="Apply" colspan="1"/> </group> </form> </field> @@ -75,10 +74,9 @@ <group colspan="8" col="8"> <separator string="" colspan="8"/> <group colspan="4" width="220"> - <field name="progress" widget="progressbar" nolabel="1" colspan="2"/> </group> <button name="action_skip" icon="gtk-jump-to" special="cancel" - type="object" string="Skip" colspan="1"/> + type="object" string="Cancel" colspan="1"/> <button name="action_next" icon="gtk-go-forward" type="object" string="Install Modules" colspan="1"/> </group> diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py index 3b7e427a923..01d8b745e6f 100644 --- a/openerp/addons/base/res/res_currency.py +++ b/openerp/addons/base/res/res_currency.py @@ -62,17 +62,36 @@ class res_currency(osv.osv): 'active': fields.boolean('Active'), 'company_id':fields.many2one('res.company', 'Company'), 'date': fields.date('Date'), - 'base': fields.boolean('Base') - + 'base': fields.boolean('Base'), + 'position': fields.selection([('after','After Amount'),('before','Before Amount')], 'Symbol position', help="Determines where the currency symbol should be placed after or before the amount.") } _defaults = { 'active': lambda *a: 1, - 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'res.currency', context=c) + 'position' : 'after', } + _sql_constraints = [ + # this constraint does not cover all cases due to SQL NULL handling for company_id, + # so it is complemented with a unique index (see below). The constraint and index + # share the same prefix so that IntegrityError triggered by the index will be caught + # and reported to the user with the constraint's error message. + ('unique_name_company_id', 'unique (name, company_id)', 'The currency code must be unique per company!'), + ] _order = "name" + def init(self, cr): + # CONSTRAINT/UNIQUE INDEX on (name,company_id) + # /!\ The unique constraint 'unique_name_company_id' is not sufficient, because SQL92 + # only support field names in constraint definitions, and we need a function here: + # we need to special-case company_id to treat all NULL company_id as equal, otherwise + # we would allow duplicate "global" currencies (all having company_id == NULL) + cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_currency_unique_name_company_id_idx'""") + if not cr.fetchone(): + cr.execute("""CREATE UNIQUE INDEX res_currency_unique_name_company_id_idx + ON res_currency + (name, (COALESCE(company_id,-1)))""") + def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): - res = super(osv.osv, self).read(cr, user, ids, fields, context, load) + res = super(res_currency, self).read(cr, user, ids, fields, context, load) currency_rate_obj = self.pool.get('res.currency.rate') for r in res: if r.__contains__('rate_ids'): @@ -150,7 +169,7 @@ res_currency() class res_currency_rate_type(osv.osv): _name = "res.currency.rate.type" - _description = "Used to define the type of Currency Rates" + _description = "Currency Rate Type" _columns = { 'name': fields.char('Name', size=64, required=True, translate=True), } diff --git a/openerp/addons/base/res/res_currency_view.xml b/openerp/addons/base/res/res_currency_view.xml index 8d747c882b1..7dab4c051f4 100644 --- a/openerp/addons/base/res/res_currency_view.xml +++ b/openerp/addons/base/res/res_currency_view.xml @@ -2,6 +2,18 @@ <openerp> <data> + <record id="view_currency_search" model="ir.ui.view"> + <field name="name">res.currency.search</field> + <field name="model">res.currency</field> + <field name="type">search</field> + <field name="arch" type="xml"> + <search string="Currencies"> + <field name="name"/> + <field name="active"/> + </search> + </field> + </record> + <record id="view_currency_tree" model="ir.ui.view"> <field name="name">res.currency.tree</field> <field name="model">res.currency</field> @@ -9,12 +21,13 @@ <field name="arch" type="xml"> <tree string="Currencies"> <field name="name"/> - <field name="company_id" select="2" /> + <field name="company_id" groups="base.group_multi_company"/> <field name="rate_ids" invisible="1"/> <field name="date"/> <field name="rate"/> <field name="rounding"/> <field name="accuracy"/> + <field name="position"/> <field name="active"/> </tree> </field> @@ -25,23 +38,30 @@ <field name="type">form</field> <field name="arch" type="xml"> <form string="Currency"> - <group col="6" colspan="6"> - <field name="name" select="1"/> + <group col="6" colspan="4"> + <field name="name"/> <field name="rate"/> - <field name="company_id" select="2" groups="base.group_multi_company" /> - <field name="symbol"/> + <field name="company_id" groups="base.group_multi_company"/> </group> - <group col="2" colspan="2"> - <separator string="Price Accuracy" colspan="2"/> - <field name="rounding"/> - <field name="accuracy"/> - </group> + <group col="6" colspan="4"> + <group col="2" colspan="2"> + <separator string="Price Accuracy" colspan="2"/> + <field name="rounding"/> + <field name="accuracy"/> + </group> + + <group col="2" colspan="2"> + <separator string="Display" colspan="2"/> + <field name="symbol"/> + <field name="position"/> + </group> - <group col="2" colspan="2"> - <separator string="Miscelleanous" colspan="2"/> - <field name="base"/> - <field name="active" select="1"/> + <group col="2" colspan="2"> + <separator string="Miscelleanous" colspan="2"/> + <field name="base"/> + <field name="active" select="1"/> + </group> </group> <field colspan="4" mode="tree,form" name="rate_ids" nolabel="1" attrs="{'readonly':[('base','=',True)]}"> @@ -62,6 +82,7 @@ <field name="res_model">res.currency</field> <field name="view_type">form</field> <field name="view_mode">tree,form</field> + <field name="search_view_id" ref="view_currency_search"/> </record> <menuitem action="action_currency_form" id="menu_action_currency_form" parent="menu_localisation" sequence="3"/> diff --git a/openerp/addons/base/res/res_lang.py b/openerp/addons/base/res/res_lang.py index f6743a54062..50841241f8a 100644 --- a/openerp/addons/base/res/res_lang.py +++ b/openerp/addons/base/res/res_lang.py @@ -194,7 +194,7 @@ class lang(osv.osv): trans_obj.unlink(cr, uid, trans_ids, context=context) return super(lang, self).unlink(cr, uid, ids, context=context) - def format(self, cr, uid, ids, percent, value, grouping=False, monetary=False): + def format(self, cr, uid, ids, percent, value, grouping=False, monetary=False, context=None): """ Format() will return the language-specific output for float values""" if percent[0] != '%': diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 4b8f1279787..9746db40cc1 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -131,12 +131,15 @@ class res_partner(osv.osv): 'customer': fields.boolean('Customer', help="Check this box if the partner is a customer."), 'supplier': fields.boolean('Supplier', help="Check this box if the partner is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."), 'city': fields.related('address', 'city', type='char', string='City'), + 'function': fields.related('address', 'function', type='char', string='function'), + 'subname': fields.related('address', 'name', type='char', string='Contact Name'), 'phone': fields.related('address', 'phone', type='char', string='Phone'), 'mobile': fields.related('address', 'mobile', type='char', string='Mobile'), 'country': fields.related('address', 'country_id', type='many2one', relation='res.country', string='Country'), 'employee': fields.boolean('Employee', help="Check this box if the partner is an Employee."), 'email': fields.related('address', 'email', type='char', size=240, string='E-mail'), 'company_id': fields.many2one('res.company', 'Company', select=1), + 'color': fields.integer('Color Index'), } def _default_category(self, cr, uid, context={}): @@ -150,6 +153,7 @@ class res_partner(osv.osv): 'address': [{'type': 'default'}], 'category_id': _default_category, 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=c), + 'color': 0, } def copy(self, cr, uid, id, default={}, context={}): @@ -225,7 +229,7 @@ class res_partner(osv.osv): def address_get(self, cr, uid, ids, adr_pref=['default']): address_obj = self.pool.get('res.partner.address') - address_ids = address_obj.search(cr, uid, [('partner_id', '=', ids)]) + address_ids = address_obj.search(cr, uid, [('partner_id', 'in', ids)]) address_rec = address_obj.read(cr, uid, address_ids, ['type']) res = list(tuple(addr.values()) for addr in address_rec) adr = dict(res) @@ -300,6 +304,7 @@ class res_partner_address(osv.osv): 'active': fields.boolean('Active', help="Uncheck the active field to hide the contact."), # 'company_id': fields.related('partner_id','company_id',type='many2one',relation='res.company',string='Company', store=True), 'company_id': fields.many2one('res.company', 'Company',select=1), + 'color': fields.integer('Color Index'), } _defaults = { 'active': lambda *a: 1, diff --git a/openerp/addons/base/res/res_partner_demo.xml b/openerp/addons/base/res/res_partner_demo.xml index e8d8d540422..d3c4db106f9 100644 --- a/openerp/addons/base/res/res_partner_demo.xml +++ b/openerp/addons/base/res/res_partner_demo.xml @@ -90,67 +90,88 @@ <record id="res_partner_asus" model="res.partner"> <field name="name">ASUStek</field> - <field name="user_id" ref="user_demo"/> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="supplier">1</field> + <field eval="0" name="customer"/> <field name="address" eval="[]"/> + <field name="website">www.asustek.com</field> </record> <record id="res_partner_agrolait" model="res.partner"> <field name="name">Agrolait</field> - <field eval="[(6, 0, [ref('res_partner_category_8')])]" name="category_id"/> + <field eval="[(6, 0, [ref('base.res_partner_category_0')])]" name="category_id"/> + <field name="user_id" ref="base.user_root"/> <field name="address" eval="[]"/> + <field name="website">www.agrolait.com</field> </record> <record id="res_partner_c2c" model="res.partner"> <field name="name">Camptocamp</field> <field eval="[(6, 0, [ref('res_partner_category_10'), ref('res_partner_category_5')])]" name="category_id"/> <field name="supplier">1</field> + <field name="user_id" ref="base.user_root"/> <field name="address" eval="[]"/> + <field name="website">www.camptocamp.com</field> </record> <record id="res_partner_sednacom" model="res.partner"> - <field name="website">http://www.syleam.fr</field> + <field name="website">www.syleam.fr</field> <field name="name">Syleam</field> <field eval="[(6, 0, [ref('res_partner_category_5')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> </record> <record id="res_partner_thymbra" model="res.partner"> <field name="name">Thymbra</field> + <field name="user_id" ref="base.user_root"/> <field eval="[(6, 0, [ref('res_partner_category_4')])]" name="category_id"/> + <field name="website">www.thymbra.com/</field> </record> <record id="res_partner_desertic_hispafuentes" model="res.partner"> <field name="name">Axelor</field> <field eval="[(6, 0, [ref('res_partner_category_4')])]" name="category_id"/> <field name="supplier">1</field> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> + <field name="website">www.axelor.com/</field> </record> <record id="res_partner_tinyatwork" model="res.partner"> <field name="name">Tiny AT Work</field> + <field name="user_id" ref="base.user_root"/> <field eval="[(6, 0, [ref('res_partner_category_5'), ref('res_partner_category_10')])]" name="category_id"/> + <field name="website">www.tinyatwork.com/</field> </record> <record id="res_partner_2" model="res.partner"> <field name="name">Bank Wealthy and sons</field> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> + <field name="website">www.wealthyandsons.com/</field> </record> <record id="res_partner_3" model="res.partner"> <field name="name">China Export</field> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> + <field name="website">www.chinaexport.com/</field> </record> <record id="res_partner_4" model="res.partner"> <field name="name">Distrib PC</field> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="supplier">1</field> + <field eval="0" name="customer"/> <field name="address" eval="[]"/> + <field name="website">www.distribpc.com/</field> </record> <record id="res_partner_5" model="res.partner"> <field name="name">Ecole de Commerce de Liege</field> <field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> + <field name="website">www.eci-liege.info//</field> </record> <record id="res_partner_6" model="res.partner"> <field name="name">Elec Import</field> <field name="user_id" ref="user_demo"/> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="supplier">1</field> + <field eval="0" name="customer"/> <field name="address" eval="[]"/> </record> <record id="res_partner_maxtor" model="res.partner"> @@ -159,6 +180,7 @@ <field name="user_id" ref="user_demo"/> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="supplier">1</field> + <field eval="0" name="customer"/> <field name="address" eval="[]"/> </record> <record id="res_partner_seagate" model="res.partner"> @@ -177,11 +199,11 @@ <field name="address" eval="[]"/> </record> <record id="res_partner_9" model="res.partner"> - <field name="website">http://balmerinc.com</field> + <field name="website">www.balmerinc.com</field> <field name="name">BalmerInc S.A.</field> <field eval="12000.00" name="credit_limit"/> <field name="ref">or</field> - <field name="user_id" ref="user_demo"/> + <field name="user_id" ref="base.user_root"/> <field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/> <field name="address" eval="[]"/> </record> @@ -190,6 +212,7 @@ <field name="ean13">3020170000003</field> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> </record> <record id="res_partner_11" model="res.partner"> <field name="name">Leclerc</field> @@ -205,6 +228,7 @@ <field name="parent_id" ref="res_partner_10"/> <field eval="[(6, 0, [ref('res_partner_category_11')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> </record> <record id="res_partner_15" model="res.partner"> <field name="name">Magazin BML 1</field> @@ -219,6 +243,8 @@ <field name="name">Université de Liège</field> <field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> + <field name="website">http://www.ulg.ac.be/</field> </record> <!-- @@ -230,16 +256,19 @@ <field model="res.users" name="user_id" search="[('name', '=', u'Thomas Lebrun')]"/> <field name="name">Dubois sprl</field> <field name="address" eval="[]"/> + <field name="website">http://www.dubois.be/</field> </record> <record id="res_partner_ericdubois0" model="res.partner"> <field name="name">Eric Dubois</field> <field name="address" eval="[]"/> + <field name="user_id" ref="user_demo"/> </record> <record id="res_partner_fabiendupont0" model="res.partner"> <field name="name">Fabien Dupont</field> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> </record> <record id="res_partner_lucievonck0" model="res.partner"> @@ -250,32 +279,41 @@ <record id="res_partner_notsotinysarl0" model="res.partner"> <field name="name">NotSoTiny SARL</field> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> + <field name="website">notsotiny.be</field> </record> <record id="res_partner_theshelvehouse0" model="res.partner"> <field name="name">The Shelve House</field> <field eval="[(6,0,[ref('res_partner_category_retailers0')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> </record> <record id="res_partner_vickingdirect0" model="res.partner"> <field name="name">Vicking Direct</field> <field eval="[(6,0,[ref('res_partner_category_miscellaneoussuppliers0')])]" name="category_id"/> <field name="supplier">1</field> + <field name="customer">0</field> <field name="address" eval="[]"/> + <field name="website">vicking-direct.be</field> </record> <record id="res_partner_woodywoodpecker0" model="res.partner"> <field name="name">Wood y Wood Pecker</field> <field eval="[(6,0,[ref('res_partner_category_woodsuppliers0')])]" name="category_id"/> <field name="supplier">1</field> + <field eval="0" name="customer"/> <field name="address" eval="[]"/> + <field name="website">woodywoodpecker.com</field> </record> <record id="res_partner_zerooneinc0" model="res.partner"> <field name="name">ZeroOne Inc</field> <field eval="[(6,0,[ref('res_partner_category_consumers0')])]" name="category_id"/> <field name="address" eval="[]"/> + <field name="user_id" ref="base.user_root"/> + <field name="website">http://www.zerooneinc.com/</field> </record> <!-- @@ -312,6 +350,7 @@ <field name="email">info@axelor.com</field> <field name="phone">+33 1 64 61 04 01</field> <field name="street">12 rue Albert Einstein</field> + <field name="type">default</field> <field name="partner_id" ref="res_partner_desertic_hispafuentes"/> </record> <record id="res_partner_address_3" model="res.partner.address"> @@ -329,6 +368,8 @@ <field name="zip">23410</field> <field model="res.country" name="country_id" search="[('name','=','Taiwan')]"/> <field name="street">31 Hong Kong street</field> + <field name="email">info@asustek.com</field> + <field name="phone">+ 1 64 61 04 01</field> <field name="type">default</field> <field name="partner_id" ref="res_partner_asus"/> </record> @@ -338,6 +379,8 @@ <field name="zip">23540</field> <field model="res.country" name="country_id" search="[('name','=','China')]"/> <field name="street">56 Beijing street</field> + <field name="email">info@maxtor.com</field> + <field name="phone">+ 11 8528 456 789</field> <field name="type">default</field> <field name="partner_id" ref="res_partner_maxtor"/> </record> @@ -348,6 +391,8 @@ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">23 rue du Vieux Bruges</field> <field name="type">default</field> + <field name="email">info@elecimport.com</field> + <field name="phone">+ 32 025 897 456</field> <field name="partner_id" ref="res_partner_6"/> </record> <record id="res_partner_address_7" model="res.partner.address"> @@ -357,6 +402,8 @@ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">42 rue de la Lesse</field> <field name="type">default</field> + <field name="email">info@distribpc.com</field> + <field name="phone">+ 32 081256987</field> <field name="partner_id" ref="res_partner_4"/> </record> <record id="res_partner_address_8" model="res.partner.address"> @@ -366,7 +413,10 @@ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">69 rue de Chimay</field> <field name="type">default</field> + <field name="email">s.l@agrolait.be</field> + <field name="phone">003281588558</field> <field name="partner_id" ref="res_partner_agrolait"/> + <field name="title" ref="base.res_partner_title_madam"/> </record> <record id="res_partner_address_8delivery" model="res.partner.address"> <field name="city">Wavre</field> @@ -375,7 +425,10 @@ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">71 rue de Chimay</field> <field name="type">delivery</field> + <field name="email">p.l@agrolait.be</field> + <field name="phone">003281588557</field> <field name="partner_id" ref="res_partner_agrolait"/> + <field name="title" ref="base.res_partner_title_sir"/> </record> <record id="res_partner_address_8invoice" model="res.partner.address"> <field name="city">Wavre</field> @@ -384,7 +437,10 @@ <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">69 rue de Chimay</field> <field name="type">invoice</field> + <field name="email">serge.l@agrolait.be</field> + <field name="phone">003281588556</field> <field name="partner_id" ref="res_partner_agrolait"/> + <field name="title" ref="base.res_partner_title_sir"/> </record> <record id="res_partner_address_9" model="res.partner.address"> <field name="city">Paris</field> @@ -393,7 +449,10 @@ <field model="res.country" name="country_id" search="[('name','=','France')]"/> <field name="street">1 rue Rockfeller</field> <field name="type">default</field> + <field name="email">a.g@wealthyandsons.com</field> + <field name="phone">003368978776</field> <field name="partner_id" ref="res_partner_2"/> + <field name="title" ref="base.res_partner_title_sir"/> </record> <record id="res_partner_address_11" model="res.partner.address"> <field name="city">Alencon</field> @@ -412,48 +471,84 @@ <field name="zip">6985</field> <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> <field name="street">2 Impasse de la Soif</field> + <field name="email">k.lesbrouffe@eci-liege.info</field> + <field name="phone">+32 421 52571</field> <field name="type">default</field> <field name="partner_id" ref="res_partner_5"/> </record> <record id="res_partner_address_zen" model="res.partner.address"> <field name="city">Shanghai</field> <field name="name">Zen</field> - <field name="zip">4785552</field> + <field name="zip">478552</field> <field model="res.country" name="country_id" search="[('name','=','China')]"/> <field name="street">52 Chop Suey street</field> <field name="type">default</field> + <field name="email">zen@chinaexport.com</field> + <field name="phone">+86-751-64845671</field> <field name="partner_id" ref="res_partner_3"/> </record> <record id="res_partner_address_12" model="res.partner.address"> <field name="type">default</field> - <field name="name">Centrale</field> + <field name="city">Grenoble</field> + <field name="name">Loïc Dupont</field> + <field name="zip">38100</field> + <field model="res.country" name="country_id" search="[('name','=','China')]"/> + <field name="street">Rue Lavoisier 145</field> + <field name="type">default</field> + <field name="email">l.dupont@tecsas.fr</field> + <field name="phone">+33-658-256545</field> <field name="partner_id" ref="res_partner_10"/> </record> <record id="res_partner_address_13" model="res.partner.address"> <field name="type">default</field> - <field name="name">Centrale d'achats 1</field> + <field name="name">Carl François</field> + <field name="city">Bruxelles</field> + <field name="zip">1000</field> + <field model="res.country" name="country_id" search="[('name','=','Belgium')]"/> + <field name="street">89 Chaussée de Waterloo</field> + <field name="email">carl.françois@bml.be</field> + <field name="phone">+32-258-256545</field> <field name="partner_id" ref="res_partner_14"/> </record> <record id="res_partner_address_14" model="res.partner.address"> <field name="type">default</field> - <field name="name">Shop 1</field> + <field name="name">Lucien Ferguson</field> + <field name="street">89 Chaussée de Liège</field> + <field name="city">Namur</field> + <field name="zip">5000</field> + <field name="email">lucien.ferguson@bml.be</field> + <field name="phone">+32-621-568978</field> <field name="partner_id" ref="res_partner_15"/> </record> <record id="res_partner_address_15" model="res.partner.address"> <field name="type">default</field> - <field name="name">Shop 2</field> + <field name="name">Marine Leclerc</field> + <field name="street">rue Grande</field> + <field name="city">Brest</field> + <field name="zip">29200</field> + <field name="email">marine@leclerc.fr</field> + <field name="phone">+33-298.334558</field> <field name="partner_id" ref="res_partner_11"/> </record> <record id="res_partner_address_16" model="res.partner.address"> - <field name="type">default</field> - <field name="name">Shop 3</field> + <field name="type">invoice</field> + <field name="name">Claude Leclerc</field> + <field name="street">rue Grande</field> + <field name="city">Brest</field> + <field name="zip">29200</field> + <field name="email">claude@leclerc.fr</field> + <field name="phone">+33-298.334598</field> <field name="partner_id" ref="res_partner_11"/> </record> <record id="res_partner_address_accent" model="res.partner.address"> <field name="type">default</field> - <field name="city">Liège</field> - <field name="street">Université de Liège</field> + <field name="name">Martine Ohio</field> + <field name="street">Place du 20Août</field> + <field name="city">Liège</field> + <field name="zip">4000</field> + <field name="email">martine.ohio@ulg.ac.be</field> + <field name="phone">+32-45895245</field> <field name="partner_id" ref="res_partner_accent"/> </record> <record id="res_partner_address_Camptocamp" model="res.partner.address"> @@ -472,6 +567,8 @@ <field name="zip">95014</field> <field model="res.country" name="country_id" search="[('name','=','United States')]"/> <field name="street">10200 S. De Anza Blvd</field> + <field name="email">info@seagate.com</field> + <field name="phone">+1 408 256987</field> <field name="type">default</field> <field name="partner_id" ref="res_partner_seagate"/> </record> @@ -552,7 +649,12 @@ <record id="res_partner_address_brussels0" model="res.partner.address"> <field eval="'Brussels'" name="city"/> - <field eval="'Brussels'" name="name"/> + <field eval="'Leen Vandenloep'" name="name"/> + <field eval="'Puurs'" name="city"/> + <field eval="'2870'" name="zip"/> + <field name="country_id" ref="base.be"/> + <field eval="'(+32).70.12.85.00'" name="phone"/> + <field eval="'Schoonmansveld 28'" name="street"/> <field name="partner_id" ref="res_partner_vickingdirect0"/> <field name="country_id" ref="base.be"/> </record> @@ -562,6 +664,7 @@ <field eval="'Kainuu'" name="city"/> <field eval="'Roger Pecker'" name="name"/> <field name="partner_id" ref="res_partner_woodywoodpecker0"/> + <field eval="'(+358).9.589 689'" name="phone"/> <field name="country_id" ref="base.fi"/> </record> @@ -597,10 +700,13 @@ <record id="res_partner_address_ericdubois0" model="res.partner.address"> <field eval="'Mons'" name="city"/> + <field eval="'Eric Dubois'" name="name"/> <field eval="'7000'" name="zip"/> <field name="partner_id" ref="res_partner_ericdubois0"/> <field name="country_id" ref="base.be"/> <field eval="'Chaussée de Binche, 27'" name="street"/> + <field eval="'e.dubois@gmail.com'" name="email"/> + <field eval="'(+32).758 958 789'" name="phone"/> </record> diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index 8b26023701d..5f3ebf73f46 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -105,11 +105,80 @@ </form> </field> </record> + + <record model="ir.ui.view" id="contacts_kanban_view"> + <field name="name">res.partner.address.kanban</field> + <field name="model">res.partner.address</field> + <field name="type">kanban</field> + <field name="arch" type="xml"> + <kanban > + <templates> + <t t-name="kanban-box"> + <t t-set="color" t-value="kanban_color(record.color.raw_value || record.name.raw_value)"/> + <div t-att-class="color + (record.color.raw_value == 1 ? ' oe_kanban_color_alert' : '')"> + <div class="oe_kanban_box oe_kanban_color_border"> + <div class="oe_kanban_box_header oe_kanban_color_bgdark oe_kanban_color_border oe_kanban_draghandle"> + <table class="oe_kanban_table"> + <tr> + <td class="oe_kanban_title1" align="left" valign="middle"> + <field name="name"/> + </td> + <td valign="top" width="22"> + <img t-att-src="kanban_gravatar(record.email.value, 22)" class="oe_kanban_gravatar"/> + </td> + </tr> + </table> + </div> + <div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_box_show_onclick_trigger oe_kanban_color_border"> + <table class="oe_kanban_table"> + <tr> + <td valign="top" width="22" align="left"> + <img src="/web/static/src/img/persons.png"/> + </td> + <td valign="top" align="left"> + <div class="oe_kanban_title2"> + <field name="title"/> + <t t-if="record.title.raw_value && record.function.raw_value">,</t> + <field name="function"/> + </div> + <div class="oe_kanban_title3"> + <field name="partner_id"/> + <t t-if="record.partner_id.raw_value && record.country_id.raw_value">,</t> + <field name="country_id"/> + </div> + <div class="oe_kanban_title3"> + <i><field name="email"/> + <t t-if="record.phone.raw_value && record.email.raw_value">,</t> + <field name="phone"/></i> + </div> + </td> + </tr> + </table> + </div> + <div class="oe_kanban_buttons_set oe_kanban_color_border oe_kanban_color_bglight oe_kanban_box_show_onclick"> + <div class="oe_kanban_left"> + <a string="Edit" icon="gtk-edit" type="edit"/> + <a string="Change Color" icon="color-picker" type="color" name="color"/> + <a title="Mail" t-att-href="'mailto:'+record.email.value" style="text-decoration: none;" > + <img src="/web/static/src/img/icons/terp-mail-message-new.png" border="0" width="16" height="16"/> + </a> + </div> + <br class="oe_kanban_clear"/> + </div> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> + <record id="action_partner_address_form" model="ir.actions.act_window"> <field name="name">Addresses</field> <field name="type">ir.actions.act_window</field> <field name="res_model">res.partner.address</field> <field name="view_type">form</field> + <field name="view_mode">tree,form,kanban</field> <field name="context">{"search_default_customer":1}</field> <field name="search_view_id" ref="view_res_partner_address_filter"/> <field name="help">Customers (also called Partners in other areas of the system) helps you manage your address book of companies whether they are prospects, customers and/or suppliers. The partner form allows you to track and record all the necessary information to interact with your partners from the company address to their contacts as well as pricelists, and much more. If you installed the CRM, with the history tab, you can track all the interactions with a partner such as opportunities, emails, or sales orders issued.</field> @@ -353,12 +422,81 @@ </search> </field> </record> + + <!-- Partner Kanban View --> + <record model="ir.ui.view" id="res_partner_kanban_view"> + <field name="name">RES - PARTNER KANBAN</field> + <field name="model">res.partner</field> + <field name="type">kanban</field> + <field name="arch" type="xml"> + <kanban> + <templates> + <t t-name="kanban-box"> + <t t-set="color" t-value="kanban_color(record.color.raw_value || record.name.raw_value)"/> + <div t-att-class="color + (record.color.raw_value == 1 ? ' oe_kanban_color_alert' : '')"> + <div class="oe_kanban_box oe_kanban_color_border"> + <div class="oe_kanban_box_header oe_kanban_color_bgdark oe_kanban_color_border oe_kanban_draghandle"> + <table class="oe_kanban_table"> + <tr> + <td class="oe_kanban_title1" align="left" valign="middle"> + <field name="name"/> + </td> + <td valign="top" width="22"> + <img t-att-src="kanban_gravatar(record.email.value, 22)" class="oe_kanban_gravatar"/> + </td> + </tr> + </table> + </div> + <div class="oe_kanban_box_content oe_kanban_color_bglight oe_kanban_box_show_onclick_trigger oe_kanban_color_border"> + <table class="oe_kanban_table"> + <tr> + <td valign="top" width="22" align="left"> + <img src="/web/static/src/img/partner.png"/> + </td> + <td valign="top" align="left"> + <div class="oe_kanban_title2"> + <field name="title"/> + <t t-if="record.title.raw_value && record.country.raw_value">,</t> + <field name="country"/> + </div> + <div class="oe_kanban_title3"> + <field name="subname"/> + <t t-if="record.subname.raw_value && record.function.raw_value">,</t> + <field name="function"/> + </div> + <div class="oe_kanban_title3"> + <i><field name="email"/> + <t t-if="record.phone.raw_value && record.email.raw_value">,</t> + <field name="phone"/></i> + </div> + </td> + </tr> + </table> + </div> + <div class="oe_kanban_buttons_set oe_kanban_color_border oe_kanban_color_bglight oe_kanban_box_show_onclick"> + <div class="oe_kanban_left"> + <a string="Edit" icon="gtk-edit" type="edit"/> + <a string="Change Color" icon="color-picker" type="color" name="color"/> + <a title="Mail" t-att-href="'mailto:'+record.email.value" style="text-decoration: none;" > + <img src="/web/static/src/img/icons/terp-mail-message-new.png" border="0" width="16" height="16"/> + </a> + </div> + <br class="oe_kanban_clear"/> + </div> + </div> + </div> + </t> + </templates> + </kanban> + </field> + </record> <record id="action_partner_form" model="ir.actions.act_window"> <field name="name">Customers</field> <field name="type">ir.actions.act_window</field> <field name="res_model">res.partner</field> <field name="view_type">form</field> + <field name="view_mode">kanban</field> <field name="context">{"search_default_customer":1}</field> <field name="search_view_id" ref="view_res_partner_filter"/> <field name="help">A customer is an entity you do business with, like a company or an organization. A customer can have several contacts or addresses which are the people working for this company. You can use the history tab, to follow all transactions related to a customer: sales order, emails, opportunities, claims, etc. If you use the email gateway, the Outlook or the Thunderbird plugin, don't forget to register emails to each contact so that the gateway will automatically attach incoming emails to the right partner.</field> diff --git a/openerp/addons/base/res/res_request_view.xml b/openerp/addons/base/res/res_request_view.xml index 7cec248b990..3bfb0a30ce4 100644 --- a/openerp/addons/base/res/res_request_view.xml +++ b/openerp/addons/base/res/res_request_view.xml @@ -8,7 +8,7 @@ <field name="model">res.request</field> <field name="type">tree</field> <field name="arch" type="xml"> - <tree string="Requests" colors="blue:state in ('waiting');gray:state in ('closed')"> + <tree string="Requests" colors="blue:state == 'waiting';gray:state == 'closed'"> <field name="create_date"/> <field name="act_from"/> <field name="act_to"/> diff --git a/openerp/addons/base/res/res_user.py b/openerp/addons/base/res/res_users.py index f2140b30f1d..f552e8166cd 100644 --- a/openerp/addons/base/res/res_user.py +++ b/openerp/addons/base/res/res_users.py @@ -35,6 +35,7 @@ from osv import fields,osv from osv.orm import browse_record from service import security from tools.translate import _ +import openerp.exceptions class groups(osv.osv): _name = "res.groups" @@ -147,25 +148,16 @@ class users(osv.osv): return cr.fetchall() def send_welcome_email(self, cr, uid, id, context=None): - logger= netsvc.Logger() - user = self.pool.get('res.users').read(cr, uid, id, context=context) - if not user.get('email'): - return False - if not tools.config.get('smtp_server'): - logger.notifyChannel('mails', netsvc.LOG_WARNING, - _('"smtp_server" needs to be set to send mails to users')) - return False - if not tools.config.get('email_from'): - logger.notifyChannel("mails", netsvc.LOG_WARNING, - _('"email_from" needs to be set to send welcome mails ' - 'to users')) - return False + if isinstance(id,list): id = id[0] + user = self.read(cr, uid, id, ['email','login','name', 'user_email'], context=context) + email = user['email'] or user['user_email'] - return tools.email_send(email_from=None, email_to=[user['email']], - subject=self.get_welcome_mail_subject( - cr, uid, context=context), - body=self.get_welcome_mail_body( - cr, uid, context=context) % user) + ir_mail_server = self.pool.get('ir.mail_server') + msg = ir_mail_server.build_email(email_from=None, # take config default + email_to=[email], + subject=self.get_welcome_mail_subject(cr, uid, context=context), + body=(self.get_welcome_mail_body(cr, uid, context=context) % user)) + return ir_mail_server.send_email(cr, uid, msg, context=context) def _set_interface_type(self, cr, uid, ids, name, value, arg, context=None): """Implementation of 'view' function field setter, sets the type of interface of the users. @@ -347,7 +339,7 @@ class users(osv.osv): } # User can write to a few of her own fields (but not her groups for example) - SELF_WRITEABLE_FIELDS = ['menu_tips','view', 'password', 'signature', 'action_id', 'company_id', 'user_email'] + SELF_WRITEABLE_FIELDS = ['menu_tips','view', 'password', 'signature', 'action_id', 'company_id', 'user_email', 'name'] def write(self, cr, uid, ids, values, context=None): if not hasattr(ids, '__iter__'): @@ -446,14 +438,14 @@ class users(osv.osv): if passwd == tools.config['admin_passwd']: return True else: - raise security.ExceptionNoTb('AccessDenied') + raise openerp.exceptions.AccessDenied() def check(self, db, uid, passwd): """Verifies that the given (uid, password) pair is authorized for the database ``db`` and raise an exception if it is not.""" if not passwd: # empty passwords disallowed for obvious security reasons - raise security.ExceptionNoTb('AccessDenied') + raise openerp.exceptions.AccessDenied() if self._uid_cache.get(db, {}).get(uid) == passwd: return cr = pooler.get_db(db).cursor() @@ -462,7 +454,7 @@ class users(osv.osv): (int(uid), passwd, True)) res = cr.fetchone()[0] if not res: - raise security.ExceptionNoTb('AccessDenied') + raise openerp.exceptions.AccessDenied() if self._uid_cache.has_key(db): ulist = self._uid_cache[db] ulist[uid] = passwd @@ -479,7 +471,7 @@ class users(osv.osv): cr.execute('SELECT id FROM res_users WHERE id=%s AND password=%s', (uid, passwd)) res = cr.fetchone() if not res: - raise security.ExceptionNoTb('Bad username or password') + raise openerp.exceptions.AccessDenied() return res[0] finally: cr.close() @@ -490,7 +482,7 @@ class users(osv.osv): password is not used to authenticate requests. :return: True - :raise: security.ExceptionNoTb when old password is wrong + :raise: openerp.exceptions.AccessDenied when old password is wrong :raise: except_osv when new password is not set or empty """ self.check(cr.dbname, uid, old_passwd) @@ -562,7 +554,7 @@ class users_implied(osv.osv): _inherit = 'res.users' def create(self, cr, uid, values, context=None): - groups = values.pop('groups_id') + groups = values.pop('groups_id', None) user_id = super(users_implied, self).create(cr, uid, values, context) if groups: # delegate addition of groups to add implied groups @@ -709,7 +701,7 @@ class users_view(osv.osv): self._process_values_groups(cr, uid, values, context) return super(users_view, self).write(cr, uid, ids, values, context) - def read(self, cr, uid, ids, fields, context=None, load='_classic_read'): + def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): if not fields: group_fields, fields = [], self.fields_get(cr, uid, context).keys() else: diff --git a/openerp/addons/base/res/wizard/__init__.py b/openerp/addons/base/res/wizard/__init__.py index 65869c366c4..23156a24601 100644 --- a/openerp/addons/base/res/wizard/__init__.py +++ b/openerp/addons/base/res/wizard/__init__.py @@ -20,7 +20,7 @@ ############################################################################## import partner_sms_send -import partner_wizard_spam +import partner_wizard_massmail import partner_clear_ids import partner_wizard_ean_check diff --git a/openerp/addons/base/res/wizard/partner_wizard_spam.py b/openerp/addons/base/res/wizard/partner_wizard_massmail.py index 61ddd70aa45..c14101135c4 100644 --- a/openerp/addons/base/res/wizard/partner_wizard_spam.py +++ b/openerp/addons/base/res/wizard/partner_wizard_massmail.py @@ -19,15 +19,16 @@ # ############################################################################## -import netsvc -import tools from osv import fields, osv import re +import logging -class partner_wizard_spam(osv.osv_memory): +_logger = logging.getLogger('mass.mailing') + +class partner_massmail_wizard(osv.osv_memory): """ Mass Mailing """ - _name = "partner.wizard.spam" + _name = "partner.massmail.wizard" _description = "Mass Mailing" _columns = { @@ -37,45 +38,45 @@ class partner_wizard_spam(osv.osv_memory): } def mass_mail_send(self, cr, uid, ids, context): - """ - Send Email + """Send the given mail to all partners whose ids + are present in ``context['active_ids']``, to + all addresses with an email set. - @param cr: the current row, from the database cursor. - @param uid: the current user’s ID for security checks. - @param ids: the ID or list of IDs - @param context: A standard dictionary + :param dict context: ``context['active_ids']`` + should contain the list of + ids of the partners who should + receive the mail. """ - nbr = 0 partner_pool = self.pool.get('res.partner') data = self.browse(cr, uid, ids[0], context=context) event_pool = self.pool.get('res.partner.event') - active_ids = context and context.get('active_ids', []) + assert context['active_model'] == 'res.partner', 'This wizard must be started on a list of Partners' + active_ids = context.get('active_ids', []) partners = partner_pool.browse(cr, uid, active_ids, context) - type_ = 'plain' + subtype = 'plain' if re.search('(<(pre)|[pubi].*>)', data.text): - type_ = 'html' + subtype = 'html' + ir_mail_server = self.pool.get('ir.mail_server') + emails_seen = set() for partner in partners: for adr in partner.address: - if adr.email: - name = adr.name or partner.name - to = '"%s" <%s>' % (name, adr.email) - #TODO: add some tests to check for invalid email addresses - #CHECKME: maybe we should use res.partner/email_send - tools.email_send(data.email_from, - [to], - data.subject, - data.text, - subtype=type_, - openobject_id="res.partner-%s"%partner.id) - nbr += 1 + if adr.email and not adr.email in emails_seen: + try: + emails_seen.add(adr.email) + name = adr.name or partner.name + to = '"%s" <%s>' % (name, adr.email) + msg = ir_mail_server.build_email(data.email_from, [to], data.subject, data.text, subtype=subtype) + if ir_mail_server.send_email(cr, uid, msg): + nbr += 1 + except Exception: + #ignore failed deliveries, will be logged anyway + pass event_pool.create(cr, uid, {'name': 'Email(s) sent through mass mailing', 'partner_id': partner.id, 'description': data.text }) - #TODO: log number of message sent + _logger.info('Mass-mailing wizard sent %s emails', nbr) return {'email_sent': nbr} -partner_wizard_spam() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/res/wizard/partner_wizard_spam_view.xml b/openerp/addons/base/res/wizard/partner_wizard_massmail_view.xml index 0de26400f90..864550b4396 100644 --- a/openerp/addons/base/res/wizard/partner_wizard_spam_view.xml +++ b/openerp/addons/base/res/wizard/partner_wizard_massmail_view.xml @@ -4,7 +4,7 @@ <record id="view_partner_mass_mail" model="ir.ui.view"> <field name="name">Mass Mailing</field> - <field name="model">partner.wizard.spam</field> + <field name="model">partner.massmail.wizard</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="Mass Mailing" col="4"> @@ -24,7 +24,7 @@ </record> <act_window name="Mass Mailing" - res_model="partner.wizard.spam" + res_model="partner.massmail.wizard" src_model="res.partner" view_mode="form" target="new" diff --git a/openerp/addons/base/rng/view.rng b/openerp/addons/base/rng/view.rng index 3cad1a9a369..7c13afd8bfc 100644 --- a/openerp/addons/base/rng/view.rng +++ b/openerp/addons/base/rng/view.rng @@ -113,6 +113,11 @@ <rng:define name="kanban"> <rng:element name="kanban"> + <rng:optional> + <!-- group-by field to apply in the kanban view when no other + grouping is selected in the search view --> + <rng:attribute name="default_group_by" /> + </rng:optional> <rng:zeroOrMore> <rng:ref name="field"/> </rng:zeroOrMore> @@ -207,6 +212,7 @@ <rng:optional><rng:attribute name="help"/></rng:optional> <rng:optional><rng:attribute name="width"/></rng:optional> <rng:optional><rng:attribute name="wrap"/></rng:optional> + <rng:optional><rng:attribute name="name"/></rng:optional> <rng:zeroOrMore> <rng:choice> <rng:ref name="notebook"/> @@ -470,6 +476,8 @@ <rng:optional><rng:attribute name="selection"/></rng:optional> <rng:optional><rng:attribute name="default_focus"/></rng:optional> <rng:optional><rng:attribute name="filters"/></rng:optional> + <rng:optional><rng:attribute name="statusbar_visible"/></rng:optional> + <rng:optional><rng:attribute name="statusbar_colors"/></rng:optional> <rng:zeroOrMore> <rng:choice> <rng:ref name="diagram"/> diff --git a/openerp/addons/base/security/base_security.xml b/openerp/addons/base/security/base_security.xml index fe3a10fdaed..65696210687 100644 --- a/openerp/addons/base/security/base_security.xml +++ b/openerp/addons/base/security/base_security.xml @@ -42,28 +42,32 @@ <field name="groups_id" eval="[(6,0, [ref('group_system'), ref('group_erp_manager')])]"/> </record> - <record model="ir.rule" id="res_widget_user_rule"> - <field name="name">res.widget.user rule</field> - <field name="model_id" ref="model_res_widget_user"/> - <field name="global" eval="True"/> - <field name="domain_force">['|', ('user_id','=',user.id),('user_id','=',False)]</field> - </record> + </data> - <record model="ir.rule" id="res_partner_rule"> - <field name="name">res.partner company</field> - <field name="model_id" ref="model_res_partner"/> - <field name="global" eval="True"/> - <!-- Show partners from ancestors and descendants companies (or company-less), this is usually a better - default for multicompany setups. --> - <field name="domain_force">['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field> - </record> + <data noupdate="1"> - <record model="ir.rule" id="multi_company_default_rule"> - <field name="name">Multi_company_default company</field> - <field name="model_id" ref="model_multi_company_default"/> - <field name="global" eval="True"/> - <field name="domain_force">[('company_id','child_of',[user.company_id.id])]</field> - </record> + <record model="ir.rule" id="res_widget_user_rule"> + <field name="name">res.widget.user rule</field> + <field name="model_id" ref="model_res_widget_user"/> + <field name="global" eval="True"/> + <field name="domain_force">['|', ('user_id','=',user.id),('user_id','=',False)]</field> + </record> + + <record model="ir.rule" id="res_partner_rule"> + <field name="name">res.partner company</field> + <field name="model_id" ref="model_res_partner"/> + <field name="global" eval="True"/> + <!-- Show partners from ancestors and descendants companies (or company-less), this is usually a better + default for multicompany setups. --> + <field name="domain_force">['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field> + </record> + + <record model="ir.rule" id="multi_company_default_rule"> + <field name="name">Multi_company_default company</field> + <field name="model_id" ref="model_multi_company_default"/> + <field name="global" eval="True"/> + <field name="domain_force">[('company_id','child_of',[user.company_id.id])]</field> + </record> <record model="ir.rule" id="ir_values_default_rule"> <field name="name">Defaults: alter personal values only</field> diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 6460c06d1f7..7bb6e63f049 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -47,6 +47,7 @@ "access_res_country_state_group_user","res_country_state group_user","model_res_country_state","group_partner_manager",1,1,1,1 "access_res_currency_group_all","res_currency group_all","model_res_currency",,1,0,0,0 "access_res_currency_rate_group_all","res_currency_rate group_all","model_res_currency_rate",,1,0,0,0 +"access_res_currency_rate_type_group_all","res_currency_rate_type group_all","model_res_currency_rate_type",,1,0,0,0 "access_res_currency_group_system","res_currency group_system","model_res_currency","group_system",1,1,1,1 "access_res_currency_rate_group_system","res_currency_rate group_system","model_res_currency_rate","group_system",1,1,1,1 "access_res_groups_group_erp_manager","res_groups group_erp_manager","model_res_groups","group_erp_manager",1,1,1,1 @@ -122,4 +123,6 @@ "access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0 "access_res_log_all","res.log","model_res_log",,1,1,1,1 "access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0 +"access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0 "access_ir_actions_todo_category","ir_actions_todo_category","model_ir_actions_todo_category","group_system",1,1,1,1 +"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0 diff --git a/openerp/addons/base/test/__init__.py b/openerp/addons/base/test/__init__.py new file mode 100644 index 00000000000..c0cc8f7cb78 --- /dev/null +++ b/openerp/addons/base/test/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011-TODAY OpenERP S.A. <http://www.openerp.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +# Useful for manual testing of cron jobs scheduling. +# This must be (un)commented with the corresponding yml file +# in ../__openerp__.py. +# import test_ir_cron + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/test/base_test.yml b/openerp/addons/base/test/base_test.yml index 5a17ca108c3..6ea578a8659 100644 --- a/openerp/addons/base/test/base_test.yml +++ b/openerp/addons/base/test/base_test.yml @@ -144,45 +144,3 @@ !python {model: res.partner.category}: | self.pool._init = True -- - "OSV Memory: Verify that osv_memory properly handles large data allocation" -- - 1. No "count-based" auto-vaccuum when max_count is disabled -- - !python {model: base.language.export}: | - # setup special limits for the test, these will be reset at next pool reload anyway - self._max_count = None - num_recs = 250 - for i in xrange(num_recs): - self.create(cr, uid, {'format':'po'}) - assert (len(self.datas) >= num_recs), "OSV Memory must not auto-vaccum records from the current transaction if max_count is not set" -- - 2. Auto-vaccuum should be enabled when max_count is set -- - !python {model: base.language.export}: | - # setup special limits for the test, these will be reset at next pool reload anyway - self._max_count = 100 - num_recs = 219 - for i in xrange(num_recs): - self.create(cr, uid, {'name': i, 'format':'po'}) - assert (self._max_count <= len(self.datas) < self._max_count + self._check_time), "OSV Memory must auto-expire records when max_count is reached" - for k,v in self.datas.iteritems(): - assert (int(v['name']) >= (num_recs - (self._max_count + self._check_time))), "OSV Memory must auto-expire records based on age" -- - 3. Auto-vaccuum should be based on age only when max_count is not set -- - !python {model: base.language.export}: | - # setup special limits for the test, these will be reset at next pool reload anyway - self._max_count = None - self._max_hours = 0.01 #36 seconds - num_recs = 200 - for i in xrange(num_recs): - self.create(cr, uid, {'format':'po'}) - assert (len(self.datas) >= num_recs), "OSV Memory must not auto-expire records from the current transaction" - - # expire all records - for k,v in self.datas.iteritems(): - v['internal.date_access'] = 0 - self.vaccum(cr, 1, force=True) - - assert (len(self.datas) == 0), "OSV Memory must expire old records after vaccuum" diff --git a/openerp/addons/base/test/test_ir_cron.py b/openerp/addons/base/test/test_ir_cron.py new file mode 100644 index 00000000000..6ef79ac3a78 --- /dev/null +++ b/openerp/addons/base/test/test_ir_cron.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011-TODAY OpenERP S.A. <http://www.openerp.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import time +from datetime import datetime +from dateutil.relativedelta import relativedelta + +import openerp + +JOB = { + 'function': u'_0_seconds', + 'interval_type': u'minutes', + 'user_id': 1, + 'name': u'test', + 'args': False, + 'numbercall': 1, + 'nextcall': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), + 'priority': 5, + 'doall': True, + 'active': True, + 'interval_number': 1, + 'model': u'ir.cron' +} + +class test_ir_cron(openerp.osv.osv.osv): + """ Add a few handy methods to test cron jobs scheduling. """ + _inherit = "ir.cron" + + def _0_seconds(a, b, c): + print ">>> _0_seconds" + + def _20_seconds(self, cr, uid): + print ">>> in _20_seconds" + time.sleep(20) + print ">>> out _20_seconds" + + def _80_seconds(self, cr, uid): + print ">>> in _80_seconds" + time.sleep(80) + print ">>> out _80_seconds" + + def test_0(self, cr, uid): + now = datetime.now() + t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') + t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') + t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') + self.create(cr, uid, dict(JOB, name='test_0 _20_seconds A', function='_20_seconds', nextcall=t1)) + self.create(cr, uid, dict(JOB, name='test_0 _20_seconds B', function='_20_seconds', nextcall=t2)) + self.create(cr, uid, dict(JOB, name='test_0 _20_seconds C', function='_20_seconds', nextcall=t3)) + + def test_1(self, cr, uid): + now = datetime.now() + t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') + self.create(cr, uid, dict(JOB, name='test_1 _20_seconds * 3', function='_20_seconds', nextcall=t1, numbercall=3)) + + def test_2(self, cr, uid): + now = datetime.now() + t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') + self.create(cr, uid, dict(JOB, name='test_2 _80_seconds * 2', function='_80_seconds', nextcall=t1, numbercall=2)) + + def test_3(self, cr, uid): + now = datetime.now() + t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') + t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') + t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') + self.create(cr, uid, dict(JOB, name='test_3 _80_seconds A', function='_80_seconds', nextcall=t1)) + self.create(cr, uid, dict(JOB, name='test_3 _20_seconds B', function='_20_seconds', nextcall=t2)) + self.create(cr, uid, dict(JOB, name='test_3 _20_seconds C', function='_20_seconds', nextcall=t3)) + + # This test assumes 4 cron threads. + def test_00(self, cr, uid): + self.test_00_set = set() + now = datetime.now() + t1 = (now + relativedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') + t2 = (now + relativedelta(minutes=1, seconds=5)).strftime('%Y-%m-%d %H:%M:%S') + t3 = (now + relativedelta(minutes=1, seconds=10)).strftime('%Y-%m-%d %H:%M:%S') + self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_A', function='_20_seconds_A', nextcall=t1)) + self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_B', function='_20_seconds_B', nextcall=t2)) + self.create(cr, uid, dict(JOB, name='test_00 _20_seconds_C', function='_20_seconds_C', nextcall=t3)) + + def _expect(self, cr, uid, to_add, to_sleep, to_expect_in, to_expect_out): + assert self.test_00_set == to_expect_in + self.test_00_set.add(to_add) + time.sleep(to_sleep) + self.test_00_set.discard(to_add) + assert self.test_00_set == to_expect_out + + def _20_seconds_A(self, cr, uid): + self._expect(cr, uid, 'A', 20, set(), set(['B', 'C'])) + + def _20_seconds_B(self, cr, uid): + self._expect(cr, uid, 'B', 20, set('A'), set('C')) + + def _20_seconds_C(self, cr, uid): + self._expect(cr, uid, 'C', 20, set(['A', 'B']), set()) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/openerp/addons/base/test/test_ir_cron.yml b/openerp/addons/base/test/test_ir_cron.yml new file mode 100644 index 00000000000..16d648e1c30 --- /dev/null +++ b/openerp/addons/base/test/test_ir_cron.yml @@ -0,0 +1,61 @@ +- + Test the cron jobs scheduling. +- + Disable the existing cron jobs if any during the tests. +- + !python {model: ir.cron }: | + # For this test to work, as it involves multiple database cursors, + # we have to commit changes. But YAML tests must be rollbacked, so + # the final database state is left untouched. So we have to be a bit + # ugly here: use our own cursor, commit, and clean after ourselves. + # We also pass around some ids using setattr/delattr, and we have to + # rollback the previous tests otherwise we won't be able to touch the + # db. + # Well, this should probably be a standalone, or regular unit test, + # instead of using the YAML infrastructure. + cr.rollback() + our_cr = self.pool.db.cursor() + try: + ids = self.search(our_cr, uid, [], {}) + setattr(self, 'saved_ids', ids) + self.write(our_cr, uid, ids, {'active': False}, {}) + our_cr.commit() + finally: + our_cr.close() +- + Three concurrent jobs started with a slight time gap. Assume 4 cron threads. + This will take about 2 minutes. +- + !python {model: ir.cron }: | + # Pretend initialization is already done. We the use a try/finally + # to reset _init correctly. + self.pool._init = False + our_cr = self.pool.db.cursor() + try: + self.test_00(our_cr, uid) # this will commit using the passed cursor + import openerp.cron + openerp.cron._thread_slots = 4 + # Wake up this db as soon as the master cron thread starts. + openerp.cron.schedule_wakeup(1, self.pool.db.dbname) + # Pretend to be the master thread, for 4 iterations. + openerp.cron.runner_body() + openerp.cron.runner_body() + openerp.cron.runner_body() + openerp.cron.runner_body() + finally: + self.pool._init = True + our_cr.close() +- + Clean after ourselves. +- + !python {model: ir.cron }: | + our_cr = self.pool.db.cursor() + try: + ids = [x for x in self.search(our_cr, uid, ['|', ('active', '=', True), ('active', '=', False)], {}) if x not in self.saved_ids] + self.unlink(our_cr, uid, ids, {}) + ids = self.saved_ids + delattr(self, 'saved_ids') + self.write(our_cr, uid, ids, {'active': True}, {}) + our_cr.commit() + finally: + our_cr.close() diff --git a/openerp/addons/base/test/test_osv_expression.yml b/openerp/addons/base/test/test_osv_expression.yml index 3a5e41dacc7..43fea5c16cf 100644 --- a/openerp/addons/base/test/test_osv_expression.yml +++ b/openerp/addons/base/test/test_osv_expression.yml @@ -178,6 +178,251 @@ res_ids.sort() assert res_ids == all_ids, "Searching against empty set failed, returns %r" % res_ids - + Test the '(not) like/in' behavior. res.partner and its parent_id column are used because + parent_id is a many2one, allowing to test the Null value, and there are actually some + null and non-null values in the demo data. +- + !python {model: res.partner }: | + partner_ids = self.search(cr, uid, []) + partner_ids.sort() + max_partner_id = max(partner_ids) + + # Grab test sample data without using a normal + # search domain, because we want to test these later, + # so we can't rely on them! + partners = self.browse(cr, uid, partner_ids) + with_parent = [] + without_parent = [] + with_website = [] + for x in partners: + if x.parent_id: + with_parent.append(x.id) + else: + without_parent.append(x.id) + if x.website: + with_website.append(x.id) + with_parent.sort() + without_parent.sort() + with_website.sort() + + # We treat null values differently than in SQL. For instance in SQL: + # SELECT id FROM res_partner WHERE parent_id NOT IN (0) + # will return only the records with non-null parent_id. + # SELECT id FROM res_partner WHERE parent_id IN (0) + # will return expectedly nothing (our ids always begin at 1). + # This means the union of those two results will give only some + # records, but not all present in database. + # + # When using domains and the ORM's search method, we think it is + # more intuitive that the union returns all the records, and that + # a domain like ('parent_id', 'not in', [0]) will return all + # the records. For instance, if you perform a search for the companies + # that don't have OpenERP has a parent company, you expect to find, + # among others, the companies that don't have parent company. + # + # ('parent_id', 'not in', [0]) must give the same result than + # ('parent_id', 'not in', []), i.e. a empty set or a set with non- + # existing values be treated similarly if we simply check that some + # existing value belongs to them. + + res_0 = self.search(cr, uid, [('parent_id', 'not like', 'probably_unexisting_name')]) # get all rows, included null parent_id + res_0.sort() + res_1 = self.search(cr, uid, [('parent_id', 'not in', [max_partner_id + 1])]) # get all rows, included null parent_id + res_1.sort() + res_2 = self.search(cr, uid, [('parent_id', 'not in', False)]) # get rows with not null parent_id, deprecated syntax + res_2.sort() + res_3 = self.search(cr, uid, [('parent_id', 'not in', [])]) # get all rows, included null parent_id + res_3.sort() + res_4 = self.search(cr, uid, [('parent_id', 'not in', [False])]) # get rows with not null parent_id + res_4.sort() + assert res_0 == partner_ids + assert res_1 == partner_ids + assert res_2 == with_parent + assert res_3 == partner_ids + assert res_4 == with_parent + # The results of these queries, when combined with queries 0..4 must + # give the whole set of ids. + res_5 = self.search(cr, uid, [('parent_id', 'like', 'probably_unexisting_name')]) + res_5.sort() + res_6 = self.search(cr, uid, [('parent_id', 'in', [max_partner_id + 1])]) + res_6.sort() + res_7 = self.search(cr, uid, [('parent_id', 'in', False)]) + res_7.sort() + res_8 = self.search(cr, uid, [('parent_id', 'in', [])]) + res_8.sort() + res_9 = self.search(cr, uid, [('parent_id', 'in', [False])]) + res_9.sort() + assert res_5 == [] + assert res_6 == [] + assert res_7 == without_parent + assert res_8 == [] + assert res_9 == without_parent + # These queries must return exactly the results than the queries 0..4, + # i.e. not ... in ... must be the same as ... not in ... . + res_10 = self.search(cr, uid, ['!', ('parent_id', 'like', 'probably_unexisting_name')]) + res_10.sort() + res_11 = self.search(cr, uid, ['!', ('parent_id', 'in', [max_partner_id + 1])]) + res_11.sort() + res_12 = self.search(cr, uid, ['!', ('parent_id', 'in', False)]) + res_12.sort() + res_13 = self.search(cr, uid, ['!', ('parent_id', 'in', [])]) + res_13.sort() + res_14 = self.search(cr, uid, ['!', ('parent_id', 'in', [False])]) + res_14.sort() + assert res_0 == res_10 + assert res_1 == res_11 + assert res_2 == res_12 + assert res_3 == res_13 + assert res_4 == res_14 + + # Testing many2one field is not enough, a regular char field is tested + # with in [] and must not return any result. + res_15 = self.search(cr, uid, [('website', 'in', [])]) + assert res_15 == [] + # not in [] must return everything. + res_16 = self.search(cr, uid, [('website', 'not in', [])]) + res_16.sort() + assert res_16 == partner_ids + + res_17 = self.search(cr, uid, [('website', 'not in', False)]) + res_17.sort() + assert res_17 == with_website +- + Property of the query (one2many not in False). +- + !python {model: res.currency }: | + ids = self.search(cr, uid, []) + referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)]) + companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'not in', False)])) + assert referenced_companies == companies +- + Property of the query (one2many in False). +- + !python {model: res.currency }: | + ids = self.search(cr, uid, []) + referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)]) + unreferenced_companies = set(self.pool.get('res.company').search(cr, uid, [])).difference(referenced_companies) + companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'in', False)])) + assert unreferenced_companies == companies +- + Equivalent queries. +- + !python {model: res.currency }: | + max_currency_id = max(self.search(cr, uid, [])) + res_0 = self.search(cr, uid, []) + res_1 = self.search(cr, uid, [('name', 'not like', 'probably_unexisting_name')]) + res_2 = self.search(cr, uid, [('id', 'not in', [max_currency_id + 1003])]) + res_3 = self.search(cr, uid, [('id', 'not in', [])]) + res_4 = self.search(cr, uid, [('id', 'not in', False)]) + res_0.sort() + res_1.sort() + res_2.sort() + res_3.sort() + res_4.sort() + assert res_0 == res_1 + assert res_0 == res_2 + assert res_0 == res_3 + assert res_0 == res_4 +- + Equivalent queries, integer and string. +- + !python {model: res.partner }: | + all_ids = self.search(cr, uid, []) + if len(all_ids) > 1: + one = all_ids[0] + record = self.browse(cr, uid, one) + others = all_ids[1:] + res_1 = self.search(cr, uid, [('id', '=', one)]) + # self.search(cr, uid, [('id', '!=', others)]) # not permitted + res_2 = self.search(cr, uid, [('id', 'not in', others)]) + res_3 = self.search(cr, uid, ['!', ('id', '!=', one)]) + res_4 = self.search(cr, uid, ['!', ('id', 'in', others)]) + # res_5 = self.search(cr, uid, [('id', 'in', one)]) # TODO make it permitted, just like for child_of + res_6 = self.search(cr, uid, [('id', 'in', [one])]) + res_7 = self.search(cr, uid, [('name', '=', record.name)]) + res_8 = self.search(cr, uid, [('name', 'in', [record.name])]) + # res_9 = self.search(cr, uid, [('name', 'in', record.name)]) # TODO + assert [one] == res_1 + assert [one] == res_2 + assert [one] == res_3 + assert [one] == res_4 + #assert [one] == res_5 + assert [one] == res_6 + assert [one] == res_7 +- + Need a company with a parent_id. +- + !record {model: res.company, id: ymltest_company3}: + name: Acme 3 +- + Need a company with a parent_id. +- + !record {model: res.company, id: ymltest_company4}: + name: Acme 4 + parent_id: ymltest_company3 +- + Equivalent queries, one2many. +- + !python {model: res.company }: | + # Search the company via its one2many (the one2many must point back at the company). + company = self.browse(cr, uid, ref('ymltest_company3')) + max_currency_id = max(self.pool.get('res.currency').search(cr, uid, [])) + currency_ids1 = self.pool.get('res.currency').search(cr, uid, [('name', 'not like', 'probably_unexisting_name')]) + currency_ids2 = self.pool.get('res.currency').search(cr, uid, [('id', 'not in', [max_currency_id + 1003])]) + currency_ids3 = self.pool.get('res.currency').search(cr, uid, [('id', 'not in', [])]) + assert currency_ids1 == currency_ids2 == currency_ids3, 'All 3 results should have be the same: all currencies' + default_company = self.browse(cr, uid, 1) + # one2many towards same model + res_1 = self.search(cr, uid, [('child_ids', 'in', [x.id for x in company.child_ids])]) # any company having a child of company3 as child + res_2 = self.search(cr, uid, [('child_ids', 'in', [company.child_ids[0].id])]) # any company having the first child of company3 as child + # one2many towards another model + res_3 = self.search(cr, uid, [('currency_ids', 'in', [x.id for x in default_company.currency_ids])]) # companies having a currency of main company + res_4 = self.search(cr, uid, [('currency_ids', 'in', [default_company.currency_ids[0].id])]) # companies having first currency of main company + res_5 = self.search(cr, uid, [('currency_ids', 'in', default_company.currency_ids[0].id)]) # companies having first currency of main company + # res_6 = self.search(cr, uid, [('currency_ids', 'in', [default_company.currency_ids[0].name])]) # TODO + res_7 = self.search(cr, uid, [('currency_ids', '=', default_company.currency_ids[0].name)]) + res_8 = self.search(cr, uid, [('currency_ids', 'like', default_company.currency_ids[0].name)]) + res_9 = self.search(cr, uid, [('currency_ids', 'like', 'probably_unexisting_name')]) + # self.search(cr, uid, [('currency_ids', 'unexisting_op', 'probably_unexisting_name')]) # TODO expected exception + assert res_1 == [ref('ymltest_company3')] + assert res_2 == [ref('ymltest_company3')] + assert res_3 == [1] + assert res_4 == [1] + assert res_5 == [1] + assert res_7 == [1] + assert res_8 == [1] + assert res_9 == [] + + # get the companies referenced by some currency (this is normally the main company) + res_10 = self.search(cr, uid, [('currency_ids', 'not like', 'probably_unexisting_name')]) + res_11 = self.search(cr, uid, [('currency_ids', 'not in', [max_currency_id + 1])]) + res_12 = self.search(cr, uid, [('currency_ids', 'not in', False)]) + res_13 = self.search(cr, uid, [('currency_ids', 'not in', [])]) + res_10.sort() + res_11.sort() + res_12.sort() + res_13.sort() + assert res_10 == res_11 + assert res_10 == res_12 + assert res_10 == res_13 + + # child_of x returns x and its children (direct or not). + company = self.browse(cr, uid, ref('ymltest_company3')) + expected = [ref('ymltest_company3'), ref('ymltest_company4')] + expected.sort() + res_1 = self.search(cr, uid, [('id', 'child_of', [ref('ymltest_company3')])]) + res_1.sort() + res_2 = self.search(cr, uid, [('id', 'child_of', ref('ymltest_company3'))]) + res_2.sort() + res_3 = self.search(cr, uid, [('id', 'child_of', [company.name])]) + res_3.sort() + res_4 = self.search(cr, uid, [('id', 'child_of', company.name)]) + res_4.sort() + assert res_1 == expected + assert res_2 == expected + assert res_3 == expected + assert res_4 == expected +- Verify that normalize_domain() works. - !python {model: res.partner}: | @@ -187,6 +432,72 @@ domain = [('x','in',['y','z']),('a.v','=','e'),'|','|',('a','=','b'),'!',('c','>','d'),('e','!=','f'),('g','=','h')] norm_domain = ['&','&','&'] + domain assert norm_domain == expression.normalize(domain), "Non-normalized domains should be properly normalized" +- + Unaccent. Create a company with an accent in its name. +- + !record {model: res.company, id: ymltest_unaccent_company}: + name: Hélène +- + Test the unaccent-enabled 'ilike'. +- + !python {model: res.company}: | + if self.pool.has_unaccent: + ids = self.search(cr, uid, [('name','ilike','Helene')], {}) + assert ids == [ref('ymltest_unaccent_company')] + ids = self.search(cr, uid, [('name','ilike','hélène')], {}) + assert ids == [ref('ymltest_unaccent_company')] + ids = self.search(cr, uid, [('name','not ilike','Helene')], {}) + assert ref('ymltest_unaccent_company') not in ids + ids = self.search(cr, uid, [('name','not ilike','hélène')], {}) + assert ref('ymltest_unaccent_company') not in ids +- + Check that =like/=ilike expressions (no wildcard variants of like/ilike) are working on an untranslated field. +- + !python {model: res.partner }: | + all_ids = self.search(cr, uid, [('name', '=like', 'A_e_or')]) + assert len(all_ids) == 1, "Must match one partner (Axelor), got %r"%all_ids + all_ids = self.search(cr, uid, [('name', '=ilike', 'm_____')]) + assert len(all_ids) == 1, "Must match *only* one partner (Maxtor), got %r"%all_ids +- + Check that =like/=ilike expressions (no wildcard variants of like/ilike) are working on translated field. +- + !python {model: res.country }: | + all_ids = self.search(cr, uid, [('name', '=like', 'Ind__')]) + assert len(all_ids) == 1, "Must match India only, got %r"%all_ids + all_ids = self.search(cr, uid, [('name', '=ilike', 'z%')]) + assert len(all_ids) == 3, "Must match only countries with names starting with Z (currently 3), got %r"%all_ids +- + Use the create_date column on res.country (which doesn't declare it in _columns). +- + !python {model: res.country }: | + ids = self.search(cr, uid, [('create_date', '<', '2001-01-01 12:00:00')]) + + +- + Verify that invalid expressions are refused, even for magic fields +- + !python {model: res.country }: | + try: + self.search(cr, uid, [('does_not_exist', '=', 'foo')]) + raise AssertionError('Invalid fields should not be accepted') + except ValueError: + pass + try: + self.search(cr, uid, [('create_date', '>>', 'foo')]) + raise AssertionError('Invalid operators should not be accepted') + except ValueError: + pass + import psycopg2 + try: + cr._default_log_exceptions = False + cr.execute('SAVEPOINT expression_failure_test') + self.search(cr, uid, [('create_date', '=', "1970-01-01'); --")]) + # if the above search gives no error, the operand was not escaped! + cr.execute('RELEASE SAVEPOINT expression_failure_test') + raise AssertionError('Operands should always be SQL escaped') + except psycopg2.DataError: + # Should give: 'DataError: invalid input syntax for type timestamp' or similar + cr.execute('ROLLBACK TO SAVEPOINT expression_failure_test') diff --git a/openerp/conf/__init__.py b/openerp/conf/__init__.py index 7de8070f9e2..c89ddf44734 100644 --- a/openerp/conf/__init__.py +++ b/openerp/conf/__init__.py @@ -28,8 +28,25 @@ parsing, configuration file loading and saving, ...) in this module and provide real Python variables, e.g. addons_paths is really a list of paths. +To initialize properly this module, openerp.tools.config.parse_config() +must be used. + """ import deprecation +# Maximum number of threads processing concurrently cron jobs. +max_cron_threads = 4 # Actually the default value here is meaningless, + # look at tools.config for the default value. + +# Paths to search for OpenERP addons. +addons_paths = [] + +# List of server-wide modules to load. Those modules are supposed to provide +# features not necessarily tied to a particular database. This is in contrast +# to modules that are always bound to a specific database when they are +# installed (i.e. the majority of OpenERP addons). This is set with the --load +# command-line option. +server_wide_modules = [] + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/cron.py b/openerp/cron.py new file mode 100644 index 00000000000..d24300b7f43 --- /dev/null +++ b/openerp/cron.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2011 OpenERP SA (<http://www.openerp.com>) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +""" Cron jobs scheduling + +Cron jobs are defined in the ir_cron table/model. This module deals with all +cron jobs, for all databases of a single OpenERP server instance. + +It defines a single master thread that will spawn (a bounded number of) +threads to process individual cron jobs. + +The thread runs forever, checking every 60 seconds for new +'database wake-ups'. It maintains a heapq of database wake-ups. At each +wake-up, it will call ir_cron._run_jobs_multithread() for the given database. _run_jobs_multithread +will check the jobs defined in the ir_cron table and spawn accordingly threads +to process them. + +This module's behavior depends on the following configuration variable: +openerp.conf.max_cron_threads. + +""" + +import heapq +import logging +import threading +import time + +import openerp +import tools + +# Heapq of database wake-ups. Note that 'database wake-up' meaning is in +# the context of the cron management. This is not originally about loading +# a database, although having the database name in the queue will +# cause it to be loaded when the schedule time is reached, even if it was +# unloaded in the mean time. Normally a database's wake-up is cancelled by +# the RegistryManager when the database is unloaded - so this should not +# cause it to be reloaded. +# +# TODO: perhaps in the future we could consider a flag on ir.cron jobs +# that would cause database wake-up even if the database has not been +# loaded yet or was already unloaded (e.g. 'force_db_wakeup' or something) +# +# Each element is a triple (timestamp, database-name, boolean). The boolean +# specifies if the wake-up is canceled (so a wake-up can be canceled without +# relying on the heapq implementation detail; no need to remove the job from +# the heapq). +_wakeups = [] + +# Mapping of database names to the wake-up defined in the heapq, +# so that we can cancel the wake-up without messing with the heapq +# invariant: lookup the wake-up by database-name, then set +# its third element to True. +_wakeup_by_db = {} + +# Re-entrant lock to protect the above _wakeups and _wakeup_by_db variables. +# We could use a simple (non-reentrant) lock if the runner function below +# was more fine-grained, but we are fine with the loop owning the lock +# while spawning a few threads. +_wakeups_lock = threading.RLock() + +# Maximum number of threads allowed to process cron jobs concurrently. This +# variable is set by start_master_thread using openerp.conf.max_cron_threads. +_thread_slots = None + +# A (non re-entrant) lock to protect the above _thread_slots variable. +_thread_slots_lock = threading.Lock() + +_logger = logging.getLogger('cron') + +# Sleep duration limits - must not loop too quickly, but can't sleep too long +# either, because a new job might be inserted in ir_cron with a much sooner +# execution date than current known ones. We won't see it until we wake! +MAX_SLEEP = 60 # 1 min +MIN_SLEEP = 1 # 1 sec + +# Dummy wake-up timestamp that can be used to force a database wake-up asap +WAKE_UP_NOW = 1 + +def get_thread_slots(): + """ Return the number of available thread slots """ + return _thread_slots + + +def release_thread_slot(): + """ Increment the number of available thread slots """ + global _thread_slots + with _thread_slots_lock: + _thread_slots += 1 + + +def take_thread_slot(): + """ Decrement the number of available thread slots """ + global _thread_slots + with _thread_slots_lock: + _thread_slots -= 1 + + +def cancel(db_name): + """ Cancel the next wake-up of a given database, if any. + + :param db_name: database name for which the wake-up is canceled. + + """ + _logger.debug("Cancel next wake-up for database '%s'.", db_name) + with _wakeups_lock: + if db_name in _wakeup_by_db: + _wakeup_by_db[db_name][2] = True + + +def cancel_all(): + """ Cancel all database wake-ups. """ + _logger.debug("Cancel all database wake-ups") + global _wakeups + global _wakeup_by_db + with _wakeups_lock: + _wakeups = [] + _wakeup_by_db = {} + + +def schedule_wakeup(timestamp, db_name): + """ Schedule a new wake-up for a database. + + If an earlier wake-up is already defined, the new wake-up is discarded. + If another wake-up is defined, that wake-up is discarded and the new one + is scheduled. + + :param db_name: database name for which a new wake-up is scheduled. + :param timestamp: when the wake-up is scheduled. + + """ + if not timestamp: + return + with _wakeups_lock: + if db_name in _wakeup_by_db: + task = _wakeup_by_db[db_name] + if not task[2] and timestamp > task[0]: + # existing wakeup is valid and occurs earlier than new one + return + task[2] = True # cancel existing task + task = [timestamp, db_name, False] + heapq.heappush(_wakeups, task) + _wakeup_by_db[db_name] = task + _logger.debug("Wake-up scheduled for database '%s' @ %s", db_name, + 'NOW' if timestamp == WAKE_UP_NOW else timestamp) + +def runner(): + """Neverending function (intended to be run in a dedicated thread) that + checks every 60 seconds the next database wake-up. TODO: make configurable + """ + while True: + runner_body() + +def runner_body(): + with _wakeups_lock: + while _wakeups and _wakeups[0][0] < time.time() and get_thread_slots(): + task = heapq.heappop(_wakeups) + timestamp, db_name, canceled = task + if canceled: + continue + del _wakeup_by_db[db_name] + registry = openerp.pooler.get_pool(db_name) + if not registry._init: + _logger.debug("Database '%s' wake-up! Firing multi-threaded cron job processing", db_name) + registry['ir.cron']._run_jobs_multithread() + amount = MAX_SLEEP + with _wakeups_lock: + # Sleep less than MAX_SLEEP if the next known wake-up will happen before that. + if _wakeups and get_thread_slots(): + amount = min(MAX_SLEEP, max(MIN_SLEEP, _wakeups[0][0] - time.time())) + _logger.debug("Going to sleep for %ss", amount) + time.sleep(amount) + +def start_master_thread(): + """ Start the above runner function in a daemon thread. + + The thread is a typical daemon thread: it will never quit and must be + terminated when the main process exits - with no consequence (the processing + threads it spawns are not marked daemon). + + """ + global _thread_slots + _thread_slots = openerp.conf.max_cron_threads + db_maxconn = tools.config['db_maxconn'] + if _thread_slots >= tools.config.get('db_maxconn', 64): + _logger.warning("Connection pool size (%s) is set lower than max number of cron threads (%s), " + "this may cause trouble if you reach that number of parallel cron tasks.", + db_maxconn, _thread_slots) + t = threading.Thread(target=runner, name="openerp.cron.master_thread") + t.setDaemon(True) + t.start() + _logger.debug("Master cron daemon started!") + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/exceptions.py b/openerp/exceptions.py new file mode 100644 index 00000000000..fbf52c7f3a9 --- /dev/null +++ b/openerp/exceptions.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +""" OpenERP core exceptions. + +This module defines a few exception types. Those types are understood by the +RPC layer. Any other exception type bubbling until the RPC layer will be +treated as a 'Server error'. + +""" + +class Warning(Exception): + pass + +class AccessDenied(Exception): + """ Login/password error. No message, no traceback. """ + def __init__(self): + super(AccessDenied, self).__init__('Access denied.') + self.traceback = ('', '', '') + +class AccessError(Exception): + """ Access rights error. """ + +class DeferredException(Exception): + """ Exception object holding a traceback for asynchronous reporting. + + Some RPC calls (database creation and report generation) happen with + an initial request followed by multiple, polling requests. This class + is used to store the possible exception occuring in the thread serving + the first request, and is then sent to a polling request. + + ('Traceback' is misleading, this is really a exc_info() triple.) + """ + def __init__(self, msg, tb): + self.message = msg + self.traceback = tb + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/modules/db.py b/openerp/modules/db.py index 25ce7283c97..8650bb5de9a 100644 --- a/openerp/modules/db.py +++ b/openerp/modules/db.py @@ -21,6 +21,7 @@ ############################################################################## import openerp.modules +import logging def is_initialized(cr): """ Check if a database has been initialized for the ORM. @@ -40,6 +41,10 @@ def initialize(cr): """ f = openerp.modules.get_module_resource('base', 'base.sql') + if not f: + m = "File not found: 'base.sql' (provided by module 'base')." + logging.getLogger('init').critical(m) + raise IOError(m) base_sql_file = openerp.tools.misc.file_open(f) try: cr.execute(base_sql_file.read()) @@ -70,13 +75,14 @@ def initialize(cr): cr.execute('INSERT INTO ir_module_module \ (author, website, name, shortdesc, description, \ - category_id, state, certificate, web, license) \ - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', ( + category_id, state, certificate, web, license, complexity) \ + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', ( info['author'], info['website'], i, info['name'], info['description'], category_id, state, info['certificate'], info['web'], - info['license'])) + info['license'], + info['complexity'])) id = cr.fetchone()[0] cr.execute('INSERT INTO ir_model_data \ (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', ( @@ -118,4 +124,14 @@ def create_categories(cr, categories): categories = categories[1:] return p_id +def has_unaccent(cr): + """ Test if the database has an unaccent function. + + The unaccent is supposed to be provided by the PostgreSQL unaccent contrib + module but any similar function will be picked by OpenERP. + + """ + cr.execute("SELECT proname FROM pg_proc WHERE proname='unaccent'") + return len(cr.fetchall()) > 0 + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/modules/graph.py b/openerp/modules/graph.py index 078d23c235b..539dda25b50 100644 --- a/openerp/modules/graph.py +++ b/openerp/modules/graph.py @@ -58,16 +58,16 @@ class Graph(dict): """ - def add_node(self, name, deps): + def add_node(self, name, info): max_depth, father = 0, None - for n in [Node(x, self) for x in deps]: + for n in [Node(x, self, None) for x in info['depends']]: if n.depth >= max_depth: father = n max_depth = n.depth if father: - return father.add_child(name) + return father.add_child(name, info) else: - return Node(name, self) + return Node(name, self, info) def update_from_db(self, cr): if not len(self): @@ -120,7 +120,7 @@ class Graph(dict): continue later.clear() current.remove(package) - node = self.add_node(package, deps) + node = self.add_node(package, info) node.data = info for kind in ('init', 'demo', 'update'): if package in tools.config[kind] or 'all' in tools.config[kind] or kind in force: @@ -154,12 +154,13 @@ class Graph(dict): class Singleton(object): - def __new__(cls, name, graph): + def __new__(cls, name, graph, info): if name in graph: inst = graph[name] else: inst = object.__new__(cls) inst.name = name + inst.info = info graph[name] = inst return inst @@ -167,19 +168,21 @@ class Singleton(object): class Node(Singleton): """ One module in the modules dependency graph. - Node acts as a per-module singleton. + Node acts as a per-module singleton. A node is constructed via + Graph.add_module() or Graph.add_modules(). Some of its fields are from + ir_module_module (setted by Graph.update_from_db()). """ - def __init__(self, name, graph): + def __init__(self, name, graph, info): self.graph = graph if not hasattr(self, 'children'): self.children = [] if not hasattr(self, 'depth'): self.depth = 0 - def add_child(self, name): - node = Node(name, self.graph) + def add_child(self, name, info): + node = Node(name, self.graph, info) node.depth = self.depth + 1 if node not in self.children: self.children.append(node) diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index 45a466e5462..b06368ba1b2 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -158,7 +158,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= logger.info('module %s: loading objects', package.name) migrations.migrate_module(package, 'pre') register_module_classes(package.name) - models = pool.instanciate(package.name, cr) + models = pool.load(cr, package) loaded_modules.append(package.name) if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): init_module_models(cr, package.name, models) @@ -273,8 +273,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # This is a brand new pool, just created in pooler.get_db_and_pool() pool = pooler.get_pool(cr.dbname) - processed_modules = [] # for cleanup step after install - loaded_modules = [] # to avoid double loading report = tools.assertion_report() if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) @@ -285,8 +283,10 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if not graph: logger.notifyChannel('init', netsvc.LOG_CRITICAL, 'module base cannot be loaded! (hint: verify addons-path)') raise osv.osv.except_osv(_('Could not load base module'), _('module base cannot be loaded! (hint: verify addons-path)')) - loaded, processed = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report) - processed_modules.extend(processed) + + # processed_modules: for cleanup step after install + # loaded_modules: to avoid double loading + loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report) if tools.config['load_language']: for lang in tools.config['load_language'].split(','): @@ -339,16 +339,16 @@ def load_modules(db, force_demo=False, status=None, update_module=False): cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""") for (model, name) in cr.fetchall(): model_obj = pool.get(model) - if model_obj and not isinstance(model_obj, osv.osv.osv_memory): - logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name)) + if model_obj and not model_obj.is_transient(): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'Model %s (%s) has no access rules!' % (model, name)) # Temporary warning while we remove access rights on osv_memory objects, as they have # been replaced by owner-only access rights cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""") for (model, name) in cr.fetchall(): model_obj = pool.get(model) - if isinstance(model_obj, osv.osv.osv_memory): - logger.notifyChannel('init', netsvc.LOG_WARNING, 'In-memory object %s (%s) should not have explicit access rules!' % (model, name)) + if model_obj and model_obj.is_transient(): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'The transient model %s (%s) should not have explicit access rules!' % (model, name)) cr.execute("SELECT model from ir_model") for (model,) in cr.fetchall(): @@ -356,7 +356,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if obj: obj._check_removed_columns(cr, log=True) else: - logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is referenced but not present in the orm pool!" % model) + logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)" % model) # Cleanup orphan records pool.get('ir.model.data')._process_end(cr, 1, processed_modules) diff --git a/openerp/modules/module.py b/openerp/modules/module.py index 1514e836dd8..809339897ab 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -31,7 +31,6 @@ import openerp.osv as osv import openerp.tools as tools import openerp.tools.osutil as osutil from openerp.tools.safe_eval import safe_eval as eval -import openerp.pooler as pooler from openerp.tools.translate import _ import openerp.netsvc as netsvc @@ -58,6 +57,11 @@ loaded = [] logger = netsvc.Logger() def initialize_sys_path(): + """ Add all addons paths in sys.path. + + This ensures something like ``import crm`` works even if the addons are + not in the PYTHONPATH. + """ global ad_paths if ad_paths: @@ -245,11 +249,14 @@ def load_information_from_description_file(module): info.setdefault('website', '') info.setdefault('name', False) info.setdefault('description', '') + info.setdefault('complexity', False) info['certificate'] = info.get('certificate') or None info['web'] = info.get('web') or False info['license'] = info.get('license') or 'AGPL-3' info.setdefault('installable', True) info.setdefault('active', False) + # If the following is provided, it is called after the module is --loaded. + info.setdefault('post_load', None) for kind in ['data', 'demo', 'test', 'init_xml', 'update_xml', 'demo_xml']: info.setdefault(kind, []) @@ -271,7 +278,6 @@ def init_module_models(cr, module_name, obj_list): TODO better explanation of _auto_init and init. """ - logger.notifyChannel('init', netsvc.LOG_INFO, 'module %s: creating or updating database tables' % module_name) todo = [] @@ -290,23 +296,22 @@ def init_module_models(cr, module_name, obj_list): t[1](cr, *t[2]) cr.commit() +# Import hook to write a addon m in both sys.modules['m'] and +# sys.modules['openerp.addons.m']. Otherwise it could be loaded twice +# if imported twice using different names. +#class MyImportHook(object): +# def find_module(self, module_name, package_path): +# print ">>>", module_name, package_path +# def load_module(self, module_name): +# raise ImportError("Restricted") -def load_module(module_name): - """ Load a Python module found on the addons paths.""" - fm = imp.find_module(module_name, ad_paths) - try: - imp.load_module(module_name, *fm) - finally: - if fm[0]: - fm[0].close() - +#sys.meta_path.append(MyImportHook()) def register_module_classes(m): """ Register module named m, if not already registered. - This will load the module and register all of its models. (Actually, the - explicit constructor call of each of the models inside the module will - register them.) + This loads the module and register all of its models, thanks to either + the MetaModel metaclass, or the explicit instantiation of the model. """ @@ -326,7 +331,7 @@ def register_module_classes(m): try: zip_mod_path = mod_path + '.zip' if not os.path.isfile(zip_mod_path): - load_module(m) + __import__(m) else: zimp = zipimport.zipimporter(zip_mod_path) zimp.load_module(m) diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index 072082db000..20500f981c3 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -22,10 +22,16 @@ """ Models registries. """ +import threading + +import logging import openerp.sql_db import openerp.osv.orm - +import openerp.cron +import openerp.tools +import openerp.modules.db +import openerp.tools.config class Registry(object): """ Model registry for a particular database. @@ -44,6 +50,14 @@ class Registry(object): self.db_name = db_name self.db = openerp.sql_db.db_connect(db_name) + cr = self.db.cursor() + has_unaccent = openerp.modules.db.has_unaccent(cr) + if openerp.tools.config['unaccent'] and not has_unaccent: + logger = logging.getLogger('unaccent') + logger.warning("The option --unaccent was given but no unaccent() function was found in database.") + self.has_unaccent = openerp.tools.config['unaccent'] and has_unaccent + cr.close() + def do_parent_store(self, cr): for o in self._init_parent: self.get(o)._parent_store_compute(cr) @@ -65,28 +79,42 @@ class Registry(object): """ Return a model for a given name or raise KeyError if it doesn't exist.""" return self.models[model_name] - def instanciate(self, module, cr): - """ Instanciate all the classes of a given module for a particular db.""" + def load(self, cr, module): + """ Load a given module in the registry. + + At the Python level, the modules are already loaded, but not yet on a + per-registry level. This method populates a registry with the given + modules, i.e. it instanciates all the classes of a the given module + and registers them in the registry. + + """ res = [] - # Instantiate registered classes (via metamodel discovery or via explicit - # constructor call), and add them to the pool. - for cls in openerp.osv.orm.MetaModel.module_to_models.get(module, []): - res.append(cls.createInstance(self, cr)) + # Instantiate registered classes (via the MetaModel automatic discovery + # or via explicit constructor call), and add them to the pool. + for cls in openerp.osv.orm.MetaModel.module_to_models.get(module.name, []): + res.append(cls.create_instance(self, cr)) return res + def schedule_cron_jobs(self): + """ Make the cron thread care about this registry/database jobs. + This will initiate the cron thread to check for any pending jobs for + this registry/database as soon as possible. Then it will continuously + monitor the ir.cron model for future jobs. See openerp.cron for + details. + """ + openerp.cron.schedule_wakeup(openerp.cron.WAKE_UP_NOW, self.db.dbname) + def clear_caches(self): """ Clear the caches - This clears the caches associated to methods decorated with ``tools.ormcache`` or ``tools.ormcache_multi`` for all the models. """ for model in self.models.itervalues(): model.clear_caches() - class RegistryManager(object): """ Model registries manager. @@ -94,24 +122,20 @@ class RegistryManager(object): registries (essentially database connection/model registry pairs). """ - # Mapping between db name and model registry. # Accessed through the methods below. registries = {} - + registries_lock = threading.RLock() @classmethod def get(cls, db_name, force_demo=False, status=None, update_module=False, pooljobs=True): """ Return a registry for a given database name.""" - - if db_name in cls.registries: - registry = cls.registries[db_name] - else: - registry = cls.new(db_name, force_demo, status, - update_module, pooljobs) - return registry - + try: + return cls.registries[db_name] + except KeyError: + return cls.new(db_name, force_demo, status, + update_module, pooljobs) @classmethod def new(cls, db_name, force_demo=False, status=None, @@ -121,47 +145,64 @@ class RegistryManager(object): The (possibly) previous registry for that database name is discarded. """ - import openerp.modules - registry = Registry(db_name) - - # Initializing a registry will call general code which will in turn - # call registries.get (this object) to obtain the registry being - # initialized. Make it available in the registries dictionary then - # remove it if an exception is raised. - cls.delete(db_name) - cls.registries[db_name] = registry - try: - # This should be a method on Registry - openerp.modules.load_modules(registry.db, force_demo, status, update_module) - except Exception: - del cls.registries[db_name] - raise - - cr = registry.db.cursor() - try: - registry.do_parent_store(cr) - registry.get('ir.actions.report.xml').register_all(cr) - cr.commit() - finally: - cr.close() + with cls.registries_lock: + registry = Registry(db_name) + + # Initializing a registry will call general code which will in turn + # call registries.get (this object) to obtain the registry being + # initialized. Make it available in the registries dictionary then + # remove it if an exception is raised. + cls.delete(db_name) + cls.registries[db_name] = registry + try: + # This should be a method on Registry + openerp.modules.load_modules(registry.db, force_demo, status, update_module) + except Exception: + del cls.registries[db_name] + raise + + cr = registry.db.cursor() + try: + registry.do_parent_store(cr) + registry.get('ir.actions.report.xml').register_all(cr) + cr.commit() + finally: + cr.close() if pooljobs: - registry.get('ir.cron').restart(registry.db.dbname) + registry.schedule_cron_jobs() return registry - @classmethod def delete(cls, db_name): - """ Delete the registry linked to a given database. """ - if db_name in cls.registries: - del cls.registries[db_name] + """Delete the registry linked to a given database. + + This also cleans the associated caches. For good measure this also + cancels the associated cron job. But please note that the cron job can + be running and take some time before ending, and that you should not + remove a registry if it can still be used by some thread. So it might + be necessary to call yourself openerp.cron.Agent.cancel(db_name) and + and join (i.e. wait for) the thread. + """ + with cls.registries_lock: + if db_name in cls.registries: + cls.registries[db_name].clear_caches() + del cls.registries[db_name] + openerp.cron.cancel(db_name) @classmethod + def delete_all(cls): + """Delete all the registries. """ + with cls.registries_lock: + for db_name in cls.registries.keys(): + cls.delete(db_name) + + @classmethod def clear_caches(cls, db_name): - """ Clear the caches + """Clear caches This clears the caches associated to methods decorated with ``tools.ormcache`` or ``tools.ormcache_multi`` for all the models @@ -170,8 +211,9 @@ class RegistryManager(object): This method is given to spare you a ``RegistryManager.get(db_name)`` that would loads the given database if it was not already loaded. """ - if db_name in cls.registries: - cls.registries[db_name].clear_caches() + with cls.registries_lock: + if db_name in cls.registries: + cls.registries[db_name].clear_caches() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/netsvc.py b/openerp/netsvc.py index 359813e7d41..c1120763ad4 100644 --- a/openerp/netsvc.py +++ b/openerp/netsvc.py @@ -21,7 +21,6 @@ ############################################################################## import errno -import heapq import logging import logging.handlers import os @@ -31,12 +30,14 @@ import socket import sys import threading import time +import traceback import types from pprint import pformat # TODO modules that import netsvc only for things from loglevels must be changed to use loglevels. from loglevels import * import tools +import openerp def close_socket(sock): """ Closes a socket instance cleanly @@ -60,20 +61,19 @@ def close_socket(sock): #.apidoc title: Common Services: netsvc #.apidoc module-mods: member-order: bysource +def abort_response(dummy_1, description, dummy_2, details): + # TODO Replace except_{osv,orm} with these directly. + raise openerp.osv.osv.except_osv(description, details) + class Service(object): """ Base class for *Local* services Functionality here is trusted, no authentication. """ _services = {} - def __init__(self, name, audience=''): + def __init__(self, name): Service._services[name] = self self.__name = name - self._methods = {} - - def joinGroup(self, name): - raise Exception("No group for local services") - #GROUPS.setdefault(name, {})[self.__name] = self @classmethod def exists(cls, name): @@ -84,75 +84,39 @@ class Service(object): if cls.exists(name): cls._services.pop(name) - def exportMethod(self, method): - if callable(method): - self._methods[method.__name__] = method - - def abortResponse(self, error, description, origin, details): - if not tools.config['debug_mode']: - raise Exception("%s -- %s\n\n%s"%(origin, description, details)) - else: - raise +def LocalService(name): + # Special case for addons support, will be removed in a few days when addons + # are updated to directly use openerp.osv.osv.service. + if name == 'object_proxy': + return openerp.osv.osv.service -class LocalService(object): - """ Proxy for local services. - - Any instance of this class will behave like the single instance - of Service(name) - """ - __logger = logging.getLogger('service') - def __init__(self, name): - self.__name = name - try: - self._service = Service._services[name] - for method_name, method_definition in self._service._methods.items(): - setattr(self, method_name, method_definition) - except KeyError, keyError: - self.__logger.error('This service does not exist: %s' % (str(keyError),) ) - raise - - def __call__(self, method, *params): - return getattr(self, method)(*params) + return Service._services[name] class ExportService(object): """ Proxy for exported services. - All methods here should take an AuthProxy as their first parameter. It - will be appended by the calling framework. - Note that this class has no direct proxy, capable of calling eservice.method(). Rather, the proxy should call - dispatch(method,auth,params) + dispatch(method, params) """ _services = {} - _groups = {} _logger = logging.getLogger('web-services') - - def __init__(self, name, audience=''): + + def __init__(self, name): ExportService._services[name] = self self.__name = name self._logger.debug("Registered an exported service: %s" % name) - def joinGroup(self, name): - ExportService._groups.setdefault(name, {})[self.__name] = self - @classmethod def getService(cls,name): return cls._services[name] - def dispatch(self, method, auth, params): + # Dispatch a RPC call w.r.t. the method name. The dispatching + # w.r.t. the service (this class) is done by OpenERPDispatcher. + def dispatch(self, method, params): raise Exception("stub dispatch at %s" % self.__name) - def new_dispatch(self,method,auth,params): - raise Exception("stub dispatch at %s" % self.__name) - - def abortResponse(self, error, description, origin, details): - if not tools.config['debug_mode']: - raise Exception("%s -- %s\n\n%s"%(origin, description, details)) - else: - raise - BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10) #The background is set with 40 plus the number of the color, and the foreground with 30 #These are the sequences need to get colored ouput @@ -244,83 +208,6 @@ def init_alternative_logger(): logger.addHandler(handler) logger.setLevel(logging.ERROR) -class Agent(object): - """ Singleton that keeps track of cancellable tasks to run at a given - timestamp. - - The tasks are characterised by: - - * a timestamp - * the database on which the task run - * the function to call - * the arguments and keyword arguments to pass to the function - - Implementation details: - - - Tasks are stored as list, allowing the cancellation by setting - the timestamp to 0. - - A heapq is used to store tasks, so we don't need to sort - tasks ourself. - """ - __tasks = [] - __tasks_by_db = {} - _logger = logging.getLogger('netsvc.agent') - - @classmethod - def setAlarm(cls, function, timestamp, db_name, *args, **kwargs): - task = [timestamp, db_name, function, args, kwargs] - heapq.heappush(cls.__tasks, task) - cls.__tasks_by_db.setdefault(db_name, []).append(task) - - @classmethod - def cancel(cls, db_name): - """Cancel all tasks for a given database. If None is passed, all tasks are cancelled""" - cls._logger.debug("Cancel timers for %s db", db_name or 'all') - if db_name is None: - cls.__tasks, cls.__tasks_by_db = [], {} - else: - if db_name in cls.__tasks_by_db: - for task in cls.__tasks_by_db[db_name]: - task[0] = 0 - - @classmethod - def quit(cls): - cls.cancel(None) - - @classmethod - def runner(cls): - """Neverending function (intended to be ran in a dedicated thread) that - checks every 60 seconds tasks to run. TODO: make configurable - """ - current_thread = threading.currentThread() - while True: - while cls.__tasks and cls.__tasks[0][0] < time.time(): - task = heapq.heappop(cls.__tasks) - timestamp, dbname, function, args, kwargs = task - cls.__tasks_by_db[dbname].remove(task) - if not timestamp: - # null timestamp -> cancelled task - continue - current_thread.dbname = dbname # hack hack - cls._logger.debug("Run %s.%s(*%s, **%s)", function.im_class.__name__, function.func_name, args, kwargs) - delattr(current_thread, 'dbname') - task_thread = threading.Thread(target=function, name='netsvc.Agent.task', args=args, kwargs=kwargs) - # force non-daemon task threads (the runner thread must be daemon, and this property is inherited by default) - task_thread.setDaemon(False) - task_thread.start() - time.sleep(1) - time.sleep(60) - -def start_agent(): - agent_runner = threading.Thread(target=Agent.runner, name="netsvc.Agent.runner") - # the agent runner is a typical daemon thread, that will never quit and must be - # terminated when the main process exits - with no consequence (the processing - # threads it spawns are not marked daemon) - agent_runner.setDaemon(True) - agent_runner.start() - -import traceback - class Server: """ Generic interface for all servers with an event loop etc. Override this to impement http, net-rpc etc. servers. @@ -403,11 +290,6 @@ class Server: def _close_socket(self): close_socket(self.socket) -class OpenERPDispatcherException(Exception): - def __init__(self, exception, traceback): - self.exception = exception - self.traceback = traceback - def replace_request_password(args): # password is always 3rd argument in a request, we replace it in RPC logs # so it's easier to forward logs for diagnostics/debugging purposes... @@ -425,33 +307,47 @@ def log(title, msg, channel=logging.DEBUG_RPC, depth=None, fn=""): logger.log(channel, indent+line) indent=indent_after -class OpenERPDispatcher: - def log(self, title, msg, channel=logging.DEBUG_RPC, depth=None, fn=""): +def dispatch_rpc(service_name, method, params): + """ Handle a RPC call. + + This is pure Python code, the actual marshalling (from/to XML-RPC or + NET-RPC) is done in a upper layer. + """ + def _log(title, msg, channel=logging.DEBUG_RPC, depth=None, fn=""): log(title, msg, channel=channel, depth=depth, fn=fn) - def dispatch(self, service_name, method, params): - try: - auth = getattr(self, 'auth_provider', None) - logger = logging.getLogger('result') - start_time = end_time = 0 - if logger.isEnabledFor(logging.DEBUG_RPC_ANSWER): - self.log('service', tuple(replace_request_password(params)), depth=None, fn='%s.%s'%(service_name,method)) - if logger.isEnabledFor(logging.DEBUG_RPC): - start_time = time.time() - result = ExportService.getService(service_name).dispatch(method, auth, params) - if logger.isEnabledFor(logging.DEBUG_RPC): - end_time = time.time() - if not logger.isEnabledFor(logging.DEBUG_RPC_ANSWER): - self.log('service (%.3fs)' % (end_time - start_time), tuple(replace_request_password(params)), depth=1, fn='%s.%s'%(service_name,method)) - self.log('execution time', '%.3fs' % (end_time - start_time), channel=logging.DEBUG_RPC_ANSWER) - self.log('result', result, channel=logging.DEBUG_RPC_ANSWER) - return result - except Exception, e: - self.log('exception', tools.exception_to_unicode(e)) - tb = getattr(e, 'traceback', sys.exc_info()) - tb_s = "".join(traceback.format_exception(*tb)) - if tools.config['debug_mode'] and isinstance(tb[2], types.TracebackType): - import pdb - pdb.post_mortem(tb[2]) - raise OpenERPDispatcherException(e, tb_s) + try: + logger = logging.getLogger('result') + start_time = end_time = 0 + if logger.isEnabledFor(logging.DEBUG_RPC_ANSWER): + _log('service', tuple(replace_request_password(params)), depth=None, fn='%s.%s'%(service_name,method)) + if logger.isEnabledFor(logging.DEBUG_RPC): + start_time = time.time() + result = ExportService.getService(service_name).dispatch(method, params) + if logger.isEnabledFor(logging.DEBUG_RPC): + end_time = time.time() + if not logger.isEnabledFor(logging.DEBUG_RPC_ANSWER): + _log('service (%.3fs)' % (end_time - start_time), tuple(replace_request_password(params)), depth=1, fn='%s.%s'%(service_name,method)) + _log('execution time', '%.3fs' % (end_time - start_time), channel=logging.DEBUG_RPC_ANSWER) + _log('result', result, channel=logging.DEBUG_RPC_ANSWER) + return result + except openerp.exceptions.AccessError: + raise + except openerp.exceptions.AccessDenied: + raise + except openerp.exceptions.Warning: + raise + except openerp.exceptions.DeferredException, e: + _log('exception', tools.exception_to_unicode(e)) + post_mortem(e.traceback) + raise + except Exception, e: + _log('exception', tools.exception_to_unicode(e)) + post_mortem(sys.exc_info()) + raise + +def post_mortem(info): + if tools.config['debug_mode'] and isinstance(info[2], types.TracebackType): + import pdb + pdb.post_mortem(info[2]) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index 54726a289f2..cb8cfea583f 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -20,17 +20,146 @@ # ############################################################################## +""" Domain expression processing + +The main duty of this module is to compile a domain expression into a SQL +query. A lot of things should be documented here, but as a first step in the +right direction, some tests in test_osv_expression.yml might give you some +additional information. + +For legacy reasons, a domain uses an inconsistent two-levels abstract syntax +(domains are regular Python data structures). At the first level, a domain +is an expression made of terms (sometimes called leaves) and (domain) operators +used in prefix notation. The available operators at this level are '!', '&', +and '|'. '!' is a unary 'not', '&' is a binary 'and', and '|' is a binary 'or'. +For instance, here is a possible domain. (<term> stands for an arbitrary term, +more on this later.) + + ['&', '!', <term1>, '|', <term2>, <term3>] + +It is equivalent to this pseudo code using infix notation: + + (not <term1>) and (<term2> or <term3>) + +The second level of syntax deals with the term representation. A term is +a triple of the form (left, operator, right). That is, a term uses an infix +notation, and the available operators, and possible left and right operands +differ with those of the previous level. Here is a possible term: + + ('company_id.name', '=', 'OpenERP') + +The left and right operand don't have the same possible values. The left +operand is field name (related to the model for which the domain applies). +Actually, the field name can use the dot-notation to traverse relationships. +The right operand is a Python value whose type should match the used operator +and field type. In the above example, a string is used because the name field +of a company has type string, and because we use the '=' operator. When +appropriate, a 'in' operator can be used, and thus the right operand should be +a list. + +Note: the non-uniform syntax could have been more uniform, but this would hide +an important limitation of the domain syntax. Say that the term representation +was ['=', 'company_id.name', 'OpenERP']. Used in a complete domain, this would +look like: + + ['!', ['=', 'company_id.name', 'OpenERP']] + +and you would be tempted to believe something like this would be possible: + + ['!', ['=', 'company_id.name', ['&', ..., ...]]] + +That is, a domain could be a valid operand. But this is not the case. A domain +is really limited to a two-level nature, and can not takes a recursive form: a +domain is not a valid second-level operand. + +Unaccent - Accent-insensitive search + +OpenERP will use the SQL function 'unaccent' when available for the 'ilike' and +'not ilike' operators, and enabled in the configuration. +Normally the 'unaccent' function is obtained from the PostgreSQL 'unaccent' +contrib module[0]. + + +..todo: The following explanation should be moved in some external installation + guide + +The steps to install the module might differ on specific PostgreSQL versions. +We give here some instruction for PostgreSQL 9.x on a Ubuntu system. + +Ubuntu doesn't come yet with PostgreSQL 9.x, so an alternative package source +is used. We use Martin Pitt's PPA available at ppa:pitti/postgresql[1]. See +[2] for instructions. Basically: + + > sudo add-apt-repository ppa:pitti/postgresql + > sudo apt-get update + +Once the package list is up-to-date, you have to install PostgreSQL 9.0 and +its contrib modules. + + > sudo apt-get install postgresql-9.0 postgresql-contrib-9.0 + +When you want to enable unaccent on some database: + + > psql9 <database> -f /usr/share/postgresql/9.0/contrib/unaccent.sql + +Here 'psql9' is an alias for the newly installed PostgreSQL 9.0 tool, together +with the correct port if necessary (for instance if PostgreSQL 8.4 is running +on 5432). (Other aliases can be used for createdb and dropdb.) + + > alias psql9='/usr/lib/postgresql/9.0/bin/psql -p 5433' + +You can check unaccent is working: + + > psql9 <database> -c"select unaccent('hélène')" + +Finally, to instruct OpenERP to really use the unaccent function, you have to +start the server specifying the --unaccent flag. + +[0] http://developer.postgresql.org/pgdocs/postgres/unaccent.html +[1] https://launchpad.net/~pitti/+archive/postgresql +[2] https://launchpad.net/+help/soyuz/ppa-sources-list.html + +""" + +import logging + from openerp.tools import flatten, reverse_enumerate import fields +import openerp.modules +from openerp.osv.orm import MAGIC_COLUMNS #.apidoc title: Domain Expressions +# Domain operators. NOT_OPERATOR = '!' OR_OPERATOR = '|' AND_OPERATOR = '&' +DOMAIN_OPERATORS = (NOT_OPERATOR, OR_OPERATOR, AND_OPERATOR) + +# List of available term operators. It is also possible to use the '<>' +# operator, which is strictly the same as '!='; the later should be prefered +# for consistency. This list doesn't contain '<>' as it is simpified to '!=' +# by the normalize_operator() function (so later part of the code deals with +# only one representation). +# An internal (i.e. not available to the user) 'inselect' operator is also +# used. In this case its right operand has the form (subselect, params). +TERM_OPERATORS = ('=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', + 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', + 'child_of') -TRUE_DOMAIN = [(1,'=',1)] -FALSE_DOMAIN = [(0,'=',1)] +# A subset of the above operators, with a 'negative' semantic. When the +# expressions 'in NEGATIVE_TERM_OPERATORS' or 'not in NEGATIVE_TERM_OPERATORS' are used in the code +# below, this doesn't necessarily mean that any of those NEGATIVE_TERM_OPERATORS is +# legal in the processed term. +NEGATIVE_TERM_OPERATORS = ('!=', 'not like', 'not ilike', 'not in') + +TRUE_LEAF = (1, '=', 1) +FALSE_LEAF = (0, '=', 1) + +TRUE_DOMAIN = [TRUE_LEAF] +FALSE_DOMAIN = [FALSE_LEAF] + +_logger = logging.getLogger('expression') def normalize(domain): """Returns a normalized version of ``domain_expr``, where all implicit '&' operators @@ -45,10 +174,10 @@ def normalize(domain): op_arity = {NOT_OPERATOR: 1, AND_OPERATOR: 2, OR_OPERATOR: 2} for token in domain: if expected == 0: # more than expected, like in [A, B] - result[0:0] = ['&'] # put an extra '&' in front + result[0:0] = [AND_OPERATOR] # put an extra '&' in front expected = 1 result.append(token) - if isinstance(token, (list,tuple)): # domain term + if isinstance(token, (list, tuple)): # domain term expected -= 1 else: expected += op_arity.get(token, 0) - 1 @@ -57,7 +186,8 @@ def normalize(domain): def combine(operator, unit, zero, domains): """Returns a new domain expression where all domain components from ``domains`` - have been added together using the binary operator ``operator``. + have been added together using the binary operator ``operator``. The given + domains must be normalized. :param unit: the identity element of the domains "set" with regard to the operation performed by ``operator``, i.e the domain component ``i`` which, when @@ -69,6 +199,7 @@ def combine(operator, unit, zero, domains): combined with any domain ``x`` via ``operator``, yields ``z``. E.g. [(1,'=',1)] is the typical zero for OR_OPERATOR: as soon as you see it in a domain component the resulting domain is the zero. + :param domains: a list of normalized domains. """ result = [] count = 0 @@ -84,13 +215,130 @@ def combine(operator, unit, zero, domains): return result def AND(domains): - """ AND([D1,D2,...]) returns a domain representing D1 and D2 and ... """ + """AND([D1,D2,...]) returns a domain representing D1 and D2 and ... """ return combine(AND_OPERATOR, TRUE_DOMAIN, FALSE_DOMAIN, domains) def OR(domains): - """ OR([D1,D2,...]) returns a domain representing D1 or D2 or ... """ + """OR([D1,D2,...]) returns a domain representing D1 or D2 or ... """ return combine(OR_OPERATOR, FALSE_DOMAIN, TRUE_DOMAIN, domains) +def is_operator(element): + """Test whether an object is a valid domain operator. """ + return isinstance(element, basestring) and element in DOMAIN_OPERATORS + +# TODO change the share wizard to use this function. +def is_leaf(element, internal=False): + """ Test whether an object is a valid domain term. + + :param internal: allow or not the 'inselect' internal operator in the term. + This normally should be always left to False. + """ + INTERNAL_OPS = TERM_OPERATORS + ('inselect',) + return (isinstance(element, tuple) or isinstance(element, list)) \ + and len(element) == 3 \ + and (((not internal) and element[1] in TERM_OPERATORS + ('<>',)) \ + or (internal and element[1] in INTERNAL_OPS + ('<>',))) + +def normalize_leaf(left, operator, right): + """ Change a term's operator to some canonical form, simplifying later + processing. + """ + original = operator + operator = operator.lower() + if operator == '<>': + operator = '!=' + if isinstance(right, bool) and operator in ('in', 'not in'): + _logger.warning("The domain term '%s' should use the '=' or '!=' operator." % ((left, original, right),)) + operator = '=' if operator == 'in' else '!=' + if isinstance(right, (list, tuple)) and operator in ('=', '!='): + _logger.warning("The domain term '%s' should use the 'in' or 'not in' operator." % ((left, original, right),)) + operator = 'in' if operator == '=' else 'not in' + return left, operator, right + +def distribute_not(domain): + """ Distribute any '!' domain operators found inside a normalized domain. + + Because we don't use SQL semantic for processing a 'left not in right' + query (i.e. our 'not in' is not simply translated to a SQL 'not in'), + it means that a '! left in right' can not be simply processed + by __leaf_to_sql by first emitting code for 'left in right' then wrapping + the result with 'not (...)', as it would result in a 'not in' at the SQL + level. + + This function is thus responsible for pushing any '!' domain operators + inside the terms themselves. For example:: + + ['!','&',('user_id','=',4),('partner_id','in',[1,2])] + will be turned into: + ['|',('user_id','!=',4),('partner_id','not in',[1,2])] + + """ + def negate(leaf): + """Negates and returns a single domain leaf term, + using the opposite operator if possible""" + left, operator, right = leaf + mapping = { + '<': '>=', + '>': '<=', + '<=': '>', + '>=': '<', + '=': '!=', + '!=': '=', + } + if operator in ('in', 'like', 'ilike'): + operator = 'not ' + operator + return [(left, operator, right)] + if operator in ('not in', 'not like', 'not ilike'): + operator = operator[4:] + return [(left, operator, right)] + if operator in mapping: + operator = mapping[operator] + return [(left, operator, right)] + return [NOT_OPERATOR, (left, operator, right)] + def distribute_negate(domain): + """Negate the domain ``subtree`` rooted at domain[0], + leaving the rest of the domain intact, and return + (negated_subtree, untouched_domain_rest) + """ + if is_leaf(domain[0]): + return negate(domain[0]), domain[1:] + if domain[0] == AND_OPERATOR: + done1, todo1 = distribute_negate(domain[1:]) + done2, todo2 = distribute_negate(todo1) + return [OR_OPERATOR] + done1 + done2, todo2 + if domain[0] == OR_OPERATOR: + done1, todo1 = distribute_negate(domain[1:]) + done2, todo2 = distribute_negate(todo1) + return [AND_OPERATOR] + done1 + done2, todo2 + if not domain: + return [] + if domain[0] != NOT_OPERATOR: + return [domain[0]] + distribute_not(domain[1:]) + if domain[0] == NOT_OPERATOR: + done, todo = distribute_negate(domain[1:]) + return done + distribute_not(todo) + +def select_from_where(cr, select_field, from_table, where_field, where_ids, where_operator): + # todo: merge into parent query as sub-query + res = [] + if where_ids: + if where_operator in ['<','>','>=','<=']: + cr.execute('SELECT "%s" FROM "%s" WHERE "%s" %s %%s' % \ + (select_field, from_table, where_field, where_operator), + (where_ids[0],)) # TODO shouldn't this be min/max(where_ids) ? + res = [r[0] for r in cr.fetchall()] + else: # TODO where_operator is supposed to be 'in'? It is called with child_of... + for i in range(0, len(where_ids), cr.IN_MAX): + subids = where_ids[i:i+cr.IN_MAX] + cr.execute('SELECT "%s" FROM "%s" WHERE "%s" IN %%s' % \ + (select_field, from_table, where_field), (tuple(subids),)) + res.extend([r[0] for r in cr.fetchall()]) + return res + +def select_distinct_from_where_not_null(cr, select_field, from_table): + cr.execute('SELECT distinct("%s") FROM "%s" where "%s" is not null' % \ + (select_field, from_table, select_field)) + return [r[0] for r in cr.fetchall()] class expression(object): """ @@ -100,148 +348,124 @@ class expression(object): For more info: http://christophe-simonis-at-tiny.blogspot.com/2008/08/new-new-domain-notation.html """ - @classmethod - def _is_operator(cls, element): - return isinstance(element, (str, unicode)) and element in [AND_OPERATOR, OR_OPERATOR, NOT_OPERATOR] - - @classmethod - def _is_leaf(cls, element, internal=False): - OPS = ('=', '!=', '<>', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of') - INTERNAL_OPS = OPS + ('inselect',) - return (isinstance(element, tuple) or isinstance(element, list)) \ - and len(element) == 3 \ - and (((not internal) and element[1] in OPS) \ - or (internal and element[1] in INTERNAL_OPS)) - - def __execute_recursive_in(self, cr, s, f, w, ids, op, type): - # todo: merge into parent query as sub-query - res = [] - if ids: - if op in ['<','>','>=','<=']: - cr.execute('SELECT "%s"' \ - ' FROM "%s"' \ - ' WHERE "%s" %s %%s' % (s, f, w, op), (ids[0],)) - res.extend([r[0] for r in cr.fetchall()]) - else: - for i in range(0, len(ids), cr.IN_MAX): - subids = ids[i:i+cr.IN_MAX] - cr.execute('SELECT "%s"' \ - ' FROM "%s"' \ - ' WHERE "%s" IN %%s' % (s, f, w),(tuple(subids),)) - res.extend([r[0] for r in cr.fetchall()]) - else: - cr.execute('SELECT distinct("%s")' \ - ' FROM "%s" where "%s" is not null' % (s, f, s)), - res.extend([r[0] for r in cr.fetchall()]) - return res - - def __init__(self, exp): - # check if the expression is valid - if not reduce(lambda acc, val: acc and (self._is_operator(val) or self._is_leaf(val)), exp, True): - raise ValueError('Bad domain expression: %r' % (exp,)) - self.__exp = exp + def __init__(self, cr, uid, exp, table, context): + self.has_unaccent = openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent self.__field_tables = {} # used to store the table to use for the sql generation. key = index of the leaf self.__all_tables = set() self.__joins = [] self.__main_table = None # 'root' table. set by parse() - self.__DUMMY_LEAF = (1, '=', 1) # a dummy leaf that must not be parsed or sql generated + # assign self.__exp with the normalized, parsed domain. + self.parse(cr, uid, distribute_not(normalize(exp)), table, context) + # TODO used only for osv_memory @property def exp(self): return self.__exp[:] - def parse(self, cr, uid, table, context): - """ transform the leafs of the expression """ - if not self.__exp: - return self + def parse(self, cr, uid, exp, table, context): + """ transform the leaves of the expression """ + self.__exp = exp + self.__main_table = table + self.__all_tables.add(table) - def _rec_get(ids, table, parent=None, left='id', prefix=''): - if table._parent_store and (not table.pool._init): -# TODO: Improve where joins are implemented for many with '.', replace by: -# doms += ['&',(prefix+'.parent_left','<',o.parent_right),(prefix+'.parent_left','>=',o.parent_left)] + def child_of_domain(left, ids, left_model, parent=None, prefix=''): + """Returns a domain implementing the child_of operator for [(left,child_of,ids)], + either as a range using the parent_left/right tree lookup fields (when available), + or as an expanded [(left,in,child_ids)]""" + if left_model._parent_store and (not left_model.pool._init): + # TODO: Improve where joins are implemented for many with '.', replace by: + # doms += ['&',(prefix+'.parent_left','<',o.parent_right),(prefix+'.parent_left','>=',o.parent_left)] doms = [] - for o in table.browse(cr, uid, ids, context=context): + for o in left_model.browse(cr, uid, ids, context=context): if doms: doms.insert(0, OR_OPERATOR) doms += [AND_OPERATOR, ('parent_left', '<', o.parent_right), ('parent_left', '>=', o.parent_left)] if prefix: - return [(left, 'in', table.search(cr, uid, doms, context=context))] + return [(left, 'in', left_model.search(cr, uid, doms, context=context))] return doms else: - def rg(ids, table, parent): + def recursive_children(ids, model, parent_field): if not ids: return [] - ids2 = table.search(cr, uid, [(parent, 'in', ids)], context=context) - return ids + rg(ids2, table, parent) - return [(left, 'in', rg(ids, table, parent or table._parent_name))] - - def child_of_right_to_ids(value): - """ Normalize a single id, or a string, or a list of ids to a list of ids. + ids2 = model.search(cr, uid, [(parent_field, 'in', ids)], context=context) + return ids + recursive_children(ids2, model, parent_field) + return [(left, 'in', recursive_children(ids, left_model, parent or left_model._parent_name))] - This function is always used with _rec_get() above, so it should be - called directly from _rec_get instead of repeatedly before _rec_get. - - """ + def to_ids(value, field_obj): + """Normalize a single id or name, or a list of those, into a list of ids""" + names = [] if isinstance(value, basestring): - return [x[0] for x in field_obj.name_search(cr, uid, value, [], 'ilike', context=context, limit=None)] + names = [value] + if value and isinstance(value, (tuple, list)) and isinstance(value[0], basestring): + names = value + if names: + return flatten([[x[0] for x in field_obj.name_search(cr, uid, n, [], 'ilike', context=context, limit=None)] \ + for n in names]) elif isinstance(value, (int, long)): return [value] - else: - return list(value) - - self.__main_table = table - self.__all_tables.add(table) + return list(value) i = -1 while i + 1<len(self.__exp): i += 1 e = self.__exp[i] - if self._is_operator(e) or e == self.__DUMMY_LEAF: + if is_operator(e) or e == TRUE_LEAF or e == FALSE_LEAF: continue + + # check if the expression is valid + if not is_leaf(e): + raise ValueError("Invalid term %r in domain expression %r" % (e, exp)) + + # normalize the leaf's operator + e = normalize_leaf(*e) + self.__exp[i] = e left, operator, right = e - operator = operator.lower() - working_table = table - main_table = table - fargs = left.split('.', 1) - if fargs[0] in table._inherit_fields: + + working_table = table # The table containing the field (the name provided in the left operand) + field_path = left.split('.', 1) + + # If the field is _inherits'd, search for the working_table, + # and extract the field. + if field_path[0] in table._inherit_fields: while True: - field = main_table._columns.get(fargs[0], False) + field = working_table._columns.get(field_path[0]) if field: - working_table = main_table self.__field_tables[i] = working_table break - working_table = main_table.pool.get(main_table._inherit_fields[fargs[0]][0]) - if working_table not in self.__all_tables: - self.__joins.append('%s.%s=%s.%s' % (working_table._table, 'id', main_table._table, main_table._inherits[working_table._name])) - self.__all_tables.add(working_table) - main_table = working_table + next_table = working_table.pool.get(working_table._inherit_fields[field_path[0]][0]) + if next_table not in self.__all_tables: + self.__joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name])) + self.__all_tables.add(next_table) + working_table = next_table + # Or (try to) directly extract the field. + else: + field = working_table._columns.get(field_path[0]) - field = working_table._columns.get(fargs[0], False) if not field: if left == 'id' and operator == 'child_of': - ids2 = child_of_right_to_ids(right) - dom = _rec_get(ids2, working_table) + ids2 = to_ids(right, table) + dom = child_of_domain(left, ids2, working_table) self.__exp = self.__exp[:i] + dom + self.__exp[i+1:] + else: + # field could not be found in model columns, it's probably invalid, unless + # it's one of the _log_access special fields + # TODO: make these fields explicitly available in self.columns instead! + if field_path[0] not in MAGIC_COLUMNS: + raise ValueError("Invalid field %r in domain expression %r" % (left, exp)) continue field_obj = table.pool.get(field._obj) - if len(fargs) > 1: + if len(field_path) > 1: if field._type == 'many2one': - right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context) - if right == []: - self.__exp[i] = ( 'id', '=', 0 ) - else: - self.__exp[i] = (fargs[0], 'in', right) + right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context) + self.__exp[i] = (field_path[0], 'in', right) # Making search easier when there is a left operand as field.o2m or field.m2m - if field._type in ['many2many','one2many']: - right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context) - right1 = table.search(cr, uid, [(fargs[0],'in', right)], context=context) - if right1 == []: - self.__exp[i] = ( 'id', '=', 0 ) - else: - self.__exp[i] = ('id', 'in', right1) + if field._type in ['many2many', 'one2many']: + right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context) + right1 = table.search(cr, uid, [(field_path[0], 'in', right)], context=context) + self.__exp[i] = ('id', 'in', right1) - if not isinstance(field,fields.property): + if not isinstance(field, fields.property): continue if field._properties and not field.store: @@ -249,16 +473,16 @@ class expression(object): if not field._fnct_search: # the function field doesn't provide a search function and doesn't store # values in the database, so we must ignore it : we generate a dummy leaf - self.__exp[i] = self.__DUMMY_LEAF + self.__exp[i] = TRUE_LEAF else: subexp = field.search(cr, uid, table, left, [self.__exp[i]], context=context) if not subexp: - self.__exp[i] = self.__DUMMY_LEAF + self.__exp[i] = TRUE_LEAF else: # we assume that the expression is valid # we create a dummy leaf for forcing the parsing of the resulting expression self.__exp[i] = AND_OPERATOR - self.__exp.insert(i + 1, self.__DUMMY_LEAF) + self.__exp.insert(i + 1, TRUE_LEAF) for j, se in enumerate(subexp): self.__exp.insert(i + 2 + j, se) # else, the value of the field is store in the database, so we search on it @@ -266,11 +490,11 @@ class expression(object): elif field._type == 'one2many': # Applying recursivity on field(one2many) if operator == 'child_of': - ids2 = child_of_right_to_ids(right) + ids2 = to_ids(right, field_obj) if field._obj != working_table._name: - dom = _rec_get(ids2, field_obj, left=left, prefix=field._obj) + dom = child_of_domain(left, ids2, field_obj, prefix=field._obj) else: - dom = _rec_get(ids2, working_table, parent=left) + dom = child_of_domain('id', ids2, working_table, parent=left) self.__exp = self.__exp[:i] + dom + self.__exp[i+1:] else: @@ -282,7 +506,7 @@ class expression(object): if ids2: operator = 'in' else: - if not isinstance(right,list): + if not isinstance(right, list): ids2 = [right] else: ids2 = right @@ -290,22 +514,16 @@ class expression(object): if operator in ['like','ilike','in','=']: #no result found with given search criteria call_null = False - self.__exp[i] = ('id','=',0) - else: - call_null = True - operator = 'in' # operator changed because ids are directly related to main object + self.__exp[i] = FALSE_LEAF else: - call_null = False - o2m_op = 'in' - if operator in ['not like','not ilike','not in','<>','!=']: - o2m_op = 'not in' - self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', ids2, operator, field._type)) + ids2 = select_from_where(cr, field._fields_id, field_obj._table, 'id', ids2, operator) + if ids2: + call_null = False + self.__exp[i] = ('id', 'in', ids2) if call_null: - o2m_op = 'not in' - if operator in ['not like','not ilike','not in','<>','!=']: - o2m_op = 'in' - self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', [], operator, field._type) or [0]) + o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in' + self.__exp[i] = ('id', o2m_op, select_distinct_from_where_not_null(cr, field._fields_id, field_obj._table)) elif field._type == 'many2many': #FIXME @@ -313,10 +531,10 @@ class expression(object): def _rec_convert(ids): if field_obj == table: return ids - return self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, ids, operator, field._type) + return select_from_where(cr, field._id1, field._rel, field._id2, ids, operator) - ids2 = child_of_right_to_ids(right) - dom = _rec_get(ids2, field_obj) + ids2 = to_ids(right, field_obj) + dom = child_of_domain('id', ids2, field_obj) ids2 = field_obj.search(cr, uid, dom, context=context) self.__exp[i] = ('id', 'in', _rec_convert(ids2)) else: @@ -335,34 +553,28 @@ class expression(object): if operator in ['like','ilike','in','=']: #no result found with given search criteria call_null_m2m = False - self.__exp[i] = ('id','=',0) + self.__exp[i] = FALSE_LEAF else: - call_null_m2m = True operator = 'in' # operator changed because ids are directly related to main object else: call_null_m2m = False - m2m_op = 'in' - if operator in ['not like','not ilike','not in','<>','!=']: - m2m_op = 'not in' + m2m_op = 'not in' if operator in NEGATIVE_TERM_OPERATORS else 'in' + self.__exp[i] = ('id', m2m_op, select_from_where(cr, field._id1, field._rel, field._id2, res_ids, operator) or [0]) - self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, res_ids, operator, field._type) or [0]) if call_null_m2m: - m2m_op = 'not in' - if operator in ['not like','not ilike','not in','<>','!=']: - m2m_op = 'in' - self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, [], operator, field._type) or [0]) + m2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in' + self.__exp[i] = ('id', m2m_op, select_distinct_from_where_not_null(cr, field._id1, field._rel)) elif field._type == 'many2one': if operator == 'child_of': - ids2 = child_of_right_to_ids(right) - self.__operator = 'in' + ids2 = to_ids(right, field_obj) if field._obj != working_table._name: - dom = _rec_get(ids2, field_obj, left=left, prefix=field._obj) + dom = child_of_domain(left, ids2, field_obj, prefix=field._obj) else: - dom = _rec_get(ids2, working_table, parent=left) + dom = child_of_domain('id', ids2, working_table, parent=left) self.__exp = self.__exp[:i] + dom + self.__exp[i+1:] else: - def _get_expression(field_obj,cr, uid, left, right, operator, context=None): + def _get_expression(field_obj, cr, uid, left, right, operator, context=None): if context is None: context = {} c = context.copy() @@ -370,46 +582,35 @@ class expression(object): #Special treatment to ill-formed domains operator = ( operator in ['<','>','<=','>='] ) and 'in' or operator - dict_op = {'not in':'!=','in':'=','=':'in','!=':'not in','<>':'not in'} - if isinstance(right,tuple): + dict_op = {'not in':'!=','in':'=','=':'in','!=':'not in'} + if isinstance(right, tuple): right = list(right) - if (not isinstance(right,list)) and operator in ['not in','in']: + if (not isinstance(right, list)) and operator in ['not in','in']: operator = dict_op[operator] - elif isinstance(right,list) and operator in ['<>','!=','=']: #for domain (FIELD,'=',['value1','value2']) + elif isinstance(right, list) and operator in ['!=','=']: #for domain (FIELD,'=',['value1','value2']) operator = dict_op[operator] - res_ids = field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c) - if not res_ids: - return ('id','=',0) - else: - right = map(lambda x: x[0], res_ids) - return (left, 'in', right) + res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c)] + if operator in NEGATIVE_TERM_OPERATORS: + res_ids.append(False) # TODO this should not be appended if False was in 'right' + return (left, 'in', res_ids) m2o_str = False if right: if isinstance(right, basestring): # and not isinstance(field, fields.related): m2o_str = True - elif isinstance(right,(list,tuple)): + elif isinstance(right, (list, tuple)): m2o_str = True for ele in right: if not isinstance(ele, basestring): m2o_str = False break + if m2o_str: + self.__exp[i] = _get_expression(field_obj, cr, uid, left, right, operator, context=context) elif right == []: - m2o_str = False - if operator in ('not in', '!=', '<>'): - # (many2one not in []) should return all records - self.__exp[i] = self.__DUMMY_LEAF - else: - self.__exp[i] = ('id','=',0) - else: - new_op = '=' - if operator in ['not like','not ilike','not in','<>','!=']: - new_op = '!=' - #Is it ok to put 'left' and not 'id' ? - self.__exp[i] = (left,new_op,False) - - if m2o_str: - self.__exp[i] = _get_expression(field_obj,cr, uid, left, right, operator, context=context) + pass # Handled by __leaf_to_sql(). + else: # right is False + pass # Handled by __leaf_to_sql(). + else: # other field type # add the time part to datetime field when it's not there: @@ -425,127 +626,160 @@ class expression(object): self.__exp[i] = tuple(self.__exp[i]) if field.translate: - if operator in ('like', 'ilike', 'not like', 'not ilike'): + need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike') + sql_operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator) + if need_wildcard: right = '%%%s%%' % right - operator = operator == '=like' and 'like' or operator - - query1 = '( SELECT res_id' \ + subselect = '( SELECT res_id' \ ' FROM ir_translation' \ ' WHERE name = %s' \ ' AND lang = %s' \ ' AND type = %s' instr = ' %s' #Covering in,not in operators with operands (%s,%s) ,etc. - if operator in ['in','not in']: + if sql_operator in ['in','not in']: instr = ','.join(['%s'] * len(right)) - query1 += ' AND value ' + operator + ' ' +" (" + instr + ")" \ + subselect += ' AND value ' + sql_operator + ' ' +" (" + instr + ")" \ ') UNION (' \ ' SELECT id' \ ' FROM "' + working_table._table + '"' \ - ' WHERE "' + left + '" ' + operator + ' ' +" (" + instr + "))" + ' WHERE "' + left + '" ' + sql_operator + ' ' +" (" + instr + "))" else: - query1 += ' AND value ' + operator + instr + \ + subselect += ' AND value ' + sql_operator + instr + \ ') UNION (' \ ' SELECT id' \ ' FROM "' + working_table._table + '"' \ - ' WHERE "' + left + '" ' + operator + instr + ")" + ' WHERE "' + left + '" ' + sql_operator + instr + ")" - query2 = [working_table._name + ',' + left, + params = [working_table._name + ',' + left, context.get('lang', False) or 'en_US', 'model', right, right, ] - self.__exp[i] = ('id', 'inselect', (query1, query2)) - return self + self.__exp[i] = ('id', 'inselect', (subselect, params)) def __leaf_to_sql(self, leaf, table): - if leaf == self.__DUMMY_LEAF: - return ('(1=1)', []) left, operator, right = leaf - if operator == 'inselect': - query = '(%s.%s in (%s))' % (table._table, left, right[0]) + # final sanity checks - should never fail + assert operator in (TERM_OPERATORS + ('inselect',)), \ + "Invalid operator %r in domain term %r" % (operator, leaf) + assert leaf in (TRUE_LEAF, FALSE_LEAF) or left in table._all_columns \ + or left in MAGIC_COLUMNS, "Invalid field %r in domain term %r" % (left, leaf) + + if leaf == TRUE_LEAF: + query = 'TRUE' + params = [] + + elif leaf == FALSE_LEAF: + query = 'FALSE' + params = [] + + elif operator == 'inselect': + query = '(%s."%s" in (%s))' % (table._table, left, right[0]) params = right[1] + elif operator in ['in', 'not in']: - params = right and right[:] or [] - len_before = len(params) - for i in range(len_before)[::-1]: - if params[i] == False: - del params[i] - - len_after = len(params) - check_nulls = len_after != len_before - query = '(1=0)' - - if len_after: - if left == 'id': - instr = ','.join(['%s'] * len_after) - else: - instr = ','.join([table._columns[left]._symbol_set[0]] * len_after) - query = '(%s.%s %s (%s))' % (table._table, left, operator, instr) - else: - # the case for [field, 'in', []] or [left, 'not in', []] + # Two cases: right is a boolean or a list. The boolean case is an + # abuse and handled for backward compatibility. + if isinstance(right, bool): + _logger.warning("The domain term '%s' should use the '=' or '!=' operator." % (leaf,)) if operator == 'in': - query = '(%s.%s IS NULL)' % (table._table, left) + r = 'NOT NULL' if right else 'NULL' else: - query = '(%s.%s IS NOT NULL)' % (table._table, left) - if check_nulls: - query = '(%s OR %s.%s IS NULL)' % (query, table._table, left) - else: + r = 'NULL' if right else 'NOT NULL' + query = '(%s."%s" IS %s)' % (table._table, left, r) + params = [] + elif isinstance(right, (list, tuple)): + params = right[:] + check_nulls = False + for i in range(len(params))[::-1]: + if params[i] == False: + check_nulls = True + del params[i] + + if params: + if left == 'id': + instr = ','.join(['%s'] * len(params)) + else: + instr = ','.join([table._columns[left]._symbol_set[0]] * len(params)) + query = '(%s."%s" %s (%s))' % (table._table, left, operator, instr) + else: + # The case for (left, 'in', []) or (left, 'not in', []). + query = 'FALSE' if operator == 'in' else 'TRUE' + + if check_nulls and operator == 'in': + query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left) + elif not check_nulls and operator == 'not in': + query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left) + elif check_nulls and operator == 'not in': + query = '(%s AND %s."%s" IS NOT NULL)' % (query, table._table, left) # needed only for TRUE. + else: # Must not happen + raise ValueError("Invalid domain term %r" % (leaf,)) + + elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '='): + query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left, table._table, left) params = [] - if right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator == '='): - query = '(%s.%s IS NULL or %s.%s = false )' % (table._table, left,table._table, left) - elif (((right == False) and (type(right)==bool)) or (right is None)) and (operator == '='): - query = '%s.%s IS NULL ' % (table._table, left) - elif right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator in ['<>', '!=']): - query = '(%s.%s IS NOT NULL and %s.%s != false)' % (table._table, left,table._table, left) - elif (((right == False) and (type(right)==bool)) or right is None) and (operator in ['<>', '!=']): - query = '%s.%s IS NOT NULL' % (table._table, left) - elif (operator == '=?'): - op = '=' - if (right is False or right is None): - return ( 'TRUE',[]) - if left in table._columns: - format = table._columns[left]._symbol_set[0] - query = '(%s.%s %s %s)' % (table._table, left, op, format) - params = table._columns[left]._symbol_set[1](right) - else: - query = "(%s.%s %s '%%s')" % (table._table, left, op) - params = right + elif (right is False or right is None) and (operator == '='): + query = '%s."%s" IS NULL ' % (table._table, left) + params = [] + elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '!='): + query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table._table, left, table._table, left) + params = [] + + elif (right is False or right is None) and (operator == '!='): + query = '%s."%s" IS NOT NULL' % (table._table, left) + params = [] + + elif (operator == '=?'): + if (right is False or right is None): + # '=?' is a short-circuit that makes the term TRUE if right is None or False + query = 'TRUE' + params = [] else: - if left == 'id': - query = '%s.id %s %%s' % (table._table, operator) + # '=?' behaves like '=' in other cases + query, params = self.__leaf_to_sql((left, '=', right), table) + + elif left == 'id': + query = '%s.id %s %%s' % (table._table, operator) + params = right + + else: + need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike') + sql_operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator) + + if left in table._columns: + format = need_wildcard and '%s' or table._columns[left]._symbol_set[0] + if self.has_unaccent and sql_operator in ('ilike', 'not ilike'): + query = '(unaccent(%s."%s") %s unaccent(%s))' % (table._table, left, sql_operator, format) + else: + query = '(%s."%s" %s %s)' % (table._table, left, sql_operator, format) + elif left in MAGIC_COLUMNS: + query = "(%s.\"%s\" %s %%s)" % (table._table, left, sql_operator) params = right + else: # Must not happen + raise ValueError("Invalid field %r in domain term %r" % (left, leaf)) + + add_null = False + if need_wildcard: + if isinstance(right, str): + str_utf8 = right + elif isinstance(right, unicode): + str_utf8 = right.encode('utf-8') else: - like = operator in ('like', 'ilike', 'not like', 'not ilike') - - op = {'=like':'like','=ilike':'ilike'}.get(operator,operator) - if left in table._columns: - format = like and '%s' or table._columns[left]._symbol_set[0] - query = '(%s.%s %s %s)' % (table._table, left, op, format) - else: - query = "(%s.%s %s '%s')" % (table._table, left, op, right) - - add_null = False - if like: - if isinstance(right, str): - str_utf8 = right - elif isinstance(right, unicode): - str_utf8 = right.encode('utf-8') - else: - str_utf8 = str(right) - params = '%%%s%%' % str_utf8 - add_null = not str_utf8 - elif left in table._columns: - params = table._columns[left]._symbol_set[1](right) + str_utf8 = str(right) + params = '%%%s%%' % str_utf8 + add_null = not str_utf8 + elif left in table._columns: + params = table._columns[left]._symbol_set[1](right) - if add_null: - query = '(%s OR %s IS NULL)' % (query, left) + if add_null: + query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left) if isinstance(params, basestring): params = [params] @@ -555,25 +789,26 @@ class expression(object): def to_sql(self): stack = [] params = [] + # Process the domain from right to left, using a stack, to generate a SQL expression. for i, e in reverse_enumerate(self.__exp): - if self._is_leaf(e, internal=True): + if is_leaf(e, internal=True): table = self.__field_tables.get(i, self.__main_table) q, p = self.__leaf_to_sql(e, table) params.insert(0, p) stack.append(q) + elif e == NOT_OPERATOR: + stack.append('(NOT (%s))' % (stack.pop(),)) else: - if e == NOT_OPERATOR: - stack.append('(NOT (%s))' % (stack.pop(),)) - else: - ops = {AND_OPERATOR: ' AND ', OR_OPERATOR: ' OR '} - q1 = stack.pop() - q2 = stack.pop() - stack.append('(%s %s %s)' % (q1, ops[e], q2,)) + ops = {AND_OPERATOR: ' AND ', OR_OPERATOR: ' OR '} + q1 = stack.pop() + q2 = stack.pop() + stack.append('(%s %s %s)' % (q1, ops[e], q2,)) - query = ' AND '.join(reversed(stack)) + assert len(stack) == 1 + query = stack[0] joins = ' AND '.join(self.__joins) if joins: - query = '(%s) AND (%s)' % (joins, query) + query = '(%s) AND %s' % (joins, query) return (query, flatten(params)) def get_tables(self): diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 7a8f460f5cb..9b437de86e4 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -55,7 +55,7 @@ def _symbol_set(symb): class _column(object): """ Base of all fields, a database column - + An instance of this object is a *description* of a database column. It will not hold any data, but only provide the methods to manipulate data of an ORM record or even prepare/update the database to hold such a field of data. @@ -72,7 +72,7 @@ class _column(object): _symbol_set = (_symbol_c, _symbol_f) _symbol_get = None - def __init__(self, string='unknown', required=False, readonly=False, domain=None, context=None, states=None, priority=0, change_default=False, size=None, ondelete="set null", translate=False, select=False, manual=False, **args): + def __init__(self, string='unknown', required=False, readonly=False, domain=None, context=None, states=None, priority=0, change_default=False, size=None, ondelete=None, translate=False, select=False, manual=False, **args): """ The 'manual' keyword argument specifies if the field is a custom one. @@ -91,7 +91,7 @@ class _column(object): self.help = args.get('help', '') self.priority = priority self.change_default = change_default - self.ondelete = ondelete + self.ondelete = ondelete.lower() if ondelete else None # defaults to 'set null' in ORM self.translate = translate self._domain = domain self._context = context @@ -112,12 +112,6 @@ class _column(object): def set(self, cr, obj, id, name, value, user=None, context=None): cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%s', (self._symbol_set[1](value), id)) - def set_memory(self, cr, obj, id, name, value, user=None, context=None): - raise Exception(_('Not implemented set_memory method !')) - - def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None): - raise Exception(_('Not implemented get_memory method !')) - def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): raise Exception(_('undefined get method !')) @@ -126,9 +120,6 @@ class _column(object): res = obj.read(cr, uid, ids, [name], context=context) return [x[name] for x in res] - def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, context=None): - raise Exception(_('Not implemented search_memory method !')) - # --------------------------------------------------------- # Simple fields @@ -269,7 +260,7 @@ class binary(_column): _column.__init__(self, string=string, **args) self.filters = filters - def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None): + def get(self, cr, obj, ids, name, user=None, context=None, values=None): if not context: context = {} if not values: @@ -293,9 +284,6 @@ class binary(_column): res[i] = val return res - get = get_memory - - class selection(_column): _type = 'selection' @@ -355,30 +343,6 @@ class many2one(_column): _column.__init__(self, string=string, **args) self._obj = obj - def set_memory(self, cr, obj, id, field, values, user=None, context=None): - obj.datas.setdefault(id, {}) - obj.datas[id][field] = values - - def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None): - result = {} - for id in ids: - result[id] = obj.datas[id].get(name, False) - - # build a dictionary of the form {'id_of_distant_resource': name_of_distant_resource} - # we use uid=1 because the visibility of a many2one field value (just id and name) - # must be the access right of the parent form and not the linked object itself. - obj = obj.pool.get(self._obj) - records = dict(obj.name_get(cr, 1, - list(set([x for x in result.values() if x and isinstance(x, (int,long))])), - context=context)) - for id in ids: - if result[id] in records: - result[id] = (result[id], records[result[id]]) - else: - result[id] = False - - return result - def get(self, cr, obj, ids, name, user=None, context=None, values=None): if context is None: context = {} @@ -447,55 +411,6 @@ class one2many(_column): #one2many can't be used as condition for defaults assert(self.change_default != True) - def get_memory(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): - if context is None: - context = {} - if self._context: - context = context.copy() - context.update(self._context) - if not values: - values = {} - res = {} - for id in ids: - res[id] = [] - ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id, 'in', ids)], limit=self._limit, context=context) - for r in obj.pool.get(self._obj).read(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'): - if r[self._fields_id] in res: - res[r[self._fields_id]].append(r['id']) - return res - - def set_memory(self, cr, obj, id, field, values, user=None, context=None): - if not context: - context = {} - if self._context: - context = context.copy() - context.update(self._context) - if not values: - return - obj = obj.pool.get(self._obj) - for act in values: - if act[0] == 0: - act[2][self._fields_id] = id - obj.create(cr, user, act[2], context=context) - elif act[0] == 1: - obj.write(cr, user, [act[1]], act[2], context=context) - elif act[0] == 2: - obj.unlink(cr, user, [act[1]], context=context) - elif act[0] == 3: - obj.datas[act[1]][self._fields_id] = False - elif act[0] == 4: - obj.datas[act[1]][self._fields_id] = id - elif act[0] == 5: - for o in obj.datas.values(): - if o[self._fields_id] == id: - o[self._fields_id] = False - elif act[0] == 6: - for id2 in (act[2] or []): - obj.datas[id2][self._fields_id] = id - - def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None): - raise _('Not Implemented') - def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): if context is None: context = {} @@ -578,14 +493,43 @@ class one2many(_column): # (6, ?, ids) set a list of links # class many2many(_column): + """Encapsulates the logic of a many-to-many bidirectional relationship, handling the + low-level details of the intermediary relationship table transparently. + A many-to-many relationship is always symmetrical, and can be declared and accessed + from either endpoint model. + If ``rel`` (relationship table name), ``id1`` (source foreign key column name) + or id2 (destination foreign key column name) are not specified, the system will + provide default values. This will by default only allow one single symmetrical + many-to-many relationship between the source and destination model. + For multiple many-to-many relationship between the same models and for + relationships where source and destination models are the same, ``rel``, ``id1`` + and ``id2`` should be specified explicitly. + + :param str obj: destination model + :param str rel: optional name of the intermediary relationship table. If not specified, + a canonical name will be derived based on the alphabetically-ordered + model names of the source and destination (in the form: ``amodel_bmodel_rel``). + Automatic naming is not possible when the source and destination are + the same, for obvious ambiguity reasons. + :param str id1: optional name for the column holding the foreign key to the current + model in the relationship table. If not specified, a canonical name + will be derived based on the model name (in the form: `src_model_id`). + :param str id2: optional name for the column holding the foreign key to the destination + model in the relationship table. If not specified, a canonical name + will be derived based on the model name (in the form: `dest_model_id`) + :param str string: field label + """ _classic_read = False _classic_write = False _prefetch = False _type = 'many2many' - def __init__(self, obj, rel, id1, id2, string='unknown', limit=None, **args): + + def __init__(self, obj, rel=None, id1=None, id2=None, string='unknown', limit=None, **args): + """ + """ _column.__init__(self, string=string, **args) self._obj = obj - if '.' in rel: + if rel and '.' in rel: raise Exception(_('The second argument of the many2many field %s must be a SQL table !'\ 'You used %s, which is not a valid SQL table name.')% (string,rel)) self._rel = rel @@ -593,7 +537,30 @@ class many2many(_column): self._id2 = id2 self._limit = limit - def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): + def _sql_names(self, source_model): + """Return the SQL names defining the structure of the m2m relationship table + + :return: (m2m_table, local_col, dest_col) where m2m_table is the table name, + local_col is the name of the column holding the current model's FK, and + dest_col is the name of the column holding the destination model's FK, and + """ + tbl, col1, col2 = self._rel, self._id1, self._id2 + if not all((tbl, col1, col2)): + # the default table name is based on the stable alphabetical order of tables + dest_model = source_model.pool.get(self._obj) + tables = tuple(sorted([source_model._table, dest_model._table])) + if not tbl: + assert tables[0] != tables[1], 'Implicit/Canonical naming of m2m relationship table '\ + 'is not possible when source and destination models are '\ + 'the same' + tbl = '%s_%s_rel' % tables + if not col1: + col1 = '%s_id' % source_model._table + if not col2: + col2 = '%s_id' % dest_model._table + return (tbl, col1, col2) + + def get(self, cr, model, ids, name, user=None, offset=0, context=None, values=None): if not context: context = {} if not values: @@ -606,7 +573,8 @@ class many2many(_column): if offset: warnings.warn("Specifying offset at a many2many.get() may produce unpredictable results.", DeprecationWarning, stacklevel=2) - obj = obj.pool.get(self._obj) + obj = model.pool.get(self._obj) + rel, id1, id2 = self._sql_names(model) # static domains are lists, and are evaluated both here and on client-side, while string # domains supposed by dynamic and evaluated on client-side only (thus ignored here) @@ -636,11 +604,11 @@ class many2many(_column): %(order_by)s \ %(limit)s \ OFFSET %(offset)d' \ - % {'rel': self._rel, + % {'rel': rel, 'from_c': from_c, 'tbl': obj._table, - 'id1': self._id1, - 'id2': self._id2, + 'id1': id1, + 'id2': id2, 'where_c': where_c, 'limit': limit_str, 'order_by': order_by, @@ -651,31 +619,32 @@ class many2many(_column): res[r[1]].append(r[0]) return res - def set(self, cr, obj, id, name, values, user=None, context=None): + def set(self, cr, model, id, name, values, user=None, context=None): if not context: context = {} if not values: return - obj = obj.pool.get(self._obj) + rel, id1, id2 = self._sql_names(model) + obj = model.pool.get(self._obj) for act in values: if not (isinstance(act, list) or isinstance(act, tuple)) or not act: continue if act[0] == 0: idnew = obj.create(cr, user, act[2], context=context) - cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, idnew)) + cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s,%s)', (id, idnew)) elif act[0] == 1: obj.write(cr, user, [act[1]], act[2], context=context) elif act[0] == 2: obj.unlink(cr, user, [act[1]], context=context) elif act[0] == 3: - cr.execute('delete from '+self._rel+' where ' + self._id1 + '=%s and '+ self._id2 + '=%s', (id, act[1])) + cr.execute('delete from '+rel+' where ' + id1 + '=%s and '+ id2 + '=%s', (id, act[1])) elif act[0] == 4: # following queries are in the same transaction - so should be relatively safe - cr.execute('SELECT 1 FROM '+self._rel+' WHERE '+self._id1+' = %s and '+self._id2+' = %s', (id, act[1])) + cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+' = %s and '+id2+' = %s', (id, act[1])) if not cr.fetchone(): - cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, act[1])) + cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s,%s)', (id, act[1])) elif act[0] == 5: - cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,)) + cr.execute('delete from '+rel+' where ' + id1 + ' = %s', (id,)) elif act[0] == 6: d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context) @@ -683,10 +652,10 @@ class many2many(_column): d1 = ' and ' + ' and '.join(d1) else: d1 = '' - cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2) + cr.execute('delete from '+rel+' where '+id1+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2) for act_nbr in act[2]: - cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s, %s)', (id, act_nbr)) + cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s, %s)', (id, act_nbr)) # # TODO: use a name_search @@ -694,32 +663,6 @@ class many2many(_column): def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None): return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name', operator, value)], offset, limit, context=context) - def get_memory(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None): - result = {} - for id in ids: - result[id] = obj.datas[id].get(name, []) - return result - - def set_memory(self, cr, obj, id, name, values, user=None, context=None): - if not values: - return - for act in values: - # TODO: use constants instead of these magic numbers - if act[0] == 0: - raise _('Not Implemented') - elif act[0] == 1: - raise _('Not Implemented') - elif act[0] == 2: - raise _('Not Implemented') - elif act[0] == 3: - raise _('Not Implemented') - elif act[0] == 4: - raise _('Not Implemented') - elif act[0] == 5: - raise _('Not Implemented') - elif act[0] == 6: - obj.datas[id][name] = act[2] - def get_nice_size(value): size = 0 @@ -801,8 +744,8 @@ class function(_column): Implements the function field. - :param orm_template model: model to which the field belongs (should be ``self`` for - a model method) + :param orm model: model to which the field belongs (should be ``self`` for + a model method) :param field_name(s): name of the field to compute, or if ``multi`` is provided, list of field names to compute. :type field_name(s): str | [str] @@ -865,8 +808,8 @@ class function(_column): Callable that implements the ``write`` operation for the function field. - :param orm_template model: model to which the field belongs (should be ``self`` for - a model method) + :param orm model: model to which the field belongs (should be ``self`` for + a model method) :param int id: the identifier of the object to write on :param str field_name: name of the field to set :param fnct_inv_arg: arbitrary value passed when declaring the function field @@ -887,10 +830,10 @@ class function(_column): a search criterion based on the function field into a new domain based only on columns that are stored in the database. - :param orm_template model: model to which the field belongs (should be ``self`` for - a model method) - :param orm_template model_again: same value as ``model`` (seriously! this is for backwards - compatibility) + :param orm model: model to which the field belongs (should be ``self`` for + a model method) + :param orm model_again: same value as ``model`` (seriously! this is for backwards + compatibility) :param str field_name: name of the field to search on :param list criterion: domain component specifying the search criterion on the field. :rtype: list @@ -935,7 +878,7 @@ class function(_column): corresponding records in the source model (whose field values need to be recomputed). - :param orm_template model: trigger_model + :param orm model: trigger_model :param list trigger_ids: ids of the records of trigger_model that were modified :rtype: list @@ -1064,14 +1007,11 @@ class function(_column): result[id] = self.postprocess(cr, uid, obj, name, result[id], context) return result - get_memory = get - def set(self, cr, obj, id, name, value, user=None, context=None): if not context: context = {} if self._fnct_inv: self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context) - set_memory = set # --------------------------------------------------------- # Related fields @@ -1295,7 +1235,7 @@ class property(function): def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None): prop = obj.pool.get('ir.property') - # get the default values (for res_id = False) for the property fields + # get the default values (for res_id = False) for the property fields default_val = self._get_defaults(obj, cr, uid, prop_names, context) # build the dictionary that will be returned @@ -1354,7 +1294,7 @@ class property(function): self.field_id = {} -def field_to_dict(self, cr, user, context, field): +def field_to_dict(model, cr, user, field, context=None): """ Return a dictionary representation of a field. The string, help, and selection attributes (if any) are untranslated. This @@ -1377,8 +1317,9 @@ def field_to_dict(self, cr, user, context, field): res['fnct_inv_arg'] = field._fnct_inv_arg or False res['func_obj'] = field._obj or False if isinstance(field, many2many): - res['related_columns'] = list((field._id1, field._id2)) - res['third_table'] = field._rel + (table, col1, col2) = field._sql_names(model) + res['related_columns'] = [col1, col2] + res['third_table'] = table for arg in ('string', 'readonly', 'states', 'size', 'required', 'group_operator', 'change_default', 'translate', 'help', 'select', 'selectable'): if getattr(field, arg): @@ -1397,7 +1338,7 @@ def field_to_dict(self, cr, user, context, field): res['selection'] = field.selection else: # call the 'dynamic selection' function - res['selection'] = field.selection(self, cr, user, context) + res['selection'] = field.selection(model, cr, user, context) if res['type'] in ('one2many', 'many2many', 'many2one', 'one2one'): res['relation'] = field._obj res['domain'] = field._domain @@ -1417,12 +1358,16 @@ class column_info(object): :attr parent_column: the name of the column containing the m2o relationship to the parent model that contains this column, None for local columns. + :attr original_parent: if the column is inherited, name of the original + parent model that contains it i.e in case of multilevel + inheritence, None for local columns. """ - def __init__(self, name, column, parent_model=None, parent_column=None): + def __init__(self, name, column, parent_model=None, parent_column=None, original_parent=None): self.name = name self.column = column self.parent_model = parent_model self.parent_column = parent_column + self.original_parent = original_parent # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index b87672c012d..7a9db5f50be 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -38,31 +38,32 @@ - classicals (varchar, integer, boolean, ...) - relations (one2many, many2one, many2many) - functions - + """ import calendar import copy import datetime import logging -import warnings import operator import pickle import re +import simplejson import time import traceback import types -import simplejson - -import openerp.netsvc as netsvc +import warnings from lxml import etree -from openerp.tools.config import config -from openerp.tools.translate import _ import fields -from query import Query +import openerp +import openerp.netsvc as netsvc import openerp.tools as tools +from openerp.tools.config import config from openerp.tools.safe_eval import safe_eval as eval +from openerp.tools.translate import _ +from openerp import SUPERUSER_ID +from query import Query # List of etree._Element subclasses that we choose to ignore when parsing XML. from openerp.tools import SKIPPED_ELEMENT_TYPES @@ -70,9 +71,6 @@ from openerp.tools import SKIPPED_ELEMENT_TYPES regex_order = re.compile('^(([a-z0-9_]+|"[a-z0-9_]+")( *desc| *asc)?( *, *|))+$', re.I) regex_object_name = re.compile(r'^[a-z0-9_.]+$') -# Super-user identifier (aka Administrator aka root) -ROOT_USER_ID = 1 - def transfer_field_to_modifiers(field, modifiers): default_values = {} state_exceptions = {} @@ -165,7 +163,7 @@ def modifiers_tests(): test_modifiers({}, '{}') test_modifiers({"invisible": True}, '{"invisible": true}') test_modifiers({"invisible": False}, '{}') - + def check_object_name(name): """ Check if the given name is a valid openerp object name. @@ -212,6 +210,19 @@ def last_day_of_current_month(): def intersect(la, lb): return filter(lambda x: x in lb, la) +def fix_import_export_id_paths(fieldname): + """ + Fixes the id fields in import and exports, and splits field paths + on '/'. + + :param str fieldname: name of the field to import/export + :return: split field name + :rtype: list of str + """ + fixed_db_id = re.sub(r'([^/])\.id', r'\1/.id', fieldname) + fixed_external_id = re.sub(r'([^/]):id', r'\1/id', fixed_db_id) + return fixed_external_id.split('/') + class except_orm(Exception): def __init__(self, name, value): self.name = name @@ -252,7 +263,7 @@ class browse_null(object): # class browse_record_list(list): """ Collection of browse objects - + Such an instance will be returned when doing a ``browse([ids..])`` and will be iterable, yielding browse() objects """ @@ -267,9 +278,9 @@ class browse_record_list(list): class browse_record(object): """ An object that behaves like a row of an object's table. It has attributes after the columns of the corresponding object. - + Examples:: - + uobj = pool.get('res.users') user_rec = uobj.browse(cr, uid, 104) name = user_rec.name @@ -326,9 +337,12 @@ class browse_record(object): col = self._table._inherit_fields[name][2] elif hasattr(self._table, str(name)): attr = getattr(self._table, name) - if isinstance(attr, (types.MethodType, types.LambdaType, types.FunctionType)): - return lambda *args, **argv: attr(self._cr, self._uid, [self._id], *args, **argv) + def function_proxy(*args, **kwargs): + if 'context' not in kwargs and self._context: + kwargs.update(context=self._context) + return attr(self._cr, self._uid, [self._id], *args, **kwargs) + return function_proxy else: return attr else: @@ -475,6 +489,16 @@ class browse_record(object): __repr__ = __str__ + def refresh(self): + """Force refreshing this browse_record's data and all the data of the + records that belong to the same cache, by emptying the cache completely, + preserving only the record identifiers (for prefetching optimizations). + """ + for model, model_cache in self._cache.iteritems(): + # only preserve the ids of the records that were in the cache + cached_ids = dict([(i, {'id': i}) for i in model_cache.keys()]) + self._cache[model].clear() + self._cache[model].update(cached_ids) def get_pg_type(f): """ @@ -559,22 +583,36 @@ class MetaModel(type): self.module_to_models.setdefault(self._module, []).append(self) -class orm_template(object): +# Definition of log access columns, automatically added to models if +# self._log_access is True +LOG_ACCESS_COLUMNS = { + 'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL', + 'create_date': 'TIMESTAMP', + 'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL', + 'write_date': 'TIMESTAMP' +} +# special columns automatically created by the ORM +MAGIC_COLUMNS = ['id'] + LOG_ACCESS_COLUMNS.keys() + +class BaseModel(object): """ Base class for OpenERP models. - OpenERP models are created by inheriting from this class (although - not directly; more specifically by inheriting from osv or - osv_memory). The constructor is called once, usually directly - after the class definition, e.g.: + OpenERP models are created by inheriting from this class' subclasses: - class user(osv): - ... - user() + * Model: for regular database-persisted models + * TransientModel: for temporary data, stored in the database but automatically + vaccuumed every so often + * AbstractModel: for abstract super classes meant to be shared by multiple + _inheriting classes (usually Models or TransientModels) - The system will later instanciate the class once per database (on + The system will later instantiate the class once per database (on which the class' module is installed). + To create a class that should not be instantiated, the _register class attribute + may be set to False. """ + __metaclass__ = MetaModel + _register = False # Set to false if the model shouldn't be automatically discovered. _name = None _columns = {} _constraints = [] @@ -587,22 +625,42 @@ class orm_template(object): _order = 'id' _sequence = None _description = None + + # Transience + _transient = False # True in a TransientModel + _transient_max_count = None + _transient_max_hours = None + _transient_check_time = 20 + + # structure: + # { 'parent_model': 'm2o_field', ... } _inherits = {} - # Mapping from inherits'd field name to triple (m, r, f) - # where m is the model from which it is inherits'd, - # r is the (local) field towards m, - # and f is the _column object itself. + + # Mapping from inherits'd field name to triple (m, r, f, n) where m is the + # model from which it is inherits'd, r is the (local) field towards m, f + # is the _column object itself, and n is the original (i.e. top-most) + # parent model. + # Example: + # { 'field_name': ('parent_model', 'm2o_field_to_reach_parent', + # field_column_obj, origina_parent_model), ... } _inherit_fields = {} + # Mapping field name/column_info object # This is similar to _inherit_fields but: # 1. includes self fields, # 2. uses column_info instead of a triple. _all_columns = {} + _table = None _invalids = set() _log_create = False + _sql_constraints = [] + _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists'] + __logger = logging.getLogger('orm') + __schema = logging.getLogger('orm.schema') CONCURRENCY_CHECK_FIELD = '__last_update' + def log(self, cr, uid, id, message, secondary=False, context=None): if context and context.get('disable_log'): return True @@ -620,9 +678,6 @@ class orm_template(object): """Override this method to do specific things when a view on the object is opened.""" pass - def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False): - raise NotImplementedError(_('The read_group method is not implemented on this object !')) - def _field_create(self, cr, context=None): """ Create entries in ir_model_fields for all the model's fields. @@ -725,19 +780,12 @@ class orm_template(object): break cr.commit() - def _auto_init(self, cr, context=None): - raise_on_invalid_object_name(self._name) - self._field_create(cr, context=context) - - def _auto_end(self, cr, context=None): - pass - # # Goal: try to apply inheritance at the instanciation level and # put objects in the pool var # @classmethod - def makeInstance(cls, pool, cr, attributes): + def create_instance(cls, pool, cr): """ Instanciate a given model. This class method instanciates the class of some model (i.e. a class @@ -752,6 +800,9 @@ class orm_template(object): this method. This is probably unnecessary. """ + attributes = ['_columns', '_defaults', '_inherits', '_constraints', + '_sql_constraints'] + parent_names = getattr(cls, '_inherit', None) if parent_names: if isinstance(parent_names, (str, unicode)): @@ -770,7 +821,7 @@ class orm_template(object): 'You may need to add a dependency on the parent class\' module.' % (name, parent_name)) nattr = {} for s in attributes: - new = copy.copy(getattr(pool.get(parent_name), s)) + new = copy.copy(getattr(pool.get(parent_name), s, {})) if s == '_columns': # Don't _inherit custom fields. for c in new.keys(): @@ -807,7 +858,10 @@ class orm_template(object): This doesn't create an instance but simply register the model as being part of the module where it is defined. + """ + + # Set the module name (e.g. base, sale, accounting, ...) on the class. module = cls.__module__.split('.')[0] if not hasattr(cls, '_module'): @@ -824,7 +878,15 @@ class orm_template(object): return None def __init__(self, pool, cr): - """ Initialize a model and make it part of the given registry.""" + """ Initialize a model and make it part of the given registry. + + - copy the stored fields' functions in the osv_pool, + - update the _columns with the fields found in ir_model_fields, + - ensure there is a many2one for each _inherits'd parent, + - update the children's _columns, + - give a chance to each field to initialize itself. + + """ pool.add(self._name, self) self.pool = pool @@ -841,26 +903,93 @@ class orm_template(object): if not self._table: self._table = self._name.replace('.', '_') - def browse(self, cr, uid, select, context=None, list_class=None, fields_process=None): - """Fetch records as objects allowing to use dot notation to browse fields and relations + if not hasattr(self, '_log_access'): + # If _log_access is not specified, it is the same value as _auto. + self._log_access = getattr(self, "_auto", True) - :param cr: database cursor - :param user: current user id - :param select: id or list of ids. - :param context: context arguments, like lang, time zone - :rtype: object or list of objects requested + self._columns = self._columns.copy() + for store_field in self._columns: + f = self._columns[store_field] + if hasattr(f, 'digits_change'): + f.digits_change(cr) + def not_this_field(stored_func): + x, y, z, e, f, l = stored_func + return x != self._name or y != store_field + self.pool._store_function[self._name] = filter(not_this_field, self.pool._store_function.get(self._name, [])) + if not isinstance(f, fields.function): + continue + if not f.store: + continue + sm = f.store + if sm is True: + sm = {self._name: (lambda self, cr, uid, ids, c={}: ids, None, 10, None)} + for object, aa in sm.items(): + if len(aa) == 4: + (fnct, fields2, order, length) = aa + elif len(aa) == 3: + (fnct, fields2, order) = aa + length = None + else: + raise except_orm('Error', + ('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.' % (store_field, self._name))) + self.pool._store_function.setdefault(object, []) + self.pool._store_function[object].append((self._name, store_field, fnct, tuple(fields2) if fields2 else None, order, length)) + self.pool._store_function[object].sort(lambda x, y: cmp(x[4], y[4])) - """ - self._list_class = list_class or browse_record_list - cache = {} - # need to accepts ints and longs because ids coming from a method - # launched by button in the interface have a type long... - if isinstance(select, (int, long)): - return browse_record(cr, uid, select, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) - elif isinstance(select, list): - return self._list_class([browse_record(cr, uid, id, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) for id in select], context=context) - else: - return browse_null() + for (key, _, msg) in self._sql_constraints: + self.pool._sql_error[self._table+'_'+key] = msg + + # Load manual fields + + cr.execute("SELECT id FROM ir_model_fields WHERE name=%s AND model=%s", ('state', 'ir.model.fields')) + if cr.fetchone(): + cr.execute('SELECT * FROM ir_model_fields WHERE model=%s AND state=%s', (self._name, 'manual')) + for field in cr.dictfetchall(): + if field['name'] in self._columns: + continue + attrs = { + 'string': field['field_description'], + 'required': bool(field['required']), + 'readonly': bool(field['readonly']), + 'domain': eval(field['domain']) if field['domain'] else None, + 'size': field['size'], + 'ondelete': field['on_delete'], + 'translate': (field['translate']), + 'manual': True, + #'select': int(field['select_level']) + } + + if field['ttype'] == 'selection': + self._columns[field['name']] = fields.selection(eval(field['selection']), **attrs) + elif field['ttype'] == 'reference': + self._columns[field['name']] = fields.reference(selection=eval(field['selection']), **attrs) + elif field['ttype'] == 'many2one': + self._columns[field['name']] = fields.many2one(field['relation'], **attrs) + elif field['ttype'] == 'one2many': + self._columns[field['name']] = fields.one2many(field['relation'], field['relation_field'], **attrs) + elif field['ttype'] == 'many2many': + _rel1 = field['relation'].replace('.', '_') + _rel2 = field['model'].replace('.', '_') + _rel_name = 'x_%s_%s_%s_rel' % (_rel1, _rel2, field['name']) + self._columns[field['name']] = fields.many2many(field['relation'], _rel_name, 'id1', 'id2', **attrs) + else: + self._columns[field['name']] = getattr(fields, field['ttype'])(**attrs) + self._inherits_check() + self._inherits_reload() + if not self._sequence: + self._sequence = self._table + '_id_seq' + for k in self._defaults: + assert (k in self._columns) or (k in self._inherit_fields), 'Default function defined in %s but field %s does not exist !' % (self._name, k,) + for f in self._columns: + self._columns[f].restart() + + # Transience + if self.is_transient(): + self._transient_check_count = 0 + self._transient_max_count = config.get('osv_memory_count_limit') + self._transient_max_hours = config.get('osv_memory_age_limit') + assert self._log_access, "TransientModels must have log_access turned on, "\ + "in order to implement their access rights policy" def __export_row(self, cr, uid, row, fields, context=None): if context is None: @@ -872,7 +1001,7 @@ class orm_template(object): elif field_type == 'integer': return 0 elif field_type == 'boolean': - return False + return 'False' return '' def selection_field(in_field): @@ -905,7 +1034,18 @@ class orm_template(object): else: r = d['name'] else: - break + postfix = 0 + while True: + n = self._table+'_'+str(r['id']) + (postfix and ('_'+str(postfix)) or '' ) + if not model_data.search(cr, uid, [('name', '=', n)]): + break + postfix += 1 + model_data.create(cr, uid, { + 'name': n, + 'model': self._name, + 'res_id': r['id'], + }) + r = n else: r = r[f[i]] # To display external name of selection field when its exported @@ -984,11 +1124,7 @@ class orm_template(object): cols = self._columns.copy() for f in self._inherit_fields: cols.update({f: self._inherit_fields[f][2]}) - def fsplit(fieldname): - fixed_db_id = re.sub(r'([^/])\.id', r'\1/.id', fieldname) - fixed_external_id = re.sub(r'([^/]):id', r'\1/id', fixed_db_id) - return fixed_external_id.split('/') - fields_to_export = map(fsplit, fields_to_export) + fields_to_export = map(fix_import_export_id_paths, fields_to_export) datas = [] for row in self.browse(cr, uid, ids, context): datas += self.__export_row(cr, uid, row, fields_to_export, context) @@ -998,17 +1134,6 @@ class orm_template(object): """ Import given data in given module - :param cr: database cursor - :param uid: current user id - :param fields: list of fields - :param data: data to import - :param mode: 'init' or 'update' for record creation - :param current_module: module name - :param noupdate: flag for record creation - :param context: context arguments, like lang, time zone, - :param filename: optional file to store partial import state for recovery - :rtype: tuple - This method is used when importing data via client menu. Example of fields to import for a sale.order:: @@ -1021,13 +1146,26 @@ class orm_template(object): order_line/price_unit, order_line/product_uom_qty, order_line/product_uom/id (=xml_id) + + This method returns a 4-tuple with the following structure: + + * The first item is a return code, it returns either ``-1`` in case o + + :param cr: database cursor + :param uid: current user id + :param fields: list of fields + :param data: data to import + :param mode: 'init' or 'update' for record creation + :param current_module: module name + :param noupdate: flag for record creation + :param context: context arguments, like lang, time zone, + :param filename: optional file to store partial import state for recovery + :returns: 4-tuple of a return code, an errored resource, an error message and ??? + :rtype: (int, dict|0, str|0, ''|0) """ if not context: context = {} - def _replace_field(x): - x = re.sub('([a-z0-9A-Z_])\\.id$', '\\1/.id', x) - return x.replace(':id','/id').split('/') - fields = map(_replace_field, fields) + fields = map(fix_import_export_id_paths, fields) logger = netsvc.Logger() ir_model_data_obj = self.pool.get('ir.model.data') @@ -1089,7 +1227,7 @@ class orm_template(object): if line[i] and skip: return False continue - + #set the mode for m2o, o2m, m2m : xml_id/id/name if len(field) == len(prefix)+1: mode = False @@ -1102,7 +1240,7 @@ class orm_template(object): for db_id in line.split(config.get('csv_internal_sep')): res.append(_get_id(relation, db_id, current_module, mode)) return [(6,0,res)] - + # ID of the record using a XML ID if field[len(prefix)]=='id': try: @@ -1126,9 +1264,9 @@ class orm_template(object): relation_obj = self.pool.get(relation) newfd = relation_obj.fields_get( cr, uid, context=context ) pos = position - + res = many_ids(line[i], relation, current_module, mode) - + first = 0 while pos < len(datas): res2 = process_liness(self, datas, prefix + [field[len(prefix)]], current_module, relation_obj._name, newfd, pos, first) @@ -1138,15 +1276,15 @@ class orm_template(object): nbrmax = max(nbrmax, pos) warning += w2 first += 1 - + if data_res_id2: res.append((4, data_res_id2)) - + if (not newrow) or not reduce(lambda x, y: x or y, newrow.values(), 0): break res.append( (data_res_id2 and 1 or 0, data_res_id2 or 0, newrow) ) - + elif fields_def[field[len(prefix)]]['type']=='many2one': relation = fields_def[field[len(prefix)]]['relation'] @@ -1175,7 +1313,7 @@ class orm_template(object): else: res = line[i] - + row[field[len(prefix)]] = res or False result = (row, nbrmax, warning, data_res_id, xml_id) @@ -1189,7 +1327,7 @@ class orm_template(object): position = 0 while position<len(datas): res = {} - + (res, position, warning, res_id, xml_id) = \ process_liness(self, datas, [], current_module, self._name, fields_def, position=position) if len(warning): @@ -1201,7 +1339,7 @@ class orm_template(object): current_module, res, mode=mode, xml_id=xml_id, noupdate=noupdate, res_id=res_id, context=context) except Exception, e: - return (-1, res, 'Line ' + str(position) +' : ' + str(e), '') + return (-1, res, 'Line ' + str(position) + ' : ' + tools.ustr(e), '') if config.get('import_partial', False) and filename and (not (position%100)): data = pickle.load(file(config.get('import_partial'))) @@ -1215,30 +1353,6 @@ class orm_template(object): self._parent_store_compute(cr) return (position, 0, 0, 0) - def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): - """ - Read records with given ids with the given fields - - :param cr: database cursor - :param user: current user id - :param ids: id or list of the ids of the records to read - :param fields: optional list of field names to return (default: all fields would be returned) - :type fields: list (example ['field_name_1', ...]) - :param context: optional context dictionary - it may contains keys for specifying certain options - like ``context_lang``, ``context_tz`` to alter the results of the call. - A special ``bin_size`` boolean flag may also be passed in the context to request the - value of all fields.binary columns to be returned as the size of the binary instead of its - contents. This can also be selectively overriden by passing a field-specific flag - in the form ``bin_size_XXX: True/False`` where ``XXX`` is the name of the field. - Note: The ``bin_size_XXX`` form is new in OpenERP v6.0. - :return: list of dictionaries((dictionary per record asked)) with requested field values - :rtype: [{‘name_of_the_field’: value, ...}, ...] - :raise AccessError: * if user has no read rights on the requested object - * if user tries to bypass access rules for read on the requested object - - """ - raise NotImplementedError(_('The read method is not implemented on this object !')) - def get_invalid_fields(self, cr, uid): return list(self._invalids) @@ -1371,19 +1485,6 @@ class orm_template(object): defaults[key[8:]] = context[key] return defaults - - def perm_read(self, cr, user, ids, context=None, details=True): - raise NotImplementedError(_('The perm_read method is not implemented on this object !')) - - def unlink(self, cr, uid, ids, context=None): - raise NotImplementedError(_('The unlink method is not implemented on this object !')) - - def write(self, cr, user, ids, vals, context=None): - raise NotImplementedError(_('The write method is not implemented on this object !')) - - def create(self, cr, user, vals, context=None): - raise NotImplementedError(_('The create method is not implemented on this object !')) - def fields_get_keys(self, cr, user, context=None): res = self._columns.keys() # TODO I believe this loop can be replace by @@ -1392,56 +1493,6 @@ class orm_template(object): res.extend(self.pool.get(parent).fields_get_keys(cr, user, context)) return res - - def fields_get(self, cr, user, allfields=None, context=None, write_access=True): - """ Return the definition of each field. - - The returned value is a dictionary (indiced by field name) of - dictionaries. The _inherits'd fields are included. The string, - help, and selection (if present) attributes are translated. - - """ - if context is None: - context = {} - - res = {} - - translation_obj = self.pool.get('ir.translation') - for parent in self._inherits: - res.update(self.pool.get(parent).fields_get(cr, user, allfields, context)) - - for f, field in self._columns.iteritems(): - if allfields and f not in allfields: - continue - - res[f] = fields.field_to_dict(self, cr, user, context, field) - - if not write_access: - res[f]['readonly'] = True - res[f]['states'] = {} - - if 'string' in res[f]: - res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US') - if res_trans: - res[f]['string'] = res_trans - if 'help' in res[f]: - help_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'help', context.get('lang', False) or 'en_US') - if help_trans: - res[f]['help'] = help_trans - if 'selection' in res[f]: - if isinstance(field.selection, (tuple, list)): - sel = field.selection - sel2 = [] - for key, val in sel: - val2 = None - if val: - val2 = translation_obj._get_source(cr, user, self._name + ',' + f, 'selection', context.get('lang', False) or 'en_US', val) - sel2.append((key, val2 or val)) - res[f]['selection'] = sel2 - - return res - - # # Overload this method if you need a window title which depends on the context # @@ -1477,8 +1528,8 @@ class orm_template(object): """ Set invisible to true if the user is not in the specified groups. """ if node.get('groups'): groups = node.get('groups').split(',') - access_pool = self.pool.get('ir.model.access') - can_see = any(access_pool.check_groups(cr, user, group) for group in groups) + ir_model_access = self.pool.get('ir.model.access') + can_see = any(ir_model_access.check_groups(cr, user, group) for group in groups) if not can_see: node.set('invisible', '1') modifiers['invisible'] = True @@ -1556,7 +1607,7 @@ class orm_template(object): field = model_fields.get(node.get('name')) if field: transfer_field_to_modifiers(field, modifiers) - + elif node.tag in ('form', 'tree'): result = self.view_header_get(cr, user, False, node.tag, context) @@ -1887,22 +1938,20 @@ class orm_template(object): raise_view_error("Element '%s' not found in parent view '%%(parent_xml_id)s'" % tag, inherit_id) return source - def apply_view_inheritance(source, inherit_id): + def apply_view_inheritance(cr, user, source, inherit_id): """ Apply all the (directly and indirectly) inheriting views. :param source: a parent architecture to modify (with parent modifications already applied) - :param inherit_id: the database id of the parent view + :param inherit_id: the database view_id of the parent view :return: a modified source where all the modifying architecture are applied """ - # get all views which inherit from (ie modify) this view - cr.execute('select arch,id from ir_ui_view where inherit_id=%s and model=%s order by priority', (inherit_id, self._name)) - sql_inherit = cr.fetchall() - for (inherit, id) in sql_inherit: - source = apply_inheritance_specs(source, inherit, id) - source = apply_view_inheritance(source, id) + sql_inherit = self.pool.get('ir.ui.view').get_inheriting_views_arch(cr, user, inherit_id, self._name) + for (view_arch, view_id) in sql_inherit: + source = apply_inheritance_specs(source, view_arch, view_id) + source = apply_view_inheritance(cr, user, source, view_id) return source result = {'type': view_type, 'model': self._name} @@ -1945,7 +1994,7 @@ class orm_template(object): result['view_id'] = sql_res['id'] source = etree.fromstring(encode(sql_res['arch'])) - result['arch'] = apply_view_inheritance(source, result['view_id']) + result['arch'] = apply_view_inheritance(cr, user, source, result['view_id']) result['name'] = sql_res['name'] result['field_parent'] = sql_res['field_parent'] or False @@ -2017,8 +2066,9 @@ class orm_template(object): context) resprint = map(clean, resprint) resaction = map(clean, resaction) - resaction = filter(lambda x: not x.get('multi', False), resaction) - resprint = filter(lambda x: not x.get('multi', False), resprint) + if view_type != 'tree': + resaction = filter(lambda x: not x.get('multi'), resaction) + resprint = filter(lambda x: not x.get('multi'), resprint) resrelate = map(lambda x: x[2], resrelate) for x in resprint + resaction + resrelate: @@ -2085,31 +2135,16 @@ class orm_template(object): """ return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count) - def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): - """ - Private implementation of search() method, allowing specifying the uid to use for the access right check. - This is useful for example when filling in the selection list for a drop-down and avoiding access rights errors, - by specifying ``access_rights_uid=1`` to bypass access rights check, but not ir.rules! - - :param access_rights_uid: optional user ID to use when checking access rights - (not for ir.rules, this is only for ir.model.access) - """ - raise NotImplementedError(_('The search method is not implemented on this object !')) - def name_get(self, cr, user, ids, context=None): + """Returns the preferred display value (text representation) for the records with the + given ``ids``. By default this will be the value of the ``name`` column, unless + the model implements a custom behavior. + Can sometimes be seen as the inverse function of :meth:`~.name_search`, but it is not + guaranteed to be. + + :rtype: list(tuple) + :return: list of pairs ``(id,text_repr)`` for all records with the given ``ids``. """ - - :param cr: database cursor - :param user: current user id - :type user: integer - :param ids: list of ids - :param context: context arguments, like lang, time zone - :type context: dictionary - :return: tuples with the text representation of requested objects for to-many relationships - - """ - if not context: - context = {} if not ids: return [] if isinstance(ids, (int, long)): @@ -2118,38 +2153,39 @@ class orm_template(object): [self._rec_name], context, load='_classic_write')] def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100): - """ - Search for records and their display names according to a search domain. - - :param cr: database cursor - :param user: current user id - :param name: object name to search - :param args: list of tuples specifying search criteria [('field_name', 'operator', 'value'), ...] - :param operator: operator for search criterion - :param context: context arguments, like lang, time zone - :type context: dictionary - :param limit: optional max number of records to return - :return: list of object names matching the search criteria, used to provide completion for to-many relationships - - This method is equivalent of :py:meth:`~osv.osv.osv.search` on **name** + :py:meth:`~osv.osv.osv.name_get` on the result. - See :py:meth:`~osv.osv.osv.search` for an explanation of the possible values for the search domain specified in **args**. - + """Search for records that have a display name matching the given ``name`` pattern if compared + with the given ``operator``, while also matching the optional search domain (``args``). + This is used for example to provide suggestions based on a partial value for a relational + field. + Sometimes be seen as the inverse function of :meth:`~.name_get`, but it is not + guaranteed to be. + + This method is equivalent to calling :meth:`~.search` with a search domain based on ``name`` + and then :meth:`~.name_get` on the result of the search. + + :param list args: optional search domain (see :meth:`~.search` for syntax), + specifying further restrictions + :param str operator: domain operator for matching the ``name`` pattern, such as ``'like'`` + or ``'='``. + :param int limit: optional max number of records to return + :rtype: list + :return: list of pairs ``(id,text_repr)`` for all matching records. """ return self._name_search(cr, user, name, args, operator, context, limit) def name_create(self, cr, uid, name, context=None): - """ - Creates a new record by calling :py:meth:`~osv.osv.osv.create` with only one - value provided: the name of the new record (``_rec_name`` field). - The new record will also be initialized with any default values applicable - to this model, or provided through the context. The usual behavior of - :py:meth:`~osv.osv.osv.create` applies. - Similarly, this method may raise an exception if the model has multiple - required fields and some do not have default values. - - :param name: name of the record to create - - :return: the :py:meth:`~osv.osv.osv.name_get` value for the newly-created record. + """Creates a new record by calling :meth:`~.create` with only one + value provided: the name of the new record (``_rec_name`` field). + The new record will also be initialized with any default values applicable + to this model, or provided through the context. The usual behavior of + :meth:`~.create` applies. + Similarly, this method may raise an exception if the model has multiple + required fields and some do not have default values. + + :param name: name of the record to create + + :rtype: tuple + :return: the :meth:`~.name_get` pair value for the newly-created record. """ rec_id = self.create(cr, uid, {self._rec_name: name}, context); return self.name_get(cr, uid, [rec_id], context)[0] @@ -2169,16 +2205,10 @@ class orm_template(object): res = self.name_get(cr, access_rights_uid, ids, context) return res - def copy(self, cr, uid, id, default=None, context=None): - raise NotImplementedError(_('The copy method is not implemented on this object !')) - - def exists(self, cr, uid, id, context=None): - raise NotImplementedError(_('The exists method is not implemented on this object !')) - def read_string(self, cr, uid, id, langs, fields=None, context=None): res = {} res2 = {} - self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'read') + self.pool.get('ir.translation').check_read(cr, uid) if not fields: fields = self._columns.keys() + self._inherit_fields.keys() #FIXME: collect all calls to _get_source into one SQL call. @@ -2202,7 +2232,7 @@ class orm_template(object): return res def write_string(self, cr, uid, id, langs, vals, context=None): - self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'write') + self.pool.get('ir.translation').check_write(cr, uid) #FIXME: try to only call the translation in one SQL for lang in langs: for field in vals: @@ -2215,9 +2245,6 @@ class orm_template(object): self.pool.get(table).write_string(cr, uid, id, langs, vals, context) return True - def _check_removed_columns(self, cr, log=False): - raise NotImplementedError() - def _add_missing_default_values(self, cr, uid, values, context=None): missing_defaults = [] avoid_tables = [] # avoid overriding inherited values when parent is set @@ -2259,244 +2286,6 @@ class orm_template(object): except AttributeError: pass -class orm_memory(orm_template): - - _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists'] - _inherit_fields = {} - _max_count = None - _max_hours = None - _check_time = 20 - - @classmethod - def createInstance(cls, pool, cr): - return cls.makeInstance(pool, cr, ['_columns', '_defaults']) - - def __init__(self, pool, cr): - super(orm_memory, self).__init__(pool, cr) - self.datas = {} - self.next_id = 0 - self.check_id = 0 - self._max_count = config.get('osv_memory_count_limit') - self._max_hours = config.get('osv_memory_age_limit') - cr.execute('delete from wkf_instance where res_type=%s', (self._name,)) - - def _check_access(self, uid, object_id, mode): - if uid != 1 and self.datas[object_id]['internal.create_uid'] != uid: - raise except_orm(_('AccessError'), '%s access is only allowed on your own records for osv_memory objects except for the super-user' % mode.capitalize()) - - def vaccum(self, cr, uid, force=False): - """Run the vaccuum cleaning system, expiring and removing old records from the - virtual osv_memory tables if the "max count" or "max age" conditions are enabled - and have been reached. This method can be called very often (e.g. everytime a record - is created), but will only actually trigger the cleanup process once out of - "_check_time" times (by default once out of 20 calls).""" - self.check_id += 1 - if (not force) and (self.check_id % self._check_time): - return True - tounlink = [] - - # Age-based expiration - if self._max_hours: - max = time.time() - self._max_hours * 60 * 60 - for k,v in self.datas.iteritems(): - if v['internal.date_access'] < max: - tounlink.append(k) - self.unlink(cr, ROOT_USER_ID, tounlink) - - # Count-based expiration - if self._max_count and len(self.datas) > self._max_count: - # sort by access time to remove only the first/oldest ones in LRU fashion - records = self.datas.items() - records.sort(key=lambda x:x[1]['internal.date_access']) - self.unlink(cr, ROOT_USER_ID, [x[0] for x in records[:len(self.datas)-self._max_count]]) - - return True - - def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'): - if not context: - context = {} - if not fields_to_read: - fields_to_read = self._columns.keys() - result = [] - if self.datas: - ids_orig = ids - if isinstance(ids, (int, long)): - ids = [ids] - for id in ids: - r = {'id': id} - for f in fields_to_read: - record = self.datas.get(id) - if record: - self._check_access(user, id, 'read') - r[f] = record.get(f, False) - if r[f] and isinstance(self._columns[f], fields.binary) and context.get('bin_size', False): - r[f] = len(r[f]) - result.append(r) - if id in self.datas: - self.datas[id]['internal.date_access'] = time.time() - fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields_to_read) - for f in fields_post: - res2 = self._columns[f].get_memory(cr, self, ids, f, user, context=context, values=result) - for record in result: - record[f] = res2[record['id']] - if isinstance(ids_orig, (int, long)): - return result[0] - return result - - def write(self, cr, user, ids, vals, context=None): - if not ids: - return True - vals2 = {} - upd_todo = [] - for field in vals: - if self._columns[field]._classic_write: - vals2[field] = vals[field] - else: - upd_todo.append(field) - for object_id in ids: - self._check_access(user, object_id, mode='write') - self.datas[object_id].update(vals2) - self.datas[object_id]['internal.date_access'] = time.time() - for field in upd_todo: - self._columns[field].set_memory(cr, self, object_id, field, vals[field], user, context) - self._validate(cr, user, [object_id], context) - wf_service = netsvc.LocalService("workflow") - wf_service.trg_write(user, self._name, object_id, cr) - return object_id - - def create(self, cr, user, vals, context=None): - self.vaccum(cr, user) - self.next_id += 1 - id_new = self.next_id - - vals = self._add_missing_default_values(cr, user, vals, context) - - vals2 = {} - upd_todo = [] - for field in vals: - if self._columns[field]._classic_write: - vals2[field] = vals[field] - else: - upd_todo.append(field) - self.datas[id_new] = vals2 - self.datas[id_new]['internal.date_access'] = time.time() - self.datas[id_new]['internal.create_uid'] = user - - for field in upd_todo: - self._columns[field].set_memory(cr, self, id_new, field, vals[field], user, context) - self._validate(cr, user, [id_new], context) - if self._log_create and not (context and context.get('no_store_function', False)): - message = self._description + \ - " '" + \ - self.name_get(cr, user, [id_new], context=context)[0][1] + \ - "' "+ _("created.") - self.log(cr, user, id_new, message, True, context=context) - wf_service = netsvc.LocalService("workflow") - wf_service.trg_create(user, self._name, id_new, cr) - return id_new - - def _where_calc(self, cr, user, args, active_test=True, context=None): - if not context: - context = {} - args = args[:] - res = [] - # if the object has a field named 'active', filter out all inactive - # records unless they were explicitely asked for - if 'active' in self._columns and (active_test and context.get('active_test', True)): - if args: - active_in_args = False - for a in args: - if a[0] == 'active': - active_in_args = True - if not active_in_args: - args.insert(0, ('active', '=', 1)) - else: - args = [('active', '=', 1)] - if args: - import expression - e = expression.expression(args) - e.parse(cr, user, self, context) - res = e.exp - return res or [] - - def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): - if not context: - context = {} - - # implicit filter on current user except for superuser - if user != 1: - if not args: - args = [] - args.insert(0, ('internal.create_uid', '=', user)) - - result = self._where_calc(cr, user, args, context=context) - if result == []: - return self.datas.keys() - - res = [] - counter = 0 - #Find the value of dict - f = False - if result: - for id, data in self.datas.items(): - counter = counter + 1 - data['id'] = id - if limit and (counter > int(limit)): - break - f = True - for arg in result: - if arg[1] == '=': - val = eval('data[arg[0]]'+'==' +' arg[2]', locals()) - elif arg[1] in ['<', '>', 'in', 'not in', '<=', '>=', '<>']: - val = eval('data[arg[0]]'+arg[1] +' arg[2]', locals()) - elif arg[1] in ['ilike']: - val = (str(data[arg[0]]).find(str(arg[2]))!=-1) - - f = f and val - - if f: - res.append(id) - if count: - return len(res) - return res or [] - - def unlink(self, cr, uid, ids, context=None): - for id in ids: - self._check_access(uid, id, 'unlink') - self.datas.pop(id, None) - if len(ids): - cr.execute('delete from wkf_instance where res_type=%s and res_id IN %s', (self._name, tuple(ids))) - return True - - def perm_read(self, cr, user, ids, context=None, details=True): - result = [] - credentials = self.pool.get('res.users').name_get(cr, user, [user])[0] - create_date = time.strftime('%Y-%m-%d %H:%M:%S') - for id in ids: - self._check_access(user, id, 'read') - result.append({ - 'create_uid': credentials, - 'create_date': create_date, - 'write_uid': False, - 'write_date': False, - 'id': id, - 'xmlid' : False, - }) - return result - - def _check_removed_columns(self, cr, log=False): - # nothing to check in memory... - pass - - def exists(self, cr, uid, id, context=None): - return id in self.datas - -class orm(orm_template): - _sql_constraints = [] - _table = None - _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists'] - __logger = logging.getLogger('orm') - __schema = logging.getLogger('orm.schema') def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False): """ Get the list of records in list view grouped by the given ``groupby`` fields @@ -2524,7 +2313,7 @@ class orm(orm_template): """ context = context or {} - self.pool.get('ir.model.access').check(cr, uid, self._name, 'read') + self.check_read(cr, uid) if not fields: fields = self._columns.keys() @@ -2617,20 +2406,22 @@ class orm(orm_template): del d['id'] return data - def _inherits_join_add(self, parent_model_name, query): + def _inherits_join_add(self, current_table, parent_model_name, query): """ Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates) - + :param current_table: current model object :param parent_model_name: name of the parent model for which the clauses should be added :param query: query object on which the JOIN should be added """ - inherits_field = self._inherits[parent_model_name] + inherits_field = current_table._inherits[parent_model_name] parent_model = self.pool.get(parent_model_name) parent_table_name = parent_model._table quoted_parent_table_name = '"%s"' % parent_table_name if quoted_parent_table_name not in query.tables: query.tables.append(quoted_parent_table_name) - query.where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name)) + query.where_clause.append('(%s.%s = %s.id)' % (current_table._table, inherits_field, parent_table_name)) + + def _inherits_join_calc(self, field, query): """ @@ -2645,7 +2436,7 @@ class orm(orm_template): while field in current_table._inherit_fields and not field in current_table._columns: parent_model_name = current_table._inherit_fields[field][0] parent_table = self.pool.get(parent_model_name) - self._inherits_join_add(parent_model_name, query) + self._inherits_join_add(current_table, parent_model_name, query) current_table = parent_table return '"%s".%s' % (current_table._table, field) @@ -2686,7 +2477,7 @@ class orm(orm_template): while ids_lst: iids = ids_lst[:40] ids_lst = ids_lst[40:] - res = f.get(cr, self, iids, k, ROOT_USER_ID, {}) + res = f.get(cr, self, iids, k, SUPERUSER_ID, {}) for key, val in res.items(): if f._multi: val = val[k] @@ -2707,7 +2498,7 @@ class orm(orm_template): pass if not val_id: raise except_orm(_('ValidateError'), - _('Invalid value for reference field "%s" (last part must be a non-zero integer): "%s"') % (field, value)) + _('Invalid value for reference field "%s.%s" (last part must be a non-zero integer): "%s"') % (self._table, field, value)) val = val_model else: val = value @@ -2717,13 +2508,13 @@ class orm(orm_template): elif val in dict(self._columns[field].selection(self, cr, uid, context=context)): return raise except_orm(_('ValidateError'), - _('The value "%s" for the field "%s" is not in the selection') % (value, field)) + _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field)) def _check_removed_columns(self, cr, log=False): # iterate on the database columns to drop the NOT NULL constraints # of fields which were required but have been removed (or will be added by another module) columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)] - columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns + columns += MAGIC_COLUMNS cr.execute("SELECT a.attname, a.attnotnull" " FROM pg_class c, pg_attribute a" " WHERE c.relname=%s" @@ -2741,6 +2532,25 @@ class orm(orm_template): self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint", self._table, column['attname']) + # checked version: for direct m2o starting from `self` + def _m2o_add_foreign_key_checked(self, source_field, dest_model, ondelete): + assert self.is_transient() or not dest_model.is_transient(), \ + 'Many2One relationships from non-transient Model to TransientModel are forbidden' + if self.is_transient() and not dest_model.is_transient(): + # TransientModel relationships to regular Models are annoying + # usually because they could block deletion due to the FKs. + # So unless stated otherwise we default them to ondelete=cascade. + ondelete = ondelete or 'cascade' + self._foreign_keys.append((self._table, source_field, dest_model._table, ondelete or 'set null')) + self.__schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s", + self._table, source_field, dest_model._table, ondelete) + + # unchecked version: for custom cases, such as m2m relationships + def _m2o_add_foreign_key_unchecked(self, source_table, source_field, dest_model, ondelete): + self._foreign_keys.append((source_table, source_field, dest_model._table, ondelete or 'set null')) + self.__schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s", + source_table, source_field, dest_model._table, ondelete) + def _auto_init(self, cr, context=None): """ @@ -2790,7 +2600,7 @@ class orm(orm_template): column_data = self._select_column_data(cr) for k, f in self._columns.iteritems(): - if k in ('id', 'write_uid', 'write_date', 'create_uid', 'create_date'): + if k in MAGIC_COLUMNS: continue # Don't update custom (also called manual) fields if f.manual and not update_custom_fields: @@ -2883,7 +2693,7 @@ class orm(orm_template): cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k)) cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname)) cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1])) - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''"))) + cr.execute("COMMENT ON COLUMN %s.\"%s\" IS %%s" % (self._table, k), (f.string,)) self.__schema.debug("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !", self._table, k, f_pg_type, f._type, newname) @@ -2892,7 +2702,7 @@ class orm(orm_template): # set the field to the default value if any if k in self._defaults: if callable(self._defaults[k]): - default = self._defaults[k](self, cr, ROOT_USER_ID, context) + default = self._defaults[k](self, cr, SUPERUSER_ID, context) else: default = self._defaults[k] @@ -2939,7 +2749,8 @@ class orm(orm_template): self.__schema.debug(msg, self._table, k, f._type) if isinstance(f, fields.many2one): - ref = self.pool.get(f._obj)._table + dest_model = self.pool.get(f._obj) + ref = dest_model._table if ref != 'ir_actions': cr.execute('SELECT confdeltype, conname FROM pg_constraint as con, pg_class as cl1, pg_class as cl2, ' 'pg_attribute as att1, pg_attribute as att2 ' @@ -2958,9 +2769,9 @@ class orm(orm_template): "AND con.contype = 'f'", (self._table, ref, k, 'id')) res2 = cr.dictfetchall() if res2: - if res2[0]['confdeltype'] != POSTGRES_CONFDELTYPES.get(f.ondelete.upper(), 'a'): + if res2[0]['confdeltype'] != POSTGRES_CONFDELTYPES.get((f.ondelete or 'set null').upper(), 'a'): cr.execute('ALTER TABLE "' + self._table + '" DROP CONSTRAINT "' + res2[0]['conname'] + '"') - self._foreign_keys.append((self._table, k, ref, f.ondelete)) + self._m2o_add_foreign_key_checked(k, dest_model, f.ondelete) cr.commit() self.__schema.debug("Table '%s': column '%s': XXX", self._table, k) @@ -2970,14 +2781,14 @@ class orm(orm_template): if not isinstance(f, fields.function) or f.store: # add the missing field cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1])) - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''"))) + cr.execute("COMMENT ON COLUMN %s.\"%s\" IS %%s" % (self._table, k), (f.string,)) self.__schema.debug("Table '%s': added column '%s' with definition=%s", self._table, k, get_pg_type(f)[1]) # initialize it if not create and k in self._defaults: if callable(self._defaults[k]): - default = self._defaults[k](self, cr, ROOT_USER_ID, context) + default = self._defaults[k](self, cr, SUPERUSER_ID, context) else: default = self._defaults[k] @@ -2998,12 +2809,11 @@ class orm(orm_template): if isinstance(f, fields.many2one): if not self.pool.get(f._obj): raise except_orm('Programming Error', ('There is no reference available for %s') % (f._obj,)) - ref = self.pool.get(f._obj)._table + dest_model = self.pool.get(f._obj) + ref = dest_model._table # ir_actions is inherited so foreign key doesn't work on it if ref != 'ir_actions': - self._foreign_keys.append((self._table, k, ref, f.ondelete)) - self.__schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s", - self._table, k, ref, f.ondelete) + self._m2o_add_foreign_key_checked(k, dest_model, f.ondelete) if f.select: cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k)) if f.required: @@ -3053,7 +2863,7 @@ class orm(orm_template): def _create_table(self, cr): cr.execute('CREATE TABLE "%s" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITHOUT OIDS' % (self._table,)) - cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'", "''"))) + cr.execute(("COMMENT ON TABLE \"%s\" IS %%s" % self._table), (self._description,)) self.__schema.debug("Table '%s': created", self._table) @@ -3092,23 +2902,17 @@ class orm(orm_template): def _add_log_columns(self, cr): - logs = { - 'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL', - 'create_date': 'TIMESTAMP', - 'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL', - 'write_date': 'TIMESTAMP' - } - for k in logs: + for field, field_def in LOG_ACCESS_COLUMNS.iteritems(): cr.execute(""" SELECT c.relname FROM pg_class c, pg_attribute a WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid - """, (self._table, k)) + """, (self._table, field)) if not cr.rowcount: - cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k])) + cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, field, field_def)) cr.commit() self.__schema.debug("Table '%s': added column '%s' with definition=%s", - self._table, k, logs[k]) + self._table, field, field_def) def _select_column_data(self, cr): @@ -3131,20 +2935,28 @@ class orm(orm_template): def _m2m_raise_or_create_relation(self, cr, f): - cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (f._rel,)) + m2m_tbl, col1, col2 = f._sql_names(self) + cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (m2m_tbl,)) if not cr.dictfetchall(): if not self.pool.get(f._obj): - raise except_orm('Programming Error', ('There is no reference available for %s') % (f._obj,)) - ref = self.pool.get(f._obj)._table - cr.execute('CREATE TABLE "%s" ("%s" INTEGER NOT NULL, "%s" INTEGER NOT NULL, UNIQUE("%s","%s")) WITH OIDS' % (f._rel, f._id1, f._id2, f._id1, f._id2)) - self._foreign_keys.append((f._rel, f._id1, self._table, 'CASCADE')) - self._foreign_keys.append((f._rel, f._id2, ref, 'CASCADE')) - cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id1, f._rel, f._id1)) - cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (f._rel, f._id2, f._rel, f._id2)) - cr.execute("COMMENT ON TABLE \"%s\" IS 'RELATION BETWEEN %s AND %s'" % (f._rel, self._table, ref)) + raise except_orm('Programming Error', ('Many2Many destination model does not exist: `%s`') % (f._obj,)) + dest_model = self.pool.get(f._obj) + ref = dest_model._table + cr.execute('CREATE TABLE "%s" ("%s" INTEGER NOT NULL, "%s" INTEGER NOT NULL, UNIQUE("%s","%s")) WITH OIDS' % (m2m_tbl, col1, col2, col1, col2)) + + # create foreign key references with ondelete=cascade, unless the targets are SQL views + cr.execute("SELECT relkind FROM pg_class WHERE relkind IN ('v') AND relname=%s", (ref,)) + if not cr.fetchall(): + self._m2o_add_foreign_key_unchecked(m2m_tbl, col2, dest_model, 'cascade') + cr.execute("SELECT relkind FROM pg_class WHERE relkind IN ('v') AND relname=%s", (self._table,)) + if not cr.fetchall(): + self._m2o_add_foreign_key_unchecked(m2m_tbl, col1, self, 'cascade') + + cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (m2m_tbl, col1, m2m_tbl, col1)) + cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (m2m_tbl, col2, m2m_tbl, col2)) + cr.execute("COMMENT ON TABLE \"%s\" IS 'RELATION BETWEEN %s AND %s'" % (m2m_tbl, self._table, ref)) cr.commit() - self.__schema.debug("Create table '%s': relation between '%s' and '%s'", - f._rel, self._table, ref) + self.__schema.debug("Create table '%s': m2m relation between '%s' and '%s'", m2m_tbl, self._table, ref) def _add_sql_constraints(self, cr): @@ -3212,109 +3024,6 @@ class orm(orm_template): cr.execute(line2) cr.commit() - - @classmethod - def createInstance(cls, pool, cr): - return cls.makeInstance(pool, cr, ['_columns', '_defaults', - '_inherits', '_constraints', '_sql_constraints']) - - def __init__(self, pool, cr): - """ - - - copy the stored fields' functions in the osv_pool, - - update the _columns with the fields found in ir_model_fields, - - ensure there is a many2one for each _inherits'd parent, - - update the children's _columns, - - give a chance to each field to initialize itself. - - """ - super(orm, self).__init__(pool, cr) - - if not hasattr(self, '_log_access'): - # if not access is not specify, it is the same value as _auto - self._log_access = getattr(self, "_auto", True) - - self._columns = self._columns.copy() - for store_field in self._columns: - f = self._columns[store_field] - if hasattr(f, 'digits_change'): - f.digits_change(cr) - if not isinstance(f, fields.function): - continue - if not f.store: - continue - if self._columns[store_field].store is True: - sm = {self._name: (lambda self, cr, uid, ids, c={}: ids, None, 10, None)} - else: - sm = self._columns[store_field].store - for object, aa in sm.items(): - if len(aa) == 4: - (fnct, fields2, order, length) = aa - elif len(aa) == 3: - (fnct, fields2, order) = aa - length = None - else: - raise except_orm('Error', - ('Invalid function definition %s in object %s !\nYou must use the definition: store={object:(fnct, fields, priority, time length)}.' % (store_field, self._name))) - self.pool._store_function.setdefault(object, []) - ok = True - for x, y, z, e, f, l in self.pool._store_function[object]: - if (x==self._name) and (y==store_field) and (e==fields2): - if f == order: - ok = False - if ok: - self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order, length)) - self.pool._store_function[object].sort(lambda x, y: cmp(x[4], y[4])) - - for (key, _, msg) in self._sql_constraints: - self.pool._sql_error[self._table+'_'+key] = msg - - # Load manual fields - - cr.execute("SELECT id FROM ir_model_fields WHERE name=%s AND model=%s", ('state', 'ir.model.fields')) - if cr.fetchone(): - cr.execute('SELECT * FROM ir_model_fields WHERE model=%s AND state=%s', (self._name, 'manual')) - for field in cr.dictfetchall(): - if field['name'] in self._columns: - continue - attrs = { - 'string': field['field_description'], - 'required': bool(field['required']), - 'readonly': bool(field['readonly']), - 'domain': eval(field['domain']) if field['domain'] else None, - 'size': field['size'], - 'ondelete': field['on_delete'], - 'translate': (field['translate']), - 'manual': True, - #'select': int(field['select_level']) - } - - if field['ttype'] == 'selection': - self._columns[field['name']] = fields.selection(eval(field['selection']), **attrs) - elif field['ttype'] == 'reference': - self._columns[field['name']] = fields.reference(selection=eval(field['selection']), **attrs) - elif field['ttype'] == 'many2one': - self._columns[field['name']] = fields.many2one(field['relation'], **attrs) - elif field['ttype'] == 'one2many': - self._columns[field['name']] = fields.one2many(field['relation'], field['relation_field'], **attrs) - elif field['ttype'] == 'many2many': - _rel1 = field['relation'].replace('.', '_') - _rel2 = field['model'].replace('.', '_') - _rel_name = 'x_%s_%s_%s_rel' % (_rel1, _rel2, field['name']) - self._columns[field['name']] = fields.many2many(field['relation'], _rel_name, 'id1', 'id2', **attrs) - else: - self._columns[field['name']] = getattr(fields, field['ttype'])(**attrs) - self._inherits_check() - self._inherits_reload() - if not self._sequence: - self._sequence = self._table + '_id_seq' - for k in self._defaults: - assert (k in self._columns) or (k in self._inherit_fields), 'Default function defined in %s but field %s does not exist !' % (self._name, k,) - for f in self._columns: - self._columns[f].restart() - - __init__.__doc__ = orm_template.__init__.__doc__ + __init__.__doc__ - # # Update objects that uses this one to update their _inherits fields # @@ -3336,9 +3045,9 @@ class orm(orm_template): for table in self._inherits: other = self.pool.get(table) for col in other._columns.keys(): - res[col] = (table, self._inherits[table], other._columns[col]) + res[col] = (table, self._inherits[table], other._columns[col], table) for col in other._inherit_fields.keys(): - res[col] = (table, self._inherits[table], other._inherit_fields[col][2]) + res[col] = (table, self._inherits[table], other._inherit_fields[col][2], other._inherit_fields[col][3]) self._inherit_fields = res self._all_columns = self._get_column_infos() self._inherits_reload_src() @@ -3349,8 +3058,8 @@ class orm(orm_template): inherited field via _inherits) to a ``column_info`` struct giving detailed columns """ result = {} - for k, (parent, m2o, col) in self._inherit_fields.iteritems(): - result[k] = fields.column_info(k, col, parent, m2o) + for k, (parent, m2o, col, original_parent) in self._inherit_fields.iteritems(): + result[k] = fields.column_info(k, col, parent, m2o, original_parent) for k, col in self._columns.iteritems(): result[k] = fields.column_info(k, col) return result @@ -3393,9 +3102,12 @@ class orm(orm_template): # return _proxy - def fields_get(self, cr, user, fields=None, context=None): - """ - Get the description of list of fields + def fields_get(self, cr, user, allfields=None, context=None, write_access=True): + """ Return the definition of each field. + + The returned value is a dictionary (indiced by field name) of + dictionaries. The _inherits'd fields are included. The string, help, + and selection (if present) attributes are translated. :param cr: database cursor :param user: current user id @@ -3405,15 +3117,74 @@ class orm(orm_template): :raise AccessError: * if user has no create/write rights on the requested object """ - ira = self.pool.get('ir.model.access') - write_access = ira.check(cr, user, self._name, 'write', False) or \ - ira.check(cr, user, self._name, 'create', False) - return super(orm, self).fields_get(cr, user, fields, context, write_access) + if context is None: + context = {} + + write_access = self.check_write(cr, user, False) or \ + self.check_create(cr, user, False) + + res = {} + + translation_obj = self.pool.get('ir.translation') + for parent in self._inherits: + res.update(self.pool.get(parent).fields_get(cr, user, allfields, context)) + + for f, field in self._columns.iteritems(): + if allfields and f not in allfields: + continue + + res[f] = fields.field_to_dict(self, cr, user, field, context=context) + + if not write_access: + res[f]['readonly'] = True + res[f]['states'] = {} + + if 'string' in res[f]: + res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US') + if res_trans: + res[f]['string'] = res_trans + if 'help' in res[f]: + help_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'help', context.get('lang', False) or 'en_US') + if help_trans: + res[f]['help'] = help_trans + if 'selection' in res[f]: + if isinstance(field.selection, (tuple, list)): + sel = field.selection + sel2 = [] + for key, val in sel: + val2 = None + if val: + val2 = translation_obj._get_source(cr, user, self._name + ',' + f, 'selection', context.get('lang', False) or 'en_US', val) + sel2.append((key, val2 or val)) + res[f]['selection'] = sel2 + + return res def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): + """ Read records with given ids with the given fields + + :param cr: database cursor + :param user: current user id + :param ids: id or list of the ids of the records to read + :param fields: optional list of field names to return (default: all fields would be returned) + :type fields: list (example ['field_name_1', ...]) + :param context: optional context dictionary - it may contains keys for specifying certain options + like ``context_lang``, ``context_tz`` to alter the results of the call. + A special ``bin_size`` boolean flag may also be passed in the context to request the + value of all fields.binary columns to be returned as the size of the binary instead of its + contents. This can also be selectively overriden by passing a field-specific flag + in the form ``bin_size_XXX: True/False`` where ``XXX`` is the name of the field. + Note: The ``bin_size_XXX`` form is new in OpenERP v6.0. + :return: list of dictionaries((dictionary per record asked)) with requested field values + :rtype: [{‘name_of_the_field’: value, ...}, ...] + :raise AccessError: * if user has no read rights on the requested object + * if user tries to bypass access rules for read on the requested object + + """ + if not context: context = {} - self.pool.get('ir.model.access').check(cr, user, self._name, 'read') + self.check_read(cr, user) if not fields: fields = list(set(self._columns.keys() + self._inherit_fields.keys())) if isinstance(ids, (int, long)): @@ -3454,7 +3225,7 @@ class orm(orm_template): res = [] if len(fields_pre): def convert_field(f): - f_qual = "%s.%s" % (self._table, f) # need fully-qualified references in case len(tables) > 1 + f_qual = '%s."%s"' % (self._table, f) # need fully-qualified references in case len(tables) > 1 if f in ('create_date', 'write_date'): return "date_trunc('second', %s) as %s" % (f_qual, f) if f == self.CONCURRENCY_CHECK_FIELD: @@ -3587,6 +3358,7 @@ class orm(orm_template): vals[field] = False return res + # TODO check READ access def perm_read(self, cr, user, ids, context=None, details=True): """ Returns some metadata about the given records. @@ -3656,6 +3428,23 @@ class orm(orm_template): # mention the first one only to keep the error message readable raise except_orm('ConcurrencyException', _('A document was modified since you last viewed it (%s:%d)') % (self._description, res[0])) + def check_access_rights(self, cr, uid, operation, raise_exception=True): # no context on purpose. + """Verifies that the operation given by ``operation`` is allowed for the user + according to the access rights.""" + return self.pool.get('ir.model.access').check(cr, uid, self._name, operation, raise_exception) + + def check_create(self, cr, uid, raise_exception=True): + return self.check_access_rights(cr, uid, 'create', raise_exception) + + def check_read(self, cr, uid, raise_exception=True): + return self.check_access_rights(cr, uid, 'read', raise_exception) + + def check_unlink(self, cr, uid, raise_exception=True): + return self.check_access_rights(cr, uid, 'unlink', raise_exception) + + def check_write(self, cr, uid, raise_exception=True): + return self.check_access_rights(cr, uid, 'write', raise_exception) + def check_access_rule(self, cr, uid, ids, operation, context=None): """Verifies that the operation given by ``operation`` is allowed for the user according to ir.rules. @@ -3664,17 +3453,35 @@ class orm(orm_template): :raise except_orm: * if current ir.rules do not permit this operation. :return: None if the operation is allowed """ - where_clause, where_params, tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, operation, context=context) - if where_clause: - where_clause = ' and ' + ' and '.join(where_clause) - for sub_ids in cr.split_for_in_conditions(ids): - cr.execute('SELECT ' + self._table + '.id FROM ' + ','.join(tables) + - ' WHERE ' + self._table + '.id IN %s' + where_clause, - [sub_ids] + where_params) - if cr.rowcount != len(sub_ids): - raise except_orm(_('AccessError'), - _('Operation prohibited by access rules, or performed on an already deleted document (Operation: %s, Document type: %s).') - % (operation, self._description)) + if uid == SUPERUSER_ID: + return + + if self.is_transient: + # Only one single implicit access rule for transient models: owner only! + # This is ok to hardcode because we assert that TransientModels always + # have log_access enabled and this the create_uid column is always there. + # And even with _inherits, these fields are always present in the local + # table too, so no need for JOINs. + cr.execute("""SELECT distinct create_uid + FROM %s + WHERE id IN %%s""" % self._table, (tuple(ids),)) + uids = [x[0] for x in cr.fetchall()] + if len(uids) != 1 or uids[0] != uid: + raise except_orm(_('AccessError'), '%s access is ' + 'restricted to your own records for transient models ' + '(except for the super-user).' % operation.capitalize()) + else: + where_clause, where_params, tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, operation, context=context) + if where_clause: + where_clause = ' and ' + ' and '.join(where_clause) + for sub_ids in cr.split_for_in_conditions(ids): + cr.execute('SELECT ' + self._table + '.id FROM ' + ','.join(tables) + + ' WHERE ' + self._table + '.id IN %s' + where_clause, + [sub_ids] + where_params) + if cr.rowcount != len(sub_ids): + raise except_orm(_('AccessError'), + _('Operation prohibited by access rules, or performed on an already deleted document (Operation: %s, Document type: %s).') + % (operation, self._description)) def unlink(self, cr, uid, ids, context=None): """ @@ -3699,7 +3506,7 @@ class orm(orm_template): self._check_concurrency(cr, ids, context) - self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink') + self.check_unlink(cr, uid) properties = self.pool.get('ir.property') domain = [('res_id', '=', False), @@ -3725,10 +3532,10 @@ class orm(orm_template): # Note: following steps performed as admin to avoid access rights restrictions, and with no context # to avoid possible side-effects during admin calls. # Step 1. Calling unlink of ir_model_data only for the affected IDS - reference_ids = pool_model_data.search(cr, ROOT_USER_ID, [('res_id','in',list(sub_ids)),('model','=',self._name)]) + reference_ids = pool_model_data.search(cr, SUPERUSER_ID, [('res_id','in',list(sub_ids)),('model','=',self._name)]) # Step 2. Marching towards the real deletion of referenced records if reference_ids: - pool_model_data.unlink(cr, ROOT_USER_ID, reference_ids) + pool_model_data.unlink(cr, SUPERUSER_ID, reference_ids) # For the same reason, removing the record relevant to ir_values ir_value_ids = ir_values_obj.search(cr, uid, @@ -3836,7 +3643,7 @@ class orm(orm_template): ids = [ids] self._check_concurrency(cr, ids, context) - self.pool.get('ir.model.access').check(cr, user, self._name, 'write') + self.check_write(cr, user) result = self._store_get_values(cr, user, ids, vals.keys(), context) or [] @@ -4045,7 +3852,11 @@ class orm(orm_template): """ if not context: context = {} - self.pool.get('ir.model.access').check(cr, user, self._name, 'create') + + if self.is_transient(): + self._transient_vacuum(cr, user) + + self.check_create(cr, user) vals = self._add_missing_default_values(cr, user, vals, context) @@ -4059,7 +3870,7 @@ class orm(orm_template): upd_todo = [] for v in vals.keys(): if v in self._inherit_fields: - (table, col, col_detail) = self._inherit_fields[v] + (table, col, col_detail, original_parent) = self._inherit_fields[v] tocreate[table][v] = vals[v] del vals[v] else: @@ -4198,6 +4009,27 @@ class orm(orm_template): wf_service.trg_create(user, self._name, id_new, cr) return id_new + def browse(self, cr, uid, select, context=None, list_class=None, fields_process=None): + """Fetch records as objects allowing to use dot notation to browse fields and relations + + :param cr: database cursor + :param user: current user id + :param select: id or list of ids. + :param context: context arguments, like lang, time zone + :rtype: object or list of objects requested + + """ + self._list_class = list_class or browse_record_list + cache = {} + # need to accepts ints and longs because ids coming from a method + # launched by button in the interface have a type long... + if isinstance(select, (int, long)): + return browse_record(cr, uid, select, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) + elif isinstance(select, list): + return self._list_class([browse_record(cr, uid, id, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) for id in select], context=context) + else: + return browse_null() + def _store_get_values(self, cr, uid, ids, fields, context): """Returns an ordered list of fields.functions to call due to an update operation on ``fields`` of records with ``ids``, @@ -4206,44 +4038,52 @@ class orm(orm_template): :return: [(priority, model_name, [record_ids,], [function_fields,])] """ - # FIXME: rewrite, cleanup, use real variable names - # e.g.: http://pastie.org/1222060 - result = {} - fncts = self.pool._store_function.get(self._name, []) - for fnct in range(len(fncts)): - if fncts[fnct][3]: - ok = False - if not fields: - ok = True - for f in (fields or []): - if f in fncts[fnct][3]: - ok = True - break - if not ok: - continue + if fields is None: fields = [] + stored_functions = self.pool._store_function.get(self._name, []) + + # use indexed names for the details of the stored_functions: + model_name_, func_field_to_compute_, id_mapping_fnct_, trigger_fields_, priority_ = range(5) - result.setdefault(fncts[fnct][0], {}) + # only keep functions that should be triggered for the ``fields`` + # being written to. + to_compute = [f for f in stored_functions \ + if ((not f[trigger_fields_]) or set(fields).intersection(f[trigger_fields_]))] + mapping = {} + for function in to_compute: # use admin user for accessing objects having rules defined on store fields - ids2 = fncts[fnct][2](self, cr, ROOT_USER_ID, ids, context) - for id in filter(None, ids2): - result[fncts[fnct][0]].setdefault(id, []) - result[fncts[fnct][0]][id].append(fnct) - dict = {} - for object in result: - k2 = {} - for id, fnct in result[object].items(): - k2.setdefault(tuple(fnct), []) - k2[tuple(fnct)].append(id) - for fnct, id in k2.items(): - dict.setdefault(fncts[fnct[0]][4], []) - dict[fncts[fnct[0]][4]].append((fncts[fnct[0]][4], object, id, map(lambda x: fncts[x][1], fnct))) - result2 = [] - tmp = dict.keys() - tmp.sort() - for k in tmp: - result2 += dict[k] - return result2 + target_ids = [id for id in function[id_mapping_fnct_](self, cr, SUPERUSER_ID, ids, context) if id] + + # the compound key must consider the priority and model name + key = (function[priority_], function[model_name_]) + for target_id in target_ids: + mapping.setdefault(key, {}).setdefault(target_id,set()).add(tuple(function)) + + # Here mapping looks like: + # { (10, 'model_a') : { target_id1: [ (function_1_tuple, function_2_tuple) ], ... } + # (20, 'model_a') : { target_id2: [ (function_3_tuple, function_4_tuple) ], ... } + # (99, 'model_a') : { target_id1: [ (function_5_tuple, function_6_tuple) ], ... } + # } + + # Now we need to generate the batch function calls list + # call_map = + # { (10, 'model_a') : [(10, 'model_a', [record_ids,], [function_fields,])] } + call_map = {} + for ((priority,model), id_map) in mapping.iteritems(): + functions_ids_maps = {} + # function_ids_maps = + # { (function_1_tuple, function_2_tuple) : [target_id1, target_id2, ..] } + for id, functions in id_map.iteritems(): + functions_ids_maps.setdefault(tuple(functions), []).append(id) + for functions, ids in functions_ids_maps.iteritems(): + call_map.setdefault((priority,model),[]).append((priority, model, ids, + [f[func_field_to_compute_] for f in functions])) + ordered_keys = call_map.keys() + ordered_keys.sort() + result = [] + if ordered_keys: + result = reduce(operator.add, (call_map[k] for k in ordered_keys)) + return result def _store_set_values(self, cr, uid, ids, fields, context): """Calls the fields.function's "implementation function" for all ``fields``, on records with ``ids`` (taking care of @@ -4279,7 +4119,7 @@ class orm(orm_template): val = todo[key] if key: # use admin user for accessing objects having rules defined on store fields - result = self._columns[val[0]].get(cr, self, ids, val, ROOT_USER_ID, context=context) + result = self._columns[val[0]].get(cr, self, ids, val, SUPERUSER_ID, context=context) for id, value in result.items(): if field_flag: for f in value.keys(): @@ -4305,7 +4145,7 @@ class orm(orm_template): else: for f in val: # use admin user for accessing objects having rules defined on store fields - result = self._columns[f].get(cr, self, ids, f, ROOT_USER_ID, context=context) + result = self._columns[f].get(cr, self, ids, f, SUPERUSER_ID, context=context) for r in result.keys(): if field_flag: if r in field_dict.keys(): @@ -4354,9 +4194,7 @@ class orm(orm_template): domain = [('active', '=', 1)] if domain: - import expression - e = expression.expression(domain) - e.parse(cr, user, self, context) + e = expression.expression(cr, user, domain, self, context) tables = e.get_tables() where_clause, where_params = e.to_sql() where_clause = where_clause and [where_clause] or [] @@ -4381,7 +4219,7 @@ class orm(orm_template): if parent_model and child_object: # as inherited rules are being applied, we need to add the missing JOIN # to reach the parent table (if it was not JOINed yet in the query) - child_object._inherits_join_add(parent_model, query) + child_object._inherits_join_add(child_object, parent_model, query) query.where_clause += added_clause query.where_clause_params += added_params for table in added_tables: @@ -4470,7 +4308,7 @@ class orm(orm_template): else: continue # ignore non-readable or "non-joinable" fields elif order_field in self._inherit_fields: - parent_obj = self.pool.get(self._inherit_fields[order_field][0]) + parent_obj = self.pool.get(self._inherit_fields[order_field][3]) order_column = parent_obj._columns[order_field] if order_column._classic_read: inner_clause = self._inherits_join_calc(order_field, query) @@ -4501,7 +4339,11 @@ class orm(orm_template): """ if context is None: context = {} - self.pool.get('ir.model.access').check(cr, access_rights_uid or user, self._name, 'read') + self.check_read(cr, access_rights_uid or user) + + # For transient models, restrict acces to the current user, except for the super-user + if self.is_transient() and self._log_access and user != SUPERUSER_ID: + args = expression.AND(([('create_uid', '=', user)], args or [])) query = self._where_calc(cr, user, args, context=context) self._apply_ir_rules(cr, user, query, 'read', context=context) @@ -4577,7 +4419,7 @@ class orm(orm_template): for f in fields: ftype = fields[f]['type'] - if self._log_access and f in ('create_date', 'create_uid', 'write_date', 'write_uid'): + if self._log_access and f in LOG_ACCESS_COLUMNS: del data[f] if f in default: @@ -4614,9 +4456,13 @@ class orm(orm_template): # force a clean recompute! for parent_column in ['parent_left', 'parent_right']: data.pop(parent_column, None) - - for v in self._inherits: - del data[self._inherits[v]] + # Remove _inherits field's from data recursively, missing parents will + # be created by create() (so that copy() copy everything). + def remove_ids(inherits_dict): + for parent_table in inherits_dict: + del data[inherits_dict[parent_table]] + remove_ids(self.pool.get(parent_table)._inherits) + remove_ids(self._inherits) return data def copy_translations(self, cr, uid, old_id, new_id, context=None): @@ -4688,11 +4534,23 @@ class orm(orm_template): return new_id def exists(self, cr, uid, ids, context=None): + """Checks whether the given id or ids exist in this model, + and return the list of ids that do. This is simple to use for + a truth test on a browse_record:: + + if record.exists(): + pass + + :param ids: id or list of ids to check for existence + :type ids: int or [int] + :return: the list of ids that currently exist, out of + the given `ids` + """ if type(ids) in (int, long): ids = [ids] - query = 'SELECT count(1) FROM "%s"' % (self._table) + query = 'SELECT id FROM "%s"' % (self._table) cr.execute(query + "WHERE ID IN %s", (tuple(ids),)) - return cr.fetchone()[0] == len(ids) + return [x[0] for x in cr.fetchall()] def check_recursion(self, cr, uid, ids, context=None, parent=None): warnings.warn("You are using deprecated %s.check_recursion(). Please use the '_check_recursion()' instead!" % \ @@ -4772,5 +4630,98 @@ class orm(orm_template): results[k] = '' return results -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + # Transience + def is_transient(self): + """ Return whether the model is transient. + + See TransientModel. + + """ + return self._transient + + def _transient_clean_rows_older_than(self, cr, seconds): + assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name + cr.execute("SELECT id FROM " + self._table + " WHERE" + " COALESCE(write_date, create_date, now())::timestamp <" + " (now() - interval %s)", ("%s seconds" % seconds,)) + ids = [x[0] for x in cr.fetchall()] + self.unlink(cr, SUPERUSER_ID, ids) + + def _transient_clean_old_rows(self, cr, count): + assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name + cr.execute( + "SELECT id, COALESCE(write_date, create_date, now())::timestamp" + " AS t FROM " + self._table + + " ORDER BY t LIMIT %s", (count,)) + ids = [x[0] for x in cr.fetchall()] + self.unlink(cr, SUPERUSER_ID, ids) + + def _transient_vacuum(self, cr, uid, force=False): + """Clean the transient records. + + This unlinks old records from the transient model tables whenever the + "_transient_max_count" or "_max_age" conditions (if any) are reached. + Actual cleaning will happen only once every "_transient_check_time" calls. + This means this method can be called frequently called (e.g. whenever + a new record is created). + """ + assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name + self._transient_check_count += 1 + if (not force) and (self._transient_check_count % self._transient_check_time): + self._transient_check_count = 0 + return True + + # Age-based expiration + if self._transient_max_hours: + self._transient_clean_rows_older_than(cr, self._transient_max_hours * 60 * 60) + # Count-based expiration + if self._transient_max_count: + self._transient_clean_old_rows(cr, self._transient_max_count) + + return True + +# keep this import here, at top it will cause dependency cycle errors +import expression + +class Model(BaseModel): + """Main super-class for regular database-persisted OpenERP models. + + OpenERP models are created by inheriting from this class:: + + class user(Model): + ... + + The system will later instantiate the class once per database (on + which the class' module is installed). + """ + _register = False # not visible in ORM registry, meant to be python-inherited only + _transient = False # True in a TransientModel + +class TransientModel(BaseModel): + """Model super-class for transient records, meant to be temporarily + persisted, and regularly vaccuum-cleaned. + + A TransientModel has a simplified access rights management, + all users can create new records, and may only access the + records they created. The super-user has unrestricted access + to all TransientModel records. + """ + _register = False # not visible in ORM registry, meant to be python-inherited only + _transient = True + +class AbstractModel(BaseModel): + """Abstract Model super-class for creating an abstract class meant to be + inherited by regular models (Models or TransientModels) but not meant to + be usable on its own, or persisted. + + Technical note: we don't want to make AbstractModel the super-class of + Model or BaseModel because it would not make sense to put the main + definition of persistence methods such as create() in it, and still we + should be able to override them within an AbstractModel. + """ + _auto = False # don't create any database backend for AbstractModels + _register = False # not visible in ORM registry, meant to be python-inherited only + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/osv/osv.py b/openerp/osv/osv.py index 1327efe5731..76a403b87c2 100644 --- a/openerp/osv/osv.py +++ b/openerp/osv/osv.py @@ -21,31 +21,33 @@ #.apidoc title: Objects Services (OSV) +import logging +from psycopg2 import IntegrityError, errorcodes + import orm +import openerp import openerp.netsvc as netsvc import openerp.pooler as pooler import openerp.sql_db as sql_db -import logging -from psycopg2 import IntegrityError, errorcodes from openerp.tools.func import wraps from openerp.tools.translate import translate -from openerp.osv.orm import MetaModel - +from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel +import openerp.exceptions +# Deprecated. class except_osv(Exception): - def __init__(self, name, value, exc_type='warning'): + def __init__(self, name, value): self.name = name - self.exc_type = exc_type self.value = value - self.args = (exc_type, name) + self.args = (name, value) +service = None -class object_proxy(netsvc.Service): +class object_proxy(object): def __init__(self): self.logger = logging.getLogger('web-services') - netsvc.Service.__init__(self, 'object_proxy', audience='') - self.exportMethod(self.exec_workflow) - self.exportMethod(self.execute) + global service + service = self def check(f): @wraps(f) @@ -117,16 +119,14 @@ class object_proxy(netsvc.Service): raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.') return f(self, dbname, *args, **kwargs) except orm.except_orm, inst: - if inst.name == 'AccessError': - self.logger.debug("AccessError", exc_info=True) - self.abortResponse(1, inst.name, 'warning', inst.value) - except except_osv, inst: - self.abortResponse(1, inst.name, inst.exc_type, inst.value) + raise except_osv(inst.name, inst.value) + except except_osv: + raise except IntegrityError, inst: osv_pool = pooler.get_pool(dbname) for key in osv_pool._sql_error.keys(): if key in inst[0]: - self.abortResponse(1, _('Constraint Error'), 'warning', + netsvc.abort_response(1, _('Constraint Error'), 'warning', tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0]) if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set') @@ -147,9 +147,9 @@ class object_proxy(netsvc.Service): msg += _('\n\n[object with reference: %s - %s]') % (model_name, model) except Exception: pass - self.abortResponse(1, _('Integrity Error'), 'warning', msg) + netsvc.abort_response(1, _('Integrity Error'), 'warning', msg) else: - self.abortResponse(1, _('Integrity Error'), 'warning', inst[0]) + netsvc.abort_response(1, _('Integrity Error'), 'warning', inst[0]) except Exception: self.logger.exception("Uncaught exception") raise @@ -198,17 +198,10 @@ class object_proxy(netsvc.Service): cr.close() return res - -class osv_memory(orm.orm_memory): - """ Deprecated class. """ - __metaclass__ = MetaModel - _register = False # Set to false if the model shouldn't be automatically discovered. - - -class osv(orm.orm): - """ Deprecated class. """ - __metaclass__ = MetaModel - _register = False # Set to false if the model shouldn't be automatically discovered. +# deprecated - for backward compatibility. +osv = Model +osv_memory = TransientModel +osv_abstract = AbstractModel # ;-) def start_object_proxy(): diff --git a/openerp/pooler.py b/openerp/pooler.py index c754385d6b3..88b60864b90 100644 --- a/openerp/pooler.py +++ b/openerp/pooler.py @@ -34,11 +34,6 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False, return registry.db, registry -def delete_pool(db_name): - """Delete an existing registry.""" - RegistryManager.delete(db_name) - - def restart_pool(db_name, force_demo=False, status=None, update_module=False): """Delete an existing registry and return a database connection and a newly initialized registry.""" registry = RegistryManager.new(db_name, force_demo, status, update_module, True) diff --git a/openerp/release.py b/openerp/release.py index c0c14099d33..23a764bc94c 100644 --- a/openerp/release.py +++ b/openerp/release.py @@ -19,8 +19,7 @@ # ############################################################################## -name = 'openerp-server' -version = '6.1-dev' +version = '6.1dev' major_version = '6.1' description = 'OpenERP Server' long_desc = '''OpenERP is a complete ERP and CRM. The main features are accounting (analytic @@ -36,7 +35,7 @@ Programming Language :: Python url = 'http://www.openerp.com' author = 'OpenERP S.A.' author_email = 'info@openerp.com' -support_email = 'support@openerp.com' license = 'AGPL-3' +timestamp = None # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/report/custom.py b/openerp/report/custom.py index f3d6cfbc074..051d1f29862 100644 --- a/openerp/report/custom.py +++ b/openerp/report/custom.py @@ -136,16 +136,15 @@ class report_custom(report_int): ids = self.pool.get(report.model_id.model).search(cr, uid, []) datas['ids'] = ids - service = netsvc.LocalService("object_proxy") report_id = datas['report_id'] - report = service.execute(cr.dbname, uid, 'ir.report.custom', 'read', [report_id], context=context)[0] - fields = service.execute(cr.dbname, uid, 'ir.report.custom.fields', 'read', report['fields_child0'], context=context) + report = self.pool.get('ir.report.custom').read(cr, uid, [report_id], context=context)[0] + fields = self.pool.get('ir.report.custom.fields').read(cr, uid, report['fields_child0'], context=context) fields.sort(lambda x,y : x['sequence'] - y['sequence']) if report['field_parent']: - parent_field = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [report['field_parent'][0]],['model']) - model_name = service.execute(cr.dbname, uid, 'ir.model', 'read', [report['model_id'][0]], ['model'],context=context)[0]['model'] + parent_field = self.pool.get('ir.model.fields').read(cr, uid, [report['field_parent'][0]], ['model']) + model_name = self.pool.get('ir.model').read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model'] fct = {} fct['id'] = lambda x : x @@ -160,9 +159,7 @@ class report_custom(report_int): field_child = f['field_child'+str(i)] if field_child: row.append( - service.execute(cr.dbname, uid, - 'ir.model.fields', 'read', [field_child[0]], - ['name'], context=context)[0]['name'] + self.pool.get('ir.model.fields').read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name'] ) if f['fc'+str(i)+'_operande']: fct_name = 'id' @@ -346,7 +343,7 @@ class report_custom(report_int): def _create_lines(self, cr, uid, ids, report, fields, results, context): - service = netsvc.LocalService("object_proxy") + pool = pooler.get_pool(cr.dbname) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') @@ -376,7 +373,7 @@ class report_custom(report_int): for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: - type = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [field_id],['ttype']) + type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype']) if type[0]['ttype'] == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] @@ -449,7 +446,7 @@ class report_custom(report_int): def _create_bars(self, cr, uid, ids, report, fields, results, context): - service = netsvc.LocalService("object_proxy") + pool = pooler.get_pool(cr.dbname) pdf_string = cStringIO.StringIO() can = canvas.init(fname=pdf_string, format='pdf') @@ -475,7 +472,7 @@ class report_custom(report_int): for f in fields: field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0]) if field_id: - type = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [field_id],['ttype']) + type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype']) if type[0]['ttype'] == 'date': date_idx = idx fct[idx] = process_date[report['frequency']] diff --git a/openerp/report/interface.py b/openerp/report/interface.py index 178c015ba34..9a97c445671 100644 --- a/openerp/report/interface.py +++ b/openerp/report/interface.py @@ -41,9 +41,9 @@ def toxml(value): return unicode_value.replace('&', '&').replace('<','<').replace('>','>') class report_int(netsvc.Service): - def __init__(self, name, audience='*'): + def __init__(self, name): assert not self.exists(name), 'The report "%s" already exists!' % name - super(report_int, self).__init__(name, audience) + super(report_int, self).__init__(name) if name[0:7]<>'report.': raise Exception, 'ConceptionError, bad report name, should start with "report."' self.name = name @@ -51,8 +51,6 @@ class report_int(netsvc.Service): self.name2 = '.'.join(name.split('.')[1:]) # TODO the reports have methods with a 'title' kwarg that is redundant with this attribute self.title = None - #self.joinGroup('report') - self.exportMethod(self.create) def create(self, cr, uid, ids, datas, context=None): return False @@ -233,6 +231,7 @@ class report_rml(report_int): def _get_path(self): ret = [] ret.append(self.tmpl.replace(os.path.sep, '/').rsplit('/',1)[0]) # Same dir as the report rml + ret.append('addons') ret.append(tools.config['root_path']) return ret diff --git a/openerp/report/preprocess.py b/openerp/report/preprocess.py index c84ce66b472..b339e078d81 100644 --- a/openerp/report/preprocess.py +++ b/openerp/report/preprocess.py @@ -65,7 +65,10 @@ class report(object): if type =='html2html': match = html_parents if txt.group(3): - match = [txt.group(3)] + group_3 = txt.group(3) + if group_3.startswith("'") or group_3.startswith('"'): + group_3 = group_3[1:-1] + match = [group_3] n = node while n.tag not in match: n = n.getparent() diff --git a/openerp/report/print_xml.py b/openerp/report/print_xml.py index ad2b0528d99..b7074a2d0c3 100644 --- a/openerp/report/print_xml.py +++ b/openerp/report/print_xml.py @@ -137,9 +137,8 @@ class document(object): value = self.get_value(browser, attrs['name']) - service = netsvc.LocalService("object_proxy") - ids = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'search', [('res_model','=',model),('res_id','=',int(value))]) - datas = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'read', ids) + ids = self.pool.get('ir.attachment').search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))]) + datas = self.pool.get('ir.attachment').read(self.cr, self.uid, ids) if len(datas): # if there are several, pick first diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index a770a19ec27..0067bf300f2 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -447,14 +447,14 @@ class _rml_canvas(object): self._logger.debug("Image %s used", node.get('name')) s = StringIO(image_data) else: + newtext = node.text if self.localcontext: - res = utils._regex.findall(node.text) + res = utils._regex.findall(newtext) for key in res: - newtext = eval(key, {}, self.localcontext) - node.text = newtext or '' + newtext = eval(key, {}, self.localcontext) or '' image_data = None - if node.text: - image_data = base64.decodestring(node.text) + if newtext: + image_data = base64.decodestring(newtext) if image_data: s = StringIO(image_data) else: diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py index 210a54760c4..98de86b01a8 100644 --- a/openerp/report/report_sxw.py +++ b/openerp/report/report_sxw.py @@ -68,6 +68,9 @@ rml2sxw = { 'para': 'p', } +def get_date_length(date_format=DT_FORMAT): + return len((datetime.now()).strftime(date_format)) + class _format(object): def set_value(self, cr, uid, name, object, field, lang_obj): self.object = object @@ -78,7 +81,7 @@ class _format(object): class _float_format(float, _format): def __init__(self,value): super(_float_format, self).__init__() - self.val = value + self.val = value or 0.0 def __str__(self): digits = 2 @@ -86,17 +89,17 @@ class _float_format(float, _format): digits = self._field.digits[1] if hasattr(self, 'lang_obj'): return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True) - return self.val + return str(self.val) class _int_format(int, _format): def __init__(self,value): super(_int_format, self).__init__() - self.val = value and str(value) or str(0) + self.val = value or 0 def __str__(self): if hasattr(self,'lang_obj'): return self.lang_obj.format('%.d', self.name, True) - return self.val + return str(self.val) class _date_format(str, _format): def __init__(self,value): @@ -106,7 +109,7 @@ class _date_format(str, _format): def __str__(self): if self.val: if getattr(self,'name', None): - date = datetime.strptime(self.name, DT_FORMAT) + date = datetime.strptime(self.name[:get_date_length()], DT_FORMAT) return date.strftime(str(self.lang_obj.date_format)) return self.val @@ -264,7 +267,7 @@ class rml_parse(object): d = obj._field.digits[1] or DEFAULT_DIGITS return d - def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False): + def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False, currency_obj=False): """ Assuming 'Account' decimal.precision=3: formatLang(value) -> digits=2 (default) @@ -296,13 +299,19 @@ class rml_parse(object): date_format = date_format + " " + self.lang_dict['time_format'] parse_format = DHM_FORMAT if not isinstance(value, time.struct_time): - return time.strftime(date_format, time.strptime(value, parse_format)) + return time.strftime(date_format, time.strptime(value[:get_date_length(parse_format)], parse_format)) else: date = datetime(*value.timetuple()[:6]) return date.strftime(date_format) - return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) + res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) + if currency_obj: + if currency_obj.position == 'after': + res='%s %s'%(res,currency_obj.symbol) + elif currency_obj and currency_obj.position == 'before': + res='%s %s'%(currency_obj.symbol, res) + return res def repeatIn(self, lst, name,nodes_parent=False): ret_lst = [] diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index b9ee98fcab0..1bb83dfd228 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -19,9 +19,21 @@ # ############################################################################## +import logging +import threading +import time + import http_server import netrpc_server import web_services +import websrv_lib + +import openerp.cron +import openerp.modules +import openerp.netsvc +import openerp.osv +import openerp.tools +import openerp.wsgi #.apidoc title: RPC Services @@ -34,5 +46,58 @@ import web_services low-level behavior of the wire. """ +def start_services(): + """ Start all services. + + Services include the different servers and cron threads. + + """ + # Instantiate local services (this is a legacy design). + openerp.osv.osv.start_object_proxy() + # Export (for RPC) services. + web_services.start_web_services() + + # Initialize the HTTP stack. + #http_server.init_servers() + #http_server.init_static_http() + netrpc_server.init_servers() + + # Start the main cron thread. + openerp.cron.start_master_thread() + + # Start the top-level servers threads (normally HTTP, HTTPS, and NETRPC). + openerp.netsvc.Server.startAll() + + # Start the WSGI server. + openerp.wsgi.start_server() + + +def stop_services(): + """ Stop all services. """ + # stop scheduling new jobs; we will have to wait for the jobs to complete below + openerp.cron.cancel_all() + + openerp.netsvc.Server.quitAll() + openerp.wsgi.stop_server() + config = openerp.tools.config + logger = logging.getLogger('server') + logger.info("Initiating shutdown") + logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") + logging.shutdown() + + # Manually join() all threads before calling sys.exit() to allow a second signal + # to trigger _force_quit() in case some non-daemon threads won't exit cleanly. + # threading.Thread.join() should not mask signals (at least in python 2.5). + for thread in threading.enumerate(): + if thread != threading.currentThread() and not thread.isDaemon(): + while thread.isAlive(): + # Need a busyloop here as thread.join() masks signals + # and would prevent the forced shutdown. + thread.join(0.05) + time.sleep(0.05) + + openerp.modules.registry.RegistryManager.delete_all() + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/http_server.py b/openerp/service/http_server.py index 61713e9f2dd..63bd991ee35 100644 --- a/openerp/service/http_server.py +++ b/openerp/service/http_server.py @@ -64,53 +64,6 @@ try: except ImportError: class SSLError(Exception): pass -class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer): - """ A threaded httpd server, with all the necessary functionality for us. - - It also inherits the xml-rpc dispatcher, so that some xml-rpc functions - will be available to the request handler - """ - encoding = None - allow_none = False - allow_reuse_address = 1 - _send_traceback_header = False - i = 0 - - def __init__(self, addr, requestHandler, proto='http', - logRequests=True, allow_none=False, encoding=None, bind_and_activate=True): - self.logRequests = logRequests - - SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding) - HTTPServer.__init__(self, addr, requestHandler) - - self.numThreads = 0 - self.proto = proto - self.__threadno = 0 - - # [Bug #1222790] If possible, set close-on-exec flag; if a - # method spawns a subprocess, the subprocess shouldn't have - # the listening socket open. - if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'): - flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD) - flags |= fcntl.FD_CLOEXEC - fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) - - def handle_error(self, request, client_address): - """ Override the error handler - """ - - logging.getLogger("init").exception("Server error in request from %s:" % (client_address,)) - - def _mark_start(self, thread): - self.numThreads += 1 - - def _mark_end(self, thread): - self.numThreads -= 1 - - - def _get_next_name(self): - self.__threadno += 1 - return 'http-client-%d' % self.__threadno class HttpLogHandler: """ helper class for uniform log handling Please define self._logger at each class that is derived from this @@ -129,182 +82,6 @@ class HttpLogHandler: def log_request(self, code='-', size='-'): self._logger.log(netsvc.logging.DEBUG_RPC, '"%s" %s %s', self.requestline, str(code), str(size)) - -class MultiHandler2(HttpLogHandler, MultiHTTPHandler): - _logger = logging.getLogger('http') - - -class SecureMultiHandler2(HttpLogHandler, SecureMultiHTTPHandler): - _logger = logging.getLogger('https') - - def getcert_fnames(self): - tc = tools.config - fcert = tc.get('secure_cert_file', 'server.cert') - fkey = tc.get('secure_pkey_file', 'server.key') - return (fcert,fkey) - -class BaseHttpDaemon(threading.Thread, netsvc.Server): - _RealProto = '??' - - def __init__(self, interface, port, handler): - threading.Thread.__init__(self, name='%sDaemon-%d'%(self._RealProto, port)) - netsvc.Server.__init__(self) - self.__port = port - self.__interface = interface - - try: - self.server = ThreadedHTTPServer((interface, port), handler, proto=self._RealProto) - self.server.vdirs = [] - self.server.logRequests = True - self.server.timeout = self._busywait_timeout - logging.getLogger("web-services").info( - "starting %s service at %s port %d" % - (self._RealProto, interface or '0.0.0.0', port,)) - except Exception, e: - logging.getLogger("httpd").exception("Error occured when starting the server daemon.") - raise - - @property - def socket(self): - return self.server.socket - - def attach(self, path, gw): - pass - - def stop(self): - self.running = False - self._close_socket() - - def run(self): - self.running = True - while self.running: - try: - self.server.handle_request() - except (socket.error, select.error), e: - if self.running or e.args[0] != errno.EBADF: - raise - return True - - def stats(self): - res = "%sd: " % self._RealProto + ((self.running and "running") or "stopped") - if self.server: - res += ", %d threads" % (self.server.numThreads,) - return res - - def append_svc(self, service): - if not isinstance(service, HTTPDir): - raise Exception("Wrong class for http service") - - pos = len(self.server.vdirs) - lastpos = pos - while pos > 0: - pos -= 1 - if self.server.vdirs[pos].matches(service.path): - lastpos = pos - # we won't break here, but search all way to the top, to - # ensure there is no lesser entry that will shadow the one - # we are inserting. - self.server.vdirs.insert(lastpos, service) - - def list_services(self): - ret = [] - for svc in self.server.vdirs: - ret.append( ( svc.path, str(svc.handler)) ) - - return ret - - -class HttpDaemon(BaseHttpDaemon): - _RealProto = 'HTTP' - def __init__(self, interface, port): - super(HttpDaemon, self).__init__(interface, port, - handler=MultiHandler2) - -class HttpSDaemon(BaseHttpDaemon): - _RealProto = 'HTTPS' - def __init__(self, interface, port): - try: - super(HttpSDaemon, self).__init__(interface, port, - handler=SecureMultiHandler2) - except SSLError, e: - logging.getLogger('httpsd').exception( \ - "Can not load the certificate and/or the private key files") - raise - -httpd = None -httpsd = None - -def init_servers(): - global httpd, httpsd - if tools.config.get('xmlrpc'): - httpd = HttpDaemon(tools.config.get('xmlrpc_interface', ''), - int(tools.config.get('xmlrpc_port', 8069))) - - if tools.config.get('xmlrpcs'): - httpsd = HttpSDaemon(tools.config.get('xmlrpcs_interface', ''), - int(tools.config.get('xmlrpcs_port', 8071))) - -def reg_http_service(hts, secure_only = False): - """ Register some handler to httpd. - hts must be an HTTPDir - """ - global httpd, httpsd - - if httpd and not secure_only: - httpd.append_svc(hts) - - if httpsd: - httpsd.append_svc(hts) - - if (not httpd) and (not httpsd): - logging.getLogger('httpd').warning("No httpd available to register service %s" % hts.path) - return - -def list_http_services(protocol=None): - global httpd, httpsd - if httpd and (protocol == 'http' or protocol == None): - return httpd.list_services() - elif httpsd and (protocol == 'https' or protocol == None): - return httpsd.list_services() - else: - raise Exception("Incorrect protocol or no http services") - -import SimpleXMLRPCServer -class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,HttpLogHandler,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): - rpc_paths = [] - protocol_version = 'HTTP/1.1' - _logger = logging.getLogger('xmlrpc') - - def _dispatch(self, method, params): - try: - service_name = self.path.split("/")[-1] - return self.dispatch(service_name, method, params) - except netsvc.OpenERPDispatcherException, e: - raise xmlrpclib.Fault(tools.exception_to_unicode(e.exception), e.traceback) - - def handle(self): - pass - - def finish(self): - pass - - def setup(self): - self.connection = dummyconn() - self.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys()) - - -def init_xmlrpc(): - if tools.config.get('xmlrpc', False): - # Example of http file serving: - # reg_http_service(HTTPDir('/test/',HTTPHandler)) - reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler)) - logging.getLogger("web-services").info("Registered XML-RPC over HTTP") - - if tools.config.get('xmlrpcs', False) \ - and not tools.config.get('xmlrpc', False): - # only register at the secure server - reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler), True) - logging.getLogger("web-services").info("Registered XML-RPC over HTTPS only") class StaticHTTPHandler(HttpLogHandler, FixSendError, HttpOptions, HTTPHandler): _logger = logging.getLogger('httpd') @@ -345,23 +122,34 @@ def init_static_http(): base_path = tools.config.get('static_http_url_prefix', '/') - reg_http_service(HTTPDir(base_path,StaticHTTPHandler)) + reg_http_service(base_path, StaticHTTPHandler) logging.getLogger("web-services").info("Registered HTTP dir %s for %s" % \ (document_root, base_path)) -class OerpAuthProxy(AuthProxy): - """ Require basic authentication.. +import security - This is a copy of the BasicAuthProxy, which however checks/caches the db - as well. - """ - def __init__(self,provider): - AuthProxy.__init__(self,provider) +class OpenERPAuthProvider(AuthProvider): + """ Require basic authentication.""" + def __init__(self,realm='OpenERP User'): + self.realm = realm self.auth_creds = {} self.auth_tries = 0 self.last_auth = None + def authenticate(self, db, user, passwd, client_address): + try: + uid = security.login(db,user,passwd) + if uid is False: + return False + return (user, passwd, db, uid) + except Exception,e: + logging.getLogger("auth").debug("Fail auth: %s" % e ) + return False + + def log(self, msg, lvl=logging.INFO): + logging.getLogger("auth").log(lvl,msg) + def checkRequest(self,handler,path, db=False): auth_str = handler.headers.get('Authorization',False) try: @@ -375,46 +163,23 @@ class OerpAuthProxy(AuthProxy): db = psp[0] else: #FIXME! - self.provider.log("Wrong path: %s, failing auth" %path) + self.log("Wrong path: %s, failing auth" %path) raise AuthRejectedExc("Authorization failed. Wrong sub-path.") if self.auth_creds.get(db): return True if auth_str and auth_str.startswith('Basic '): auth_str=auth_str[len('Basic '):] (user,passwd) = base64.decodestring(auth_str).split(':') - self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db)) - acd = self.provider.authenticate(db,user,passwd,handler.client_address) + self.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db)) + acd = self.authenticate(db,user,passwd,handler.client_address) if acd != False: self.auth_creds[db] = acd self.last_auth = db return True if self.auth_tries > 5: - self.provider.log("Failing authorization after 5 requests w/o password") + self.log("Failing authorization after 5 requests w/o password") raise AuthRejectedExc("Authorization failed.") self.auth_tries += 1 - raise AuthRequiredExc(atype='Basic', realm=self.provider.realm) - -import security -class OpenERPAuthProvider(AuthProvider): - def __init__(self,realm='OpenERP User'): - self.realm = realm - - def setupAuth(self, multi, handler): - if not multi.sec_realms.has_key(self.realm): - multi.sec_realms[self.realm] = OerpAuthProxy(self) - handler.auth_proxy = multi.sec_realms[self.realm] - - def authenticate(self, db, user, passwd, client_address): - try: - uid = security.login(db,user,passwd) - if uid is False: - return False - return (user, passwd, db, uid) - except Exception,e: - logging.getLogger("auth").debug("Fail auth: %s" % e ) - return False - - def log(self, msg, lvl=logging.INFO): - logging.getLogger("auth").log(lvl,msg) + raise AuthRequiredExc(atype='Basic', realm=self.realm) #eof diff --git a/openerp/service/netrpc_server.py b/openerp/service/netrpc_server.py index 70855a018e5..5b0fe239e51 100644 --- a/openerp/service/netrpc_server.py +++ b/openerp/service/netrpc_server.py @@ -36,7 +36,7 @@ import openerp.netsvc as netsvc import openerp.tiny_socket as tiny_socket import openerp.tools as tools -class TinySocketClientThread(threading.Thread, netsvc.OpenERPDispatcher): +class TinySocketClientThread(threading.Thread): def __init__(self, sock, threads): spn = sock and sock.getpeername() spn = 'netrpc-client-%s:%s' % spn[0:2] @@ -59,26 +59,18 @@ class TinySocketClientThread(threading.Thread, netsvc.OpenERPDispatcher): while self.running: try: msg = ts.myreceive() - result = self.dispatch(msg[0], msg[1], msg[2:]) + result = netsvc.dispatch_rpc(msg[0], msg[1], msg[2:]) ts.mysend(result) except socket.timeout: #terminate this channel because other endpoint is gone break - except netsvc.OpenERPDispatcherException, e: - try: - new_e = Exception(tools.exception_to_unicode(e.exception)) # avoid problems of pickeling - logging.getLogger('web-services').debug("netrpc: rpc-dispatching exception", exc_info=True) - ts.mysend(new_e, exception=True, traceback=e.traceback) - except Exception: - #terminate this channel if we can't properly send back the error - logging.getLogger('web-services').exception("netrpc: cannot deliver exception message to client") - break except Exception, e: try: + new_e = Exception(tools.exception_to_unicode(e)) # avoid problems of pickeling tb = getattr(e, 'traceback', sys.exc_info()) tb_s = "".join(traceback.format_exception(*tb)) logging.getLogger('web-services').debug("netrpc: communication-level exception", exc_info=True) - ts.mysend(e, exception=True, traceback=tb_s) + ts.mysend(new_e, exception=True, traceback=tb_s) break except Exception, ex: #terminate this channel if we can't properly send back the error @@ -107,7 +99,7 @@ class TinySocketServerThread(threading.Thread,netsvc.Server): self.socket.listen(5) self.threads = [] netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO, - "starting NET-RPC service at %s port %d" % (interface or '0.0.0.0', port,)) + "starting NET-RPC service on %s:%s" % (interface or '0.0.0.0', port,)) def run(self): try: diff --git a/openerp/service/security.py b/openerp/service/security.py index 86c381b683f..ff140ad261b 100644 --- a/openerp/service/security.py +++ b/openerp/service/security.py @@ -19,18 +19,12 @@ # ############################################################################## +import openerp.exceptions import openerp.pooler as pooler import openerp.tools as tools #.apidoc title: Authentication helpers -class ExceptionNoTb(Exception): - """ When rejecting a password, hide the traceback - """ - def __init__(self, msg): - super(ExceptionNoTb, self).__init__(msg) - self.traceback = ('','','') - def login(db, login, password): pool = pooler.get_pool(db) user_obj = pool.get('res.users') @@ -40,7 +34,7 @@ def check_super(passwd): if passwd == tools.config['admin_passwd']: return True else: - raise ExceptionNoTb('AccessDenied: Invalid super administrator password.') + raise openerp.exceptions.AccessDenied() def check(db, uid, passwd): pool = pooler.get_pool(db) diff --git a/openerp/service/web_services.py b/openerp/service/web_services.py index c768a3cb877..5f0a1dccff9 100644 --- a/openerp/service/web_services.py +++ b/openerp/service/web_services.py @@ -38,6 +38,7 @@ import openerp.release as release import openerp.sql_db as sql_db import openerp.tools as tools import openerp.modules +import openerp.exceptions #.apidoc title: Exported Service methods #.apidoc module-mods: member-order: bysource @@ -48,6 +49,8 @@ import openerp.modules procedures to be called. Each method has its own arguments footprint. """ +RPC_VERSION_1 = {'server_version': '6.1', 'protocol_version': 1} + # This should be moved to openerp.modules.db, along side initialize(). def _initialize_db(serv, id, db_name, demo, lang, user_password): cr = None @@ -87,17 +90,17 @@ def _initialize_db(serv, id, db_name, demo, lang, user_password): class db(netsvc.ExportService): def __init__(self, name="db"): netsvc.ExportService.__init__(self, name) - self.joinGroup("web-services") self.actions = {} self.id = 0 self.id_protect = threading.Semaphore() self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var - def dispatch(self, method, auth, params): + def dispatch(self, method, params): if method in [ 'create', 'get_progress', 'drop', 'dump', 'restore', 'rename', - 'change_admin_password', 'migrate_databases' ]: + 'change_admin_password', 'migrate_databases', + 'create_database' ]: passwd = params[0] params = params[1:] security.check_super(passwd) @@ -110,8 +113,6 @@ class db(netsvc.ExportService): fn = getattr(self, 'exp_'+method) return fn(*params) - def new_dispatch(self,method,auth,params): - pass def _create_empty_database(self, name): db = sql_db.db_connect('template1') cr = db.cursor() @@ -138,6 +139,20 @@ class db(netsvc.ExportService): self.actions[id]['thread'] = create_thread return id + def exp_create_database(self, db_name, demo, lang, user_password='admin'): + """ Similar to exp_create but blocking.""" + self.id_protect.acquire() + self.id += 1 + id = self.id + self.id_protect.release() + + self.actions[id] = {'clean': False} + + logging.getLogger('db.create').info('CREATE DATABASE %s', db_name.lower()) + self._create_empty_database(db_name) + _initialize_db(self, id, db_name, demo, lang, user_password) + return True + def exp_get_progress(self, id): if self.actions[id]['thread'].isAlive(): # return openerp.modules.init_progress[db_name] @@ -149,14 +164,13 @@ class db(netsvc.ExportService): self.actions.pop(id) return (1.0, users) else: - e = self.actions[id]['exception'] + e = self.actions[id]['exception'] # TODO this seems wrong: actions[id]['traceback'] is set, but not 'exception'. self.actions.pop(id) raise Exception, e def exp_drop(self, db_name): + openerp.modules.registry.RegistryManager.delete(db_name) sql_db.close_db(db_name) - openerp.modules.registry.RegistryManager.clear_caches(db_name) - openerp.netsvc.Agent.cancel(db_name) logger = netsvc.Logger() db = sql_db.db_connect('template1') @@ -258,9 +272,8 @@ class db(netsvc.ExportService): return True def exp_rename(self, old_name, new_name): + openerp.modules.registry.RegistryManager.delete(old_name) sql_db.close_db(old_name) - openerp.modules.registry.RegistryManager.clear_caches(old_name) - openerp.netsvc.Agent.cancel(old_name) logger = netsvc.Logger() db = sql_db.db_connect('template1') @@ -290,7 +303,7 @@ class db(netsvc.ExportService): def exp_list(self, document=False): if not tools.config['list_db'] and not document: - raise Exception('AccessDenied') + raise openerp.exceptions.AccessDenied() db = sql_db.db_connect('template1') cr = db.cursor() @@ -342,9 +355,9 @@ class db(netsvc.ExportService): tools.config['update']['base'] = True pooler.restart_pool(db, force_demo=False, update_module=True) except except_orm, inst: - self.abortResponse(1, inst.name, 'warning', inst.value) + netsvc.abort_response(1, inst.name, 'warning', inst.value) except except_osv, inst: - self.abortResponse(1, inst.name, inst.exc_type, inst.value) + netsvc.abort_response(1, inst.name, 'warning', inst.value) except Exception: import traceback tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback)) @@ -352,42 +365,21 @@ class db(netsvc.ExportService): raise return True -class _ObjectService(netsvc.ExportService): - "A common base class for those who have fn(db, uid, password,...) " - - def common_dispatch(self, method, auth, params): - (db, uid, passwd ) = params[0:3] - params = params[3:] - security.check(db,uid,passwd) - cr = pooler.get_db(db).cursor() - fn = getattr(self, 'exp_'+method) - res = fn(cr, uid, *params) - cr.commit() - cr.close() - return res - -class common(_ObjectService): +class common(netsvc.ExportService): def __init__(self,name="common"): - _ObjectService.__init__(self,name) - self.joinGroup("web-services") + netsvc.ExportService.__init__(self,name) - def dispatch(self, method, auth, params): + def dispatch(self, method, params): logger = netsvc.Logger() if method == 'login': - # At this old dispatcher, we do NOT update the auth proxy res = security.login(params[0], params[1], params[2]) msg = res and 'successful login' or 'bad login or password' # TODO log the client ip address.. logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, params[1], params[0].lower())) return res or False - elif method == 'logout': - if auth: - auth.logout(params[1]) - logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db)) - return True elif method in ['about', 'timezone_get', 'get_server_environment', 'login_message','get_stats', 'check_connectivity', - 'list_http_services']: + 'list_http_services', 'version']: pass elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel', 'get_os_time', 'get_sqlcount']: passwd = params[0] @@ -399,9 +391,8 @@ class common(_ObjectService): fn = getattr(self, 'exp_'+method) return fn(*params) - - def new_dispatch(self,method,auth,params): - pass + def exp_version(self): + return RPC_VERSION_1 def exp_about(self, extended=False): """Return information about the OpenERP Server. @@ -436,7 +427,7 @@ GNU Public Licence. return rc.get_available_updates(rc.id, openerp.modules.get_modules_with_version()) except tm.RemoteContractException, e: - self.abortResponse(1, 'Migration Error', 'warning', str(e)) + netsvc.abort_response(1, 'Migration Error', 'warning', str(e)) def exp_get_migration_scripts(self, contract_id, contract_password): @@ -504,7 +495,7 @@ GNU Public Licence. return True except tm.RemoteContractException, e: - self.abortResponse(1, 'Migration Error', 'warning', str(e)) + netsvc.abort_response(1, 'Migration Error', 'warning', str(e)) except Exception, e: import traceback tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback)) @@ -568,9 +559,8 @@ GNU Public Licence. class objects_proxy(netsvc.ExportService): def __init__(self, name="object"): netsvc.ExportService.__init__(self,name) - self.joinGroup('web-services') - def dispatch(self, method, auth, params): + def dispatch(self, method, params): (db, uid, passwd ) = params[0:3] params = params[3:] if method == 'obj_list': @@ -578,16 +568,12 @@ class objects_proxy(netsvc.ExportService): if method not in ['execute','exec_workflow']: raise NameError("Method not available %s" % method) security.check(db,uid,passwd) - ls = netsvc.LocalService('object_proxy') - fn = getattr(ls, method) + assert openerp.osv.osv.service, "The object_proxy class must be started with start_object_proxy." + fn = getattr(openerp.osv.osv.service, method) res = fn(db, uid, *params) return res - def new_dispatch(self,method,auth,params): - pass - - # # Wizard ID: 1 # - None = end of wizard @@ -602,13 +588,12 @@ class objects_proxy(netsvc.ExportService): class wizard(netsvc.ExportService): def __init__(self, name='wizard'): netsvc.ExportService.__init__(self,name) - self.joinGroup('web-services') self.id = 0 self.wiz_datas = {} self.wiz_name = {} self.wiz_uid = {} - def dispatch(self, method, auth, params): + def dispatch(self, method, params): (db, uid, passwd ) = params[0:3] params = params[3:] if method not in ['execute','create']: @@ -618,9 +603,6 @@ class wizard(netsvc.ExportService): res = fn(db, uid, *params) return res - def new_dispatch(self,method,auth,params): - pass - def _execute(self, db, uid, wiz_id, datas, action, context): self.wiz_datas[wiz_id].update(datas) wiz = netsvc.LocalService('wizard.'+self.wiz_name[wiz_id]) @@ -644,9 +626,9 @@ class wizard(netsvc.ExportService): if self.wiz_uid[wiz_id] == uid: return self._execute(db, uid, wiz_id, datas, action, context) else: - raise Exception, 'AccessDenied' + raise openerp.exceptions.AccessDenied() else: - raise Exception, 'WizardNotFound' + raise openerp.exceptions.Warning('Wizard not found.') # # TODO: set a maximum report number per user to avoid DOS attacks @@ -655,33 +637,64 @@ class wizard(netsvc.ExportService): # False -> True # -class ExceptionWithTraceback(Exception): - def __init__(self, msg, tb): - self.message = msg - self.traceback = tb - self.args = (msg, tb) - class report_spool(netsvc.ExportService): def __init__(self, name='report'): netsvc.ExportService.__init__(self, name) - self.joinGroup('web-services') self._reports = {} self.id = 0 self.id_protect = threading.Semaphore() - def dispatch(self, method, auth, params): + def dispatch(self, method, params): (db, uid, passwd ) = params[0:3] params = params[3:] - if method not in ['report','report_get']: + if method not in ['report', 'report_get', 'render_report']: raise KeyError("Method not supported %s" % method) security.check(db,uid,passwd) fn = getattr(self, 'exp_' + method) res = fn(db, uid, *params) return res + def exp_render_report(self, db, uid, object, ids, datas=None, context=None): + if not datas: + datas={} + if not context: + context={} + + self.id_protect.acquire() + self.id += 1 + id = self.id + self.id_protect.release() + + self._reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} + + cr = pooler.get_db(db).cursor() + import traceback + import sys + try: + obj = netsvc.LocalService('report.'+object) + (result, format) = obj.create(cr, uid, ids, datas, context) + if not result: + tb = sys.exc_info() + self._reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) + self._reports[id]['result'] = result + self._reports[id]['format'] = format + self._reports[id]['state'] = True + except Exception, exception: + + tb = sys.exc_info() + tb_s = "".join(traceback.format_exception(*tb)) + logger = netsvc.Logger() + logger.notifyChannel('web-services', netsvc.LOG_ERROR, + 'Exception: %s\n%s' % (str(exception), tb_s)) + if hasattr(exception, 'name') and hasattr(exception, 'value'): + self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) + else: + self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb) + self._reports[id]['state'] = True + cr.commit() + cr.close() - def new_dispatch(self,method,auth,params): - pass + return self._check_report(id) def exp_report(self, db, uid, object, ids, datas=None, context=None): if not datas: @@ -705,7 +718,7 @@ class report_spool(netsvc.ExportService): (result, format) = obj.create(cr, uid, ids, datas, context) if not result: tb = sys.exc_info() - self._reports[id]['exception'] = ExceptionWithTraceback('RML is not available at specified location or not enough data to print!', tb) + self._reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb) self._reports[id]['result'] = result self._reports[id]['format'] = format self._reports[id]['state'] = True @@ -717,9 +730,9 @@ class report_spool(netsvc.ExportService): logger.notifyChannel('web-services', netsvc.LOG_ERROR, 'Exception: %s\n%s' % (str(exception), tb_s)) if hasattr(exception, 'name') and hasattr(exception, 'value'): - self._reports[id]['exception'] = ExceptionWithTraceback(tools.ustr(exception.name), tools.ustr(exception.value)) + self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.ustr(exception.name), tools.ustr(exception.value)) else: - self._reports[id]['exception'] = ExceptionWithTraceback(tools.exception_to_unicode(exception), tb) + self._reports[id]['exception'] = openerp.exceptions.DeferredException(tools.exception_to_unicode(exception), tb) self._reports[id]['state'] = True cr.commit() cr.close() @@ -732,7 +745,7 @@ class report_spool(netsvc.ExportService): result = self._reports[report_id] exc = result['exception'] if exc: - self.abortResponse(exc, exc.message, 'warning', exc.traceback) + netsvc.abort_response(exc, exc.message, 'warning', exc.traceback) res = {'state': result['state']} if res['state']: if tools.config['reportgz']: diff --git a/openerp/service/websrv_lib.py b/openerp/service/websrv_lib.py index 2e098169bae..3df441458fd 100644 --- a/openerp/service/websrv_lib.py +++ b/openerp/service/websrv_lib.py @@ -52,61 +52,17 @@ class AuthProvider: def __init__(self,realm): self.realm = realm - def setupAuth(self, multi,handler): - """ Attach an AuthProxy object to handler - """ - pass - def authenticate(self, user, passwd, client_address): return False def log(self, msg): print msg -class BasicAuthProvider(AuthProvider): - def setupAuth(self, multi, handler): - if not multi.sec_realms.has_key(self.realm): - multi.sec_realms[self.realm] = BasicAuthProxy(self) - - -class AuthProxy: - """ This class will hold authentication information for a handler, - i.e. a connection - """ - def __init__(self, provider): - self.provider = provider - def checkRequest(self,handler,path = '/'): """ Check if we are allowed to process that request """ pass -class BasicAuthProxy(AuthProxy): - """ Require basic authentication.. - """ - def __init__(self,provider): - AuthProxy.__init__(self,provider) - self.auth_creds = None - self.auth_tries = 0 - - def checkRequest(self,handler,path = '/'): - if self.auth_creds: - return True - auth_str = handler.headers.get('Authorization',False) - if auth_str and auth_str.startswith('Basic '): - auth_str=auth_str[len('Basic '):] - (user,passwd) = base64.decodestring(auth_str).split(':') - self.provider.log("Found user=\"%s\", passwd=\"%s\"" %(user,passwd)) - self.auth_creds = self.provider.authenticate(user,passwd,handler.client_address) - if self.auth_creds: - return True - if self.auth_tries > 5: - self.provider.log("Failing authorization after 5 requests w/o password") - raise AuthRejectedExc("Authorization failed.") - self.auth_tries += 1 - raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm) - - class HTTPHandler(SimpleHTTPRequestHandler): def __init__(self,request, client_address, server): SimpleHTTPRequestHandler.__init__(self,request,client_address,server) @@ -125,13 +81,17 @@ class HTTPHandler(SimpleHTTPRequestHandler): def setup(self): pass +# A list of HTTPDir. +handlers = [] + class HTTPDir: """ A dispatcher class, like a virtual folder in httpd """ - def __init__(self,path,handler, auth_provider = None): + def __init__(self, path, handler, auth_provider=None, secure_only=False): self.path = path self.handler = handler self.auth_provider = auth_provider + self.secure_only = secure_only def matches(self, request): """ Test if some request matches us. If so, return @@ -140,6 +100,48 @@ class HTTPDir: return self.path return False + def instanciate_handler(self, request, client_address, server): + handler = self.handler(noconnection(request), client_address, server) + if self.auth_provider: + handler.auth_provider = self.auth_provider() + return handler + +def reg_http_service(path, handler, auth_provider=None, secure_only=False): + """ Register a HTTP handler at a given path. + + The auth_provider will be instanciated and set on the handler instances. + """ + global handlers + service = HTTPDir(path, handler, auth_provider, secure_only) + pos = len(handlers) + lastpos = pos + while pos > 0: + pos -= 1 + if handlers[pos].matches(service.path): + lastpos = pos + # we won't break here, but search all way to the top, to + # ensure there is no lesser entry that will shadow the one + # we are inserting. + handlers.insert(lastpos, service) + +def list_http_services(protocol=None): + global handlers + ret = [] + for svc in handlers: + if protocol is None or protocol == 'http' or svc.secure_only: + ret.append((svc.path, str(svc.handler))) + + return ret + +def find_http_service(path, secure=False): + global handlers + for vdir in handlers: + p = vdir.matches(path) + if p == False or (vdir.secure_only and not secure): + continue + return vdir + return None + class noconnection(object): """ a class to use instead of the real connection """ @@ -230,312 +232,3 @@ class HttpOptions: """ return opts -class MultiHTTPHandler(FixSendError, HttpOptions, BaseHTTPRequestHandler): - """ this is a multiple handler, that will dispatch each request - to a nested handler, iff it matches - - The handler will also have *one* dict of authentication proxies, - groupped by their realm. - """ - - protocol_version = "HTTP/1.1" - default_request_version = "HTTP/0.9" # compatibility with py2.5 - - auth_required_msg = """ <html><head><title>Authorization required</title></head> - <body>You must authenticate to use this service</body><html>\r\r""" - - def __init__(self, request, client_address, server): - self.in_handlers = {} - self.sec_realms = {} - SocketServer.StreamRequestHandler.__init__(self,request,client_address,server) - self.log_message("MultiHttpHandler init for %s" %(str(client_address))) - - def _handle_one_foreign(self,fore, path, auth_provider): - """ This method overrides the handle_one_request for *children* - handlers. It is required, since the first line should not be - read again.. - - """ - fore.raw_requestline = "%s %s %s\n" % (self.command, path, self.version) - if not fore.parse_request(): # An error code has been sent, just exit - return - if fore.headers.status: - self.log_error("Parse error at headers: %s", fore.headers.status) - self.close_connection = 1 - self.send_error(400,"Parse error at HTTP headers") - return - - self.request_version = fore.request_version - if auth_provider and auth_provider.realm: - try: - self.sec_realms[auth_provider.realm].checkRequest(fore,path) - except AuthRequiredExc,ae: - # Darwin 9.x.x webdav clients will report "HTTP/1.0" to us, while they support (and need) the - # authorisation features of HTTP/1.1 - if self.request_version != 'HTTP/1.1' and ('Darwin/9.' not in fore.headers.get('User-Agent', '')): - self.log_error("Cannot require auth at %s", self.request_version) - self.send_error(403) - return - self._get_ignore_body(fore) # consume any body that came, not loose sync with input - self.send_response(401,'Authorization required') - self.send_header('WWW-Authenticate','%s realm="%s"' % (ae.atype,ae.realm)) - self.send_header('Connection', 'keep-alive') - self.send_header('Content-Type','text/html') - self.send_header('Content-Length',len(self.auth_required_msg)) - self.end_headers() - self.wfile.write(self.auth_required_msg) - return - except AuthRejectedExc,e: - self.log_error("Rejected auth: %s" % e.args[0]) - self.send_error(403,e.args[0]) - self.close_connection = 1 - return - mname = 'do_' + fore.command - if not hasattr(fore, mname): - if fore.command == 'OPTIONS': - self.do_OPTIONS() - return - self.send_error(501, "Unsupported method (%r)" % fore.command) - return - fore.close_connection = 0 - method = getattr(fore, mname) - try: - method() - except (AuthRejectedExc, AuthRequiredExc): - raise - except Exception, e: - if hasattr(self, 'log_exception'): - self.log_exception("Could not run %s", mname) - else: - self.log_error("Could not run %s: %s", mname, e) - self.send_error(500, "Internal error") - # may not work if method has already sent data - fore.close_connection = 1 - self.close_connection = 1 - if hasattr(fore, '_flush'): - fore._flush() - return - - if fore.close_connection: - # print "Closing connection because of handler" - self.close_connection = fore.close_connection - if hasattr(fore, '_flush'): - fore._flush() - - - def parse_rawline(self): - """Parse a request (internal). - - The request should be stored in self.raw_requestline; the results - are in self.command, self.path, self.request_version and - self.headers. - - Return True for success, False for failure; on failure, an - error is sent back. - - """ - self.command = None # set in case of error on the first line - self.request_version = version = self.default_request_version - self.close_connection = 1 - requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] - self.requestline = requestline - words = requestline.split() - if len(words) == 3: - [command, path, version] = words - if version[:5] != 'HTTP/': - self.send_error(400, "Bad request version (%r)" % version) - return False - try: - base_version_number = version.split('/', 1)[1] - version_number = base_version_number.split(".") - # RFC 2145 section 3.1 says there can be only one "." and - # - major and minor numbers MUST be treated as - # separate integers; - # - HTTP/2.4 is a lower version than HTTP/2.13, which in - # turn is lower than HTTP/12.3; - # - Leading zeros MUST be ignored by recipients. - if len(version_number) != 2: - raise ValueError - version_number = int(version_number[0]), int(version_number[1]) - except (ValueError, IndexError): - self.send_error(400, "Bad request version (%r)" % version) - return False - if version_number >= (1, 1): - self.close_connection = 0 - if version_number >= (2, 0): - self.send_error(505, - "Invalid HTTP Version (%s)" % base_version_number) - return False - elif len(words) == 2: - [command, path] = words - self.close_connection = 1 - if command != 'GET': - self.log_error("Junk http request: %s", self.raw_requestline) - self.send_error(400, - "Bad HTTP/0.9 request type (%r)" % command) - return False - elif not words: - return False - else: - #self.send_error(400, "Bad request syntax (%r)" % requestline) - return False - self.request_version = version - self.command, self.path, self.version = command, path, version - return True - - def handle_one_request(self): - """Handle a single HTTP request. - Dispatch to the correct handler. - """ - self.request.setblocking(True) - self.raw_requestline = self.rfile.readline() - if not self.raw_requestline: - self.close_connection = 1 - # self.log_message("no requestline, connection closed?") - return - if not self.parse_rawline(): - self.log_message("Could not parse rawline.") - return - # self.parse_request(): # Do NOT parse here. the first line should be the only - - if self.path == '*' and self.command == 'OPTIONS': - # special handling of path='*', must not use any vdir at all. - if not self.parse_request(): - return - self.do_OPTIONS() - return - - for vdir in self.server.vdirs: - p = vdir.matches(self.path) - if p == False: - continue - npath = self.path[len(p):] - if not npath.startswith('/'): - npath = '/' + npath - - if not self.in_handlers.has_key(p): - self.in_handlers[p] = vdir.handler(noconnection(self.request),self.client_address,self.server) - if vdir.auth_provider: - vdir.auth_provider.setupAuth(self, self.in_handlers[p]) - hnd = self.in_handlers[p] - hnd.rfile = self.rfile - hnd.wfile = self.wfile - self.rlpath = self.raw_requestline - try: - self._handle_one_foreign(hnd,npath, vdir.auth_provider) - except IOError, e: - if e.errno == errno.EPIPE: - self.log_message("Could not complete request %s," \ - "client closed connection", self.rlpath.rstrip()) - else: - raise - return - # if no match: - self.send_error(404, "Path not found: %s" % self.path) - return - - def _get_ignore_body(self,fore): - if not fore.headers.has_key("content-length"): - return - max_chunk_size = 10*1024*1024 - size_remaining = int(fore.headers["content-length"]) - got = '' - while size_remaining: - chunk_size = min(size_remaining, max_chunk_size) - got = fore.rfile.read(chunk_size) - size_remaining -= len(got) - - -class SecureMultiHTTPHandler(MultiHTTPHandler): - def getcert_fnames(self): - """ Return a pair with the filenames of ssl cert,key - - Override this to direct to other filenames - """ - return ('server.cert','server.key') - - def setup(self): - import ssl - certfile, keyfile = self.getcert_fnames() - try: - self.connection = ssl.wrap_socket(self.request, - server_side=True, - certfile=certfile, - keyfile=keyfile, - ssl_version=ssl.PROTOCOL_SSLv23) - self.rfile = self.connection.makefile('rb', self.rbufsize) - self.wfile = self.connection.makefile('wb', self.wbufsize) - self.log_message("Secure %s connection from %s",self.connection.cipher(),self.client_address) - except Exception: - self.request.shutdown(socket.SHUT_RDWR) - raise - - def finish(self): - # With ssl connections, closing the filehandlers alone may not - # work because of ref counting. We explicitly tell the socket - # to shutdown. - MultiHTTPHandler.finish(self) - try: - self.connection.shutdown(socket.SHUT_RDWR) - except Exception: - pass - -import threading -class ConnThreadingMixIn: - """Mix-in class to handle each _connection_ in a new thread. - - This is necessary for persistent connections, where multiple - requests should be handled synchronously at each connection, but - multiple connections can run in parallel. - """ - - # Decides how threads will act upon termination of the - # main process - daemon_threads = False - - def _get_next_name(self): - return None - - def _handle_request_noblock(self): - """Start a new thread to process the request.""" - if not threading: # happens while quitting python - return - t = threading.Thread(name=self._get_next_name(), target=self._handle_request2) - if self.daemon_threads: - t.setDaemon (1) - t.start() - - def _mark_start(self, thread): - """ Mark the start of a request thread """ - pass - - def _mark_end(self, thread): - """ Mark the end of a request thread """ - pass - - def _handle_request2(self): - """Handle one request, without blocking. - - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). - """ - try: - self._mark_start(threading.currentThread()) - request, client_address = self.get_request() - if self.verify_request(request, client_address): - try: - self.process_request(request, client_address) - except Exception: - self.handle_error(request, client_address) - self.close_request(request) - except socket.error: - return - finally: - self._mark_end(threading.currentThread()) - -#eof diff --git a/openerp/sql_db.py b/openerp/sql_db.py index f4a899c8db2..ab92d7cc21d 100644 --- a/openerp/sql_db.py +++ b/openerp/sql_db.py @@ -183,6 +183,8 @@ class Cursor(object): self.__caller = False self.__closer = False + self._default_log_exceptions = True + def __del__(self): if not self.__closed: # Oops. 'self' has not been closed explicitly. @@ -199,7 +201,7 @@ class Cursor(object): self._close(True) @check - def execute(self, query, params=None, log_exceptions=True): + def execute(self, query, params=None, log_exceptions=None): if '%d' in query or '%f' in query: self.__logger.warn(query) self.__logger.warn("SQL queries cannot contain %d or %f anymore. " @@ -212,11 +214,11 @@ class Cursor(object): params = params or None res = self._obj.execute(query, params) except psycopg2.ProgrammingError, pe: - if log_exceptions: + if (self._default_log_exceptions if log_exceptions is None else log_exceptions): self.__logger.error("Programming error: %s, in query %s", pe, query) raise except Exception: - if log_exceptions: + if (self._default_log_exceptions if log_exceptions is None else log_exceptions): self.__logger.exception("bad query: %s", self._obj.query or query) raise @@ -294,6 +296,9 @@ class Cursor(object): del self._obj self.__closed = True + # Clean the underlying connection. + self._cnx.rollback() + if leak: self._cnx.leaked = True else: @@ -430,6 +435,7 @@ class ConnectionPool(object): self._debug('Put connection to %r in pool', cnx.dsn) else: self._debug('Forgot connection to %r', cnx.dsn) + cnx.close() break else: raise PoolError('This connection does not below to the pool') @@ -498,7 +504,7 @@ def db_connect(db_name): return Connection(_Pool, db_name) def close_db(db_name): - """ You might want to call openerp.netsvc.Agent.cancel(db_name) along this function.""" + """ You might want to call openerp.modules.registry.RegistryManager.delete(db_name) along this function.""" _Pool.close_all(dsn(db_name)) ct = currentThread() if hasattr(ct, 'dbname'): diff --git a/openerp/tools/config.py b/openerp/tools/config.py index 18f40e0011f..a628cc8cab0 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -24,6 +24,7 @@ import optparse import os import sys import openerp +import openerp.conf import openerp.loglevels as loglevels import logging import openerp.release as release @@ -101,8 +102,10 @@ class configmanager(object): group.add_option("-P", "--import-partial", dest="import_partial", my_default='', help="Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states.") group.add_option("--pidfile", dest="pidfile", help="file where the server pid will be stored") + group.add_option("--load", dest="server_wide_modules", help="Comma-separated list of server-wide modules default=web") parser.add_option_group(group) + # XML-RPC / HTTP group = optparse.OptionGroup(parser, "XML-RPC Configuration") group.add_option("--xmlrpc-interface", dest="xmlrpc_interface", my_default='', help="Specify the TCP IP address for the XML-RPC protocol. The empty string binds to all interfaces.") @@ -112,6 +115,7 @@ class configmanager(object): help="disable the XML-RPC protocol") parser.add_option_group(group) + # XML-RPC / HTTPS title = "XML-RPC Secure Configuration" if not self.has_ssl: title += " (disabled as ssl is unavailable)" @@ -139,6 +143,13 @@ class configmanager(object): help="disable the NETRPC protocol") parser.add_option_group(group) + # WEB + # TODO move to web addons after MetaOption merge + group = optparse.OptionGroup(parser, "Web interface Configuration") + group.add_option("--db-filter", dest="dbfilter", default='.*', + help="Filter listed database", metavar="REGEXP") + parser.add_option_group(group) + # Static HTTP group = optparse.OptionGroup(parser, "Static HTTP service") group.add_option("--static-http-enable", dest="static_http_enable", action="store_true", my_default=False, help="enable static HTTP service for serving plain HTML files") @@ -250,6 +261,12 @@ class configmanager(object): "osv_memory tables. This is a decimal value expressed in hours, " "and the default is 1 hour.", type="float") + group.add_option("--max-cron-threads", dest="max_cron_threads", my_default=4, + help="Maximum number of threads processing concurrently cron jobs.", + type="int") + group.add_option("--unaccent", dest="unaccent", my_default=False, action="store_true", + help="Use the unaccent function provided by the database when available.") + parser.add_option_group(group) # Copy all optparse options (i.e. MyOption) into self.options. @@ -258,9 +275,26 @@ class configmanager(object): self.options[option.dest] = option.my_default self.casts[option.dest] = option - self.parse_config() + self.parse_config(None, False) + + def parse_config(self, args=None, complete=True): + """ Parse the configuration file (if any) and the command-line + arguments. + + This method initializes openerp.tools.config and openerp.conf (the + former should be removed in the furture) with library-wide + configuration values. + + This method must be called before proper usage of this library can be + made. - def parse_config(self, args=None): + Typical usage of this method: + + openerp.tools.config.parse_config(sys.argv[1:]) + + :param complete: this is a hack used in __init__(), leave it to True. + + """ if args is None: args = [] opt, args = self.parser.parse_args(args) @@ -317,8 +351,8 @@ class configmanager(object): 'netrpc_interface', 'netrpc_port', 'db_maxconn', 'import_partial', 'addons_path', 'netrpc', 'xmlrpc', 'syslog', 'without_demo', 'timezone', 'xmlrpcs_interface', 'xmlrpcs_port', 'xmlrpcs', - 'secure_cert_file', 'secure_pkey_file', - 'static_http_enable', 'static_http_document_root', 'static_http_url_prefix' + 'static_http_enable', 'static_http_document_root', 'static_http_url_prefix', + 'secure_cert_file', 'secure_pkey_file', 'dbfilter' ] for arg in keys: @@ -335,7 +369,7 @@ class configmanager(object): 'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog', 'list_db', 'xmlrpcs', 'test_file', 'test_disable', 'test_commit', 'test_report_directory', - 'osv_memory_count_limit', 'osv_memory_age_limit', + 'osv_memory_count_limit', 'osv_memory_age_limit', 'max_cron_threads', 'unaccent', ] for arg in keys: @@ -417,6 +451,20 @@ class configmanager(object): if opt.save: self.save() + openerp.conf.max_cron_threads = self.options['max_cron_threads'] + + openerp.conf.addons_paths = self.options['addons_path'].split(',') + if opt.server_wide_modules: + openerp.conf.server_wide_modules = map(lambda m: m.strip(), opt.server_wide_modules.split(',')) + else: + openerp.conf.server_wide_modules = ['web'] + if complete: + openerp.modules.module.initialize_sys_path() + openerp.modules.loading.open_openerp_namespace() + # openerp.addons.__path__.extend(openerp.conf.addons_paths) # This + # is not compatible with initialize_sys_path(): import crm and + # import openerp.addons.crm load twice the module. + def _generate_pgpassfile(self): """ Generate the pgpass file with the parameters from the command line (db_host, db_user, diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index b1d23e74630..dbccbe5b217 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -45,6 +45,7 @@ from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart from email.Header import Header from email.Utils import formatdate, COMMASPACE +from email import Utils from email import Encoders from itertools import islice, izip from lxml import etree @@ -59,6 +60,7 @@ except ImportError: html2text = None import openerp.loglevels as loglevels +import openerp.pooler as pooler from config import config from cache import * @@ -280,15 +282,7 @@ email_re = re.compile(r""" """, re.VERBOSE) res_re = re.compile(r"\[([0-9]+)\]", re.UNICODE) command_re = re.compile("^Set-([a-z]+) *: *(.+)$", re.I + re.UNICODE) -reference_re = re.compile("<.*-openobject-(\\d+)@(.*)>", re.UNICODE) - -priorities = { - '1': '1 (Highest)', - '2': '2 (High)', - '3': '3 (Normal)', - '4': '4 (Low)', - '5': '5 (Lowest)', - } +reference_re = re.compile("<.*-open(?:object|erp)-(\\d+).*@(.*)>", re.UNICODE) def html2plaintext(html, body_id=None, encoding='utf-8'): """ From an HTML text, convert the HTML to plain text. @@ -354,150 +348,51 @@ def html2plaintext(html, body_id=None, encoding='utf-8'): return html -def generate_tracking_message_id(openobject_id): +def generate_tracking_message_id(res_id): """Returns a string that can be used in the Message-ID RFC822 header field Used to track the replies related to a given object thanks to the "In-Reply-To" or "References" fields that Mail User Agents will set. """ - return "<%s-openobject-%s@%s>" % (time.time(), openobject_id, socket.gethostname()) + return "<%s-openerp-%s@%s>" % (time.time(), res_id, socket.gethostname()) -def _email_send(smtp_from, smtp_to_list, message, openobject_id=None, ssl=False, debug=False): - """ Low-level method to send directly a Message through the configured smtp server. - - :param smtp_from: RFC-822 envelope FROM (not displayed to recipient) - :param smtp_to_list: RFC-822 envelope RCPT_TOs (not displayed to recipient) - :param message: an email.message.Message to send - :param debug: True if messages should be output to stderr before being sent, - and smtplib.SMTP put into debug mode. - :return: True if the mail was delivered successfully to the smtp, - else False (+ exception logged) +def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False, + attachments=None, message_id=None, references=None, openobject_id=False, debug=False, subtype='plain', headers=None, + smtp_server=None, smtp_port=None, ssl=False, smtp_user=None, smtp_password=None, cr=None, uid=None): + """Low-level function for sending an email (deprecated). + + :deprecate: since OpenERP 6.1, please use ir.mail_server.send_email() instead. + :param email_from: A string used to fill the `From` header, if falsy, + config['email_from'] is used instead. Also used for + the `Reply-To` header if `reply_to` is not provided + :param email_to: a sequence of addresses to send the mail to. """ - class WriteToLogger(object): - def __init__(self): - self.logger = loglevels.Logger() - def write(self, s): - self.logger.notifyChannel('email_send', loglevels.LOG_DEBUG, s) - - if openobject_id: - message['Message-Id'] = generate_tracking_message_id(openobject_id) + # If not cr, get cr from current thread database + if not cr: + db_name = getattr(threading.currentThread(), 'dbname', None) + if db_name: + cr = pooler.get_db_only(db_name).cursor() + else: + raise Exception("No database cursor found, please pass one explicitly") + # Send Email try: - smtp_server = config['smtp_server'] - - if smtp_server.startswith('maildir:/'): - from mailbox import Maildir - maildir_path = smtp_server[8:] - mdir = Maildir(maildir_path,factory=None, create = True) - mdir.add(message.as_string(True)) - return True - - oldstderr = smtplib.stderr - if not ssl: ssl = config.get('smtp_ssl', False) - s = smtplib.SMTP() - try: - # in case of debug, the messages are printed to stderr. - if debug: - smtplib.stderr = WriteToLogger() - - s.set_debuglevel(int(bool(debug))) # 0 or 1 - s.connect(smtp_server, config['smtp_port']) - if ssl: - s.ehlo() - s.starttls() - s.ehlo() - - if config['smtp_user'] or config['smtp_password']: - s.login(config['smtp_user'], config['smtp_password']) - - s.sendmail(smtp_from, smtp_to_list, message.as_string()) - finally: - try: - s.quit() - if debug: - smtplib.stderr = oldstderr - except Exception: - # ignored, just a consequence of the previous exception - pass - + mail_server_pool = pooler.get_pool(cr.dbname).get('ir.mail_server') + res = False + # Pack Message into MIME Object + email_msg = mail_server_pool.build_email(email_from, email_to, subject, body, email_cc, email_bcc, reply_to, + attachments, message_id, references, openobject_id, subtype, headers=headers) + + res = mail_server_pool.send_email(cr, uid or 1, email_msg, mail_server_id=None, + smtp_server=smtp_server, smtp_port=smtp_port, smtp_user=smtp_user, smtp_password=smtp_password, + smtp_encryption=('ssl' if ssl else None), debug=debug) except Exception: - _logger.error('could not deliver email', exc_info=True) + _log.exception("tools.email_send failed to deliver email") return False - - return True - - -def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False, - attach=None, openobject_id=False, ssl=False, debug=False, subtype='plain', x_headers=None, priority='3'): - - """Send an email. - - @param email_from A string used to fill the `From` header, if falsy, - config['email_from'] is used instead. Also used for - the `Reply-To` header if `reply_to` is not provided - - @param email_to a sequence of addresses to send the mail to. - """ - if x_headers is None: - x_headers = {} - - - - if not (email_from or config['email_from']): - raise ValueError("Sending an email requires either providing a sender " - "address or having configured one") - - if not email_from: email_from = config.get('email_from', False) - email_from = ustr(email_from).encode('utf-8') - - if not email_cc: email_cc = [] - if not email_bcc: email_bcc = [] - if not body: body = u'' - - email_body = ustr(body).encode('utf-8') - email_text = MIMEText(email_body or '',_subtype=subtype,_charset='utf-8') - - msg = MIMEMultipart() - - msg['Subject'] = Header(ustr(subject), 'utf-8') - msg['From'] = email_from - del msg['Reply-To'] - if reply_to: - msg['Reply-To'] = reply_to - else: - msg['Reply-To'] = msg['From'] - msg['To'] = COMMASPACE.join(email_to) - if email_cc: - msg['Cc'] = COMMASPACE.join(email_cc) - if email_bcc: - msg['Bcc'] = COMMASPACE.join(email_bcc) - msg['Date'] = formatdate(localtime=True) - - msg['X-Priority'] = priorities.get(priority, '3 (Normal)') - - # Add dynamic X Header - for key, value in x_headers.iteritems(): - msg['%s' % key] = str(value) - - if html2text and subtype == 'html': - text = html2text(email_body.decode('utf-8')).encode('utf-8') - alternative_part = MIMEMultipart(_subtype="alternative") - alternative_part.attach(MIMEText(text, _charset='utf-8', _subtype='plain')) - alternative_part.attach(email_text) - msg.attach(alternative_part) - else: - msg.attach(email_text) - - if attach: - for (fname,fcontent) in attach: - part = MIMEBase('application', "octet-stream") - part.set_payload( fcontent ) - Encoders.encode_base64(part) - part.add_header('Content-Disposition', 'attachment; filename="%s"' % (fname,)) - msg.attach(part) - - return _email_send(email_from, flatten([email_to, email_cc, email_bcc]), msg, openobject_id=openobject_id, ssl=ssl, debug=debug) + finally: + cr.close() + return res #---------------------------------------------------------- # SMS @@ -1089,10 +984,7 @@ def detect_server_timezone(): return 'UTC' def get_server_timezone(): - # timezone detection is safe in multithread, so lazy init is ok here - if (not config['timezone']): - config['timezone'] = detect_server_timezone() - return config['timezone'] + return "UTC" DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d" diff --git a/openerp/tools/yaml_import.py b/openerp/tools/yaml_import.py index 00bb79f0499..bb4ce9db87d 100644 --- a/openerp/tools/yaml_import.py +++ b/openerp/tools/yaml_import.py @@ -1,10 +1,12 @@ # -*- encoding: utf-8 -*- +import threading import types import time # used to eval time.strftime expressions from datetime import datetime, timedelta import logging import openerp.pooler as pooler +import openerp.sql_db as sql_db import misc from config import config import yaml_tag @@ -305,7 +307,7 @@ class YamlInterpreter(object): import openerp.osv as osv record, fields = node.items()[0] model = self.get_model(record.model) - if isinstance(model, osv.osv.osv_memory): + if model.is_transient(): record_dict=self.create_osv_memory_record(record, fields) else: self.validate_xml_id(record.id) @@ -331,6 +333,7 @@ class YamlInterpreter(object): def _create_record(self, model, fields): record_dict = {} + fields = fields or {} for field_name, expression in fields.items(): field_value = self._eval_field(model, field_name, expression) record_dict[field_name] = field_value @@ -800,4 +803,19 @@ def yaml_import(cr, module, yamlfile, idref=None, mode='init', noupdate=False): # keeps convention of convert.py convert_yaml_import = yaml_import +def threaded_yaml_import(db_name, module_name, file_name, delay=0): + def f(): + time.sleep(delay) + cr = None + fp = None + try: + cr = sql_db.db_connect(db_name).cursor() + fp = misc.file_open(file_name) + convert_yaml_import(cr, module_name, fp, {}, 'update', True) + finally: + if cr: cr.close() + if fp: fp.close() + threading.Thread(target=f).start() + + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/wizard/__init__.py b/openerp/wizard/__init__.py index df0b942d0df..2ed01921afa 100644 --- a/openerp/wizard/__init__.py +++ b/openerp/wizard/__init__.py @@ -44,7 +44,6 @@ class interface(netsvc.Service): def __init__(self, name): assert not self.exists('wizard.'+name), 'The wizard "%s" already exists!' % (name,) super(interface, self).__init__('wizard.'+name) - self.exportMethod(self.execute) self.wiz_name = name def translate_view(self, cr, node, state, lang): @@ -156,7 +155,7 @@ class interface(netsvc.Service): if isinstance(e, except_wizard) \ or isinstance(e, except_osv) \ or isinstance(e, except_orm): - self.abortResponse(2, e.name, 'warning', e.value) + netsvc.abort_response(2, e.name, 'warning', e.value) else: import traceback tb_s = reduce(lambda x, y: x+y, traceback.format_exception( diff --git a/openerp/workflow/wkf_service.py b/openerp/workflow/wkf_service.py index 6f5059e6817..a8d829aa546 100644 --- a/openerp/workflow/wkf_service.py +++ b/openerp/workflow/wkf_service.py @@ -27,27 +27,49 @@ import openerp.netsvc as netsvc import openerp.pooler as pooler class workflow_service(netsvc.Service): - def __init__(self, name='workflow', audience='*'): - netsvc.Service.__init__(self, name, audience) - self.exportMethod(self.trg_write) - self.exportMethod(self.trg_delete) - self.exportMethod(self.trg_create) - self.exportMethod(self.trg_validate) - self.exportMethod(self.trg_redirect) - self.exportMethod(self.trg_trigger) - self.exportMethod(self.clear_cache) + """ + Sometimes you might want to fire a signal or re-evaluate the current state + of a workflow using the service's API. You can access the workflow services + using: + + >>> import netsvc + >>> wf_service = netsvc.LocalService("workflow") + + """ + + def __init__(self, name='workflow'): + netsvc.Service.__init__(self, name) self.wkf_on_create_cache={} def clear_cache(self, cr, uid): self.wkf_on_create_cache[cr.dbname]={} def trg_write(self, uid, res_type, res_id, cr): + """ + Reevaluates the specified workflow instance. Thus if any condition for + a transition have been changed in the backend, then running ``trg_write`` + will move the workflow over that transition. + + :param res_type: the model name + :param res_id: the model instance id the workflow belongs to + :param cr: a database cursor + """ ident = (uid,res_type,res_id) cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (res_id or None,res_type or None, 'active')) for (id,) in cr.fetchall(): instance.update(cr, id, ident) def trg_trigger(self, uid, res_type, res_id, cr): + """ + Activate a trigger. + + If a workflow instance is waiting for a trigger from another model, then this + trigger can be activated if its conditions are met. + + :param res_type: the model name + :param res_id: the model instance id the workflow belongs to + :param cr: a database cursor + """ cr.execute('select instance_id from wkf_triggers where res_id=%s and model=%s', (res_id,res_type)) res = cr.fetchall() for (instance_id,) in res: @@ -56,10 +78,24 @@ class workflow_service(netsvc.Service): instance.update(cr, instance_id, ident) def trg_delete(self, uid, res_type, res_id, cr): + """ + Delete a workflow instance + + :param res_type: the model name + :param res_id: the model instance id the workflow belongs to + :param cr: a database cursor + """ ident = (uid,res_type,res_id) instance.delete(cr, ident) def trg_create(self, uid, res_type, res_id, cr): + """ + Create a new workflow instance + + :param res_type: the model name + :param res_id: the model instance id to own the created worfklow instance + :param cr: a database cursor + """ ident = (uid,res_type,res_id) self.wkf_on_create_cache.setdefault(cr.dbname, {}) if res_type in self.wkf_on_create_cache[cr.dbname]: @@ -72,6 +108,14 @@ class workflow_service(netsvc.Service): instance.create(cr, ident, wkf_id) def trg_validate(self, uid, res_type, res_id, signal, cr): + """ + Fire a signal on a given workflow instance + + :param res_type: the model name + :param res_id: the model instance id the workflow belongs to + :signal: the signal name to be fired + :param cr: a database cursor + """ result = False ident = (uid,res_type,res_id) # ids of all active workflow instances for a corresponding resource (id, model_nam) @@ -81,10 +125,19 @@ class workflow_service(netsvc.Service): result = result or res2 return result - # make all workitems which are waiting for a (subflow) workflow instance - # for the old resource point to the (first active) workflow instance for - # the new resource def trg_redirect(self, uid, res_type, res_id, new_rid, cr): + """ + Re-bind a workflow instance to another instance of the same model. + + Make all workitems which are waiting for a (subflow) workflow instance + for the old resource point to the (first active) workflow instance for + the new resource. + + :param res_type: the model name + :param res_id: the model instance id the workflow belongs to + :param new_rid: the model instance id to own the worfklow instance + :param cr: a database cursor + """ # get ids of wkf instances for the old resource (res_id) #CHECKME: shouldn't we get only active instances? cr.execute('select id, wkf_id from wkf_instance where res_id=%s and res_type=%s', (res_id, res_type)) diff --git a/openerp/wsgi.py b/openerp/wsgi.py new file mode 100644 index 00000000000..be7d2bfbdc1 --- /dev/null +++ b/openerp/wsgi.py @@ -0,0 +1,492 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2011 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 +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +""" WSGI stuffs (proof of concept for now) + +This module offers a WSGI interface to OpenERP. + +""" + +import httplib +import urllib +import xmlrpclib +import StringIO + +import logging +import os +import signal +import sys +import threading +import time +import traceback + +import openerp +import openerp.modules +import openerp.tools.config as config +import service.websrv_lib as websrv_lib + +# XML-RPC fault codes. Some care must be taken when changing these: the +# constants are also defined client-side and must remain in sync. +# User code must use the exceptions defined in ``openerp.exceptions`` (not +# create directly ``xmlrpclib.Fault`` objects). +RPC_FAULT_CODE_CLIENT_ERROR = 1 # indistinguishable from app. error. +RPC_FAULT_CODE_APPLICATION_ERROR = 1 +RPC_FAULT_CODE_WARNING = 2 +RPC_FAULT_CODE_ACCESS_DENIED = 3 +RPC_FAULT_CODE_ACCESS_ERROR = 4 + +# The new (6.1) versioned RPC paths. +XML_RPC_PATH = '/openerp/xmlrpc' +XML_RPC_PATH_1 = '/openerp/xmlrpc/1' +JSON_RPC_PATH = '/openerp/jsonrpc' +JSON_RPC_PATH_1 = '/openerp/jsonrpc/1' + +def xmlrpc_return(start_response, service, method, params, legacy_exceptions=False): + """ + Helper to call a service's method with some params, using a wsgi-supplied + ``start_response`` callback. + + This is the place to look at to see the mapping between core exceptions + and XML-RPC fault codes. + """ + # Map OpenERP core exceptions to XML-RPC fault codes. Specific exceptions + # defined in ``openerp.exceptions`` are mapped to specific fault codes; + # all the other exceptions are mapped to the generic + # RPC_FAULT_CODE_APPLICATION_ERROR value. + # This also mimics SimpleXMLRPCDispatcher._marshaled_dispatch() for + # exception handling. + try: + result = openerp.netsvc.dispatch_rpc(service, method, params) + response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False, encoding=None) + except Exception, e: + if legacy_exceptions: + response = xmlrpc_handle_exception_legacy(e) + else: + response = xmlrpc_handle_exception(e) + start_response("200 OK", [('Content-Type','text/xml'), ('Content-Length', str(len(response)))]) + return [response] + +def xmlrpc_handle_exception(e): + if isinstance(e, openerp.osv.osv.except_osv): # legacy + fault = xmlrpclib.Fault(RPC_FAULT_CODE_WARNING, openerp.tools.ustr(e.value)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.Warning): + fault = xmlrpclib.Fault(RPC_FAULT_CODE_WARNING, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance (e, openerp.exceptions.AccessError): + fault = xmlrpclib.Fault(RPC_FAULT_CODE_ACCESS_ERROR, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.AccessDenied): + fault = xmlrpclib.Fault(RPC_FAULT_CODE_ACCESS_DENIED, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.DeferredException): + info = e.traceback + # Which one is the best ? + formatted_info = "".join(traceback.format_exception(*info)) + #formatted_info = openerp.tools.exception_to_unicode(e) + '\n' + info + fault = xmlrpclib.Fault(RPC_FAULT_CODE_APPLICATION_ERROR, formatted_info) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + else: + if hasattr(e, 'message') and e.message == 'AccessDenied': # legacy + fault = xmlrpclib.Fault(RPC_FAULT_CODE_ACCESS_DENIED, str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + else: + info = sys.exc_info() + # Which one is the best ? + formatted_info = "".join(traceback.format_exception(*info)) + #formatted_info = openerp.tools.exception_to_unicode(e) + '\n' + info + fault = xmlrpclib.Fault(RPC_FAULT_CODE_APPLICATION_ERROR, formatted_info) + response = xmlrpclib.dumps(fault, allow_none=None, encoding=None) + return response + +def xmlrpc_handle_exception_legacy(e): + if isinstance(e, openerp.osv.osv.except_osv): + fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '') + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.Warning): + fault = xmlrpclib.Fault('warning -- Warning\n\n' + str(e), '') + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.AccessError): + fault = xmlrpclib.Fault('warning -- AccessError\n\n' + str(e), '') + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.AccessDenied): + fault = xmlrpclib.Fault('AccessDenied', str(e)) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + elif isinstance(e, openerp.exceptions.DeferredException): + info = e.traceback + formatted_info = "".join(traceback.format_exception(*info)) + fault = xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info) + response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) + else: + info = sys.exc_info() + formatted_info = "".join(traceback.format_exception(*info)) + fault = xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info) + response = xmlrpclib.dumps(fault, allow_none=None, encoding=None) + return response + +def wsgi_xmlrpc_1(environ, start_response): + """ The main OpenERP WSGI handler.""" + if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith(XML_RPC_PATH_1): + length = int(environ['CONTENT_LENGTH']) + data = environ['wsgi.input'].read(length) + + params, method = xmlrpclib.loads(data) + + path = environ['PATH_INFO'][len(XML_RPC_PATH_1):] + if path.startswith('/'): path = path[1:] + if path.endswith('/'): p = path[:-1] + path = path.split('/') + + # All routes are hard-coded. + + # No need for a db segment. + if len(path) == 1: + service = path[0] + + if service == 'common': + if method in ('server_version',): + service = 'db' + return xmlrpc_return(start_response, service, method, params) + + # A db segment must be given. + elif len(path) == 2: + service, db_name = path + params = (db_name,) + params + + return xmlrpc_return(start_response, service, method, params) + + # A db segment and a model segment must be given. + elif len(path) == 3 and path[0] == 'model': + service, db_name, model_name = path + params = (db_name,) + params[:2] + (model_name,) + params[2:] + service = 'object' + return xmlrpc_return(start_response, service, method, params) + + # The body has been read, need to raise an exception (not return None). + fault = xmlrpclib.Fault(RPC_FAULT_CODE_CLIENT_ERROR, '') + response = xmlrpclib.dumps(fault, allow_none=None, encoding=None) + start_response("200 OK", [('Content-Type','text/xml'), ('Content-Length', str(len(response)))]) + return [response] + +def wsgi_xmlrpc(environ, start_response): + """ WSGI handler to return the versions.""" + if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith(XML_RPC_PATH): + length = int(environ['CONTENT_LENGTH']) + data = environ['wsgi.input'].read(length) + + params, method = xmlrpclib.loads(data) + + path = environ['PATH_INFO'][len(XML_RPC_PATH):] + if path.startswith('/'): path = path[1:] + if path.endswith('/'): p = path[:-1] + path = path.split('/') + + # All routes are hard-coded. + + if len(path) == 1 and path[0] == '' and method in ('version',): + return xmlrpc_return(start_response, 'common', method, ()) + + # The body has been read, need to raise an exception (not return None). + fault = xmlrpclib.Fault(RPC_FAULT_CODE_CLIENT_ERROR, '') + response = xmlrpclib.dumps(fault, allow_none=None, encoding=None) + start_response("200 OK", [('Content-Type','text/xml'), ('Content-Length', str(len(response)))]) + return [response] + +def wsgi_xmlrpc_legacy(environ, start_response): + if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): + length = int(environ['CONTENT_LENGTH']) + data = environ['wsgi.input'].read(length) + path = environ['PATH_INFO'][len('/xmlrpc/'):] # expected to be one of db, object, ... + + params, method = xmlrpclib.loads(data) + return xmlrpc_return(start_response, path, method, params, True) + +def wsgi_jsonrpc(environ, start_response): + pass + +def wsgi_webdav(environ, start_response): + pi = environ['PATH_INFO'] + if environ['REQUEST_METHOD'] == 'OPTIONS' and pi in ['*','/']: + return return_options(environ, start_response) + elif pi.startswith('/webdav'): + http_dir = websrv_lib.find_http_service(pi) + if http_dir: + path = pi[len(http_dir.path):] + if path.startswith('/'): + environ['PATH_INFO'] = path + else: + environ['PATH_INFO'] = '/' + path + return http_to_wsgi(http_dir)(environ, start_response) + +def return_options(environ, start_response): + # Microsoft specific header, see + # http://www.ibm.com/developerworks/rational/library/2089.html + if 'Microsoft' in environ.get('User-Agent', ''): + option = [('MS-Author-Via', 'DAV')] + else: + option = [] + options += [('DAV', '1 2'), ('Allow', 'GET HEAD PROPFIND OPTIONS REPORT')] + start_response("200 OK", [('Content-Length', str(0))] + options) + return [] + +def http_to_wsgi(http_dir): + """ + Turn a BaseHTTPRequestHandler into a WSGI entry point. + + Actually the argument is not a bare BaseHTTPRequestHandler but is wrapped + (as a class, so it needs to be instanciated) in a HTTPDir. + + This code is adapted from wbsrv_lib.MultiHTTPHandler._handle_one_foreign(). + It is a temporary solution: the HTTP sub-handlers (in particular the + document_webdav addon) have to be WSGIfied. + """ + def wsgi_handler(environ, start_response): + + # Extract from the WSGI environment the necessary data. + scheme = environ['wsgi.url_scheme'] + + headers = {} + for key, value in environ.items(): + if key.startswith('HTTP_'): + key = key[5:].replace('_', '-').title() + headers[key] = value + if key == 'CONTENT_LENGTH': + key = key.replace('_', '-').title() + headers[key] = value + if environ.get('Content-Type'): + headers['Content-Type'] = environ['Content-Type'] + + path = urllib.quote(environ.get('PATH_INFO', '')) + if environ.get('QUERY_STRING'): + path += '?' + environ['QUERY_STRING'] + + request_version = 'HTTP/1.1' # TODO + request_line = "%s %s %s\n" % (environ['REQUEST_METHOD'], path, request_version) + + class Dummy(object): + pass + + # Let's pretend we have a server to hand to the handler. + server = Dummy() + server.server_name = environ['SERVER_NAME'] + server.server_port = int(environ['SERVER_PORT']) + + # Initialize the underlying handler and associated auth. provider. + con = openerp.service.websrv_lib.noconnection(environ['wsgi.input']) + handler = http_dir.instanciate_handler(con, environ['REMOTE_ADDR'], server) + + # Populate the handler as if it is called by a regular HTTP server + # and the request is already parsed. + handler.wfile = StringIO.StringIO() + handler.rfile = environ['wsgi.input'] + handler.headers = headers + handler.command = environ['REQUEST_METHOD'] + handler.path = path + handler.request_version = request_version + handler.close_connection = 1 + handler.raw_requestline = request_line + handler.requestline = request_line + + # Handle authentication if there is an auth. provider associated to + # the handler. + if hasattr(handler, 'auth_provider'): + try: + handler.auth_provider.checkRequest(handler, path) + except websrv_lib.AuthRequiredExc, ae: + # Darwin 9.x.x webdav clients will report "HTTP/1.0" to us, while they support (and need) the + # authorisation features of HTTP/1.1 + if request_version != 'HTTP/1.1' and ('Darwin/9.' not in handler.headers.get('User-Agent', '')): + start_response("403 Forbidden", []) + return [] + start_response("401 Authorization required", [ + ('WWW-Authenticate', '%s realm="%s"' % (ae.atype,ae.realm)), + # ('Connection', 'keep-alive'), + ('Content-Type', 'text/html'), + ('Content-Length', 4), # len(self.auth_required_msg) + ]) + return ['Blah'] # self.auth_required_msg + except websrv_lib.AuthRejectedExc,e: + start_response("403 %s" % (e.args[0],), []) + return [] + + method_name = 'do_' + handler.command + + # Support the OPTIONS method even when not provided directly by the + # handler. TODO I would prefer to remove it and fix the handler if + # needed. + if not hasattr(handler, method_name): + if handler.command == 'OPTIONS': + return return_options(environ, start_response) + start_response("501 Unsupported method (%r)" % handler.command, []) + return [] + + # Finally, call the handler's method. + try: + method = getattr(handler, method_name) + method() + # The DAV handler buffers its output and provides a _flush() + # method. + getattr(handler, '_flush', lambda: None)() + response = parse_http_response(handler.wfile.getvalue()) + response_headers = response.getheaders() + body = response.read() + start_response(str(response.status) + ' ' + response.reason, response_headers) + return [body] + except (websrv_lib.AuthRejectedExc, websrv_lib.AuthRequiredExc): + raise + except Exception, e: + start_response("500 Internal error", []) + return [] + + return wsgi_handler + +def parse_http_response(s): + """ Turn a HTTP response string into a httplib.HTTPResponse object.""" + class DummySocket(StringIO.StringIO): + """ + This is used to provide a StringIO to httplib.HTTPResponse + which, instead of taking a file object, expects a socket and + uses its makefile() method. + """ + def makefile(self, *args, **kw): + return self + response = httplib.HTTPResponse(DummySocket(s)) + response.begin() + return response + +# WSGI handlers registered through the register_wsgi_handler() function below. +module_handlers = [] + +def register_wsgi_handler(handler): + """ Register a WSGI handler. + + Handlers are tried in the order they are added. We might provide a way to + register a handler for specific routes later. + """ + module_handlers.append(handler) + +def application(environ, start_response): + """ WSGI entry point.""" + + # Try all handlers until one returns some result (i.e. not None). + wsgi_handlers = [ + wsgi_xmlrpc_1, + wsgi_xmlrpc, + wsgi_jsonrpc, + wsgi_xmlrpc_legacy, + wsgi_webdav + ] + module_handlers + for handler in wsgi_handlers: + result = handler(environ, start_response) + if result is None: + continue + return result + + # We never returned from the loop. + response = 'No handler found.\n' + start_response('404 Not Found', [('Content-Type', 'text/plain'), ('Content-Length', str(len(response)))]) + return [response] + +# The WSGI server, started by start_server(), stopped by stop_server(). +httpd = None + +def serve(): + """ Serve HTTP requests via werkzeug development server. + + If werkzeug can not be imported, we fall back to wsgiref's simple_server. + + Calling this function is blocking, you might want to call it in its own + thread. + """ + + global httpd + + # TODO Change the xmlrpc_* options to http_* + interface = config['xmlrpc_interface'] or '0.0.0.0' + port = config['xmlrpc_port'] + try: + import werkzeug.serving + httpd = werkzeug.serving.make_server(interface, port, application, threaded=True) + logging.getLogger('wsgi').info('HTTP service (werkzeug) running on %s:%s', interface, port) + except ImportError, e: + import wsgiref.simple_server + logging.getLogger('wsgi').warn('Werkzeug module unavailable, falling back to wsgiref.') + httpd = wsgiref.simple_server.make_server(interface, port, application) + logging.getLogger('wsgi').info('HTTP service (wsgiref) running on %s:%s', interface, port) + + httpd.serve_forever() + +def start_server(): + """ Call serve() in its own thread. + + The WSGI server can be shutdown with stop_server() below. + """ + threading.Thread(target=openerp.wsgi.serve).start() + +def stop_server(): + """ Initiate the shutdown of the WSGI server. + + The server is supposed to have been started by start_server() above. + """ + if httpd: + httpd.shutdown() + +# Master process id, can be used for signaling. +arbiter_pid = None + +# Application setup before we can spawn any worker process. +# This is suitable for e.g. gunicorn's on_starting hook. +def on_starting(server): + global arbiter_pid + arbiter_pid = os.getpid() # TODO check if this is true even after replacing the executable + config = openerp.tools.config + #openerp.tools.cache = kill_workers_cache + openerp.netsvc.init_logger() + openerp.osv.osv.start_object_proxy() + openerp.service.web_services.start_web_services() + +# Install our own signal handler on the master process. +def when_ready(server): + # Hijack gunicorn's SIGWINCH handling; we can choose another one. + signal.signal(signal.SIGWINCH, make_winch_handler(server)) + +# Our signal handler will signal a SGIQUIT to all workers. +def make_winch_handler(server): + def handle_winch(sig, fram): + server.kill_workers(signal.SIGQUIT) # This is gunicorn specific. + return handle_winch + +# Kill gracefuly the workers (e.g. because we want to clear their cache). +# This is done by signaling a SIGWINCH to the master process, so it can be +# called by the workers themselves. +def kill_workers(): + try: + os.kill(arbiter_pid, signal.SIGWINCH) + except OSError, e: + if e.errno == errno.ESRCH: # no such pid + return + raise + +class kill_workers_cache(openerp.tools.ormcache): + def clear(self, dbname, *args, **kwargs): + kill_workers() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/pixmaps/openerp-intro.bmp b/pixmaps/openerp-intro.bmp Binary files differdeleted file mode 100644 index 8d3c9340c9b..00000000000 --- a/pixmaps/openerp-intro.bmp +++ /dev/null diff --git a/pixmaps/openerp-slogan.bmp b/pixmaps/openerp-slogan.bmp Binary files differdeleted file mode 100644 index a3cffd104f2..00000000000 --- a/pixmaps/openerp-slogan.bmp +++ /dev/null diff --git a/python25-compat/BaseHTTPServer.py b/python25-compat/BaseHTTPServer.py deleted file mode 100644 index 5f2d558b689..00000000000 --- a/python25-compat/BaseHTTPServer.py +++ /dev/null @@ -1,587 +0,0 @@ -"""HTTP server base class. - -Note: the class in this module doesn't implement any HTTP request; see -SimpleHTTPServer for simple implementations of GET, HEAD and POST -(including CGI scripts). It does, however, optionally implement HTTP/1.1 -persistent connections, as of version 0.3. - -Contents: - -- BaseHTTPRequestHandler: HTTP request handler base class -- test: test function - -XXX To do: - -- log requests even later (to capture byte count) -- log user-agent header and other interesting goodies -- send error log to separate file -""" - - -# See also: -# -# HTTP Working Group T. Berners-Lee -# INTERNET-DRAFT R. T. Fielding -# <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen -# Expires September 8, 1995 March 8, 1995 -# -# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt -# -# and -# -# Network Working Group R. Fielding -# Request for Comments: 2616 et al -# Obsoletes: 2068 June 1999 -# Category: Standards Track -# -# URL: http://www.faqs.org/rfcs/rfc2616.html - -# Log files -# --------- -# -# Here's a quote from the NCSA httpd docs about log file format. -# -# | The logfile format is as follows. Each line consists of: -# | -# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb -# | -# | host: Either the DNS name or the IP number of the remote client -# | rfc931: Any information returned by identd for this person, -# | - otherwise. -# | authuser: If user sent a userid for authentication, the user name, -# | - otherwise. -# | DD: Day -# | Mon: Month (calendar name) -# | YYYY: Year -# | hh: hour (24-hour format, the machine's timezone) -# | mm: minutes -# | ss: seconds -# | request: The first line of the HTTP request as sent by the client. -# | ddd: the status code returned by the server, - if not available. -# | bbbb: the total number of bytes sent, -# | *not including the HTTP/1.0 header*, - if not available -# | -# | You can determine the name of the file accessed through request. -# -# (Actually, the latter is only true if you know the server configuration -# at the time the request was made!) - -__version__ = "0.3" - -__all__ = ["HTTPServer", "BaseHTTPRequestHandler"] - -import sys -import time -import socket # For gethostbyaddr() -import mimetools -import SocketServer - -# Default error message template -DEFAULT_ERROR_MESSAGE = """\ -<head> -<title>Error response</title> -</head> -<body> -<h1>Error response</h1> -<p>Error code %(code)d. -<p>Message: %(message)s. -<p>Error code explanation: %(code)s = %(explain)s. -</body> -""" - -DEFAULT_ERROR_CONTENT_TYPE = "text/html" - -def _quote_html(html): - return html.replace("&", "&").replace("<", "<").replace(">", ">") - -class HTTPServer(SocketServer.TCPServer): - - allow_reuse_address = 1 # Seems to make sense in testing environment - - def server_bind(self): - """Override server_bind to store the server name.""" - SocketServer.TCPServer.server_bind(self) - host, port = self.socket.getsockname()[:2] - self.server_name = socket.getfqdn(host) - self.server_port = port - - -class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): - - """HTTP request handler base class. - - The following explanation of HTTP serves to guide you through the - code as well as to expose any misunderstandings I may have about - HTTP (so you don't need to read the code to figure out I'm wrong - :-). - - HTTP (HyperText Transfer Protocol) is an extensible protocol on - top of a reliable stream transport (e.g. TCP/IP). The protocol - recognizes three parts to a request: - - 1. One line identifying the request type and path - 2. An optional set of RFC-822-style headers - 3. An optional data part - - The headers and data are separated by a blank line. - - The first line of the request has the form - - <command> <path> <version> - - where <command> is a (case-sensitive) keyword such as GET or POST, - <path> is a string containing path information for the request, - and <version> should be the string "HTTP/1.0" or "HTTP/1.1". - <path> is encoded using the URL encoding scheme (using %xx to signify - the ASCII character with hex code xx). - - The specification specifies that lines are separated by CRLF but - for compatibility with the widest range of clients recommends - servers also handle LF. Similarly, whitespace in the request line - is treated sensibly (allowing multiple spaces between components - and allowing trailing whitespace). - - Similarly, for output, lines ought to be separated by CRLF pairs - but most clients grok LF characters just fine. - - If the first line of the request has the form - - <command> <path> - - (i.e. <version> is left out) then this is assumed to be an HTTP - 0.9 request; this form has no optional headers and data part and - the reply consists of just the data. - - The reply form of the HTTP 1.x protocol again has three parts: - - 1. One line giving the response code - 2. An optional set of RFC-822-style headers - 3. The data - - Again, the headers and data are separated by a blank line. - - The response code line has the form - - <version> <responsecode> <responsestring> - - where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"), - <responsecode> is a 3-digit response code indicating success or - failure of the request, and <responsestring> is an optional - human-readable string explaining what the response code means. - - This server parses the request and the headers, and then calls a - function specific to the request type (<command>). Specifically, - a request SPAM will be handled by a method do_SPAM(). If no - such method exists the server sends an error response to the - client. If it exists, it is called with no arguments: - - do_SPAM() - - Note that the request name is case sensitive (i.e. SPAM and spam - are different requests). - - The various request details are stored in instance variables: - - - client_address is the client IP address in the form (host, - port); - - - command, path and version are the broken-down request line; - - - headers is an instance of mimetools.Message (or a derived - class) containing the header information; - - - rfile is a file object open for reading positioned at the - start of the optional input data part; - - - wfile is a file object open for writing. - - IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING! - - The first thing to be written must be the response line. Then - follow 0 or more header lines, then a blank line, and then the - actual data (if any). The meaning of the header lines depends on - the command executed by the server; in most cases, when data is - returned, there should be at least one header line of the form - - Content-type: <type>/<subtype> - - where <type> and <subtype> should be registered MIME types, - e.g. "text/html" or "text/plain". - - """ - - # The Python system version, truncated to its first component. - sys_version = "Python/" + sys.version.split()[0] - - # The server software version. You may want to override this. - # The format is multiple whitespace-separated strings, - # where each string is of the form name[/version]. - server_version = "BaseHTTP/" + __version__ - - # The default request version. This only affects responses up until - # the point where the request line is parsed, so it mainly decides what - # the client gets back when sending a malformed request line. - # Most web servers default to HTTP 0.9, i.e. don't send a status line. - default_request_version = "HTTP/0.9" - - def parse_request(self): - """Parse a request (internal). - - The request should be stored in self.raw_requestline; the results - are in self.command, self.path, self.request_version and - self.headers. - - Return True for success, False for failure; on failure, an - error is sent back. - - """ - self.command = None # set in case of error on the first line - self.request_version = version = self.default_request_version - self.close_connection = 1 - requestline = self.raw_requestline - if requestline[-2:] == '\r\n': - requestline = requestline[:-2] - elif requestline[-1:] == '\n': - requestline = requestline[:-1] - self.requestline = requestline - words = requestline.split() - if len(words) == 3: - [command, path, version] = words - if version[:5] != 'HTTP/': - self.send_error(400, "Bad request version (%r)" % version) - return False - try: - base_version_number = version.split('/', 1)[1] - version_number = base_version_number.split(".") - # RFC 2145 section 3.1 says there can be only one "." and - # - major and minor numbers MUST be treated as - # separate integers; - # - HTTP/2.4 is a lower version than HTTP/2.13, which in - # turn is lower than HTTP/12.3; - # - Leading zeros MUST be ignored by recipients. - if len(version_number) != 2: - raise ValueError - version_number = int(version_number[0]), int(version_number[1]) - except (ValueError, IndexError): - self.send_error(400, "Bad request version (%r)" % version) - return False - if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": - self.close_connection = 0 - if version_number >= (2, 0): - self.send_error(505, - "Invalid HTTP Version (%s)" % base_version_number) - return False - elif len(words) == 2: - [command, path] = words - self.close_connection = 1 - if command != 'GET': - self.send_error(400, - "Bad HTTP/0.9 request type (%r)" % command) - return False - elif not words: - return False - else: - self.send_error(400, "Bad request syntax (%r)" % requestline) - return False - self.command, self.path, self.request_version = command, path, version - - # Examine the headers and look for a Connection directive - self.headers = self.MessageClass(self.rfile, 0) - - conntype = self.headers.get('Connection', "") - if conntype.lower() == 'close': - self.close_connection = 1 - elif (conntype.lower() == 'keep-alive' and - self.protocol_version >= "HTTP/1.1"): - self.close_connection = 0 - return True - - def handle_one_request(self): - """Handle a single HTTP request. - - You normally don't need to override this method; see the class - __doc__ string for information on how to handle specific HTTP - commands such as GET and POST. - - """ - self.raw_requestline = self.rfile.readline() - if not self.raw_requestline: - self.close_connection = 1 - return - if not self.parse_request(): # An error code has been sent, just exit - return - mname = 'do_' + self.command - if not hasattr(self, mname): - self.send_error(501, "Unsupported method (%r)" % self.command) - return - method = getattr(self, mname) - method() - - def handle(self): - """Handle multiple requests if necessary.""" - self.close_connection = 1 - - self.handle_one_request() - while not self.close_connection: - self.handle_one_request() - - def send_error(self, code, message=None): - """Send and log an error reply. - - Arguments are the error code, and a detailed message. - The detailed message defaults to the short entry matching the - response code. - - This sends an error response (so it must be called before any - output has been generated), logs the error, and finally sends - a piece of HTML explaining the error to the user. - - """ - - try: - short, long = self.responses[code] - except KeyError: - short, long = '???', '???' - if message is None: - message = short - explain = long - self.log_error("code %d, message %s", code, message) - # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201) - content = (self.error_message_format % - {'code': code, 'message': _quote_html(message), 'explain': explain}) - self.send_response(code, message) - self.send_header("Content-Type", self.error_content_type) - self.send_header('Connection', 'close') - self.end_headers() - if self.command != 'HEAD' and code >= 200 and code not in (204, 304): - self.wfile.write(content) - - error_message_format = DEFAULT_ERROR_MESSAGE - error_content_type = DEFAULT_ERROR_CONTENT_TYPE - - def send_response(self, code, message=None): - """Send the response header and log the response code. - - Also send two standard headers with the server software - version and the current date. - - """ - self.log_request(code) - if message is None: - if code in self.responses: - message = self.responses[code][0] - else: - message = '' - if self.request_version != 'HTTP/0.9': - self.wfile.write("%s %d %s\r\n" % - (self.protocol_version, code, message)) - # print (self.protocol_version, code, message) - self.send_header('Server', self.version_string()) - self.send_header('Date', self.date_time_string()) - - def send_header(self, keyword, value): - """Send a MIME header.""" - if self.request_version != 'HTTP/0.9': - self.wfile.write("%s: %s\r\n" % (keyword, value)) - - if keyword.lower() == 'connection': - if value.lower() == 'close': - self.close_connection = 1 - elif value.lower() == 'keep-alive': - self.close_connection = 0 - - def end_headers(self): - """Send the blank line ending the MIME headers.""" - if self.request_version != 'HTTP/0.9': - self.wfile.write("\r\n") - - def log_request(self, code='-', size='-'): - """Log an accepted request. - - This is called by send_response(). - - """ - - self.log_message('"%s" %s %s', - self.requestline, str(code), str(size)) - - def log_error(self, format, *args): - """Log an error. - - This is called when a request cannot be fulfilled. By - default it passes the message on to log_message(). - - Arguments are the same as for log_message(). - - XXX This should go to the separate error log. - - """ - - self.log_message(format, *args) - - def log_message(self, format, *args): - """Log an arbitrary message. - - This is used by all other logging functions. Override - it if you have specific logging wishes. - - The first argument, FORMAT, is a format string for the - message to be logged. If the format string contains - any % escapes requiring parameters, they should be - specified as subsequent arguments (it's just like - printf!). - - The client host and current date/time are prefixed to - every message. - - """ - - sys.stderr.write("%s - - [%s] %s\n" % - (self.address_string(), - self.log_date_time_string(), - format%args)) - - def version_string(self): - """Return the server software version string.""" - return self.server_version + ' ' + self.sys_version - - def date_time_string(self, timestamp=None): - """Return the current date and time formatted for a message header.""" - if timestamp is None: - timestamp = time.time() - year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) - s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( - self.weekdayname[wd], - day, self.monthname[month], year, - hh, mm, ss) - return s - - def log_date_time_string(self): - """Return the current time formatted for logging.""" - now = time.time() - year, month, day, hh, mm, ss, x, y, z = time.localtime(now) - s = "%02d/%3s/%04d %02d:%02d:%02d" % ( - day, self.monthname[month], year, hh, mm, ss) - return s - - weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - - monthname = [None, - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - - def address_string(self): - """Return the client address formatted for logging. - - This version looks up the full hostname using gethostbyaddr(), - and tries to find a name that contains at least one dot. - - """ - - host, port = self.client_address[:2] - return socket.getfqdn(host) - - # Essentially static class variables - - # The version of the HTTP protocol we support. - # Set this to HTTP/1.1 to enable automatic keepalive - protocol_version = "HTTP/1.0" - - # The Message-like class used to parse headers - MessageClass = mimetools.Message - - # Table mapping response codes to messages; entries have the - # form {code: (shortmessage, longmessage)}. - # See RFC 2616. - responses = { - 100: ('Continue', 'Request received, please continue'), - 101: ('Switching Protocols', - 'Switching to new protocol; obey Upgrade header'), - - 200: ('OK', 'Request fulfilled, document follows'), - 201: ('Created', 'Document created, URL follows'), - 202: ('Accepted', - 'Request accepted, processing continues off-line'), - 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), - 204: ('No Content', 'Request fulfilled, nothing follows'), - 205: ('Reset Content', 'Clear input form for further input.'), - 206: ('Partial Content', 'Partial content follows.'), - - 300: ('Multiple Choices', - 'Object has several resources -- see URI list'), - 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), - 302: ('Found', 'Object moved temporarily -- see URI list'), - 303: ('See Other', 'Object moved -- see Method and URL list'), - 304: ('Not Modified', - 'Document has not changed since given time'), - 305: ('Use Proxy', - 'You must use proxy specified in Location to access this ' - 'resource.'), - 307: ('Temporary Redirect', - 'Object moved temporarily -- see URI list'), - - 400: ('Bad Request', - 'Bad request syntax or unsupported method'), - 401: ('Unauthorized', - 'No permission -- see authorization schemes'), - 402: ('Payment Required', - 'No payment -- see charging schemes'), - 403: ('Forbidden', - 'Request forbidden -- authorization will not help'), - 404: ('Not Found', 'Nothing matches the given URI'), - 405: ('Method Not Allowed', - 'Specified method is invalid for this server.'), - 406: ('Not Acceptable', 'URI not available in preferred format.'), - 407: ('Proxy Authentication Required', 'You must authenticate with ' - 'this proxy before proceeding.'), - 408: ('Request Timeout', 'Request timed out; try again later.'), - 409: ('Conflict', 'Request conflict.'), - 410: ('Gone', - 'URI no longer exists and has been permanently removed.'), - 411: ('Length Required', 'Client must specify Content-Length.'), - 412: ('Precondition Failed', 'Precondition in headers is false.'), - 413: ('Request Entity Too Large', 'Entity is too large.'), - 414: ('Request-URI Too Long', 'URI is too long.'), - 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), - 416: ('Requested Range Not Satisfiable', - 'Cannot satisfy request range.'), - 417: ('Expectation Failed', - 'Expect condition could not be satisfied.'), - - 500: ('Internal Server Error', 'Server got itself in trouble'), - 501: ('Not Implemented', - 'Server does not support this operation'), - 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), - 503: ('Service Unavailable', - 'The server cannot process the request due to a high load'), - 504: ('Gateway Timeout', - 'The gateway server did not receive a timely response'), - 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), - } - - -def test(HandlerClass = BaseHTTPRequestHandler, - ServerClass = HTTPServer, protocol="HTTP/1.0"): - """Test the HTTP request handler class. - - This runs an HTTP server on port 8000 (or the first command line - argument). - - """ - - if sys.argv[1:]: - port = int(sys.argv[1]) - else: - port = 8000 - server_address = ('', port) - - HandlerClass.protocol_version = protocol - httpd = ServerClass(server_address, HandlerClass) - - sa = httpd.socket.getsockname() - print "Serving HTTP on", sa[0], "port", sa[1], "..." - httpd.serve_forever() - - -if __name__ == '__main__': - test() diff --git a/python25-compat/SimpleXMLRPCServer.py b/python25-compat/SimpleXMLRPCServer.py deleted file mode 100644 index 43757a03dda..00000000000 --- a/python25-compat/SimpleXMLRPCServer.py +++ /dev/null @@ -1,611 +0,0 @@ -"""Simple XML-RPC Server. - -This module can be used to create simple XML-RPC servers -by creating a server and either installing functions, a -class instance, or by extending the SimpleXMLRPCServer -class. - -It can also be used to handle XML-RPC requests in a CGI -environment using CGIXMLRPCRequestHandler. - -A list of possible usage patterns follows: - -1. Install functions: - -server = SimpleXMLRPCServer(("localhost", 8000)) -server.register_function(pow) -server.register_function(lambda x,y: x+y, 'add') -server.serve_forever() - -2. Install an instance: - -class MyFuncs: - def __init__(self): - # make all of the string functions available through - # string.func_name - import string - self.string = string - def _listMethods(self): - # implement this method so that system.listMethods - # knows to advertise the strings methods - return list_public_methods(self) + \ - ['string.' + method for method in list_public_methods(self.string)] - def pow(self, x, y): return pow(x, y) - def add(self, x, y) : return x + y - -server = SimpleXMLRPCServer(("localhost", 8000)) -server.register_introspection_functions() -server.register_instance(MyFuncs()) -server.serve_forever() - -3. Install an instance with custom dispatch method: - -class Math: - def _listMethods(self): - # this method must be present for system.listMethods - # to work - return ['add', 'pow'] - def _methodHelp(self, method): - # this method must be present for system.methodHelp - # to work - if method == 'add': - return "add(2,3) => 5" - elif method == 'pow': - return "pow(x, y[, z]) => number" - else: - # By convention, return empty - # string if no help is available - return "" - def _dispatch(self, method, params): - if method == 'pow': - return pow(*params) - elif method == 'add': - return params[0] + params[1] - else: - raise 'bad method' - -server = SimpleXMLRPCServer(("localhost", 8000)) -server.register_introspection_functions() -server.register_instance(Math()) -server.serve_forever() - -4. Subclass SimpleXMLRPCServer: - -class MathServer(SimpleXMLRPCServer): - def _dispatch(self, method, params): - try: - # We are forcing the 'export_' prefix on methods that are - # callable through XML-RPC to prevent potential security - # problems - func = getattr(self, 'export_' + method) - except AttributeError: - raise Exception('method "%s" is not supported' % method) - else: - return func(*params) - - def export_add(self, x, y): - return x + y - -server = MathServer(("localhost", 8000)) -server.serve_forever() - -5. CGI script: - -server = CGIXMLRPCRequestHandler() -server.register_function(pow) -server.handle_request() -""" - -# Written by Brian Quinlan (brian@sweetapp.com). -# Based on code written by Fredrik Lundh. - -import xmlrpclib -from xmlrpclib import Fault -import SocketServer -import BaseHTTPServer -import sys -import os -import traceback -try: - import fcntl -except ImportError: - fcntl = None - -def resolve_dotted_attribute(obj, attr, allow_dotted_names=True): - """resolve_dotted_attribute(a, 'b.c.d') => a.b.c.d - - Resolves a dotted attribute name to an object. Raises - an AttributeError if any attribute in the chain starts with a '_'. - - If the optional allow_dotted_names argument is false, dots are not - supported and this function operates similar to getattr(obj, attr). - """ - - if allow_dotted_names: - attrs = attr.split('.') - else: - attrs = [attr] - - for i in attrs: - if i.startswith('_'): - raise AttributeError( - 'attempt to access private attribute "%s"' % i - ) - else: - obj = getattr(obj,i) - return obj - -def list_public_methods(obj): - """Returns a list of attribute strings, found in the specified - object, which represent callable attributes""" - - return [member for member in dir(obj) - if not member.startswith('_') and - hasattr(getattr(obj, member), '__call__')] - -def remove_duplicates(lst): - """remove_duplicates([2,2,2,1,3,3]) => [3,1,2] - - Returns a copy of a list without duplicates. Every list - item must be hashable and the order of the items in the - resulting list is not defined. - """ - u = {} - for x in lst: - u[x] = 1 - - return u.keys() - -class SimpleXMLRPCDispatcher: - """Mix-in class that dispatches XML-RPC requests. - - This class is used to register XML-RPC method handlers - and then to dispatch them. There should never be any - reason to instantiate this class directly. - """ - - def __init__(self, allow_none, encoding): - self.funcs = {} - self.instance = None - self.allow_none = allow_none - self.encoding = encoding - - def register_instance(self, instance, allow_dotted_names=False): - """Registers an instance to respond to XML-RPC requests. - - Only one instance can be installed at a time. - - If the registered instance has a _dispatch method then that - method will be called with the name of the XML-RPC method and - its parameters as a tuple - e.g. instance._dispatch('add',(2,3)) - - If the registered instance does not have a _dispatch method - then the instance will be searched to find a matching method - and, if found, will be called. Methods beginning with an '_' - are considered private and will not be called by - SimpleXMLRPCServer. - - If a registered function matches a XML-RPC request, then it - will be called instead of the registered instance. - - If the optional allow_dotted_names argument is true and the - instance does not have a _dispatch method, method names - containing dots are supported and resolved, as long as none of - the name segments start with an '_'. - - *** SECURITY WARNING: *** - - Enabling the allow_dotted_names options allows intruders - to access your module's global variables and may allow - intruders to execute arbitrary code on your machine. Only - use this option on a secure, closed network. - - """ - - self.instance = instance - self.allow_dotted_names = allow_dotted_names - - def register_function(self, function, name = None): - """Registers a function to respond to XML-RPC requests. - - The optional name argument can be used to set a Unicode name - for the function. - """ - - if name is None: - name = function.__name__ - self.funcs[name] = function - - def register_introspection_functions(self): - """Registers the XML-RPC introspection methods in the system - namespace. - - see http://xmlrpc.usefulinc.com/doc/reserved.html - """ - - self.funcs.update({'system.listMethods' : self.system_listMethods, - 'system.methodSignature' : self.system_methodSignature, - 'system.methodHelp' : self.system_methodHelp}) - - def register_multicall_functions(self): - """Registers the XML-RPC multicall method in the system - namespace. - - see http://www.xmlrpc.com/discuss/msgReader$1208""" - - self.funcs.update({'system.multicall' : self.system_multicall}) - - def _marshaled_dispatch(self, data, dispatch_method = None): - """Dispatches an XML-RPC method from marshalled (XML) data. - - XML-RPC methods are dispatched from the marshalled (XML) data - using the _dispatch method and the result is returned as - marshalled data. For backwards compatibility, a dispatch - function can be provided as an argument (see comment in - SimpleXMLRPCRequestHandler.do_POST) but overriding the - existing method through subclassing is the prefered means - of changing method dispatch behavior. - """ - - try: - params, method = xmlrpclib.loads(data) - - # generate response - if dispatch_method is not None: - response = dispatch_method(method, params) - else: - response = self._dispatch(method, params) - # wrap response in a singleton tuple - response = (response,) - response = xmlrpclib.dumps(response, methodresponse=1, - allow_none=self.allow_none, encoding=self.encoding) - except Fault, fault: - response = xmlrpclib.dumps(fault, allow_none=self.allow_none, - encoding=self.encoding) - except: - # report exception back to server - exc_type, exc_value, exc_tb = sys.exc_info() - response = xmlrpclib.dumps( - xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)), - encoding=self.encoding, allow_none=self.allow_none, - ) - - return response - - def system_listMethods(self): - """system.listMethods() => ['add', 'subtract', 'multiple'] - - Returns a list of the methods supported by the server.""" - - methods = self.funcs.keys() - if self.instance is not None: - # Instance can implement _listMethod to return a list of - # methods - if hasattr(self.instance, '_listMethods'): - methods = remove_duplicates( - methods + self.instance._listMethods() - ) - # if the instance has a _dispatch method then we - # don't have enough information to provide a list - # of methods - elif not hasattr(self.instance, '_dispatch'): - methods = remove_duplicates( - methods + list_public_methods(self.instance) - ) - methods.sort() - return methods - - def system_methodSignature(self, method_name): - """system.methodSignature('add') => [double, int, int] - - Returns a list describing the signature of the method. In the - above example, the add method takes two integers as arguments - and returns a double result. - - This server does NOT support system.methodSignature.""" - - # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html - - return 'signatures not supported' - - def system_methodHelp(self, method_name): - """system.methodHelp('add') => "Adds two integers together" - - Returns a string containing documentation for the specified method.""" - - method = None - if method_name in self.funcs: - method = self.funcs[method_name] - elif self.instance is not None: - # Instance can implement _methodHelp to return help for a method - if hasattr(self.instance, '_methodHelp'): - return self.instance._methodHelp(method_name) - # if the instance has a _dispatch method then we - # don't have enough information to provide help - elif not hasattr(self.instance, '_dispatch'): - try: - method = resolve_dotted_attribute( - self.instance, - method_name, - self.allow_dotted_names - ) - except AttributeError: - pass - - # Note that we aren't checking that the method actually - # be a callable object of some kind - if method is None: - return "" - else: - import pydoc - return pydoc.getdoc(method) - - def system_multicall(self, call_list): - """system.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => \ -[[4], ...] - - Allows the caller to package multiple XML-RPC calls into a single - request. - - See http://www.xmlrpc.com/discuss/msgReader$1208 - """ - - results = [] - for call in call_list: - method_name = call['methodName'] - params = call['params'] - - try: - # XXX A marshalling error in any response will fail the entire - # multicall. If someone cares they should fix this. - results.append([self._dispatch(method_name, params)]) - except Fault, fault: - results.append( - {'faultCode' : fault.faultCode, - 'faultString' : fault.faultString} - ) - except: - exc_type, exc_value, exc_tb = sys.exc_info() - results.append( - {'faultCode' : 1, - 'faultString' : "%s:%s" % (exc_type, exc_value)} - ) - return results - - def _dispatch(self, method, params): - """Dispatches the XML-RPC method. - - XML-RPC calls are forwarded to a registered function that - matches the called XML-RPC method name. If no such function - exists then the call is forwarded to the registered instance, - if available. - - If the registered instance has a _dispatch method then that - method will be called with the name of the XML-RPC method and - its parameters as a tuple - e.g. instance._dispatch('add',(2,3)) - - If the registered instance does not have a _dispatch method - then the instance will be searched to find a matching method - and, if found, will be called. - - Methods beginning with an '_' are considered private and will - not be called. - """ - - func = None - try: - # check to see if a matching function has been registered - func = self.funcs[method] - except KeyError: - if self.instance is not None: - # check for a _dispatch method - if hasattr(self.instance, '_dispatch'): - return self.instance._dispatch(method, params) - else: - # call instance method directly - try: - func = resolve_dotted_attribute( - self.instance, - method, - self.allow_dotted_names - ) - except AttributeError: - pass - - if func is not None: - return func(*params) - else: - raise Exception('method "%s" is not supported' % method) - -class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): - """Simple XML-RPC request handler class. - - Handles all HTTP POST requests and attempts to decode them as - XML-RPC requests. - """ - - # Class attribute listing the accessible path components; - # paths not on this list will result in a 404 error. - rpc_paths = ('/', '/RPC2') - - def is_rpc_path_valid(self): - if self.rpc_paths: - return self.path in self.rpc_paths - else: - # If .rpc_paths is empty, just assume all paths are legal - return True - - def do_POST(self): - """Handles the HTTP POST request. - - Attempts to interpret all HTTP POST requests as XML-RPC calls, - which are forwarded to the server's _dispatch method for handling. - """ - - # Check that the path is legal - if not self.is_rpc_path_valid(): - self.report_404() - return - - try: - # Get arguments by reading body of request. - # We read this in chunks to avoid straining - # socket.read(); around the 10 or 15Mb mark, some platforms - # begin to have problems (bug #792570). - max_chunk_size = 10*1024*1024 - size_remaining = int(self.headers["content-length"]) - L = [] - while size_remaining: - chunk_size = min(size_remaining, max_chunk_size) - L.append(self.rfile.read(chunk_size)) - size_remaining -= len(L[-1]) - data = ''.join(L) - - # In previous versions of SimpleXMLRPCServer, _dispatch - # could be overridden in this class, instead of in - # SimpleXMLRPCDispatcher. To maintain backwards compatibility, - # check to see if a subclass implements _dispatch and dispatch - # using that method if present. - response = self.server._marshaled_dispatch( - data, getattr(self, '_dispatch', None) - ) - except Exception, e: # This should only happen if the module is buggy - # internal error, report as HTTP server error - self.send_response(500) - - # Send information about the exception if requested - if hasattr(self.server, '_send_traceback_header') and \ - self.server._send_traceback_header: - self.send_header("X-exception", str(e)) - self.send_header("X-traceback", traceback.format_exc()) - - self.end_headers() - else: - # got a valid XML RPC response - self.send_response(200) - self.send_header("Content-type", "text/xml") - self.send_header("Content-length", str(len(response))) - self.end_headers() - self.wfile.write(response) - - # shut down the connection - self.wfile.flush() - self.connection.shutdown(1) - - def report_404 (self): - # Report a 404 error - self.send_response(404) - response = 'No such page' - self.send_header("Content-type", "text/plain") - self.send_header("Content-length", str(len(response))) - self.end_headers() - self.wfile.write(response) - # shut down the connection - self.wfile.flush() - self.connection.shutdown(1) - - def log_request(self, code='-', size='-'): - """Selectively log an accepted request.""" - - if self.server.logRequests: - BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) - -class SimpleXMLRPCServer(SocketServer.TCPServer, - SimpleXMLRPCDispatcher): - """Simple XML-RPC server. - - Simple XML-RPC server that allows functions and a single instance - to be installed to handle requests. The default implementation - attempts to dispatch XML-RPC calls to the functions or instance - installed in the server. Override the _dispatch method inhereted - from SimpleXMLRPCDispatcher to change this behavior. - """ - - allow_reuse_address = True - - # Warning: this is for debugging purposes only! Never set this to True in - # production code, as will be sending out sensitive information (exception - # and stack trace details) when exceptions are raised inside - # SimpleXMLRPCRequestHandler.do_POST - _send_traceback_header = False - - def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, - logRequests=True, allow_none=False, encoding=None, bind_and_activate=True): - self.logRequests = logRequests - - SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding) - SocketServer.TCPServer.__init__(self, addr, requestHandler, bind_and_activate) - - # [Bug #1222790] If possible, set close-on-exec flag; if a - # method spawns a subprocess, the subprocess shouldn't have - # the listening socket open. - if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'): - flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD) - flags |= fcntl.FD_CLOEXEC - fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) - -class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): - """Simple handler for XML-RPC data passed through CGI.""" - - def __init__(self, allow_none=False, encoding=None): - SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding) - - def handle_xmlrpc(self, request_text): - """Handle a single XML-RPC request""" - - response = self._marshaled_dispatch(request_text) - - print 'Content-Type: text/xml' - print 'Content-Length: %d' % len(response) - print - sys.stdout.write(response) - - def handle_get(self): - """Handle a single HTTP GET request. - - Default implementation indicates an error because - XML-RPC uses the POST method. - """ - - code = 400 - message, explain = \ - BaseHTTPServer.BaseHTTPRequestHandler.responses[code] - - response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \ - { - 'code' : code, - 'message' : message, - 'explain' : explain - } - print 'Status: %d %s' % (code, message) - print 'Content-Type: text/html' - print 'Content-Length: %d' % len(response) - print - sys.stdout.write(response) - - def handle_request(self, request_text = None): - """Handle a single XML-RPC request passed through a CGI post method. - - If no XML data is given then it is read from stdin. The resulting - XML-RPC response is printed to stdout along with the correct HTTP - headers. - """ - - if request_text is None and \ - os.environ.get('REQUEST_METHOD', None) == 'GET': - self.handle_get() - else: - # POST data is normally available through stdin - if request_text is None: - request_text = sys.stdin.read() - - self.handle_xmlrpc(request_text) - -if __name__ == '__main__': - print 'Running XML-RPC server on port 8000' - server = SimpleXMLRPCServer(("localhost", 8000)) - server.register_function(pow) - server.register_function(lambda x,y: x+y, 'add') - server.serve_forever() diff --git a/python25-compat/SocketServer.py b/python25-compat/SocketServer.py deleted file mode 100644 index 2c41fbb6dc0..00000000000 --- a/python25-compat/SocketServer.py +++ /dev/null @@ -1,681 +0,0 @@ -"""Generic socket server classes. - -This module tries to capture the various aspects of defining a server: - -For socket-based servers: - -- address family: - - AF_INET{,6}: IP (Internet Protocol) sockets (default) - - AF_UNIX: Unix domain sockets - - others, e.g. AF_DECNET are conceivable (see <socket.h> -- socket type: - - SOCK_STREAM (reliable stream, e.g. TCP) - - SOCK_DGRAM (datagrams, e.g. UDP) - -For request-based servers (including socket-based): - -- client address verification before further looking at the request - (This is actually a hook for any processing that needs to look - at the request before anything else, e.g. logging) -- how to handle multiple requests: - - synchronous (one request is handled at a time) - - forking (each request is handled by a new process) - - threading (each request is handled by a new thread) - -The classes in this module favor the server type that is simplest to -write: a synchronous TCP/IP server. This is bad class design, but -save some typing. (There's also the issue that a deep class hierarchy -slows down method lookups.) - -There are five classes in an inheritance diagram, four of which represent -synchronous servers of four types: - - +------------+ - | BaseServer | - +------------+ - | - v - +-----------+ +------------------+ - | TCPServer |------->| UnixStreamServer | - +-----------+ +------------------+ - | - v - +-----------+ +--------------------+ - | UDPServer |------->| UnixDatagramServer | - +-----------+ +--------------------+ - -Note that UnixDatagramServer derives from UDPServer, not from -UnixStreamServer -- the only difference between an IP and a Unix -stream server is the address family, which is simply repeated in both -unix server classes. - -Forking and threading versions of each type of server can be created -using the ForkingMixIn and ThreadingMixIn mix-in classes. For -instance, a threading UDP server class is created as follows: - - class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass - -The Mix-in class must come first, since it overrides a method defined -in UDPServer! Setting the various member variables also changes -the behavior of the underlying server mechanism. - -To implement a service, you must derive a class from -BaseRequestHandler and redefine its handle() method. You can then run -various versions of the service by combining one of the server classes -with your request handler class. - -The request handler class must be different for datagram or stream -services. This can be hidden by using the request handler -subclasses StreamRequestHandler or DatagramRequestHandler. - -Of course, you still have to use your head! - -For instance, it makes no sense to use a forking server if the service -contains state in memory that can be modified by requests (since the -modifications in the child process would never reach the initial state -kept in the parent process and passed to each child). In this case, -you can use a threading server, but you will probably have to use -locks to avoid two requests that come in nearly simultaneous to apply -conflicting changes to the server state. - -On the other hand, if you are building e.g. an HTTP server, where all -data is stored externally (e.g. in the file system), a synchronous -class will essentially render the service "deaf" while one request is -being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking -server is appropriate. - -In some cases, it may be appropriate to process part of a request -synchronously, but to finish processing in a forked child depending on -the request data. This can be implemented by using a synchronous -server and doing an explicit fork in the request handler class -handle() method. - -Another approach to handling multiple simultaneous requests in an -environment that supports neither threads nor fork (or where these are -too expensive or inappropriate for the service) is to maintain an -explicit table of partially finished requests and to use select() to -decide which request to work on next (or whether to handle a new -incoming request). This is particularly important for stream services -where each client can potentially be connected for a long time (if -threads or subprocesses cannot be used). - -Future work: -- Standard classes for Sun RPC (which uses either UDP or TCP) -- Standard mix-in classes to implement various authentication - and encryption schemes -- Standard framework for select-based multiplexing - -XXX Open problems: -- What to do with out-of-band data? - -BaseServer: -- split generic "request" functionality out into BaseServer class. - Copyright (C) 2000 Luke Kenneth Casson Leighton <lkcl@samba.org> - - example: read entries from a SQL database (requires overriding - get_request() to return a table entry from the database). - entry is processed by a RequestHandlerClass. - -""" - -# Author of the BaseServer patch: Luke Kenneth Casson Leighton - -# XXX Warning! -# There is a test suite for this module, but it cannot be run by the -# standard regression test. -# To run it manually, run Lib/test/test_socketserver.py. - -__version__ = "0.4" - - -import socket -import select -import sys -import os -try: - import threading -except ImportError: - import dummy_threading as threading - -__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", - "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", - "StreamRequestHandler","DatagramRequestHandler", - "ThreadingMixIn", "ForkingMixIn"] -if hasattr(socket, "AF_UNIX"): - __all__.extend(["UnixStreamServer","UnixDatagramServer", - "ThreadingUnixStreamServer", - "ThreadingUnixDatagramServer"]) - -class BaseServer: - - """Base class for server classes. - - Methods for the caller: - - - __init__(server_address, RequestHandlerClass) - - serve_forever(poll_interval=0.5) - - shutdown() - - handle_request() # if you do not use serve_forever() - - fileno() -> int # for select() - - Methods that may be overridden: - - - server_bind() - - server_activate() - - get_request() -> request, client_address - - handle_timeout() - - verify_request(request, client_address) - - server_close() - - process_request(request, client_address) - - close_request(request) - - handle_error() - - Methods for derived classes: - - - finish_request(request, client_address) - - Class variables that may be overridden by derived classes or - instances: - - - timeout - - address_family - - socket_type - - allow_reuse_address - - Instance variables: - - - RequestHandlerClass - - socket - - """ - - timeout = None - - def __init__(self, server_address, RequestHandlerClass): - """Constructor. May be extended, do not override.""" - self.server_address = server_address - self.RequestHandlerClass = RequestHandlerClass - self.__is_shut_down = threading.Event() - self.__serving = False - - def server_activate(self): - """Called by constructor to activate the server. - - May be overridden. - - """ - pass - - def serve_forever(self, poll_interval=0.5): - """Handle one request at a time until shutdown. - - Polls for shutdown every poll_interval seconds. Ignores - self.timeout. If you need to do periodic tasks, do them in - another thread. - """ - self.__serving = True - self.__is_shut_down.clear() - while self.__serving: - # XXX: Consider using another file descriptor or - # connecting to the socket to wake this up instead of - # polling. Polling reduces our responsiveness to a - # shutdown request and wastes cpu at all other times. - r, w, e = select.select([self], [], [], poll_interval) - if r: - self._handle_request_noblock() - self.__is_shut_down.set() - - def shutdown(self): - """Stops the serve_forever loop. - - Blocks until the loop has finished. This must be called while - serve_forever() is running in another thread, or it will - deadlock. - """ - self.__serving = False - self.__is_shut_down.wait() - - # The distinction between handling, getting, processing and - # finishing a request is fairly arbitrary. Remember: - # - # - handle_request() is the top-level call. It calls - # select, get_request(), verify_request() and process_request() - # - get_request() is different for stream or datagram sockets - # - process_request() is the place that may fork a new process - # or create a new thread to finish the request - # - finish_request() instantiates the request handler class; - # this constructor will handle the request all by itself - - def handle_request(self): - """Handle one request, possibly blocking. - - Respects self.timeout. - """ - # Support people who used socket.settimeout() to escape - # handle_request before self.timeout was available. - timeout = self.socket.gettimeout() - if timeout is None: - timeout = self.timeout - elif self.timeout is not None: - timeout = min(timeout, self.timeout) - fd_sets = select.select([self], [], [], timeout) - if not fd_sets[0]: - self.handle_timeout() - return - self._handle_request_noblock() - - def _handle_request_noblock(self): - """Handle one request, without blocking. - - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). - """ - try: - request, client_address = self.get_request() - except socket.error: - return - if self.verify_request(request, client_address): - try: - self.process_request(request, client_address) - except: - self.handle_error(request, client_address) - self.close_request(request) - - def handle_timeout(self): - """Called if no new request arrives within self.timeout. - - Overridden by ForkingMixIn. - """ - pass - - def verify_request(self, request, client_address): - """Verify the request. May be overridden. - - Return True if we should proceed with this request. - - """ - return True - - def process_request(self, request, client_address): - """Call finish_request. - - Overridden by ForkingMixIn and ThreadingMixIn. - - """ - self.finish_request(request, client_address) - self.close_request(request) - - def server_close(self): - """Called to clean-up the server. - - May be overridden. - - """ - pass - - def finish_request(self, request, client_address): - """Finish one request by instantiating RequestHandlerClass.""" - self.RequestHandlerClass(request, client_address, self) - - def close_request(self, request): - """Called to clean up an individual request.""" - pass - - def handle_error(self, request, client_address): - """Handle an error gracefully. May be overridden. - - The default is to print a traceback and continue. - - """ - print '-'*40 - print 'Exception happened during processing of request from', - print client_address - import traceback - traceback.print_exc() # XXX But this goes to stderr! - print '-'*40 - - -class TCPServer(BaseServer): - - """Base class for various socket-based server classes. - - Defaults to synchronous IP stream (i.e., TCP). - - Methods for the caller: - - - __init__(server_address, RequestHandlerClass, bind_and_activate=True) - - serve_forever(poll_interval=0.5) - - shutdown() - - handle_request() # if you don't use serve_forever() - - fileno() -> int # for select() - - Methods that may be overridden: - - - server_bind() - - server_activate() - - get_request() -> request, client_address - - handle_timeout() - - verify_request(request, client_address) - - process_request(request, client_address) - - close_request(request) - - handle_error() - - Methods for derived classes: - - - finish_request(request, client_address) - - Class variables that may be overridden by derived classes or - instances: - - - timeout - - address_family - - socket_type - - request_queue_size (only for stream sockets) - - allow_reuse_address - - Instance variables: - - - server_address - - RequestHandlerClass - - socket - - """ - - address_family = socket.AF_INET - - socket_type = socket.SOCK_STREAM - - request_queue_size = 5 - - allow_reuse_address = False - - def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): - """Constructor. May be extended, do not override.""" - BaseServer.__init__(self, server_address, RequestHandlerClass) - self.socket = socket.socket(self.address_family, - self.socket_type) - if bind_and_activate: - self.server_bind() - self.server_activate() - - def server_bind(self): - """Called by constructor to bind the socket. - - May be overridden. - - """ - if self.allow_reuse_address: - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.socket.bind(self.server_address) - self.server_address = self.socket.getsockname() - - def server_activate(self): - """Called by constructor to activate the server. - - May be overridden. - - """ - self.socket.listen(self.request_queue_size) - - def server_close(self): - """Called to clean-up the server. - - May be overridden. - - """ - self.socket.close() - - def fileno(self): - """Return socket file number. - - Interface required by select(). - - """ - return self.socket.fileno() - - def get_request(self): - """Get the request and client address from the socket. - - May be overridden. - - """ - return self.socket.accept() - - def close_request(self, request): - """Called to clean up an individual request.""" - request.close() - - -class UDPServer(TCPServer): - - """UDP server class.""" - - allow_reuse_address = False - - socket_type = socket.SOCK_DGRAM - - max_packet_size = 8192 - - def get_request(self): - data, client_addr = self.socket.recvfrom(self.max_packet_size) - return (data, self.socket), client_addr - - def server_activate(self): - # No need to call listen() for UDP. - pass - - def close_request(self, request): - # No need to close anything. - pass - -class ForkingMixIn: - - """Mix-in class to handle each request in a new process.""" - - timeout = 300 - active_children = None - max_children = 40 - - def collect_children(self): - """Internal routine to wait for children that have exited.""" - if self.active_children is None: return - while len(self.active_children) >= self.max_children: - # XXX: This will wait for any child process, not just ones - # spawned by this library. This could confuse other - # libraries that expect to be able to wait for their own - # children. - try: - pid, status = os.waitpid(0, options=0) - except os.error: - pid = None - if pid not in self.active_children: continue - self.active_children.remove(pid) - - # XXX: This loop runs more system calls than it ought - # to. There should be a way to put the active_children into a - # process group and then use os.waitpid(-pgid) to wait for any - # of that set, but I couldn't find a way to allocate pgids - # that couldn't collide. - for child in self.active_children: - try: - pid, status = os.waitpid(child, os.WNOHANG) - except os.error: - pid = None - if not pid: continue - try: - self.active_children.remove(pid) - except ValueError, e: - raise ValueError('%s. x=%d and list=%r' % (e.message, pid, - self.active_children)) - - def handle_timeout(self): - """Wait for zombies after self.timeout seconds of inactivity. - - May be extended, do not override. - """ - self.collect_children() - - def process_request(self, request, client_address): - """Fork a new subprocess to process the request.""" - self.collect_children() - pid = os.fork() - if pid: - # Parent process - if self.active_children is None: - self.active_children = [] - self.active_children.append(pid) - self.close_request(request) - return - else: - # Child process. - # This must never return, hence os._exit()! - try: - self.finish_request(request, client_address) - os._exit(0) - except: - try: - self.handle_error(request, client_address) - finally: - os._exit(1) - - -class ThreadingMixIn: - """Mix-in class to handle each request in a new thread.""" - - # Decides how threads will act upon termination of the - # main process - daemon_threads = False - - def process_request_thread(self, request, client_address): - """Same as in BaseServer but as a thread. - - In addition, exception handling is done here. - - """ - try: - self.finish_request(request, client_address) - self.close_request(request) - except: - self.handle_error(request, client_address) - self.close_request(request) - - def process_request(self, request, client_address): - """Start a new thread to process the request.""" - t = threading.Thread(target = self.process_request_thread, - args = (request, client_address)) - if self.daemon_threads: - t.setDaemon (1) - t.start() - - -class ForkingUDPServer(ForkingMixIn, UDPServer): pass -class ForkingTCPServer(ForkingMixIn, TCPServer): pass - -class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass -class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass - -if hasattr(socket, 'AF_UNIX'): - - class UnixStreamServer(TCPServer): - address_family = socket.AF_UNIX - - class UnixDatagramServer(UDPServer): - address_family = socket.AF_UNIX - - class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass - - class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass - -class BaseRequestHandler: - - """Base class for request handler classes. - - This class is instantiated for each request to be handled. The - constructor sets the instance variables request, client_address - and server, and then calls the handle() method. To implement a - specific service, all you need to do is to derive a class which - defines a handle() method. - - The handle() method can find the request as self.request, the - client address as self.client_address, and the server (in case it - needs access to per-server information) as self.server. Since a - separate instance is created for each request, the handle() method - can define arbitrary other instance variariables. - - """ - - def __init__(self, request, client_address, server): - self.request = request - self.client_address = client_address - self.server = server - try: - self.setup() - self.handle() - self.finish() - finally: - sys.exc_traceback = None # Help garbage collection - - def setup(self): - pass - - def handle(self): - pass - - def finish(self): - pass - - -# The following two classes make it possible to use the same service -# class for stream or datagram servers. -# Each class sets up these instance variables: -# - rfile: a file object from which receives the request is read -# - wfile: a file object to which the reply is written -# When the handle() method returns, wfile is flushed properly - - -class StreamRequestHandler(BaseRequestHandler): - - """Define self.rfile and self.wfile for stream sockets.""" - - # Default buffer sizes for rfile, wfile. - # We default rfile to buffered because otherwise it could be - # really slow for large data (a getc() call per byte); we make - # wfile unbuffered because (a) often after a write() we want to - # read and we need to flush the line; (b) big writes to unbuffered - # files are typically optimized by stdio even when big reads - # aren't. - rbufsize = -1 - wbufsize = 0 - - def setup(self): - self.connection = self.request - self.rfile = self.connection.makefile('rb', self.rbufsize) - self.wfile = self.connection.makefile('wb', self.wbufsize) - - def finish(self): - if not self.wfile.closed: - self.wfile.flush() - self.wfile.close() - self.rfile.close() - - -class DatagramRequestHandler(BaseRequestHandler): - - # XXX Regrettably, I cannot get this working on Linux; - # s.recvfrom() doesn't return a meaningful client address. - - """Define self.rfile and self.wfile for datagram sockets.""" - - def setup(self): - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - self.packet, self.socket = self.request - self.rfile = StringIO(self.packet) - self.wfile = StringIO() - - def finish(self): - self.socket.sendto(self.wfile.getvalue(), self.client_address) diff --git a/setup.README b/setup.README deleted file mode 100644 index 5ee564ecfb4..00000000000 --- a/setup.README +++ /dev/null @@ -1,27 +0,0 @@ -Some instructions to use setup.py for a user-install. -This file should/will be moved on a proper documentation place later. - -- Possibly clean any left-over of the previous build. - > rm -rf dist openerp_server.egg-info - -- Possibly copy the addons in the server if we want them to be packaged - together: - > rsync -av --delete \ - --exclude .bzr/ \ - --exclude .bzrignore \ - --exclude /__init__.py \ - --exclude /base \ - --exclude /base_quality_interrogation.py \ - <path-to-addons> openerp/addons - -- Create the user-local directory where we want the package to be installed: - > mkdir -p /home/openerp/openerp-tmp/lib/python2.6/site-packages/ - -- Use --prefix to specify where the package is installed and include that - place in PYTHONPATH: - > PYTHONPATH=/home/openerp/openerp-tmp/lib/python2.6/site-packages/ \ - python setup.py install --prefix=/home/openerp/openerp-tmp - -- Run the main script, again specifying the PYTHONPATH: - > PYTHONPATH=/home/openerp/openerp-tmp/lib/python2.6/site-packages/ \ - /home/openerp/openerp-tmp/bin/openerp-server diff --git a/setup.cfg b/setup.cfg index 483eb2f22e1..2f64223e455 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,4 +17,4 @@ requires=python >= 2.5 # Need to overwrite the install-part of the RPM to patch # the filenames of the man pages. -install_script=rpminstall_sh.txt +install_script=setup_rpm.sh diff --git a/setup.nsi b/setup.nsi index f9c962ae383..0ea37b0f9e6 100644 --- a/setup.nsi +++ b/setup.nsi @@ -210,6 +210,7 @@ Section OpenERP_Server SectionOpenERP_Server WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_user" $TextPostgreSQLUsername
WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_password" $TextPostgreSQLPassword
WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_port" $TextPostgreSQLPort
+ WriteIniStr "$INSTDIR\openerp-server.conf" "options" "pg_path" "$INSTDIR\PostgreSQL\bin"
nsExec::Exec '"$INSTDIR\openerp-server.exe" --stop-after-init --logfile "$INSTDIR\openerp-server.log" -s'
nsExec::Exec '"$INSTDIR\service\OpenERPServerService.exe" -auto -install'
diff --git a/setup.py b/setup.py index 91248a0ea73..08c30faf737 100644..100755 --- a/setup.py +++ b/setup.py @@ -1,89 +1,115 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## -import os -import re -import sys -from setuptools import setup +import glob, os, re, setuptools, sys +from os.path import join, isfile -name = 'openerp-web-proto' -version = '6.0.1' -description = "Web Client of OpenERP, the Enterprise Management Software" -long_description = "OpenERP Web is the web client of the OpenERP, a free enterprise management software" -author = "OpenERP S.A." -author_email = "info@openerp.com" -support_email = 'support@openerp.com' -url = "http://www.openerp.com/" -download_url = '' -license = "OEPL" +# List all data files +def data(): + files = [] + for root, dirnames, filenames in os.walk('openerp'): + for filename in filenames: + if not re.match(r'.*(\.pyc|\.pyo|\~)$',filename): + files.append(os.path.join(root, filename)) + d = {} + for v in files: + k=os.path.dirname(v) + if k in d: + d[k].append(v) + else: + d[k]=[v] + r = d.items() + return r -version_dash_incompatible = False -if 'bdist_rpm' in sys.argv: - version_dash_incompatible = True -try: - import py2exe - from py2exe_utils import opts - version_dash_incompatible = True -except ImportError: - opts = {} -if version_dash_incompatible: - version = version.split('-')[0] +def gen_manifest(): + file_list="\n".join(data()) + open('MANIFEST','w').write(file_list) -FILE_PATTERNS = \ - r'.+\.(py|cfg|po|pot|mo|txt|rst|gif|png|jpg|ico|mako|html|js|css|htc|swf)$' -def find_data_files(source, patterns=FILE_PATTERNS): - file_matcher = re.compile(patterns, re.I) - out = [] - for base, _, files in os.walk(source): - cur_files = [] - for f in files: - if file_matcher.match(f): - cur_files.append(os.path.join(base, f)) - if cur_files: - out.append( - (base, cur_files)) +def py2exe_options(): + if os.name == 'nt': + import py2exe + return { + "console" : [ { "script": "openerp-server", "icon_resources": [(1, join("pixmaps","openerp-icon.ico"))], }], + 'options' : { + "py2exe": { + "skip_archive": 1, + "optimize": 2, + "dist_dir": 'dist', + "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber" "vobject", "xml", "xml", "xml.dom", "xml.xpath", "yaml", ], + "excludes" : ["Tkconstants","Tkinter","tcl"], + } + } + } + else: + return {} - return out +execfile(join(os.path.dirname(__file__), 'openerp', 'release.py')) +if timestamp: + version = version + "-" + timestamp -setup( - name=name, - version=version, - description=description, - long_description=long_description, - author=author, - author_email=author_email, - url=url, - download_url=download_url, - license=license, - install_requires=[ - "CherryPy >= 3.1.2", - "Babel >= 0.9.6", - "simplejson >= 2.0.9", - "python-dateutil >= 1.4.1", - "pytz", - ], - tests_require=[ - 'unittest2', - 'mock', - ], - test_suite = 'unittest2.collector', - zip_safe=False, - packages=[ - 'addons', - 'addons.base', - 'addons.base.controllers', - 'addons.base_calendar', - 'addons.base_hello', - 'openerpweb', - ], - classifiers=[ - 'Development Status :: 6 - Production/Stable', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Environment :: Web Environment', - 'Topic :: Office/Business :: Financial', - ], - scripts=['scripts/openerp-web'], - data_files=(find_data_files('addons') - + opts.pop('data_files', []) - ), - **opts +setuptools.setup( + name = 'openerp', + version = version, + description = description, + long_description = long_desc, + url = url, + author = author, + author_email = author_email, + classifiers = filter(None, classifiers.split("\n")), + license = license, + scripts = ['openerp-server'], + data_files = data(), + packages = setuptools.find_packages(), + #include_package_data = True, + install_requires = [ + # TODO the pychart package we include in openerp corresponds to PyChart 1.37. + # It seems there is a single difference, which is a spurious print in generate_docs.py. + # It is probably safe to move to PyChart 1.39 (the latest one). + # (Let setup.py choose the latest one, and we should check we can remove pychart from + # our tree.) http://download.gna.org/pychart/ + # TODO 'pychart', + 'babel', + 'feedparser', + 'gdata', + 'lxml', + 'mako', + 'psycopg2', + 'pydot', + 'python-dateutil', + 'python-ldap', + 'python-openid', + 'pytz', + 'pywebdav', + 'pyyaml', + 'reportlab', + 'simplejson', + 'vatnumber', # recommended by base_vat + 'vobject', + 'werkzeug', + 'zsi', + ], + extras_require = { + 'SSL' : ['pyopenssl'], + }, + **py2exe_options() ) + diff --git a/rpminstall_sh.txt b/setup_rpm.sh index bb7bb3fc10c..bb7bb3fc10c 100644 --- a/rpminstall_sh.txt +++ b/setup_rpm.sh diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000000..396284efaf7 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +import test_xmlrpc diff --git a/tests/addons/test_exceptions/__init__.py b/tests/addons/test_exceptions/__init__.py new file mode 100644 index 00000000000..fe4487156b1 --- /dev/null +++ b/tests/addons/test_exceptions/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +import models +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/__openerp__.py b/tests/addons/test_exceptions/__openerp__.py new file mode 100644 index 00000000000..bac853e301a --- /dev/null +++ b/tests/addons/test_exceptions/__openerp__.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'test-exceptions', + 'version': '0.1', + 'category': 'Tests', + 'description': """A module to generate exceptions.""", + 'author': 'OpenERP SA', + 'maintainer': 'OpenERP SA', + 'website': 'http://www.openerp.com', + 'depends': ['base'], + 'data': ['view.xml'], + 'installable': True, + 'active': False, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/models.py b/tests/addons/test_exceptions/models.py new file mode 100644 index 00000000000..45f0e6dbd47 --- /dev/null +++ b/tests/addons/test_exceptions/models.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +import openerp + +class m(openerp.osv.osv.Model): + """ This model exposes a few methods that will raise the different + exceptions that must be handled by the server (and its RPC layer) + and the clients. + """ + _name = 'test.exceptions.model' + + def generate_except_osv(self, cr, uid, ids, context=None): + # title is ignored in the new (6.1) exceptions + raise openerp.osv.osv.except_osv('title', 'description') + + def generate_except_orm(self, cr, uid, ids, context=None): + # title is ignored in the new (6.1) exceptions + raise openerp.osv.orm.except_orm('title', 'description') + + def generate_warning(self, cr, uid, ids, context=None): + raise openerp.exceptions.Warning('description') + + def generate_access_denied(self, cr, uid, ids, context=None): + raise openerp.exceptions.AccessDenied() + + def generate_access_error(self, cr, uid, ids, context=None): + raise openerp.exceptions.AccessError('description') + + def generate_exc_access_denied(self, cr, uid, ids, context=None): + raise Exception('AccessDenied') + + def generate_undefined(self, cr, uid, ids, context=None): + self.surely_undefined_sumbol +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/tests/addons/test_exceptions/view.xml b/tests/addons/test_exceptions/view.xml new file mode 100644 index 00000000000..296f862aec4 --- /dev/null +++ b/tests/addons/test_exceptions/view.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <record id="view_test_exceptions_model" model="ir.ui.view"> + <field name="name">Test exceptions</field> + <field name="model">test.exceptions.model</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Test exceptions"> + <label string="Each button generates a specific exception on the server. The text on the right is the expected representation of the exception when displayed on the client."/> + <group colspan="8" col="8"> + <separator string="" colspan="8"/> + <button name="generate_except_osv" string="except_osv" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_except_orm" string="except_orm" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_warning" string="Warning" type="object" icon="gtk-ok" colspan="1"/> + <label string="Warning-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_access_denied" string="AccessDenied" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access denied-traceback"/> + </group> + <group colspan="8" col="8"> + <button name="generate_access_error" string="AccessError" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access rights error-description"/> + </group> + <group colspan="8" col="8"> + <button name="generate_exc_access_denied" string="Exc AccessDenied" type="object" icon="gtk-ok" colspan="1"/> + <label string="Access denied-traceback"/> + </group> + <group colspan="8" col="8"> + <button name="generate_undefined" string="Undefined" type="object" icon="gtk-ok" colspan="1"/> + <label string="Server error-traceback"/> + </group> + <group colspan="8" col="8"> + <separator string="" colspan="8"/> + <label colspan="6" width="220"/> + <button special="cancel" string="Cancel" icon="gtk-cancel" colspan="1"/> + </group> + </form> + </field> + </record> + + <record id="action_test_exceptions" model="ir.actions.act_window"> + <field name="name">Test exceptions</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">test.exceptions.model</field> + <field name="view_type">form</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + + <menuitem icon="STOCK_PREFERENCES" id="base.menu_tests" name="Tests"/> + + <menuitem id="menu_test_exceptions" parent="base.menu_tests" name="Test exceptions"/> + + <menuitem id="menu_test_exceptions_leaf" + name="Test exceptions" + action="action_test_exceptions" + parent="menu_test_exceptions"/> + </data> +</openerp> diff --git a/tests/common.py b/tests/common.py new file mode 100644 index 00000000000..116898dc7ef --- /dev/null +++ b/tests/common.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +import os +import time +import unittest2 +import xmlrpclib + +import openerp + +ADDONS_PATH = os.environ['OPENERP_ADDONS_PATH'] +PORT = int(os.environ['OPENERP_PORT']) +DB = os.environ['OPENERP_DATABASE'] + +HOST = '127.0.0.1' + +ADMIN_USER = 'admin' +ADMIN_USER_ID = 1 +ADMIN_PASSWORD = 'admin' + +common_proxy_60 = None +db_proxy_60 = None +object_proxy_60 = None + +common_proxy_61 = None +db_proxy_61 = None +model_proxy_61 = None +model_uri_61 = None + +def setUpModule(): + """ + Start the OpenERP server similary to the openerp-server script and + setup some xmlrpclib proxies. + """ + openerp.tools.config['addons_path'] = ADDONS_PATH + openerp.tools.config['xmlrpc_port'] = PORT + openerp.service.start_services() + + global common_proxy_60 + global db_proxy_60 + global object_proxy_60 + + # Use the old (pre 6.1) API. + url = 'http://%s:%d/xmlrpc/' % (HOST, PORT) + common_proxy_60 = xmlrpclib.ServerProxy(url + 'common') + db_proxy_60 = xmlrpclib.ServerProxy(url + 'db') + object_proxy_60 = xmlrpclib.ServerProxy(url + 'object') + + global common_proxy_61 + global db_proxy_61 + global model_proxy_61 + global model_uri_61 + + # Use the new (6.1) API. + model_uri_61 = 'http://%s:%d/openerp/xmlrpc/1/' % (HOST, PORT) + common_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'common') + db_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'db') + model_proxy_61 = xmlrpclib.ServerProxy(model_uri_61 + 'model/' + DB) + + # Ugly way to ensure the server is listening. + time.sleep(2) + +def tearDownModule(): + """ Shutdown the OpenERP server similarly to a single ctrl-c. """ + openerp.service.stop_services() diff --git a/tests/test_ir_sequence.py b/tests/test_ir_sequence.py new file mode 100644 index 00000000000..8a4731d524f --- /dev/null +++ b/tests/test_ir_sequence.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# Run with one of these commands: +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_ir_sequence.py +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy nosetests tests/test_ir_sequence.py +# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence +# This assume an existing database. +import os +import psycopg2 +import time +import unittest2 +import xmlrpclib + +import openerp +import common + +DB = common.DB +ADMIN_USER_ID = common.ADMIN_USER_ID + +setUpModule = common.setUpModule +tearDownModule = common.tearDownModule + +def registry(model): + return openerp.modules.registry.RegistryManager.get(DB)[model] + +def cursor(): + return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + +class test_ir_sequence_standard(unittest2.TestCase): + """ A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """ + + def test_ir_sequence_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_search(self): + """ Try a search. """ + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, [], {}) + assert ids + cr.commit() + cr.close() + + def test_ir_sequence_draw(self): + """ Try to draw a number. """ + cr = cursor() + n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n + cr.commit() + cr.close() + + def test_ir_sequence_draw_twice(self): + """ Try to draw a number from two transactions. """ + cr0 = cursor() + cr1 = cursor() + n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n0 + n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type', {}) + assert n1 + cr0.commit() + cr1.commit() + cr0.close() + cr1.close() + +class test_ir_sequence_no_gap(unittest2.TestCase): + """ Copy of the previous tests for a 'No gap' sequence. """ + + def test_ir_sequence_create_no_gap(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_2', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_2', name='Test sequence', + implementation='no_gap') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_draw_no_gap(self): + """ Try to draw a number. """ + cr = cursor() + n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_2', {}) + assert n + cr.commit() + cr.close() + + def test_ir_sequence_draw_twice_no_gap(self): + """ Try to draw a number from two transactions. + This is expected to not work. + """ + cr0 = cursor() + cr1 = cursor() + msg_re = '^could not obtain lock on row in relation "ir_sequence"$' + with self.assertRaisesRegexp(psycopg2.OperationalError, msg_re): + n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {}) + assert n0 + n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {}) + cr0.close() + cr1.close() + +class test_ir_sequence_change_implementation(unittest2.TestCase): + """ Create sequence objects and change their ``implementation`` field. """ + + def test_ir_sequence_1_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_3', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_3', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_4', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_4', name='Test sequence', + implementation='no_gap') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + def test_ir_sequence_2_write(self): + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, + [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {}) + registry('ir.sequence').write(cr, ADMIN_USER_ID, ids, + {'implementation': 'standard'}, {}) + registry('ir.sequence').write(cr, ADMIN_USER_ID, ids, + {'implementation': 'no_gap'}, {}) + cr.commit() + cr.close() + + def test_ir_sequence_3_unlink(self): + cr = cursor() + ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, + [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {}) + registry('ir.sequence').unlink(cr, ADMIN_USER_ID, ids, {}) + cr.commit() + cr.close() + +class test_ir_sequence_generate(unittest2.TestCase): + """ Create sequence objects and generate some values. """ + + def test_ir_sequence_create(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_5', name='Test sequence type') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_5', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + cr = cursor() + f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_5', {}) + assert all(str(x) == f() for x in xrange(1,1000)) + cr.commit() + cr.close() + + def test_ir_sequence_create_no_gap(self): + """ Try to create a sequence object. """ + cr = cursor() + d = dict(code='test_sequence_type_6', name='Test sequence type', + implementation='no_gap') + c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {}) + assert c + d = dict(code='test_sequence_type_6', name='Test sequence') + c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {}) + assert c + cr.commit() + cr.close() + + cr = cursor() + f = lambda *a: registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_6', {}) + assert all(str(x) == f() for x in xrange(1,1000)) + cr.commit() + cr.close() + + + +if __name__ == '__main__': + unittest2.main() + diff --git a/tests/test_xmlrpc.py b/tests/test_xmlrpc.py new file mode 100644 index 00000000000..4ad530cbeda --- /dev/null +++ b/tests/test_xmlrpc.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Run with one of these commands: +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_xmlrpc.py +# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy nosetests tests/test_xmlrpc.py +# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \ +# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_xmlrpc +import os +import time +import unittest2 +import xmlrpclib + +import openerp +import common + +DB = common.DB +ADMIN_USER = common.ADMIN_USER +ADMIN_USER_ID = common.ADMIN_USER_ID +ADMIN_PASSWORD = common.ADMIN_PASSWORD + +setUpModule = common.setUpModule +tearDownModule = common.tearDownModule + +class test_xmlrpc(unittest2.TestCase): + + def test_00_xmlrpc_create_database_polling(self): + """ + Simulate a OpenERP client requesting the creation of a database and + polling the server until the creation is complete. + """ + progress_id = common.db_proxy_60.create(ADMIN_PASSWORD, DB, True, + False, ADMIN_PASSWORD) + while True: + time.sleep(1) + progress, users = common.db_proxy_60.get_progress(ADMIN_PASSWORD, + progress_id) + if progress == 1.0: + break + + def test_xmlrpc_login(self): + """ Try to login on the common service. """ + uid = common.common_proxy_60.login(DB, ADMIN_USER, ADMIN_PASSWORD) + assert uid == ADMIN_USER_ID + + def test_xmlrpc_ir_model_search(self): + """ Try a search on the object service. """ + ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD, + 'ir.model', 'search', []) + assert ids + ids = common.object_proxy_60.execute(DB, ADMIN_USER_ID, ADMIN_PASSWORD, + 'ir.model', 'search', [], {}) + assert ids + + def test_xmlrpc_61_ir_model_search(self): + """ Try a search on the object service. """ + + proxy = xmlrpclib.ServerProxy(common.model_uri_61 + 'model/' + DB + '/ir.model') + ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', []) + assert ids + ids = proxy.execute(ADMIN_USER_ID, ADMIN_PASSWORD, 'search', [], {}) + assert ids + +if __name__ == '__main__': + unittest2.main() + |
